diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 7889b52afa141d9ec38c739b7bff350fc88997fa..769ee60d1e78eed4cb481f6af4044d2f9869141c 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -44,7 +44,6 @@ variables: - cargo --version - sccache -s only: - - tags - master - /^v[0-9]+\.[0-9]+.*$/ # i.e. v1.0, v2.1rc1 - schedules @@ -53,6 +52,13 @@ variables: tags: - linux-docker +.build-only: &build-only + only: + - master + - /^v[0-9]+\.[0-9]+.*$/ # i.e. v1.0, v2.1rc1 + - web + + #### stage: test @@ -95,7 +101,7 @@ cargo-check-benches: stage: test <<: *docker-env script: - - BUILD_DUMMY_WASM_BINARY=1 time cargo check --benches --all + - BUILD_DUMMY_WASM_BINARY=1 time cargo +nightly check --benches --all - sccache -s @@ -145,10 +151,6 @@ test-srml-staking: &test-srml-staking except: variables: - $DEPLOY_TAG - only: - changes: - - .gitlab-ci.yml - - srml/staking/* script: - cd srml/staking/ - time cargo test --release --verbose --no-default-features --features std @@ -202,7 +204,6 @@ check-web-wasm: - time cargo web build -p substrate-keystore - time cargo web build -p substrate-executor - time cargo web build -p substrate-network - - time cargo web build -p substrate-offchain - time cargo web build -p substrate-panic-handler - time cargo web build -p substrate-peerset - time cargo web build -p substrate-primitives @@ -215,11 +216,13 @@ check-web-wasm: - time cargo web build -p substrate-trie - sccache -s -.build-only: &build-only - only: - - master - - tags - - web +node-exits: + stage: test + <<: *docker-env + except: + - /^v[0-9]+\.[0-9]+.*$/ # i.e. v1.0, v2.1rc1 + script: + - ./ci/check_for_exit.sh #### stage: build @@ -285,7 +288,7 @@ build-rust-doc-release: <<: *build-only script: - rm -f ./crate-docs/index.html # use it as an indicator if the job succeeds - - BUILD_DUMMY_WASM_BINARY=1 time cargo +nightly doc --release --all --verbose + - BUILD_DUMMY_WASM_BINARY=1 RUSTDOCFLAGS="--html-in-header $(pwd)/rustdoc-header.html" time cargo +nightly doc --release --all --verbose - cp -R ./target/doc ./crate-docs - echo "" > ./crate-docs/index.html - sccache -s @@ -336,7 +339,7 @@ check_warnings: - docker push $CONTAINER_IMAGE:$VERSION - docker push $CONTAINER_IMAGE:latest -publish-docker-substrate: +publish-docker-substrate: stage: publish <<: *publish-docker-release # collect VERSION artifact here to pass it on to kubernetes @@ -526,6 +529,8 @@ deploy-ue1-tag: name: parity-prod-ue1 .validator-deploy: &validator-deploy + # script will fail if there is no artifacts/substrate/VERSION + <<: *build-only stage: flaming-fir dependencies: - build-linux-substrate diff --git a/CODEOWNERS b/CODEOWNERS index 2106b2a59e1b3eaea8c407c2267a964b0ccc4c06..866f16522316bcfa0d89aaf1ea1762982a36bc9c 100644 --- a/CODEOWNERS +++ b/CODEOWNERS @@ -1,4 +1,11 @@ -# Lists some code owners +# Lists some code owners. +# +# A codeowner just oversees some part of the codebase. If an owned file is changed then the +# corresponding codeowner receives a review request. An approval of the codeowner is +# not required for merging a PR though. +# +# **This is pretty much an experiment at the moment**. Feel free to remove yourself at any time if +# you do not want to receive review requests any longer. # # For details about syntax, see: # https://help.github.com/en/articles/about-code-owners @@ -8,8 +15,54 @@ # can be everywhere. # - Multiple owners are supported. # - Either handle (e.g, @pepyakin) or email can be used. Keep in mind, that handles might work better because they -# are more recognizable on GitHub, you can use them for mentioning unlike an email. +# are more recognizable on GitHub, you can use them for mentioning unlike an email. # - The latest matching rule, if multiple, takes precedence. -/srml/contracts/ @pepyakin +# Wasm execution and the wasm side of Substrate Runtime Interface /core/executor/ @pepyakin +/core/sr-io/without_std.rs @pepyakin +/core/sr-std/without_std.rs @pepyakin + +# Sandboxing capability of Substrate Runtime +/core/sr-sandbox/ @pepyakin +/core/primitives/src/sandbox.rs @pepyakin + +# Transaction pool +/core/transaction-pool/ @tomusdrw + +# Offchain +/core/offchain/ @tomusdrw +/sr-io/src/offchain/ @tomusdrw + +# Everything that has RPC in it +/core/rpc/ @tomusdrw +/node/rpc/ @tomusdrw +/node/rpc-client/ @tomusdrw +/core/rpc-servers/ @tomusdrw + +# GRANDPA, BABE, consensus stuff +/srml/babe/ @andresilva @DemiMarie-parity +/srml/grandpa/ @andresilva @DemiMarie-parity +/core/finality-grandpa/ @andresilva @DemiMarie-parity +/core/consensus/babe/ @andresilva @DemiMarie-parity +/core/consensus/slots/ @andresilva @DemiMarie-parity + +# Contracts +/srml/contracts/ @pepyakin @thiolliere @jimpo +/srml/contracts/src/wasm/runtime.rs @Robbepop + +# Inflation points +/srml/staking/src/inflation.rs @thiolliere + +# NPoS and Governance +/srml/staking/ @kianenigma +/srml/election/ @kianenigma + +# End to end testing of substrate node +/node/executor/ @kianenigma + +# Transaction weight stuff +/core/sr-primitives/weights.rs @kianenigma + +# Support crates +/srml/support/ @thiolliere @kianenigma diff --git a/CONTRIBUTING.adoc b/CONTRIBUTING.adoc index b797e72e82b542fa06724a0d0eceaa7a92b6e779..1de4820a1170673b1aa0741305860d92dd64e26d 100644 --- a/CONTRIBUTING.adoc +++ b/CONTRIBUTING.adoc @@ -45,6 +45,21 @@ When reviewing a pull request, the end-goal is to suggest useful changes to the . There exists a somewhat cleaner/better/faster way of accomplishing the same feature/fix. . It does not fit well with some other contributors' longer-term vision for the project. +=== Updating Polkadot as well + +If your PR changes the external APIs or interfaces used by Polkadot, **a corresponding PR on Polkadot must** be submitted as well. If you tagged the PR with `breaksapi` or `breaksconsensus` this is most certainly the case, in all other cases check for it by running step 1. + +To update a corresponding Polkadot PR: + +0. Pull lastet Polkadot master (or clone it, if you haven't yet). +1. Replace `polkadot-master` in all `Cargo.toml` with the name of the PR-branch - e.g. by running `find . -name "Cargo.toml" -exec sed -i "s/polkadot-master/PR_BRANCH/g" {}` (and to your repo, if the branch is not on mainline); Commit this change. +2. Make the changes required to pass the build again. +3. Submit all this as a PR against the Polkadot Repo, link that new PR in the existing substrate PR for reference +4. Wait for reviews on both +5. Once both PRs have been green lit, merge the Substrate PR into master and sync the changes onto the `polkadot-master` on mainline (push it). Now revert that first commit in your Polkadot PR, reverting the name back to `polkadot-master`, push and wait for the CI to confirm all is fine. Then merge the Polkadot PR. + +As there might be multiple pending PRs that might conflict with one another, a) you should not merge the substrate PR until the Polkadot PR has also been reviewed and b) both should be merged pretty quickly after another to not block others. + == Helping out We use https://github.com/paritytech/substrate/labels[labels] to manage PRs and issues and communicate state of a PR. Please familiarize yourself with them. Furthermore we are organizing issues in https://github.com/paritytech/substrate/milestones[milestones]. Best way to get started is to a pick a ticket from the current milestone tagged https://github.com/paritytech/substrate/issues?q=is%3Aissue+is%3Aopen+label%3AQ2-easy[`easy`] or https://github.com/paritytech/substrate/issues?q=is%3Aissue+is%3Aopen+label%3AQ3-medium[`medium`] and get going or https://github.com/paritytech/substrate/issues?q=is%3Aissue+is%3Aopen+label%3AX1-mentor[`mentor`] and get in contact with the mentor offering their support on that larger task. diff --git a/Cargo.lock b/Cargo.lock index a207eb8ad95777d1644d8537bd50c3f24c8f6016..170ed9e2f1efb960451ea46ac1f1ed2df88ea710 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2,7 +2,7 @@ # It is not intended for manual editing. [[package]] name = "adler32" -version = "1.0.3" +version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] @@ -13,7 +13,7 @@ dependencies = [ "aes-soft 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", "aesni 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)", "ctr 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", - "stream-cipher 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", + "stream-cipher 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -23,7 +23,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "block-cipher-trait 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", "byteorder 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)", - "opaque-debug 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", + "opaque-debug 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -32,13 +32,21 @@ version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "block-cipher-trait 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", - "opaque-debug 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", - "stream-cipher 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", + "opaque-debug 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", + "stream-cipher 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "ahash" +version = "0.2.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "const-random 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "aho-corasick" -version = "0.7.4" +version = "0.7.6" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "memchr 2.2.1 (registry+https://github.com/rust-lang/crates.io-index)", @@ -46,12 +54,12 @@ dependencies = [ [[package]] name = "aio-limited" -version = "0.1.0" +version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "futures 0.1.28 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", - "parking_lot 0.5.5 (registry+https://github.com/rust-lang/crates.io-index)", + "futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", + "parking_lot 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-executor 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-io 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-timer 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", @@ -62,7 +70,15 @@ name = "ansi_term" version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "ansi_term" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -108,7 +124,7 @@ version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "quote 0.6.13 (registry+https://github.com/rust-lang/crates.io-index)", - "syn 0.15.42 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 0.15.44 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -121,24 +137,24 @@ name = "atty" version = "0.2.13" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "libc 0.2.60 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "autocfg" -version = "0.1.5" +version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "backtrace" -version = "0.3.33" +version = "0.3.38" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "backtrace-sys 0.1.31 (registry+https://github.com/rust-lang/crates.io-index)", - "cfg-if 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.60 (registry+https://github.com/rust-lang/crates.io-index)", - "rustc-demangle 0.1.15 (registry+https://github.com/rust-lang/crates.io-index)", + "cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)", + "rustc-demangle 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -146,8 +162,8 @@ name = "backtrace-sys" version = "0.1.31" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "cc 1.0.38 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.60 (registry+https://github.com/rust-lang/crates.io-index)", + "cc 1.0.45 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -161,7 +177,7 @@ version = "0.9.3" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "byteorder 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)", - "safemem 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", + "safemem 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -172,39 +188,30 @@ dependencies = [ "byteorder 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)", ] -[[package]] -name = "bigint" -version = "4.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "byteorder 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)", - "crunchy 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", -] - [[package]] name = "bindgen" version = "0.47.3" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "bitflags 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "bitflags 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "cexpr 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)", - "cfg-if 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)", + "cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", "clang-sys 0.26.4 (registry+https://github.com/rust-lang/crates.io-index)", "clap 2.32.0 (registry+https://github.com/rust-lang/crates.io-index)", "env_logger 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", "hashbrown 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", - "lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", + "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "peeking_take_while 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", "proc-macro2 0.4.30 (registry+https://github.com/rust-lang/crates.io-index)", "quote 0.6.13 (registry+https://github.com/rust-lang/crates.io-index)", - "regex 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "regex 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)", "which 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "bitflags" -version = "1.1.0" +version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] @@ -212,11 +219,6 @@ name = "bitmask" version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -[[package]] -name = "bitvec" -version = "0.11.3" -source = "registry+https://github.com/rust-lang/crates.io-index" - [[package]] name = "bitvec" version = "0.14.0" @@ -224,13 +226,13 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "blake2" -version = "0.8.0" +version = "0.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "byte-tools 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", "crypto-mac 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", "digest 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)", - "opaque-debug 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", + "opaque-debug 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -239,7 +241,7 @@ version = "0.2.18" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "arrayvec 0.4.11 (registry+https://github.com/rust-lang/crates.io-index)", - "constant_time_eq 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", + "constant_time_eq 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -280,18 +282,18 @@ dependencies = [ [[package]] name = "bs58" -version = "0.2.2" +version = "0.2.5" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "bstr" -version = "0.2.6" +version = "0.2.8" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", + "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "memchr 2.2.1 (registry+https://github.com/rust-lang/crates.io-index)", "regex-automata 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.97 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -304,7 +306,7 @@ dependencies = [ [[package]] name = "bumpalo" -version = "2.5.0" +version = "2.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] @@ -338,7 +340,7 @@ version = "0.4.12" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "byteorder 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)", - "either 1.5.2 (registry+https://github.com/rust-lang/crates.io-index)", + "either 1.5.3 (registry+https://github.com/rust-lang/crates.io-index)", "iovec 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -347,7 +349,7 @@ name = "c2-chacha" version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", + "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "ppv-lite86 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -358,13 +360,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "cargo_metadata" -version = "0.8.1" +version = "0.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "failure 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", "semver 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.97 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_derive 1.0.97 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_derive 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)", "serde_json 1.0.40 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -375,10 +376,11 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "cc" -version = "1.0.38" +version = "1.0.45" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "rayon 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "jobserver 0.1.17 (registry+https://github.com/rust-lang/crates.io-index)", + "num_cpus 1.10.1 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -391,7 +393,7 @@ dependencies = [ [[package]] name = "cfg-if" -version = "0.1.9" +version = "0.1.10" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] @@ -406,10 +408,10 @@ dependencies = [ [[package]] name = "chrono" -version = "0.4.7" +version = "0.4.9" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "libc 0.2.60 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)", "num-integer 0.1.41 (registry+https://github.com/rust-lang/crates.io-index)", "num-traits 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", "time 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)", @@ -421,7 +423,7 @@ version = "0.26.4" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "glob 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.60 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)", "libloading 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -432,10 +434,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "ansi_term 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)", "atty 0.2.13 (registry+https://github.com/rust-lang/crates.io-index)", - "bitflags 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "bitflags 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "strsim 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", "textwrap 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)", - "unicode-width 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", + "unicode-width 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", "vec_map 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)", "yaml-rust 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -445,7 +447,7 @@ name = "clear_on_drop" version = "0.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "cc 1.0.38 (registry+https://github.com/rust-lang/crates.io-index)", + "cc 1.0.45 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -453,20 +455,38 @@ name = "cloudabi" version = "0.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "bitflags 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "bitflags 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "cmake" -version = "0.1.40" +version = "0.1.42" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "cc 1.0.45 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "const-random" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "const-random-macro 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", + "proc-macro-hack 0.5.10 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "const-random-macro" +version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "cc 1.0.38 (registry+https://github.com/rust-lang/crates.io-index)", + "proc-macro-hack 0.5.10 (registry+https://github.com/rust-lang/crates.io-index)", + "rand 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "constant_time_eq" -version = "0.1.3" +version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] @@ -475,7 +495,7 @@ version = "0.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "core-foundation-sys 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.60 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -488,7 +508,7 @@ name = "crc32fast" version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "cfg-if 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)", + "cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -502,16 +522,16 @@ dependencies = [ "criterion-plot 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", "csv 1.1.1 (registry+https://github.com/rust-lang/crates.io-index)", "itertools 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", - "lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.60 (registry+https://github.com/rust-lang/crates.io-index)", + "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)", "num-traits 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", "rand_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", "rand_os 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", "rand_xoshiro 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "rayon 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "rayon-core 1.5.0 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.97 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_derive 1.0.97 (registry+https://github.com/rust-lang/crates.io-index)", + "rayon 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "rayon-core 1.6.0 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_derive 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)", "serde_json 1.0.40 (registry+https://github.com/rust-lang/crates.io-index)", "tinytemplate 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", "walkdir 2.2.9 (registry+https://github.com/rust-lang/crates.io-index)", @@ -535,15 +555,6 @@ dependencies = [ "crossbeam-utils 0.6.6 (registry+https://github.com/rust-lang/crates.io-index)", ] -[[package]] -name = "crossbeam-deque" -version = "0.6.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "crossbeam-epoch 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)", - "crossbeam-utils 0.6.6 (registry+https://github.com/rust-lang/crates.io-index)", -] - [[package]] name = "crossbeam-deque" version = "0.7.1" @@ -559,9 +570,9 @@ version = "0.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "arrayvec 0.4.11 (registry+https://github.com/rust-lang/crates.io-index)", - "cfg-if 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)", + "cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", "crossbeam-utils 0.6.6 (registry+https://github.com/rust-lang/crates.io-index)", - "lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", + "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "memoffset 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", "scopeguard 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -579,15 +590,10 @@ name = "crossbeam-utils" version = "0.6.6" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "cfg-if 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)", - "lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", + "cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", + "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", ] -[[package]] -name = "crunchy" -version = "0.1.6" -source = "registry+https://github.com/rust-lang/crates.io-index" - [[package]] name = "crunchy" version = "0.2.2" @@ -598,7 +604,7 @@ name = "crypto-mac" version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "constant_time_eq 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", + "constant_time_eq 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", "generic-array 0.8.3 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -616,11 +622,11 @@ name = "csv" version = "1.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "bstr 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)", + "bstr 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", "csv-core 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", "itoa 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)", "ryu 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.97 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -633,11 +639,11 @@ dependencies = [ [[package]] name = "ctor" -version = "0.1.9" +version = "0.1.12" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "quote 0.6.13 (registry+https://github.com/rust-lang/crates.io-index)", - "syn 0.15.42 (registry+https://github.com/rust-lang/crates.io-index)", + "quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -646,7 +652,7 @@ version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "block-cipher-trait 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", - "stream-cipher 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", + "stream-cipher 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -655,7 +661,7 @@ version = "3.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "nix 0.14.1 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -669,14 +675,14 @@ dependencies = [ [[package]] name = "curve25519-dalek" -version = "1.2.1" +version = "1.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "byteorder 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)", "clear_on_drop 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", "digest 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)", "rand_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", - "subtle 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "subtle 2.2.1 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -684,28 +690,17 @@ name = "data-encoding" version = "2.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -[[package]] -name = "derive_more" -version = "0.14.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "proc-macro2 0.4.30 (registry+https://github.com/rust-lang/crates.io-index)", - "quote 0.6.13 (registry+https://github.com/rust-lang/crates.io-index)", - "rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", - "syn 0.15.42 (registry+https://github.com/rust-lang/crates.io-index)", -] - [[package]] name = "derive_more" version = "0.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", + "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "proc-macro2 0.4.30 (registry+https://github.com/rust-lang/crates.io-index)", "quote 0.6.13 (registry+https://github.com/rust-lang/crates.io-index)", - "regex 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "regex 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)", "rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", - "syn 0.15.42 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 0.15.44 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -743,13 +738,24 @@ name = "doc-comment" version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "ed25519-dalek" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "clear_on_drop 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", + "curve25519-dalek 1.2.3 (registry+https://github.com/rust-lang/crates.io-index)", + "failure 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", + "rand 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "ed25519-dalek" version = "1.0.0-pre.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "clear_on_drop 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", - "curve25519-dalek 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)", + "curve25519-dalek 1.2.3 (registry+https://github.com/rust-lang/crates.io-index)", "failure 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", "rand 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", "sha2 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -757,7 +763,7 @@ dependencies = [ [[package]] name = "either" -version = "1.5.2" +version = "1.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] @@ -774,15 +780,15 @@ version = "0.6.2" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "atty 0.2.13 (registry+https://github.com/rust-lang/crates.io-index)", - "humantime 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", - "regex 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "humantime 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", + "regex 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)", "termcolor 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "environmental" -version = "1.0.1" +version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] @@ -790,7 +796,7 @@ name = "erased-serde" version = "0.3.9" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "serde 1.0.97 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -798,7 +804,7 @@ name = "error-chain" version = "0.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "backtrace 0.3.33 (registry+https://github.com/rust-lang/crates.io-index)", + "backtrace 0.3.38 (registry+https://github.com/rust-lang/crates.io-index)", "version_check 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -807,7 +813,7 @@ name = "exit-future" version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "futures 0.1.28 (registry+https://github.com/rust-lang/crates.io-index)", + "futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)", "parking_lot 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -816,7 +822,7 @@ name = "failure" version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "backtrace 0.3.33 (registry+https://github.com/rust-lang/crates.io-index)", + "backtrace 0.3.38 (registry+https://github.com/rust-lang/crates.io-index)", "failure_derive 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -827,7 +833,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "proc-macro2 0.4.30 (registry+https://github.com/rust-lang/crates.io-index)", "quote 0.6.13 (registry+https://github.com/rust-lang/crates.io-index)", - "syn 0.15.42 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 0.15.44 (registry+https://github.com/rust-lang/crates.io-index)", "synstructure 0.10.2 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -841,7 +847,7 @@ name = "fdlimit" version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "libc 0.2.60 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -849,11 +855,11 @@ name = "finality-grandpa" version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "futures 0.1.28 (registry+https://github.com/rust-lang/crates.io-index)", - "hashmap_core 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", + "futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)", + "hashmap_core 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "num-traits 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", - "parity-scale-codec 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", + "parity-scale-codec 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", "parking_lot 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -863,23 +869,28 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "byteorder 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.60 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)", "rand 0.5.6 (registry+https://github.com/rust-lang/crates.io-index)", "rustc-hex 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)", "static_assertions 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "fixedbitset" +version = "0.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "flate2" -version = "1.0.9" +version = "1.0.12" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ + "cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", "crc32fast 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", - "futures 0.1.28 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.60 (registry+https://github.com/rust-lang/crates.io-index)", + "futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)", "libz-sys 1.0.25 (registry+https://github.com/rust-lang/crates.io-index)", - "miniz-sys 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", - "miniz_oxide_c_api 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", + "miniz_oxide 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-io 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -905,7 +916,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" name = "fork-tree" version = "2.0.0" dependencies = [ - "parity-scale-codec 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", + "parity-scale-codec 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -913,10 +924,10 @@ name = "fs-swap" version = "0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.60 (registry+https://github.com/rust-lang/crates.io-index)", + "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)", "libloading 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -924,8 +935,8 @@ name = "fs2" version = "0.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "libc 0.2.60 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -938,7 +949,7 @@ name = "fuchsia-zircon" version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "bitflags 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "bitflags 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "fuchsia-zircon-sys 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -949,21 +960,21 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "futures" -version = "0.1.28" +version = "0.1.29" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "futures-channel-preview" -version = "0.3.0-alpha.17" +version = "0.3.0-alpha.19" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "futures-core-preview 0.3.0-alpha.17 (registry+https://github.com/rust-lang/crates.io-index)", - "futures-sink-preview 0.3.0-alpha.17 (registry+https://github.com/rust-lang/crates.io-index)", + "futures-core-preview 0.3.0-alpha.19 (registry+https://github.com/rust-lang/crates.io-index)", + "futures-sink-preview 0.3.0-alpha.19 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "futures-core-preview" -version = "0.3.0-alpha.17" +version = "0.3.0-alpha.19" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] @@ -971,66 +982,63 @@ name = "futures-cpupool" version = "0.1.8" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "futures 0.1.28 (registry+https://github.com/rust-lang/crates.io-index)", + "futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)", "num_cpus 1.10.1 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "futures-executor-preview" -version = "0.3.0-alpha.17" +version = "0.3.0-alpha.19" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "futures-channel-preview 0.3.0-alpha.17 (registry+https://github.com/rust-lang/crates.io-index)", - "futures-core-preview 0.3.0-alpha.17 (registry+https://github.com/rust-lang/crates.io-index)", - "futures-util-preview 0.3.0-alpha.17 (registry+https://github.com/rust-lang/crates.io-index)", + "futures-core-preview 0.3.0-alpha.19 (registry+https://github.com/rust-lang/crates.io-index)", + "futures-util-preview 0.3.0-alpha.19 (registry+https://github.com/rust-lang/crates.io-index)", "num_cpus 1.10.1 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "futures-io-preview" -version = "0.3.0-alpha.17" +version = "0.3.0-alpha.19" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "futures-preview" -version = "0.3.0-alpha.17" +version = "0.3.0-alpha.19" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "futures-channel-preview 0.3.0-alpha.17 (registry+https://github.com/rust-lang/crates.io-index)", - "futures-core-preview 0.3.0-alpha.17 (registry+https://github.com/rust-lang/crates.io-index)", - "futures-executor-preview 0.3.0-alpha.17 (registry+https://github.com/rust-lang/crates.io-index)", - "futures-io-preview 0.3.0-alpha.17 (registry+https://github.com/rust-lang/crates.io-index)", - "futures-sink-preview 0.3.0-alpha.17 (registry+https://github.com/rust-lang/crates.io-index)", - "futures-util-preview 0.3.0-alpha.17 (registry+https://github.com/rust-lang/crates.io-index)", + "futures-channel-preview 0.3.0-alpha.19 (registry+https://github.com/rust-lang/crates.io-index)", + "futures-core-preview 0.3.0-alpha.19 (registry+https://github.com/rust-lang/crates.io-index)", + "futures-executor-preview 0.3.0-alpha.19 (registry+https://github.com/rust-lang/crates.io-index)", + "futures-io-preview 0.3.0-alpha.19 (registry+https://github.com/rust-lang/crates.io-index)", + "futures-sink-preview 0.3.0-alpha.19 (registry+https://github.com/rust-lang/crates.io-index)", + "futures-util-preview 0.3.0-alpha.19 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "futures-sink-preview" -version = "0.3.0-alpha.17" +version = "0.3.0-alpha.19" source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "futures-core-preview 0.3.0-alpha.17 (registry+https://github.com/rust-lang/crates.io-index)", -] [[package]] name = "futures-timer" -version = "0.2.1" +version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "futures-preview 0.3.0-alpha.17 (registry+https://github.com/rust-lang/crates.io-index)", + "futures-core-preview 0.3.0-alpha.19 (registry+https://github.com/rust-lang/crates.io-index)", + "futures-util-preview 0.3.0-alpha.19 (registry+https://github.com/rust-lang/crates.io-index)", "pin-utils 0.1.0-alpha.4 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "futures-util-preview" -version = "0.3.0-alpha.17" +version = "0.3.0-alpha.19" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "futures 0.1.28 (registry+https://github.com/rust-lang/crates.io-index)", - "futures-channel-preview 0.3.0-alpha.17 (registry+https://github.com/rust-lang/crates.io-index)", - "futures-core-preview 0.3.0-alpha.17 (registry+https://github.com/rust-lang/crates.io-index)", - "futures-io-preview 0.3.0-alpha.17 (registry+https://github.com/rust-lang/crates.io-index)", - "futures-sink-preview 0.3.0-alpha.17 (registry+https://github.com/rust-lang/crates.io-index)", + "futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)", + "futures-channel-preview 0.3.0-alpha.19 (registry+https://github.com/rust-lang/crates.io-index)", + "futures-core-preview 0.3.0-alpha.19 (registry+https://github.com/rust-lang/crates.io-index)", + "futures-io-preview 0.3.0-alpha.19 (registry+https://github.com/rust-lang/crates.io-index)", + "futures-sink-preview 0.3.0-alpha.19 (registry+https://github.com/rust-lang/crates.io-index)", "memchr 2.2.1 (registry+https://github.com/rust-lang/crates.io-index)", "pin-utils 0.1.0-alpha.4 (registry+https://github.com/rust-lang/crates.io-index)", "slab 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1047,7 +1055,7 @@ version = "0.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "nodrop 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)", - "typenum 1.10.0 (registry+https://github.com/rust-lang/crates.io-index)", + "typenum 1.11.2 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1055,7 +1063,7 @@ name = "generic-array" version = "0.12.3" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "typenum 1.10.0 (registry+https://github.com/rust-lang/crates.io-index)", + "typenum 1.11.2 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1065,7 +1073,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "c_linked_list 1.1.1 (registry+https://github.com/rust-lang/crates.io-index)", "get_if_addrs-sys 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.60 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)", "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -1075,16 +1083,17 @@ version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "gcc 0.3.55 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.60 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "getrandom" -version = "0.1.6" +version = "0.1.12" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.60 (registry+https://github.com/rust-lang/crates.io-index)", + "cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)", + "wasi 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1102,11 +1111,11 @@ name = "globset" version = "0.4.4" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "aho-corasick 0.7.4 (registry+https://github.com/rust-lang/crates.io-index)", - "bstr 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)", + "aho-corasick 0.7.6 (registry+https://github.com/rust-lang/crates.io-index)", + "bstr 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", "fnv 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", - "regex 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", + "regex 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1117,10 +1126,10 @@ dependencies = [ "byteorder 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)", "bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)", "fnv 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", - "futures 0.1.28 (registry+https://github.com/rust-lang/crates.io-index)", - "http 0.1.17 (registry+https://github.com/rust-lang/crates.io-index)", - "indexmap 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", + "futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)", + "http 0.1.18 (registry+https://github.com/rust-lang/crates.io-index)", + "indexmap 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "slab 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", "string 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-io 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1128,12 +1137,12 @@ dependencies = [ [[package]] name = "hash-db" -version = "0.15.0" +version = "0.15.2" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "hash256-std-hasher" -version = "0.15.0" +version = "0.15.2" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "crunchy 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1148,9 +1157,18 @@ dependencies = [ "scopeguard 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "hashbrown" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "ahash 0.2.13 (registry+https://github.com/rust-lang/crates.io-index)", + "autocfg 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "hashmap_core" -version = "0.1.10" +version = "0.1.11" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] @@ -1158,7 +1176,7 @@ name = "heapsize" version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1176,19 +1194,19 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "hex-literal" -version = "0.2.0" +version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "hex-literal-impl 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", - "proc-macro-hack 0.5.8 (registry+https://github.com/rust-lang/crates.io-index)", + "hex-literal-impl 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", + "proc-macro-hack 0.5.10 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "hex-literal-impl" -version = "0.2.0" +version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "proc-macro-hack 0.5.8 (registry+https://github.com/rust-lang/crates.io-index)", + "proc-macro-hack 0.5.10 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1220,9 +1238,19 @@ dependencies = [ "hmac 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "hmac-drbg" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "digest 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)", + "generic-array 0.12.3 (registry+https://github.com/rust-lang/crates.io-index)", + "hmac 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "http" -version = "0.1.17" +version = "0.1.18" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1236,8 +1264,8 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)", - "futures 0.1.28 (registry+https://github.com/rust-lang/crates.io-index)", - "http 0.1.17 (registry+https://github.com/rust-lang/crates.io-index)", + "futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)", + "http 0.1.18 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-buf 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -1248,7 +1276,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "humantime" -version = "1.2.0" +version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "quick-error 1.2.2 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1274,19 +1302,19 @@ dependencies = [ [[package]] name = "hyper" -version = "0.12.33" +version = "0.12.35" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)", - "futures 0.1.28 (registry+https://github.com/rust-lang/crates.io-index)", + "futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)", "futures-cpupool 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", "h2 0.1.26 (registry+https://github.com/rust-lang/crates.io-index)", - "http 0.1.17 (registry+https://github.com/rust-lang/crates.io-index)", + "http 0.1.18 (registry+https://github.com/rust-lang/crates.io-index)", "http-body 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "httparse 1.3.4 (registry+https://github.com/rust-lang/crates.io-index)", "iovec 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", "itoa 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "net2 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)", "rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", "time 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1294,13 +1322,25 @@ dependencies = [ "tokio-buf 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-executor 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-io 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-reactor 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-reactor 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-tcp 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-threadpool 0.1.15 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-threadpool 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-timer 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", "want 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "hyper-tls" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)", + "futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)", + "hyper 0.12.35 (registry+https://github.com/rust-lang/crates.io-index)", + "native-tls 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-io 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "idna" version = "0.1.5" @@ -1311,34 +1351,45 @@ dependencies = [ "unicode-normalization 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "idna" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "matches 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", + "unicode-bidi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", + "unicode-normalization 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "impl-codec" -version = "0.4.0" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "parity-scale-codec 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", + "parity-scale-codec 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "impl-serde" -version = "0.1.1" +version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "rustc-hex 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.97 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] -name = "impl-serde" -version = "0.2.0" +name = "impl-trait-for-tuples" +version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "serde 1.0.97 (registry+https://github.com/rust-lang/crates.io-index)", + "proc-macro2 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", + "quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "indexmap" -version = "1.0.2" +version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] @@ -1356,7 +1407,7 @@ name = "iovec" version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "libc 0.2.60 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)", "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -1370,7 +1421,7 @@ name = "itertools" version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "either 1.5.2 (registry+https://github.com/rust-lang/crates.io-index)", + "either 1.5.3 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1378,114 +1429,125 @@ name = "itoa" version = "0.4.4" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "jobserver" +version = "0.1.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "getrandom 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "js-sys" -version = "0.3.25" +version = "0.3.28" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "wasm-bindgen 0.2.48 (registry+https://github.com/rust-lang/crates.io-index)", + "wasm-bindgen 0.2.51 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "jsonrpc-client-transports" -version = "12.1.0" +version = "13.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "failure 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", - "futures 0.1.28 (registry+https://github.com/rust-lang/crates.io-index)", - "hyper 0.12.33 (registry+https://github.com/rust-lang/crates.io-index)", - "jsonrpc-core 12.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "jsonrpc-pubsub 12.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.97 (registry+https://github.com/rust-lang/crates.io-index)", + "futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)", + "hyper 0.12.35 (registry+https://github.com/rust-lang/crates.io-index)", + "jsonrpc-core 13.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "jsonrpc-pubsub 13.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)", "serde_json 1.0.40 (registry+https://github.com/rust-lang/crates.io-index)", "tokio 0.1.22 (registry+https://github.com/rust-lang/crates.io-index)", - "websocket 0.22.4 (registry+https://github.com/rust-lang/crates.io-index)", + "url 1.7.2 (registry+https://github.com/rust-lang/crates.io-index)", + "websocket 0.23.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "jsonrpc-core" -version = "12.1.0" +version = "13.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "futures 0.1.28 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.97 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_derive 1.0.97 (registry+https://github.com/rust-lang/crates.io-index)", + "futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_derive 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)", "serde_json 1.0.40 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "jsonrpc-core-client" -version = "12.1.0" +version = "13.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "jsonrpc-client-transports 12.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "jsonrpc-client-transports 13.2.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "jsonrpc-derive" -version = "12.1.0" +version = "13.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "proc-macro-crate 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", "proc-macro2 0.4.30 (registry+https://github.com/rust-lang/crates.io-index)", "quote 0.6.13 (registry+https://github.com/rust-lang/crates.io-index)", - "syn 0.15.42 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 0.15.44 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "jsonrpc-http-server" -version = "12.1.0" +version = "13.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "hyper 0.12.33 (registry+https://github.com/rust-lang/crates.io-index)", - "jsonrpc-core 12.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "jsonrpc-server-utils 12.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", + "hyper 0.12.35 (registry+https://github.com/rust-lang/crates.io-index)", + "jsonrpc-core 13.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "jsonrpc-server-utils 13.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "net2 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)", - "parking_lot 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", - "unicase 2.4.0 (registry+https://github.com/rust-lang/crates.io-index)", + "parking_lot 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", + "unicase 2.5.1 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "jsonrpc-pubsub" -version = "12.1.0" +version = "13.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "jsonrpc-core 12.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", - "parking_lot 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.97 (registry+https://github.com/rust-lang/crates.io-index)", + "jsonrpc-core 13.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", + "parking_lot 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "jsonrpc-server-utils" -version = "12.1.0" +version = "13.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)", "globset 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)", - "jsonrpc-core 12.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", + "jsonrpc-core 13.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "num_cpus 1.10.1 (registry+https://github.com/rust-lang/crates.io-index)", "tokio 0.1.22 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-codec 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", - "unicase 2.4.0 (registry+https://github.com/rust-lang/crates.io-index)", + "unicase 2.5.1 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "jsonrpc-ws-server" -version = "12.1.0" +version = "13.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "jsonrpc-core 12.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "jsonrpc-server-utils 12.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", - "parking_lot 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", + "jsonrpc-core 13.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "jsonrpc-server-utils 13.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", + "parking_lot 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", "slab 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", - "ws 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)", + "ws 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1495,11 +1557,11 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "keccak-hasher" -version = "0.15.0" +version = "0.15.2" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "hash-db 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)", - "hash256-std-hasher 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)", + "hash-db 0.15.2 (registry+https://github.com/rust-lang/crates.io-index)", + "hash256-std-hasher 0.15.2 (registry+https://github.com/rust-lang/crates.io-index)", "tiny-keccak 1.5.0 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -1539,10 +1601,10 @@ dependencies = [ "fs-swap 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)", "interleaved-ordered 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", "kvdb 0.1.0 (git+https://github.com/paritytech/parity-common?rev=b0317f649ab2c665b7987b8475878fc4d2e1f81d)", - "log 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "num_cpus 1.10.1 (registry+https://github.com/rust-lang/crates.io-index)", "parking_lot 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)", - "regex 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "regex 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)", "rocksdb 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -1553,11 +1615,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "lazy_static" -version = "1.3.0" +version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "spin 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", -] [[package]] name = "lazycell" @@ -1566,7 +1625,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "libc" -version = "0.2.60" +version = "0.2.62" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] @@ -1574,38 +1633,38 @@ name = "libloading" version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "cc 1.0.38 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", + "cc 1.0.45 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "libp2p" -version = "0.11.0" +version = "0.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)", - "futures 0.1.28 (registry+https://github.com/rust-lang/crates.io-index)", - "lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", - "libp2p-core 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)", - "libp2p-core-derive 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)", - "libp2p-deflate 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", - "libp2p-dns 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)", - "libp2p-floodsub 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)", - "libp2p-identify 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)", - "libp2p-kad 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)", - "libp2p-mdns 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)", - "libp2p-mplex 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)", - "libp2p-noise 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", - "libp2p-ping 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)", - "libp2p-plaintext 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)", - "libp2p-ratelimit 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)", - "libp2p-secio 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)", - "libp2p-swarm 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "libp2p-tcp 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)", - "libp2p-uds 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)", - "libp2p-wasm-ext 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", - "libp2p-websocket 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)", - "libp2p-yamux 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)", + "futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)", + "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", + "libp2p-core 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)", + "libp2p-core-derive 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)", + "libp2p-deflate 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", + "libp2p-dns 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)", + "libp2p-floodsub 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)", + "libp2p-identify 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)", + "libp2p-kad 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)", + "libp2p-mdns 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)", + "libp2p-mplex 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)", + "libp2p-noise 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)", + "libp2p-ping 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)", + "libp2p-plaintext 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)", + "libp2p-ratelimit 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)", + "libp2p-secio 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)", + "libp2p-swarm 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "libp2p-tcp 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)", + "libp2p-uds 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)", + "libp2p-wasm-ext 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", + "libp2p-websocket 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)", + "libp2p-yamux 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)", "parity-multiaddr 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", "parity-multihash 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", "parking_lot 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1618,24 +1677,24 @@ dependencies = [ [[package]] name = "libp2p-core" -version = "0.11.0" +version = "0.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "asn1_der 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", - "bs58 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", + "bs58 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)", "bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)", "ed25519-dalek 1.0.0-pre.1 (registry+https://github.com/rust-lang/crates.io-index)", "failure 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", "fnv 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", - "futures 0.1.28 (registry+https://github.com/rust-lang/crates.io-index)", - "lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", + "futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)", + "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "libsecp256k1 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", - "multistream-select 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", + "multistream-select 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", "parity-multiaddr 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", "parity-multihash 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", "parking_lot 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", - "protobuf 2.8.0 (registry+https://github.com/rust-lang/crates.io-index)", + "protobuf 2.8.1 (registry+https://github.com/rust-lang/crates.io-index)", "quick-error 1.2.2 (registry+https://github.com/rust-lang/crates.io-index)", "rand 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", "ring 0.14.6 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1648,53 +1707,53 @@ dependencies = [ "untrusted 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", "void 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", "wasm-timer 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", - "zeroize 0.9.2 (registry+https://github.com/rust-lang/crates.io-index)", + "zeroize 0.9.3 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "libp2p-core-derive" -version = "0.11.0" +version = "0.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "quote 0.6.13 (registry+https://github.com/rust-lang/crates.io-index)", - "syn 0.15.42 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 0.15.44 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "libp2p-deflate" -version = "0.3.0" +version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "flate2 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)", - "futures 0.1.28 (registry+https://github.com/rust-lang/crates.io-index)", - "libp2p-core 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)", + "flate2 1.0.12 (registry+https://github.com/rust-lang/crates.io-index)", + "futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)", + "libp2p-core 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-io 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "libp2p-dns" -version = "0.11.0" +version = "0.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "futures 0.1.28 (registry+https://github.com/rust-lang/crates.io-index)", - "libp2p-core 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", + "futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)", + "libp2p-core 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-dns-unofficial 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "libp2p-floodsub" -version = "0.11.0" +version = "0.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "bs58 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", + "bs58 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)", "bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)", "cuckoofilter 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", "fnv 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", - "futures 0.1.28 (registry+https://github.com/rust-lang/crates.io-index)", - "libp2p-core 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)", - "libp2p-swarm 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "protobuf 2.8.0 (registry+https://github.com/rust-lang/crates.io-index)", + "futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)", + "libp2p-core 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)", + "libp2p-swarm 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "protobuf 2.8.1 (registry+https://github.com/rust-lang/crates.io-index)", "rand 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", "smallvec 0.6.10 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-io 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1702,16 +1761,16 @@ dependencies = [ [[package]] name = "libp2p-identify" -version = "0.11.0" +version = "0.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)", - "futures 0.1.28 (registry+https://github.com/rust-lang/crates.io-index)", - "libp2p-core 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)", - "libp2p-swarm 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", + "futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)", + "libp2p-core 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)", + "libp2p-swarm 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "parity-multiaddr 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", - "protobuf 2.8.0 (registry+https://github.com/rust-lang/crates.io-index)", + "protobuf 2.8.1 (registry+https://github.com/rust-lang/crates.io-index)", "smallvec 0.6.10 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-codec 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-io 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1722,26 +1781,26 @@ dependencies = [ [[package]] name = "libp2p-kad" -version = "0.11.0" +version = "0.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "arrayvec 0.4.11 (registry+https://github.com/rust-lang/crates.io-index)", - "bigint 4.4.1 (registry+https://github.com/rust-lang/crates.io-index)", "bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)", - "either 1.5.2 (registry+https://github.com/rust-lang/crates.io-index)", + "either 1.5.3 (registry+https://github.com/rust-lang/crates.io-index)", "fnv 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", - "futures 0.1.28 (registry+https://github.com/rust-lang/crates.io-index)", - "libp2p-core 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)", - "libp2p-swarm 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", + "futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)", + "libp2p-core 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)", + "libp2p-swarm 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "parity-multiaddr 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", "parity-multihash 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", - "protobuf 2.8.0 (registry+https://github.com/rust-lang/crates.io-index)", + "protobuf 2.8.1 (registry+https://github.com/rust-lang/crates.io-index)", "rand 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", "sha2 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", "smallvec 0.6.10 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-codec 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-io 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", + "uint 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)", "unsigned-varint 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", "void 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", "wasm-timer 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1749,36 +1808,36 @@ dependencies = [ [[package]] name = "libp2p-mdns" -version = "0.11.0" +version = "0.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "data-encoding 2.1.2 (registry+https://github.com/rust-lang/crates.io-index)", "dns-parser 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", - "futures 0.1.28 (registry+https://github.com/rust-lang/crates.io-index)", - "libp2p-core 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)", - "libp2p-swarm 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", + "futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)", + "libp2p-core 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)", + "libp2p-swarm 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "net2 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)", "parity-multiaddr 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", "rand 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", "smallvec 0.6.10 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-io 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-reactor 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-udp 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-reactor 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-udp 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", "void 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", "wasm-timer 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "libp2p-mplex" -version = "0.11.0" +version = "0.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)", "fnv 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", - "futures 0.1.28 (registry+https://github.com/rust-lang/crates.io-index)", - "libp2p-core 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", + "futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)", + "libp2p-core 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "parking_lot 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-codec 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-io 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1787,34 +1846,34 @@ dependencies = [ [[package]] name = "libp2p-noise" -version = "0.9.0" +version = "0.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)", - "curve25519-dalek 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)", - "futures 0.1.28 (registry+https://github.com/rust-lang/crates.io-index)", - "lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", - "libp2p-core 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", - "protobuf 2.8.0 (registry+https://github.com/rust-lang/crates.io-index)", + "curve25519-dalek 1.2.3 (registry+https://github.com/rust-lang/crates.io-index)", + "futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)", + "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", + "libp2p-core 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", + "protobuf 2.8.1 (registry+https://github.com/rust-lang/crates.io-index)", "rand 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", "ring 0.14.6 (registry+https://github.com/rust-lang/crates.io-index)", "snow 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-io 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", "x25519-dalek 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)", - "zeroize 0.9.2 (registry+https://github.com/rust-lang/crates.io-index)", + "zeroize 0.9.3 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "libp2p-ping" -version = "0.11.0" +version = "0.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)", - "futures 0.1.28 (registry+https://github.com/rust-lang/crates.io-index)", - "libp2p-core 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)", - "libp2p-swarm 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", + "futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)", + "libp2p-core 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)", + "libp2p-swarm 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "parity-multiaddr 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", "rand 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-io 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1824,44 +1883,44 @@ dependencies = [ [[package]] name = "libp2p-plaintext" -version = "0.11.0" +version = "0.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "futures 0.1.28 (registry+https://github.com/rust-lang/crates.io-index)", - "libp2p-core 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)", + "futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)", + "libp2p-core 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)", "void 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "libp2p-ratelimit" -version = "0.11.0" +version = "0.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "aio-limited 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "aio-limited 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", "bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)", - "futures 0.1.28 (registry+https://github.com/rust-lang/crates.io-index)", - "libp2p-core 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", + "futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)", + "libp2p-core 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-executor 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-io 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "libp2p-secio" -version = "0.11.0" +version = "0.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "aes-ctr 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)", "ctr 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", - "futures 0.1.28 (registry+https://github.com/rust-lang/crates.io-index)", + "futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)", "hmac 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)", - "js-sys 0.3.25 (registry+https://github.com/rust-lang/crates.io-index)", - "lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", - "libp2p-core 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", + "js-sys 0.3.28 (registry+https://github.com/rust-lang/crates.io-index)", + "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", + "libp2p-core 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "parity-send-wrapper 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "protobuf 2.8.0 (registry+https://github.com/rust-lang/crates.io-index)", + "protobuf 2.8.1 (registry+https://github.com/rust-lang/crates.io-index)", "rand 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", "ring 0.14.6 (registry+https://github.com/rust-lang/crates.io-index)", "rw-stream-sink 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1869,18 +1928,18 @@ dependencies = [ "tokio-io 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", "twofish 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "untrusted 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", - "wasm-bindgen 0.2.48 (registry+https://github.com/rust-lang/crates.io-index)", - "wasm-bindgen-futures 0.3.25 (registry+https://github.com/rust-lang/crates.io-index)", - "web-sys 0.3.25 (registry+https://github.com/rust-lang/crates.io-index)", + "wasm-bindgen 0.2.51 (registry+https://github.com/rust-lang/crates.io-index)", + "wasm-bindgen-futures 0.3.27 (registry+https://github.com/rust-lang/crates.io-index)", + "web-sys 0.3.28 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "libp2p-swarm" -version = "0.1.0" +version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "futures 0.1.28 (registry+https://github.com/rust-lang/crates.io-index)", - "libp2p-core 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)", + "futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)", + "libp2p-core 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)", "smallvec 0.6.10 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-io 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", "void 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1889,56 +1948,56 @@ dependencies = [ [[package]] name = "libp2p-tcp" -version = "0.11.0" +version = "0.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)", - "futures 0.1.28 (registry+https://github.com/rust-lang/crates.io-index)", + "futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)", "get_if_addrs 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)", "ipnet 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)", - "libp2p-core 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", - "tk-listen 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", + "libp2p-core 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-io 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-tcp 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-timer 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "libp2p-uds" -version = "0.11.0" +version = "0.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "futures 0.1.28 (registry+https://github.com/rust-lang/crates.io-index)", - "libp2p-core 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", + "futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)", + "libp2p-core 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-uds 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "libp2p-wasm-ext" -version = "0.4.0" +version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "futures 0.1.28 (registry+https://github.com/rust-lang/crates.io-index)", - "js-sys 0.3.25 (registry+https://github.com/rust-lang/crates.io-index)", - "libp2p-core 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)", + "futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)", + "js-sys 0.3.28 (registry+https://github.com/rust-lang/crates.io-index)", + "libp2p-core 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)", "parity-send-wrapper 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-io 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", - "wasm-bindgen 0.2.48 (registry+https://github.com/rust-lang/crates.io-index)", - "wasm-bindgen-futures 0.3.25 (registry+https://github.com/rust-lang/crates.io-index)", + "wasm-bindgen 0.2.51 (registry+https://github.com/rust-lang/crates.io-index)", + "wasm-bindgen-futures 0.3.27 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "libp2p-websocket" -version = "0.11.0" +version = "0.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)", - "futures 0.1.28 (registry+https://github.com/rust-lang/crates.io-index)", - "libp2p-core 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", + "futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)", + "libp2p-core 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "rw-stream-sink 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", - "soketto 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", + "soketto 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-codec 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-io 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-rustls 0.10.0-alpha.4 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1948,12 +2007,12 @@ dependencies = [ [[package]] name = "libp2p-yamux" -version = "0.11.0" +version = "0.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "futures 0.1.28 (registry+https://github.com/rust-lang/crates.io-index)", - "libp2p-core 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", + "futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)", + "libp2p-core 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-io 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", "yamux 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -1964,9 +2023,9 @@ version = "5.18.3" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "bindgen 0.47.3 (registry+https://github.com/rust-lang/crates.io-index)", - "cc 1.0.38 (registry+https://github.com/rust-lang/crates.io-index)", + "cc 1.0.45 (registry+https://github.com/rust-lang/crates.io-index)", "glob 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.60 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1979,7 +2038,20 @@ dependencies = [ "hmac-drbg 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", "rand 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", "sha2 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)", - "typenum 1.10.0 (registry+https://github.com/rust-lang/crates.io-index)", + "typenum 1.11.2 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "libsecp256k1" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "arrayref 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)", + "digest 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)", + "hmac-drbg 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "rand 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", + "sha2 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", + "typenum 1.11.2 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1987,9 +2059,9 @@ name = "libz-sys" version = "1.0.25" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "cc 1.0.38 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.60 (registry+https://github.com/rust-lang/crates.io-index)", - "pkg-config 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)", + "cc 1.0.45 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)", + "pkg-config 0.3.16 (registry+https://github.com/rust-lang/crates.io-index)", "vcpkg 0.2.7 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -2036,15 +2108,15 @@ name = "log" version = "0.3.9" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "log 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "log" -version = "0.4.7" +version = "0.4.8" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "cfg-if 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)", + "cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -2061,7 +2133,7 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "proc-macro2 0.4.30 (registry+https://github.com/rust-lang/crates.io-index)", - "syn 0.15.42 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 0.15.44 (registry+https://github.com/rust-lang/crates.io-index)", "synstructure 0.10.2 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -2075,7 +2147,7 @@ name = "memchr" version = "2.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "libc 0.2.60 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -2088,11 +2160,11 @@ dependencies = [ [[package]] name = "memory-db" -version = "0.15.0" +version = "0.15.2" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "hash-db 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)", - "hashmap_core 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", + "hash-db 0.15.2 (registry+https://github.com/rust-lang/crates.io-index)", + "hashbrown 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)", "parity-util-mem 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -2103,13 +2175,13 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "merlin" -version = "1.2.0" +version = "1.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "byteorder 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)", "clear_on_drop 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", "keccak 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "rand_core 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", + "rand_core 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -2120,32 +2192,12 @@ dependencies = [ "log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", ] -[[package]] -name = "miniz-sys" -version = "0.1.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "cc 1.0.38 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.60 (registry+https://github.com/rust-lang/crates.io-index)", -] - [[package]] name = "miniz_oxide" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "adler32 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "miniz_oxide_c_api" -version = "0.2.3" +version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "cc 1.0.38 (registry+https://github.com/rust-lang/crates.io-index)", - "crc32fast 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.60 (registry+https://github.com/rust-lang/crates.io-index)", - "miniz_oxide 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", + "adler32 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -2157,8 +2209,8 @@ dependencies = [ "fuchsia-zircon-sys 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", "iovec 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", "kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.60 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "miow 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", "net2 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)", "slab 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2171,7 +2223,7 @@ version = "2.0.5" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "lazycell 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "mio 0.6.19 (registry+https://github.com/rust-lang/crates.io-index)", "slab 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -2182,7 +2234,7 @@ version = "0.6.7" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "iovec 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.60 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)", "mio 0.6.19 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -2198,15 +2250,19 @@ dependencies = [ ] [[package]] -name = "multistream-select" +name = "multimap" version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "multistream-select" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)", - "futures 0.1.28 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", + "futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "smallvec 0.6.10 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-codec 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-io 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", "unsigned-varint 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -2224,13 +2280,13 @@ name = "native-tls" version = "0.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.60 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", + "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "openssl 0.10.24 (registry+https://github.com/rust-lang/crates.io-index)", "openssl-probe 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", - "openssl-sys 0.9.48 (registry+https://github.com/rust-lang/crates.io-index)", - "schannel 0.1.15 (registry+https://github.com/rust-lang/crates.io-index)", + "openssl-sys 0.9.49 (registry+https://github.com/rust-lang/crates.io-index)", + "schannel 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)", "security-framework 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", "security-framework-sys 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", "tempfile 3.1.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2241,9 +2297,9 @@ name = "net2" version = "0.2.33" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "cfg-if 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.60 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", + "cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -2251,10 +2307,10 @@ name = "nix" version = "0.14.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "bitflags 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "cc 1.0.38 (registry+https://github.com/rust-lang/crates.io-index)", - "cfg-if 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.60 (registry+https://github.com/rust-lang/crates.io-index)", + "bitflags 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "cc 1.0.45 (registry+https://github.com/rust-lang/crates.io-index)", + "cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)", "void 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -2263,17 +2319,21 @@ name = "node-cli" version = "2.0.0" dependencies = [ "exit-future 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", - "futures 0.1.28 (registry+https://github.com/rust-lang/crates.io-index)", - "futures-preview 0.3.0-alpha.17 (registry+https://github.com/rust-lang/crates.io-index)", - "hex-literal 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", + "futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)", + "futures-preview 0.3.0-alpha.19 (registry+https://github.com/rust-lang/crates.io-index)", + "hex-literal 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", + "jsonrpc-core 13.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "node-executor 2.0.0", "node-primitives 2.0.0", + "node-rpc 2.0.0", "node-runtime 2.0.0", - "parity-scale-codec 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", - "rand 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", + "parity-scale-codec 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", + "rand 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)", "sr-io 2.0.0", "sr-primitives 2.0.0", + "srml-authority-discovery 0.1.0", "srml-balances 2.0.0", "srml-contracts 2.0.0", "srml-finality-tracker 2.0.0", @@ -2283,9 +2343,12 @@ dependencies = [ "srml-system 2.0.0", "srml-timestamp 2.0.0", "structopt 0.2.18 (registry+https://github.com/rust-lang/crates.io-index)", + "substrate-authority-discovery 2.0.0", "substrate-basic-authorship 2.0.0", + "substrate-chain-spec 2.0.0", "substrate-cli 2.0.0", "substrate-client 2.0.0", + "substrate-client-db 2.0.0", "substrate-consensus-babe 2.0.0", "substrate-consensus-babe-primitives 2.0.0", "substrate-consensus-common 2.0.0", @@ -2295,7 +2358,9 @@ dependencies = [ "substrate-keyring 2.0.0", "substrate-keystore 2.0.0", "substrate-network 2.0.0", + "substrate-offchain 2.0.0", "substrate-primitives 2.0.0", + "substrate-rpc 2.0.0", "substrate-service 2.0.0", "substrate-service-test 2.0.0", "substrate-telemetry 2.0.0", @@ -2311,7 +2376,8 @@ version = "2.0.0" dependencies = [ "node-primitives 2.0.0", "node-runtime 2.0.0", - "parity-scale-codec 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", + "node-testing 2.0.0", + "parity-scale-codec 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", "sr-io 2.0.0", "sr-primitives 2.0.0", "srml-balances 2.0.0", @@ -2319,60 +2385,85 @@ dependencies = [ "srml-grandpa 2.0.0", "srml-indices 2.0.0", "srml-session 2.0.0", - "srml-staking 2.0.0", "srml-support 2.0.0", "srml-system 2.0.0", "srml-timestamp 2.0.0", "srml-treasury 2.0.0", "substrate-executor 2.0.0", - "substrate-keyring 2.0.0", "substrate-primitives 2.0.0", "substrate-state-machine 2.0.0", "substrate-test-client 2.0.0", "substrate-trie 2.0.0", - "trie-root 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)", - "wabt 0.7.4 (registry+https://github.com/rust-lang/crates.io-index)", + "trie-root 0.15.2 (registry+https://github.com/rust-lang/crates.io-index)", + "wabt 0.9.2 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "node-primitives" version = "2.0.0" dependencies = [ - "parity-scale-codec 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", + "parity-scale-codec 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", "pretty_assertions 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.97 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)", "sr-primitives 2.0.0", "sr-std 2.0.0", + "substrate-client 2.0.0", "substrate-primitives 2.0.0", "substrate-serializer 2.0.0", ] [[package]] -name = "node-rpc-client" +name = "node-rpc" version = "2.0.0" dependencies = [ "env_logger 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", - "futures 0.1.28 (registry+https://github.com/rust-lang/crates.io-index)", - "hyper 0.12.33 (registry+https://github.com/rust-lang/crates.io-index)", - "jsonrpc-core-client 12.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", + "futures-preview 0.3.0-alpha.19 (registry+https://github.com/rust-lang/crates.io-index)", + "jsonrpc-core 13.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "jsonrpc-core-client 13.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "jsonrpc-derive 13.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "jsonrpc-pubsub 13.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "node-primitives 2.0.0", - "substrate-rpc 2.0.0", -] - -[[package]] + "node-runtime 2.0.0", + "node-testing 2.0.0", + "parity-scale-codec 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)", + "sr-primitives 2.0.0", + "substrate-client 2.0.0", + "substrate-keyring 2.0.0", + "substrate-primitives 2.0.0", + "substrate-rpc-primitives 2.0.0", + "substrate-transaction-pool 2.0.0", +] + +[[package]] +name = "node-rpc-client" +version = "2.0.0" +dependencies = [ + "env_logger 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", + "futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)", + "hyper 0.12.35 (registry+https://github.com/rust-lang/crates.io-index)", + "jsonrpc-core-client 13.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", + "node-primitives 2.0.0", + "substrate-rpc 2.0.0", +] + +[[package]] name = "node-runtime" version = "2.0.0" dependencies = [ "integer-sqrt 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", "node-primitives 2.0.0", - "parity-scale-codec 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", + "parity-scale-codec 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", "rustc-hex 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)", "safe-mix 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.97 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)", "sr-primitives 2.0.0", + "sr-staking-primitives 2.0.0", "sr-std 2.0.0", "sr-version 2.0.0", + "srml-authority-discovery 0.1.0", "srml-authorship 0.1.0", "srml-babe 2.0.0", "srml-balances 2.0.0", @@ -2386,21 +2477,24 @@ dependencies = [ "srml-im-online 0.1.0", "srml-indices 2.0.0", "srml-membership 2.0.0", + "srml-offences 1.0.0", "srml-session 2.0.0", "srml-staking 2.0.0", + "srml-staking-reward-curve 2.0.0", "srml-sudo 2.0.0", "srml-support 2.0.0", "srml-system 2.0.0", "srml-timestamp 2.0.0", "srml-treasury 2.0.0", + "srml-utility 2.0.0", + "substrate-authority-discovery-primitives 2.0.0", "substrate-client 2.0.0", "substrate-consensus-babe-primitives 2.0.0", - "substrate-consensus-common-primitives 2.0.0", "substrate-keyring 2.0.0", "substrate-offchain-primitives 2.0.0", "substrate-primitives 2.0.0", "substrate-session 2.0.0", - "substrate-wasm-builder-runner 1.0.2", + "substrate-wasm-builder-runner 1.0.3", ] [[package]] @@ -2408,20 +2502,21 @@ name = "node-template" version = "2.0.0" dependencies = [ "ctrlc 3.1.3 (registry+https://github.com/rust-lang/crates.io-index)", - "derive_more 0.14.1 (registry+https://github.com/rust-lang/crates.io-index)", + "derive_more 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)", "exit-future 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", - "futures 0.1.28 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", + "futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "node-template-runtime 2.0.0", - "parity-scale-codec 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", + "parity-scale-codec 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", "parking_lot 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", "sr-io 2.0.0", "substrate-basic-authorship 2.0.0", "substrate-cli 2.0.0", "substrate-client 2.0.0", - "substrate-consensus-aura 2.0.0", - "substrate-consensus-aura-primitives 2.0.0", + "substrate-consensus-babe 2.0.0", + "substrate-consensus-babe-primitives 2.0.0", "substrate-executor 2.0.0", + "substrate-finality-grandpa 2.0.0", "substrate-finality-grandpa-primitives 2.0.0", "substrate-inherents 2.0.0", "substrate-network 2.0.0", @@ -2429,7 +2524,7 @@ dependencies = [ "substrate-service 2.0.0", "substrate-transaction-pool 2.0.0", "tokio 0.1.22 (registry+https://github.com/rust-lang/crates.io-index)", - "trie-root 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)", + "trie-root 0.15.2 (registry+https://github.com/rust-lang/crates.io-index)", "vergen 3.0.4 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -2437,27 +2532,56 @@ dependencies = [ name = "node-template-runtime" version = "2.0.0" dependencies = [ - "parity-scale-codec 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", + "parity-scale-codec 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", "safe-mix 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.97 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)", "sr-io 2.0.0", "sr-primitives 2.0.0", "sr-std 2.0.0", "sr-version 2.0.0", - "srml-aura 2.0.0", + "srml-babe 2.0.0", "srml-balances 2.0.0", "srml-executive 2.0.0", + "srml-grandpa 2.0.0", "srml-indices 2.0.0", "srml-sudo 2.0.0", "srml-support 2.0.0", "srml-system 2.0.0", "srml-timestamp 2.0.0", "substrate-client 2.0.0", - "substrate-consensus-aura-primitives 2.0.0", + "substrate-consensus-babe-primitives 2.0.0", "substrate-offchain-primitives 2.0.0", "substrate-primitives 2.0.0", "substrate-session 2.0.0", - "substrate-wasm-builder-runner 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", + "substrate-wasm-builder-runner 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "node-testing" +version = "2.0.0" +dependencies = [ + "node-executor 2.0.0", + "node-primitives 2.0.0", + "node-runtime 2.0.0", + "parity-scale-codec 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", + "sr-io 2.0.0", + "sr-primitives 2.0.0", + "srml-balances 2.0.0", + "srml-contracts 2.0.0", + "srml-grandpa 2.0.0", + "srml-indices 2.0.0", + "srml-session 2.0.0", + "srml-staking 2.0.0", + "srml-support 2.0.0", + "srml-system 2.0.0", + "srml-timestamp 2.0.0", + "srml-treasury 2.0.0", + "substrate-client 2.0.0", + "substrate-executor 2.0.0", + "substrate-keyring 2.0.0", + "substrate-primitives 2.0.0", + "substrate-test-client 2.0.0", + "wabt 0.9.2 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -2467,7 +2591,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "nohash-hasher" -version = "0.1.1" +version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] @@ -2481,9 +2605,10 @@ dependencies = [ [[package]] name = "num-bigint" -version = "0.2.2" +version = "0.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ + "autocfg 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", "num-integer 0.1.41 (registry+https://github.com/rust-lang/crates.io-index)", "num-traits 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -2493,7 +2618,7 @@ name = "num-integer" version = "0.1.41" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "autocfg 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", + "autocfg 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", "num-traits 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -2502,8 +2627,8 @@ name = "num-rational" version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "autocfg 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", - "num-bigint 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", + "autocfg 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", + "num-bigint 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", "num-integer 0.1.41 (registry+https://github.com/rust-lang/crates.io-index)", "num-traits 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -2513,7 +2638,7 @@ name = "num-traits" version = "0.2.8" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "autocfg 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", + "autocfg 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -2521,7 +2646,7 @@ name = "num_cpus" version = "1.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "libc 0.2.60 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -2541,9 +2666,14 @@ dependencies = [ "parking_lot 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "once_cell" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "opaque-debug" -version = "0.2.2" +version = "0.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] @@ -2551,12 +2681,12 @@ name = "openssl" version = "0.10.24" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "bitflags 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "cfg-if 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)", + "bitflags 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", "foreign-types 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", - "lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.60 (registry+https://github.com/rust-lang/crates.io-index)", - "openssl-sys 0.9.48 (registry+https://github.com/rust-lang/crates.io-index)", + "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)", + "openssl-sys 0.9.49 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -2566,13 +2696,13 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "openssl-sys" -version = "0.9.48" +version = "0.9.49" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "autocfg 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", - "cc 1.0.38 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.60 (registry+https://github.com/rust-lang/crates.io-index)", - "pkg-config 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)", + "autocfg 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", + "cc 1.0.45 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)", + "pkg-config 0.3.16 (registry+https://github.com/rust-lang/crates.io-index)", "vcpkg 0.2.7 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -2581,15 +2711,7 @@ name = "output_vt100" version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "owning_ref" -version = "0.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "stable_deref_trait 1.1.1 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -2605,29 +2727,19 @@ name = "parity-bytes" version = "0.1.0" source = "git+https://github.com/paritytech/parity-common?rev=b0317f649ab2c665b7987b8475878fc4d2e1f81d#b0317f649ab2c665b7987b8475878fc4d2e1f81d" -[[package]] -name = "parity-codec" -version = "4.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "arrayvec 0.4.11 (registry+https://github.com/rust-lang/crates.io-index)", - "bitvec 0.11.3 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.97 (registry+https://github.com/rust-lang/crates.io-index)", -] - [[package]] name = "parity-multiaddr" version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "arrayref 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)", - "bs58 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", + "bs58 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)", "byteorder 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)", "bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)", "data-encoding 2.1.2 (registry+https://github.com/rust-lang/crates.io-index)", "parity-multihash 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", "percent-encoding 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.97 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)", "unsigned-varint 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", "url 1.7.2 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -2637,7 +2749,7 @@ name = "parity-multihash" version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "blake2 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", + "blake2 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)", "bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)", "rand 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", "sha-1 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2648,26 +2760,25 @@ dependencies = [ [[package]] name = "parity-scale-codec" -version = "1.0.4" +version = "1.0.6" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "arrayvec 0.4.11 (registry+https://github.com/rust-lang/crates.io-index)", "bitvec 0.14.0 (registry+https://github.com/rust-lang/crates.io-index)", "byte-slice-cast 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", - "parity-scale-codec-derive 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.97 (registry+https://github.com/rust-lang/crates.io-index)", - "vecarray 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", + "parity-scale-codec-derive 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "parity-scale-codec-derive" -version = "1.0.2" +version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "proc-macro-crate 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", "proc-macro2 0.4.30 (registry+https://github.com/rust-lang/crates.io-index)", "quote 0.6.13 (registry+https://github.com/rust-lang/crates.io-index)", - "syn 0.15.42 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 0.15.44 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -2680,27 +2791,15 @@ name = "parity-util-mem" version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "cfg-if 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)", + "cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", "malloc_size_of_derive 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "parity-wasm" -version = "0.31.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "byteorder 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "parking_lot" -version = "0.5.5" +version = "0.40.3" source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "owning_ref 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", - "parking_lot_core 0.2.14 (registry+https://github.com/rust-lang/crates.io-index)", -] [[package]] name = "parking_lot" @@ -2740,27 +2839,16 @@ dependencies = [ "rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", ] -[[package]] -name = "parking_lot_core" -version = "0.2.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "libc 0.2.60 (registry+https://github.com/rust-lang/crates.io-index)", - "rand 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", - "smallvec 0.6.10 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", -] - [[package]] name = "parking_lot_core" version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "libc 0.2.60 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)", "rand 0.5.6 (registry+https://github.com/rust-lang/crates.io-index)", "rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", "smallvec 0.6.10 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -2768,11 +2856,11 @@ name = "parking_lot_core" version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "libc 0.2.60 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)", "rand 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", "rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", "smallvec 0.6.10 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -2780,14 +2868,14 @@ name = "parking_lot_core" version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "cfg-if 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)", + "cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", "cloudabi 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.60 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)", "rand 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", "redox_syscall 0.1.56 (registry+https://github.com/rust-lang/crates.io-index)", "rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", "smallvec 0.6.10 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -2795,33 +2883,33 @@ name = "parking_lot_core" version = "0.6.2" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "cfg-if 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)", + "cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", "cloudabi 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.60 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)", "redox_syscall 0.1.56 (registry+https://github.com/rust-lang/crates.io-index)", "rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", "smallvec 0.6.10 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "paste" -version = "0.1.5" +version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "paste-impl 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", - "proc-macro-hack 0.5.8 (registry+https://github.com/rust-lang/crates.io-index)", + "paste-impl 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", + "proc-macro-hack 0.5.10 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "paste-impl" -version = "0.1.5" +version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "proc-macro-hack 0.5.8 (registry+https://github.com/rust-lang/crates.io-index)", - "proc-macro2 0.4.30 (registry+https://github.com/rust-lang/crates.io-index)", - "quote 0.6.13 (registry+https://github.com/rust-lang/crates.io-index)", - "syn 0.15.42 (registry+https://github.com/rust-lang/crates.io-index)", + "proc-macro-hack 0.5.10 (registry+https://github.com/rust-lang/crates.io-index)", + "proc-macro2 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", + "quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -2833,6 +2921,11 @@ dependencies = [ "crypto-mac 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "pdqselect" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "peeking_take_while" version = "0.1.2" @@ -2843,6 +2936,19 @@ name = "percent-encoding" version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "percent-encoding" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "petgraph" +version = "0.4.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "fixedbitset 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "pin-utils" version = "0.1.0-alpha.4" @@ -2850,7 +2956,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "pkg-config" -version = "0.3.15" +version = "0.3.16" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] @@ -2864,20 +2970,20 @@ version = "0.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "ansi_term 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)", - "ctor 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)", + "ctor 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", "difference 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "output_vt100 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "primitive-types" -version = "0.5.0" +version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "fixed-hash 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", - "impl-codec 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", - "impl-serde 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", - "uint 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", + "impl-codec 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", + "impl-serde 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", + "uint 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -2885,17 +2991,17 @@ name = "proc-macro-crate" version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "toml 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", + "toml 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "proc-macro-hack" -version = "0.5.8" +version = "0.5.10" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "proc-macro2 0.4.30 (registry+https://github.com/rust-lang/crates.io-index)", - "quote 0.6.13 (registry+https://github.com/rust-lang/crates.io-index)", - "syn 0.15.42 (registry+https://github.com/rust-lang/crates.io-index)", + "proc-macro2 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", + "quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -2906,19 +3012,75 @@ dependencies = [ "unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "proc-macro2" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "unicode-xid 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "prost" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "byteorder 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)", + "bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)", + "prost-derive 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "prost-build" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)", + "heck 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", + "itertools 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", + "multimap 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", + "petgraph 0.4.13 (registry+https://github.com/rust-lang/crates.io-index)", + "prost 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", + "prost-types 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", + "tempfile 3.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "which 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "prost-derive" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "failure 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", + "itertools 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", + "proc-macro2 0.4.30 (registry+https://github.com/rust-lang/crates.io-index)", + "quote 0.6.13 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 0.15.44 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "prost-types" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)", + "prost 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "protobuf" -version = "2.8.0" +version = "2.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "pwasm-utils" -version = "0.6.2" +version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "byteorder 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", - "parity-wasm 0.31.3 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", + "parity-wasm 0.40.3 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -2933,13 +3095,13 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "quickcheck" -version = "0.8.5" +version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "env_logger 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", - "rand 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", - "rand_core 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", + "rand 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)", + "rand_core 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -2950,12 +3112,20 @@ dependencies = [ "proc-macro2 0.4.30 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "quote" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "proc-macro2 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "rand" version = "0.3.23" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "libc 0.2.60 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)", "rand 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -2965,10 +3135,10 @@ version = "0.4.6" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "fuchsia-cprng 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.60 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)", "rand_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", "rdrand 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -2978,9 +3148,9 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "cloudabi 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)", "fuchsia-cprng 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.60 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)", "rand_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -2988,28 +3158,28 @@ name = "rand" version = "0.6.5" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "autocfg 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.60 (registry+https://github.com/rust-lang/crates.io-index)", + "autocfg 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)", "rand_chacha 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", - "rand_core 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", + "rand_core 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", "rand_hc 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "rand_isaac 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", "rand_jitter 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", "rand_os 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", "rand_pcg 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", "rand_xorshift 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "rand" -version = "0.7.0" +version = "0.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "getrandom 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.60 (registry+https://github.com/rust-lang/crates.io-index)", + "getrandom 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)", "rand_chacha 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", - "rand_core 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", + "rand_core 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", "rand_hc 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -3018,7 +3188,7 @@ name = "rand_chacha" version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "autocfg 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", + "autocfg 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", "rand_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -3028,7 +3198,7 @@ version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "c2-chacha 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", - "rand_core 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", + "rand_core 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -3036,20 +3206,20 @@ name = "rand_core" version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "rand_core 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", + "rand_core 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "rand_core" -version = "0.4.0" +version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "rand_core" -version = "0.5.0" +version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "getrandom 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", + "getrandom 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -3065,7 +3235,7 @@ name = "rand_hc" version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "rand_core 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", + "rand_core 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -3081,9 +3251,9 @@ name = "rand_jitter" version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "libc 0.2.60 (registry+https://github.com/rust-lang/crates.io-index)", - "rand_core 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)", + "rand_core 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -3093,10 +3263,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "cloudabi 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)", "fuchsia-cprng 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.60 (registry+https://github.com/rust-lang/crates.io-index)", - "rand_core 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)", + "rand_core 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", "rdrand 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -3104,8 +3274,8 @@ name = "rand_pcg" version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "autocfg 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", - "rand_core 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", + "autocfg 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", + "rand_core 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -3127,23 +3297,23 @@ dependencies = [ [[package]] name = "rayon" -version = "1.1.0" +version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "crossbeam-deque 0.6.3 (registry+https://github.com/rust-lang/crates.io-index)", - "either 1.5.2 (registry+https://github.com/rust-lang/crates.io-index)", - "rayon-core 1.5.0 (registry+https://github.com/rust-lang/crates.io-index)", + "crossbeam-deque 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)", + "either 1.5.3 (registry+https://github.com/rust-lang/crates.io-index)", + "rayon-core 1.6.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "rayon-core" -version = "1.5.0" +version = "1.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "crossbeam-deque 0.6.3 (registry+https://github.com/rust-lang/crates.io-index)", + "crossbeam-deque 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)", "crossbeam-queue 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", "crossbeam-utils 0.6.6 (registry+https://github.com/rust-lang/crates.io-index)", - "lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", + "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "num_cpus 1.10.1 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -3167,14 +3337,13 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "regex" -version = "1.2.0" +version = "1.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "aho-corasick 0.7.4 (registry+https://github.com/rust-lang/crates.io-index)", + "aho-corasick 0.7.6 (registry+https://github.com/rust-lang/crates.io-index)", "memchr 2.2.1 (registry+https://github.com/rust-lang/crates.io-index)", - "regex-syntax 0.6.10 (registry+https://github.com/rust-lang/crates.io-index)", + "regex-syntax 0.6.12 (registry+https://github.com/rust-lang/crates.io-index)", "thread_local 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", - "utf8-ranges 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -3187,18 +3356,15 @@ dependencies = [ [[package]] name = "regex-syntax" -version = "0.6.10" +version = "0.6.12" source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "ucd-util 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", -] [[package]] name = "remove_dir_all" version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -3207,9 +3373,9 @@ version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "error-chain 0.12.1 (registry+https://github.com/rust-lang/crates.io-index)", - "futures 0.1.28 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", - "parity-scale-codec 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", + "futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", + "parity-scale-codec 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -3217,12 +3383,12 @@ name = "ring" version = "0.14.6" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "cc 1.0.38 (registry+https://github.com/rust-lang/crates.io-index)", - "lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.60 (registry+https://github.com/rust-lang/crates.io-index)", - "spin 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", + "cc 1.0.45 (registry+https://github.com/rust-lang/crates.io-index)", + "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)", + "spin 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)", "untrusted 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -3230,23 +3396,22 @@ name = "rocksdb" version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "libc 0.2.60 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)", "librocksdb-sys 5.18.3 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "rpassword" -version = "3.0.2" +version = "4.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.60 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "rustc-demangle" -version = "0.1.15" +version = "0.1.16" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] @@ -3268,20 +3433,30 @@ version = "0.15.2" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "base64 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "ring 0.14.6 (registry+https://github.com/rust-lang/crates.io-index)", "sct 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", "untrusted 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", "webpki 0.19.1 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "rustversion" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "proc-macro2 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", + "quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "rw-stream-sink" version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)", - "futures 0.1.28 (registry+https://github.com/rust-lang/crates.io-index)", + "futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-io 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -3300,7 +3475,7 @@ dependencies = [ [[package]] name = "safemem" -version = "0.3.0" +version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] @@ -3313,26 +3488,27 @@ dependencies = [ [[package]] name = "schannel" -version = "0.1.15" +version = "0.1.16" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", + "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "schnorrkel" -version = "0.8.4" +version = "0.8.5" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "curve25519-dalek 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)", - "ed25519-dalek 1.0.0-pre.1 (registry+https://github.com/rust-lang/crates.io-index)", + "curve25519-dalek 1.2.3 (registry+https://github.com/rust-lang/crates.io-index)", "failure 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", - "merlin 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "merlin 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)", "rand 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", + "rand_core 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", + "rand_os 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", "sha2 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", - "subtle 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "zeroize 0.9.2 (registry+https://github.com/rust-lang/crates.io-index)", + "subtle 2.2.1 (registry+https://github.com/rust-lang/crates.io-index)", + "zeroize 0.9.3 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -3361,7 +3537,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "core-foundation 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)", "core-foundation-sys 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.60 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)", "security-framework-sys 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -3387,7 +3563,7 @@ version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "semver-parser 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.97 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -3402,20 +3578,20 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "serde" -version = "1.0.97" +version = "1.0.101" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "serde_derive 1.0.97 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_derive 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "serde_derive" -version = "1.0.97" +version = "1.0.101" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "proc-macro2 0.4.30 (registry+https://github.com/rust-lang/crates.io-index)", - "quote 0.6.13 (registry+https://github.com/rust-lang/crates.io-index)", - "syn 0.15.42 (registry+https://github.com/rust-lang/crates.io-index)", + "proc-macro2 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", + "quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -3425,7 +3601,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "itoa 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)", "ryu 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.97 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -3436,7 +3612,7 @@ dependencies = [ "block-buffer 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)", "digest 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)", "fake-simd 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", - "opaque-debug 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", + "opaque-debug 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -3464,7 +3640,7 @@ dependencies = [ "block-buffer 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)", "digest 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)", "fake-simd 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", - "opaque-debug 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", + "opaque-debug 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -3476,7 +3652,7 @@ dependencies = [ "byte-tools 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", "digest 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)", "keccak 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "opaque-debug 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", + "opaque-debug 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -3517,9 +3693,9 @@ name = "slog-json" version = "2.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "chrono 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", + "chrono 0.4.9 (registry+https://github.com/rust-lang/crates.io-index)", "erased-serde 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.97 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)", "serde_json 1.0.40 (registry+https://github.com/rust-lang/crates.io-index)", "slog 2.5.2 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -3530,7 +3706,7 @@ version = "4.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "arc-swap 0.3.11 (registry+https://github.com/rust-lang/crates.io-index)", - "lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", + "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "slog 2.5.2 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -3541,7 +3717,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "proc-macro2 0.4.30 (registry+https://github.com/rust-lang/crates.io-index)", "quote 0.6.13 (registry+https://github.com/rust-lang/crates.io-index)", - "syn 0.15.42 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 0.15.44 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -3558,26 +3734,26 @@ dependencies = [ "byteorder 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)", "failure 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", "failure_derive 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", - "rand_core 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", + "rand_core 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", "ring 0.14.6 (registry+https://github.com/rust-lang/crates.io-index)", "rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", "smallvec 0.6.10 (registry+https://github.com/rust-lang/crates.io-index)", "static_slice 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)", - "subtle 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "subtle 2.2.1 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "soketto" -version = "0.2.2" +version = "0.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "base64 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)", "bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)", - "flate2 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)", - "futures 0.1.28 (registry+https://github.com/rust-lang/crates.io-index)", - "http 0.1.17 (registry+https://github.com/rust-lang/crates.io-index)", + "flate2 1.0.12 (registry+https://github.com/rust-lang/crates.io-index)", + "futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)", + "http 0.1.18 (registry+https://github.com/rust-lang/crates.io-index)", "httparse 1.3.4 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "rand 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", "sha1 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)", "smallvec 0.6.10 (registry+https://github.com/rust-lang/crates.io-index)", @@ -3592,7 +3768,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "spin" -version = "0.5.0" +version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] @@ -3601,10 +3777,11 @@ version = "2.0.0" dependencies = [ "blake2-rfc 0.2.18 (registry+https://github.com/rust-lang/crates.io-index)", "criterion 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", - "parity-scale-codec 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", + "parity-scale-codec 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", "proc-macro-crate 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", "proc-macro2 0.4.30 (registry+https://github.com/rust-lang/crates.io-index)", "quote 0.6.13 (registry+https://github.com/rust-lang/crates.io-index)", + "rustversion 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", "sr-primitives 2.0.0", "sr-version 2.0.0", "substrate-client 2.0.0", @@ -3612,21 +3789,20 @@ dependencies = [ "substrate-primitives 2.0.0", "substrate-state-machine 2.0.0", "substrate-test-runtime-client 2.0.0", - "syn 0.15.42 (registry+https://github.com/rust-lang/crates.io-index)", - "trybuild 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 0.15.44 (registry+https://github.com/rust-lang/crates.io-index)", + "trybuild 1.0.15 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "sr-io" version = "2.0.0" dependencies = [ - "environmental 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", - "hash-db 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)", - "libsecp256k1 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", - "parity-scale-codec 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", + "environmental 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", + "hash-db 0.15.2 (registry+https://github.com/rust-lang/crates.io-index)", + "libsecp256k1 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", + "parity-scale-codec 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", "rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", "sr-std 2.0.0", - "substrate-offchain 2.0.0", "substrate-primitives 2.0.0", "substrate-state-machine 2.0.0", "substrate-trie 2.0.0", @@ -3637,18 +3813,20 @@ dependencies = [ name = "sr-primitives" version = "2.0.0" dependencies = [ + "impl-trait-for-tuples 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", "integer-sqrt 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "num-traits 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", - "parity-scale-codec 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", - "paste 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", - "primitive-types 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", - "rand 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.97 (registry+https://github.com/rust-lang/crates.io-index)", + "parity-scale-codec 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", + "paste 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", + "primitive-types 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", + "rand 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)", "serde_json 1.0.40 (registry+https://github.com/rust-lang/crates.io-index)", "sr-io 2.0.0", "sr-std 2.0.0", "substrate-application-crypto 2.0.0", + "substrate-offchain 2.0.0", "substrate-primitives 2.0.0", ] @@ -3657,12 +3835,21 @@ name = "sr-sandbox" version = "2.0.0" dependencies = [ "assert_matches 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", - "parity-scale-codec 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", + "parity-scale-codec 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", "rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", "sr-std 2.0.0", "substrate-primitives 2.0.0", - "wabt 0.7.4 (registry+https://github.com/rust-lang/crates.io-index)", - "wasmi 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", + "wabt 0.9.2 (registry+https://github.com/rust-lang/crates.io-index)", + "wasmi 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "sr-staking-primitives" +version = "2.0.0" +dependencies = [ + "parity-scale-codec 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", + "sr-primitives 2.0.0", + "sr-std 2.0.0", ] [[package]] @@ -3676,9 +3863,9 @@ dependencies = [ name = "sr-version" version = "2.0.0" dependencies = [ - "impl-serde 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", - "parity-scale-codec 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.97 (registry+https://github.com/rust-lang/crates.io-index)", + "impl-serde 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", + "parity-scale-codec 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)", "sr-primitives 2.0.0", "sr-std 2.0.0", ] @@ -3687,8 +3874,8 @@ dependencies = [ name = "srml-assets" version = "2.0.0" dependencies = [ - "parity-scale-codec 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.97 (registry+https://github.com/rust-lang/crates.io-index)", + "parity-scale-codec 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)", "sr-io 2.0.0", "sr-primitives 2.0.0", "sr-std 2.0.0", @@ -3701,15 +3888,14 @@ dependencies = [ name = "srml-aura" version = "2.0.0" dependencies = [ - "lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", - "parity-scale-codec 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", + "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", + "parity-scale-codec 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", "parking_lot 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.97 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)", "sr-io 2.0.0", "sr-primitives 2.0.0", "sr-std 2.0.0", "srml-session 2.0.0", - "srml-staking 2.0.0", "srml-support 2.0.0", "srml-system 2.0.0", "srml-timestamp 2.0.0", @@ -3719,11 +3905,30 @@ dependencies = [ "substrate-primitives 2.0.0", ] +[[package]] +name = "srml-authority-discovery" +version = "0.1.0" +dependencies = [ + "parity-scale-codec 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)", + "sr-io 2.0.0", + "sr-primitives 2.0.0", + "sr-staking-primitives 2.0.0", + "sr-std 2.0.0", + "srml-session 2.0.0", + "srml-support 2.0.0", + "srml-system 2.0.0", + "substrate-application-crypto 2.0.0", + "substrate-consensus-babe-primitives 2.0.0", + "substrate-primitives 2.0.0", +] + [[package]] name = "srml-authorship" version = "0.1.0" dependencies = [ - "parity-scale-codec 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", + "impl-trait-for-tuples 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", + "parity-scale-codec 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", "sr-io 2.0.0", "sr-primitives 2.0.0", "sr-std 2.0.0", @@ -3737,31 +3942,33 @@ dependencies = [ name = "srml-babe" version = "2.0.0" dependencies = [ - "hex-literal 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", - "lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", - "parity-scale-codec 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", + "hex-literal 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", + "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", + "parity-scale-codec 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", "parking_lot 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.97 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)", "sr-io 2.0.0", "sr-primitives 2.0.0", + "sr-staking-primitives 2.0.0", "sr-std 2.0.0", + "sr-version 2.0.0", "srml-session 2.0.0", - "srml-staking 2.0.0", "srml-support 2.0.0", "srml-system 2.0.0", "srml-timestamp 2.0.0", "substrate-consensus-babe-primitives 2.0.0", "substrate-inherents 2.0.0", "substrate-primitives 2.0.0", + "substrate-test-runtime 2.0.0", ] [[package]] name = "srml-balances" version = "2.0.0" dependencies = [ - "parity-scale-codec 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", + "parity-scale-codec 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", "safe-mix 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.97 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)", "sr-io 2.0.0", "sr-primitives 2.0.0", "sr-std 2.0.0", @@ -3775,10 +3982,10 @@ dependencies = [ name = "srml-collective" version = "2.0.0" dependencies = [ - "hex-literal 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", - "parity-scale-codec 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", + "hex-literal 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", + "parity-scale-codec 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", "safe-mix 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.97 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)", "sr-io 2.0.0", "sr-primitives 2.0.0", "sr-std 2.0.0", @@ -3794,11 +4001,11 @@ version = "2.0.0" dependencies = [ "assert_matches 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "hex 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", - "hex-literal 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", - "parity-scale-codec 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", - "parity-wasm 0.31.3 (registry+https://github.com/rust-lang/crates.io-index)", - "pwasm-utils 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.97 (registry+https://github.com/rust-lang/crates.io-index)", + "hex-literal 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", + "parity-scale-codec 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", + "parity-wasm 0.40.3 (registry+https://github.com/rust-lang/crates.io-index)", + "pwasm-utils 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)", "sr-io 2.0.0", "sr-primitives 2.0.0", "sr-sandbox 2.0.0", @@ -3808,17 +4015,17 @@ dependencies = [ "srml-system 2.0.0", "srml-timestamp 2.0.0", "substrate-primitives 2.0.0", - "wabt 0.7.4 (registry+https://github.com/rust-lang/crates.io-index)", - "wasmi-validation 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "wabt 0.9.2 (registry+https://github.com/rust-lang/crates.io-index)", + "wasmi-validation 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "srml-democracy" version = "2.0.0" dependencies = [ - "parity-scale-codec 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", + "parity-scale-codec 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", "safe-mix 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.97 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)", "sr-io 2.0.0", "sr-primitives 2.0.0", "sr-std 2.0.0", @@ -3832,10 +4039,10 @@ dependencies = [ name = "srml-elections" version = "2.0.0" dependencies = [ - "hex-literal 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", - "parity-scale-codec 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", + "hex-literal 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", + "parity-scale-codec 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", "safe-mix 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.97 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)", "sr-io 2.0.0", "sr-primitives 2.0.0", "sr-std 2.0.0", @@ -3845,14 +4052,32 @@ dependencies = [ "substrate-primitives 2.0.0", ] +[[package]] +name = "srml-elections-phragmen" +version = "2.0.0" +dependencies = [ + "hex-literal 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", + "parity-scale-codec 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)", + "sr-io 2.0.0", + "sr-primitives 2.0.0", + "sr-std 2.0.0", + "srml-balances 2.0.0", + "srml-support 2.0.0", + "srml-system 2.0.0", + "substrate-phragmen 2.0.0", + "substrate-primitives 2.0.0", +] + [[package]] name = "srml-example" version = "2.0.0" dependencies = [ - "parity-scale-codec 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.97 (registry+https://github.com/rust-lang/crates.io-index)", + "parity-scale-codec 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)", "sr-io 2.0.0", "sr-primitives 2.0.0", + "sr-std 2.0.0", "srml-balances 2.0.0", "srml-support 2.0.0", "srml-system 2.0.0", @@ -3863,9 +4088,9 @@ dependencies = [ name = "srml-executive" version = "2.0.0" dependencies = [ - "hex-literal 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", - "parity-scale-codec 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.97 (registry+https://github.com/rust-lang/crates.io-index)", + "hex-literal 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", + "parity-scale-codec 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)", "sr-io 2.0.0", "sr-primitives 2.0.0", "sr-std 2.0.0", @@ -3880,8 +4105,9 @@ dependencies = [ name = "srml-finality-tracker" version = "2.0.0" dependencies = [ - "parity-scale-codec 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.97 (registry+https://github.com/rust-lang/crates.io-index)", + "impl-trait-for-tuples 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", + "parity-scale-codec 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)", "sr-io 2.0.0", "sr-primitives 2.0.0", "sr-std 2.0.0", @@ -3895,8 +4121,8 @@ dependencies = [ name = "srml-generic-asset" version = "2.0.0" dependencies = [ - "parity-scale-codec 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.97 (registry+https://github.com/rust-lang/crates.io-index)", + "parity-scale-codec 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)", "sr-io 2.0.0", "sr-primitives 2.0.0", "sr-std 2.0.0", @@ -3909,10 +4135,11 @@ dependencies = [ name = "srml-grandpa" version = "2.0.0" dependencies = [ - "parity-scale-codec 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.97 (registry+https://github.com/rust-lang/crates.io-index)", + "parity-scale-codec 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)", "sr-io 2.0.0", "sr-primitives 2.0.0", + "sr-staking-primitives 2.0.0", "sr-std 2.0.0", "srml-finality-tracker 2.0.0", "srml-session 2.0.0", @@ -3926,15 +4153,17 @@ dependencies = [ name = "srml-im-online" version = "0.1.0" dependencies = [ - "parity-scale-codec 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.97 (registry+https://github.com/rust-lang/crates.io-index)", + "parity-scale-codec 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)", "sr-io 2.0.0", "sr-primitives 2.0.0", + "sr-staking-primitives 2.0.0", "sr-std 2.0.0", "srml-session 2.0.0", "srml-support 2.0.0", "srml-system 2.0.0", "substrate-application-crypto 2.0.0", + "substrate-offchain 2.0.0", "substrate-primitives 2.0.0", ] @@ -3942,10 +4171,10 @@ dependencies = [ name = "srml-indices" version = "2.0.0" dependencies = [ - "parity-scale-codec 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", + "parity-scale-codec 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", "ref_thread_local 0.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "safe-mix 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.97 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)", "sr-io 2.0.0", "sr-primitives 2.0.0", "sr-std 2.0.0", @@ -3959,8 +4188,8 @@ dependencies = [ name = "srml-membership" version = "2.0.0" dependencies = [ - "parity-scale-codec 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.97 (registry+https://github.com/rust-lang/crates.io-index)", + "parity-scale-codec 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)", "sr-io 2.0.0", "sr-primitives 2.0.0", "sr-std 2.0.0", @@ -3973,9 +4202,40 @@ dependencies = [ name = "srml-metadata" version = "2.0.0" dependencies = [ - "parity-scale-codec 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.97 (registry+https://github.com/rust-lang/crates.io-index)", + "parity-scale-codec 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)", + "sr-std 2.0.0", + "substrate-primitives 2.0.0", +] + +[[package]] +name = "srml-offences" +version = "1.0.0" +dependencies = [ + "parity-scale-codec 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)", + "sr-io 2.0.0", + "sr-primitives 2.0.0", + "sr-staking-primitives 2.0.0", + "sr-std 2.0.0", + "srml-balances 2.0.0", + "srml-support 2.0.0", + "srml-system 2.0.0", + "substrate-primitives 2.0.0", +] + +[[package]] +name = "srml-scored-pool" +version = "1.0.0" +dependencies = [ + "parity-scale-codec 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)", + "sr-io 2.0.0", + "sr-primitives 2.0.0", "sr-std 2.0.0", + "srml-balances 2.0.0", + "srml-support 2.0.0", + "srml-system 2.0.0", "substrate-primitives 2.0.0", ] @@ -3983,12 +4243,14 @@ dependencies = [ name = "srml-session" version = "2.0.0" dependencies = [ - "lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", - "parity-scale-codec 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", + "impl-trait-for-tuples 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", + "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", + "parity-scale-codec 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", "safe-mix 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.97 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)", "sr-io 2.0.0", "sr-primitives 2.0.0", + "sr-staking-primitives 2.0.0", "sr-std 2.0.0", "srml-support 2.0.0", "srml-system 2.0.0", @@ -4002,34 +4264,46 @@ dependencies = [ name = "srml-staking" version = "2.0.0" dependencies = [ - "parity-scale-codec 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", - "rand 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", + "parity-scale-codec 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", "safe-mix 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.97 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)", "sr-io 2.0.0", "sr-primitives 2.0.0", + "sr-staking-primitives 2.0.0", "sr-std 2.0.0", "srml-authorship 0.1.0", "srml-balances 2.0.0", "srml-session 2.0.0", + "srml-staking-reward-curve 2.0.0", "srml-support 2.0.0", "srml-system 2.0.0", "srml-timestamp 2.0.0", "substrate-keyring 2.0.0", + "substrate-phragmen 2.0.0", "substrate-primitives 2.0.0", ] +[[package]] +name = "srml-staking-reward-curve" +version = "2.0.0" +dependencies = [ + "proc-macro-crate 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", + "proc-macro2 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", + "quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", + "sr-primitives 2.0.0", + "syn 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "srml-sudo" version = "2.0.0" dependencies = [ - "parity-scale-codec 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.97 (registry+https://github.com/rust-lang/crates.io-index)", + "parity-scale-codec 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)", "sr-io 2.0.0", "sr-primitives 2.0.0", "sr-std 2.0.0", "srml-support 2.0.0", - "srml-support-procedural 2.0.0", "srml-system 2.0.0", "substrate-primitives 2.0.0", ] @@ -4039,11 +4313,12 @@ name = "srml-support" version = "2.0.0" dependencies = [ "bitmask 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", - "once_cell 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", - "parity-scale-codec 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", - "paste 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", + "impl-trait-for-tuples 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", + "once_cell 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)", + "parity-scale-codec 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", + "paste 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", "pretty_assertions 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.97 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)", "sr-io 2.0.0", "sr-primitives 2.0.0", "sr-std 2.0.0", @@ -4062,7 +4337,7 @@ dependencies = [ "quote 0.6.13 (registry+https://github.com/rust-lang/crates.io-index)", "sr-api-macros 2.0.0", "srml-support-procedural-tools 2.0.0", - "syn 0.15.42 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 0.15.44 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -4073,7 +4348,7 @@ dependencies = [ "proc-macro2 0.4.30 (registry+https://github.com/rust-lang/crates.io-index)", "quote 0.6.13 (registry+https://github.com/rust-lang/crates.io-index)", "srml-support-procedural-tools-derive 2.0.0", - "syn 0.15.42 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 0.15.44 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -4082,21 +4357,21 @@ version = "2.0.0" dependencies = [ "proc-macro2 0.4.30 (registry+https://github.com/rust-lang/crates.io-index)", "quote 0.6.13 (registry+https://github.com/rust-lang/crates.io-index)", - "syn 0.15.42 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 0.15.44 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "srml-support-test" version = "2.0.0" dependencies = [ - "parity-scale-codec 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", + "parity-scale-codec 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", "pretty_assertions 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.97 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)", "sr-io 2.0.0", "srml-support 2.0.0", "substrate-inherents 2.0.0", "substrate-primitives 2.0.0", - "trybuild 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)", + "trybuild 1.0.15 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -4104,12 +4379,14 @@ name = "srml-system" version = "2.0.0" dependencies = [ "criterion 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", - "parity-scale-codec 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", + "impl-trait-for-tuples 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", + "parity-scale-codec 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", "safe-mix 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.97 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)", "sr-io 2.0.0", "sr-primitives 2.0.0", "sr-std 2.0.0", + "sr-version 2.0.0", "srml-support 2.0.0", "substrate-primitives 2.0.0", ] @@ -4118,8 +4395,9 @@ dependencies = [ name = "srml-timestamp" version = "2.0.0" dependencies = [ - "parity-scale-codec 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.97 (registry+https://github.com/rust-lang/crates.io-index)", + "impl-trait-for-tuples 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", + "parity-scale-codec 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)", "sr-io 2.0.0", "sr-primitives 2.0.0", "sr-std 2.0.0", @@ -4133,8 +4411,23 @@ dependencies = [ name = "srml-treasury" version = "2.0.0" dependencies = [ - "parity-scale-codec 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.97 (registry+https://github.com/rust-lang/crates.io-index)", + "parity-scale-codec 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)", + "sr-io 2.0.0", + "sr-primitives 2.0.0", + "sr-std 2.0.0", + "srml-balances 2.0.0", + "srml-support 2.0.0", + "srml-system 2.0.0", + "substrate-primitives 2.0.0", +] + +[[package]] +name = "srml-utility" +version = "2.0.0" +dependencies = [ + "parity-scale-codec 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)", "sr-io 2.0.0", "sr-primitives 2.0.0", "sr-std 2.0.0", @@ -4161,7 +4454,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "stream-cipher" -version = "0.3.0" +version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "generic-array 0.12.3 (registry+https://github.com/rust-lang/crates.io-index)", @@ -4197,7 +4490,7 @@ dependencies = [ "heck 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", "proc-macro2 0.4.30 (registry+https://github.com/rust-lang/crates.io-index)", "quote 0.6.13 (registry+https://github.com/rust-lang/crates.io-index)", - "syn 0.15.42 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 0.15.44 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -4213,7 +4506,7 @@ dependencies = [ "heck 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", "proc-macro2 0.4.30 (registry+https://github.com/rust-lang/crates.io-index)", "quote 0.6.13 (registry+https://github.com/rust-lang/crates.io-index)", - "syn 0.15.42 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 0.15.44 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -4222,11 +4515,11 @@ version = "2.0.0" dependencies = [ "clap 2.32.0 (registry+https://github.com/rust-lang/crates.io-index)", "hex 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", - "hex-literal 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "hex-literal 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", "node-primitives 2.0.0", "node-runtime 2.0.0", - "parity-scale-codec 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", - "rand 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", + "parity-scale-codec 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", + "rand 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)", "rustc-hex 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)", "sr-primitives 2.0.0", "srml-balances 2.0.0", @@ -4241,7 +4534,7 @@ name = "substrate" version = "2.0.0" dependencies = [ "ctrlc 3.1.3 (registry+https://github.com/rust-lang/crates.io-index)", - "futures 0.1.28 (registry+https://github.com/rust-lang/crates.io-index)", + "futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)", "node-cli 2.0.0", "vergen 3.0.4 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -4250,8 +4543,8 @@ dependencies = [ name = "substrate-application-crypto" version = "2.0.0" dependencies = [ - "parity-scale-codec 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.97 (registry+https://github.com/rust-lang/crates.io-index)", + "parity-scale-codec 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)", "sr-io 2.0.0", "sr-primitives 2.0.0", "sr-std 2.0.0", @@ -4259,13 +4552,48 @@ dependencies = [ "substrate-test-runtime-client 2.0.0", ] +[[package]] +name = "substrate-authority-discovery" +version = "2.0.0" +dependencies = [ + "bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)", + "derive_more 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)", + "futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)", + "libp2p 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", + "parity-scale-codec 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", + "parking_lot 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", + "prost 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", + "prost-build 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_json 1.0.40 (registry+https://github.com/rust-lang/crates.io-index)", + "sr-primitives 2.0.0", + "substrate-authority-discovery-primitives 2.0.0", + "substrate-client 2.0.0", + "substrate-network 2.0.0", + "substrate-peerset 2.0.0", + "substrate-primitives 2.0.0", + "substrate-test-runtime-client 2.0.0", + "tokio 0.1.22 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-timer 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "substrate-authority-discovery-primitives" +version = "2.0.0" +dependencies = [ + "parity-scale-codec 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", + "sr-primitives 2.0.0", + "sr-std 2.0.0", + "substrate-client 2.0.0", +] + [[package]] name = "substrate-basic-authorship" version = "2.0.0" dependencies = [ - "futures-preview 0.3.0-alpha.17 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", - "parity-scale-codec 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", + "futures-preview 0.3.0-alpha.19 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", + "parity-scale-codec 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", "sr-primitives 2.0.0", "substrate-client 2.0.0", "substrate-consensus-common 2.0.0", @@ -4283,33 +4611,58 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "hmac 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)", "pbkdf2 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", - "schnorrkel 0.8.4 (registry+https://github.com/rust-lang/crates.io-index)", + "schnorrkel 0.8.5 (registry+https://github.com/rust-lang/crates.io-index)", "sha2 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "substrate-chain-spec" +version = "2.0.0" +dependencies = [ + "impl-trait-for-tuples 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_json 1.0.40 (registry+https://github.com/rust-lang/crates.io-index)", + "sr-primitives 2.0.0", + "substrate-chain-spec-derive 2.0.0", + "substrate-network 2.0.0", + "substrate-primitives 2.0.0", + "substrate-telemetry 2.0.0", +] + +[[package]] +name = "substrate-chain-spec-derive" +version = "2.0.0" +dependencies = [ + "proc-macro-crate 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", + "proc-macro2 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", + "quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "substrate-cli" version = "2.0.0" dependencies = [ - "ansi_term 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)", + "ansi_term 0.12.1 (registry+https://github.com/rust-lang/crates.io-index)", "app_dirs 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)", "atty 0.2.13 (registry+https://github.com/rust-lang/crates.io-index)", "clap 2.32.0 (registry+https://github.com/rust-lang/crates.io-index)", - "derive_more 0.14.1 (registry+https://github.com/rust-lang/crates.io-index)", + "derive_more 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)", "env_logger 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", "exit-future 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", "fdlimit 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", - "futures 0.1.28 (registry+https://github.com/rust-lang/crates.io-index)", - "futures-preview 0.3.0-alpha.17 (registry+https://github.com/rust-lang/crates.io-index)", - "lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", + "futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)", + "futures-preview 0.3.0-alpha.19 (registry+https://github.com/rust-lang/crates.io-index)", + "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "names 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)", - "regex 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", - "rpassword 3.0.2 (registry+https://github.com/rust-lang/crates.io-index)", + "regex 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)", + "rpassword 4.0.1 (registry+https://github.com/rust-lang/crates.io-index)", "serde_json 1.0.40 (registry+https://github.com/rust-lang/crates.io-index)", "sr-primitives 2.0.0", "structopt 0.2.18 (registry+https://github.com/rust-lang/crates.io-index)", "substrate-client 2.0.0", + "substrate-header-metadata 2.0.0", "substrate-keyring 2.0.0", "substrate-network 2.0.0", "substrate-panic-handler 2.0.0", @@ -4326,16 +4679,17 @@ dependencies = [ name = "substrate-client" version = "2.0.0" dependencies = [ - "derive_more 0.14.1 (registry+https://github.com/rust-lang/crates.io-index)", + "derive_more 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)", "env_logger 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", "fnv 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", - "futures-preview 0.3.0-alpha.17 (registry+https://github.com/rust-lang/crates.io-index)", - "hash-db 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)", - "hex-literal 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)", + "futures-preview 0.3.0-alpha.19 (registry+https://github.com/rust-lang/crates.io-index)", + "hash-db 0.15.2 (registry+https://github.com/rust-lang/crates.io-index)", + "hex-literal 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", "kvdb 0.1.0 (git+https://github.com/paritytech/parity-common?rev=b0317f649ab2c665b7987b8475878fc4d2e1f81d)", "kvdb-memorydb 0.1.0 (git+https://github.com/paritytech/parity-common?rev=b0317f649ab2c665b7987b8475878fc4d2e1f81d)", - "log 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", - "parity-scale-codec 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", + "parity-scale-codec 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", "parking_lot 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", "sr-api-macros 2.0.0", "sr-primitives 2.0.0", @@ -4343,13 +4697,16 @@ dependencies = [ "sr-version 2.0.0", "substrate-consensus-common 2.0.0", "substrate-executor 2.0.0", + "substrate-header-metadata 2.0.0", "substrate-inherents 2.0.0", "substrate-keyring 2.0.0", + "substrate-panic-handler 2.0.0", "substrate-primitives 2.0.0", "substrate-state-machine 2.0.0", "substrate-telemetry 2.0.0", "substrate-test-runtime-client 2.0.0", "substrate-trie 2.0.0", + "tempfile 3.1.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -4357,18 +4714,19 @@ name = "substrate-client-db" version = "2.0.0" dependencies = [ "env_logger 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", - "hash-db 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)", + "hash-db 0.15.2 (registry+https://github.com/rust-lang/crates.io-index)", "kvdb 0.1.0 (git+https://github.com/paritytech/parity-common?rev=b0317f649ab2c665b7987b8475878fc4d2e1f81d)", "kvdb-memorydb 0.1.0 (git+https://github.com/paritytech/parity-common?rev=b0317f649ab2c665b7987b8475878fc4d2e1f81d)", "kvdb-rocksdb 0.1.4 (git+https://github.com/paritytech/parity-common?rev=b0317f649ab2c665b7987b8475878fc4d2e1f81d)", "linked-hash-map 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", - "parity-scale-codec 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", + "parity-scale-codec 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", "parking_lot 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", "sr-primitives 2.0.0", "substrate-client 2.0.0", "substrate-consensus-common 2.0.0", "substrate-executor 2.0.0", + "substrate-header-metadata 2.0.0", "substrate-keyring 2.0.0", "substrate-primitives 2.0.0", "substrate-state-db 2.0.0", @@ -4381,12 +4739,13 @@ dependencies = [ name = "substrate-consensus-aura" version = "2.0.0" dependencies = [ + "derive_more 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)", "env_logger 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", - "futures 0.1.28 (registry+https://github.com/rust-lang/crates.io-index)", - "futures-preview 0.3.0-alpha.17 (registry+https://github.com/rust-lang/crates.io-index)", - "futures-timer 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", - "parity-scale-codec 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", + "futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)", + "futures-preview 0.3.0-alpha.19 (registry+https://github.com/rust-lang/crates.io-index)", + "futures-timer 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", + "parity-scale-codec 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", "parking_lot 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", "sr-io 2.0.0", "sr-primitives 2.0.0", @@ -4415,7 +4774,7 @@ dependencies = [ name = "substrate-consensus-aura-primitives" version = "2.0.0" dependencies = [ - "parity-scale-codec 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", + "parity-scale-codec 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", "sr-primitives 2.0.0", "sr-std 2.0.0", "substrate-application-crypto 2.0.0", @@ -4428,18 +4787,19 @@ version = "2.0.0" dependencies = [ "env_logger 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", "fork-tree 2.0.0", - "futures 0.1.28 (registry+https://github.com/rust-lang/crates.io-index)", - "futures-preview 0.3.0-alpha.17 (registry+https://github.com/rust-lang/crates.io-index)", - "futures-timer 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", - "merlin 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", - "num-bigint 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", + "futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)", + "futures-preview 0.3.0-alpha.19 (registry+https://github.com/rust-lang/crates.io-index)", + "futures-timer 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", + "merlin 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)", + "num-bigint 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", "num-rational 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", "num-traits 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", - "parity-scale-codec 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", + "parity-scale-codec 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", "parking_lot 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", - "rand 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", - "schnorrkel 0.8.4 (registry+https://github.com/rust-lang/crates.io-index)", + "pdqselect 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "rand 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)", + "schnorrkel 0.8.5 (registry+https://github.com/rust-lang/crates.io-index)", "sr-io 2.0.0", "sr-primitives 2.0.0", "sr-version 2.0.0", @@ -4452,6 +4812,7 @@ dependencies = [ "substrate-consensus-slots 2.0.0", "substrate-consensus-uncles 2.0.0", "substrate-executor 2.0.0", + "substrate-header-metadata 2.0.0", "substrate-inherents 2.0.0", "substrate-keyring 2.0.0", "substrate-keystore 2.0.0", @@ -4468,8 +4829,8 @@ dependencies = [ name = "substrate-consensus-babe-primitives" version = "2.0.0" dependencies = [ - "parity-scale-codec 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", - "schnorrkel 0.8.4 (registry+https://github.com/rust-lang/crates.io-index)", + "parity-scale-codec 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", + "schnorrkel 0.8.5 (registry+https://github.com/rust-lang/crates.io-index)", "sr-primitives 2.0.0", "sr-std 2.0.0", "substrate-application-crypto 2.0.0", @@ -4481,12 +4842,12 @@ dependencies = [ name = "substrate-consensus-common" version = "2.0.0" dependencies = [ - "derive_more 0.14.1 (registry+https://github.com/rust-lang/crates.io-index)", - "futures-preview 0.3.0-alpha.17 (registry+https://github.com/rust-lang/crates.io-index)", - "futures-timer 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", - "libp2p 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", - "parity-scale-codec 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", + "derive_more 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)", + "futures-preview 0.3.0-alpha.19 (registry+https://github.com/rust-lang/crates.io-index)", + "futures-timer 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", + "libp2p 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", + "parity-scale-codec 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", "parking_lot 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", "sr-primitives 2.0.0", "sr-std 2.0.0", @@ -4497,24 +4858,41 @@ dependencies = [ ] [[package]] -name = "substrate-consensus-common-primitives" +name = "substrate-consensus-pow" +version = "2.0.0" +dependencies = [ + "futures-preview 0.3.0-alpha.19 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", + "parity-scale-codec 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", + "sr-primitives 2.0.0", + "srml-timestamp 2.0.0", + "substrate-client 2.0.0", + "substrate-consensus-common 2.0.0", + "substrate-consensus-pow-primitives 2.0.0", + "substrate-inherents 2.0.0", + "substrate-primitives 2.0.0", +] + +[[package]] +name = "substrate-consensus-pow-primitives" version = "2.0.0" dependencies = [ - "parity-scale-codec 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", + "parity-scale-codec 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", "sr-primitives 2.0.0", "sr-std 2.0.0", "substrate-client 2.0.0", + "substrate-primitives 2.0.0", ] [[package]] name = "substrate-consensus-rhd" version = "2.0.0" dependencies = [ - "derive_more 0.14.1 (registry+https://github.com/rust-lang/crates.io-index)", + "derive_more 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)", "exit-future 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", - "futures 0.1.28 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", - "parity-scale-codec 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", + "futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", + "parity-scale-codec 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", "parking_lot 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", "rhododendron 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", "sr-io 2.0.0", @@ -4534,16 +4912,17 @@ dependencies = [ name = "substrate-consensus-slots" version = "2.0.0" dependencies = [ - "futures-preview 0.3.0-alpha.17 (registry+https://github.com/rust-lang/crates.io-index)", - "futures-timer 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", - "parity-scale-codec 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", + "futures-preview 0.3.0-alpha.19 (registry+https://github.com/rust-lang/crates.io-index)", + "futures-timer 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", + "parity-scale-codec 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", "parking_lot 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", "sr-primitives 2.0.0", "substrate-client 2.0.0", "substrate-consensus-common 2.0.0", "substrate-inherents 2.0.0", "substrate-primitives 2.0.0", + "substrate-telemetry 2.0.0", "substrate-test-runtime-client 2.0.0", ] @@ -4551,7 +4930,7 @@ dependencies = [ name = "substrate-consensus-uncles" version = "2.0.0" dependencies = [ - "log 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "sr-primitives 2.0.0", "srml-authorship 0.1.0", "substrate-client 2.0.0", @@ -4565,14 +4944,13 @@ name = "substrate-executor" version = "2.0.0" dependencies = [ "assert_matches 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", - "byteorder 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)", - "derive_more 0.14.1 (registry+https://github.com/rust-lang/crates.io-index)", - "hex-literal 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", - "lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", - "libsecp256k1 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", - "parity-scale-codec 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", - "parity-wasm 0.31.3 (registry+https://github.com/rust-lang/crates.io-index)", + "derive_more 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)", + "hex-literal 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", + "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", + "libsecp256k1 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", + "parity-scale-codec 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", + "parity-wasm 0.40.3 (registry+https://github.com/rust-lang/crates.io-index)", "parking_lot 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", "sr-io 2.0.0", "sr-version 2.0.0", @@ -4584,9 +4962,10 @@ dependencies = [ "substrate-serializer 2.0.0", "substrate-state-machine 2.0.0", "substrate-trie 2.0.0", + "substrate-wasm-interface 2.0.0", "tiny-keccak 1.5.0 (registry+https://github.com/rust-lang/crates.io-index)", - "wabt 0.7.4 (registry+https://github.com/rust-lang/crates.io-index)", - "wasmi 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", + "wabt 0.9.2 (registry+https://github.com/rust-lang/crates.io-index)", + "wasmi 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -4596,12 +4975,12 @@ dependencies = [ "env_logger 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", "finality-grandpa 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", "fork-tree 2.0.0", - "futures 0.1.28 (registry+https://github.com/rust-lang/crates.io-index)", - "futures-preview 0.3.0-alpha.17 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", - "parity-scale-codec 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", + "futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)", + "futures-preview 0.3.0-alpha.19 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", + "parity-scale-codec 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", "parking_lot 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", - "rand 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", + "rand 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)", "serde_json 1.0.40 (registry+https://github.com/rust-lang/crates.io-index)", "sr-primitives 2.0.0", "srml-finality-tracker 2.0.0", @@ -4609,12 +4988,12 @@ dependencies = [ "substrate-consensus-babe-primitives 2.0.0", "substrate-consensus-common 2.0.0", "substrate-finality-grandpa-primitives 2.0.0", + "substrate-header-metadata 2.0.0", "substrate-inherents 2.0.0", "substrate-keyring 2.0.0", "substrate-keystore 2.0.0", "substrate-network 2.0.0", "substrate-primitives 2.0.0", - "substrate-service 2.0.0", "substrate-telemetry 2.0.0", "substrate-test-runtime-client 2.0.0", "tempfile 3.1.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -4627,19 +5006,28 @@ dependencies = [ name = "substrate-finality-grandpa-primitives" version = "2.0.0" dependencies = [ - "parity-scale-codec 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.97 (registry+https://github.com/rust-lang/crates.io-index)", + "parity-scale-codec 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)", "sr-primitives 2.0.0", "sr-std 2.0.0", "substrate-application-crypto 2.0.0", "substrate-client 2.0.0", ] +[[package]] +name = "substrate-header-metadata" +version = "2.0.0" +dependencies = [ + "lru-cache 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", + "parking_lot 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", + "sr-primitives 2.0.0", +] + [[package]] name = "substrate-inherents" version = "2.0.0" dependencies = [ - "parity-scale-codec 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", + "parity-scale-codec 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", "parking_lot 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", "sr-primitives 2.0.0", "sr-std 2.0.0", @@ -4649,7 +5037,7 @@ dependencies = [ name = "substrate-keyring" version = "2.0.0" dependencies = [ - "lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", + "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "sr-primitives 2.0.0", "strum 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)", "strum_macros 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -4663,11 +5051,11 @@ dependencies = [ "derive_more 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)", "hex 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", "parking_lot 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", - "rand 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", + "rand 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)", "serde_json 1.0.40 (registry+https://github.com/rust-lang/crates.io-index)", "substrate-application-crypto 2.0.0", "substrate-primitives 2.0.0", - "subtle 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "subtle 2.2.1 (registry+https://github.com/rust-lang/crates.io-index)", "tempdir 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -4675,28 +5063,28 @@ dependencies = [ name = "substrate-network" version = "2.0.0" dependencies = [ - "bitflags 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "bitflags 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)", - "derive_more 0.14.1 (registry+https://github.com/rust-lang/crates.io-index)", - "either 1.5.2 (registry+https://github.com/rust-lang/crates.io-index)", + "derive_more 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)", + "either 1.5.3 (registry+https://github.com/rust-lang/crates.io-index)", "env_logger 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", "erased-serde 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", "fnv 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", "fork-tree 2.0.0", - "futures 0.1.28 (registry+https://github.com/rust-lang/crates.io-index)", - "futures-preview 0.3.0-alpha.17 (registry+https://github.com/rust-lang/crates.io-index)", - "futures-timer 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", - "libp2p 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)", + "futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)", + "futures-preview 0.3.0-alpha.19 (registry+https://github.com/rust-lang/crates.io-index)", + "futures-timer 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", + "libp2p 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)", "linked-hash-map 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)", "linked_hash_set 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "lru-cache 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", - "parity-scale-codec 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", + "parity-scale-codec 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", "parking_lot 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", - "quickcheck 0.8.5 (registry+https://github.com/rust-lang/crates.io-index)", - "rand 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", + "quickcheck 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", + "rand 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)", "rustc-hex 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.97 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)", "serde_json 1.0.40 (registry+https://github.com/rust-lang/crates.io-index)", "slog 2.5.2 (registry+https://github.com/rust-lang/crates.io-index)", "slog_derive 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", @@ -4705,6 +5093,7 @@ dependencies = [ "substrate-client 2.0.0", "substrate-consensus-babe-primitives 2.0.0", "substrate-consensus-common 2.0.0", + "substrate-header-metadata 2.0.0", "substrate-keyring 2.0.0", "substrate-peerset 2.0.0", "substrate-primitives 2.0.0", @@ -4716,18 +5105,25 @@ dependencies = [ "tokio-io 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", "unsigned-varint 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", "void 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", - "zeroize 0.9.2 (registry+https://github.com/rust-lang/crates.io-index)", + "zeroize 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "substrate-offchain" version = "2.0.0" dependencies = [ + "bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)", "env_logger 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", - "futures-preview 0.3.0-alpha.17 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", - "parity-scale-codec 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", + "fnv 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", + "futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)", + "futures-preview 0.3.0-alpha.19 (registry+https://github.com/rust-lang/crates.io-index)", + "futures-timer 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", + "hyper 0.12.35 (registry+https://github.com/rust-lang/crates.io-index)", + "hyper-tls 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", + "parity-scale-codec 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", "parking_lot 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", + "rand 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)", "sr-primitives 2.0.0", "substrate-client 2.0.0", "substrate-client-db 2.0.0", @@ -4737,6 +5133,7 @@ dependencies = [ "substrate-primitives 2.0.0", "substrate-test-runtime-client 2.0.0", "substrate-transaction-pool 2.0.0", + "tokio 0.1.22 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -4751,23 +5148,34 @@ dependencies = [ name = "substrate-panic-handler" version = "2.0.0" dependencies = [ - "backtrace 0.3.33 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", + "backtrace 0.3.38 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "substrate-peerset" version = "2.0.0" dependencies = [ - "futures-preview 0.3.0-alpha.17 (registry+https://github.com/rust-lang/crates.io-index)", - "libp2p 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)", + "futures-preview 0.3.0-alpha.19 (registry+https://github.com/rust-lang/crates.io-index)", + "libp2p 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)", "linked-hash-map 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "lru-cache 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", - "rand 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", + "rand 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)", "serde_json 1.0.40 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "substrate-phragmen" +version = "2.0.0" +dependencies = [ + "rand 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)", + "sr-io 2.0.0", + "sr-primitives 2.0.0", + "sr-std 2.0.0", + "srml-support 2.0.0", +] + [[package]] name = "substrate-primitives" version = "2.0.0" @@ -4776,31 +5184,32 @@ dependencies = [ "blake2-rfc 0.2.18 (registry+https://github.com/rust-lang/crates.io-index)", "byteorder 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)", "criterion 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", - "ed25519-dalek 1.0.0-pre.1 (registry+https://github.com/rust-lang/crates.io-index)", - "hash-db 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)", - "hash256-std-hasher 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)", + "ed25519-dalek 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)", + "hash-db 0.15.2 (registry+https://github.com/rust-lang/crates.io-index)", + "hash256-std-hasher 0.15.2 (registry+https://github.com/rust-lang/crates.io-index)", "hex 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", - "hex-literal 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", - "impl-serde 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", - "lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", + "hex-literal 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", + "impl-serde 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", + "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "num-traits 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", - "parity-scale-codec 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", + "parity-scale-codec 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", "parking_lot 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", "pretty_assertions 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)", - "primitive-types 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", - "rand 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", - "regex 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "primitive-types 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", + "rand 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)", + "regex 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)", "rustc-hex 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)", - "schnorrkel 0.8.4 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.97 (registry+https://github.com/rust-lang/crates.io-index)", + "schnorrkel 0.8.5 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)", "sha2 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", "sr-std 2.0.0", "substrate-bip39 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", "substrate-serializer 2.0.0", "tiny-bip39 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", - "twox-hash 1.4.2 (registry+https://github.com/rust-lang/crates.io-index)", - "wasmi 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", - "zeroize 0.9.2 (registry+https://github.com/rust-lang/crates.io-index)", + "twox-hash 1.5.0 (registry+https://github.com/rust-lang/crates.io-index)", + "wasmi 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", + "zeroize 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -4808,18 +5217,15 @@ name = "substrate-rpc" version = "2.0.0" dependencies = [ "assert_matches 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", - "derive_more 0.14.1 (registry+https://github.com/rust-lang/crates.io-index)", - "futures 0.1.28 (registry+https://github.com/rust-lang/crates.io-index)", - "futures-preview 0.3.0-alpha.17 (registry+https://github.com/rust-lang/crates.io-index)", - "jsonrpc-core 12.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "jsonrpc-core-client 12.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "jsonrpc-derive 12.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "jsonrpc-pubsub 12.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", - "parity-scale-codec 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", + "futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)", + "futures-preview 0.3.0-alpha.19 (registry+https://github.com/rust-lang/crates.io-index)", + "hash-db 0.15.2 (registry+https://github.com/rust-lang/crates.io-index)", + "jsonrpc-core 13.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "jsonrpc-pubsub 13.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", + "parity-scale-codec 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", "parking_lot 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", "rustc-hex 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.97 (registry+https://github.com/rust-lang/crates.io-index)", "serde_json 1.0.40 (registry+https://github.com/rust-lang/crates.io-index)", "sr-io 2.0.0", "sr-primitives 2.0.0", @@ -4829,6 +5235,8 @@ dependencies = [ "substrate-keystore 2.0.0", "substrate-network 2.0.0", "substrate-primitives 2.0.0", + "substrate-rpc-api 2.0.0", + "substrate-rpc-primitives 2.0.0", "substrate-session 2.0.0", "substrate-state-machine 2.0.0", "substrate-test-runtime-client 2.0.0", @@ -4836,17 +5244,47 @@ dependencies = [ "tokio 0.1.22 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "substrate-rpc-api" +version = "2.0.0" +dependencies = [ + "derive_more 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)", + "futures-preview 0.3.0-alpha.19 (registry+https://github.com/rust-lang/crates.io-index)", + "jsonrpc-core 13.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "jsonrpc-core-client 13.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "jsonrpc-derive 13.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "jsonrpc-pubsub 13.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", + "parity-scale-codec 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", + "parking_lot 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_json 1.0.40 (registry+https://github.com/rust-lang/crates.io-index)", + "sr-version 2.0.0", + "substrate-primitives 2.0.0", + "substrate-rpc-primitives 2.0.0", + "substrate-transaction-graph 2.0.0", +] + +[[package]] +name = "substrate-rpc-primitives" +version = "2.0.0" +dependencies = [ + "serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)", + "substrate-primitives 2.0.0", +] + [[package]] name = "substrate-rpc-servers" version = "2.0.0" dependencies = [ - "jsonrpc-http-server 12.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "jsonrpc-pubsub 12.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "jsonrpc-ws-server 12.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.97 (registry+https://github.com/rust-lang/crates.io-index)", + "jsonrpc-core 13.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "jsonrpc-http-server 13.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "jsonrpc-pubsub 13.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "jsonrpc-ws-server 13.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_json 1.0.40 (registry+https://github.com/rust-lang/crates.io-index)", "sr-primitives 2.0.0", - "substrate-rpc 2.0.0", ] [[package]] @@ -4854,17 +5292,18 @@ name = "substrate-runtime-test" version = "2.0.0" dependencies = [ "sr-io 2.0.0", + "sr-primitives 2.0.0", "sr-sandbox 2.0.0", "sr-std 2.0.0", "substrate-primitives 2.0.0", - "substrate-wasm-builder-runner 1.0.2", + "substrate-wasm-builder-runner 1.0.3", ] [[package]] name = "substrate-serializer" version = "2.0.0" dependencies = [ - "serde 1.0.97 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)", "serde_json 1.0.40 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -4872,24 +5311,27 @@ dependencies = [ name = "substrate-service" version = "2.0.0" dependencies = [ - "derive_more 0.14.1 (registry+https://github.com/rust-lang/crates.io-index)", + "derive_more 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)", "exit-future 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", - "futures 0.1.28 (registry+https://github.com/rust-lang/crates.io-index)", - "futures-preview 0.3.0-alpha.17 (registry+https://github.com/rust-lang/crates.io-index)", - "lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", + "futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)", + "futures-preview 0.3.0-alpha.19 (registry+https://github.com/rust-lang/crates.io-index)", + "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "node-executor 2.0.0", "node-primitives 2.0.0", "node-runtime 2.0.0", "parity-multiaddr 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", - "parity-scale-codec 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", + "parity-scale-codec 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", "parking_lot 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.97 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)", "serde_json 1.0.40 (registry+https://github.com/rust-lang/crates.io-index)", "slog 2.5.2 (registry+https://github.com/rust-lang/crates.io-index)", "sr-io 2.0.0", "sr-primitives 2.0.0", "substrate-application-crypto 2.0.0", + "substrate-authority-discovery 2.0.0", + "substrate-authority-discovery-primitives 2.0.0", + "substrate-chain-spec 2.0.0", "substrate-client 2.0.0", "substrate-client-db 2.0.0", "substrate-consensus-babe-primitives 2.0.0", @@ -4901,12 +5343,13 @@ dependencies = [ "substrate-network 2.0.0", "substrate-offchain 2.0.0", "substrate-primitives 2.0.0", + "substrate-rpc 2.0.0", "substrate-rpc-servers 2.0.0", "substrate-session 2.0.0", "substrate-telemetry 2.0.0", "substrate-test-runtime-client 2.0.0", "substrate-transaction-pool 2.0.0", - "sysinfo 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", + "sysinfo 0.9.5 (registry+https://github.com/rust-lang/crates.io-index)", "target_info 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-executor 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-timer 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", @@ -4918,8 +5361,9 @@ version = "2.0.0" dependencies = [ "env_logger 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", "fdlimit 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", - "futures 0.1.28 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", + "futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)", + "futures-preview 0.3.0-alpha.19 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "sr-primitives 2.0.0", "substrate-client 2.0.0", "substrate-consensus-common 2.0.0", @@ -4945,8 +5389,8 @@ name = "substrate-state-db" version = "2.0.0" dependencies = [ "env_logger 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", - "parity-scale-codec 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", + "parity-scale-codec 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", "parking_lot 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", "substrate-primitives 2.0.0", ] @@ -4955,17 +5399,18 @@ dependencies = [ name = "substrate-state-machine" version = "2.0.0" dependencies = [ - "hash-db 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)", - "hex-literal 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", + "hash-db 0.15.2 (registry+https://github.com/rust-lang/crates.io-index)", + "hex-literal 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "num-traits 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", - "parity-scale-codec 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", + "parity-scale-codec 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", "parking_lot 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", + "rand 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)", "substrate-panic-handler 2.0.0", "substrate-primitives 2.0.0", "substrate-trie 2.0.0", - "trie-db 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)", - "trie-root 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)", + "trie-db 0.15.2 (registry+https://github.com/rust-lang/crates.io-index)", + "trie-root 0.15.2 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -4973,14 +5418,14 @@ name = "substrate-telemetry" version = "2.0.0" dependencies = [ "bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)", - "futures 0.1.28 (registry+https://github.com/rust-lang/crates.io-index)", - "futures-preview 0.3.0-alpha.17 (registry+https://github.com/rust-lang/crates.io-index)", - "futures-timer 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", - "libp2p 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", + "futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)", + "futures-preview 0.3.0-alpha.19 (registry+https://github.com/rust-lang/crates.io-index)", + "futures-timer 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", + "libp2p 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "parking_lot 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", - "rand 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.97 (registry+https://github.com/rust-lang/crates.io-index)", + "rand 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)", "slog 2.5.2 (registry+https://github.com/rust-lang/crates.io-index)", "slog-async 2.3.0 (git+https://github.com/paritytech/slog-async)", "slog-json 2.3.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -4993,9 +5438,9 @@ dependencies = [ name = "substrate-test-client" version = "2.0.0" dependencies = [ - "futures-preview 0.3.0-alpha.17 (registry+https://github.com/rust-lang/crates.io-index)", - "hash-db 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)", - "parity-scale-codec 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", + "futures-preview 0.3.0-alpha.19 (registry+https://github.com/rust-lang/crates.io-index)", + "hash-db 0.15.2 (registry+https://github.com/rust-lang/crates.io-index)", + "parity-scale-codec 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", "sr-primitives 2.0.0", "substrate-client 2.0.0", "substrate-client-db 2.0.0", @@ -5010,11 +5455,11 @@ dependencies = [ name = "substrate-test-runtime" version = "2.0.0" dependencies = [ - "cfg-if 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", - "memory-db 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)", - "parity-scale-codec 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.97 (registry+https://github.com/rust-lang/crates.io-index)", + "cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", + "memory-db 0.15.2 (registry+https://github.com/rust-lang/crates.io-index)", + "parity-scale-codec 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)", "sr-io 2.0.0", "sr-primitives 2.0.0", "sr-std 2.0.0", @@ -5037,15 +5482,15 @@ dependencies = [ "substrate-state-machine 2.0.0", "substrate-test-runtime-client 2.0.0", "substrate-trie 2.0.0", - "substrate-wasm-builder-runner 1.0.2", - "trie-db 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)", + "substrate-wasm-builder-runner 1.0.3", + "trie-db 0.15.2 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "substrate-test-runtime-client" version = "2.0.0" dependencies = [ - "parity-scale-codec 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", + "parity-scale-codec 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", "sr-primitives 2.0.0", "substrate-primitives 2.0.0", "substrate-test-client 2.0.0", @@ -5057,13 +5502,13 @@ name = "substrate-transaction-graph" version = "2.0.0" dependencies = [ "assert_matches 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", - "derive_more 0.14.1 (registry+https://github.com/rust-lang/crates.io-index)", + "derive_more 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)", "env_logger 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", - "futures 0.1.28 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", - "parity-scale-codec 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", + "futures-preview 0.3.0-alpha.19 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", + "parity-scale-codec 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", "parking_lot 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.97 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)", "sr-primitives 2.0.0", "substrate-primitives 2.0.0", "substrate-test-runtime 2.0.0", @@ -5073,10 +5518,10 @@ dependencies = [ name = "substrate-transaction-pool" version = "2.0.0" dependencies = [ - "derive_more 0.14.1 (registry+https://github.com/rust-lang/crates.io-index)", - "futures 0.1.28 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", - "parity-scale-codec 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", + "derive_more 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)", + "futures-preview 0.3.0-alpha.19 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", + "parity-scale-codec 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", "parking_lot 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", "sr-primitives 2.0.0", "substrate-client 2.0.0", @@ -5091,40 +5536,47 @@ name = "substrate-trie" version = "2.0.0" dependencies = [ "criterion 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", - "hash-db 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)", - "hex-literal 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", - "keccak-hasher 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)", - "memory-db 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)", - "parity-scale-codec 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", + "hash-db 0.15.2 (registry+https://github.com/rust-lang/crates.io-index)", + "hex-literal 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", + "keccak-hasher 0.15.2 (registry+https://github.com/rust-lang/crates.io-index)", + "memory-db 0.15.2 (registry+https://github.com/rust-lang/crates.io-index)", + "parity-scale-codec 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", "sr-std 2.0.0", "substrate-primitives 2.0.0", - "trie-bench 0.16.0 (registry+https://github.com/rust-lang/crates.io-index)", - "trie-db 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)", - "trie-root 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)", - "trie-standardmap 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)", + "trie-bench 0.16.2 (registry+https://github.com/rust-lang/crates.io-index)", + "trie-db 0.15.2 (registry+https://github.com/rust-lang/crates.io-index)", + "trie-root 0.15.2 (registry+https://github.com/rust-lang/crates.io-index)", + "trie-standardmap 0.15.2 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "substrate-wasm-builder" -version = "1.0.4" +version = "1.0.7" dependencies = [ "build-helper 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", - "cargo_metadata 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)", + "cargo_metadata 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)", "fs2 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)", "tempfile 3.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "toml 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", + "toml 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)", "walkdir 2.2.9 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "substrate-wasm-builder-runner" -version = "1.0.2" +version = "1.0.3" [[package]] name = "substrate-wasm-builder-runner" -version = "1.0.2" +version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "substrate-wasm-interface" +version = "2.0.0" +dependencies = [ + "wasmi 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "subtle" version = "1.0.0" @@ -5132,12 +5584,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "subtle" -version = "2.1.0" +version = "2.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "syn" -version = "0.15.42" +version = "0.15.44" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "proc-macro2 0.4.30 (registry+https://github.com/rust-lang/crates.io-index)", @@ -5145,6 +5597,16 @@ dependencies = [ "unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "syn" +version = "1.0.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "proc-macro2 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", + "quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", + "unicode-xid 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "synstructure" version = "0.10.2" @@ -5152,20 +5614,20 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "proc-macro2 0.4.30 (registry+https://github.com/rust-lang/crates.io-index)", "quote 0.6.13 (registry+https://github.com/rust-lang/crates.io-index)", - "syn 0.15.42 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 0.15.44 (registry+https://github.com/rust-lang/crates.io-index)", "unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "sysinfo" -version = "0.9.0" +version = "0.9.5" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "cfg-if 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)", + "cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", "doc-comment 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.60 (registry+https://github.com/rust-lang/crates.io-index)", - "rayon 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)", + "rayon 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -5192,12 +5654,12 @@ name = "tempfile" version = "3.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "cfg-if 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.60 (registry+https://github.com/rust-lang/crates.io-index)", - "rand 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", + "cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)", + "rand 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)", "redox_syscall 0.1.56 (registry+https://github.com/rust-lang/crates.io-index)", "remove_dir_all 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -5205,7 +5667,7 @@ name = "termcolor" version = "1.0.5" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "wincolor 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", + "wincolor 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -5213,7 +5675,7 @@ name = "textwrap" version = "0.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "unicode-width 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", + "unicode-width 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -5221,7 +5683,7 @@ name = "thread_local" version = "0.3.6" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", + "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -5229,9 +5691,9 @@ name = "time" version = "0.1.42" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "libc 0.2.60 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)", "redox_syscall 0.1.56 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -5261,28 +5723,17 @@ name = "tinytemplate" version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "serde 1.0.97 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)", "serde_json 1.0.40 (registry+https://github.com/rust-lang/crates.io-index)", ] -[[package]] -name = "tk-listen" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "futures 0.1.28 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio 0.1.22 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-io 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", -] - [[package]] name = "tokio" version = "0.1.22" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)", - "futures 0.1.28 (registry+https://github.com/rust-lang/crates.io-index)", + "futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)", "mio 0.6.19 (registry+https://github.com/rust-lang/crates.io-index)", "num_cpus 1.10.1 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-codec 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", @@ -5290,12 +5741,12 @@ dependencies = [ "tokio-executor 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-fs 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-io 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-reactor 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-reactor 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-sync 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-tcp 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-threadpool 0.1.15 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-threadpool 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-timer 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-udp 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-udp 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-uds 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -5305,8 +5756,8 @@ version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)", - "either 1.5.2 (registry+https://github.com/rust-lang/crates.io-index)", - "futures 0.1.28 (registry+https://github.com/rust-lang/crates.io-index)", + "either 1.5.3 (registry+https://github.com/rust-lang/crates.io-index)", + "futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -5315,7 +5766,7 @@ version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)", - "futures 0.1.28 (registry+https://github.com/rust-lang/crates.io-index)", + "futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-io 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -5324,7 +5775,7 @@ name = "tokio-current-thread" version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "futures 0.1.28 (registry+https://github.com/rust-lang/crates.io-index)", + "futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-executor 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -5333,9 +5784,9 @@ name = "tokio-dns-unofficial" version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "futures 0.1.28 (registry+https://github.com/rust-lang/crates.io-index)", + "futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)", "futures-cpupool 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", - "lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", + "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "tokio 0.1.22 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -5345,7 +5796,7 @@ version = "0.1.8" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "crossbeam-utils 0.6.6 (registry+https://github.com/rust-lang/crates.io-index)", - "futures 0.1.28 (registry+https://github.com/rust-lang/crates.io-index)", + "futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -5353,9 +5804,9 @@ name = "tokio-fs" version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "futures 0.1.28 (registry+https://github.com/rust-lang/crates.io-index)", + "futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-io 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-threadpool 0.1.15 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-threadpool 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -5364,22 +5815,22 @@ version = "0.1.12" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)", - "futures 0.1.28 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", + "futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "tokio-reactor" -version = "0.1.9" +version = "0.1.10" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "crossbeam-utils 0.6.6 (registry+https://github.com/rust-lang/crates.io-index)", - "futures 0.1.28 (registry+https://github.com/rust-lang/crates.io-index)", - "lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", + "futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)", + "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "mio 0.6.19 (registry+https://github.com/rust-lang/crates.io-index)", "num_cpus 1.10.1 (registry+https://github.com/rust-lang/crates.io-index)", - "parking_lot 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)", + "parking_lot 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", "slab 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-executor 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-io 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", @@ -5392,7 +5843,7 @@ version = "0.10.0-alpha.4" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)", - "futures 0.1.28 (registry+https://github.com/rust-lang/crates.io-index)", + "futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)", "iovec 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", "rustls 0.15.2 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-io 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", @@ -5405,7 +5856,7 @@ version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "fnv 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", - "futures 0.1.28 (registry+https://github.com/rust-lang/crates.io-index)", + "futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -5414,25 +5865,25 @@ version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)", - "futures 0.1.28 (registry+https://github.com/rust-lang/crates.io-index)", + "futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)", "iovec 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", "mio 0.6.19 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-io 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-reactor 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-reactor 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "tokio-threadpool" -version = "0.1.15" +version = "0.1.16" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "crossbeam-deque 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)", "crossbeam-queue 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", "crossbeam-utils 0.6.6 (registry+https://github.com/rust-lang/crates.io-index)", - "futures 0.1.28 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", + "futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)", + "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "num_cpus 1.10.1 (registry+https://github.com/rust-lang/crates.io-index)", - "rand 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", "slab 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-executor 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -5443,7 +5894,7 @@ version = "0.2.11" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "crossbeam-utils 0.6.6 (registry+https://github.com/rust-lang/crates.io-index)", - "futures 0.1.28 (registry+https://github.com/rust-lang/crates.io-index)", + "futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)", "slab 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-executor 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -5453,23 +5904,23 @@ name = "tokio-tls" version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "futures 0.1.28 (registry+https://github.com/rust-lang/crates.io-index)", + "futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)", "native-tls 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-io 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "tokio-udp" -version = "0.1.3" +version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)", - "futures 0.1.28 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", + "futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "mio 0.6.19 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-codec 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-io 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-reactor 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-reactor 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -5478,23 +5929,23 @@ version = "0.2.5" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)", - "futures 0.1.28 (registry+https://github.com/rust-lang/crates.io-index)", + "futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)", "iovec 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.60 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "mio 0.6.19 (registry+https://github.com/rust-lang/crates.io-index)", "mio-uds 0.6.7 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-codec 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-io 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-reactor 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-reactor 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "toml" -version = "0.5.1" +version = "0.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "serde 1.0.97 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -5506,8 +5957,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" name = "transaction-factory" version = "0.0.1" dependencies = [ - "log 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", - "parity-scale-codec 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", + "parity-scale-codec 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", "sr-primitives 2.0.0", "substrate-cli 2.0.0", "substrate-client 2.0.0", @@ -5518,46 +5969,46 @@ dependencies = [ [[package]] name = "trie-bench" -version = "0.16.0" +version = "0.16.2" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "criterion 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", - "hash-db 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)", - "keccak-hasher 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)", - "memory-db 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)", - "parity-scale-codec 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", - "trie-db 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)", - "trie-root 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)", - "trie-standardmap 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)", + "hash-db 0.15.2 (registry+https://github.com/rust-lang/crates.io-index)", + "keccak-hasher 0.15.2 (registry+https://github.com/rust-lang/crates.io-index)", + "memory-db 0.15.2 (registry+https://github.com/rust-lang/crates.io-index)", + "parity-scale-codec 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", + "trie-db 0.15.2 (registry+https://github.com/rust-lang/crates.io-index)", + "trie-root 0.15.2 (registry+https://github.com/rust-lang/crates.io-index)", + "trie-standardmap 0.15.2 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "trie-db" -version = "0.15.0" +version = "0.15.2" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "elastic-array 0.10.2 (registry+https://github.com/rust-lang/crates.io-index)", - "hash-db 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)", - "hashmap_core 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", + "hash-db 0.15.2 (registry+https://github.com/rust-lang/crates.io-index)", + "hashbrown 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "rand 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "trie-root" -version = "0.15.0" +version = "0.15.2" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "hash-db 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)", + "hash-db 0.15.2 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "trie-standardmap" -version = "0.15.0" +version = "0.15.2" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "hash-db 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)", - "keccak-hasher 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)", + "hash-db 0.15.2 (registry+https://github.com/rust-lang/crates.io-index)", + "keccak-hasher 0.15.2 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -5567,15 +6018,15 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "trybuild" -version = "1.0.9" +version = "1.0.15" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "glob 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", - "lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.97 (registry+https://github.com/rust-lang/crates.io-index)", + "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)", "serde_json 1.0.40 (registry+https://github.com/rust-lang/crates.io-index)", "termcolor 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", - "toml 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", + "toml 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -5585,15 +6036,15 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "block-cipher-trait 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", "byteorder 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)", - "opaque-debug 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", + "opaque-debug 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "twox-hash" -version = "1.4.2" +version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "rand 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", + "rand 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -5603,17 +6054,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "typenum" -version = "1.10.0" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "ucd-util" -version = "0.1.5" +version = "1.11.2" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "uint" -version = "0.8.0" +version = "0.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "byteorder 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)", @@ -5631,7 +6077,7 @@ dependencies = [ [[package]] name = "unicase" -version = "2.4.0" +version = "2.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "version_check 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", @@ -5660,7 +6106,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "unicode-width" -version = "0.1.5" +version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] @@ -5668,6 +6114,11 @@ name = "unicode-xid" version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "unicode-xid" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "unsigned-varint" version = "0.2.2" @@ -5693,9 +6144,14 @@ dependencies = [ ] [[package]] -name = "utf8-ranges" -version = "1.0.3" +name = "url" +version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "idna 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "matches 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", + "percent-encoding 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)", +] [[package]] name = "vcpkg" @@ -5707,23 +6163,13 @@ name = "vec_map" version = "0.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -[[package]] -name = "vecarray" -version = "0.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "parity-codec 4.1.3 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.97 (registry+https://github.com/rust-lang/crates.io-index)", - "typenum 1.10.0 (registry+https://github.com/rust-lang/crates.io-index)", -] - [[package]] name = "vergen" version = "3.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "bitflags 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "chrono 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", + "bitflags 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "chrono 0.4.9 (registry+https://github.com/rust-lang/crates.io-index)", "failure 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -5739,22 +6185,22 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "wabt" -version = "0.7.4" +version = "0.9.2" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "serde 1.0.97 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_derive 1.0.97 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_derive 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)", "serde_json 1.0.40 (registry+https://github.com/rust-lang/crates.io-index)", - "wabt-sys 0.5.4 (registry+https://github.com/rust-lang/crates.io-index)", + "wabt-sys 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "wabt-sys" -version = "0.5.4" +version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "cc 1.0.38 (registry+https://github.com/rust-lang/crates.io-index)", - "cmake 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)", + "cc 1.0.45 (registry+https://github.com/rust-lang/crates.io-index)", + "cmake 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)", "glob 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -5764,7 +6210,7 @@ version = "2.2.9" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "same-file 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", "winapi-util 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -5773,81 +6219,89 @@ name = "want" version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "futures 0.1.28 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", + "futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "try-lock 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "wasi" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "wasm-bindgen" -version = "0.2.48" +version = "0.2.51" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "wasm-bindgen-macro 0.2.48 (registry+https://github.com/rust-lang/crates.io-index)", + "cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", + "wasm-bindgen-macro 0.2.51 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "wasm-bindgen-backend" -version = "0.2.48" +version = "0.2.51" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "bumpalo 2.5.0 (registry+https://github.com/rust-lang/crates.io-index)", - "lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", - "proc-macro2 0.4.30 (registry+https://github.com/rust-lang/crates.io-index)", - "quote 0.6.13 (registry+https://github.com/rust-lang/crates.io-index)", - "syn 0.15.42 (registry+https://github.com/rust-lang/crates.io-index)", - "wasm-bindgen-shared 0.2.48 (registry+https://github.com/rust-lang/crates.io-index)", + "bumpalo 2.6.0 (registry+https://github.com/rust-lang/crates.io-index)", + "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", + "proc-macro2 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", + "quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", + "wasm-bindgen-shared 0.2.51 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "wasm-bindgen-futures" -version = "0.3.25" +version = "0.3.27" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "futures 0.1.28 (registry+https://github.com/rust-lang/crates.io-index)", - "js-sys 0.3.25 (registry+https://github.com/rust-lang/crates.io-index)", - "wasm-bindgen 0.2.48 (registry+https://github.com/rust-lang/crates.io-index)", + "cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", + "futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)", + "js-sys 0.3.28 (registry+https://github.com/rust-lang/crates.io-index)", + "wasm-bindgen 0.2.51 (registry+https://github.com/rust-lang/crates.io-index)", + "web-sys 0.3.28 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "wasm-bindgen-macro" -version = "0.2.48" +version = "0.2.51" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "quote 0.6.13 (registry+https://github.com/rust-lang/crates.io-index)", - "wasm-bindgen-macro-support 0.2.48 (registry+https://github.com/rust-lang/crates.io-index)", + "quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", + "wasm-bindgen-macro-support 0.2.51 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.48" +version = "0.2.51" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "proc-macro2 0.4.30 (registry+https://github.com/rust-lang/crates.io-index)", - "quote 0.6.13 (registry+https://github.com/rust-lang/crates.io-index)", - "syn 0.15.42 (registry+https://github.com/rust-lang/crates.io-index)", - "wasm-bindgen-backend 0.2.48 (registry+https://github.com/rust-lang/crates.io-index)", - "wasm-bindgen-shared 0.2.48 (registry+https://github.com/rust-lang/crates.io-index)", + "proc-macro2 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", + "quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", + "wasm-bindgen-backend 0.2.51 (registry+https://github.com/rust-lang/crates.io-index)", + "wasm-bindgen-shared 0.2.51 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "wasm-bindgen-shared" -version = "0.2.48" +version = "0.2.51" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "wasm-bindgen-webidl" -version = "0.2.48" +version = "0.2.51" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "failure 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", "heck 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", - "proc-macro2 0.4.30 (registry+https://github.com/rust-lang/crates.io-index)", - "quote 0.6.13 (registry+https://github.com/rust-lang/crates.io-index)", - "syn 0.15.42 (registry+https://github.com/rust-lang/crates.io-index)", - "wasm-bindgen-backend 0.2.48 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", + "proc-macro2 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", + "quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", + "wasm-bindgen-backend 0.2.51 (registry+https://github.com/rust-lang/crates.io-index)", "weedle 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -5856,46 +6310,45 @@ name = "wasm-timer" version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "futures 0.1.28 (registry+https://github.com/rust-lang/crates.io-index)", - "js-sys 0.3.25 (registry+https://github.com/rust-lang/crates.io-index)", + "futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)", + "js-sys 0.3.28 (registry+https://github.com/rust-lang/crates.io-index)", "send_wrapper 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-timer 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", - "wasm-bindgen 0.2.48 (registry+https://github.com/rust-lang/crates.io-index)", - "web-sys 0.3.25 (registry+https://github.com/rust-lang/crates.io-index)", + "wasm-bindgen 0.2.51 (registry+https://github.com/rust-lang/crates.io-index)", + "web-sys 0.3.28 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "wasmi" -version = "0.5.0" +version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "libc 0.2.60 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)", "memory_units 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "num-rational 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", "num-traits 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", - "parity-wasm 0.31.3 (registry+https://github.com/rust-lang/crates.io-index)", - "wasmi-validation 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "parity-wasm 0.40.3 (registry+https://github.com/rust-lang/crates.io-index)", + "wasmi-validation 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "wasmi-validation" -version = "0.1.0" +version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "hashbrown 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", - "parity-wasm 0.31.3 (registry+https://github.com/rust-lang/crates.io-index)", + "parity-wasm 0.40.3 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "web-sys" -version = "0.3.25" +version = "0.3.28" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "failure 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", - "js-sys 0.3.25 (registry+https://github.com/rust-lang/crates.io-index)", + "js-sys 0.3.28 (registry+https://github.com/rust-lang/crates.io-index)", "sourcefile 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", - "wasm-bindgen 0.2.48 (registry+https://github.com/rust-lang/crates.io-index)", - "wasm-bindgen-webidl 0.2.48 (registry+https://github.com/rust-lang/crates.io-index)", + "wasm-bindgen 0.2.51 (registry+https://github.com/rust-lang/crates.io-index)", + "wasm-bindgen-webidl 0.2.51 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -5918,21 +6371,21 @@ dependencies = [ [[package]] name = "websocket" -version = "0.22.4" +version = "0.23.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "base64 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)", - "bitflags 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "bitflags 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "byteorder 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)", "bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)", - "futures 0.1.28 (registry+https://github.com/rust-lang/crates.io-index)", + "futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)", "hyper 0.10.16 (registry+https://github.com/rust-lang/crates.io-index)", "native-tls 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", "rand 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", "sha1 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-codec 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-io 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-reactor 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-reactor 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-tcp 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-tls 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", "unicase 1.4.2 (registry+https://github.com/rust-lang/crates.io-index)", @@ -5953,7 +6406,7 @@ version = "2.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "failure 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.60 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -5963,7 +6416,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "winapi" -version = "0.3.7" +version = "0.3.8" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "winapi-i686-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -5985,7 +6438,7 @@ name = "winapi-util" version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -5995,28 +6448,28 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "wincolor" -version = "1.0.1" +version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", "winapi-util 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "ws" -version = "0.8.1" +version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "byteorder 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)", "bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)", "httparse 1.3.4 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "mio 0.6.19 (registry+https://github.com/rust-lang/crates.io-index)", "mio-extras 2.0.5 (registry+https://github.com/rust-lang/crates.io-index)", "rand 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", "sha-1 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)", "slab 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", - "url 1.7.2 (registry+https://github.com/rust-lang/crates.io-index)", + "url 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -6034,7 +6487,7 @@ version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "clear_on_drop 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", - "curve25519-dalek 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)", + "curve25519-dalek 1.2.3 (registry+https://github.com/rust-lang/crates.io-index)", "rand_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -6054,9 +6507,9 @@ version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)", - "futures 0.1.28 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", - "nohash-hasher 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", + "futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", + "nohash-hasher 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", "parking_lot 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)", "quick-error 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", "rand 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", @@ -6066,31 +6519,38 @@ dependencies = [ [[package]] name = "zeroize" -version = "0.9.2" +version = "0.9.3" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "zeroize_derive 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", + "zeroize_derive 0.9.3 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "zeroize" +version = "0.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "zeroize_derive" -version = "0.9.0" +version = "0.9.3" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "proc-macro2 0.4.30 (registry+https://github.com/rust-lang/crates.io-index)", "quote 0.6.13 (registry+https://github.com/rust-lang/crates.io-index)", - "syn 0.15.42 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 0.15.44 (registry+https://github.com/rust-lang/crates.io-index)", "synstructure 0.10.2 (registry+https://github.com/rust-lang/crates.io-index)", ] [metadata] -"checksum adler32 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "7e522997b529f05601e05166c07ed17789691f562762c7f3b987263d2dedee5c" +"checksum adler32 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "5d2e7343e7fc9de883d1b0341e0b13970f764c14101234857d2ddafa1cb1cac2" "checksum aes-ctr 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d2e5b0458ea3beae0d1d8c0f3946564f8e10f90646cf78c06b4351052058d1ee" "checksum aes-soft 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "cfd7e7ae3f9a1fb5c03b389fc6bb9a51400d0c13053f0dca698c832bfd893a0d" "checksum aesni 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "2f70a6b5f971e473091ab7cfb5ffac6cde81666c4556751d8d5620ead8abf100" -"checksum aho-corasick 0.7.4 (registry+https://github.com/rust-lang/crates.io-index)" = "36b7aa1ccb7d7ea3f437cf025a2ab1c47cc6c1bc9fc84918ff449def12f5e282" -"checksum aio-limited 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7f10b352bc3fc08ae24dc5d2d3ddcac153678533986122dc283d747b12071000" +"checksum ahash 0.2.13 (registry+https://github.com/rust-lang/crates.io-index)" = "b58aeefd9396419a4f4f2b9778f2d832a11851b55010e231c5390cf2b1c416b4" +"checksum aho-corasick 0.7.6 (registry+https://github.com/rust-lang/crates.io-index)" = "58fb5e95d83b38284460a5fda7d6470aa0b8844d283a0b614b8535e880800d2d" +"checksum aio-limited 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "c4dddf55b0b2da9acb7512f21c0a4f1c0871522ec4ab7fb919d0da807d1e32b3" "checksum ansi_term 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ee49baf6cb617b853aa8d93bf420db2383fab46d314482ca2803b40d5fde979b" +"checksum ansi_term 0.12.1 (registry+https://github.com/rust-lang/crates.io-index)" = "d52a9bb7ec0cf484c551830a7ce27bd20d67eac647e1befb56b0be4ee39a55d2" "checksum app_dirs 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "e73a24bad9bd6a94d6395382a6c69fe071708ae4409f763c5475e14ee896313d" "checksum arc-swap 0.3.11 (registry+https://github.com/rust-lang/crates.io-index)" = "bc4662175ead9cd84451d5c35070517777949a2ed84551764129cedb88384841" "checksum arrayref 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "0d382e583f07208808f6b1249e60848879ba3543f57c32277bf52d69c2f0f0ee" @@ -6099,28 +6559,26 @@ dependencies = [ "checksum asn1_der_derive 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "9e7f92edafad155aff997fa5b727c6429b91e996b5a5d62a2b0adbae1306b5fe" "checksum assert_matches 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7deb0a829ca7bcfaf5da70b073a8d128619259a7be8216a355e23f00763059e5" "checksum atty 0.2.13 (registry+https://github.com/rust-lang/crates.io-index)" = "1803c647a3ec87095e7ae7acfca019e98de5ec9a7d01343f611cf3152ed71a90" -"checksum autocfg 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "22130e92352b948e7e82a49cdb0aa94f2211761117f29e052dd397c1ac33542b" -"checksum backtrace 0.3.33 (registry+https://github.com/rust-lang/crates.io-index)" = "88fb679bc9af8fa639198790a77f52d345fe13656c08b43afa9424c206b731c6" +"checksum autocfg 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "b671c8fb71b457dd4ae18c4ba1e59aa81793daacc361d82fcd410cef0d491875" +"checksum backtrace 0.3.38 (registry+https://github.com/rust-lang/crates.io-index)" = "690a62be8920ccf773ee00ef0968649b0e724cda8bd5b12286302b4ae955fdf5" "checksum backtrace-sys 0.1.31 (registry+https://github.com/rust-lang/crates.io-index)" = "82a830b4ef2d1124a711c71d263c5abdc710ef8e907bd508c88be475cebc422b" "checksum base58 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "5024ee8015f02155eee35c711107ddd9a9bf3cb689cf2a9089c97e79b6e1ae83" "checksum base64 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)" = "0b25d992356d2eb0ed82172f5248873db5560c4721f564b13cb5193bda5e668e" "checksum base64 0.9.3 (registry+https://github.com/rust-lang/crates.io-index)" = "489d6c0ed21b11d038c31b6ceccca973e65d73ba3bd8ecb9a2babf5546164643" -"checksum bigint 4.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "ebecac13b3c745150d7b6c3ea7572d372f09d627c2077e893bf26c5c7f70d282" "checksum bindgen 0.47.3 (registry+https://github.com/rust-lang/crates.io-index)" = "df683a55b54b41d5ea8ebfaebb5aa7e6b84e3f3006a78f010dadc9ca88469260" -"checksum bitflags 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3d155346769a6855b86399e9bc3814ab343cd3d62c7e985113d46a0ec3c281fd" +"checksum bitflags 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "8a606a02debe2813760609f57a64a2ffd27d9fdf5b2f133eaca0b248dd92cdd2" "checksum bitmask 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "5da9b3d9f6f585199287a473f4f8dfab6566cf827d15c00c219f53c645687ead" -"checksum bitvec 0.11.3 (registry+https://github.com/rust-lang/crates.io-index)" = "b67491e1cc6f37da6c4415cd743cb8d2e2c65388acc91ca3094a054cbf3cbd0c" "checksum bitvec 0.14.0 (registry+https://github.com/rust-lang/crates.io-index)" = "9633b74910e1870f50f5af189b08487195cdb83c0e27a71d6f64d5e09dd0538b" -"checksum blake2 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "91721a6330935673395a0607df4d49a9cb90ae12d259f1b3e0a3f6e1d486872e" +"checksum blake2 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)" = "94cb07b0da6a73955f8fb85d24c466778e70cda767a568229b104f0264089330" "checksum blake2-rfc 0.2.18 (registry+https://github.com/rust-lang/crates.io-index)" = "5d6d530bdd2d52966a6d03b7a964add7ae1a288d25214066fd4b600f0f796400" "checksum block-buffer 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1339a1042f5d9f295737ad4d9a6ab6bf81c84a933dba110b9200cd6d1448b814" "checksum block-buffer 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)" = "c0940dc441f31689269e10ac70eb1002a3a1d3ad1390e030043662eb7fe4688b" "checksum block-cipher-trait 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)" = "1c924d49bd09e7c06003acda26cd9742e796e34282ec6c1189404dee0c1f4774" "checksum block-padding 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "6d4dc3af3ee2e12f3e5d224e5e1e3d73668abbeb69e566d361f7d5563a4fdf09" -"checksum bs58 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "0de79cfb98e7aa9988188784d8664b4b5dad6eaaa0863b91d9a4ed871d4f7a42" -"checksum bstr 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)" = "e0a692f1c740e7e821ca71a22cf99b9b2322dfa94d10f71443befb1797b3946a" +"checksum bs58 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)" = "c95ee6bba9d950218b6cc910cf62bc9e0a171d0f4537e3627b0f54d08549b188" +"checksum bstr 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)" = "8d6c2c5b58ab920a4f5aeaaca34b4488074e8cc7596af94e6f8c6ff247c60245" "checksum build-helper 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "bdce191bf3fa4995ce948c8c83b4640a1745457a149e73c6db75b4ffe36aad5f" -"checksum bumpalo 2.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "2cd43d82f27d68911e6ee11ee791fb248f138f5d69424dc02e098d4f152b0b05" +"checksum bumpalo 2.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ad807f2fc2bf185eeb98ff3a901bd46dc5ad58163d0fa4577ba0d25674d71708" "checksum byte-slice-cast 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7cbcbf18128ec71d8d4a0d054461ec59fff5b75b7d10a4c9b7c7cb1a379c3e77" "checksum byte-tools 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "560c32574a12a89ecd91f5e742165893f86e3ab98d21f8ea548658eb9eef5f40" "checksum byte-tools 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "e3b5ca7a04898ad4bcd41c90c5285445ff5b791899bb1b0abdd2a2aa791211d7" @@ -6129,53 +6587,53 @@ dependencies = [ "checksum bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)" = "206fdffcfa2df7cbe15601ef46c813fce0965eb3286db6b56c583b814b51c81c" "checksum c2-chacha 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7d64d04786e0f528460fc884753cf8dddcc466be308f6026f8e355c41a0e4101" "checksum c_linked_list 1.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "4964518bd3b4a8190e832886cdc0da9794f12e8e6c1613a9e90ff331c4c8724b" -"checksum cargo_metadata 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)" = "5e904f164f39cae0c3a4f2713eb97a47ba64676a071e99a69ddfef4994694d2c" +"checksum cargo_metadata 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)" = "700b3731fd7d357223d0000f4dbf1808401b694609035c3c411fbc0cd375c426" "checksum cast 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "926013f2860c46252efceabb19f4a6b308197505082c609025aa6706c011d427" -"checksum cc 1.0.38 (registry+https://github.com/rust-lang/crates.io-index)" = "ce400c638d48ee0e9ab75aef7997609ec57367ccfe1463f21bf53c3eca67bf46" +"checksum cc 1.0.45 (registry+https://github.com/rust-lang/crates.io-index)" = "4fc9a35e1f4290eb9e5fc54ba6cf40671ed2a2514c3eeb2b2a908dda2ea5a1be" "checksum cexpr 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "a7fa24eb00d5ffab90eaeaf1092ac85c04c64aaf358ea6f84505b8116d24c6af" -"checksum cfg-if 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)" = "b486ce3ccf7ffd79fdeb678eac06a9e6c09fc88d33836340becb8fffe87c5e33" -"checksum chrono 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)" = "77d81f58b7301084de3b958691458a53c3f7e0b1d702f77e550b6a88e3a88abe" +"checksum cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)" = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822" +"checksum chrono 0.4.9 (registry+https://github.com/rust-lang/crates.io-index)" = "e8493056968583b0193c1bb04d6f7684586f3726992d6c573261941a895dbd68" "checksum clang-sys 0.26.4 (registry+https://github.com/rust-lang/crates.io-index)" = "6ef0c1bcf2e99c649104bd7a7012d8f8802684400e03db0ec0af48583c6fa0e4" "checksum clap 2.32.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b957d88f4b6a63b9d70d5f454ac8011819c6efa7727858f458ab71c756ce2d3e" "checksum clear_on_drop 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "97276801e127ffb46b66ce23f35cc96bd454fa311294bced4bbace7baa8b1d17" "checksum cloudabi 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "ddfc5b9aa5d4507acaf872de71051dfd0e309860e88966e1051e462a077aac4f" -"checksum cmake 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)" = "2ca4386c8954b76a8415b63959337d940d724b336cabd3afe189c2b51a7e1ff0" -"checksum constant_time_eq 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "8ff012e225ce166d4422e0e78419d901719760f62ae2b7969ca6b564d1b54a9e" +"checksum cmake 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)" = "81fb25b677f8bf1eb325017cb6bb8452f87969db0fedb4f757b297bee78a7c62" +"checksum const-random 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "7b641a8c9867e341f3295564203b1c250eb8ce6cb6126e007941f78c4d2ed7fe" +"checksum const-random-macro 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "c750ec12b83377637110d5a57f5ae08e895b06c4b16e2bdbf1a94ef717428c59" +"checksum constant_time_eq 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "995a44c877f9212528ccc74b21a232f66ad69001e40ede5bcee2ac9ef2657120" "checksum core-foundation 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)" = "25b9e03f145fd4f2bf705e07b900cd41fc636598fe5dc452fd0db1441c3f496d" "checksum core-foundation-sys 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)" = "e7ca8a5221364ef15ce201e8ed2f609fc312682a8f4e0e3d4aa5879764e0fa3b" "checksum crc32fast 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ba125de2af0df55319f41944744ad91c71113bf74a4646efff39afe1f6842db1" "checksum criterion 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)" = "0363053954f3e679645fc443321ca128b7b950a6fe288cf5f9335cc22ee58394" "checksum criterion-plot 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "76f9212ddf2f4a9eb2d401635190600656a1f88a932ef53d06e7fa4c7e02fb8e" "checksum crossbeam-channel 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)" = "c8ec7fcd21571dc78f96cc96243cab8d8f035247c3efd16c687be154c3fa9efa" -"checksum crossbeam-deque 0.6.3 (registry+https://github.com/rust-lang/crates.io-index)" = "05e44b8cf3e1a625844d1750e1f7820da46044ff6d28f4d43e455ba3e5bb2c13" "checksum crossbeam-deque 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)" = "b18cd2e169ad86297e6bc0ad9aa679aee9daa4f19e8163860faf7c164e4f5a71" "checksum crossbeam-epoch 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)" = "fedcd6772e37f3da2a9af9bf12ebe046c0dfe657992377b4df982a2b54cd37a9" "checksum crossbeam-queue 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7c979cd6cfe72335896575c6b5688da489e420d36a27a0b9eb0c73db574b4a4b" "checksum crossbeam-utils 0.6.6 (registry+https://github.com/rust-lang/crates.io-index)" = "04973fa96e96579258a5091af6003abde64af786b860f18622b82e026cca60e6" -"checksum crunchy 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "a2f4a431c5c9f662e1200b7c7f02c34e91361150e382089a8f2dec3ba680cbda" "checksum crunchy 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7a81dae078cea95a014a339291cec439d2f232ebe854a9d672b796c6afafa9b7" "checksum crypto-mac 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "779015233ac67d65098614aec748ac1c756ab6677fa2e14cf8b37c08dfed1198" "checksum crypto-mac 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "4434400df11d95d556bac068ddfedd482915eb18fe8bea89bc80b6e4b1c179e5" "checksum csv 1.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "37519ccdfd73a75821cac9319d4fce15a81b9fcf75f951df5b9988aa3a0af87d" "checksum csv-core 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "9b5cadb6b25c77aeff80ba701712494213f4a8418fcda2ee11b6560c3ad0bf4c" -"checksum ctor 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)" = "3b4c17619643c1252b5f690084b82639dd7fac141c57c8e77a00e0148132092c" +"checksum ctor 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)" = "cd8ce37ad4184ab2ce004c33bf6379185d3b1c95801cab51026bd271bf68eedc" "checksum ctr 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "022cd691704491df67d25d006fe8eca083098253c4d43516c2206479c58c6736" "checksum ctrlc 3.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "c7dfd2d8b4c82121dfdff120f818e09fc4380b0b7e17a742081a89b94853e87f" "checksum cuckoofilter 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "8dd43f7cfaffe0a386636a10baea2ee05cc50df3b77bea4a456c9572a939bf1f" -"checksum curve25519-dalek 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "5d4b820e8711c211745880150f5fac78ab07d6e3851d8ce9f5a02cedc199174c" +"checksum curve25519-dalek 1.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "8b7dcd30ba50cdf88b55b033456138b7c0ac4afdc436d82e1b79f370f24cc66d" "checksum data-encoding 2.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "f4f47ca1860a761136924ddd2422ba77b2ea54fe8cc75b9040804a0d9d32ad97" -"checksum derive_more 0.14.1 (registry+https://github.com/rust-lang/crates.io-index)" = "6d944ac6003ed268757ef1ee686753b57efc5fcf0ebe7b64c9fc81e7e32ff839" "checksum derive_more 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7a141330240c921ec6d074a3e188a7c7ef95668bb95e7d44fa0e5778ec2a7afe" "checksum difference 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "524cbf6897b527295dff137cec09ecf3a05f4fddffd7dfcd1585403449e74198" "checksum digest 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)" = "e5b29bf156f3f4b3c4f610a25ff69370616ae6e0657d416de22645483e72af0a" "checksum digest 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)" = "f3d0c8c8752312f9713efd397ff63acb9f85585afbf179282e720e7704954dd5" "checksum dns-parser 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c4d33be9473d06f75f58220f71f7a9317aca647dc061dbd3c361b0bef505fbea" "checksum doc-comment 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "923dea538cea0aa3025e8685b20d6ee21ef99c4f77e954a30febbaac5ec73a97" +"checksum ed25519-dalek 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)" = "2d07e8b8a8386c3b89a7a4b329fdfa4cb545de2545e9e2ebbc3dd3929253e426" "checksum ed25519-dalek 1.0.0-pre.1 (registry+https://github.com/rust-lang/crates.io-index)" = "81956bcf7ef761fb4e1d88de3fa181358a0d26cbcb9755b587a08f9119824b86" -"checksum either 1.5.2 (registry+https://github.com/rust-lang/crates.io-index)" = "5527cfe0d098f36e3f8839852688e63c8fff1c90b2b405aef730615f9a7bcf7b" +"checksum either 1.5.3 (registry+https://github.com/rust-lang/crates.io-index)" = "bb1f6b1ce1c140482ea30ddd3335fc0024ac7ee112895426e0a629a6c20adfe3" "checksum elastic-array 0.10.2 (registry+https://github.com/rust-lang/crates.io-index)" = "073be79b6538296faf81c631872676600616073817dd9a440c477ad09b408983" "checksum env_logger 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)" = "aafcde04e90a5226a6443b7aabdb016ba2f8307c847d524724bd9b346dd1a2d3" -"checksum environmental 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "5c7464757b80de8930c91c9afe77ddce501826bf9d134a87db2c67d9dc177e2c" +"checksum environmental 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "34f8467a0284de039e6bd0e25c14519538462ba5beb548bb1f03e645097837a8" "checksum erased-serde 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)" = "3beee4bc16478a1b26f2e80ad819a52d24745e292f521a63c16eea5f74b7eb60" "checksum error-chain 0.12.1 (registry+https://github.com/rust-lang/crates.io-index)" = "3ab49e9dcb602294bc42f9a7dfc9bc6e936fca4418ea300dbfb84fe16de0b7d9" "checksum exit-future 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "d8013f441e38e31c670e7f34ec8f1d5d3a2bd9d303c1ff83976ca886005e8f48" @@ -6185,7 +6643,8 @@ dependencies = [ "checksum fdlimit 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "b1ee15a7050e5580b3712877157068ea713b245b080ff302ae2ca973cfcd9baa" "checksum finality-grandpa 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "9681c1f75941ea47584573dd2bc10558b2067d460612945887e00744e43393be" "checksum fixed-hash 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "516877b7b9a1cc2d0293cbce23cd6203f0edbfd4090e6ca4489fecb5aa73050e" -"checksum flate2 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)" = "550934ad4808d5d39365e5d61727309bf18b3b02c6c56b729cb92e7dd84bc3d8" +"checksum fixedbitset 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)" = "86d4de0081402f5e88cdac65c8dcdcc73118c1a7a465e2a05f0da05843a8ea33" +"checksum flate2 1.0.12 (registry+https://github.com/rust-lang/crates.io-index)" = "ad3c5233c9a940c8719031b423d7e6c16af66e031cb0420b0896f5245bf181d3" "checksum fnv 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)" = "2fad85553e09a6f881f739c29f0b00b0f01357c743266d478b68951ce23285f3" "checksum foreign-types 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "f6f339eb8adc052cd2ca78910fda869aefa38d22d5cb648e6485e4d3fc06f3b1" "checksum foreign-types-shared 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b" @@ -6194,98 +6653,104 @@ dependencies = [ "checksum fuchsia-cprng 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "a06f77d526c1a601b7c4cdd98f54b5eaabffc14d5f2f0296febdc7f357c6d3ba" "checksum fuchsia-zircon 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "2e9763c69ebaae630ba35f74888db465e49e259ba1bc0eda7d06f4a067615d82" "checksum fuchsia-zircon-sys 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "3dcaa9ae7725d12cdb85b3ad99a434db70b468c09ded17e012d86b5c1010f7a7" -"checksum futures 0.1.28 (registry+https://github.com/rust-lang/crates.io-index)" = "45dc39533a6cae6da2b56da48edae506bb767ec07370f86f70fc062e9d435869" -"checksum futures-channel-preview 0.3.0-alpha.17 (registry+https://github.com/rust-lang/crates.io-index)" = "21c71ed547606de08e9ae744bb3c6d80f5627527ef31ecf2a7210d0e67bc8fae" -"checksum futures-core-preview 0.3.0-alpha.17 (registry+https://github.com/rust-lang/crates.io-index)" = "4b141ccf9b7601ef987f36f1c0d9522f76df3bba1cf2e63bfacccc044c4558f5" +"checksum futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)" = "1b980f2816d6ee8673b6517b52cb0e808a180efc92e5c19d02cdda79066703ef" +"checksum futures-channel-preview 0.3.0-alpha.19 (registry+https://github.com/rust-lang/crates.io-index)" = "d5e5f4df964fa9c1c2f8bddeb5c3611631cacd93baf810fc8bb2fb4b495c263a" +"checksum futures-core-preview 0.3.0-alpha.19 (registry+https://github.com/rust-lang/crates.io-index)" = "b35b6263fb1ef523c3056565fa67b1d16f0a8604ff12b11b08c25f28a734c60a" "checksum futures-cpupool 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)" = "ab90cde24b3319636588d0c35fe03b1333857621051837ed769faefb4c2162e4" -"checksum futures-executor-preview 0.3.0-alpha.17 (registry+https://github.com/rust-lang/crates.io-index)" = "87ba260fe51080ba37f063ad5b0732c4ff1f737ea18dcb67833d282cdc2c6f14" -"checksum futures-io-preview 0.3.0-alpha.17 (registry+https://github.com/rust-lang/crates.io-index)" = "082e402605fcb8b1ae1e5ba7d7fdfd3e31ef510e2a8367dd92927bb41ae41b3a" -"checksum futures-preview 0.3.0-alpha.17 (registry+https://github.com/rust-lang/crates.io-index)" = "bf25f91c8a9a1f64c451e91b43ba269ed359b9f52d35ed4b3ce3f9c842435867" -"checksum futures-sink-preview 0.3.0-alpha.17 (registry+https://github.com/rust-lang/crates.io-index)" = "4309a25a1069a1f3c10647b227b9afe6722b67a030d3f00a9cbdc171fc038de4" -"checksum futures-timer 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "eb4a32e84935678650944c6ebd0d912db46405d37bf94f1a058435c5080abcb1" -"checksum futures-util-preview 0.3.0-alpha.17 (registry+https://github.com/rust-lang/crates.io-index)" = "af8198c48b222f02326940ce2b3aa9e6e91a32886eeaad7ca3b8e4c70daa3f4e" +"checksum futures-executor-preview 0.3.0-alpha.19 (registry+https://github.com/rust-lang/crates.io-index)" = "75236e88bd9fe88e5e8bfcd175b665d0528fe03ca4c5207fabc028c8f9d93e98" +"checksum futures-io-preview 0.3.0-alpha.19 (registry+https://github.com/rust-lang/crates.io-index)" = "f4914ae450db1921a56c91bde97a27846287d062087d4a652efc09bb3a01ebda" +"checksum futures-preview 0.3.0-alpha.19 (registry+https://github.com/rust-lang/crates.io-index)" = "3b1dce2a0267ada5c6ff75a8ba864b4e679a9e2aa44262af7a3b5516d530d76e" +"checksum futures-sink-preview 0.3.0-alpha.19 (registry+https://github.com/rust-lang/crates.io-index)" = "86f148ef6b69f75bb610d4f9a2336d4fc88c4b5b67129d1a340dd0fd362efeec" +"checksum futures-timer 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "878f1d2fc31355fa02ed2372e741b0c17e58373341e6a122569b4623a14a7d33" +"checksum futures-util-preview 0.3.0-alpha.19 (registry+https://github.com/rust-lang/crates.io-index)" = "5ce968633c17e5f97936bd2797b6e38fb56cf16a7422319f7ec2e30d3c470e8d" "checksum gcc 0.3.55 (registry+https://github.com/rust-lang/crates.io-index)" = "8f5f3913fa0bfe7ee1fd8248b6b9f42a5af4b9d65ec2dd2c3c26132b950ecfc2" "checksum generic-array 0.12.3 (registry+https://github.com/rust-lang/crates.io-index)" = "c68f0274ae0e023facc3c97b2e00f076be70e254bc851d972503b328db79b2ec" "checksum generic-array 0.8.3 (registry+https://github.com/rust-lang/crates.io-index)" = "fceb69994e330afed50c93524be68c42fa898c2d9fd4ee8da03bd7363acd26f2" "checksum get_if_addrs 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)" = "abddb55a898d32925f3148bd281174a68eeb68bbfd9a5938a57b18f506ee4ef7" "checksum get_if_addrs-sys 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "0d04f9fb746cf36b191c00f3ede8bde9c8e64f9f4b05ae2694a9ccf5e3f5ab48" -"checksum getrandom 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "e65cce4e5084b14874c4e7097f38cab54f47ee554f9194673456ea379dcc4c55" +"checksum getrandom 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)" = "473a1265acc8ff1e808cd0a1af8cee3c2ee5200916058a2ca113c29f2d903571" "checksum glob 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)" = "8be18de09a56b60ed0edf84bc9df007e30040691af7acd1c41874faac5895bfb" "checksum glob 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "9b919933a397b79c37e33b77bb2aa3dc8eb6e165ad809e58ff75bc7db2e34574" "checksum globset 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)" = "925aa2cac82d8834e2b2a4415b6f6879757fb5c0928fc445ae76461a12eed8f2" "checksum h2 0.1.26 (registry+https://github.com/rust-lang/crates.io-index)" = "a5b34c246847f938a410a03c5458c7fee2274436675e76d8b903c08efc29c462" -"checksum hash-db 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)" = "32c87fec93c4a2d264483ef843ac1930ae7c7999d97d73721305a5188b4c23a4" -"checksum hash256-std-hasher 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)" = "16293646125e09e5bc216d9f73fa81ab31c4f97007d56c036bbf15a58e970540" +"checksum hash-db 0.15.2 (registry+https://github.com/rust-lang/crates.io-index)" = "d23bd4e7b5eda0d0f3a307e8b381fdc8ba9000f26fbe912250c0a4cc3956364a" +"checksum hash256-std-hasher 0.15.2 (registry+https://github.com/rust-lang/crates.io-index)" = "92c171d55b98633f4ed3860808f004099b36c1cc29c42cfc53aa8591b21efcf2" "checksum hashbrown 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)" = "3bae29b6653b3412c2e71e9d486db9f9df5d701941d86683005efb9f2d28e3da" -"checksum hashmap_core 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)" = "8e04cb7a5051270ef3fa79f8c7604d581ecfa73d520e74f554e45541c4b5881a" +"checksum hashbrown 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "2bcea5b597dd98e6d1f1ec171744cc5dee1a30d1c23c5b98e3cf9d4fbdf8a526" +"checksum hashmap_core 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)" = "2d6852e5a86250521973b0c1d39677166d8a9c0047c908d7e04f1aa04177973c" "checksum heapsize 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "1679e6ea370dee694f91f1dc469bf94cf8f52051d147aec3e1f9497c6fc22461" "checksum heck 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "20564e78d53d2bb135c343b3f47714a56af2061f1c928fdb541dc7b9fdd94205" "checksum hex 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "805026a5d0141ffc30abb3be3173848ad46a1b1664fe632428479619a3644d77" -"checksum hex-literal 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c3da68162fdd2147e66682e78e729bd77f93b4c99656db058c5782d8c6b6225a" -"checksum hex-literal-impl 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "06095d08c7c05760f11a071b3e1d4c5b723761c01bd8d7201c30a9536668a612" +"checksum hex-literal 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "961de220ec9a91af2e1e5bd80d02109155695e516771762381ef8581317066e0" +"checksum hex-literal-impl 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "9d4c5c844e2fee0bf673d54c2c177f1713b3d2af2ff6e666b49cb7572e6cf42d" "checksum hmac 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7a13f4163aa0c5ca1be584aace0e2212b2e41be5478218d4f657f5f778b2ae2a" "checksum hmac 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)" = "5dcb5e64cda4c23119ab41ba960d1e170a774c8e4b9d9e6a9bc18aabf5e59695" "checksum hmac-drbg 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "4fe727d41d2eec0a6574d887914347e5ff96a3b87177817e2a9820c5c87fecc2" -"checksum http 0.1.17 (registry+https://github.com/rust-lang/crates.io-index)" = "eed324f0f0daf6ec10c474f150505af2c143f251722bf9dbd1261bd1f2ee2c1a" +"checksum hmac-drbg 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c6e570451493f10f6581b48cdd530413b63ea9e780f544bfd3bdcaa0d89d1a7b" +"checksum http 0.1.18 (registry+https://github.com/rust-lang/crates.io-index)" = "372bcb56f939e449117fb0869c2e8fd8753a8223d92a172c6e808cf123a5b6e4" "checksum http-body 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "6741c859c1b2463a423a1dbce98d418e6c3c3fc720fb0d45528657320920292d" "checksum httparse 1.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "cd179ae861f0c2e53da70d892f5f3029f9594be0c41dc5269cd371691b1dc2f9" -"checksum humantime 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3ca7e5f2e110db35f93b837c81797f3714500b81d517bf20c431b16d3ca4f114" +"checksum humantime 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "df004cfca50ef23c36850aaaa59ad52cc70d0e90243c3c7737a4dd32dc7a3c4f" "checksum hyper 0.10.16 (registry+https://github.com/rust-lang/crates.io-index)" = "0a0652d9a2609a968c14be1a9ea00bf4b1d64e2e1f53a1b51b6fff3a6e829273" -"checksum hyper 0.12.33 (registry+https://github.com/rust-lang/crates.io-index)" = "7cb44cbce9d8ee4fb36e4c0ad7b794ac44ebaad924b9c8291a63215bb44c2c8f" +"checksum hyper 0.12.35 (registry+https://github.com/rust-lang/crates.io-index)" = "9dbe6ed1438e1f8ad955a4701e9a944938e9519f6888d12d8558b645e247d5f6" +"checksum hyper-tls 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "3a800d6aa50af4b5850b2b0f659625ce9504df908e9733b635720483be26174f" "checksum idna 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "38f09e0f0b1fb55fdee1f17470ad800da77af5186a1a76c026b679358b7e844e" -"checksum impl-codec 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "78c441b3d2b5e24b407161e76d482b7bbd29b5da357707839ac40d95152f031f" -"checksum impl-serde 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "5158079de9d4158e0ce1de3ae0bd7be03904efc40b3d7dd8b8c301cbf6b52b56" -"checksum impl-serde 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7d26be4b97d738552ea423f76c4f681012ff06c3fa36fa968656b3679f60b4a1" -"checksum indexmap 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7e81a7c05f79578dbc15793d8b619db9ba32b4577003ef3af1a91c416798c58d" +"checksum idna 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "02e2673c30ee86b5b96a9cb52ad15718aa1f966f5ab9ad54a8b95d5ca33120a9" +"checksum impl-codec 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "3fa0086251524c50fd53b32e7b05eb6d79e2f97221eaf0c53c0ca9c3096f21d3" +"checksum impl-serde 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "bbb1ea6188aca47a0eaeeb330d8a82f16cd500f30b897062d23922568727333a" +"checksum impl-trait-for-tuples 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "6947b372790f8948f439bb6aaa6baabdf80be1a207a477ff072f83fb793e428f" +"checksum indexmap 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a61202fbe46c4a951e9404a720a0180bcf3212c750d735cb5c4ba4dc551299f3" "checksum integer-sqrt 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "ea155abb3ba6f382a75f1418988c05fe82959ed9ce727de427f9cfd425b0c903" "checksum interleaved-ordered 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "141340095b15ed7491bd3d4ced9d20cebfb826174b6bb03386381f62b01e3d77" "checksum iovec 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "dbe6e417e7d0975db6512b90796e8ce223145ac4e33c377e4a42882a0e88bb08" "checksum ipnet 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e61c2da0d0f700c77d2d313dbf4f93e41d235fa12c6681fee06621036df4c2af" "checksum itertools 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "5b8467d9c1cebe26feb08c640139247fac215782d35371ade9a2136ed6085358" "checksum itoa 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)" = "501266b7edd0174f8530248f87f99c88fbe60ca4ef3dd486835b8d8d53136f7f" -"checksum js-sys 0.3.25 (registry+https://github.com/rust-lang/crates.io-index)" = "da3ea71161651a4cd97d999b2da139109c537b15ab33abc8ae4ead38deac8a03" -"checksum jsonrpc-client-transports 12.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "6be24a8de4ced80f6fd8b6ace54aa610823a7642976a0e8e00e3bb2f4d8c33f0" -"checksum jsonrpc-core 12.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "0216cf4c95fb373d89c63572672097b8aa74cfcdd77054accbf545d840be5bd7" -"checksum jsonrpc-core-client 12.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1603b6cc05060de7794c2962edd705e1ad2698bd2b0d2ddd4489f8c85df122b7" -"checksum jsonrpc-derive 12.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "8afff172177878850d133ccdcd93cad794e85d7779ab334998d669ef80e13180" -"checksum jsonrpc-http-server 12.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a24e140242e0d2e9a694cf8db513a2bd739d24c392e0ad15e0d6d7ee8851e3a2" -"checksum jsonrpc-pubsub 12.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e3c45f7cdb1bb28a3bfb3a0a5184bf99669c9ffe8cf8d7b8a582f2a52bf9944a" -"checksum jsonrpc-server-utils 12.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d7aac8e0029d19582b68c9fd498d18bdcf0846612c968acc93b6e5ae67eea4e0" -"checksum jsonrpc-ws-server 12.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "698fee4fcaf09a5927b7e39dd8a8136a102b343cebacaa351fc4def01a050a5b" +"checksum jobserver 0.1.17 (registry+https://github.com/rust-lang/crates.io-index)" = "f2b1d42ef453b30b7387e113da1c83ab1605d90c5b4e0eb8e96d016ed3b8c160" +"checksum js-sys 0.3.28 (registry+https://github.com/rust-lang/crates.io-index)" = "2cc9a97d7cec30128fd8b28a7c1f9df1c001ceb9b441e2b755e24130a6b43c79" +"checksum jsonrpc-client-transports 13.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "8dbf2466adbf6d5b4e618857f22be40b1e1cc6ed79d72751324358f6b539b06d" +"checksum jsonrpc-core 13.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "91d767c183a7e58618a609499d359ce3820700b3ebb4823a18c343b4a2a41a0d" +"checksum jsonrpc-core-client 13.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "161dc223549fa6fe4a4eda675de2d1d3cff5a7164e5c031cdf1e22c734700f8b" +"checksum jsonrpc-derive 13.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "4a76285ebba4515680fbfe4b62498ccb2a932384c8732eed68351b02fb7ae475" +"checksum jsonrpc-http-server 13.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "601fcc7bec888c7cbc7fd124d3d6744d72c0ebb540eca6fe2261b71f9cff6320" +"checksum jsonrpc-pubsub 13.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "64e0fb0664d8ce287e826940dafbb45379443c595bdd71d93655f3c8f25fd992" +"checksum jsonrpc-server-utils 13.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "4d415f51d016a4682878e19dd03e8c0b61cd4394912d7cd3dc48d4f19f061a4e" +"checksum jsonrpc-ws-server 13.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "4699433c1ac006d7df178b4c29c191e5bb6d81e2dca18c5c804a094592900101" "checksum keccak 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "67c21572b4949434e4fc1e1978b99c5f77064153c59d998bf13ecd96fb5ecba7" -"checksum keccak-hasher 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3bf18164fd7ce989041f8fc4a1ae72a8bd1bec3575f2aeaf1d4968fc053aabef" +"checksum keccak-hasher 0.15.2 (registry+https://github.com/rust-lang/crates.io-index)" = "3468207deea1359a0e921591ae9b4c928733d94eb9d6a2eeda994cfd59f42cf8" "checksum kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7507624b29483431c0ba2d82aece8ca6cdba9382bff4ddd0f7490560c056098d" "checksum kvdb 0.1.0 (git+https://github.com/paritytech/parity-common?rev=b0317f649ab2c665b7987b8475878fc4d2e1f81d)" = "" "checksum kvdb-memorydb 0.1.0 (git+https://github.com/paritytech/parity-common?rev=b0317f649ab2c665b7987b8475878fc4d2e1f81d)" = "" "checksum kvdb-rocksdb 0.1.4 (git+https://github.com/paritytech/parity-common?rev=b0317f649ab2c665b7987b8475878fc4d2e1f81d)" = "" "checksum language-tags 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "a91d884b6667cd606bb5a69aa0c99ba811a115fc68915e7056ec08a46e93199a" -"checksum lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "bc5729f27f159ddd61f4df6228e827e86643d4d3e7c32183cb30a1c08f604a14" +"checksum lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" "checksum lazycell 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "b294d6fa9ee409a054354afc4352b0b9ef7ca222c69b8812cbea9e7d2bf3783f" -"checksum libc 0.2.60 (registry+https://github.com/rust-lang/crates.io-index)" = "d44e80633f007889c7eff624b709ab43c92d708caad982295768a7b13ca3b5eb" +"checksum libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)" = "34fcd2c08d2f832f376f4173a231990fa5aef4e99fb569867318a227ef4c06ba" "checksum libloading 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)" = "f2b111a074963af1d37a139918ac6d49ad1d0d5e47f72fd55388619691a7d753" -"checksum libp2p 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "18b3404dae1e3110caaae14b2d59bf7254b1e988ed7ed38da59c005bed711e7d" -"checksum libp2p-core 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "efa1b75b0b388c0f33bc2e2f5d385885f9ed77f622802895b68ac8397aaef2de" -"checksum libp2p-core-derive 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "954fe45edba727b76196abff0d3894116c32a07e4f8173a8f26caf3484add4c0" -"checksum libp2p-deflate 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "56b77964eaf8ba7019df8de2a02f2241ee240011d6de69f4991baf174ad42d2e" -"checksum libp2p-dns 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "0c2625c6acd4073403f1107e4e038efa02ba5de54de0d08567a2cc338560d63f" -"checksum libp2p-floodsub 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d14e6c61c6e69f291261c8ec001b85a2c6426f2074183a40c337c29ed7939bd1" -"checksum libp2p-identify 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "34ba4b8d4e27f4848a6b121604d98818a8527f4269948ba77dfe49f0f1c3dc8f" -"checksum libp2p-kad 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "93384ee24fe137bf3afa8263b8d9e63c6bd6c92aad7cc50949fdba2b90db93a4" -"checksum libp2p-mdns 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "bd24b59da234647e15c34054158b6853a505301d5888719593e6fcd7841c39d9" -"checksum libp2p-mplex 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "8b101952e8dfdc5c902f1063cd8bfbb80e735857a16d387033ae8180df578009" -"checksum libp2p-noise 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1dd3313a8216b92e3ae5a24034d6fc35bf9671e9f4ad4b2ce445291852508b77" -"checksum libp2p-ping 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "0c803a4d21c97e14eb8b5019cc32242e296f1d1835de8664e5464d7dc31f068d" -"checksum libp2p-plaintext 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "fbac75c9683aa5997887420007ea2cf47ab9b68584b4edfa2b20598c9d509273" -"checksum libp2p-ratelimit 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7abef2e38e9d4bb5036724d325dd0518007e32d73d5171334d4d5355995bb4d8" -"checksum libp2p-secio 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "33c208e7c74c15c72e7092503d6772ed5b2add2155e08234ae10169769e3135c" -"checksum libp2p-swarm 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "8788a19e54240ba632ec0913bb951e7fd744f4e6151b2dc1a8b44d80b2947830" -"checksum libp2p-tcp 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "180543c45126c4eec42f35594e169a8d7c891253bc127297ca7781c05ad8bce6" -"checksum libp2p-uds 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ffaf9dfc24beaf7ad5be01a6eabe67842cd02575da68a08ebe11b5a8821fc4a9" -"checksum libp2p-wasm-ext 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "35307568a484cce18eae7516201ecbbfc3fb7e17c7f235d407690aee6adaa046" -"checksum libp2p-websocket 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "2e6c6d86998e66848f16b65e89896d94fa3825e218d2fc44cbc6b84e8ef97bb9" -"checksum libp2p-yamux 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1c03b89d025c7b01c966348e4d618b1ec4b95f3c09749ca9f2b2c98240aabfe6" +"checksum libp2p 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)" = "4183fb4be621d97baebbbe0c499d6ae337e9e6ec955f9fa3cb29e55547dfacdb" +"checksum libp2p-core 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)" = "2a7ebd9d597299512e096cc1bd58e955c03ef28f33214a33b9c7e4ace109ff41" +"checksum libp2p-core-derive 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)" = "baffb3527eac95b717e5ebcd6539007152019a06b00548352cbd74474c07db27" +"checksum libp2p-deflate 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "84bb91afe976893b9822103522cc178bd66eb7aa8e54c69ddd9e1825a3d894ab" +"checksum libp2p-dns 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b43d79936984b46a5ef4d7b070eaf786f6fab2d1a57e07646306b492e38b2d7f" +"checksum libp2p-floodsub 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)" = "798615b01761454818788dafe61b4fe2bda4306bfa5378cbe8715f57b752235f" +"checksum libp2p-identify 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a0a630d5ab928403e426672187514884a9ed0ea2065970ef0ec64971770be6d5" +"checksum libp2p-kad 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a66d2214dd47fa67878eaf0d76d19fd129eff65c45f83617829eb177b7285f97" +"checksum libp2p-mdns 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)" = "cbd443101542670935b6e6863b7bb88c10ac04393062e662201a3c104d80ae00" +"checksum libp2p-mplex 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)" = "59f283e603b078aa88e65c66c5d4f842f67bfbe4d016b0ae345b7e3bb78fe0af" +"checksum libp2p-noise 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)" = "6ab3c7b36cde3bfe18a1d7a0a5693361115066365d32c60f210acc8224b88017" +"checksum libp2p-ping 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)" = "006bbfcb7d6ca7e617cb2924d99fff0e391d4c6e42e7047e226692c8c3e1f6a0" +"checksum libp2p-plaintext 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a4e673668e5ef47689ca832c33f2dc1e321ede245ee50b6084e4c45cce10fff6" +"checksum libp2p-ratelimit 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)" = "838538f6df5941626047903d14edc3112afb2807fc139535a8ca78469ccaf1ac" +"checksum libp2p-secio 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a99533cb55b9554d2927ad8a220c87b4e0bbfdec22b738eb6030b03e6a722fa1" +"checksum libp2p-swarm 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "541f66cc794e522fb8072d35dba6be3fe4c3ffeadbed39bf4a6939d0695b4134" +"checksum libp2p-tcp 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b4e56f7c7e31d303898d51b293f8d95dcb99e6293fefebe184df03e82dd37571" +"checksum libp2p-uds 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)" = "180fa5ceb2f986786b4fca9582f6ffb98772db2e44df07c800693c97205e3310" +"checksum libp2p-wasm-ext 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a806f0e4985ae2dbac2cbebadb72d586ffe2e1f62a265f5e019e57a3f02aa481" +"checksum libp2p-websocket 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e0dd3cb203aaa1736a38cdd157709153f90bfaed06b87f4dc3ebb62b5d79a643" +"checksum libp2p-yamux 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a37bed07c8ee0ceeecdfb90d703aa6b1cec99a69b4157e5f7f2c03acacbfca15" "checksum librocksdb-sys 5.18.3 (registry+https://github.com/rust-lang/crates.io-index)" = "d19778314deaa7048f2ea7d07b8aa12e1c227acebe975a37eeab6d2f8c74e41b" "checksum libsecp256k1 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "688e8d65e495567c2c35ea0001b26b9debf0b4ea11f8cccc954233b75fc3428a" +"checksum libsecp256k1 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "dcf0a4113e7b18b72b9b65d5b35335d99865ef059034426e4b85ad63adddf996" "checksum libz-sys 1.0.25 (registry+https://github.com/rust-lang/crates.io-index)" = "2eb5e43362e38e2bca2fd5f5134c4d4564a23a5c28e9b95411652021a8675ebe" "checksum linked-hash-map 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)" = "ae91b68aebc4ddb91978b11a1b02ddd8602a05ec19002801c5666000e05e0f83" "checksum linked_hash_set 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "3c7c91c4c7bbeb4f2f7c4e5be11e6a05bd6830bc37249c47ce1ad86ad453ff9c" @@ -6293,93 +6758,98 @@ dependencies = [ "checksum lock_api 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ed946d4529956a20f2d63ebe1b69996d5a2137c91913fe3ebbeff957f5bca7ff" "checksum lock_api 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "f8912e782533a93a167888781b836336a6ca5da6175c05944c86cf28c31104dc" "checksum log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)" = "e19e8d5c34a3e0e2223db8e060f9e8264aeeb5c5fc64a4ee9965c062211c024b" -"checksum log 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)" = "c275b6ad54070ac2d665eef9197db647b32239c9d244bfb6f041a766d00da5b3" +"checksum log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)" = "14b6052be84e6b71ab17edffc2eeabf5c2c3ae1fdb464aae35ac50c67a44e1f7" "checksum lru-cache 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "31e24f1ad8321ca0e8a1e0ac13f23cb668e6f5466c2c57319f6a5cf1cc8e3b1c" "checksum malloc_size_of_derive 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "35adee9ed962cf7d07d62cb58bc45029f3227f5b5b86246caa8632f06c187bc3" "checksum matches 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)" = "7ffc5c5338469d4d3ea17d269fa8ea3512ad247247c30bd2df69e68309ed0a08" "checksum memchr 2.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "88579771288728879b57485cc7d6b07d648c9f0141eb955f8ab7f9d45394468e" "checksum memoffset 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "ce6075db033bbbb7ee5a0bbd3a3186bbae616f57fb001c485c7ff77955f8177f" -"checksum memory-db 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a688133a81c915553c1dd9c3e859949f43a854cb8f8773e690e849b53b1f89f0" +"checksum memory-db 0.15.2 (registry+https://github.com/rust-lang/crates.io-index)" = "ef49315991403ba5fa225a70399df5e115f57b274cb0b1b4bcd6e734fa5bd783" "checksum memory_units 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "71d96e3f3c0b6325d8ccd83c33b28acb183edcb6c67938ba104ec546854b0882" -"checksum merlin 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "66448a173ad394ef5ebf734efa724f3644dcffda083b1e89979da4461ddac079" +"checksum merlin 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "de2d16d3b15fec5943d1144f861f61f279d165fdd60998ca262913b9bf1c8adb" "checksum mime 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)" = "ba626b8a6de5da682e1caa06bdb42a335aee5a84db8e5046a3e8ab17ba0a3ae0" -"checksum miniz-sys 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)" = "1e9e3ae51cea1576ceba0dde3d484d30e6e5b86dee0b2d412fe3a16a15c98202" -"checksum miniz_oxide 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c061edee74a88eb35d876ce88b94d77a0448a201de111c244b70d047f5820516" -"checksum miniz_oxide_c_api 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "6c675792957b0d19933816c4e1d56663c341dd9bfa31cb2140ff2267c1d8ecf4" +"checksum miniz_oxide 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7108aff85b876d06f22503dcce091e29f76733b2bfdd91eebce81f5e68203a10" "checksum mio 0.6.19 (registry+https://github.com/rust-lang/crates.io-index)" = "83f51996a3ed004ef184e16818edc51fadffe8e7ca68be67f9dee67d84d0ff23" "checksum mio-extras 2.0.5 (registry+https://github.com/rust-lang/crates.io-index)" = "46e73a04c2fa6250b8d802134d56d554a9ec2922bf977777c805ea5def61ce40" "checksum mio-uds 0.6.7 (registry+https://github.com/rust-lang/crates.io-index)" = "966257a94e196b11bb43aca423754d87429960a768de9414f3691d6957abf125" "checksum miow 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "8c1f2f3b1cf331de6896aabf6e9d55dca90356cc9960cca7eaaf408a355ae919" -"checksum multistream-select 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "f989d40aab0ed0d83c1cdb4856b5790e980b96548d1a921f280e985eb049f38d" +"checksum multimap 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "2eb04b9f127583ed176e163fb9ec6f3e793b87e21deedd5734a69386a18a0151" +"checksum multistream-select 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "e8f3cb4c93f2d79811fc11fa01faab99d8b7b8cbe024b602c27434ff2b08a59d" "checksum names 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ef320dab323286b50fb5cdda23f61c796a72a89998ab565ca32525c5c556f2da" "checksum native-tls 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "4b2df1a4c22fd44a62147fd8f13dd0f95c9d8ca7b2610299b2a2f9cf8964274e" "checksum net2 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)" = "42550d9fb7b6684a6d404d9fa7250c2eb2646df731d1c06afc06dcee9e1bcf88" "checksum nix 0.14.1 (registry+https://github.com/rust-lang/crates.io-index)" = "6c722bee1037d430d0f8e687bbdbf222f27cc6e4e68d5caf630857bb2b6dbdce" "checksum nodrop 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)" = "2f9667ddcc6cc8a43afc9b7917599d7216aa09c463919ea32c59ed6cac8bc945" -"checksum nohash-hasher 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "0d138afcce92d219ccb6eb53d9b1e8a96ac0d633cfd3c53cd9856d96d1741bb8" +"checksum nohash-hasher 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "4e657a6ec97f9a3ba46f6f7034ea6db9fcd5b71d25ef1074b7bc03da49be0e8e" "checksum nom 4.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "2ad2a91a8e869eeb30b9cb3119ae87773a8f4ae617f41b1eb9c154b2905f7bd6" -"checksum num-bigint 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "57450397855d951f1a41305e54851b1a7b8f5d2e349543a02a2effe25459f718" +"checksum num-bigint 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "f9c3f34cdd24f334cb265d9bf8bfa8a241920d026916785747a92f0e55541a1a" "checksum num-integer 0.1.41 (registry+https://github.com/rust-lang/crates.io-index)" = "b85e541ef8255f6cf42bbfe4ef361305c6c135d10919ecc26126c4e5ae94bc09" "checksum num-rational 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "f2885278d5fe2adc2f75ced642d52d879bffaceb5a2e0b1d4309ffdfb239b454" "checksum num-traits 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)" = "6ba9a427cfca2be13aa6f6403b0b7e7368fe982bfa16fccc450ce74c46cd9b32" "checksum num_cpus 1.10.1 (registry+https://github.com/rust-lang/crates.io-index)" = "bcef43580c035376c0705c42792c294b66974abbfd2789b511784023f71f3273" "checksum ole32-sys 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "5d2c49021782e5233cd243168edfa8037574afed4eba4bbaf538b3d8d1789d8c" "checksum once_cell 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)" = "532c29a261168a45ce28948f9537ddd7a5dd272cc513b3017b1e82a88f962c37" -"checksum opaque-debug 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "93f5bb2e8e8dec81642920ccff6b61f1eb94fa3020c5a325c9851ff604152409" +"checksum once_cell 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)" = "d584f08c2d717d5c23a6414fc2822b71c651560713e54fa7eace675f758a355e" +"checksum opaque-debug 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "2839e79665f131bdb5782e51f2c6c9599c133c6098982a54c794358bf432529c" "checksum openssl 0.10.24 (registry+https://github.com/rust-lang/crates.io-index)" = "8152bb5a9b5b721538462336e3bef9a539f892715e5037fda0f984577311af15" "checksum openssl-probe 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "77af24da69f9d9341038eba93a073b1fdaaa1b788221b00a69bce9e762cb32de" -"checksum openssl-sys 0.9.48 (registry+https://github.com/rust-lang/crates.io-index)" = "b5ba300217253bcc5dc68bed23d782affa45000193866e025329aa8a7a9f05b8" +"checksum openssl-sys 0.9.49 (registry+https://github.com/rust-lang/crates.io-index)" = "f4fad9e54bd23bd4cbbe48fdc08a1b8091707ac869ef8508edea2fec77dcc884" "checksum output_vt100 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "53cdc5b785b7a58c5aad8216b3dfa114df64b0b06ae6e1501cef91df2fbdf8f9" -"checksum owning_ref 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "cdf84f41639e037b484f93433aa3897863b561ed65c6e59c7073d7c561710f37" "checksum owning_ref 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "49a4b8ea2179e6a2e27411d3bca09ca6dd630821cf6894c6c7c8467a8ee7ef13" "checksum parity-bytes 0.1.0 (git+https://github.com/paritytech/parity-common?rev=b0317f649ab2c665b7987b8475878fc4d2e1f81d)" = "" -"checksum parity-codec 4.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "2900f06356edf90de66a2922db622b36178dca71e85625eae58d0d9cc6cff2ac" "checksum parity-multiaddr 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "045b3c7af871285146300da35b1932bb6e4639b66c7c98e85d06a32cbc4e8fa7" "checksum parity-multihash 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "df3a17dc27848fd99e4f87eb0f8c9baba6ede0a6d555400c850ca45254ef4ce3" -"checksum parity-scale-codec 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "00fd14ff806ad82cea9a8f909bb116443d92efda7c9acd4502690af64741ad81" -"checksum parity-scale-codec-derive 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "a81f3cd93ed368a8e41c4e79538e99ca6e8f536096de23e3a0bc3e782093ce28" +"checksum parity-scale-codec 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)" = "001fbbb956d8593f321c7a784f64d16b2c99b2657823976eea729006ad2c3668" +"checksum parity-scale-codec-derive 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "42af752f59119656fa3cb31e8852ed24e895b968c0bdb41847da7f0cea6d155f" "checksum parity-send-wrapper 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "aa9777aa91b8ad9dd5aaa04a9b6bcb02c7f1deb952fca5a66034d5e63afc5c6f" "checksum parity-util-mem 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e2005637ccf93dbb60c85081ccaaf3f945f573da48dcc79f27f9646caa3ec1dc" -"checksum parity-wasm 0.31.3 (registry+https://github.com/rust-lang/crates.io-index)" = "511379a8194230c2395d2f5fa627a5a7e108a9f976656ce723ae68fca4097bfc" -"checksum parking_lot 0.5.5 (registry+https://github.com/rust-lang/crates.io-index)" = "d4d05f1349491390b1730afba60bb20d55761bef489a954546b58b4b34e1e2ac" +"checksum parity-wasm 0.40.3 (registry+https://github.com/rust-lang/crates.io-index)" = "1e39faaa292a687ea15120b1ac31899b13586446521df6c149e46f1584671e0f" "checksum parking_lot 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)" = "f0802bff09003b291ba756dc7e79313e51cc31667e94afbe847def490424cde5" "checksum parking_lot 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)" = "ab41b4aed082705d1056416ae4468b6ea99d52599ecf3169b00088d43113e337" "checksum parking_lot 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "fa7767817701cce701d5585b9c4db3cdd02086398322c1d7e8bf5094a96a2ce7" "checksum parking_lot 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "f842b1982eb6c2fe34036a4fbfb06dd185a3f5c8edfaacdf7d1ea10b07de6252" -"checksum parking_lot_core 0.2.14 (registry+https://github.com/rust-lang/crates.io-index)" = "4db1a8ccf734a7bce794cc19b3df06ed87ab2f3907036b693c68f56b4d4537fa" "checksum parking_lot_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "ad7f7e6ebdc79edff6fdcb87a55b620174f7a989e3eb31b65231f4af57f00b8c" "checksum parking_lot_core 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "94c8c7923936b28d546dfd14d4472eaf34c99b14e1c973a32b3e6d4eb04298c9" "checksum parking_lot_core 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "cb88cb1cb3790baa6776844f968fea3be44956cf184fa1be5a03341f5491278c" "checksum parking_lot_core 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)" = "b876b1b9e7ac6e1a74a6da34d25c42e17e8862aa409cbbbdcfc8d86c6f3bc62b" -"checksum paste 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "1f4a4a1c555c6505821f9d58b8779d0f630a6b7e4e1be24ba718610acf01fa79" -"checksum paste-impl 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "26e796e623b8b257215f27e6c80a5478856cae305f5b59810ff9acdaa34570e6" +"checksum paste 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "423a519e1c6e828f1e73b720f9d9ed2fa643dce8a7737fb43235ce0b41eeaa49" +"checksum paste-impl 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "4214c9e912ef61bf42b81ba9a47e8aad1b2ffaf739ab162bf96d1e011f54e6c5" "checksum pbkdf2 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "006c038a43a45995a9670da19e67600114740e8511d4333bf97a56e66a7542d9" +"checksum pdqselect 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "4ec91767ecc0a0bbe558ce8c9da33c068066c57ecc8bb8477ef8c1ad3ef77c27" "checksum peeking_take_while 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "19b17cddbe7ec3f8bc800887bab5e717348c95ea2ca0b1bf0837fb964dc67099" "checksum percent-encoding 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "31010dd2e1ac33d5b46a5b413495239882813e0369f8ed8a5e266f173602f831" +"checksum percent-encoding 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d4fd5641d01c8f18a23da7b6fe29298ff4b55afcccdf78973b24cf3175fee32e" +"checksum petgraph 0.4.13 (registry+https://github.com/rust-lang/crates.io-index)" = "9c3659d1ee90221741f65dd128d9998311b0e40c5d3c23a62445938214abce4f" "checksum pin-utils 0.1.0-alpha.4 (registry+https://github.com/rust-lang/crates.io-index)" = "5894c618ce612a3fa23881b152b608bafb8c56cfc22f434a3ba3120b40f7b587" -"checksum pkg-config 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)" = "a7c1d2cfa5a714db3b5f24f0915e74fcdf91d09d496ba61329705dda7774d2af" +"checksum pkg-config 0.3.16 (registry+https://github.com/rust-lang/crates.io-index)" = "72d5370d90f49f70bd033c3d75e87fc529fbfff9d6f7cccef07d6170079d91ea" "checksum ppv-lite86 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)" = "e3cbf9f658cdb5000fcf6f362b8ea2ba154b9f146a61c7a20d647034c6b6561b" "checksum pretty_assertions 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)" = "3f81e1644e1b54f5a68959a29aa86cde704219254669da328ecfdf6a1f09d427" -"checksum primitive-types 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e44400d651ca5276415dc8e00541c5c9d03844f1f0a87ad28f0a8fadcb2300bc" +"checksum primitive-types 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "83ef7b3b965c0eadcb6838f34f827e1dfb2939bdd5ebd43f9647e009b12b0371" "checksum proc-macro-crate 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "e10d4b51f154c8a7fb96fd6dad097cb74b863943ec010ac94b9fd1be8861fe1e" -"checksum proc-macro-hack 0.5.8 (registry+https://github.com/rust-lang/crates.io-index)" = "982a35d1194084ba319d65c4a68d24ca28f5fdb5b8bc20899e4eef8641ea5178" +"checksum proc-macro-hack 0.5.10 (registry+https://github.com/rust-lang/crates.io-index)" = "114cdf1f426eb7f550f01af5f53a33c0946156f6814aec939b3bd77e844f9a9d" "checksum proc-macro2 0.4.30 (registry+https://github.com/rust-lang/crates.io-index)" = "cf3d2011ab5c909338f7887f4fc896d35932e29146c12c8d01da6b22a80ba759" -"checksum protobuf 2.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "8aefcec9f142b524d98fc81d07827743be89dd6586a1ba6ab21fa66a500b3fa5" -"checksum pwasm-utils 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)" = "efb0dcbddbb600f47a7098d33762a00552c671992171637f5bb310b37fe1f0e4" +"checksum proc-macro2 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "afdc77cc74ec70ed262262942ebb7dac3d479e9e5cfa2da1841c0806f6cdabcc" +"checksum prost 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "96d14b1c185652833d24aaad41c5832b0be5616a590227c1fbff57c616754b23" +"checksum prost-build 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "eb788126ea840817128183f8f603dce02cb7aea25c2a0b764359d8e20010702e" +"checksum prost-derive 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "5e7dc378b94ac374644181a2247cebf59a6ec1c88b49ac77f3a94b86b79d0e11" +"checksum prost-types 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1de482a366941c8d56d19b650fac09ca08508f2a696119ee7513ad590c8bac6f" +"checksum protobuf 2.8.1 (registry+https://github.com/rust-lang/crates.io-index)" = "40361836defdd5871ff7e84096c6f6444af7fc157f8ef1789f54f147687caa20" +"checksum pwasm-utils 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1d473123ba135028544926f7aa6f34058d8bc6f120c4fcd3777f84af724280b3" "checksum quick-error 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "5fb6ccf8db7bbcb9c2eae558db5ab4f3da1c2a87e4e597ed394726bc8ea6ca1d" "checksum quick-error 1.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "9274b940887ce9addde99c4eee6b5c44cc494b182b97e73dc8ffdcb3397fd3f0" -"checksum quickcheck 0.8.5 (registry+https://github.com/rust-lang/crates.io-index)" = "9c35d9c36a562f37eca96e79f66d5fd56eefbc22560dacc4a864cabd2d277456" +"checksum quickcheck 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d5ca504a2fdaa08d3517f442fbbba91ac24d1ec4c51ea68688a038765e3b2662" "checksum quote 0.6.13 (registry+https://github.com/rust-lang/crates.io-index)" = "6ce23b6b870e8f94f81fb0a363d65d86675884b34a09043c81e5562f11c1f8e1" +"checksum quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "053a8c8bcc71fcce321828dc897a98ab9760bef03a4fc36693c231e5b3216cfe" "checksum rand 0.3.23 (registry+https://github.com/rust-lang/crates.io-index)" = "64ac302d8f83c0c1974bf758f6b041c6c8ada916fbb44a609158ca8b064cc76c" "checksum rand 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)" = "552840b97013b1a26992c11eac34bdd778e464601a4c2054b5f0bff7c6761293" "checksum rand 0.5.6 (registry+https://github.com/rust-lang/crates.io-index)" = "c618c47cd3ebd209790115ab837de41425723956ad3ce2e6a7f09890947cacb9" "checksum rand 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)" = "6d71dacdc3c88c1fde3885a3be3fbab9f35724e6ce99467f7d9c5026132184ca" -"checksum rand 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d47eab0e83d9693d40f825f86948aa16eff6750ead4bdffc4ab95b8b3a7f052c" +"checksum rand 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)" = "3ae1b169243eaf61759b8475a998f0a385e42042370f3a7dbaf35246eacc8412" "checksum rand_chacha 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "556d3a1ca6600bfcbab7c7c91ccb085ac7fbbcd70e008a98742e7847f4f7bcef" "checksum rand_chacha 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "03a2a90da8c7523f554344f921aa97283eadf6ac484a6d2a7d0212fa7f8d6853" "checksum rand_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7a6fdeb83b075e8266dcc8762c22776f6877a63111121f5f8c7411e5be7eed4b" -"checksum rand_core 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d0e7a549d590831370895ab7ba4ea0c1b6b011d106b5ff2da6eee112615e6dc0" -"checksum rand_core 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "615e683324e75af5d43d8f7a39ffe3ee4a9dc42c5c701167a71dc59c3a493aca" +"checksum rand_core 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "9c33a3c44ca05fa6f1807d8e6743f3824e8509beca625669633be0acbdf509dc" +"checksum rand_core 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "90bde5296fc891b0cef12a6d03ddccc162ce7b2aff54160af9338f8d40df6d19" "checksum rand_hc 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7b40677c7be09ae76218dc623efbf7b18e34bced3f38883af07bb75630a21bc4" "checksum rand_hc 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ca3129af7b92a17112d59ad498c6f81eaf463253766b90396d39ea7a39d6613c" "checksum rand_isaac 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "ded997c9d5f13925be2a6fd7e66bf1872597f759fd9dd93513dd7e92e5a5ee08" @@ -6388,30 +6858,31 @@ dependencies = [ "checksum rand_pcg 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "abf9b09b01790cfe0364f52bf32995ea3c39f4d2dd011eac241d2914146d0b44" "checksum rand_xorshift 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "cbf7e9e623549b0e21f6e97cf8ecf247c1a8fd2e8a992ae265314300b2455d5c" "checksum rand_xoshiro 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "03b418169fb9c46533f326efd6eed2576699c44ca92d3052a066214a8d828929" -"checksum rayon 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a4b0186e22767d5b9738a05eab7c6ac90b15db17e5b5f9bd87976dd7d89a10a4" -"checksum rayon-core 1.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ebbe0df8435ac0c397d467b6cad6d25543d06e8a019ef3f6af3c384597515bd2" +"checksum rayon 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "83a27732a533a1be0a0035a111fe76db89ad312f6f0347004c220c57f209a123" +"checksum rayon-core 1.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "98dcf634205083b17d0861252431eb2acbfb698ab7478a2d20de07954f47ec7b" "checksum rdrand 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "678054eb77286b51581ba43620cc911abf02758c91f93f479767aed0f90458b2" "checksum redox_syscall 0.1.56 (registry+https://github.com/rust-lang/crates.io-index)" = "2439c63f3f6139d1b57529d16bc3b8bb855230c8efcc5d3a896c8bea7c3b1e84" "checksum ref_thread_local 0.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d813022b2e00774a48eaf43caaa3c20b45f040ba8cbf398e2e8911a06668dbe6" -"checksum regex 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "6b23da8dfd98a84bd7e08700190a5d9f7d2d38abd4369dd1dae651bc40bfd2cc" +"checksum regex 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "dc220bd33bdce8f093101afe22a037b8eb0e5af33592e6a9caafff0d4cb81cbd" "checksum regex-automata 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)" = "92b73c2a1770c255c240eaa4ee600df1704a38dc3feaa6e949e7fcd4f8dc09f9" -"checksum regex-syntax 0.6.10 (registry+https://github.com/rust-lang/crates.io-index)" = "cd5485bf1523a9ed51c4964273f22f63f24e31632adb5dad134f488f86a3875c" +"checksum regex-syntax 0.6.12 (registry+https://github.com/rust-lang/crates.io-index)" = "11a7e20d1cce64ef2fed88b66d347f88bd9babb82845b2b858f3edbf59a4f716" "checksum remove_dir_all 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)" = "4a83fa3702a688b9359eccba92d153ac33fd2e8462f9e0e3fdf155239ea7792e" "checksum rhododendron 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "36542aafc2429a4c010fafa079a20dee953b663cb2427f51d86cf1d436846b4d" "checksum ring 0.14.6 (registry+https://github.com/rust-lang/crates.io-index)" = "426bc186e3e95cac1e4a4be125a4aca7e84c2d616ffc02244eef36e2a60a093c" "checksum rocksdb 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "f1651697fefd273bfb4fd69466cc2a9d20de557a0213b97233b22b5e95924b5e" -"checksum rpassword 3.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "c34fa7bcae7fca3c8471e8417088bbc3ad9af8066b0ecf4f3c0d98a0d772716e" -"checksum rustc-demangle 0.1.15 (registry+https://github.com/rust-lang/crates.io-index)" = "a7f4dccf6f4891ebcc0c39f9b6eb1a83b9bf5d747cb439ec6fba4f3b977038af" +"checksum rpassword 4.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "f072d931f11a96546efd97642e1e75e807345aced86b947f9239102f262d0fcd" +"checksum rustc-demangle 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)" = "4c691c0e608126e00913e33f0ccf3727d5fc84573623b8d65b2df340b5201783" "checksum rustc-hex 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "403bb3a286107a04825a5f82e1270acc1e14028d3d554d7a1e08914549575ab8" "checksum rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "138e3e0acb6c9fb258b19b67cb8abd63c00679d2851805ea151465464fe9030a" "checksum rustls 0.15.2 (registry+https://github.com/rust-lang/crates.io-index)" = "f271e3552cd835fa28c541c34a7e8fdd8cdff09d77fe4eb8f6c42e87a11b096e" +"checksum rustversion 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "b48139cfc215c6cc70d43c6c555a59e723c3b5adb26a4cfa09f815a5ae5871e8" "checksum rw-stream-sink 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "2f9cbe61c20455d3015b2bb7be39e1872310283b8e5a52f5b242b0ac7581fe78" "checksum ryu 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c92464b447c0ee8c4fb3824ecc8383b81717b9f1e74ba2e72540aef7b9f82997" "checksum safe-mix 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7f7bf422d23a88c16d5090d455f182bc99c60af4df6a345c63428acf5129e347" -"checksum safemem 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "8dca453248a96cb0749e36ccdfe2b0b4e54a61bfef89fb97ec621eb8e0a93dd9" +"checksum safemem 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "d2b08423011dae9a5ca23f07cf57dac3857f5c885d352b76f6d95f4aea9434d0" "checksum same-file 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)" = "585e8ddcedc187886a30fa705c47985c3fa88d06624095856b36ca0b82ff4421" -"checksum schannel 0.1.15 (registry+https://github.com/rust-lang/crates.io-index)" = "f2f6abf258d99c3c1c5c2131d99d064e94b7b3dd5f416483057f308fea253339" -"checksum schnorrkel 0.8.4 (registry+https://github.com/rust-lang/crates.io-index)" = "77e8d6a92f49a53f21b71c090a5559bf45c469071ebe556aebaf2dca3abc5cb5" +"checksum schannel 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)" = "87f550b06b6cba9c8b8be3ee73f391990116bf527450d2556e9b9ce263b9a021" +"checksum schnorrkel 0.8.5 (registry+https://github.com/rust-lang/crates.io-index)" = "eacd8381b3c37840c9c9f40472af529e49975bdcbc24f83c31059fd6539023d3" "checksum scopeguard 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "94258f53601af11e6a49f722422f6e3425c52b06245a5cf9bc09908b174f5e27" "checksum scopeguard 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b42e15e59b18a828bbf5c58ea01debb36b9b096346de35d941dcb89009f24a0d" "checksum sct 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "2f5adf8fbd58e1b1b52699dc8bed2630faecb6d8c7bee77d009d6bbe4af569b9" @@ -6421,8 +6892,8 @@ dependencies = [ "checksum semver 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1d7eb9ef2c18661902cc47e535f9bc51b78acd254da71d375c2f6720d9a40403" "checksum semver-parser 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3" "checksum send_wrapper 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a0eddf2e8f50ced781f288c19f18621fa72a3779e3cb58dbf23b07469b0abeb4" -"checksum serde 1.0.97 (registry+https://github.com/rust-lang/crates.io-index)" = "d46b3dfedb19360a74316866cef04687cd4d6a70df8e6a506c63512790769b72" -"checksum serde_derive 1.0.97 (registry+https://github.com/rust-lang/crates.io-index)" = "c22a0820adfe2f257b098714323563dd06426502abbbce4f51b72ef544c5027f" +"checksum serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)" = "9796c9b7ba2ffe7a9ce53c2287dfc48080f4b2b362fcc245a259b3a7201119dd" +"checksum serde_derive 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)" = "4b133a43a1ecd55d4086bd5b4dc6c1751c68b1bfbeba7a5040442022c7e7c02e" "checksum serde_json 1.0.40 (registry+https://github.com/rust-lang/crates.io-index)" = "051c49229f282f7c6f3813f8286cc1e3323e8051823fce42c7ea80fe13521704" "checksum sha-1 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)" = "23962131a91661d643c98940b20fcaffe62d776a823247be80a48fcb8b6fce68" "checksum sha1 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "2579985fda508104f7587689507983eadd6a6e84dd35d6d115361f530916fa0d" @@ -6438,13 +6909,13 @@ dependencies = [ "checksum slog_derive 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "9eff3b513cf2e0d1a60e1aba152dc72bedc5b05585722bb3cebd7bcb1e31b98f" "checksum smallvec 0.6.10 (registry+https://github.com/rust-lang/crates.io-index)" = "ab606a9c5e214920bb66c458cd7be8ef094f813f20fe77a54cc7dbfff220d4b7" "checksum snow 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)" = "5a64f02fd208ef15bd2d1a65861df4707e416151e1272d02c8faafad1c138100" -"checksum soketto 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "db2383e992ba8ba8205cd1169cac2efdf325d3a0da465dc35f63a2074598347e" +"checksum soketto 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "bceb1a3a15232d013d9a3b7cac9e5ce8e2313f348f01d4bc1097e5e53aa07095" "checksum sourcefile 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "4bf77cb82ba8453b42b6ae1d692e4cdc92f9a47beaf89a847c8be83f4e328ad3" -"checksum spin 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "44363f6f51401c34e7be73db0db371c04705d35efbe9f7d6082e03a921a32c55" +"checksum spin 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)" = "6e63cff320ae2c57904679ba7cb63280a3dc4613885beafb148ee7bf9aa9042d" "checksum stable_deref_trait 1.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "dba1a27d3efae4351c8051072d619e3ade2820635c3958d826bfea39d59b54c8" "checksum static_assertions 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)" = "c19be23126415861cb3a23e501d34a708f7f9b2183c5252d690941c2e69199d5" "checksum static_slice 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "92a7e0c5e3dfb52e8fbe0e63a1b947bbb17b4036408b151353c4491374931362" -"checksum stream-cipher 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "8861bc80f649f5b4c9bd38b696ae9af74499d479dbfb327f0607de6b326a36bc" +"checksum stream-cipher 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "8131256a5896cabcf5eb04f4d6dacbe1aefda854b0d9896e09cb58829ec5638c" "checksum string 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "d24114bfcceb867ca7f71a0d3fe45d45619ec47a6fbfa98cb14e14250bfa5d6d" "checksum strsim 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "bb4f380125926a99e52bc279241539c018323fab05ad6368b56f93d9369ff550" "checksum structopt 0.2.18 (registry+https://github.com/rust-lang/crates.io-index)" = "16c2cdbf9cc375f15d1b4141bc48aeef444806655cd0e904207edc8d68d86ed7" @@ -6452,12 +6923,13 @@ dependencies = [ "checksum strum 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e5d1c33039533f051704951680f1adfd468fd37ac46816ded0d9ee068e60f05f" "checksum strum_macros 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)" = "47cd23f5c7dee395a00fa20135e2ec0fffcdfa151c56182966d7a3261343432e" "checksum substrate-bip39 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "3be511be555a3633e71739a79e4ddff6a6aaa6579fa6114182a51d72c3eb93c5" -"checksum substrate-wasm-builder-runner 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "f52ecbff6cc3d6e5c6401828e15937b680f459d6803ce238f01fe615bc40d071" +"checksum substrate-wasm-builder-runner 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "af21b27fad38b212c1919f700cb0def33c88cde14d22e0d1b17d4521f4eb8b40" "checksum subtle 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "2d67a5a62ba6e01cb2192ff309324cb4875d0c451d55fe2319433abe7a05a8ee" -"checksum subtle 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "01dca13cf6c3b179864ab3292bd794e757618d35a7766b7c46050c614ba00829" -"checksum syn 0.15.42 (registry+https://github.com/rust-lang/crates.io-index)" = "eadc09306ca51a40555dd6fc2b415538e9e18bc9f870e47b1a524a79fe2dcf5e" +"checksum subtle 2.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "ab3af2eb31c42e8f0ccf43548232556c42737e01a96db6e1777b0be108e79799" +"checksum syn 0.15.44 (registry+https://github.com/rust-lang/crates.io-index)" = "9ca4b3b69a77cbe1ffc9e198781b7acb0c7365a883670e8f1c1bc66fba79a5c5" +"checksum syn 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)" = "66850e97125af79138385e9b88339cbcd037e3f28ceab8c5ad98e64f0f1f80bf" "checksum synstructure 0.10.2 (registry+https://github.com/rust-lang/crates.io-index)" = "02353edf96d6e4dc81aea2d8490a7e9db177bf8acb0e951c24940bf866cb313f" -"checksum sysinfo 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c3e2cab189e59f72710e3dd5e1e0d5be0f6c5c999c326f2fdcdf3bf4483ec9fd" +"checksum sysinfo 0.9.5 (registry+https://github.com/rust-lang/crates.io-index)" = "d5bd3b813d94552a8033c650691645f8dd5a63d614dddd62428a95d3931ef7b6" "checksum take_mut 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "f764005d11ee5f36500a149ace24e00e3da98b0158b3e2d53a7495660d3f4d60" "checksum target_info 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c63f48baada5c52e65a29eef93ab4f8982681b67f9e8d29c7b05abcfec2b9ffe" "checksum tempdir 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)" = "15f2b5fb00ccdf689e0149d1b1b3c03fead81c2b37735d812fa8bddbbf41b6d8" @@ -6469,7 +6941,6 @@ dependencies = [ "checksum tiny-bip39 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)" = "c1c5676413eaeb1ea35300a0224416f57abc3bd251657e0fafc12c47ff98c060" "checksum tiny-keccak 1.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1d8a021c69bb74a44ccedb824a046447e2c84a01df9e5c20779750acb38e11b2" "checksum tinytemplate 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "4574b75faccaacddb9b284faecdf0b544b80b6b294f3d062d325c5726a209c20" -"checksum tk-listen 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "5462b0f968c0457efe38fcd2df7e487096b992419e4f5337b06775a614bbda4b" "checksum tokio 0.1.22 (registry+https://github.com/rust-lang/crates.io-index)" = "5a09c0b5bb588872ab2f09afa13ee6e9dac11e10a0ec9e8e3ba39a5a5d530af6" "checksum tokio-buf 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "8fb220f46c53859a4b7ec083e41dec9778ff0b1851c0942b211edb89e0ccdc46" "checksum tokio-codec 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "5c501eceaf96f0e1793cf26beb63da3d11c738c4a943fdf3746d81d64684c39f" @@ -6478,78 +6949,79 @@ dependencies = [ "checksum tokio-executor 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)" = "0f27ee0e6db01c5f0b2973824547ce7e637b2ed79b891a9677b0de9bd532b6ac" "checksum tokio-fs 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "3fe6dc22b08d6993916647d108a1a7d15b9cd29c4f4496c62b92c45b5041b7af" "checksum tokio-io 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)" = "5090db468dad16e1a7a54c8c67280c5e4b544f3d3e018f0b913b400261f85926" -"checksum tokio-reactor 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)" = "6af16bfac7e112bea8b0442542161bfc41cbfa4466b580bdda7d18cb88b911ce" +"checksum tokio-reactor 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)" = "c56391be9805bc80163151c0b9e5164ee64f4b0200962c346fea12773158f22d" "checksum tokio-rustls 0.10.0-alpha.4 (registry+https://github.com/rust-lang/crates.io-index)" = "3e5cebc3ca33110e460c4d2e7c5e863b159fadcbf125449d896720695b2af709" "checksum tokio-sync 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "2162248ff317e2bc713b261f242b69dbb838b85248ed20bb21df56d60ea4cae7" "checksum tokio-tcp 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "1d14b10654be682ac43efee27401d792507e30fd8d26389e1da3b185de2e4119" -"checksum tokio-threadpool 0.1.15 (registry+https://github.com/rust-lang/crates.io-index)" = "90ca01319dea1e376a001e8dc192d42ebde6dd532532a5bad988ac37db365b19" +"checksum tokio-threadpool 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)" = "2bd2c6a3885302581f4401c82af70d792bb9df1700e7437b0aeb4ada94d5388c" "checksum tokio-timer 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)" = "f2106812d500ed25a4f38235b9cae8f78a09edf43203e16e59c3b769a342a60e" "checksum tokio-tls 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "354b8cd83825b3c20217a9dc174d6a0c67441a2fae5c41bcb1ea6679f6ae0f7c" -"checksum tokio-udp 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "66268575b80f4a4a710ef83d087fdfeeabdce9b74c797535fbac18a2cb906e92" +"checksum tokio-udp 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "f02298505547f73e60f568359ef0d016d5acd6e830ab9bc7c4a5b3403440121b" "checksum tokio-uds 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)" = "037ffc3ba0e12a0ab4aca92e5234e0dedeb48fddf6ccd260f1f150a36a9f2445" -"checksum toml 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "b8c96d7873fa7ef8bdeb3a9cda3ac48389b4154f32b9803b4bc26220b677b039" +"checksum toml 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)" = "c7aabe75941d914b72bf3e5d3932ed92ce0664d49d8432305a8b547c37227724" "checksum traitobject 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "efd1f82c56340fdf16f2a953d7bda4f8fdffba13d93b00844c25572110b26079" -"checksum trie-bench 0.16.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a1861db0e69cc3d650083ca1e70e6f5aeb871491409abc0efaf321dff48df24a" -"checksum trie-db 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)" = "9b65d609ae631d808c6c1cc23a622733d5a0b66a7d67e9f5cd5171562a1f4cb5" -"checksum trie-root 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c31b0eaa64e50d686c89e6d4817ed33cb18cfa249e9071b7918b18ecfacc7867" -"checksum trie-standardmap 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)" = "64fda153c00484d640bc91334624be22ead0e5baca917d9fd53ff29bdebcf9b2" +"checksum trie-bench 0.16.2 (registry+https://github.com/rust-lang/crates.io-index)" = "3073600c543ed001319d7e092c46dfd8c245af1a218ec5c75eb01582660a2b3e" +"checksum trie-db 0.15.2 (registry+https://github.com/rust-lang/crates.io-index)" = "d0b62d27e8aa1c07414549ac872480ac82380bab39e730242ab08d82d7cc098a" +"checksum trie-root 0.15.2 (registry+https://github.com/rust-lang/crates.io-index)" = "0b779f7c1c8fe9276365d9d5be5c4b5adeacf545117bb3f64c974305789c5c0b" +"checksum trie-standardmap 0.15.2 (registry+https://github.com/rust-lang/crates.io-index)" = "c3161ba520ab28cd8e6b68e1126f1009f6e335339d1a73b978139011703264c8" "checksum try-lock 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "e604eb7b43c06650e854be16a2a03155743d3752dd1c943f6829e26b7a36e382" -"checksum trybuild 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)" = "f2e8e773ac21d176ee05243456b9f1a942cd1a586dab188ced05b8e8d58dc635" +"checksum trybuild 1.0.15 (registry+https://github.com/rust-lang/crates.io-index)" = "9fc69705e261edf3b9a87012b2353a49f49c0465186b5ab96e95f6983d6984aa" "checksum twofish 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "712d261e83e727c8e2dbb75dacac67c36e35db36a958ee504f2164fc052434e1" -"checksum twox-hash 1.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "e7834480552ffc48e1930ceddd701f47d2234319d80b7bcbbe2fe7202933c101" +"checksum twox-hash 1.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3bfd5b7557925ce778ff9b9ef90e3ade34c524b5ff10e239c69a42d546d2af56" "checksum typeable 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "1410f6f91f21d1612654e7cc69193b0334f909dcf2c790c4826254fbb86f8887" -"checksum typenum 1.10.0 (registry+https://github.com/rust-lang/crates.io-index)" = "612d636f949607bdf9b123b4a6f6d966dedf3ff669f7f045890d3a4a73948169" -"checksum ucd-util 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "fa9b3b49edd3468c0e6565d85783f51af95212b6fa3986a5500954f00b460874" -"checksum uint 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "f5375d2c574f89adad4108ad525c93e39669853a602560bf5ed4ca9943b10799" +"checksum typenum 1.11.2 (registry+https://github.com/rust-lang/crates.io-index)" = "6d2783fe2d6b8c1101136184eb41be8b1ad379e4657050b8aaff0c79ee7575f9" +"checksum uint 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)" = "f8f0f47ed099f0db671ce82c66548c5de012e3c0cba3963514d1db15c7588701" "checksum unicase 1.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7f4765f83163b74f957c797ad9253caf97f103fb064d3999aea9568d09fc8a33" -"checksum unicase 2.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a84e5511b2a947f3ae965dcb29b13b7b1691b6e7332cf5dbc1744138d5acb7f6" +"checksum unicase 2.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "2e2e6bd1e59e56598518beb94fd6db628ded570326f0a98c679a304bd9f00150" "checksum unicode-bidi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "49f2bd0c6468a8230e1db229cff8029217cf623c767ea5d60bfbd42729ea54d5" "checksum unicode-normalization 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)" = "141339a08b982d942be2ca06ff8b076563cbe223d1befd5450716790d44e2426" "checksum unicode-segmentation 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1967f4cdfc355b37fd76d2a954fb2ed3871034eb4f26d60537d88795cfc332a9" -"checksum unicode-width 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "882386231c45df4700b275c7ff55b6f3698780a650026380e72dabe76fa46526" +"checksum unicode-width 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "7007dbd421b92cc6e28410fe7362e2e0a2503394908f417b68ec8d1c364c4e20" "checksum unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "fc72304796d0818e357ead4e000d19c9c174ab23dc11093ac919054d20a6a7fc" +"checksum unicode-xid 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "826e7639553986605ec5979c7dd957c7895e93eabed50ab2ffa7f6128a75097c" "checksum unsigned-varint 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "2c64cdf40b4a9645534a943668681bcb219faf51874d4b65d2e0abda1b10a2ab" "checksum untrusted 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)" = "55cd1f4b4e96b46aeb8d4855db4a7a9bd96eeeb5c6a1ab54593328761642ce2f" "checksum url 1.7.2 (registry+https://github.com/rust-lang/crates.io-index)" = "dd4e7c0d531266369519a4aa4f399d748bd37043b00bde1e4ff1f60a120b355a" -"checksum utf8-ranges 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "9d50aa7650df78abf942826607c62468ce18d9019673d4a2ebe1865dbb96ffde" +"checksum url 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "75b414f6c464c879d7f9babf951f23bc3743fb7313c081b2e6ca719067ea9d61" "checksum vcpkg 0.2.7 (registry+https://github.com/rust-lang/crates.io-index)" = "33dd455d0f96e90a75803cfeb7f948768c08d70a6de9a8d2362461935698bf95" "checksum vec_map 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)" = "05c78687fb1a80548ae3250346c3db86a80a7cdd77bda190189f2d0a0987c81a" -"checksum vecarray 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "d4d68a73b7d7d950c6558b6009e9fba229fb67562bda9fd02198f614f4ecf83f" "checksum vergen 3.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "6aba5e34f93dc7051dfad05b98a18e9156f27e7b431fe1d2398cb6061c0a1dba" "checksum version_check 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "914b1a6776c4c929a602fafd8bc742e06365d4bcbe48c30f9cca5824f70dc9dd" "checksum void 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "6a02e4885ed3bc0f2de90ea6dd45ebcbb66dacffe03547fadbb0eeae2770887d" -"checksum wabt 0.7.4 (registry+https://github.com/rust-lang/crates.io-index)" = "74e463a508e390cc7447e70f640fbf44ad52e1bd095314ace1fdf99516d32add" -"checksum wabt-sys 0.5.4 (registry+https://github.com/rust-lang/crates.io-index)" = "a6265b25719e82598d104b3717375e37661d41753e2c84cde3f51050c7ed7e3c" +"checksum wabt 0.9.2 (registry+https://github.com/rust-lang/crates.io-index)" = "3c5c5c1286c6e578416982609f47594265f9d489f9b836157d403ad605a46693" +"checksum wabt-sys 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "af5d153dc96aad7dc13ab90835b892c69867948112d95299e522d370c4e13a08" "checksum walkdir 2.2.9 (registry+https://github.com/rust-lang/crates.io-index)" = "9658c94fa8b940eab2250bd5a457f9c48b748420d71293b165c8cdbe2f55f71e" "checksum want 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b6395efa4784b027708f7451087e647ec73cc74f5d9bc2e418404248d679a230" -"checksum wasm-bindgen 0.2.48 (registry+https://github.com/rust-lang/crates.io-index)" = "4de97fa1806bb1a99904216f6ac5e0c050dc4f8c676dc98775047c38e5c01b55" -"checksum wasm-bindgen-backend 0.2.48 (registry+https://github.com/rust-lang/crates.io-index)" = "5d82c170ef9f5b2c63ad4460dfcee93f3ec04a9a36a4cc20bc973c39e59ab8e3" -"checksum wasm-bindgen-futures 0.3.25 (registry+https://github.com/rust-lang/crates.io-index)" = "73c25810ee684c909488c214f55abcbc560beb62146d352b9588519e73c2fed9" -"checksum wasm-bindgen-macro 0.2.48 (registry+https://github.com/rust-lang/crates.io-index)" = "f07d50f74bf7a738304f6b8157f4a581e1512cd9e9cdb5baad8c31bbe8ffd81d" -"checksum wasm-bindgen-macro-support 0.2.48 (registry+https://github.com/rust-lang/crates.io-index)" = "95cf8fe77e45ba5f91bc8f3da0c3aa5d464b3d8ed85d84f4d4c7cc106436b1d7" -"checksum wasm-bindgen-shared 0.2.48 (registry+https://github.com/rust-lang/crates.io-index)" = "d9c2d4d4756b2e46d3a5422e06277d02e4d3e1d62d138b76a4c681e925743623" -"checksum wasm-bindgen-webidl 0.2.48 (registry+https://github.com/rust-lang/crates.io-index)" = "24e47859b4eba3d3b9a5c2c299f9d6f8d0b613671315f6f0c5c7f835e524b36a" +"checksum wasi 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b89c3ce4ce14bdc6fb6beaf9ec7928ca331de5df7e5ea278375642a2f478570d" +"checksum wasm-bindgen 0.2.51 (registry+https://github.com/rust-lang/crates.io-index)" = "cd34c5ba0d228317ce388e87724633c57edca3e7531feb4e25e35aaa07a656af" +"checksum wasm-bindgen-backend 0.2.51 (registry+https://github.com/rust-lang/crates.io-index)" = "927196b315c23eed2748442ba675a4c54a1a079d90d9bdc5ad16ce31cf90b15b" +"checksum wasm-bindgen-futures 0.3.27 (registry+https://github.com/rust-lang/crates.io-index)" = "83420b37346c311b9ed822af41ec2e82839bfe99867ec6c54e2da43b7538771c" +"checksum wasm-bindgen-macro 0.2.51 (registry+https://github.com/rust-lang/crates.io-index)" = "92c2442bf04d89792816650820c3fb407af8da987a9f10028d5317f5b04c2b4a" +"checksum wasm-bindgen-macro-support 0.2.51 (registry+https://github.com/rust-lang/crates.io-index)" = "9c075d27b7991c68ca0f77fe628c3513e64f8c477d422b859e03f28751b46fc5" +"checksum wasm-bindgen-shared 0.2.51 (registry+https://github.com/rust-lang/crates.io-index)" = "83d61fe986a7af038dd8b5ec660e5849cbd9f38e7492b9404cc48b2b4df731d1" +"checksum wasm-bindgen-webidl 0.2.51 (registry+https://github.com/rust-lang/crates.io-index)" = "9b979afb0535fe4749906a674082db1211de8aef466331d43232f63accb7c07c" "checksum wasm-timer 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "3d6101df9a5987df809216bdda7289f52b58128e6b6a6546e9ee3e6b632b4921" -"checksum wasmi 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "48437c526d40a6a593c50c5367dac825b8d6a04411013e866eca66123fb56faa" -"checksum wasmi-validation 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ab380192444b3e8522ae79c0a1976e42a82920916ccdfbce3def89f456ea33f3" -"checksum web-sys 0.3.25 (registry+https://github.com/rust-lang/crates.io-index)" = "86d515d2f713d3a6ab198031d2181b7540f8e319e4637ec2d4a41a208335ef29" +"checksum wasmi 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "f31d26deb2d9a37e6cfed420edce3ed604eab49735ba89035e13c98f9a528313" +"checksum wasmi-validation 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "6bc0356e3df56e639fc7f7d8a99741915531e27ed735d911ed83d7e1339c8188" +"checksum web-sys 0.3.28 (registry+https://github.com/rust-lang/crates.io-index)" = "c84440699cd02ca23bed6f045ffb1497bc18a3c2628bd13e2093186faaaacf6b" "checksum webpki 0.19.1 (registry+https://github.com/rust-lang/crates.io-index)" = "4f7e1cd7900a3a6b65a3e8780c51a3e6b59c0e2c55c6dc69578c288d69f7d082" "checksum webpki-roots 0.16.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c10fa4212003ba19a564f25cd8ab572c6791f99a03cc219c13ed35ccab00de0e" -"checksum websocket 0.22.4 (registry+https://github.com/rust-lang/crates.io-index)" = "0adcd2a64c5746c9702b354a1b992802b0c363df1dfa324a74cb7aebe10e0cbf" +"checksum websocket 0.23.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b255b190f412e45000c35be7fe9b48b39a2ac5eb90d093d421694e5dae8b335c" "checksum weedle 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3bb43f70885151e629e2a19ce9e50bd730fd436cfd4b666894c9ce4de9141164" "checksum which 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "b57acb10231b9493c8472b20cb57317d0679a49e0bdbee44b3b803a6473af164" "checksum winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)" = "167dc9d6949a9b857f3451275e911c3f44255842c1f7a76f33c55103a909087a" -"checksum winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)" = "f10e386af2b13e47c89e7236a7a14a086791a2b88ebad6df9bf42040195cf770" +"checksum winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)" = "8093091eeb260906a183e6ae1abdba2ef5ef2257a21801128899c3fc699229c6" "checksum winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "2d315eee3b34aca4797b2da6b13ed88266e6d612562a0c46390af8299fc699bc" "checksum winapi-i686-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" "checksum winapi-util 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7168bab6e1daee33b4557efd0e95d5ca70a03706d39fa5f3fe7a236f584b03c9" "checksum winapi-x86_64-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" -"checksum wincolor 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "561ed901ae465d6185fa7864d63fbd5720d0ef718366c9a4dc83cf6170d7e9ba" -"checksum ws 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)" = "ec91ea61b83ce033c43c06c52ddc7532f465c0153281610d44c58b74083aee1a" +"checksum wincolor 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "96f5016b18804d24db43cebf3c77269e7569b8954a8464501c216cc5e070eaa9" +"checksum ws 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "8a6f5bb86663ff4d1639408410f50bf6050367a8525d644d49a6894cd618a631" "checksum ws2_32-sys 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "d59cefebd0c892fa2dd6de581e937301d8552cb44489cdff035c6187cb63fa5e" "checksum x25519-dalek 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7ee1585dc1484373cbc1cee7aafda26634665cf449436fd6e24bfd1fad230538" "checksum xdg 2.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d089681aa106a86fade1b0128fb5daf07d5867a509ab036d99988dec80429a57" "checksum yaml-rust 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "e66366e18dc58b46801afbf2ca7661a9f59cc8c5962c29892b6039b4f86fa992" "checksum yamux 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "01bd67889938c48f0049fc60a77341039e6c3eaf16cb7693e6ead7c0ba701295" -"checksum zeroize 0.9.2 (registry+https://github.com/rust-lang/crates.io-index)" = "4177936c03b5a349c1b8e4509c46add268e66bc66fe92663729fa0570fe4f213" -"checksum zeroize_derive 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "afd1469e4bbca3b96606d26ba6e9bd6d3aed3b1299c82b92ec94377d22d78dbc" +"checksum zeroize 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)" = "4090487fa66630f7b166fba2bbb525e247a5449f41c468cc1d98f8ae6ac03120" +"checksum zeroize 0.9.3 (registry+https://github.com/rust-lang/crates.io-index)" = "45af6a010d13e4cf5b54c94ba5a2b2eba5596b9e46bf5875612d332a1f2b3f86" +"checksum zeroize_derive 0.9.3 (registry+https://github.com/rust-lang/crates.io-index)" = "080616bd0e31f36095288bb0acdf1f78ef02c2fa15527d7e993f2a6c7591643e" diff --git a/Cargo.toml b/Cargo.toml index be6c89c2b7b1002b39511cc7423d57ea89578027..71ba1c17f16954beecdd95548eaa97837a738b21 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -11,24 +11,29 @@ edition = "2018" [dependencies] cli = { package = "node-cli", path = "node/cli" } -futures = "0.1" -ctrlc = { version = "3.0", features = ["termination"] } +futures = "0.1.29" +ctrlc = { version = "3.1.3", features = ["termination"] } [build-dependencies] -vergen = "3" +vergen = "3.0.4" [workspace] members = [ + "core/authority-discovery", "core/application-crypto", + "core/chain-spec", + "core/chain-spec/derive", "core/cli", "core/client", "core/client/db", + "core/client/header-metadata", "core/consensus/aura", "core/consensus/babe", "core/consensus/common", "core/consensus/rhd", "core/consensus/slots", "core/consensus/uncles", + "core/consensus/pow", "core/executor", "core/executor/runtime-test", "core/finality-grandpa", @@ -40,6 +45,7 @@ members = [ "core/panic-handler", "core/primitives", "core/rpc", + "core/rpc/primitives", "core/rpc-servers", "core/serializer", "core/service", @@ -48,6 +54,7 @@ members = [ "core/sr-api-macros", "core/sr-io", "core/sr-primitives", + "core/sr-staking-primitives", "core/sr-sandbox", "core/sr-std", "core/sr-version", @@ -62,6 +69,7 @@ members = [ "core/utils/fork-tree", "core/utils/wasm-builder", "core/utils/wasm-builder-runner", + "core/wasm-interface", "srml/support", "srml/support/procedural", "srml/support/procedural/tools", @@ -75,26 +83,34 @@ members = [ "srml/collective", "srml/democracy", "srml/elections", + "srml/elections-phragmen", "srml/example", "srml/executive", "srml/finality-tracker", "srml/generic-asset", "srml/grandpa", "srml/im-online", + "srml/authority-discovery", "srml/indices", "srml/membership", "srml/metadata", + "srml/offences", + "srml/scored-pool", "srml/session", "srml/staking", + "srml/staking/reward-curve", "srml/sudo", "srml/system", "srml/timestamp", "srml/treasury", + "srml/utility", "node/cli", "node/executor", "node/primitives", - "node/runtime", + "node/rpc", "node/rpc-client", + "node/runtime", + "node/testing", "node-template", "subkey", "test-utils/chain-spec-builder", diff --git a/Dockerfile b/Dockerfile index 0271db8d1461d7a8c58fb52f9f6306e5ca833e2e..1ebc7b04aa87e5cc95838444d39229c52201e917 100644 --- a/Dockerfile +++ b/Dockerfile @@ -5,13 +5,15 @@ FROM phusion/baseimage:0.10.2 as builder LABEL maintainer="chevdor@gmail.com" LABEL description="This is the build stage for Substrate. Here we create the binary." +ENV DEBIAN_FRONTEND=noninteractive + ARG PROFILE=release WORKDIR /substrate COPY . /substrate RUN apt-get update && \ - apt-get dist-upgrade -y && \ + apt-get dist-upgrade -y -o Dpkg::Options::="--force-confold" && \ apt-get install -y cmake pkg-config libssl-dev git clang RUN curl https://sh.rustup.rs -sSf | sh -s -- -y && \ diff --git a/PULL_REQUEST_TEMPLATE.md b/PULL_REQUEST_TEMPLATE.md index 9b368f3f04d4c60d5f7bdfcf83eaa323340ab181..9755fa0e40ff9bcef1003d0933b174cc1adee06b 100644 --- a/PULL_REQUEST_TEMPLATE.md +++ b/PULL_REQUEST_TEMPLATE.md @@ -15,6 +15,7 @@ Before you submitting, please check that: - Any panickers have a proof or removed. - [ ] You bumped the runtime version if there are breaking changes in the **runtime**. - [ ] You updated any rustdocs which may have changed +- [ ] Has the PR altered the external API or interfaces used by Polkadot? Do you have the corresponding Polkadot PR ready? After you've read this notice feel free to remove it. Thank you! diff --git a/README.adoc b/README.adoc index aaab6df3cc2f2cafcb730b1001e85bd4375a5e42..810d07c61210d781ca605eb09b8bcfee156ff0d9 100644 --- a/README.adoc +++ b/README.adoc @@ -20,13 +20,13 @@ See also https://www.parity.io/what-is-substrate/. Substrate is still an early stage project, and while it has already been used as the basis of major projects like Polkadot, using it is still a significant undertaking. In particular, you should have a good knowledge of blockchain concepts and basic cryptography. Terminology like header, block, client, hash, transaction and signature should be familiar. At present you will need a working knowledge of Rust to be able to do anything interesting (though eventually, we aim for this not to be the case). -Substrate is designed to be used in one of three ways: +Substrate is designed for use in one of three ways: -1. Trivial: By running the Substrate binary `substrate` and configuring it with a genesis block that includes the current demonstration runtime. In this case, you just build Substrate, configure a JSON file and launch your own blockchain. This affords you the least amount of customisability, primarily allowing you to change the genesis parameters of the various included runtime modules such as balances, staking, block-period, fees and governance. +**1. Trivial**: By running the Substrate binary `substrate` and configuring it with a genesis block that includes the current demonstration runtime. In this case, you just build Substrate, configure a JSON file, and launch your own blockchain. This affords you the least amount of customizability, primarily allowing you to change the genesis parameters of the various included runtime modules such as balances, staking, block-period, fees, and governance. -2. Modular: By hacking together modules from the Substrate Runtime Module Library into a new runtime and possibly altering or reconfiguring the Substrate client's block authoring logic. This affords you a very large amount of freedom over your own blockchain's logic, letting you change datatypes, add or remove modules and, crucially, add your own modules. Much can be changed without touching the block-authoring logic (since it is generic). If this is the case, then the existing Substrate binary can be used for block authoring and syncing. If the block authoring logic needs to be tweaked, then a new altered block-authoring binary must be built as a separate project and used by validators. This is how the Polkadot relay chain is built and should suffice for almost all circumstances in the near to mid-term. +**2. Modular**: By hacking together modules from the Substrate Runtime Module Library (SRML) into a new runtime and possibly altering or reconfiguring the Substrate client's block authoring logic. This affords you a very large amount of freedom over your blockchain's logic, letting you change datatypes, add or remove modules, and crucially, add your own modules. Much can be changed without touching the block authoring logic (since it is generic). If this is the case, then the existing Substrate binary can be used for block authoring and syncing. If the block authoring logic needs to be tweaked, then a new, altered block authoring binary must be built as a separate project and used by validators. This is how the Polkadot relay chain is built and should suffice for almost all circumstances in the near to mid-term. -3. Generic: The entire Substrate Runtime Module Library can be ignored and the entire runtime designed and implemented from scratch. If desired, this can be done in a language other than Rust, providing it can target WebAssembly. If the runtime can be made to be compatible with the existing client's block authoring logic, then you can simply construct a new genesis block from your Wasm blob and launch your chain with the existing Rust-based Substrate client. If not, then you'll need to alter the client's block authoring logic accordingly. This is probably a useless option for most projects right now, but provides complete flexibility allowing for a long-term far-reaching upgrade path for the Substrate paradigm. +**3. Generic**: The entire SRML can be ignored and the entire runtime designed and implemented from scratch. If desired, this can be done in a language other than Rust, provided it can target WebAssembly. If the runtime can be made compatible with the existing client's block authoring logic, then you can simply construct a new genesis block from your Wasm blob and launch your chain with the existing Rust-based Substrate client. If not, then you'll need to alter the client's block authoring logic accordingly. This is probably a useless option for most projects right now, but provides complete flexibility allowing for a long-term, far-reaching upgrade path for the Substrate paradigm. === The Basics of Substrate @@ -133,7 +133,7 @@ First let's get a template chainspec that you can edit. We'll use the "staging" substrate build-spec --chain=staging > ~/chainspec.json ---- -Now, edit `~/chainspec.json` in your editor. There are a lot of individual fields for each module, and one very large one which contains the Webassembly code blob for this chain. The easiest field to edit is the block `period`. Change it to 10 (seconds): +Now, edit `~/chainspec.json` in your editor. There are a lot of individual fields for each module, and one very large one which contains the WebAssembly code blob for this chain. The easiest field to edit is the block `period`. Change it to 10 (seconds): [source, json] ---- @@ -160,7 +160,7 @@ It won't do much until you start producing blocks though, so to do that you'll n [source, shell] ---- -substrate --chain ~/mychain.json --validator --key ... +substrate --chain ~/mychain.json --validator ---- You can distribute `mychain.json` so that everyone can synchronize and (depending on your authorities list) validate on your chain. @@ -193,6 +193,11 @@ You will also need to install the following packages: [source, shell] sudo apt install cmake pkg-config libssl-dev git clang libclang-dev +- Linux on ARM: +`rust-lld` is required for linking wasm, but is missing on non Tier 1 platforms. +So, use this https://github.com/Plume-org/Plume/blob/master/script/wasm-deps.sh[script] +to build `lld` and create the symlink `/usr/bin/rust-lld` to the build binary. + - Mac: [source, shell] brew install cmake pkg-config openssl git llvm @@ -277,13 +282,13 @@ Or just run the tests of a specific package (i.e. `cargo test -p srml-assets`) You can start a development chain with: [source, shell] -cargo run \-- --dev +cargo run --release -- --dev -Detailed logs may be shown by running the node with the following environment variables set: `RUST_LOG=debug RUST_BACKTRACE=1 cargo run \-- --dev`. +Detailed logs may be shown by running the node with the following environment variables set: `RUST_LOG=debug RUST_BACKTRACE=1 cargo run --release \-- --dev`. -If you want to see the multi-node consensus algorithm in action locally, then you can create a local testnet with two validator nodes for Alice and Bob, who are the initial authorities of the genesis chain specification that have been endowed with a testnet DOTs. We'll give each node a name and expose them so they are listed on link:https://telemetry.polkadot.io/#/Local%20Testnet[Telemetry] . You'll need two terminals windows open. +If you want to see the multi-node consensus algorithm in action locally, then you can create a local testnet with two validator nodes for Alice and Bob, who are the initial authorities of the genesis chain specification that have been endowed with a testnet DOTs. We'll give each node a name and expose them so they are listed on link:https://telemetry.polkadot.io/#/Local%20Testnet[Telemetry]. You'll need two terminal windows open. -We'll start Alice's substrate node first on default TCP port 30333 with her chain database stored locally at `/tmp/alice`. The Bootnode ID of her node is `QmRpheLN4JWdAnY7HGJfWFNbfkQCb6tFf4vvA6hgjMZKrR`, which is generated from the `--node-key` value that we specify below: +We'll start Alice's Substrate node first on default TCP port 30333 with her chain database stored locally at `/tmp/alice`. The Bootnode ID of her node is `QmRpheLN4JWdAnY7HGJfWFNbfkQCb6tFf4vvA6hgjMZKrR`, which is generated from the `--node-key` value that we specify below: [source, shell] cargo run --release \-- \ @@ -294,7 +299,7 @@ cargo run --release \-- \ --telemetry-url ws://telemetry.polkadot.io:1024 \ --validator -In the second terminal, we'll run the following to start Bob's substrate node on a different TCP port of 30334, and with his chain database stored locally at `/tmp/bob`. We'll specify a value for the `--bootnodes` option that will connect his node to Alice's Bootnode ID on TCP port 30333: +In the second terminal, we'll run the following to start Bob's Substrate node on a different TCP port of 30334, and with his chain database stored locally at `/tmp/bob`. We'll specify a value for the `--bootnodes` option that will connect his node to Alice's Bootnode ID on TCP port 30333: [source, shell] cargo run --release \-- \ @@ -321,6 +326,8 @@ we support multiple environment variables: * `TRIGGER_WASM_BUILD` - Can be set to trigger a WASM build. On subsequent calls the value of the variable needs to change. As WASM builder instructs `cargo` to watch for file changes this environment variable should only be required in certain circumstances. +* `WASM_TARGET_DIRECTORY` - Will copy any build WASM binary to the given directory. The path needs + to be absolute. Each project can be skipped individually by using the environment variable `SKIP_PROJECT_NAME_WASM_BUILD`. Where `PROJECT_NAME` needs to be replaced by the name of the cargo project, e.g. `node-runtime` will @@ -333,13 +340,13 @@ Flaming Fir is the new testnet for Substrate master (2.0) to test the latest dev Since Flaming Fir is targeting the master branch we make absolutely no guarantees of stability and/or persistence of the network. We might reset the chain at any time if it is necessary to deploy new changes. Currently, the validators are running with a client built from `d013bd900`, if you build from this commit you should be able to successfully sync, later commits may not work as new breaking changes may be introduced in master. -Latest known working version: `d013bd900` +Latest known working version: `a2a0eb5398d6223e531455b4c155ef053a4a3a2b` [source, shell] ---- git clone https://github.com/paritytech/substrate.git cd substrate -git checkout -b flaming-fir d013bd900 +git checkout -b flaming-fir a2a0eb5398d6223e531455b4c155ef053a4a3a2b ---- You can run the tests if you like: @@ -378,6 +385,39 @@ git checkout -b v1.0 origin/v1.0 You can then follow the same steps for building and running as described above in <>. +== Key management + +Keys in Substrate are stored in the keystore in the file system. To store keys into this keystore, +you need to use one of the two provided RPC calls. If your keys are encrypted or should be encrypted +by the keystore, you need to provide the key using one of the cli arguments `--password`, +`--password-interactive` or `--password-filename`. + +=== Recommended RPC call + +For most users who want to run a validator node, the `author_rotateKeys` RPC call is sufficient. +The RPC call will generate `N` Session keys for you and return their public keys. `N` is the number +of session keys configured in the runtime. The output of the RPC call can be used as input for the +`session::set_keys` transaction. + +``` +curl -H 'Content-Type: application/json' --data '{ "jsonrpc":"2.0", "method":"author_rotateKeys", "id":1 }' localhost:9933 +``` + +=== Advanced RPC call + +If the Session keys need to match a fixed seed, they can be set individually key by key. The RPC call +expects the key seed and the key type. The key types supported by default in Substrate are listed +https://github.com/paritytech/substrate/blob/master/core/primitives/src/crypto.rs#L767[here], but the +user can declare any key type. + +``` +curl -H 'Content-Type: application/json' --data '{ "jsonrpc":"2.0", "method":"author_insertKey", "params":["KEY_TYPE", "SEED", "PUBLIC"],"id":1 }' localhost:9933 +``` + +`KEY_TYPE` - needs to be replaced with the 4-character key type identifier. +`SEED` - is the seed of the key. +`PUBLIC` - public key for the given key. + == Documentation === Viewing documentation for Substrate packages diff --git a/SECURITY.md b/SECURITY.md new file mode 100644 index 0000000000000000000000000000000000000000..b850e5462e2a8368c1e58a417eb9cef229b49537 --- /dev/null +++ b/SECURITY.md @@ -0,0 +1,101 @@ +# Security Policy + +Parity Technologies is committed to resolving security vulnerabilities in our software quickly and carefully. We take the necessary steps to minimize risk, provide timely information, and deliver vulnerability fixes and mitigations required to address security issues. + +## Reporting a Vulnerability + +Security vulnerabilities in Parity software should be reported by email to security@parity.io. If you think your report might be eligible for the Parity Bug Bounty Program, your email should be send to bugbounty@parity.io. + +Your report should include the following: + +- your name +- description of the vulnerability +- attack scenario (if any) +- components +- reproduction +- other details + +Try to include as much information in your report as you can, including a description of the vulnerability, its potential impact, and steps for reproducing it. Be sure to use a descriptive subject line. + +You'll receive a response to your email within two business days indicating the next steps in handling your report. We encourage finders to use encrypted communication channels to protect the confidentiality of vulnerability reports. You can encrypt your report using our public key. This key is [on MIT's key server](https://pgp.mit.edu/pks/lookup?op=get&search=0x5D0F03018D07DE73) server and reproduced below. + +After the initial reply to your report, our team will endeavor to keep you informed of the progress being made towards a fix. These updates will be sent at least every five business days. + +Thank you for taking the time to responsibly disclose any vulnerabilities you find. + +## Responsible Investigation and Reporting + +Responsible investigation and reporting includes, but isn't limited to, the following: + +- Don't violate the privacy of other users, destroy data, etc. +- Don’t defraud or harm Parity Technologies Ltd or its users during your research; you should make a good faith effort to not interrupt or degrade our services. +- Don't target our physical security measures, or attempt to use social engineering, spam, distributed denial of service (DDOS) attacks, etc. +- Initially report the bug only to us and not to anyone else. +- Give us a reasonable amount of time to fix the bug before disclosing it to anyone else, and give us adequate written warning before disclosing it to anyone else. +- In general, please investigate and report bugs in a way that makes a reasonable, good faith effort not to be disruptive or harmful to us or our users. Otherwise your actions might be interpreted as an attack rather than an effort to be helpful. + +## Bug Bounty Program + +Our Bug Bounty Program allows us to recognise and reward members of the Parity community for helping us find and address significant bugs, in accordance with the terms of the Parity Bug Bounty Program. A detailed description on eligibility, rewards, legal information and terms & conditions for contributors can be found on [our website](https://paritytech.io/bug-bounty.html). + + + + + + +## Plaintext PGP Key + +``` +-----BEGIN PGP PUBLIC KEY BLOCK----- + +mQINBF0vHwQBEADKui4qAo4bzdzRhMm+uhUpYGf8jjjmET3zJ8kKQIpp6JTsV+HJ +6m1We0QYeMRXoOYH1xVHBf2zNCuHS0nSQdUCQA7SHWsPB05STa2hvlR7fSdQnCCp +gnLOJWXvvedlRDIAhvqI6cwLdUlXgVSKEwrwmrpiBhh4NxI3qX+LyIa+Ovkchu2S +d/YCnE4GqojSGRfJYiGwe2N+sF7OfaoKhQuTrtdDExHrMU4cWnTXW2wyxTr4xkj9 +jS2WeLVZWflvkDHT8JD9N6jNxBVEF/Qvjk83zI0kCOzkhek8x+YUgfLq3/rHOYbX +3pW21ccHYPacHjHWvKE+xRebjeEhJ4KxKHfCVjQcxybwDBqDka1AniZt4CQ7UORf +MU/ue2oSZ9nNg0uMdb/0AbQPZ04OlMcYPAPWzFL08nVPox9wT9uqlL6JtcOeC90h +oOeDmfgwmjMmdwWTRgt9qQjcbgXzVvuAzIGbzj1X3MdLspWdHs/d2+US4nji1TkN +oYIW7vE+xkd3aB+NZunIlm9Rwd/0mSgDg+DaNa5KceOLhq0/qKgcXC/RRU29I8II +tusRoR/oesGJGYTjh4k6PJkG+nvDPsoQrwYT44bhnniS1xYkxWYXF99JFI7LgMdD +e1SgKeIDVpvm873k82E6arp5655Wod1XOjaXBggCwFp84eKcEZEN+1qEWwARAQAB +tClQYXJpdHkgU2VjdXJpdHkgVGVhbSA8c2VjdXJpdHlAcGFyaXR5LmlvPokCVAQT +AQoAPhYhBJ1LK264+XFW0ZZpqf8IEtSRuWeYBQJdLx8EAhsDBQkDwmcABQsJCAcC +BhUKCQgLAgQWAgMBAh4BAheAAAoJEP8IEtSRuWeYL84QAI6NwnwS561DWYYRAd4y +ocGPr3CnwFSt1GjkSkRy3B+tMhzexBg1y7EbLRUefIrO4LwOlywtRk8tTRGgEI4i +5xRLHbOkeolfgCFSpOj5d8cMKCt5HEIv18hsv6dkrzlSYA5NLX/GRBEh3F/0sGny +vCXapfxa1cx72sU7631JBK7t2Tf+MfwxdfyFZ9TI9WdtP5AfVjgTkIVkEDFcZPTc +n3CYXqTYFIBCNUD8LP4iTi3xUt7pTGJQQoFT8l15nJCgzRYQ+tXpoTRlf+/LtXmw +6iidPV87E06jHdK9666rBouIabAtx7i0/4kwo+bSZ8DiSKRUaehiHGd212HSEmdF +jxquWE4pEzoUowYznhSIfR+WWIqRBHxEYarP4m98Hi+VXZ7Fw1ytzO8+BAKnLXnj +2W2+T9qJks5gqVEoaWNnqpvya6JA11QZvZ0w7Om2carDc2ILNm2Xx9J0mRUye8P0 +KxcgqJuKNGFtugebQAsXagkxOKsdKna1PlDlxEfTf6AgI3ST8qSiMAwaaIMB/REF +VKUapGoslQX4tOCjibI2pzEgE//D8NAaSVu2A9+BUcFERdZRxsI7fydIXNeZ2R46 +N2qfW+DP3YR/14QgdRxDItEavUoE1vByRXwIufKAkVemOZzIoFXKFsDeXwqTVW5i +6CXu6OddZ3QHDiT9TEbRny4QuQINBF0vKCwBEACnP5J7LEGbpxNBrPvGdxZUo0YA +U8RgeKDRPxJTvMo27V1IPZGaKRCRq8LBfg/eHhqZhQ7SLJBjBljd8kuT5dHDBTRe +jE1UIOhmnlSlrEJjAmpVO08irlGpq1o+8mGcvkBsR0poCVjeNeSnwYfRnR+c3GK5 +Er6/JRqfN4mJvnEC9/Pbm6C7ql6YLKxC3yqzF97JL5brbbuozrW7nixY/yAI8619 +VlBIMP7PAUbGcnSQyuV5b/Wr2Sgr6NJclnNSLjh2U9/Du6w/0tDGlMBts8HjRnWJ +BXbkTdQKCTaqgK68kTKSiN1/x+lynxHC2AavMpH/08Kopg2ZCzJowMKIgcB+4Z/I +DJKZWHWKumhaZMGXcWgzgcByog9IpamuROEZFJNEUAFf7YIncEckPSif4looiOdS +VurKZGvYXXaGSsZbGgHxI5CWu7ZxMdLBLvtOcCYmRQrG+g/h+PGU5BT0bNAfNTkm +V3/n1B/TWbpWRmB3AwT2emQivXHkaubGI0VivhaO43AuI9JWoqiMqFtxbuTeoxwD +xlu2Dzcp0v+AR4T5cIG9D5/+yiPc25aIY7cIKxuNFHIDL4td5fwSGC7vU6998PIG +2Y48TGBnw7zpEfDfMayqAeBjX0YU6PTNsvS5O6bP3j4ojTOUYD7Z8QdCvgISDID3 +WMGAdmSwmCRvsQ/OJwARAQABiQI8BBgBCgAmFiEEnUsrbrj5cVbRlmmp/wgS1JG5 +Z5gFAl0vKCwCGwwFCQB2pwAACgkQ/wgS1JG5Z5hdbw//ZqR+JcWm59NUIHjauETJ +sYDYhcAfa3txTacRn5uPz/TQiTd7wZ82+G8Et0ZnpEHy6eWyBqHpG0hiPhFBzxjY +nhjHl8jJeyo2mQIVJhzkL58BHBZk8WM2TlaU7VxZ6TYOmP2y3qf6FD6mCcrQ4Fml +E9f0lyVUoI/5Zs9oF0izRk8vkwaY3UvLM7XEY6nM8GnFG8kaiZMYmx26Zo7Uz31G +7EGGZFsrVDXfNhSJyz79Gyn+Lx9jOTdoR0sH/THYIIosE83awMGE6jKeuDYTbVWu ++ZtHQef+pRteki3wvNLJK+kC1y3BtHqDJS9Lqx0s8SCiVozlC+fZfC9hCtU7bXJK +0UJZ4qjSvj6whzfaNgOZAqJpmwgOnd8W/3YJk1DwUeX98FcU38MR23SOkx2EDdDE +77Kdu62vTs/tLmOTuyKBvYPaHaYulYjQTxurG+o8vhHtaL87ARvuq+83dj+nO5z3 +5O9vkcVJYWjOEnJe7ZvCTxeLJehpCmHIbyUuDx5P24MWVbyXOxIlxNxTqlub5GlW +rQF6Qsa/0k9TRk7Htbct6fAA0/VahJS0g096MrTH8AxBXDNE8lIoNeGikVlaxK9Z +S+aannlWYIJymZ4FygIPPaRlzhAoXBuJd8OaR5giC7dS1xquxKOiQEXTGsLeGFaI +BZYiIhW7GG4ozvKDqyNm4eg= +=yKcB +-----END PGP PUBLIC KEY BLOCK----- +``` diff --git a/ci/check_for_exit.sh b/ci/check_for_exit.sh new file mode 100755 index 0000000000000000000000000000000000000000..c5a54eb83b80051e1a4186626ecb73146899ff74 --- /dev/null +++ b/ci/check_for_exit.sh @@ -0,0 +1,16 @@ +#!/usr/bin/env bash + +# Script that checks that a node exits after `SIGINT` was send. + +set -e + +cargo build --release +./target/release/substrate --dev & +PID=$! + +# Let the chain running for 60 seconds +sleep 60 + +# Send `SIGINT` and give the process 30 seconds to end +kill -INT $PID +timeout 30 tail --pid=$PID -f /dev/null diff --git a/core/application-crypto/Cargo.toml b/core/application-crypto/Cargo.toml index 6d39b12653fa51e5237dc57045948ca7519ed751..3a48446696058f1515f4409b0fe73269fcaf4ef8 100644 --- a/core/application-crypto/Cargo.toml +++ b/core/application-crypto/Cargo.toml @@ -8,9 +8,9 @@ description = "Provides facilities for generating application specific crypto wr [dependencies] primitives = { package = "substrate-primitives", path = "../primitives", default-features = false } codec = { package = "parity-scale-codec", version = "1.0.0", default-features = false, features = ["derive"] } -serde = { version = "1.0", optional = true, features = ["derive"] } +serde = { version = "1.0.101", optional = true, features = ["derive"] } rstd = { package = "sr-std", path = "../sr-std", default-features = false } -rio = { package = "sr-io", path = "../sr-io", default-features = false } +runtime-io = { package = "sr-io", path = "../sr-io", default-features = false } [dev-dependencies] test-client = { package = "substrate-test-runtime-client", path = "../test-runtime/client" } @@ -18,4 +18,4 @@ sr-primitives = { path = "../sr-primitives" } [features] default = [ "std" ] -std = [ "primitives/std", "codec/std", "serde", "rstd/std", "rio/std" ] +std = [ "primitives/std", "codec/std", "serde", "rstd/std", "runtime-io/std" ] diff --git a/core/application-crypto/src/ed25519.rs b/core/application-crypto/src/ed25519.rs index 6c5458492b6b8654201cfeeb7c268b2609e35834..d5c4fd7badabf161dfba2619a82096bdfcb58c40 100644 --- a/core/application-crypto/src/ed25519.rs +++ b/core/application-crypto/src/ed25519.rs @@ -21,7 +21,7 @@ use crate::{RuntimePublic, KeyTypeId}; pub use primitives::ed25519::*; mod app { - use crate::key_types::ED25519; + use primitives::testing::ED25519; crate::app_crypto!(super, ED25519); } @@ -34,26 +34,33 @@ impl RuntimePublic for Public { type Signature = Signature; fn all(key_type: KeyTypeId) -> crate::Vec { - rio::ed25519_public_keys(key_type) + runtime_io::ed25519_public_keys(key_type) } fn generate_pair(key_type: KeyTypeId, seed: Option<&str>) -> Self { - rio::ed25519_generate(key_type, seed) + runtime_io::ed25519_generate(key_type, seed) } fn sign>(&self, key_type: KeyTypeId, msg: &M) -> Option { - rio::ed25519_sign(key_type, self, msg) + runtime_io::ed25519_sign(key_type, self, msg.as_ref()) } fn verify>(&self, msg: &M, signature: &Self::Signature) -> bool { - rio::ed25519_verify(&signature, msg.as_ref(), self) + runtime_io::ed25519_verify(&signature, msg.as_ref(), self) } } #[cfg(test)] mod tests { use sr_primitives::{generic::BlockId, traits::ProvideRuntimeApi}; - use primitives::{testing::KeyStore, crypto::Pair, traits::BareCryptoStore as _}; + use primitives::{ + testing::{ + KeyStore, + ED25519, + }, + crypto::Pair, + traits::BareCryptoStore as _, + }; use test_client::{ TestClientBuilder, DefaultTestClientBuilderExt, TestClientBuilderExt, runtime::{TestAPI, app_crypto::ed25519::{AppPair, AppPublic}}, @@ -67,7 +74,7 @@ mod tests { .test_ed25519_crypto(&BlockId::Number(0)) .expect("Tests `ed25519` crypto."); - let key_pair = keystore.read().ed25519_key_pair(crate::key_types::ED25519, &public.as_ref()) + let key_pair = keystore.read().ed25519_key_pair(ED25519, &public.as_ref()) .expect("There should be at a `ed25519` key in the keystore for the given public key."); assert!(AppPair::verify(&signature, "ed25519", &AppPublic::from(key_pair.public()))); diff --git a/core/application-crypto/src/lib.rs b/core/application-crypto/src/lib.rs index d9bff822eedee4ecc9e99f4e0c4d9393ec6c7577..e3366a461a064ceac0d26ea3485b0ec69e5e2aba 100644 --- a/core/application-crypto/src/lib.rs +++ b/core/application-crypto/src/lib.rs @@ -213,6 +213,7 @@ macro_rules! app_crypto { } impl $crate::RuntimeAppPublic for Public where $public: $crate::RuntimePublic { + const ID: $crate::KeyTypeId = $key_type; type Signature = Signature; fn all() -> $crate::Vec { diff --git a/core/application-crypto/src/sr25519.rs b/core/application-crypto/src/sr25519.rs index af112dc70ee7e6b1c669dae7c5edd6e65dfa59e3..93565a628ffb60577a5cb3289a9dff335e60ea93 100644 --- a/core/application-crypto/src/sr25519.rs +++ b/core/application-crypto/src/sr25519.rs @@ -21,7 +21,7 @@ use crate::{RuntimePublic, KeyTypeId}; pub use primitives::sr25519::*; mod app { - use crate::key_types::SR25519; + use primitives::testing::SR25519; crate::app_crypto!(super, SR25519); } @@ -34,26 +34,33 @@ impl RuntimePublic for Public { type Signature = Signature; fn all(key_type: KeyTypeId) -> crate::Vec { - rio::sr25519_public_keys(key_type) + runtime_io::sr25519_public_keys(key_type) } fn generate_pair(key_type: KeyTypeId, seed: Option<&str>) -> Self { - rio::sr25519_generate(key_type, seed) + runtime_io::sr25519_generate(key_type, seed) } fn sign>(&self, key_type: KeyTypeId, msg: &M) -> Option { - rio::sr25519_sign(key_type, self, msg) + runtime_io::sr25519_sign(key_type, self, msg.as_ref()) } fn verify>(&self, msg: &M, signature: &Self::Signature) -> bool { - rio::sr25519_verify(&signature, msg.as_ref(), self) + runtime_io::sr25519_verify(&signature, msg.as_ref(), self) } } #[cfg(test)] mod tests { use sr_primitives::{generic::BlockId, traits::ProvideRuntimeApi}; - use primitives::{testing::KeyStore, crypto::Pair, traits::BareCryptoStore as _}; + use primitives::{ + testing::{ + KeyStore, + SR25519, + }, + crypto::Pair, + traits::BareCryptoStore as _, + }; use test_client::{ TestClientBuilder, DefaultTestClientBuilderExt, TestClientBuilderExt, runtime::{TestAPI, app_crypto::sr25519::{AppPair, AppPublic}}, @@ -67,7 +74,7 @@ mod tests { .test_sr25519_crypto(&BlockId::Number(0)) .expect("Tests `sr25519` crypto."); - let key_pair = keystore.read().sr25519_key_pair(crate::key_types::SR25519, public.as_ref()) + let key_pair = keystore.read().sr25519_key_pair(SR25519, public.as_ref()) .expect("There should be at a `sr25519` key in the keystore for the given public key."); assert!(AppPair::verify(&signature, "sr25519", &AppPublic::from(key_pair.public()))); diff --git a/core/application-crypto/src/traits.rs b/core/application-crypto/src/traits.rs index d7f1eafe35407d94e6a27ef476e26e67763029bf..aad076bd90012e1ba4e1ebccd47f32101085648d 100644 --- a/core/application-crypto/src/traits.rs +++ b/core/application-crypto/src/traits.rs @@ -17,6 +17,7 @@ use primitives::crypto::{KeyTypeId, CryptoType, IsWrappedBy, Public}; #[cfg(feature = "std")] use primitives::crypto::Pair; +use codec::Codec; /// An application-specific key. pub trait AppKey: 'static + Send + Sync + Sized + CryptoType + Clone { @@ -72,7 +73,7 @@ pub trait AppSignature: AppKey + Eq + PartialEq + MaybeDebugHash { /// A runtime interface for a public key. pub trait RuntimePublic: Sized { /// The signature that will be generated when signing with the corresponding private key. - type Signature; + type Signature: Codec + MaybeDebugHash + Eq + PartialEq + Clone; /// Returns all public keys for the given key type in the keystore. fn all(key_type: KeyTypeId) -> crate::Vec; @@ -95,9 +96,12 @@ pub trait RuntimePublic: Sized { } /// A runtime interface for an application's public key. -pub trait RuntimeAppPublic: Sized { +pub trait RuntimeAppPublic: Sized { + /// An identifier for this application-specific key type. + const ID: KeyTypeId; + /// The signature that will be generated when signing with the corresponding private key. - type Signature; + type Signature: Codec + MaybeDebugHash + Eq + PartialEq + Clone; /// Returns all public keys for this application in the keystore. fn all() -> crate::Vec; diff --git a/core/authority-discovery/Cargo.toml b/core/authority-discovery/Cargo.toml new file mode 100644 index 0000000000000000000000000000000000000000..a74549eb456ada7359d0422c256ffa3841325770 --- /dev/null +++ b/core/authority-discovery/Cargo.toml @@ -0,0 +1,31 @@ +[package] +name = "substrate-authority-discovery" +version = "2.0.0" +authors = ["Parity Technologies "] +edition = "2018" +build = "build.rs" + +[build-dependencies] +prost-build = "0.5.0" + +[dependencies] +authority-discovery-primitives = { package = "substrate-authority-discovery-primitives", path = "./primitives" } +bytes = "0.4.12" +client = { package = "substrate-client", path = "../../core/client" } +codec = { package = "parity-scale-codec", default-features = false, version = "1.0.3" } +derive_more = "0.15.0" +futures = "0.1.29" +libp2p = { version = "0.12.0", default-features = false, features = ["secp256k1", "libp2p-websocket"] } +log = "0.4.8" +network = { package = "substrate-network", path = "../../core/network" } +primitives = { package = "substrate-primitives", path = "../primitives" } +prost = "0.5.0" +serde_json = "1.0.40" +sr-primitives = { path = "../../core/sr-primitives" } +tokio-timer = "0.2.11" + +[dev-dependencies] +parking_lot = "0.9.0" +peerset = { package = "substrate-peerset", path = "../../core/peerset" } +test-client = { package = "substrate-test-runtime-client", path = "../../core/test-runtime/client" } +tokio = "0.1.22" diff --git a/core/authority-discovery/build.rs b/core/authority-discovery/build.rs new file mode 100644 index 0000000000000000000000000000000000000000..ed632575f3ba86d0d02e1edc013d15ada1d934cc --- /dev/null +++ b/core/authority-discovery/build.rs @@ -0,0 +1,3 @@ +fn main() { + prost_build::compile_protos(&["src/schema/dht.proto"], &["src/schema"]).unwrap(); +} diff --git a/core/authority-discovery/primitives/Cargo.toml b/core/authority-discovery/primitives/Cargo.toml new file mode 100644 index 0000000000000000000000000000000000000000..8e9e465a299f6c6577a8a235ff50dd59e0e1868c --- /dev/null +++ b/core/authority-discovery/primitives/Cargo.toml @@ -0,0 +1,21 @@ +[package] +name = "substrate-authority-discovery-primitives" +version = "2.0.0" +authors = ["Parity Technologies "] +description = "Authority discovery primitives" +edition = "2018" + +[dependencies] +codec = { package = "parity-scale-codec", default-features = false, version = "1.0.3" } +client = { package = "substrate-client", path = "../../client", default-features = false } +sr-primitives = { path = "../../sr-primitives", default-features = false } +rstd = { package = "sr-std", path = "../../sr-std", default-features = false } + +[features] +default = ["std"] +std = [ + "rstd/std", + "client/std", + "codec/std", + "sr-primitives/std" +] diff --git a/core/authority-discovery/primitives/src/lib.rs b/core/authority-discovery/primitives/src/lib.rs new file mode 100644 index 0000000000000000000000000000000000000000..13da4de0204664c4b8aa94a6991b6793945dd922 --- /dev/null +++ b/core/authority-discovery/primitives/src/lib.rs @@ -0,0 +1,49 @@ +// Copyright 2019 Parity Technologies (UK) Ltd. +// This file is part of Substrate. + +// Substrate 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. + +// Substrate 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 Substrate. If not, see . + +//! Runtime Api to help discover authorities. + +#![cfg_attr(not(feature = "std"), no_std)] + +use client::decl_runtime_apis; +use rstd::vec::Vec; + +#[derive(codec::Encode, codec::Decode, Eq, PartialEq, Clone)] +#[cfg_attr(feature = "std", derive(Debug, Hash))] +pub struct Signature(pub Vec); +#[derive(codec::Encode, codec::Decode, Eq, PartialEq, Clone)] +#[cfg_attr(feature = "std", derive(Debug, Hash))] +pub struct AuthorityId(pub Vec); + +decl_runtime_apis! { + /// The authority discovery api. + /// + /// This api is used by the `core/authority-discovery` module to retrieve our + /// own authority identifier, to retrieve identifiers of the current authority + /// set, as well as sign and verify Kademlia Dht external address payloads + /// from and to other authorities. + pub trait AuthorityDiscoveryApi { + /// Retrieve authority identifiers of the current authority set. + fn authorities() -> Vec; + + /// Sign the given payload with the private key corresponding to the given authority id. + fn sign(payload: &Vec) -> Option<(Signature, AuthorityId)>; + + /// Verify the given signature for the given payload with the given + /// authority identifier. + fn verify(payload: &Vec, signature: &Signature, authority_id: &AuthorityId) -> bool; + } +} diff --git a/core/authority-discovery/src/error.rs b/core/authority-discovery/src/error.rs new file mode 100644 index 0000000000000000000000000000000000000000..e8c1ad9705f0c6accbf8edc3b699be5ad017c5f6 --- /dev/null +++ b/core/authority-discovery/src/error.rs @@ -0,0 +1,47 @@ +// Copyright 2019 Parity Technologies (UK) Ltd. +// This file is part of Substrate. + +// Substrate 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. + +// Substrate 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 Substrate. If not, see . + +//! Authority discovery errors. + +/// AuthorityDiscovery Result. +pub type Result = std::result::Result; + +/// Error type for the authority discovery module. +#[derive(Debug, derive_more::Display, derive_more::From)] +pub enum Error { + /// Failed to verify a dht payload with the given signature. + VerifyingDhtPayload, + /// Failed to hash the authority id to be used as a dht key. + HashingAuthorityId(libp2p::core::multiaddr::multihash::EncodeError), + /// Failed calling into the Substrate runtime. + CallingRuntime(client::error::Error), + /// Failed signing the dht payload via the Substrate runtime. + SigningDhtPayload, + /// From the Dht we only get the hashed authority id. In order to retrieve the actual authority id and to ensure it + /// is actually an authority, we match the hash against the hash of the authority id of all other authorities. This + /// error is the result of the above failing. + MatchingHashedAuthorityIdWithAuthorityId, + /// Failed to set the authority discovery peerset priority group in the peerset module. + SettingPeersetPriorityGroup(String), + /// Failed to encode a dht payload. + Encoding(prost::EncodeError), + /// Failed to decode a dht payload. + Decoding(prost::DecodeError), + /// Failed to parse a libp2p multi address. + ParsingMultiaddress(libp2p::core::multiaddr::Error), + /// Tokio timer error. + PollingTokioTimer(tokio_timer::Error) +} diff --git a/core/authority-discovery/src/lib.rs b/core/authority-discovery/src/lib.rs new file mode 100644 index 0000000000000000000000000000000000000000..987169ead90b11077f8d6a3d43af1a7a475e66eb --- /dev/null +++ b/core/authority-discovery/src/lib.rs @@ -0,0 +1,698 @@ +// Copyright 2019 Parity Technologies (UK) Ltd. +// This file is part of Substrate. + +// Substrate 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. + +// Substrate 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 Substrate. If not, see . + +#![warn(missing_docs)] + +//! Substrate authority discovery. +//! +//! This crate enables Substrate authorities to directly connect to other authorities. [`AuthorityDiscovery`] implements +//! the Future trait. By polling [`AuthorityDiscovery`] an authority: +//! +//! +//! 1. **Makes itself discoverable** +//! +//! 1. Retrieves its external addresses. +//! +//! 2. Adds its network peer id to the addresses. +//! +//! 3. Signs the above. +//! +//! 4. Puts the signature and the addresses on the libp2p Kademlia DHT. +//! +//! +//! 2. **Discovers other authorities** +//! +//! 1. Retrieves the current set of authorities. +//! +//! 2. Starts DHT queries for the ids of the authorities. +//! +//! 3. Validates the signatures of the retrieved key value pairs. +//! +//! 4. Adds the retrieved external addresses as priority nodes to the peerset. + +use authority_discovery_primitives::{AuthorityDiscoveryApi, AuthorityId, Signature}; +use client::blockchain::HeaderBackend; +use error::{Error, Result}; +use futures::{prelude::*, sync::mpsc::Receiver}; +use log::{debug, error, log_enabled, warn}; +use network::specialization::NetworkSpecialization; +use network::{DhtEvent, ExHashT}; +use prost::Message; +use sr_primitives::generic::BlockId; +use sr_primitives::traits::{Block as BlockT, ProvideRuntimeApi}; +use std::collections::{HashMap, HashSet}; +use std::convert::TryInto; +use std::iter::FromIterator; +use std::marker::PhantomData; +use std::sync::Arc; +use std::time::{Duration, Instant}; + +mod error; +/// Dht payload schemas generated from Protobuf definitions via Prost crate in build.rs. +mod schema { + include!(concat!(env!("OUT_DIR"), "/authority_discovery.rs")); +} + +/// An `AuthorityDiscovery` makes a given authority discoverable and discovers other authorities. +pub struct AuthorityDiscovery +where + Block: BlockT + 'static, + Network: NetworkProvider, + Client: ProvideRuntimeApi + Send + Sync + 'static + HeaderBackend, + ::Api: AuthorityDiscoveryApi, +{ + client: Arc, + + network: Arc, + /// Channel we receive Dht events on. + dht_event_rx: Receiver, + + /// Interval to be proactive, publishing own addresses. + publish_interval: tokio_timer::Interval, + /// Interval on which to query for addresses of other authorities. + query_interval: tokio_timer::Interval, + + /// The network peerset interface for priority groups lets us only set an entire group, but we retrieve the + /// addresses of other authorities one by one from the network. To use the peerset interface we need to cache the + /// addresses and always overwrite the entire peerset priority group. To ensure this map doesn't grow indefinitely + /// `purge_old_authorities_from_cache` function is called each time we add a new entry. + address_cache: HashMap>, + + phantom: PhantomData, +} + +impl AuthorityDiscovery +where + Block: BlockT + 'static, + Network: NetworkProvider, + Client: ProvideRuntimeApi + Send + Sync + 'static + HeaderBackend, + ::Api: AuthorityDiscoveryApi, +{ + /// Return a new authority discovery. + pub fn new( + client: Arc, + network: Arc, + dht_event_rx: futures::sync::mpsc::Receiver, + ) -> AuthorityDiscovery { + // Kademlia's default time-to-live for Dht records is 36h, republishing records every 24h. Given that a node + // could restart at any point in time, one can not depend on the republishing process, thus publishing own + // external addresses should happen on an interval < 36h. + let publish_interval = + tokio_timer::Interval::new(Instant::now(), Duration::from_secs(12 * 60 * 60)); + + // External addresses of other authorities can change at any given point in time. The interval on which to query + // for external addresses of other authorities is a trade off between efficiency and performance. + let query_interval = + tokio_timer::Interval::new(Instant::now(), Duration::from_secs(10 * 60)); + + let address_cache = HashMap::new(); + + AuthorityDiscovery { + client, + network, + dht_event_rx, + publish_interval, + query_interval, + address_cache, + phantom: PhantomData, + } + } + + fn publish_own_ext_addresses(&mut self) -> Result<()> { + let id = BlockId::hash(self.client.info().best_hash); + + let addresses = self + .network + .external_addresses() + .into_iter() + .map(|a| { + a.with(libp2p::core::multiaddr::Protocol::P2p( + self.network.local_peer_id().into(), + )) + }) + .map(|a| a.to_vec()) + .collect(); + + let mut serialized_addresses = vec![]; + schema::AuthorityAddresses { addresses } + .encode(&mut serialized_addresses) + .map_err(Error::Encoding)?; + + let (signature, authority_id) = self + .client + .runtime_api() + .sign(&id, &serialized_addresses) + .map_err(Error::CallingRuntime)? + .ok_or(Error::SigningDhtPayload)?; + + let mut signed_addresses = vec![]; + schema::SignedAuthorityAddresses { + addresses: serialized_addresses, + signature: signature.0, + } + .encode(&mut signed_addresses) + .map_err(Error::Encoding)?; + + self.network.put_value( + hash_authority_id(authority_id.0.as_ref())?, + signed_addresses, + ); + + Ok(()) + } + + fn request_addresses_of_others(&mut self) -> Result<()> { + let id = BlockId::hash(self.client.info().best_hash); + + let authorities = self + .client + .runtime_api() + .authorities(&id) + .map_err(Error::CallingRuntime)?; + + for authority_id in authorities.iter() { + self.network + .get_value(&hash_authority_id(authority_id.0.as_ref())?); + } + + Ok(()) + } + + fn handle_dht_events(&mut self) -> Result<()> { + while let Ok(Async::Ready(Some(event))) = self.dht_event_rx.poll() { + match event { + DhtEvent::ValueFound(v) => { + if log_enabled!(log::Level::Debug) { + let hashes = v.iter().map(|(hash, _value)| hash.clone()); + debug!(target: "sub-authority-discovery", "Value for hash '{:?}' found on Dht.", hashes); + } + + self.handle_dht_value_found_event(v)?; + } + DhtEvent::ValueNotFound(hash) => { + warn!(target: "sub-authority-discovery", "Value for hash '{:?}' not found on Dht.", hash) + } + DhtEvent::ValuePut(hash) => { + debug!(target: "sub-authority-discovery", "Successfully put hash '{:?}' on Dht.", hash) + } + DhtEvent::ValuePutFailed(hash) => { + warn!(target: "sub-authority-discovery", "Failed to put hash '{:?}' on Dht.", hash) + } + } + } + + Ok(()) + } + + fn handle_dht_value_found_event( + &mut self, + values: Vec<(libp2p::kad::record::Key, Vec)>, + ) -> Result<()> { + debug!(target: "sub-authority-discovery", "Got Dht value from network."); + + let id = BlockId::hash(self.client.info().best_hash); + + // From the Dht we only get the hashed authority id. In order to retrieve the actual authority id and to ensure + // it is actually an authority, we match the hash against the hash of the authority id of all other authorities. + let authorities = self.client.runtime_api().authorities(&id)?; + self.purge_old_authorities_from_cache(&authorities); + + let authorities = authorities + .into_iter() + .map(|a| hash_authority_id(a.0.as_ref()).map(|h| (h, a))) + .collect::>>()?; + + for (key, value) in values.iter() { + // Check if the event origins from an authority in the current authority set. + let authority_id: &AuthorityId = authorities + .get(key) + .ok_or(Error::MatchingHashedAuthorityIdWithAuthorityId)?; + + let schema::SignedAuthorityAddresses { + signature, + addresses, + } = schema::SignedAuthorityAddresses::decode(value).map_err(Error::Decoding)?; + let signature = Signature(signature); + + let is_verified = self + .client + .runtime_api() + .verify(&id, &addresses, &signature, &authority_id.clone()) + .map_err(Error::CallingRuntime)?; + + if !is_verified { + return Err(Error::VerifyingDhtPayload); + } + + let addresses: Vec = schema::AuthorityAddresses::decode(addresses) + .map(|a| a.addresses) + .map_err(Error::Decoding)? + .into_iter() + .map(|a| a.try_into()) + .collect::>() + .map_err(Error::ParsingMultiaddress)?; + + self.address_cache.insert(authority_id.clone(), addresses); + } + + // Let's update the peerset priority group with the all the addresses we have in our cache. + + let addresses = HashSet::from_iter( + self.address_cache + .iter() + .map(|(_peer_id, addresses)| addresses.clone()) + .flatten(), + ); + + debug!(target: "sub-authority-discovery", "Applying priority group {:#?} to peerset.", addresses); + self.network + .set_priority_group("authorities".to_string(), addresses) + .map_err(Error::SettingPeersetPriorityGroup)?; + + Ok(()) + } + + fn purge_old_authorities_from_cache(&mut self, current_authorities: &Vec) { + self.address_cache + .retain(|peer_id, _addresses| current_authorities.contains(peer_id)) + } +} + +impl futures::Future for AuthorityDiscovery +where + Block: BlockT + 'static, + Network: NetworkProvider, + Client: ProvideRuntimeApi + Send + Sync + 'static + HeaderBackend, + ::Api: AuthorityDiscoveryApi, +{ + type Item = (); + type Error = (); + + fn poll(&mut self) -> futures::Poll { + let mut inner = || -> Result<()> { + // Process incoming events before triggering new ones. + self.handle_dht_events()?; + + if let Async::Ready(_) = self + .publish_interval + .poll() + .map_err(Error::PollingTokioTimer)? + { + // Make sure to call interval.poll until it returns Async::NotReady once. Otherwise, in case one of the + // function calls within this block do a `return`, we don't call `interval.poll` again and thereby the + // underlying Tokio task is never registered with Tokio's Reactor to be woken up on the next interval + // tick. + while let Async::Ready(_) = self + .publish_interval + .poll() + .map_err(Error::PollingTokioTimer)? + {} + + self.publish_own_ext_addresses()?; + } + + if let Async::Ready(_) = self + .query_interval + .poll() + .map_err(Error::PollingTokioTimer)? + { + // Make sure to call interval.poll until it returns Async::NotReady once. Otherwise, in case one of the + // function calls within this block do a `return`, we don't call `interval.poll` again and thereby the + // underlying Tokio task is never registered with Tokio's Reactor to be woken up on the next interval + // tick. + while let Async::Ready(_) = self + .query_interval + .poll() + .map_err(Error::PollingTokioTimer)? + {} + + self.request_addresses_of_others()?; + } + + Ok(()) + }; + + match inner() { + Ok(()) => {} + Err(e) => error!(target: "sub-authority-discovery", "Poll failure: {:?}", e), + }; + + // Make sure to always return NotReady as this is a long running task with the same lifetime as the node itself. + Ok(futures::Async::NotReady) + } +} + +/// NetworkProvider provides AuthorityDiscovery with all necessary hooks into the underlying Substrate networking. Using +/// this trait abstraction instead of NetworkService directly is necessary to unit test AuthorityDiscovery. +pub trait NetworkProvider { + /// Returns the local external addresses. + fn external_addresses(&self) -> Vec; + + /// Returns the network identity of the node. + fn local_peer_id(&self) -> libp2p::PeerId; + + /// Modify a peerset priority group. + fn set_priority_group( + &self, + group_id: String, + peers: HashSet, + ) -> std::result::Result<(), String>; + + /// Start putting a value in the Dht. + fn put_value(&self, key: libp2p::kad::record::Key, value: Vec); + + /// Start getting a value from the Dht. + fn get_value(&self, key: &libp2p::kad::record::Key); +} + +impl NetworkProvider for network::NetworkService +where + B: BlockT + 'static, + S: NetworkSpecialization, + H: ExHashT, +{ + fn external_addresses(&self) -> Vec { + self.external_addresses() + } + fn local_peer_id(&self) -> libp2p::PeerId { + self.local_peer_id() + } + fn set_priority_group( + &self, + group_id: String, + peers: HashSet, + ) -> std::result::Result<(), String> { + self.set_priority_group(group_id, peers) + } + fn put_value(&self, key: libp2p::kad::record::Key, value: Vec) { + self.put_value(key, value) + } + fn get_value(&self, key: &libp2p::kad::record::Key) { + self.get_value(key) + } +} + +fn hash_authority_id(id: &[u8]) -> Result { + libp2p::multihash::encode(libp2p::multihash::Hash::SHA2256, id) + .map(|k| libp2p::kad::record::Key::new(&k)) + .map_err(Error::HashingAuthorityId) +} + +#[cfg(test)] +mod tests { + use super::*; + use client::runtime_api::{ApiExt, Core, RuntimeVersion}; + use futures::future::poll_fn; + use primitives::{ExecutionContext, NativeOrEncoded}; + use sr_primitives::traits::Zero; + use sr_primitives::traits::{ApiRef, Block as BlockT, NumberFor, ProvideRuntimeApi}; + use std::sync::{Arc, Mutex}; + use test_client::runtime::Block; + use tokio::runtime::current_thread; + + #[derive(Clone)] + struct TestApi {} + + impl ProvideRuntimeApi for TestApi { + type Api = RuntimeApi; + + fn runtime_api<'a>(&'a self) -> ApiRef<'a, Self::Api> { + RuntimeApi {}.into() + } + } + + /// Blockchain database header backend. Does not perform any validation. + impl HeaderBackend for TestApi { + fn header( + &self, + _id: BlockId, + ) -> std::result::Result, client::error::Error> { + Ok(None) + } + + fn info(&self) -> client::blockchain::Info { + client::blockchain::Info { + best_hash: Default::default(), + best_number: Zero::zero(), + finalized_hash: Default::default(), + finalized_number: Zero::zero(), + genesis_hash: Default::default(), + } + } + + fn status( + &self, + _id: BlockId, + ) -> std::result::Result { + Ok(client::blockchain::BlockStatus::Unknown) + } + + fn number( + &self, + _hash: Block::Hash, + ) -> std::result::Result>, client::error::Error> { + Ok(None) + } + + fn hash( + &self, + _number: NumberFor, + ) -> std::result::Result, client::error::Error> { + Ok(None) + } + } + + struct RuntimeApi {} + + impl Core for RuntimeApi { + fn Core_version_runtime_api_impl( + &self, + _: &BlockId, + _: ExecutionContext, + _: Option<()>, + _: Vec, + ) -> std::result::Result, client::error::Error> { + unimplemented!("Not required for testing!") + } + + fn Core_execute_block_runtime_api_impl( + &self, + _: &BlockId, + _: ExecutionContext, + _: Option<(Block)>, + _: Vec, + ) -> std::result::Result, client::error::Error> { + unimplemented!("Not required for testing!") + } + + fn Core_initialize_block_runtime_api_impl( + &self, + _: &BlockId, + _: ExecutionContext, + _: Option<&::Header>, + _: Vec, + ) -> std::result::Result, client::error::Error> { + unimplemented!("Not required for testing!") + } + } + + impl ApiExt for RuntimeApi { + fn map_api_result std::result::Result, R, E>( + &self, + _: F, + ) -> std::result::Result { + unimplemented!("Not required for testing!") + } + + fn runtime_version_at( + &self, + _: &BlockId, + ) -> std::result::Result { + unimplemented!("Not required for testing!") + } + + fn record_proof(&mut self) { + unimplemented!("Not required for testing!") + } + + fn extract_proof(&mut self) -> Option>> { + unimplemented!("Not required for testing!") + } + } + + impl AuthorityDiscoveryApi for RuntimeApi { + fn AuthorityDiscoveryApi_authorities_runtime_api_impl( + &self, + _: &BlockId, + _: ExecutionContext, + _: Option<()>, + _: Vec, + ) -> std::result::Result>, client::error::Error> { + return Ok(NativeOrEncoded::Native(vec![ + AuthorityId("test-authority-id-1".as_bytes().to_vec()), + AuthorityId("test-authority-id-2".as_bytes().to_vec()), + ])); + } + fn AuthorityDiscoveryApi_sign_runtime_api_impl( + &self, + _: &BlockId, + _: ExecutionContext, + _: Option<&std::vec::Vec>, + _: Vec, + ) -> std::result::Result< + NativeOrEncoded>, + client::error::Error, + > { + return Ok(NativeOrEncoded::Native(Some(( + Signature("test-signature-1".as_bytes().to_vec()), + AuthorityId("test-authority-id-1".as_bytes().to_vec()), + )))); + } + fn AuthorityDiscoveryApi_verify_runtime_api_impl( + &self, + _: &BlockId, + _: ExecutionContext, + args: Option<(&Vec, &Signature, &AuthorityId)>, + _: Vec, + ) -> std::result::Result, client::error::Error> { + if *args.unwrap().1 == Signature("test-signature-1".as_bytes().to_vec()) { + return Ok(NativeOrEncoded::Native(true)); + } + return Ok(NativeOrEncoded::Native(false)); + } + } + + #[derive(Default)] + struct TestNetwork { + // Whenever functions on `TestNetwork` are called, the function arguments are added to the vectors below. + pub put_value_call: Arc)>>>, + pub get_value_call: Arc>>, + pub set_priority_group_call: Arc)>>>, + } + + impl NetworkProvider for TestNetwork { + fn external_addresses(&self) -> Vec { + vec![] + } + fn local_peer_id(&self) -> libp2p::PeerId { + libp2p::PeerId::random() + } + fn set_priority_group( + &self, + group_id: String, + peers: HashSet, + ) -> std::result::Result<(), String> { + self.set_priority_group_call + .lock() + .unwrap() + .push((group_id, peers)); + Ok(()) + } + fn put_value(&self, key: libp2p::kad::record::Key, value: Vec) { + self.put_value_call.lock().unwrap().push((key, value)); + } + fn get_value(&self, key: &libp2p::kad::record::Key) { + self.get_value_call.lock().unwrap().push(key.clone()); + } + } + + #[test] + fn publish_own_ext_addresses_puts_record_on_dht() { + let (_dht_event_tx, dht_event_rx) = futures::sync::mpsc::channel(1000); + let test_api = Arc::new(TestApi {}); + let network: Arc = Arc::new(Default::default()); + + let mut authority_discovery = + AuthorityDiscovery::new(test_api, network.clone(), dht_event_rx); + + authority_discovery.publish_own_ext_addresses().unwrap(); + + // Expect authority discovery to put a new record onto the dht. + assert_eq!(network.put_value_call.lock().unwrap().len(), 1); + } + + #[test] + fn request_addresses_of_others_triggers_dht_get_query() { + let (_dht_event_tx, dht_event_rx) = futures::sync::mpsc::channel(1000); + let test_api = Arc::new(TestApi {}); + let network: Arc = Arc::new(Default::default()); + + let mut authority_discovery = + AuthorityDiscovery::new(test_api, network.clone(), dht_event_rx); + + authority_discovery.request_addresses_of_others().unwrap(); + + // Expect authority discovery to request new records from the dht. + assert_eq!(network.get_value_call.lock().unwrap().len(), 2); + } + + #[test] + fn handle_dht_events_with_value_found_should_call_set_priority_group() { + // Create authority discovery. + + let (mut dht_event_tx, dht_event_rx) = futures::sync::mpsc::channel(1000); + let test_api = Arc::new(TestApi {}); + let network: Arc = Arc::new(Default::default()); + + let mut authority_discovery = + AuthorityDiscovery::new(test_api, network.clone(), dht_event_rx); + + // Create sample dht event. + + let authority_id_1 = hash_authority_id("test-authority-id-1".as_bytes()).unwrap(); + let address_1: libp2p::Multiaddr = "/ip6/2001:db8::".parse().unwrap(); + + let mut serialized_addresses = vec![]; + schema::AuthorityAddresses { + addresses: vec![address_1.to_vec()], + } + .encode(&mut serialized_addresses) + .unwrap(); + + let mut signed_addresses = vec![]; + schema::SignedAuthorityAddresses { + addresses: serialized_addresses, + signature: "test-signature-1".as_bytes().to_vec(), + } + .encode(&mut signed_addresses) + .unwrap(); + + let dht_event = network::DhtEvent::ValueFound(vec![(authority_id_1, signed_addresses)]); + dht_event_tx.try_send(dht_event).unwrap(); + + // Make authority discovery handle the event. + + let f = || { + authority_discovery.handle_dht_events().unwrap(); + + // Expect authority discovery to set the priority set. + assert_eq!(network.set_priority_group_call.lock().unwrap().len(), 1); + + assert_eq!( + network.set_priority_group_call.lock().unwrap()[0], + ( + "authorities".to_string(), + HashSet::from_iter(vec![address_1.clone()].into_iter()) + ) + ); + + Ok(Async::Ready(())) + }; + + let mut runtime = current_thread::Runtime::new().unwrap(); + runtime.block_on(poll_fn::<(), (), _>(f)).unwrap(); + } +} diff --git a/core/authority-discovery/src/schema/dht.proto b/core/authority-discovery/src/schema/dht.proto new file mode 100644 index 0000000000000000000000000000000000000000..9dbe9d559f4b121b33f048245b0e10873da30817 --- /dev/null +++ b/core/authority-discovery/src/schema/dht.proto @@ -0,0 +1,14 @@ +syntax = "proto3"; + +package authority_discovery; + +// First we need to serialize the addresses in order to be able to sign them. +message AuthorityAddresses { + repeated bytes addresses = 1; +} + +// Then we need to serialize addresses and signature to send them over the wire. +message SignedAuthorityAddresses { + bytes addresses = 1; + bytes signature = 2; +} diff --git a/core/basic-authorship/Cargo.toml b/core/basic-authorship/Cargo.toml index 003eb79349266471802a298ed3b2d477a6451fcc..0a98c151d6eaf90dab9dbde6fc8d5b2512befca2 100644 --- a/core/basic-authorship/Cargo.toml +++ b/core/basic-authorship/Cargo.toml @@ -5,8 +5,8 @@ authors = ["Parity Technologies "] edition = "2018" [dependencies] -log = "0.4" -futures-preview = "=0.3.0-alpha.17" +log = "0.4.8" +futures-preview = "0.3.0-alpha.19" codec = { package = "parity-scale-codec", version = "1.0.0" } sr-primitives = { path = "../../core/sr-primitives" } primitives = { package = "substrate-primitives", path = "../../core/primitives" } diff --git a/core/basic-authorship/src/basic_authorship.rs b/core/basic-authorship/src/basic_authorship.rs index 2030f2be5a2f92c858447bd73d2ac85fb4d6a488..7f8b343f6512c6720fe3b0f98135c464bd2426c1 100644 --- a/core/basic-authorship/src/basic_authorship.rs +++ b/core/basic-authorship/src/basic_authorship.rs @@ -30,9 +30,10 @@ use inherents::InherentData; use log::{error, info, debug, trace}; use primitives::{H256, Blake2Hasher, ExecutionContext}; use sr_primitives::{ - traits::{Block as BlockT, Hash as HashT, Header as HeaderT, ProvideRuntimeApi, DigestFor, BlakeTwo256}, + traits::{ + Block as BlockT, Hash as HashT, Header as HeaderT, ProvideRuntimeApi, DigestFor, BlakeTwo256 + }, generic::BlockId, - ApplyError, }; use transaction_pool::txpool::{self, Pool as TransactionPool}; use substrate_telemetry::{telemetry, CONSENSUS_INFO}; @@ -170,7 +171,7 @@ impl Proposer, A> wh Ok(()) => { debug!("[{:?}] Pushed to the block.", pending.hash); } - Err(error::Error::ApplyExtrinsicFailed(ApplyError::FullBlock)) => { + Err(error::Error::ApplyExtrinsicFailed(e)) if e.exhausted_resources() => { if is_first { debug!("[{:?}] Invalid transaction: FullBlock on empty block", pending.hash); unqueue_invalid.push(pending.hash.clone()); @@ -178,7 +179,7 @@ impl Proposer, A> wh skipped += 1; debug!( "Block seems full, but will try {} more transactions before quitting.", - MAX_SKIPPED_TRANSACTIONS - skipped + MAX_SKIPPED_TRANSACTIONS - skipped, ); } else { debug!("Block is full, proceed with proposing."); @@ -246,10 +247,12 @@ mod tests { fn should_cease_building_block_when_deadline_is_reached() { // given let client = Arc::new(test_client::new()); - let chain_api = transaction_pool::ChainApi::new(client.clone()); + let chain_api = transaction_pool::FullChainApi::new(client.clone()); let txpool = Arc::new(TransactionPool::new(Default::default(), chain_api)); - txpool.submit_at(&BlockId::number(0), vec![extrinsic(0), extrinsic(1)]).unwrap(); + futures::executor::block_on( + txpool.submit_at(&BlockId::number(0), vec![extrinsic(0), extrinsic(1)], false) + ).unwrap(); let mut proposer_factory = ProposerFactory { client: client.clone(), diff --git a/core/basic-authorship/src/lib.rs b/core/basic-authorship/src/lib.rs index 71c9e2792248fa260980c87400bb6130e1a898fe..7961e4fe9e9dfe7b8e4ccf41fb448335fd286173 100644 --- a/core/basic-authorship/src/lib.rs +++ b/core/basic-authorship/src/lib.rs @@ -26,7 +26,7 @@ //! # use test_client::{self, runtime::{Extrinsic, Transfer}, AccountKeyring}; //! # use transaction_pool::txpool::{self, Pool as TransactionPool}; //! # let client = Arc::new(test_client::new()); -//! # let chain_api = transaction_pool::ChainApi::new(client.clone()); +//! # let chain_api = transaction_pool::FullChainApi::new(client.clone()); //! # let txpool = Arc::new(TransactionPool::new(Default::default(), chain_api)); //! // The first step is to create a `ProposerFactory`. //! let mut proposer_factory = ProposerFactory { diff --git a/core/chain-spec/Cargo.toml b/core/chain-spec/Cargo.toml new file mode 100644 index 0000000000000000000000000000000000000000..bff5999ef4f974b3777a121c27a52266180af2ae --- /dev/null +++ b/core/chain-spec/Cargo.toml @@ -0,0 +1,17 @@ +[package] +name = "substrate-chain-spec" +version = "2.0.0" +authors = ["Parity Technologies "] +edition = "2018" + +[dependencies] +chain-spec-derive = { package = "substrate-chain-spec-derive", path = "./derive" } +impl-trait-for-tuples = "0.1.2" +network = { package = "substrate-network", path = "../../core/network" } +primitives = { package = "substrate-primitives", path = "../primitives" } +serde = { version = "1.0.101", features = ["derive"] } +serde_json = "1.0.40" +sr-primitives = { path = "../../core/sr-primitives" } +tel = { package = "substrate-telemetry", path = "../../core/telemetry" } + +[dev-dependencies] diff --git a/core/chain-spec/derive/Cargo.toml b/core/chain-spec/derive/Cargo.toml new file mode 100644 index 0000000000000000000000000000000000000000..2e42ca0cf3a7095866f17d81830fce84ebb82c21 --- /dev/null +++ b/core/chain-spec/derive/Cargo.toml @@ -0,0 +1,16 @@ +[package] +name = "substrate-chain-spec-derive" +version = "2.0.0" +authors = ["Parity Technologies "] +edition = "2018" + +[lib] +proc-macro = true + +[dependencies] +proc-macro-crate = "0.1.4" +proc-macro2 = "1.0.4" +quote = "1.0.2" +syn = "1.0.5" + +[dev-dependencies] diff --git a/core/chain-spec/derive/src/impls.rs b/core/chain-spec/derive/src/impls.rs new file mode 100644 index 0000000000000000000000000000000000000000..cdc27aef0b9c698aac9742056814f76a49091d5f --- /dev/null +++ b/core/chain-spec/derive/src/impls.rs @@ -0,0 +1,190 @@ +// Copyright 2019 Parity Technologies (UK) Ltd. +// This file is part of Substrate. + +// Substrate 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. + +// Substrate 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 Substrate. If not, see . + +use proc_macro2::{Span, TokenStream}; +use quote::quote; +use syn::{DeriveInput, Ident, Error}; +use proc_macro_crate::crate_name; + +const CRATE_NAME: &str = "substrate-chain-spec"; +const ATTRIBUTE_NAME: &str = "forks"; + +/// Implements `Extension's` `Group` accessor. +/// +/// The struct that derives this implementation will be usable within the `ChainSpec` file. +/// The derive implements a by-type accessor method. +pub fn extension_derive(ast: &DeriveInput) -> proc_macro::TokenStream { + derive(ast, |crate_name, name, generics: &syn::Generics, field_names, field_types, fields| { + let (impl_generics, ty_generics, where_clause) = generics.split_for_impl(); + let forks = fields.named.iter().find_map(|f| { + if f.attrs.iter().any(|attr| attr.path.is_ident(ATTRIBUTE_NAME)) { + let typ = &f.ty; + Some(quote! { #typ }) + } else { + None + } + }).unwrap_or_else(|| quote! { #crate_name::NoExtension }); + + quote! { + impl #impl_generics #crate_name::Extension for #name #ty_generics #where_clause { + type Forks = #forks; + + fn get(&self) -> Option<&T> { + use std::any::{Any, TypeId}; + + match TypeId::of::() { + #( x if x == TypeId::of::<#field_types>() => Any::downcast_ref(&self.#field_names) ),*, + _ => None, + } + } + } + } + }) +} + + +/// Implements required traits and creates `Fork` structs for `ChainSpec` custom parameter group. +pub fn group_derive(ast: &DeriveInput) -> proc_macro::TokenStream { + derive(ast, |crate_name, name, generics: &syn::Generics, field_names, field_types, _fields| { + let (impl_generics, ty_generics, where_clause) = generics.split_for_impl(); + let fork_name = Ident::new(&format!("{}Fork", name), Span::call_site()); + + let fork_fields = generate_fork_fields(&crate_name, &field_names, &field_types); + let to_fork = generate_base_to_fork(&fork_name, &field_names); + let combine_with = generate_combine_with(&field_names); + let to_base = generate_fork_to_base(name, &field_names); + + quote! { + #[derive(Debug, Clone, PartialEq, Serialize, Deserialize, ChainSpecExtension)] + pub struct #fork_name #ty_generics #where_clause { + #fork_fields + } + + impl #impl_generics #crate_name::Group for #name #ty_generics #where_clause { + type Fork = #fork_name #ty_generics; + + fn to_fork(self) -> Self::Fork { + use #crate_name::Group; + #to_fork + } + } + + impl #impl_generics #crate_name::Fork for #fork_name #ty_generics #where_clause { + type Base = #name #ty_generics; + + fn combine_with(&mut self, other: Self) { + use #crate_name::Fork; + #combine_with + } + + fn to_base(self) -> Option { + use #crate_name::Fork; + #to_base + } + } + } + }) +} + +pub fn derive( + ast: &DeriveInput, + derive: impl Fn( + &Ident, &Ident, &syn::Generics, Vec<&Ident>, Vec<&syn::Type>, &syn::FieldsNamed, + ) -> TokenStream, +) -> proc_macro::TokenStream { + let err = || { + let err = Error::new( + Span::call_site(), + "ChainSpecGroup is only avaible for structs with named fields." + ).to_compile_error(); + quote!( #err ).into() + }; + + let data = match &ast.data { + syn::Data::Struct(ref data) => data, + _ => return err(), + }; + + let fields = match &data.fields { + syn::Fields::Named(ref named) => named, + _ => return err(), + }; + + const PROOF: &str = "CARGO_PKG_NAME always defined when compiling; qed"; + let name = &ast.ident; + let crate_name = match crate_name(CRATE_NAME) { + Ok(chain_spec_name) => chain_spec_name, + Err(e) => if std::env::var("CARGO_PKG_NAME").expect(PROOF) == CRATE_NAME { + // we return the name of the crate here instead of `crate` to support doc tests. + CRATE_NAME.replace("-", "_") + } else { + let err = Error::new(Span::call_site(), &e).to_compile_error(); + return quote!( #err ).into() + }, + }; + let crate_name = Ident::new(&crate_name, Span::call_site()); + let field_names = fields.named.iter().flat_map(|x| x.ident.as_ref()).collect::>(); + let field_types = fields.named.iter().map(|x| &x.ty).collect::>(); + + derive(&crate_name, name, &ast.generics, field_names, field_types, fields).into() +} + +fn generate_fork_fields( + crate_name: &Ident, + names: &[&Ident], + types: &[&syn::Type], +) -> TokenStream { + let crate_name = std::iter::repeat(crate_name); + quote! { + #( pub #names: Option<<#types as #crate_name::Group>::Fork>, )* + } +} + +fn generate_base_to_fork( + fork_name: &Ident, + names: &[&Ident], +) -> TokenStream { + let names2 = names.to_vec(); + + quote!{ + #fork_name { + #( #names: Some(self.#names2.to_fork()), )* + } + } +} + +fn generate_combine_with( + names: &[&Ident], +) -> TokenStream { + let names2 = names.to_vec(); + + quote!{ + #( self.#names.combine_with(other.#names2); )* + } +} + +fn generate_fork_to_base( + fork: &Ident, + names: &[&Ident], +) -> TokenStream { + let names2 = names.to_vec(); + + quote!{ + Some(#fork { + #( #names: self.#names2?.to_base()?, )* + }) + } +} diff --git a/core/chain-spec/derive/src/lib.rs b/core/chain-spec/derive/src/lib.rs new file mode 100644 index 0000000000000000000000000000000000000000..bcd50c102178553243be1ea88fcaefd595fdfa3a --- /dev/null +++ b/core/chain-spec/derive/src/lib.rs @@ -0,0 +1,39 @@ +// Copyright 2019 Parity Technologies (UK) Ltd. +// This file is part of Substrate. + +// Substrate 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. + +// Substrate 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 Substrate. If not, see . + +//! Macros to derive chain spec extension traits implementation. + +extern crate proc_macro; + +mod impls; + +use proc_macro::TokenStream; + +#[proc_macro_derive(ChainSpecGroup)] +pub fn group_derive(input: TokenStream) -> TokenStream { + match syn::parse(input) { + Ok(ast) => impls::group_derive(&ast), + Err(e) => e.to_compile_error().into(), + } +} + +#[proc_macro_derive(ChainSpecExtension, attributes(forks))] +pub fn extensions_derive(input: TokenStream) -> TokenStream { + match syn::parse(input) { + Ok(ast) => impls::extension_derive(&ast), + Err(e) => e.to_compile_error().into(), + } +} diff --git a/core/chain-spec/res/chain_spec.json b/core/chain-spec/res/chain_spec.json new file mode 100644 index 0000000000000000000000000000000000000000..673f35d5079194ba9b1bfc0c960e3007cde2d79f --- /dev/null +++ b/core/chain-spec/res/chain_spec.json @@ -0,0 +1,31 @@ +{ + "name": "Flaming Fir", + "id": "flaming-fir", + "properties": { + "tokenDecimals": 15, + "tokenSymbol": "FIR" + }, + "bootNodes": [ + "/ip4/35.246.224.91/tcp/30333/p2p/QmSk5HQbn6LhUwDiNMseVUjuRYhEtYj4aUZ6WfWoGURpdV", + "/ip4/35.246.224.91/tcp/30334/ws/p2p/QmSk5HQbn6LhUwDiNMseVUjuRYhEtYj4aUZ6WfWoGURpdV", + "/ip4/35.246.210.11/tcp/30333/p2p/QmWv9Ww7znzgLFyCzf21SR6tUKXrmHCZH9KhebeH4gyE9f", + "/ip4/35.246.210.11/tcp/30334/ws/p2p/QmWv9Ww7znzgLFyCzf21SR6tUKXrmHCZH9KhebeH4gyE9f", + "/ip4/35.198.110.45/tcp/30333/p2p/QmTtcYKJho9vFmqtMA548QBSmLbmwAkBSiEKK3kWKfb6bJ", + "/ip4/35.198.110.45/tcp/30334/ws/p2p/QmTtcYKJho9vFmqtMA548QBSmLbmwAkBSiEKK3kWKfb6bJ", + "/ip4/35.198.114.154/tcp/30333/p2p/QmQJmDorK9c8KjMF5PdWiH2WGUXyzJtgTeJ55S5gggdju6", + "/ip4/35.198.114.154/tcp/30334/ws/p2p/QmQJmDorK9c8KjMF5PdWiH2WGUXyzJtgTeJ55S5gggdju6" + ], + "telemetryEndpoints": [ + ["wss://telemetry.polkadot.io/submit/", 0] + ], + "protocolId": "fir", + "consensusEngine": null, + "genesis": { + "raw": [ + { + "0xb2029f8665aac509629f2d28cea790a3": "0x10f26cdb14b5aec7b2789fd5ca80f979cef3761897ae1f37ffb3e154cbcc1c26633919132b851ef0fd2dae42a7e734fe547af5a6b809006100f48944d7fae8e8ef00299981a2b92f878baaf5dbeba5c18d4e70f2a1fcd9c61b32ea18daf38f437800299981a2b92f878baaf5dbeba5c18d4e70f2a1fcd9c61b32ea18daf38f4378547ff0ab649283a7ae01dbc2eb73932eba2fb09075e9485ff369082a2ff38d655633b70b80a6c8bb16270f82cca6d56b27ed7b76c8fd5af2986a25a4788ce440482a3389a6cf42d8ed83888cfd920fec738ea30f97e44699ada7323f08c3380a482a3389a6cf42d8ed83888cfd920fec738ea30f97e44699ada7323f08c3380a68655684472b743e456907b398d3a44c113f189e56d1bbfd55e889e295dfde787932cff431e748892fa48e10c63c17d30f80ca42e4de3921e641249cd7fa3c2f482dbd7297a39fa145c570552249c2ca9dd47e281f0c500c971b59c9dcdcd82e482dbd7297a39fa145c570552249c2ca9dd47e281f0c500c971b59c9dcdcd82e9c7a2ee14e565db0c69f78c7b4cd839fbf52b607d867e9e9c5a79042898a0d129becad03e6dcac03cee07edebca5475314861492cdfc96a2144a67bbe96993326e7e4eb42cbd2e0ab4cae8708ce5509580b8c04d11f6758dbf686d50fe9f91066e7e4eb42cbd2e0ab4cae8708ce5509580b8c04d11f6758dbf686d50fe9f9106" + }, + {} + ] + } +} diff --git a/core/chain-spec/res/chain_spec2.json b/core/chain-spec/res/chain_spec2.json new file mode 100644 index 0000000000000000000000000000000000000000..950a7fc82749431771376591ec3428374b27fe75 --- /dev/null +++ b/core/chain-spec/res/chain_spec2.json @@ -0,0 +1,32 @@ +{ + "name": "Flaming Fir", + "id": "flaming-fir", + "properties": { + "tokenDecimals": 15, + "tokenSymbol": "FIR" + }, + "bootNodes": [ + "/ip4/35.246.224.91/tcp/30333/p2p/QmSk5HQbn6LhUwDiNMseVUjuRYhEtYj4aUZ6WfWoGURpdV", + "/ip4/35.246.224.91/tcp/30334/ws/p2p/QmSk5HQbn6LhUwDiNMseVUjuRYhEtYj4aUZ6WfWoGURpdV", + "/ip4/35.246.210.11/tcp/30333/p2p/QmWv9Ww7znzgLFyCzf21SR6tUKXrmHCZH9KhebeH4gyE9f", + "/ip4/35.246.210.11/tcp/30334/ws/p2p/QmWv9Ww7znzgLFyCzf21SR6tUKXrmHCZH9KhebeH4gyE9f", + "/ip4/35.198.110.45/tcp/30333/p2p/QmTtcYKJho9vFmqtMA548QBSmLbmwAkBSiEKK3kWKfb6bJ", + "/ip4/35.198.110.45/tcp/30334/ws/p2p/QmTtcYKJho9vFmqtMA548QBSmLbmwAkBSiEKK3kWKfb6bJ", + "/ip4/35.198.114.154/tcp/30333/p2p/QmQJmDorK9c8KjMF5PdWiH2WGUXyzJtgTeJ55S5gggdju6", + "/ip4/35.198.114.154/tcp/30334/ws/p2p/QmQJmDorK9c8KjMF5PdWiH2WGUXyzJtgTeJ55S5gggdju6" + ], + "telemetryEndpoints": [ + ["wss://telemetry.polkadot.io/submit/", 0] + ], + "protocolId": "fir", + "consensusEngine": null, + "myProperty": "Test Extension", + "genesis": { + "raw": [ + { + "0xb2029f8665aac509629f2d28cea790a3": "0x10f26cdb14b5aec7b2789fd5ca80f979cef3761897ae1f37ffb3e154cbcc1c26633919132b851ef0fd2dae42a7e734fe547af5a6b809006100f48944d7fae8e8ef00299981a2b92f878baaf5dbeba5c18d4e70f2a1fcd9c61b32ea18daf38f437800299981a2b92f878baaf5dbeba5c18d4e70f2a1fcd9c61b32ea18daf38f4378547ff0ab649283a7ae01dbc2eb73932eba2fb09075e9485ff369082a2ff38d655633b70b80a6c8bb16270f82cca6d56b27ed7b76c8fd5af2986a25a4788ce440482a3389a6cf42d8ed83888cfd920fec738ea30f97e44699ada7323f08c3380a482a3389a6cf42d8ed83888cfd920fec738ea30f97e44699ada7323f08c3380a68655684472b743e456907b398d3a44c113f189e56d1bbfd55e889e295dfde787932cff431e748892fa48e10c63c17d30f80ca42e4de3921e641249cd7fa3c2f482dbd7297a39fa145c570552249c2ca9dd47e281f0c500c971b59c9dcdcd82e482dbd7297a39fa145c570552249c2ca9dd47e281f0c500c971b59c9dcdcd82e9c7a2ee14e565db0c69f78c7b4cd839fbf52b607d867e9e9c5a79042898a0d129becad03e6dcac03cee07edebca5475314861492cdfc96a2144a67bbe96993326e7e4eb42cbd2e0ab4cae8708ce5509580b8c04d11f6758dbf686d50fe9f91066e7e4eb42cbd2e0ab4cae8708ce5509580b8c04d11f6758dbf686d50fe9f9106" + }, + {} + ] + } +} diff --git a/core/service/src/chain_spec.rs b/core/chain-spec/src/chain_spec.rs similarity index 64% rename from core/service/src/chain_spec.rs rename to core/chain-spec/src/chain_spec.rs index 8d84b4880cc3e65fcd0f48f8537d025173b487fa..b4c57f1e0365c8e5d1d0367ee5111ed59530373d 100644 --- a/core/service/src/chain_spec.rs +++ b/core/chain-spec/src/chain_spec.rs @@ -24,7 +24,7 @@ use serde::{Serialize, Deserialize}; use primitives::storage::{StorageKey, StorageData}; use sr_primitives::{BuildStorage, StorageOverlay, ChildrenStorageOverlay}; use serde_json as json; -use crate::components::RuntimeGenesis; +use crate::RuntimeGenesis; use network::Multiaddr; use tel::TelemetryEndpoints; @@ -53,14 +53,15 @@ impl GenesisSource { match self { GenesisSource::File(path) => { - let file = File::open(path).map_err(|e| format!("Error opening spec file: {}", e))?; - let genesis: GenesisContainer = - json::from_reader(file).map_err(|e| format!("Error parsing spec file: {}", e))?; + let file = File::open(path) + .map_err(|e| format!("Error opening spec file: {}", e))?; + let genesis: GenesisContainer = json::from_reader(file) + .map_err(|e| format!("Error parsing spec file: {}", e))?; Ok(genesis.genesis) }, GenesisSource::Binary(buf) => { - let genesis: GenesisContainer = - json::from_reader(buf.as_ref()).map_err(|e| format!("Error parsing embedded file: {}", e))?; + let genesis: GenesisContainer = json::from_reader(buf.as_ref()) + .map_err(|e| format!("Error parsing embedded file: {}", e))?; Ok(genesis.genesis) }, GenesisSource::Factory(f) => Ok(Genesis::Runtime(f())), @@ -68,7 +69,7 @@ impl GenesisSource { } } -impl<'a, G: RuntimeGenesis> BuildStorage for &'a ChainSpec { +impl<'a, G: RuntimeGenesis, E> BuildStorage for &'a ChainSpec { fn build_storage(self) -> Result<(StorageOverlay, ChildrenStorageOverlay), String> { match self.genesis.resolve()? { Genesis::Runtime(gc) => gc.build_storage(), @@ -81,7 +82,11 @@ impl<'a, G: RuntimeGenesis> BuildStorage for &'a ChainSpec { )), } } - fn assimilate_storage(self, _: &mut (StorageOverlay, ChildrenStorageOverlay)) -> Result<(), String> { + + fn assimilate_storage( + self, + _: &mut (StorageOverlay, ChildrenStorageOverlay) + ) -> Result<(), String> { Err("`assimilate_storage` not implemented for `ChainSpec`.".into()) } } @@ -97,28 +102,39 @@ enum Genesis { ), } -#[derive(Serialize, Deserialize, Clone)] +#[derive(Serialize, Deserialize, Clone, Debug)] #[serde(rename_all = "camelCase")] -struct ChainSpecFile { +#[serde(deny_unknown_fields)] +struct ChainSpecFile { pub name: String, pub id: String, pub boot_nodes: Vec, pub telemetry_endpoints: Option, pub protocol_id: Option, - pub consensus_engine: Option, pub properties: Option, + #[serde(flatten)] + pub extensions: E, + // Never used, left only for backward compatibility. + consensus_engine: (), + #[serde(skip_serializing)] + genesis: serde::de::IgnoredAny, } /// Arbitrary properties defined in chain spec as a JSON object pub type Properties = json::map::Map; +/// A type denoting empty extensions. +/// +/// We use `Option` here since `()` is not flattenable by serde. +pub type NoExtension = Option<()>; + /// A configuration of a chain. Can be used to build a genesis block. -pub struct ChainSpec { - spec: ChainSpecFile, +pub struct ChainSpec { + spec: ChainSpecFile, genesis: GenesisSource, } -impl Clone for ChainSpec { +impl Clone for ChainSpec { fn clone(&self) -> Self { ChainSpec { spec: self.spec.clone(), @@ -127,7 +143,7 @@ impl Clone for ChainSpec { } } -impl ChainSpec { +impl ChainSpec { /// A list of bootnode addresses. pub fn boot_nodes(&self) -> &[String] { &self.spec.boot_nodes @@ -153,14 +169,10 @@ impl ChainSpec { self.spec.protocol_id.as_ref().map(String::as_str) } - /// Name of the consensus engine. - pub fn consensus_engine(&self) -> Option<&str> { - self.spec.consensus_engine.as_ref().map(String::as_str) - } - /// Additional loosly-typed properties of the chain. + /// + /// Returns an empty JSON object if 'properties' not defined in config pub fn properties(&self) -> Properties { - // Return an empty JSON object if 'properties' not defined in config self.spec.properties.as_ref().unwrap_or(&json::map::Map::new()).clone() } @@ -169,24 +181,9 @@ impl ChainSpec { self.spec.boot_nodes.push(addr.to_string()) } - /// Parse json content into a `ChainSpec` - pub fn from_json_bytes(json: impl Into>) -> Result { - let json = json.into(); - let spec = json::from_slice(json.as_ref()).map_err(|e| format!("Error parsing spec file: {}", e))?; - Ok(ChainSpec { - spec, - genesis: GenesisSource::Binary(json), - }) - } - - /// Parse json file into a `ChainSpec` - pub fn from_json_file(path: PathBuf) -> Result { - let file = File::open(&path).map_err(|e| format!("Error opening spec file: {}", e))?; - let spec = json::from_reader(file).map_err(|e| format!("Error parsing spec file: {}", e))?; - Ok(ChainSpec { - spec, - genesis: GenesisSource::File(path), - }) + /// Returns a reference to defined chain spec extensions. + pub fn extensions(&self) -> &E { + &self.spec.extensions } /// Create hardcoded spec. @@ -197,19 +194,21 @@ impl ChainSpec { boot_nodes: Vec, telemetry_endpoints: Option, protocol_id: Option<&str>, - consensus_engine: Option<&str>, properties: Option, - ) -> Self - { + extensions: E, + ) -> Self { let spec = ChainSpecFile { name: name.to_owned(), id: id.to_owned(), boot_nodes: boot_nodes, telemetry_endpoints, protocol_id: protocol_id.map(str::to_owned), - consensus_engine: consensus_engine.map(str::to_owned), properties, + extensions, + consensus_engine: (), + genesis: Default::default(), }; + ChainSpec { spec, genesis: GenesisSource::Factory(constructor), @@ -217,13 +216,38 @@ impl ChainSpec { } } -impl ChainSpec { +impl ChainSpec { + /// Parse json content into a `ChainSpec` + pub fn from_json_bytes(json: impl Into>) -> Result { + let json = json.into(); + let spec = json::from_slice(json.as_ref()) + .map_err(|e| format!("Error parsing spec file: {}", e))?; + Ok(ChainSpec { + spec, + genesis: GenesisSource::Binary(json), + }) + } + + /// Parse json file into a `ChainSpec` + pub fn from_json_file(path: PathBuf) -> Result { + let file = File::open(&path) + .map_err(|e| format!("Error opening spec file: {}", e))?; + let spec = json::from_reader(file) + .map_err(|e| format!("Error parsing spec file: {}", e))?; + Ok(ChainSpec { + spec, + genesis: GenesisSource::File(path), + }) + } +} + +impl ChainSpec { /// Dump to json string. pub fn to_json(self, raw: bool) -> Result { #[derive(Serialize, Deserialize)] - struct Container { + struct Container { #[serde(flatten)] - spec: ChainSpecFile, + spec: ChainSpecFile, genesis: Genesis, }; @@ -250,6 +274,58 @@ impl ChainSpec { spec: self.spec, genesis, }; - json::to_string_pretty(&spec).map_err(|e| format!("Error generating spec json: {}", e)) + json::to_string_pretty(&spec) + .map_err(|e| format!("Error generating spec json: {}", e)) + } +} + +#[cfg(test)] +mod tests { + use super::*; + + #[derive(Debug, Serialize, Deserialize)] + struct Genesis(HashMap); + + impl BuildStorage for Genesis { + fn assimilate_storage( + self, + storage: &mut (StorageOverlay, ChildrenStorageOverlay), + ) -> Result<(), String> { + storage.0.extend( + self.0.into_iter().map(|(a, b)| (a.into_bytes(), b.into_bytes())) + ); + Ok(()) + } + } + + type TestSpec = ChainSpec; + + #[test] + fn should_deserailize_example_chain_spec() { + let spec1 = TestSpec::from_json_bytes(Cow::Owned( + include_bytes!("../res/chain_spec.json").to_vec() + )).unwrap(); + let spec2 = TestSpec::from_json_file( + PathBuf::from("./res/chain_spec.json") + ).unwrap(); + + assert_eq!(spec1.to_json(false), spec2.to_json(false)); + } + + #[derive(Debug, Serialize, Deserialize)] + #[serde(rename_all = "camelCase")] + struct Extension1 { + my_property: String, + } + + type TestSpec2 = ChainSpec; + + #[test] + fn should_deserialize_chain_spec_with_extensions() { + let spec = TestSpec2::from_json_bytes(Cow::Owned( + include_bytes!("../res/chain_spec2.json").to_vec() + )).unwrap(); + + assert_eq!(spec.extensions().my_property, "Test Extension"); } } diff --git a/core/chain-spec/src/extension.rs b/core/chain-spec/src/extension.rs new file mode 100644 index 0000000000000000000000000000000000000000..bf98ced04d63fc6e124920c523070acfd3604768 --- /dev/null +++ b/core/chain-spec/src/extension.rs @@ -0,0 +1,363 @@ +// Copyright 2019 Parity Technologies (UK) Ltd. +// This file is part of Substrate. + +// Substrate 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. + +// Substrate 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 Substrate. If not, see . + +//! Chain Spec extensions helpers. + +use std::fmt::Debug; +use std::collections::BTreeMap; + +use serde::{Serialize, Deserialize, de::DeserializeOwned}; + +/// A `ChainSpec` extension. +/// +/// This trait is implemented automatically by `ChainSpecGroup` macro. +pub trait Group: Clone + Sized { + /// An associated type containing fork definition. + type Fork: Fork; + + /// Convert to fork type. + fn to_fork(self) -> Self::Fork; +} + +/// A `ChainSpec` extension fork definition. +/// +/// Basically should look the same as `Group`, but +/// all parameters are optional. This allows changing +/// only one parameter as part of the fork. +/// The forks can be combined (summed up) to specify +/// a complete set of parameters +pub trait Fork: Serialize + DeserializeOwned + Clone + Sized { + /// A base `Group` type. + type Base: Group; + + /// Combine with another struct. + /// + /// All parameters set in `other` should override the + /// ones in the current struct. + fn combine_with(&mut self, other: Self); + + /// Attempt to convert to the base type if all parameters are set. + fn to_base(self) -> Option; +} + +macro_rules! impl_trivial { + () => {}; + ($A : ty) => { + impl_trivial!($A ,); + }; + ($A : ty , $( $B : ty ),*) => { + impl_trivial!($( $B ),*); + + impl Group for $A { + type Fork = $A; + + fn to_fork(self) -> Self::Fork { + self + } + } + + impl Fork for $A { + type Base = $A; + + fn combine_with(&mut self, other: Self) { + *self = other; + } + + fn to_base(self) -> Option { + Some(self) + } + } + } +} + +impl_trivial!((), u8, u16, u32, u64, usize, String, Vec); + +impl Group for Option { + type Fork = Option; + + fn to_fork(self) -> Self::Fork { + self.map(|a| a.to_fork()) + } +} + +impl Fork for Option { + type Base = Option; + + fn combine_with(&mut self, other: Self) { + *self = match (self.take(), other) { + (Some(mut a), Some(b)) => { + a.combine_with(b); + Some(a) + }, + (a, b) => a.or(b), + }; + } + + fn to_base(self) -> Option { + self.map(|x| x.to_base()) + } +} + +/// A collection of `ChainSpec` extensions. +/// +/// This type can be passed around and allows the core +/// modules to request a strongly-typed, but optional configuration. +pub trait Extension: Serialize + DeserializeOwned + Clone { + type Forks: IsForks; + + /// Get an extension of specific type. + fn get(&self) -> Option<&T>; + + /// Get forkable extensions of specific type. + fn forks(&self) -> Option> where + BlockNumber: Ord + Clone + 'static, + T: Group + 'static, + ::Extension: Extension, + <::Extension as Group>::Fork: Extension, + { + self.get::::Extension>>()? + .for_type() + } +} + +impl Extension for crate::NoExtension { + type Forks = Self; + + fn get(&self) -> Option<&T> { None } +} + +pub trait IsForks { + type BlockNumber: Ord + 'static; + type Extension: Group + 'static; +} + +impl IsForks for Option<()> { + type BlockNumber = u64; + type Extension = Self; +} + +#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)] +#[serde(deny_unknown_fields)] +pub struct Forks { + forks: BTreeMap, + #[serde(flatten)] + base: T, +} + +impl Default for Forks { + fn default() -> Self { + Self { + base: Default::default(), + forks: Default::default(), + } + } +} + +impl Forks where + T::Fork: Debug, +{ + /// Create new fork definition given the base and the forks. + pub fn new(base: T, forks: BTreeMap) -> Self { + Self { base, forks } + } + + /// Return a set of parameters for `Group` including all forks up to `block` (inclusive). + pub fn at_block(&self, block: B) -> T { + let mut start = self.base.clone().to_fork(); + + for (_, fork) in self.forks.range(..=block) { + start.combine_with(fork.clone()); + } + + start + .to_base() + .expect("We start from the `base` object, so it's always fully initialized; qed") + } +} + +impl IsForks for Forks where + B: Ord + 'static, + T: Group + 'static, +{ + type BlockNumber = B; + type Extension = T; +} + +impl Forks where + T::Fork: Extension, +{ + /// Get forks definition for a subset of this extension. + /// + /// Returns the `Forks` struct, but limited to a particular type + /// within the extension. + pub fn for_type(&self) -> Option> where + X: Group + 'static, + { + let base = self.base.get::()?.clone(); + let forks = self.forks.iter().filter_map(|(k, v)| { + Some((k.clone(), v.get::>()?.clone()?)) + }).collect(); + + Some(Forks { + base, + forks, + }) + } +} + +impl Extension for Forks where + B: Serialize + DeserializeOwned + Ord + Clone + 'static, + E: Extension + Group + 'static, +{ + type Forks = Self; + + fn get(&self) -> Option<&T> { + use std::any::{TypeId, Any}; + + match TypeId::of::() { + x if x == TypeId::of::() => Any::downcast_ref(&self.base), + _ => self.base.get(), + } + } + + fn forks(&self) -> Option> where + BlockNumber: Ord + Clone + 'static, + T: Group + 'static, + ::Extension: Extension, + <::Extension as Group>::Fork: Extension, + { + use std::any::{TypeId, Any}; + + if TypeId::of::() == TypeId::of::() { + Any::downcast_ref(&self.for_type::()?).cloned() + } else { + self.get::::Extension>>()? + .for_type() + } + } +} + +#[cfg(test)] +mod tests { + use super::*; + use chain_spec_derive::{ChainSpecGroup, ChainSpecExtension}; + // Make the proc macro work for tests and doc tests. + use crate as substrate_chain_spec; + + #[derive(Debug, Clone, PartialEq, Serialize, Deserialize, ChainSpecGroup)] + #[serde(deny_unknown_fields)] + pub struct Extension1 { + pub test: u64, + } + + #[derive(Debug, Clone, PartialEq, Serialize, Deserialize, ChainSpecGroup)] + #[serde(deny_unknown_fields)] + pub struct Extension2 { + pub test: u8, + } + + #[derive(Debug, Clone, PartialEq, Serialize, Deserialize, ChainSpecGroup, ChainSpecExtension)] + #[serde(deny_unknown_fields)] + pub struct Extensions { + pub ext1: Extension1, + pub ext2: Extension2, + } + + #[derive(Debug, Clone, PartialEq, Serialize, Deserialize, ChainSpecExtension)] + #[serde(deny_unknown_fields)] + pub struct Ext2 { + #[serde(flatten)] + ext1: Extension1, + #[forks] + forkable: Forks, + } + + #[test] + fn forks_should_work_correctly() { + use super::Extension as _ ; + + let ext: Ext2 = serde_json::from_str(r#" +{ + "test": 11, + "forkable": { + "ext1": { + "test": 15 + }, + "ext2": { + "test": 123 + }, + "forks": { + "1": { + "ext1": { "test": 5 } + }, + "2": { + "ext2": { "test": 5 } + }, + "5": { + "ext2": { "test": 1 } + } + } + } +} + "#).unwrap(); + + assert_eq!(ext.get::(), Some(&Extension1 { + test: 11 + })); + + // get forks definition + let forks = ext.get::>().unwrap(); + assert_eq!(forks.at_block(0), Extensions { + ext1: Extension1 { test: 15 }, + ext2: Extension2 { test: 123 }, + }); + assert_eq!(forks.at_block(1), Extensions { + ext1: Extension1 { test: 5 }, + ext2: Extension2 { test: 123 }, + }); + assert_eq!(forks.at_block(2), Extensions { + ext1: Extension1 { test: 5 }, + ext2: Extension2 { test: 5 }, + }); + assert_eq!(forks.at_block(4), Extensions { + ext1: Extension1 { test: 5 }, + ext2: Extension2 { test: 5 }, + }); + assert_eq!(forks.at_block(5), Extensions { + ext1: Extension1 { test: 5 }, + ext2: Extension2 { test: 1 }, + }); + assert_eq!(forks.at_block(10), Extensions { + ext1: Extension1 { test: 5 }, + ext2: Extension2 { test: 1 }, + }); + assert!(forks.at_block(10).get::().is_some()); + + // filter forks for `Extension2` + let ext2 = forks.for_type::().unwrap(); + assert_eq!(ext2.at_block(0), Extension2 { test: 123 }); + assert_eq!(ext2.at_block(2), Extension2 { test: 5 }); + assert_eq!(ext2.at_block(10), Extension2 { test: 1 }); + + // make sure that it can return forks correctly + let ext2_2 = forks.forks::().unwrap(); + assert_eq!(ext2, ext2_2); + + // also ext should be able to return forks correctly: + let ext2_3 = ext.forks::().unwrap(); + assert_eq!(ext2_2, ext2_3); + } +} diff --git a/core/chain-spec/src/lib.rs b/core/chain-spec/src/lib.rs new file mode 100644 index 0000000000000000000000000000000000000000..705be998b7967c8a9ee9e99125213491273847bf --- /dev/null +++ b/core/chain-spec/src/lib.rs @@ -0,0 +1,123 @@ +// Copyright 2019 Parity Technologies (UK) Ltd. +// This file is part of Substrate. + +// Substrate 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. + +// Substrate 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 Substrate. If not, see . + +//! Substrate chain configurations. +//! +//! This crate contains structs and utilities to declare +//! a runtime-specific configuration file (a.k.a chain spec). +//! +//! Basic chain spec type containing all required parameters is +//! [`ChainSpec`](./struct.ChainSpec.html). It can be extended with +//! additional options that contain configuration specific to your chain. +//! Usually the extension is going to be an amalgamate of types exposed +//! by Substrate core modules. To allow the core modules to retrieve +//! their configuration from your extension you should use `ChainSpecExtension` +//! macro exposed by this crate. +//! +//! ```rust +//! use std::collections::HashMap; +//! use serde::{Serialize, Deserialize}; +//! use substrate_chain_spec::{ChainSpec, ChainSpecExtension}; +//! +//! #[derive(Clone, Debug, Serialize, Deserialize, ChainSpecExtension)] +//! pub struct MyExtension { +//! pub known_blocks: HashMap, +//! } +//! +//! pub type MyChainSpec = ChainSpec; +//! ``` +//! +//! Some parameters may require different values depending on the +//! current blockchain height (a.k.a. forks). You can use `ChainSpecGroup` +//! macro and provided [`Forks`](./struct.Forks.html) structure to put +//! such parameters to your chain spec. +//! This will allow to override a single parameter starting at specific +//! block number. +//! +//! ```rust +//! use serde::{Serialize, Deserialize}; +//! use substrate_chain_spec::{Forks, ChainSpec, ChainSpecGroup, ChainSpecExtension}; +//! +//! #[derive(Clone, Debug, Serialize, Deserialize, ChainSpecGroup)] +//! pub struct ClientParams { +//! max_block_size: usize, +//! max_extrinsic_size: usize, +//! } +//! +//! #[derive(Clone, Debug, Serialize, Deserialize, ChainSpecGroup)] +//! pub struct PoolParams { +//! max_transaction_size: usize, +//! } +//! +//! #[derive(Clone, Debug, Serialize, Deserialize, ChainSpecGroup, ChainSpecExtension)] +//! pub struct Extension { +//! pub client: ClientParams, +//! pub pool: PoolParams, +//! } +//! +//! pub type BlockNumber = u64; +//! +//! /// A chain spec supporting forkable `ClientParams`. +//! pub type MyChainSpec1 = ChainSpec>; +//! +//! /// A chain spec supporting forkable `Extension`. +//! pub type MyChainSpec2 = ChainSpec>; +//! ``` +//! +//! It's also possible to have a set of parameters that is allowed to change +//! with block numbers (i.e. is forkable), and another set that is not subject to changes. +//! This is also possible by declaring an extension that contains `Forks` within it. +//! +//! +//! ```rust +//! use serde::{Serialize, Deserialize}; +//! use substrate_chain_spec::{Forks, ChainSpec, ChainSpecGroup, ChainSpecExtension}; +//! +//! #[derive(Clone, Debug, Serialize, Deserialize, ChainSpecGroup)] +//! pub struct ClientParams { +//! max_block_size: usize, +//! max_extrinsic_size: usize, +//! } +//! +//! #[derive(Clone, Debug, Serialize, Deserialize, ChainSpecGroup)] +//! pub struct PoolParams { +//! max_transaction_size: usize, +//! } +//! +//! #[derive(Clone, Debug, Serialize, Deserialize, ChainSpecExtension)] +//! pub struct Extension { +//! pub client: ClientParams, +//! #[forks] +//! pub pool: Forks, +//! } +//! +//! pub type MyChainSpec = ChainSpec; +//! ``` + + +mod chain_spec; +mod extension; + +pub use chain_spec::{ChainSpec, Properties, NoExtension}; +pub use extension::{Group, Fork, Forks, Extension}; +pub use chain_spec_derive::{ChainSpecExtension, ChainSpecGroup}; + +use serde::{Serialize, de::DeserializeOwned}; +use sr_primitives::BuildStorage; + +/// A set of traits for the runtime genesis config. +pub trait RuntimeGenesis: Serialize + DeserializeOwned + BuildStorage {} +impl RuntimeGenesis for T {} diff --git a/core/cli/Cargo.toml b/core/cli/Cargo.toml index a5af7362268f94d413795cb85106fdabdf40739a..e3b33746d580b6e0271b786cd0b5fc15ffe6d319 100644 --- a/core/cli/Cargo.toml +++ b/core/cli/Cargo.toml @@ -6,24 +6,25 @@ description = "Substrate CLI interface." edition = "2018" [dependencies] -clap = "~2.32" -derive_more = "0.14.0" -env_logger = "0.6" -log = "0.4" -atty = "0.2" -regex = "1" -time = "0.1" -ansi_term = "0.11" -lazy_static = "1.3" -app_dirs = "1.2" -tokio = "0.1.7" -futures = "0.1.17" -futures03 = { package = "futures-preview", version = "=0.3.0-alpha.17", features = ["compat"] } -fdlimit = "0.1" -exit-future = "0.1" -serde_json = "1.0" +clap = "~2.32.0" +derive_more = "0.15.0" +env_logger = "0.6.2" +log = "0.4.8" +atty = "0.2.13" +regex = "1.3.1" +time = "0.1.42" +ansi_term = "0.12.1" +lazy_static = "1.4.0" +app_dirs = "1.2.1" +tokio = "0.1.22" +futures = "0.1.29" +futures03 = { package = "futures-preview", version = "=0.3.0-alpha.19", features = ["compat"] } +fdlimit = "0.1.1" +exit-future = "0.1.4" +serde_json = "1.0.40" panic-handler = { package = "substrate-panic-handler", path = "../../core/panic-handler" } client = { package = "substrate-client", path = "../../core/client" } +header-metadata = { package = "substrate-header-metadata", path = "../../core/client/header-metadata" } network = { package = "substrate-network", path = "../../core/network" } sr-primitives = { path = "../../core/sr-primitives" } primitives = { package = "substrate-primitives", path = "../../core/primitives" } @@ -32,8 +33,8 @@ state-machine = { package = "substrate-state-machine", path = "../../core/state- substrate-telemetry = { path = "../../core/telemetry" } keyring = { package = "substrate-keyring", path = "../keyring" } names = "0.11.0" -structopt = "0.2" -rpassword = "3.0" +structopt = "0.2.0" +rpassword = "4.0.1" [dev-dependencies] -tempdir = "0.3" +tempdir = "0.3.7" diff --git a/core/cli/src/informant.rs b/core/cli/src/informant.rs index b5a2f03d795461a75e2ad0f02084875fed395bcb..9d7f04b8f6d4f5162204107d5d4ee96f0e2971d8 100644 --- a/core/cli/src/informant.rs +++ b/core/cli/src/informant.rs @@ -16,27 +16,17 @@ //! Console informant. Prints sync progress and block events. Runs on the calling thread. -use client::{backend::Backend, BlockchainEvents}; +use client::BlockchainEvents; use futures::{Future, Stream}; use futures03::{StreamExt as _, TryStreamExt as _}; use log::{info, warn}; -use sr_primitives::{generic::BlockId, traits::Header}; -use service::{Service, Components}; -use tokio::runtime::TaskExecutor; +use sr_primitives::traits::Header; +use service::AbstractService; mod display; -/// Spawn informant on the event loop -#[deprecated(note = "Please use informant::build instead, and then create the task manually")] -pub fn start(service: &Service, exit: ::exit_future::Exit, handle: TaskExecutor) where - C: Components, -{ - handle.spawn(exit.until(build(service)).map(|_| ())); -} - /// Creates an informant in the form of a `Future` that must be polled regularly. -pub fn build(service: &Service) -> impl Future -where C: Components { +pub fn build(service: &impl AbstractService) -> impl Future { let client = service.client(); let mut display = display::InformantDisplay::new(); @@ -57,19 +47,18 @@ where C: Components { // detect and log reorganizations. if let Some((ref last_num, ref last_hash)) = last_best { if n.header.parent_hash() != last_hash && n.is_new_best { - let tree_route = ::client::blockchain::tree_route( - #[allow(deprecated)] - client.backend().blockchain(), - BlockId::Hash(last_hash.clone()), - BlockId::Hash(n.hash), + let maybe_ancestor = header_metadata::lowest_common_ancestor( + &*client, + last_hash.clone(), + n.hash, ); - match tree_route { - Ok(ref t) if !t.retracted().is_empty() => info!( + match maybe_ancestor { + Ok(ref ancestor) if ancestor.hash != *last_hash => info!( "Reorg from #{},{} to #{},{}, common ancestor #{},{}", last_num, last_hash, n.header.number(), n.hash, - t.common_block().number, t.common_block().hash, + ancestor.number, ancestor.hash, ), Ok(_) => {}, Err(e) => warn!("Error computing tree route: {}", e), diff --git a/core/cli/src/lib.rs b/core/cli/src/lib.rs index ef5290413166d6a247d53f7ecf9c39f4b798b7ff..2e7619116cd89f39ef0fe86c64e230ff296353cd 100644 --- a/core/cli/src/lib.rs +++ b/core/cli/src/lib.rs @@ -29,12 +29,15 @@ pub mod informant; use client::ExecutionStrategies; use service::{ config::Configuration, - ServiceFactory, FactoryFullConfiguration, RuntimeGenesis, - FactoryGenesis, PruningMode, ChainSpec, + ServiceBuilderExport, ServiceBuilderImport, ServiceBuilderRevert, + RuntimeGenesis, ChainSpecExtension, PruningMode, ChainSpec, }; use network::{ - self, multiaddr::Protocol, - config::{NetworkConfiguration, TransportConfig, NonReservedPeerMode, NodeKeyConfig, build_multiaddr}, + self, + multiaddr::Protocol, + config::{ + NetworkConfiguration, TransportConfig, NonReservedPeerMode, NodeKeyConfig, build_multiaddr + }, }; use primitives::H256; @@ -77,7 +80,7 @@ const NODE_KEY_ED25519_FILE: &str = "secret_ed25519"; /// Executable version. Used to pass version information from the root crate. pub struct VersionInfo { - /// Implemtation name. + /// Implementaiton name. pub name: &'static str, /// Implementation version. pub version: &'static str, @@ -121,8 +124,10 @@ fn generate_node_name() -> String { result } -fn load_spec(cli: &SharedParams, factory: F) -> error::Result> - where G: RuntimeGenesis, F: FnOnce(&str) -> Result>, String>, +fn load_spec(cli: &SharedParams, factory: F) -> error::Result> where + G: RuntimeGenesis, + E: ChainSpecExtension, + F: FnOnce(&str) -> Result>, String>, { let chain_key = get_chain_key(cli); let spec = match factory(&chain_key)? { @@ -191,13 +196,13 @@ where I: IntoIterator, ::Item: Into + Clone, { - panic_handler::set(version.support_url); - let full_version = service::config::full_version_from_strs( version.version, version.commit ); + panic_handler::set(version.support_url, &full_version); + let matches = CoreParams::::clap() .name(version.executable_name) .author(version.author) @@ -263,20 +268,23 @@ pub struct ParseAndPrepareRun<'a, RP> { impl<'a, RP> ParseAndPrepareRun<'a, RP> { /// Runs the command and runs the main client. - pub fn run( + pub fn run( self, spec_factory: S, - exit: E, + exit: Exit, run_service: RS, ) -> error::Result<()> - where S: FnOnce(&str) -> Result>, String>, + where S: FnOnce(&str) -> Result>, String>, RP: StructOpt + Clone, C: Default, G: RuntimeGenesis, - E: IntoExit, - RS: FnOnce(E, RunCmd, RP, Configuration) -> Result<(), String> + E: ChainSpecExtension, + Exit: IntoExit, + RS: FnOnce(Exit, RunCmd, RP, Configuration) -> Result<(), String> { - let config = create_run_node_config(self.params.left.clone(), spec_factory, self.impl_name, self.version)?; + let config = create_run_node_config( + self.params.left.clone(), spec_factory, self.impl_name, self.version + )?; run_service(exit, self.params.left, self.params.right, config).map_err(Into::into) } @@ -290,12 +298,13 @@ pub struct ParseAndPrepareBuildSpec<'a> { impl<'a> ParseAndPrepareBuildSpec<'a> { /// Runs the command and build the chain specs. - pub fn run( + pub fn run( self, spec_factory: S - ) -> error::Result<()> - where S: FnOnce(&str) -> Result>, String>, - G: RuntimeGenesis + ) -> error::Result<()> where + S: FnOnce(&str) -> Result>, String>, + G: RuntimeGenesis, + E: ChainSpecExtension, { info!("Building chain spec"); let raw_output = self.params.raw; @@ -317,14 +326,19 @@ pub struct ParseAndPrepareExport<'a> { impl<'a> ParseAndPrepareExport<'a> { /// Runs the command and exports from the chain. - pub fn run( + pub fn run_with_builder( self, + builder: F, spec_factory: S, - exit: E, + exit: Exit, ) -> error::Result<()> - where S: FnOnce(&str) -> Result>>, String>, - F: ServiceFactory, - E: IntoExit + where S: FnOnce(&str) -> Result>, String>, + F: FnOnce(Configuration) -> Result, + B: ServiceBuilderExport, + C: Default, + G: RuntimeGenesis, + E: ChainSpecExtension, + Exit: IntoExit { let config = create_config_with_db_path(spec_factory, &self.params.shared_params, self.version)?; @@ -338,9 +352,8 @@ impl<'a> ParseAndPrepareExport<'a> { None => Box::new(stdout()), }; - service::chain_ops::export_blocks::( - config, exit.into_exit(), file, from.into(), to.map(Into::into), json - ).map_err(Into::into) + builder(config)?.export_blocks(exit.into_exit(), file, from.into(), to.map(Into::into), json)?; + Ok(()) } } @@ -352,14 +365,19 @@ pub struct ParseAndPrepareImport<'a> { impl<'a> ParseAndPrepareImport<'a> { /// Runs the command and imports to the chain. - pub fn run( + pub fn run_with_builder( self, + builder: F, spec_factory: S, - exit: E, + exit: Exit, ) -> error::Result<()> - where S: FnOnce(&str) -> Result>>, String>, - F: ServiceFactory, - E: IntoExit + where S: FnOnce(&str) -> Result>, String>, + F: FnOnce(Configuration) -> Result, + B: ServiceBuilderImport, + C: Default, + G: RuntimeGenesis, + E: ChainSpecExtension, + Exit: IntoExit { let mut config = create_config_with_db_path(spec_factory, &self.params.shared_params, self.version)?; config.execution_strategies = ExecutionStrategies { @@ -377,7 +395,7 @@ impl<'a> ParseAndPrepareImport<'a> { }, }; - let fut = service::chain_ops::import_blocks::(config, exit.into_exit(), file)?; + let fut = builder(config)?.import_blocks(exit.into_exit(), file)?; tokio::run(fut); Ok(()) } @@ -391,18 +409,21 @@ pub struct ParseAndPreparePurge<'a> { impl<'a> ParseAndPreparePurge<'a> { /// Runs the command and purges the chain. - pub fn run( + pub fn run( self, spec_factory: S - ) -> error::Result<()> - where S: FnOnce(&str) -> Result>, String>, - G: RuntimeGenesis + ) -> error::Result<()> where + S: FnOnce(&str) -> Result>, String>, + G: RuntimeGenesis, + E: ChainSpecExtension, { - let config = create_config_with_db_path::<(), _, _>(spec_factory, &self.params.shared_params, self.version)?; + let config = create_config_with_db_path::<(), _, _, _>( + spec_factory, &self.params.shared_params, self.version + )?; let db_path = config.database_path; if !self.params.yes { - print!("Are you sure to remove {:?}? (y/n)", &db_path); + print!("Are you sure to remove {:?}? [y/N]: ", &db_path); stdout().flush().expect("failed to flush stdout"); let mut input = String::new(); @@ -440,67 +461,27 @@ pub struct ParseAndPrepareRevert<'a> { impl<'a> ParseAndPrepareRevert<'a> { /// Runs the command and reverts the chain. - pub fn run( + pub fn run_with_builder( self, + builder: F, spec_factory: S - ) -> error::Result<()> - where S: FnOnce(&str) -> Result>>, String>, - F: ServiceFactory { - let config = create_config_with_db_path(spec_factory, &self.params.shared_params, self.version)?; + ) -> error::Result<()> where + S: FnOnce(&str) -> Result>, String>, + F: FnOnce(Configuration) -> Result, + B: ServiceBuilderRevert, + C: Default, + G: RuntimeGenesis, + E: ChainSpecExtension, + { + let config = create_config_with_db_path( + spec_factory, &self.params.shared_params, self.version + )?; let blocks = self.params.num; - Ok(service::chain_ops::revert_chain::(config, blocks.into())?) + builder(config)?.revert_chain(blocks.into())?; + Ok(()) } } -/// Parse command line interface arguments and executes the desired command. -/// -/// # Return value -/// -/// A result that indicates if any error occurred. -/// If no error occurred and a custom subcommand was found, the subcommand is returned. -/// The user needs to handle this subcommand on its own. -/// -/// # Remarks -/// -/// `CC` is a custom subcommand. This needs to be an `enum`! If no custom subcommand is required, -/// `NoCustom` can be used as type here. -/// `RP` are custom parameters for the run command. This needs to be a `struct`! The custom -/// parameters are visible to the user as if they were normal run command parameters. If no custom -/// parameters are required, `NoCustom` can be used as type here. -#[deprecated( - note = "Use parse_and_prepare instead; see the source code of parse_and_execute for how to transition" -)] -pub fn parse_and_execute<'a, F, CC, RP, S, RS, E, I, T>( - spec_factory: S, - version: &VersionInfo, - impl_name: &'static str, - args: I, - exit: E, - run_service: RS, -) -> error::Result> -where - F: ServiceFactory, - S: FnOnce(&str) -> Result>>, String>, - CC: StructOpt + Clone + GetLogFilter, - RP: StructOpt + Clone + AugmentClap, - E: IntoExit, - RS: FnOnce(E, RunCmd, RP, FactoryFullConfiguration) -> Result<(), String>, - I: IntoIterator, - T: Into + Clone, -{ - match parse_and_prepare::(version, impl_name, args) { - ParseAndPrepare::Run(cmd) => cmd.run(spec_factory, exit, run_service), - ParseAndPrepare::BuildSpec(cmd) => cmd.run(spec_factory), - ParseAndPrepare::ExportBlocks(cmd) => cmd.run::(spec_factory, exit), - ParseAndPrepare::ImportBlocks(cmd) => cmd.run::(spec_factory, exit), - ParseAndPrepare::PurgeChain(cmd) => cmd.run(spec_factory), - ParseAndPrepare::RevertChain(cmd) => cmd.run::(spec_factory), - ParseAndPrepare::CustomCommand(cmd) => return Ok(Some(cmd)) - }?; - - Ok(None) -} - /// Create a `NodeKeyConfig` from the given `NodeKeyParams` in the context /// of an optional network config storage directory. fn node_key_config

(params: NodeKeyParams, net_config_dir: &Option

) @@ -556,8 +537,8 @@ fn parse_ed25519_secret(hex: &String) -> error::Result( - options: &mut Configuration, +fn fill_transaction_pool_configuration( + options: &mut Configuration, params: TransactionPoolParams, ) -> error::Result<()> { // ready queue @@ -587,7 +568,8 @@ fn fill_network_configuration( ); config.net_config_path = config.config_path.clone(); config.reserved_nodes.extend(cli.reserved_nodes.into_iter()); - if !config.reserved_nodes.is_empty() { + + if cli.reserved_only { config.non_reserved_mode = NonReservedPeerMode::Deny; } @@ -631,8 +613,8 @@ fn input_keystore_password() -> Result { } /// Fill the password field of the given config instance. -fn fill_config_keystore_password( - config: &mut service::Configuration, +fn fill_config_keystore_password( + config: &mut service::Configuration, cli: &RunCmd, ) -> Result<(), String> { config.keystore_password = if cli.password_interactive { @@ -648,13 +630,14 @@ fn fill_config_keystore_password( Ok(()) } -fn create_run_node_config( +fn create_run_node_config( cli: RunCmd, spec_factory: S, impl_name: &'static str, version: &VersionInfo -) -> error::Result> +) -> error::Result> where C: Default, G: RuntimeGenesis, - S: FnOnce(&str) -> Result>, String>, + E: ChainSpecExtension, + S: FnOnce(&str) -> Result>, String>, { let spec = load_spec(&cli.shared_params, spec_factory)?; let mut config = service::Configuration::default_with_spec(spec.clone()); @@ -693,8 +676,8 @@ where config.pruning = match cli.pruning { Some(ref s) if s == "archive" => PruningMode::ArchiveAll, None => PruningMode::default(), - Some(s) => PruningMode::keep_blocks( - s.parse().map_err(|_| error::Error::Input("Invalid pruning mode specified".to_string()))? + Some(s) => PruningMode::keep_blocks(s.parse() + .map_err(|_| error::Error::Input("Invalid pruning mode specified".to_string()))? ), }; @@ -792,13 +775,14 @@ where // 9803-9874 Unassigned // 9926-9949 Unassigned -fn with_default_boot_node( - spec: &mut ChainSpec, +fn with_default_boot_node( + spec: &mut ChainSpec, cli: BuildSpecCmd, version: &VersionInfo, ) -> error::Result<()> where - G: RuntimeGenesis + G: RuntimeGenesis, + E: ChainSpecExtension, { if spec.boot_nodes().is_empty() { let base_path = base_path(&cli.shared_params, version); @@ -817,13 +801,14 @@ where } /// Creates a configuration including the database path. -pub fn create_config_with_db_path( +pub fn create_config_with_db_path( spec_factory: S, cli: &SharedParams, version: &VersionInfo, -) -> error::Result> +) -> error::Result> where C: Default, G: RuntimeGenesis, - S: FnOnce(&str) -> Result>, String>, + E: ChainSpecExtension, + S: FnOnce(&str) -> Result>, String>, { let spec = load_spec(cli, spec_factory)?; let base_path = base_path(cli, version); diff --git a/core/cli/src/params.rs b/core/cli/src/params.rs index b17fc114c4f07fbeaa8b30fbe372f7bb13fad287..6656e1653fc986b3c17fce5428382741b092ee17 100644 --- a/core/cli/src/params.rs +++ b/core/cli/src/params.rs @@ -17,7 +17,7 @@ use crate::traits::{AugmentClap, GetLogFilter}; use std::path::PathBuf; -use structopt::{StructOpt, clap::{arg_enum, _clap_count_exprs, App, AppSettings, SubCommand, Arg}}; +use structopt::{StructOpt, clap::{arg_enum, App, AppSettings, _clap_count_exprs, SubCommand, Arg}}; use client; pub use crate::execution_strategy::ExecutionStrategy; @@ -58,11 +58,11 @@ arg_enum! { /// Shared parameters used by all `CoreParams`. #[derive(Debug, StructOpt, Clone)] pub struct SharedParams { - /// Specify the chain specification (one of dev, local or staging) + /// Specify the chain specification (one of dev, local or staging). #[structopt(long = "chain", value_name = "CHAIN_SPEC")] pub chain: Option, - /// Specify the development chain + /// Specify the development chain. #[structopt(long = "dev")] pub dev: bool, @@ -70,7 +70,7 @@ pub struct SharedParams { #[structopt(long = "base-path", short = "d", value_name = "PATH", parse(from_os_str))] pub base_path: Option, - /// Sets a custom logging filter + /// Sets a custom logging filter. #[structopt(short = "l", long = "log", value_name = "LOG_PATTERN")] pub log: Option, } @@ -84,32 +84,43 @@ impl GetLogFilter for SharedParams { /// Parameters used to create the network configuration. #[derive(Debug, StructOpt, Clone)] pub struct NetworkConfigurationParams { - /// Specify a list of bootnodes + /// Specify a list of bootnodes. #[structopt(long = "bootnodes", value_name = "URL")] pub bootnodes: Vec, - /// Specify a list of reserved node addresses + /// Specify a list of reserved node addresses. #[structopt(long = "reserved-nodes", value_name = "URL")] pub reserved_nodes: Vec, - /// Listen on this multiaddress + /// Whether to only allow connections to/from reserved nodes. + /// + /// If you are a validator your node might still connect to other validator + /// nodes regardless of whether they are defined as reserved nodes. + #[structopt(long = "reserved-only")] + pub reserved_only: bool, + + /// Listen on this multiaddress. #[structopt(long = "listen-addr", value_name = "LISTEN_ADDR")] pub listen_addr: Vec, - /// Specify p2p protocol TCP port. Only used if --listen-addr is not specified. + /// Specify p2p protocol TCP port. + /// + /// Only used if --listen-addr is not specified. #[structopt(long = "port", value_name = "PORT")] pub port: Option, - /// Specify the number of outgoing connections we're trying to maintain + /// Specify the number of outgoing connections we're trying to maintain. #[structopt(long = "out-peers", value_name = "OUT_PEERS", default_value = "25")] pub out_peers: u32, - /// Specify the maximum number of incoming connections we're accepting + /// Specify the maximum number of incoming connections we're accepting. #[structopt(long = "in-peers", value_name = "IN_PEERS", default_value = "25")] pub in_peers: u32, - /// By default, the network will use mDNS to discover other nodes on the local network. This - /// disables it. Automatically implied when using --dev. + /// Disable mDNS discovery. + /// + /// By default, the network will use mDNS to discover other nodes on the + /// local network. This disables it. Automatically implied when using --dev. #[structopt(long = "no-mdns")] pub no_mdns: bool, @@ -119,6 +130,7 @@ pub struct NetworkConfigurationParams { } arg_enum! { + #[allow(missing_docs)] #[derive(Debug, Copy, Clone, PartialEq, Eq)] pub enum NodeKeyType { Secp256k1, @@ -208,7 +220,7 @@ pub struct TransactionPoolParams { #[structopt(long = "pool-limit", value_name = "COUNT", default_value = "512")] pub pool_limit: usize, /// Maximum number of kilobytes of all transactions stored in the pool. - #[structopt(long = "pool-kbytes", value_name = "COUNT", default_value="10240")] + #[structopt(long = "pool-kbytes", value_name = "COUNT", default_value = "10240")] pub pool_kbytes: usize, } @@ -297,39 +309,43 @@ pub struct ExecutionStrategies { /// The `run` command used to run a node. #[derive(Debug, StructOpt, Clone)] pub struct RunCmd { - /// Enable validator mode + /// Enable validator mode. #[structopt(long = "validator")] pub validator: bool, - /// Disable GRANDPA voter when running in validator mode, otherwise disables the GRANDPA observer + /// Disable GRANDPA voter when running in validator mode, otherwise disables the GRANDPA observer. #[structopt(long = "no-grandpa")] pub no_grandpa: bool, - /// Experimental: Run in light client mode + /// Experimental: Run in light client mode. #[structopt(long = "light")] pub light: bool, - /// Limit the memory the database cache can use + /// Limit the memory the database cache can use. #[structopt(long = "db-cache", value_name = "MiB")] pub database_cache_size: Option, - /// Specify the state cache size + /// Specify the state cache size. #[structopt(long = "state-cache-size", value_name = "Bytes", default_value = "67108864")] pub state_cache_size: usize, - /// Listen to all RPC interfaces (default is local) + /// Listen to all RPC interfaces. + /// + /// Default is local. #[structopt(long = "rpc-external")] pub rpc_external: bool, - /// Listen to all Websocket interfaces (default is local) + /// Listen to all Websocket interfaces. + /// + /// Default is local. #[structopt(long = "ws-external")] pub ws_external: bool, - /// Specify HTTP RPC server TCP port + /// Specify HTTP RPC server TCP port. #[structopt(long = "rpc-port", value_name = "PORT")] pub rpc_port: Option, - /// Specify WebSockets RPC server TCP port + /// Specify WebSockets RPC server TCP port. #[structopt(long = "ws-port", value_name = "PORT")] pub ws_port: Option, @@ -338,33 +354,45 @@ pub struct RunCmd { pub ws_max_connections: Option, /// Specify browser Origins allowed to access the HTTP & WS RPC servers. - /// It's a comma-separated list of origins (protocol://domain or special `null` value). - /// Value of `all` will disable origin validation. - /// Default is to allow localhost, https://polkadot.js.org and https://substrate-ui.parity.io origins. - /// When running in --dev mode the default is to allow all origins. + /// + /// A comma-separated list of origins (protocol://domain or special `null` + /// value). Value of `all` will disable origin validation. Default is to + /// allow localhost, https://polkadot.js.org and + /// https://substrate-ui.parity.io origins. When running in --dev mode the + /// default is to allow all origins. #[structopt(long = "rpc-cors", value_name = "ORIGINS", parse(try_from_str = "parse_cors"))] pub rpc_cors: Option, - /// Specify the pruning mode, a number of blocks to keep or 'archive'. Default is 256. + /// Specify the pruning mode, a number of blocks to keep or 'archive'. + /// + /// Default is 256. #[structopt(long = "pruning", value_name = "PRUNING_MODE")] pub pruning: Option, - /// The human-readable name for this node, as reported to the telemetry server, if enabled + /// The human-readable name for this node. + /// + /// The node name will be reported to the telemetry server, if enabled. #[structopt(long = "name", value_name = "NAME")] pub name: Option, - /// Disable connecting to the Substrate telemetry server (telemetry is on by default on global chains). + /// Disable connecting to the Substrate telemetry server. + /// + /// Telemetry is on by default on global chains. #[structopt(long = "no-telemetry")] pub no_telemetry: bool, - /// The URL of the telemetry server to connect to. This flag can be passed multiple times - /// as a mean to specify multiple telemetry endpoints. Verbosity levels range from 0-9, with - /// 0 denoting the least verbosity. If no verbosity level is specified the default is 0. + /// The URL of the telemetry server to connect to. + /// + /// This flag can be passed multiple times as a mean to specify multiple + /// telemetry endpoints. Verbosity levels range from 0-9, with 0 denoting + /// the least verbosity. If no verbosity level is specified the default is + /// 0. #[structopt(long = "telemetry-url", value_name = "URL VERBOSITY", parse(try_from_str = "parse_telemetry_endpoints"))] pub telemetry_endpoints: Vec<(String, u8)>, - /// Should execute offchain workers on every block. By default it's only enabled for nodes that are authoring new - /// blocks. + /// Should execute offchain workers on every block. + /// + /// By default it's only enabled for nodes that are authoring new blocks. #[structopt( long = "offchain-worker", value_name = "ENABLED", @@ -440,7 +468,11 @@ lazy_static::lazy_static! { /// The Cli values for all test accounts. static ref TEST_ACCOUNTS_CLI_VALUES: Vec = { keyring::Sr25519Keyring::iter().map(|a| { - let help = format!("Shortcut for `--key //{} --name {}`.", a, a); + let help = format!( + "Shortcut for `--name {} --validator` with session keys for `{}` added to keystore.", + a, + a, + ); let conflicts_with = keyring::Sr25519Keyring::iter() .filter(|b| a != *b) .map(|b| b.to_string().to_lowercase()) @@ -579,11 +611,15 @@ pub struct ExportBlocksCmd { #[structopt(parse(from_os_str))] pub output: Option, - /// Specify starting block number. 1 by default. + /// Specify starting block number. + /// + /// Default is 1. #[structopt(long = "from", value_name = "BLOCK")] pub from: Option, - /// Specify last block number. Best block by default. + /// Specify last block number. + /// + /// Default is best block. #[structopt(long = "to", value_name = "BLOCK")] pub to: Option, @@ -605,7 +641,9 @@ pub struct ImportBlocksCmd { #[structopt(parse(from_os_str))] pub input: Option, - /// The default number of 64KB pages to ever allocate for Wasm execution. Don't alter this unless you know what you're doing. + /// The default number of 64KB pages to ever allocate for Wasm execution. + /// + /// Don't alter this unless you know what you're doing. #[structopt(long = "default-heap-pages", value_name = "COUNT")] pub default_heap_pages: Option, @@ -700,7 +738,9 @@ impl StructOpt for CoreParams where ) .subcommand( ExportBlocksCmd::augment_clap(SubCommand::with_name("export-blocks")) - .about("Export blocks to a file.") + .about("Export blocks to a file. This file can only be re-imported \ + if it is in binary format (not JSON!)." + ) ) .subcommand( ImportBlocksCmd::augment_clap(SubCommand::with_name("import-blocks")) diff --git a/core/client/Cargo.toml b/core/client/Cargo.toml index d917427a509f1cb3ba54038e2625db6ffa138d8a..8852988cb11e1c61e862dac266c7dfc907d916b8 100644 --- a/core/client/Cargo.toml +++ b/core/client/Cargo.toml @@ -5,19 +5,20 @@ authors = ["Parity Technologies "] edition = "2018" [dependencies] -derive_more = { version = "0.14.0", optional = true } -fnv = { version = "1.0", optional = true } -log = { version = "0.4", optional = true } +derive_more = { version = "0.15.0", optional = true } +fnv = { version = "1.0.6", optional = true } +log = { version = "0.4.8", optional = true } parking_lot = { version = "0.9.0", optional = true } -hex = { package = "hex-literal", version = "0.2", optional = true } -futures-preview = { version = "=0.3.0-alpha.17", optional = true } +hex-literal = { version = "0.2.1", optional = true } +futures = { version = "0.1.29", optional = true } +futures03 = { package = "futures-preview", version = "0.3.0-alpha.19", features = ["compat"], optional = true } consensus = { package = "substrate-consensus-common", path = "../consensus/common", optional = true } executor = { package = "substrate-executor", path = "../executor", optional = true } state-machine = { package = "substrate-state-machine", path = "../state-machine", optional = true } keyring = { package = "substrate-keyring", path = "../keyring", optional = true } trie = { package = "substrate-trie", path = "../trie", optional = true } substrate-telemetry = { path = "../telemetry", optional = true } -hash-db = { version = "0.15.0", default-features = false } +hash-db = { version = "0.15.2", default-features = false } kvdb = { git = "https://github.com/paritytech/parity-common", optional = true, rev="b0317f649ab2c665b7987b8475878fc4d2e1f81d" } codec = { package = "parity-scale-codec", version = "1.0.0", default-features = false, features = ["derive"] } primitives = { package = "substrate-primitives", path = "../primitives", default-features = false } @@ -26,11 +27,14 @@ runtime-version = { package = "sr-version", path = "../sr-version", default-feat rstd = { package = "sr-std", path = "../sr-std", default-features = false } inherents = { package = "substrate-inherents", path = "../inherents", default-features = false } sr-api-macros = { path = "../sr-api-macros" } +header-metadata = { package = "substrate-header-metadata", path = "header-metadata", optional = true } [dev-dependencies] -env_logger = "0.6" +env_logger = "0.6.2" +tempfile = "3.1.0" test-client = { package = "substrate-test-runtime-client", path = "../test-runtime/client" } kvdb-memorydb = { git = "https://github.com/paritytech/parity-common", rev="b0317f649ab2c665b7987b8475878fc4d2e1f81d" } +panic-handler = { package = "substrate-panic-handler", path = "../panic-handler" } [features] default = ["std"] @@ -42,13 +46,15 @@ std = [ "sr-primitives/std", "runtime-version/std", "hash-db/std", + "header-metadata", "consensus", "parking_lot", "derive_more", "fnv", "log", - "hex", - "futures-preview", + "hex-literal", + "futures", + "futures03", "executor", "state-machine", "keyring", diff --git a/core/client/db/Cargo.toml b/core/client/db/Cargo.toml index b7bc835ef012a6494168a5e22849ad4955546d58..891255cb77abb285de21a9c27d003f037f052565 100644 --- a/core/client/db/Cargo.toml +++ b/core/client/db/Cargo.toml @@ -6,13 +6,13 @@ edition = "2018" [dependencies] parking_lot = "0.9.0" -log = "0.4" +log = "0.4.8" kvdb = { git = "https://github.com/paritytech/parity-common", rev="b0317f649ab2c665b7987b8475878fc4d2e1f81d" } # FIXME replace with release as soon as our rocksdb changes are released upstream https://github.com/paritytech/parity-common/issues/88 kvdb-rocksdb = { git = "https://github.com/paritytech/parity-common", rev="b0317f649ab2c665b7987b8475878fc4d2e1f81d", optional = true } kvdb-memorydb = { git = "https://github.com/paritytech/parity-common", rev="b0317f649ab2c665b7987b8475878fc4d2e1f81d" } -linked-hash-map = "0.5" -hash-db = { version = "0.15.0" } +linked-hash-map = "0.5.2" +hash-db = "0.15.2" primitives = { package = "substrate-primitives", path = "../../primitives" } sr-primitives = { path = "../../sr-primitives" } client = { package = "substrate-client", path = "../../client" } @@ -22,11 +22,12 @@ executor = { package = "substrate-executor", path = "../../executor" } state_db = { package = "substrate-state-db", path = "../../state-db" } trie = { package = "substrate-trie", path = "../../trie" } consensus_common = { package = "substrate-consensus-common", path = "../../consensus/common" } +header_metadata = { package = "substrate-header-metadata", path = "../header-metadata" } [dev-dependencies] substrate-keyring = { path = "../../keyring" } test-client = { package = "substrate-test-runtime-client", path = "../../test-runtime/client" } -env_logger = { version = "0.6" } +env_logger = "0.6.2" [features] default = [] diff --git a/core/client/db/src/cache/list_cache.rs b/core/client/db/src/cache/list_cache.rs index c53cdbfcb71a1f004ce8423d018d4f8dc71280ab..660819bb6a868e9c612655b835b65ca2ccdd665b 100644 --- a/core/client/db/src/cache/list_cache.rs +++ b/core/client/db/src/cache/list_cache.rs @@ -52,12 +52,21 @@ use crate::cache::{CacheItemT, ComplexBlockId, EntryType}; use crate::cache::list_entry::{Entry, StorageEntry}; use crate::cache::list_storage::{Storage, StorageTransaction, Metadata}; +/// Pruning strategy. +#[derive(Debug, Clone, Copy)] +pub enum PruningStrategy { + /// Prune entries when they're too far behind best finalized block. + ByDepth(N), + /// Do not prune old entries at all. + NeverPrune, +} + /// List-based cache. pub struct ListCache> { /// Cache storage. storage: S, - /// Prune depth. - prune_depth: NumberFor, + /// Pruning strategy. + pruning_strategy: PruningStrategy>, /// Best finalized block. best_finalized_block: ComplexBlockId, /// Best finalized entry (if exists). @@ -110,7 +119,11 @@ pub enum ForkAppendResult { impl> ListCache { /// Create new db list cache entry. - pub fn new(storage: S, prune_depth: NumberFor, best_finalized_block: ComplexBlockId) -> Self { + pub fn new( + storage: S, + pruning_strategy: PruningStrategy>, + best_finalized_block: ComplexBlockId, + ) -> Self { let (best_finalized_entry, unfinalized) = storage.read_meta() .and_then(|meta| read_forks(&storage, meta)) .unwrap_or_else(|error| { @@ -120,7 +133,7 @@ impl> ListCache ListCache { storage, - prune_depth, + pruning_strategy, best_finalized_block, best_finalized_entry, unfinalized, @@ -133,7 +146,10 @@ impl> ListCache } /// Get value valid at block. - pub fn value_at_block(&self, at: &ComplexBlockId) -> ClientResult> { + pub fn value_at_block( + &self, + at: &ComplexBlockId, + ) -> ClientResult, Option>, T)>> { let head = if at.number <= self.best_finalized_block.number { // if the block is older than the best known finalized block // => we're should search for the finalized value @@ -167,7 +183,7 @@ impl> ListCache match head { Some(head) => head.search_best_before(&self.storage, at.number) - .map(|e| e.map(|e| e.0.value)), + .map(|e| e.map(|e| (e.0.valid_from, e.1, e.0.value))), None => Ok(None), } } @@ -408,9 +424,14 @@ impl> ListCache tx: &mut Tx, block: &ComplexBlockId ) { + let prune_depth = match self.pruning_strategy { + PruningStrategy::ByDepth(prune_depth) => prune_depth, + PruningStrategy::NeverPrune => return, + }; + let mut do_pruning = || -> ClientResult<()> { // calculate last ancient block number - let ancient_block = match block.number.checked_sub(&self.prune_depth) { + let ancient_block = match block.number.checked_sub(&prune_depth) { Some(number) => match self.storage.read_id(number)? { Some(hash) => ComplexBlockId::new(hash, number), None => return Ok(()), @@ -752,7 +773,7 @@ pub mod tests { // when block is earlier than best finalized block AND it is not finalized // --- 50 --- // ----------> [100] - assert_eq!(ListCache::<_, u64, _>::new(DummyStorage::new(), 1024, test_id(100)) + assert_eq!(ListCache::<_, u64, _>::new(DummyStorage::new(), PruningStrategy::ByDepth(1024), test_id(100)) .value_at_block(&test_id(50)).unwrap(), None); // when block is earlier than best finalized block AND it is finalized AND value is some // [30] ---- 50 ---> [100] @@ -762,8 +783,8 @@ pub mod tests { .with_id(50, H256::from_low_u64_be(50)) .with_entry(test_id(100), StorageEntry { prev_valid_from: Some(test_id(30)), value: 100 }) .with_entry(test_id(30), StorageEntry { prev_valid_from: None, value: 30 }), - 1024, test_id(100) - ).value_at_block(&test_id(50)).unwrap(), Some(30)); + PruningStrategy::ByDepth(1024), test_id(100) + ).value_at_block(&test_id(50)).unwrap(), Some((test_id(30), Some(test_id(100)), 30))); // when block is the best finalized block AND value is some // ---> [100] assert_eq!(ListCache::new( @@ -772,8 +793,8 @@ pub mod tests { .with_id(100, H256::from_low_u64_be(100)) .with_entry(test_id(100), StorageEntry { prev_valid_from: Some(test_id(30)), value: 100 }) .with_entry(test_id(30), StorageEntry { prev_valid_from: None, value: 30 }), - 1024, test_id(100) - ).value_at_block(&test_id(100)).unwrap(), Some(100)); + PruningStrategy::ByDepth(1024), test_id(100) + ).value_at_block(&test_id(100)).unwrap(), Some((test_id(100), None, 100))); // when block is parallel to the best finalized block // ---- 100 // ---> [100] @@ -783,7 +804,7 @@ pub mod tests { .with_id(50, H256::from_low_u64_be(50)) .with_entry(test_id(100), StorageEntry { prev_valid_from: Some(test_id(30)), value: 100 }) .with_entry(test_id(30), StorageEntry { prev_valid_from: None, value: 30 }), - 1024, test_id(100) + PruningStrategy::ByDepth(1024), test_id(100) ).value_at_block(&ComplexBlockId::new(H256::from_low_u64_be(2), 100)).unwrap(), None); // when block is later than last finalized block AND there are no forks AND finalized value is Some @@ -793,8 +814,8 @@ pub mod tests { .with_meta(Some(test_id(100)), Vec::new()) .with_id(50, H256::from_low_u64_be(50)) .with_entry(test_id(100), StorageEntry { prev_valid_from: Some(test_id(30)), value: 100 }), - 1024, test_id(100) - ).value_at_block(&test_id(200)).unwrap(), Some(100)); + PruningStrategy::ByDepth(1024), test_id(100) + ).value_at_block(&test_id(200)).unwrap(), Some((test_id(100), None, 100))); // when block is later than last finalized block AND there are no matching forks // AND block is connected to finalized block AND finalized value is Some @@ -809,8 +830,8 @@ pub mod tests { .with_header(test_header(3)) .with_header(test_header(4)) .with_header(fork_header(0, 2, 3)), - 1024, test_id(2) - ).value_at_block(&fork_id(0, 2, 3)).unwrap(), Some(2)); + PruningStrategy::ByDepth(1024), test_id(2) + ).value_at_block(&fork_id(0, 2, 3)).unwrap(), Some((correct_id(2), None, 2))); // when block is later than last finalized block AND there are no matching forks // AND block is not connected to finalized block // --- 2 --- 3 @@ -826,7 +847,7 @@ pub mod tests { .with_header(test_header(4)) .with_header(fork_header(0, 1, 3)) .with_header(fork_header(0, 1, 2)), - 1024, test_id(2) + PruningStrategy::ByDepth(1024), test_id(2) ).value_at_block(&fork_id(0, 1, 3)).unwrap(), None); // when block is later than last finalized block AND it appends to unfinalized fork from the end @@ -839,8 +860,8 @@ pub mod tests { .with_entry(correct_id(4), StorageEntry { prev_valid_from: Some(correct_id(2)), value: 4 }) .with_header(test_header(4)) .with_header(test_header(5)), - 1024, test_id(2) - ).value_at_block(&correct_id(5)).unwrap(), Some(4)); + PruningStrategy::ByDepth(1024), test_id(2) + ).value_at_block(&correct_id(5)).unwrap(), Some((correct_id(4), None, 4))); // when block is later than last finalized block AND it does not fits unfinalized fork // AND it is connected to the finalized block AND finalized value is Some // ---> [2] ----------> [4] @@ -854,8 +875,8 @@ pub mod tests { .with_header(test_header(3)) .with_header(test_header(4)) .with_header(fork_header(0, 2, 3)), - 1024, test_id(2) - ).value_at_block(&fork_id(0, 2, 3)).unwrap(), Some(2)); + PruningStrategy::ByDepth(1024), test_id(2) + ).value_at_block(&fork_id(0, 2, 3)).unwrap(), Some((correct_id(2), None, 2))); } #[test] @@ -864,7 +885,7 @@ pub mod tests { let fin = EntryType::Final; // when trying to insert block < finalized number - assert!(ListCache::new(DummyStorage::new(), 1024, test_id(100)) + assert!(ListCache::new(DummyStorage::new(), PruningStrategy::ByDepth(1024), test_id(100)) .on_block_insert( &mut DummyTransaction::new(), test_id(49), @@ -873,7 +894,7 @@ pub mod tests { nfin, ).unwrap().is_none()); // when trying to insert block @ finalized number - assert!(ListCache::new(DummyStorage::new(), 1024, test_id(100)) + assert!(ListCache::new(DummyStorage::new(), PruningStrategy::ByDepth(1024), test_id(100)) .on_block_insert( &mut DummyTransaction::new(), test_id(99), @@ -888,7 +909,7 @@ pub mod tests { DummyStorage::new() .with_meta(None, vec![test_id(4)]) .with_entry(test_id(4), StorageEntry { prev_valid_from: None, value: 4 }), - 1024, test_id(2) + PruningStrategy::ByDepth(1024), test_id(2) ); cache.unfinalized[0].best_block = Some(test_id(4)); let mut tx = DummyTransaction::new(); @@ -913,7 +934,7 @@ pub mod tests { .with_meta(None, vec![correct_id(4)]) .with_entry(correct_id(4), StorageEntry { prev_valid_from: None, value: 4 }) .with_header(test_header(4)), - 1024, test_id(2) + PruningStrategy::ByDepth(1024), test_id(2) ); let mut tx = DummyTransaction::new(); assert_eq!(cache.on_block_insert(&mut tx, correct_id(4), correct_id(5), Some(4), nfin).unwrap(), @@ -939,7 +960,7 @@ pub mod tests { .with_header(test_header(2)) .with_header(test_header(3)) .with_header(test_header(4)), - 1024, correct_id(2) + PruningStrategy::ByDepth(1024), correct_id(2) ); let mut tx = DummyTransaction::new(); assert_eq!(cache.on_block_insert(&mut tx, correct_id(3), fork_id(0, 3, 4), Some(14), nfin).unwrap(), @@ -954,7 +975,7 @@ pub mod tests { DummyStorage::new() .with_meta(Some(correct_id(2)), vec![]) .with_entry(correct_id(2), StorageEntry { prev_valid_from: None, value: 2 }), - 1024, correct_id(2) + PruningStrategy::ByDepth(1024), correct_id(2) ); let mut tx = DummyTransaction::new(); assert_eq!(cache.on_block_insert(&mut tx, correct_id(2), correct_id(3), Some(2), nfin).unwrap(), None); @@ -967,7 +988,7 @@ pub mod tests { DummyStorage::new() .with_meta(Some(correct_id(2)), vec![]) .with_entry(correct_id(2), StorageEntry { prev_valid_from: None, value: 2 }), - 1024, correct_id(2) + PruningStrategy::ByDepth(1024), correct_id(2) ); let mut tx = DummyTransaction::new(); assert_eq!(cache.on_block_insert(&mut tx, correct_id(2), correct_id(3), Some(3), nfin).unwrap(), @@ -977,7 +998,7 @@ pub mod tests { assert_eq!(*tx.updated_meta(), Some(Metadata { finalized: Some(correct_id(2)), unfinalized: vec![correct_id(3)] })); // when inserting finalized entry AND there are no previous finalized entries - let cache = ListCache::new(DummyStorage::new(), 1024, correct_id(2)); + let cache = ListCache::new(DummyStorage::new(), PruningStrategy::ByDepth(1024), correct_id(2)); let mut tx = DummyTransaction::new(); assert_eq!( cache.on_block_insert(&mut tx, correct_id(2), correct_id(3), Some(3), fin).unwrap(), @@ -995,7 +1016,7 @@ pub mod tests { DummyStorage::new() .with_meta(Some(correct_id(2)), vec![]) .with_entry(correct_id(2), StorageEntry { prev_valid_from: None, value: 2 }), - 1024, correct_id(2) + PruningStrategy::ByDepth(1024), correct_id(2) ); let mut tx = DummyTransaction::new(); assert_eq!(cache.on_block_insert(&mut tx, correct_id(2), correct_id(3), Some(2), fin).unwrap(), @@ -1023,7 +1044,7 @@ pub mod tests { .with_meta(Some(correct_id(2)), vec![fork_id(0, 1, 3)]) .with_entry(correct_id(2), StorageEntry { prev_valid_from: None, value: 2 }) .with_entry(fork_id(0, 1, 3), StorageEntry { prev_valid_from: None, value: 13 }), - 1024, correct_id(2) + PruningStrategy::ByDepth(1024), correct_id(2) ); let mut tx = DummyTransaction::new(); assert_eq!(cache.on_block_insert(&mut tx, correct_id(2), correct_id(3), Some(2), fin).unwrap(), @@ -1038,7 +1059,7 @@ pub mod tests { .with_meta(Some(correct_id(2)), vec![correct_id(5)]) .with_entry(correct_id(2), StorageEntry { prev_valid_from: None, value: 2 }) .with_entry(correct_id(5), StorageEntry { prev_valid_from: Some(correct_id(2)), value: 5 }), - 1024, correct_id(2) + PruningStrategy::ByDepth(1024), correct_id(2) ); let mut tx = DummyTransaction::new(); assert_eq!(cache.on_block_finalize(&mut tx, correct_id(2), correct_id(3)).unwrap(), @@ -1052,7 +1073,7 @@ pub mod tests { .with_meta(Some(correct_id(2)), vec![correct_id(5)]) .with_entry(correct_id(2), StorageEntry { prev_valid_from: None, value: 2 }) .with_entry(correct_id(5), StorageEntry { prev_valid_from: Some(correct_id(2)), value: 5 }), - 1024, correct_id(4) + PruningStrategy::ByDepth(1024), correct_id(4) ); let mut tx = DummyTransaction::new(); assert_eq!( @@ -1072,7 +1093,7 @@ pub mod tests { .with_meta(Some(correct_id(2)), vec![fork_id(0, 1, 3)]) .with_entry(correct_id(2), StorageEntry { prev_valid_from: None, value: 2 }) .with_entry(fork_id(0, 1, 3), StorageEntry { prev_valid_from: None, value: 13 }), - 1024, correct_id(2) + PruningStrategy::ByDepth(1024), correct_id(2) ); let mut tx = DummyTransaction::new(); assert_eq!(cache.on_block_finalize(&mut tx, correct_id(2), correct_id(3)).unwrap(), @@ -1087,7 +1108,7 @@ pub mod tests { .with_entry(correct_id(2), StorageEntry { prev_valid_from: None, value: 2 }) .with_entry(correct_id(5), StorageEntry { prev_valid_from: Some(correct_id(2)), value: 5 }) .with_entry(correct_id(6), StorageEntry { prev_valid_from: Some(correct_id(5)), value: 6 }), - 1024, correct_id(2) + PruningStrategy::ByDepth(1024), correct_id(2) ); // when new block is appended to unfinalized fork @@ -1126,7 +1147,7 @@ pub mod tests { .with_header(test_header(3)) .with_header(test_header(4)) .with_header(test_header(5)), - 1024, correct_id(0) + PruningStrategy::ByDepth(1024), correct_id(0) ).find_unfinalized_fork(&correct_id(4)).unwrap().unwrap().head.valid_from, correct_id(5)); // --- [2] ---------------> [5] // ----------> [3] ---> 4 @@ -1143,7 +1164,7 @@ pub mod tests { .with_header(fork_header(0, 1, 2)) .with_header(fork_header(0, 1, 3)) .with_header(fork_header(0, 1, 4)), - 1024, correct_id(0) + PruningStrategy::ByDepth(1024), correct_id(0) ).find_unfinalized_fork(&fork_id(0, 1, 4)).unwrap().unwrap().head.valid_from, fork_id(0, 1, 3)); // --- [2] ---------------> [5] // ----------> [3] @@ -1163,7 +1184,7 @@ pub mod tests { .with_header(fork_header(1, 1, 2)) .with_header(fork_header(1, 1, 3)) .with_header(fork_header(1, 1, 4)), - 1024, correct_id(0) + PruningStrategy::ByDepth(1024), correct_id(0) ).find_unfinalized_fork(&fork_id(1, 1, 4)).unwrap().is_none()); } @@ -1424,33 +1445,46 @@ pub mod tests { } #[test] - fn ancient_entries_are_pruned() { - let cache = ListCache::new(DummyStorage::new() - .with_id(10, H256::from_low_u64_be(10)) - .with_id(20, H256::from_low_u64_be(20)) - .with_id(30, H256::from_low_u64_be(30)) - .with_entry(test_id(10), StorageEntry { prev_valid_from: None, value: 10 }) - .with_entry(test_id(20), StorageEntry { prev_valid_from: Some(test_id(10)), value: 20 }) - .with_entry(test_id(30), StorageEntry { prev_valid_from: Some(test_id(20)), value: 30 }), - 10, test_id(9)); - let mut tx = DummyTransaction::new(); + fn ancient_entries_are_pruned_when_pruning_enabled() { + fn do_test(strategy: PruningStrategy) { + let cache = ListCache::new(DummyStorage::new() + .with_id(10, H256::from_low_u64_be(10)) + .with_id(20, H256::from_low_u64_be(20)) + .with_id(30, H256::from_low_u64_be(30)) + .with_entry(test_id(10), StorageEntry { prev_valid_from: None, value: 10 }) + .with_entry(test_id(20), StorageEntry { prev_valid_from: Some(test_id(10)), value: 20 }) + .with_entry(test_id(30), StorageEntry { prev_valid_from: Some(test_id(20)), value: 30 }), + strategy, test_id(9)); + let mut tx = DummyTransaction::new(); + + // when finalizing entry #10: no entries pruned + cache.prune_finalized_entries(&mut tx, &test_id(10)); + assert!(tx.removed_entries().is_empty()); + assert!(tx.inserted_entries().is_empty()); + // when finalizing entry #19: no entries pruned + cache.prune_finalized_entries(&mut tx, &test_id(19)); + assert!(tx.removed_entries().is_empty()); + assert!(tx.inserted_entries().is_empty()); + // when finalizing entry #20: no entries pruned + cache.prune_finalized_entries(&mut tx, &test_id(20)); + assert!(tx.removed_entries().is_empty()); + assert!(tx.inserted_entries().is_empty()); + // when finalizing entry #30: entry 10 pruned + entry 20 is truncated (if pruning is enabled) + cache.prune_finalized_entries(&mut tx, &test_id(30)); + match strategy { + PruningStrategy::NeverPrune => { + assert!(tx.removed_entries().is_empty()); + assert!(tx.inserted_entries().is_empty()); + }, + PruningStrategy::ByDepth(_) => { + assert_eq!(*tx.removed_entries(), vec![test_id(10).hash].into_iter().collect()); + assert_eq!(*tx.inserted_entries(), vec![test_id(20).hash].into_iter().collect()); + }, + } + } - // when finalizing entry #10: no entries pruned - cache.prune_finalized_entries(&mut tx, &test_id(10)); - assert!(tx.removed_entries().is_empty()); - assert!(tx.inserted_entries().is_empty()); - // when finalizing entry #19: no entries pruned - cache.prune_finalized_entries(&mut tx, &test_id(19)); - assert!(tx.removed_entries().is_empty()); - assert!(tx.inserted_entries().is_empty()); - // when finalizing entry #20: no entries pruned - cache.prune_finalized_entries(&mut tx, &test_id(20)); - assert!(tx.removed_entries().is_empty()); - assert!(tx.inserted_entries().is_empty()); - // when finalizing entry #30: entry 10 pruned + entry 20 is truncated - cache.prune_finalized_entries(&mut tx, &test_id(30)); - assert_eq!(*tx.removed_entries(), vec![test_id(10).hash].into_iter().collect()); - assert_eq!(*tx.inserted_entries(), vec![test_id(20).hash].into_iter().collect()); + do_test(PruningStrategy::ByDepth(10)); + do_test(PruningStrategy::NeverPrune) } #[test] diff --git a/core/client/db/src/cache/mod.rs b/core/client/db/src/cache/mod.rs index cad3db1bf2bccfa834648f6264951772587f8708..bfc496dd2fa3bec0bbc366682b555285c8276495 100644 --- a/core/client/db/src/cache/mod.rs +++ b/core/client/db/src/cache/mod.rs @@ -21,15 +21,14 @@ use parking_lot::RwLock; use kvdb::{KeyValueDB, DBTransaction}; -use client::blockchain::Cache as BlockchainCache; +use client::blockchain::{well_known_cache_keys::{self, Id as CacheKeyId}, Cache as BlockchainCache}; use client::error::Result as ClientResult; use codec::{Encode, Decode}; use sr_primitives::generic::BlockId; use sr_primitives::traits::{Block as BlockT, Header as HeaderT, NumberFor, Zero}; -use consensus_common::well_known_cache_keys::Id as CacheKeyId; use crate::utils::{self, COLUMN_META, db_err}; -use self::list_cache::ListCache; +use self::list_cache::{ListCache, PruningStrategy}; mod list_cache; mod list_entry; @@ -166,7 +165,7 @@ fn get_cache_helper<'a, Block: BlockT>( cache, }, ), - PRUNE_DEPTH.into(), + cache_pruning_strategy(name), best_finalized_block.clone(), ) }) @@ -315,9 +314,13 @@ impl BlockchainCache for DbCacheSync { Ok(()) } - fn get_at(&self, key: &CacheKeyId, at: &BlockId) -> Option> { - let cache = self.0.read(); - let storage = cache.cache_at.get(key)?.storage(); + fn get_at( + &self, + key: &CacheKeyId, + at: &BlockId, + ) -> Option<((NumberFor, Block::Hash), Option<(NumberFor, Block::Hash)>, Vec)> { + let mut cache = self.0.write(); + let storage = cache.get_cache(*key).storage(); let db = storage.db(); let columns = storage.columns(); let at = match *at { @@ -339,7 +342,30 @@ impl BlockchainCache for DbCacheSync { }, }; - cache.cache_at.get(key)?.value_at_block(&at).ok()? + cache.cache_at + .get(key)? + .value_at_block(&at) + .map(|block_and_value| block_and_value.map(|(begin_block, end_block, value)| + ( + (begin_block.number, begin_block.hash), + end_block.map(|end_block| (end_block.number, end_block.hash)), + value, + ))) + .ok()? } } +/// Get pruning strategy for given cache. +fn cache_pruning_strategy>(cache: CacheKeyId) -> PruningStrategy { + // the cache is mostly used to store data from consensus engines + // this kind of data is only required for non-finalized blocks + // => by default we prune finalized cached entries + + match cache { + // we need to keep changes tries configurations forever (or at least until changes tries, + // that were built using this configuration, are pruned) to make it possible to refer + // to old changes tries + well_known_cache_keys::CHANGES_TRIE_CONFIG => PruningStrategy::NeverPrune, + _ => PruningStrategy::ByDepth(PRUNE_DEPTH.into()), + } +} diff --git a/core/client/db/src/lib.rs b/core/client/db/src/lib.rs index f6be022be02107110ae009a52507a4e51a587d90..cdeda77dec0dbc1494b20a9ad33624d0545ca641 100644 --- a/core/client/db/src/lib.rs +++ b/core/client/db/src/lib.rs @@ -36,34 +36,37 @@ mod utils; use std::sync::Arc; use std::path::PathBuf; use std::io; -use std::collections::HashMap; +use std::collections::{HashMap, HashSet}; use client::backend::NewBlockState; -use client::blockchain::HeaderBackend; -use client::ExecutionStrategies; +use client::blockchain::{well_known_cache_keys, HeaderBackend}; +use client::{ForkBlocks, ExecutionStrategies}; use client::backend::{StorageCollection, ChildStorageCollection}; +use client::error::{Result as ClientResult, Error as ClientError}; use codec::{Decode, Encode}; use hash_db::{Hasher, Prefix}; use kvdb::{KeyValueDB, DBTransaction}; use trie::{MemoryDB, PrefixedMemoryDB, prefixed_key}; use parking_lot::{Mutex, RwLock}; -use primitives::{H256, Blake2Hasher, ChangesTrieConfiguration, convert_hash}; +use primitives::{H256, Blake2Hasher, ChangesTrieConfiguration, convert_hash, traits::CodeExecutor}; use primitives::storage::well_known_keys; use sr_primitives::{ generic::{BlockId, DigestItem}, Justification, StorageOverlay, ChildrenStorageOverlay, - BuildStorage + BuildStorage, }; use sr_primitives::traits::{ Block as BlockT, Header as HeaderT, NumberFor, Zero, One, SaturatedConversion }; -use state_machine::backend::Backend as StateBackend; use executor::RuntimeInfo; -use state_machine::{CodeExecutor, DBValue}; -use crate::utils::{Meta, db_err, meta_keys, read_db, block_id_to_lookup_key, read_meta}; +use state_machine::{ + DBValue, ChangesTrieTransaction, ChangesTrieCacheAction, ChangesTrieBuildCache, + backend::Backend as StateBackend, +}; +use crate::utils::{Meta, db_err, meta_keys, read_db, read_meta}; use client::leaves::{LeafSet, FinalizationDisplaced}; use client::children; use state_db::StateDb; -use consensus_common::well_known_cache_keys; +use header_metadata::{CachedHeaderMetadata, HeaderMetadata, HeaderMetadataCache}; use crate::storage_cache::{CachingState, SharedCache, new_shared_cache}; use log::{trace, debug, warn}; pub use state_db::PruningMode; @@ -108,6 +111,12 @@ impl Drop for RefTrackingState { } } +impl std::fmt::Debug for RefTrackingState { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!(f, "Block {:?}", self.parent_hash) + } +} + impl StateBackend for RefTrackingState { type Error = >::Error; type Transaction = >::Transaction; @@ -137,6 +146,10 @@ impl StateBackend for RefTrackingState { self.state.for_keys_with_prefix(prefix, f) } + fn for_key_values_with_prefix(&self, prefix: &[u8], f: F) { + self.state.for_key_values_with_prefix(prefix, f) + } + fn for_keys_in_child_storage(&self, storage_key: &[u8], f: F) { self.state.for_keys_in_child_storage(storage_key, f) } @@ -195,11 +208,19 @@ pub fn new_client( settings: DatabaseSettings, executor: E, genesis_storage: S, + fork_blocks: ForkBlocks, execution_strategies: ExecutionStrategies, keystore: Option, -) -> Result< - client::Client, - client::LocalCallExecutor, E>, Block, RA>, client::error::Error +) -> Result<( + client::Client< + Backend, + client::LocalCallExecutor, E>, + Block, + RA, + >, + Arc>, + ), + client::error::Error, > where Block: BlockT, @@ -208,7 +229,10 @@ pub fn new_client( { let backend = Arc::new(Backend::new(settings, CANONICALIZATION_DELAY)?); let executor = client::LocalCallExecutor::new(backend.clone(), executor, keystore); - Ok(client::Client::new(backend, executor, genesis_storage, execution_strategies)?) + Ok(( + client::Client::new(backend.clone(), executor, genesis_storage, fork_blocks, execution_strategies)?, + backend, + )) } pub(crate) mod columns { @@ -249,16 +273,18 @@ pub struct BlockchainDb { db: Arc, meta: Arc, Block::Hash>>>, leaves: RwLock>>, + header_metadata_cache: HeaderMetadataCache, } impl BlockchainDb { - fn new(db: Arc) -> Result { + fn new(db: Arc) -> ClientResult { let meta = read_meta::(&*db, columns::META, columns::HEADER)?; let leaves = LeafSet::read_from_db(&*db, columns::META, meta_keys::LEAF_PREFIX)?; Ok(BlockchainDb { db, leaves: RwLock::new(leaves), meta: Arc::new(RwLock::new(meta)), + header_metadata_cache: HeaderMetadataCache::default(), }) } @@ -288,7 +314,7 @@ impl BlockchainDb { } impl client::blockchain::HeaderBackend for BlockchainDb { - fn header(&self, id: BlockId) -> Result, client::error::Error> { + fn header(&self, id: BlockId) -> ClientResult> { utils::read_header(&*self.db, columns::KEY_LOOKUP, columns::HEADER, id) } @@ -303,7 +329,7 @@ impl client::blockchain::HeaderBackend for BlockchainDb) -> Result { + fn status(&self, id: BlockId) -> ClientResult { let exists = match id { BlockId::Hash(_) => read_db( &*self.db, @@ -319,16 +345,11 @@ impl client::blockchain::HeaderBackend for BlockchainDb Result>, client::error::Error> { - if let Some(lookup_key) = block_id_to_lookup_key::(&*self.db, columns::KEY_LOOKUP, BlockId::Hash(hash))? { - let number = utils::lookup_key_to_number(&lookup_key)?; - Ok(Some(number)) - } else { - Ok(None) - } + fn number(&self, hash: Block::Hash) -> ClientResult>> { + Ok(self.header_metadata(hash).ok().map(|header_metadata| header_metadata.number)) } - fn hash(&self, number: NumberFor) -> Result, client::error::Error> { + fn hash(&self, number: NumberFor) -> ClientResult> { self.header(BlockId::Number(number)).and_then(|maybe_header| match maybe_header { Some(header) => Ok(Some(header.hash().clone())), None => Ok(None), @@ -337,7 +358,7 @@ impl client::blockchain::HeaderBackend for BlockchainDb client::blockchain::Backend for BlockchainDb { - fn body(&self, id: BlockId) -> Result>, client::error::Error> { + fn body(&self, id: BlockId) -> ClientResult>> { match read_db(&*self.db, columns::KEY_LOOKUP, columns::BODY, id)? { Some(body) => match Decode::decode(&mut &body[..]) { Ok(body) => Ok(Some(body)), @@ -349,7 +370,7 @@ impl client::blockchain::Backend for BlockchainDb { } } - fn justification(&self, id: BlockId) -> Result, client::error::Error> { + fn justification(&self, id: BlockId) -> ClientResult> { match read_db(&*self.db, columns::KEY_LOOKUP, columns::JUSTIFICATION, id)? { Some(justification) => match Decode::decode(&mut &justification[..]) { Ok(justification) => Ok(Some(justification)), @@ -361,7 +382,7 @@ impl client::blockchain::Backend for BlockchainDb { } } - fn last_finalized(&self) -> Result { + fn last_finalized(&self) -> ClientResult { Ok(self.meta.read().finalized_hash.clone()) } @@ -369,11 +390,11 @@ impl client::blockchain::Backend for BlockchainDb { None } - fn leaves(&self) -> Result, client::error::Error> { + fn leaves(&self) -> ClientResult> { Ok(self.leaves.read().hashes()) } - fn children(&self, parent_hash: Block::Hash) -> Result, client::error::Error> { + fn children(&self, parent_hash: Block::Hash) -> ClientResult> { children::read_children(&*self.db, columns::META, meta_keys::CHILDREN_PREFIX, parent_hash) } } @@ -384,6 +405,31 @@ impl client::blockchain::ProvideCache for BlockchainDb HeaderMetadata for BlockchainDb { + type Error = client::error::Error; + + fn header_metadata(&self, hash: Block::Hash) -> Result, Self::Error> { + self.header_metadata_cache.header_metadata(hash).or_else(|_| { + self.header(BlockId::hash(hash))?.map(|header| { + let header_metadata = CachedHeaderMetadata::from(&header); + self.header_metadata_cache.insert_header_metadata( + header_metadata.hash, + header_metadata.clone(), + ); + header_metadata + }).ok_or(ClientError::UnknownBlock(format!("header not found in db: {}", hash))) + }) + } + + fn insert_header_metadata(&self, hash: Block::Hash, metadata: CachedHeaderMetadata) { + self.header_metadata_cache.insert_header_metadata(hash, metadata) + } + + fn remove_header_metadata(&self, hash: Block::Hash) { + self.header_metadata_cache.remove_header_metadata(hash); + } +} + /// Database transaction pub struct BlockImportOperation { old_state: CachingState, Block>, @@ -391,6 +437,7 @@ pub struct BlockImportOperation { storage_updates: StorageCollection, child_storage_updates: ChildStorageCollection, changes_trie_updates: MemoryDB, + changes_trie_cache_update: Option>>, pending_block: Option>, aux_ops: Vec<(Vec, Option>)>, finalized_blocks: Vec<(BlockId, Option)>, @@ -414,7 +461,7 @@ where Block: BlockT, { type State = CachingState, Block>; - fn state(&self) -> Result, client::error::Error> { + fn state(&self) -> ClientResult> { Ok(Some(&self.old_state)) } @@ -424,7 +471,7 @@ where Block: BlockT, body: Option>, justification: Option, leaf_state: NewBlockState, - ) -> Result<(), client::error::Error> { + ) -> ClientResult<()> { assert!(self.pending_block.is_none(), "Only one block per operation is allowed"); self.pending_block = Some(PendingBlock { header, @@ -439,7 +486,7 @@ where Block: BlockT, // Currently cache isn't implemented on full nodes. } - fn update_db_storage(&mut self, update: PrefixedMemoryDB) -> Result<(), client::error::Error> { + fn update_db_storage(&mut self, update: PrefixedMemoryDB) -> ClientResult<()> { self.db_updates = update; Ok(()) } @@ -448,7 +495,7 @@ where Block: BlockT, &mut self, top: StorageOverlay, children: ChildrenStorageOverlay - ) -> Result { + ) -> ClientResult { if top.iter().any(|(k, _)| well_known_keys::is_child_storage_key(k)) { return Err(client::error::Error::GenesisInvalid.into()); @@ -473,12 +520,16 @@ where Block: BlockT, Ok(root) } - fn update_changes_trie(&mut self, update: MemoryDB) -> Result<(), client::error::Error> { - self.changes_trie_updates = update; + fn update_changes_trie( + &mut self, + update: ChangesTrieTransaction>, + ) -> ClientResult<()> { + self.changes_trie_updates = update.0; + self.changes_trie_cache_update = Some(update.1); Ok(()) } - fn insert_aux(&mut self, ops: I) -> Result<(), client::error::Error> + fn insert_aux(&mut self, ops: I) -> ClientResult<()> where I: IntoIterator, Option>)> { self.aux_ops.append(&mut ops.into_iter().collect()); @@ -489,18 +540,18 @@ where Block: BlockT, &mut self, update: StorageCollection, child_update: ChildStorageCollection, - ) -> Result<(), client::error::Error> { + ) -> ClientResult<()> { self.storage_updates = update; self.child_storage_updates = child_update; Ok(()) } - fn mark_finalized(&mut self, block: BlockId, justification: Option) -> Result<(), client::error::Error> { + fn mark_finalized(&mut self, block: BlockId, justification: Option) -> ClientResult<()> { self.finalized_blocks.push((block, justification)); Ok(()) } - fn mark_head(&mut self, block: BlockId) -> Result<(), client::error::Error> { + fn mark_head(&mut self, block: BlockId) -> ClientResult<()> { assert!(self.set_head.is_none(), "Only one set head per operation is allowed"); self.set_head = Some(block); Ok(()) @@ -551,6 +602,7 @@ pub struct DbChangesTrieStorage { db: Arc, meta: Arc, Block::Hash>>>, min_blocks_to_keep: Option, + cache: RwLock>>, _phantom: ::std::marker::PhantomData, } @@ -562,6 +614,11 @@ impl> DbChangesTrieStorage { } } + /// Commit changes into changes trie build cache. + pub fn commit_cache(&self, cache_update: ChangesTrieCacheAction>) { + self.cache.write().perform(cache_update); + } + /// Prune obsolete changes tries. pub fn prune( &self, @@ -681,6 +738,18 @@ impl state_machine::ChangesTrieStorage> where Block: BlockT, { + fn as_roots_storage(&self) -> &dyn state_machine::ChangesTrieRootsStorage> { + self + } + + fn with_cached_changed_keys( + &self, + root: &H256, + functor: &mut dyn FnMut(&HashMap>, HashSet>>), + ) -> bool { + self.cache.read().with_changed_keys(root, functor) + } + fn get(&self, key: &H256, _prefix: Prefix) -> Result, String> { self.db.get(columns::CHANGES_TRIE, &key[..]) .map_err(|err| format!("{}", err)) @@ -706,11 +775,11 @@ impl> Backend { /// Create a new instance of database backend. /// /// The pruning window is how old a block must be before the state is pruned. - pub fn new(config: DatabaseSettings, canonicalization_delay: u64) -> client::error::Result { + pub fn new(config: DatabaseSettings, canonicalization_delay: u64) -> ClientResult { Self::new_inner(config, canonicalization_delay) } - fn new_inner(config: DatabaseSettings, canonicalization_delay: u64) -> Result { + fn new_inner(config: DatabaseSettings, canonicalization_delay: u64) -> ClientResult { #[cfg(feature = "kvdb-rocksdb")] let db = crate::utils::open_database(&config, columns::META, "full")?; #[cfg(not(feature = "kvdb-rocksdb"))] @@ -750,7 +819,7 @@ impl> Backend { db: Arc, canonicalization_delay: u64, config: &DatabaseSettings - ) -> Result { + ) -> ClientResult { let is_archive_pruning = config.pruning.is_archive(); let blockchain = BlockchainDb::new(db.clone())?; let meta = blockchain.meta.clone(); @@ -765,6 +834,7 @@ impl> Backend { db, meta, min_blocks_to_keep: if is_archive_pruning { None } else { Some(MIN_BLOCKS_TO_KEEP_CHANGES_TRIES_FOR) }, + cache: RwLock::new(ChangesTrieBuildCache::new()), _phantom: Default::default(), }; @@ -835,7 +905,7 @@ impl> Backend { /// /// Currently changes tries configuration is set up once (at genesis) and could not /// be changed. Thus, we'll actually read value once and then just use cached value. - fn changes_trie_config(&self, block: Block::Hash) -> Result, client::error::Error> { + fn changes_trie_config(&self, block: Block::Hash) -> ClientResult> { let mut cached_changes_trie_config = self.changes_trie_config.lock(); match cached_changes_trie_config.clone() { Some(cached_changes_trie_config) => Ok(cached_changes_trie_config), @@ -858,7 +928,12 @@ impl> Backend { /// In the case where the new best block is a block to be imported, `route_to` /// should be the parent of `best_to`. In the case where we set an existing block /// to be best, `route_to` should equal to `best_to`. - fn set_head_with_transaction(&self, transaction: &mut DBTransaction, route_to: Block::Hash, best_to: (NumberFor, Block::Hash)) -> Result<(Vec, Vec), client::error::Error> { + fn set_head_with_transaction( + &self, + transaction: &mut DBTransaction, + route_to: Block::Hash, + best_to: (NumberFor, Block::Hash), + ) -> ClientResult<(Vec, Vec)> { let mut enacted = Vec::default(); let mut retracted = Vec::default(); @@ -866,10 +941,10 @@ impl> Backend { // cannot find tree route with empty DB. if meta.best_hash != Default::default() { - let tree_route = ::client::blockchain::tree_route( + let tree_route = header_metadata::tree_route( &self.blockchain, - BlockId::Hash(meta.best_hash), - BlockId::Hash(route_to), + meta.best_hash, + route_to, )?; // uncanonicalize: check safety violations and ensure the numbers no longer @@ -920,7 +995,7 @@ impl> Backend { &self, header: &Block::Header, last_finalized: Option, - ) -> Result<(), client::error::Error> { + ) -> ClientResult<()> { let last_finalized = last_finalized.unwrap_or_else(|| self.blockchain.meta.read().finalized_hash); if *header.parent_hash() != last_finalized { return Err(::client::error::Error::NonSequentialFinalization( @@ -938,7 +1013,7 @@ impl> Backend { last_finalized: Option, justification: Option, finalization_displaced: &mut Option>>, - ) -> Result<(Block::Hash, ::Number, bool, bool), client::error::Error> { + ) -> ClientResult<(Block::Hash, ::Number, bool, bool)> { // TODO: ensure best chain contains this block. let number = *header.number(); self.ensure_sequential_finalization(header, last_finalized)?; @@ -966,7 +1041,7 @@ impl> Backend { hash: Block::Hash, number: NumberFor, ) - -> Result<(), client::error::Error> + -> ClientResult<()> { let number_u64 = number.saturated_into::(); if number_u64 > self.canonicalization_delay { @@ -994,31 +1069,29 @@ impl> Backend { } fn try_commit_operation(&self, mut operation: BlockImportOperation) - -> Result<(), client::error::Error> + -> ClientResult<()> { let mut transaction = DBTransaction::new(); let mut finalization_displaced_leaves = None; operation.apply_aux(&mut transaction); - let mut meta_updates = Vec::new(); + let mut meta_updates = Vec::with_capacity(operation.finalized_blocks.len()); let mut last_finalized_hash = self.blockchain.meta.read().finalized_hash; - if !operation.finalized_blocks.is_empty() { - for (block, justification) in operation.finalized_blocks { - let block_hash = self.blockchain.expect_block_hash_from_id(&block)?; - let block_header = self.blockchain.expect_header(BlockId::Hash(block_hash))?; + for (block, justification) in operation.finalized_blocks { + let block_hash = self.blockchain.expect_block_hash_from_id(&block)?; + let block_header = self.blockchain.expect_header(BlockId::Hash(block_hash))?; - meta_updates.push(self.finalize_block_with_transaction( - &mut transaction, - &block_hash, - &block_header, - Some(last_finalized_hash), - justification, - &mut finalization_displaced_leaves, - )?); - last_finalized_hash = block_hash; - } + meta_updates.push(self.finalize_block_with_transaction( + &mut transaction, + &block_hash, + &block_header, + Some(last_finalized_hash), + justification, + &mut finalization_displaced_leaves, + )?); + last_finalized_hash = block_hash; } let imported = if let Some(pending_block) = operation.pending_block { @@ -1042,6 +1115,12 @@ impl> Backend { hash, )?; + let header_metadata = CachedHeaderMetadata::from(&pending_block.header); + self.blockchain.insert_header_metadata( + header_metadata.hash, + header_metadata, + ); + transaction.put(columns::HEADER, &lookup_key, &pending_block.header.encode()); if let Some(body) = pending_block.body { transaction.put(columns::BODY, &lookup_key, &body.encode()); @@ -1078,7 +1157,6 @@ impl> Backend { self.changes_tries_storage.commit(&mut transaction, changes_trie_updates); let cache = operation.old_state.release(); // release state reference so that it can be finalized - if finalized { // TODO: ensure best chain contains this block. self.ensure_sequential_finalization(header, Some(last_finalized_hash))?; @@ -1135,6 +1213,10 @@ impl> Backend { let write_result = self.storage.db.write(transaction).map_err(db_err); + if let Some(changes_trie_cache_update) = operation.changes_trie_cache_update { + self.changes_tries_storage.commit_cache(changes_trie_cache_update); + } + if let Some((number, hash, enacted, retracted, displaced_leaf, is_best, mut cache)) = imported { if let Err(e) = write_result { let mut leaves = self.blockchain.leaves.write(); @@ -1182,7 +1264,7 @@ impl> Backend { f_header: &Block::Header, f_hash: Block::Hash, displaced: &mut Option>> - ) -> Result<(), client::error::Error> where + ) -> ClientResult<()> where Block: BlockT, { let f_num = f_header.number().clone(); @@ -1235,7 +1317,7 @@ impl client::backend::AuxStore for Backend where Block: BlockT, D: IntoIterator, - >(&self, insert: I, delete: D) -> client::error::Result<()> { + >(&self, insert: I, delete: D) -> ClientResult<()> { let mut transaction = DBTransaction::new(); for (k, v) in insert { transaction.put(columns::AUX, k, v); @@ -1247,7 +1329,7 @@ impl client::backend::AuxStore for Backend where Block: BlockT Result>, client::error::Error> { + fn get_aux(&self, key: &[u8]) -> ClientResult>> { Ok(self.storage.db.get(columns::AUX, key).map(|r| r.map(|v| v.to_vec())).map_err(db_err)?) } } @@ -1259,7 +1341,7 @@ impl client::backend::Backend for Backend whe type ChangesTrieStorage = DbChangesTrieStorage; type OffchainStorage = offchain::LocalStorage; - fn begin_operation(&self) -> Result { + fn begin_operation(&self) -> ClientResult { let old_state = self.state_at(BlockId::Hash(Default::default()))?; Ok(BlockImportOperation { pending_block: None, @@ -1268,19 +1350,24 @@ impl client::backend::Backend for Backend whe storage_updates: Default::default(), child_storage_updates: Default::default(), changes_trie_updates: MemoryDB::default(), + changes_trie_cache_update: None, aux_ops: Vec::new(), finalized_blocks: Vec::new(), set_head: None, }) } - fn begin_state_operation(&self, operation: &mut Self::BlockImportOperation, block: BlockId) -> Result<(), client::error::Error> { + fn begin_state_operation( + &self, + operation: &mut Self::BlockImportOperation, + block: BlockId, + ) -> ClientResult<()> { operation.old_state = self.state_at(block)?; Ok(()) } fn commit_operation(&self, operation: Self::BlockImportOperation) - -> Result<(), client::error::Error> + -> ClientResult<()> { match self.try_commit_operation(operation) { Ok(_) => { @@ -1295,7 +1382,7 @@ impl client::backend::Backend for Backend whe } fn finalize_block(&self, block: BlockId, justification: Option) - -> Result<(), client::error::Error> + -> ClientResult<()> { let mut transaction = DBTransaction::new(); let hash = self.blockchain.expect_block_hash_from_id(&block)?; @@ -1335,7 +1422,7 @@ impl client::backend::Backend for Backend whe Some(self.offchain_storage.clone()) } - fn revert(&self, n: NumberFor) -> Result, client::error::Error> { + fn revert(&self, n: NumberFor) -> ClientResult> { let mut best = self.blockchain.info().best_number; let finalized = self.blockchain.info().finalized_number; let revertible = best - finalized; @@ -1380,7 +1467,7 @@ impl client::backend::Backend for Backend whe Some(used) } - fn state_at(&self, block: BlockId) -> Result { + fn state_at(&self, block: BlockId) -> ClientResult { use client::blockchain::HeaderBackend as BcHeaderBackend; // special case for genesis initialization @@ -1416,7 +1503,7 @@ impl client::backend::Backend for Backend whe !self.storage.state_db.is_pruned(hash, number.saturated_into::()) } - fn destroy_state(&self, state: Self::State) -> Result<(), client::error::Error> { + fn destroy_state(&self, state: Self::State) -> ClientResult<()> { if let Some(hash) = state.cache.parent_hash.clone() { let is_best = || self.blockchain.meta.read().best_hash == hash; state.release().sync_cache(&[], &[], vec![], vec![], None, None, is_best); @@ -1449,6 +1536,8 @@ mod tests { use sr_primitives::testing::{Header, Block as RawBlock, ExtrinsicWrapper}; use sr_primitives::traits::{Hash, BlakeTwo256}; use state_machine::{TrieMut, TrieDBMut, ChangesTrieRootsStorage, ChangesTrieStorage}; + use header_metadata::{lowest_common_ancestor, tree_route}; + use test_client; type Block = RawBlock>; @@ -1477,7 +1566,6 @@ mod tests { extrinsics_root: H256, ) -> H256 { use sr_primitives::testing::Digest; - let (changes_root, changes_trie_update) = prepare_changes(changes); let digest = Digest { logs: vec![ @@ -1487,7 +1575,7 @@ mod tests { let header = Header { number, parent_hash, - state_root: BlakeTwo256::trie_root::<_, &[u8], &[u8]>(Vec::new()), + state_root: BlakeTwo256::trie_root(Vec::new()), digest, extrinsics_root, }; @@ -1501,7 +1589,7 @@ mod tests { let mut op = backend.begin_operation().unwrap(); backend.begin_state_operation(&mut op, block_id).unwrap(); op.set_block_data(header, None, None, NewBlockState::Best).unwrap(); - op.update_changes_trie(changes_trie_update).unwrap(); + op.update_changes_trie((changes_trie_update, ChangesTrieCacheAction::Clear)).unwrap(); backend.commit_operation(op).unwrap(); header_hash @@ -2020,6 +2108,7 @@ mod tests { #[test] fn tree_route_works() { let backend = Backend::::new_test(1000, 100); + let blockchain = backend.blockchain(); let block0 = insert_header(&backend, 0, Default::default(), Vec::new(), Default::default()); // fork from genesis: 3 prong. @@ -2032,11 +2121,7 @@ mod tests { let b2 = insert_header(&backend, 2, b1, Vec::new(), Default::default()); { - let tree_route = ::client::blockchain::tree_route( - backend.blockchain(), - BlockId::Hash(a3), - BlockId::Hash(b2) - ).unwrap(); + let tree_route = tree_route(blockchain, a3, b2).unwrap(); assert_eq!(tree_route.common_block().hash, block0); assert_eq!(tree_route.retracted().iter().map(|r| r.hash).collect::>(), vec![a3, a2, a1]); @@ -2044,11 +2129,7 @@ mod tests { } { - let tree_route = ::client::blockchain::tree_route( - backend.blockchain(), - BlockId::Hash(a1), - BlockId::Hash(a3), - ).unwrap(); + let tree_route = tree_route(blockchain, a1, a3).unwrap(); assert_eq!(tree_route.common_block().hash, a1); assert!(tree_route.retracted().is_empty()); @@ -2056,11 +2137,7 @@ mod tests { } { - let tree_route = ::client::blockchain::tree_route( - backend.blockchain(), - BlockId::Hash(a3), - BlockId::Hash(a1), - ).unwrap(); + let tree_route = tree_route(blockchain, a3, a1).unwrap(); assert_eq!(tree_route.common_block().hash, a1); assert_eq!(tree_route.retracted().iter().map(|r| r.hash).collect::>(), vec![a3, a2]); @@ -2068,11 +2145,7 @@ mod tests { } { - let tree_route = ::client::blockchain::tree_route( - backend.blockchain(), - BlockId::Hash(a2), - BlockId::Hash(a2), - ).unwrap(); + let tree_route = tree_route(blockchain, a2, a2).unwrap(); assert_eq!(tree_route.common_block().hash, a2); assert!(tree_route.retracted().is_empty()); @@ -2083,16 +2156,13 @@ mod tests { #[test] fn tree_route_child() { let backend = Backend::::new_test(1000, 100); + let blockchain = backend.blockchain(); let block0 = insert_header(&backend, 0, Default::default(), Vec::new(), Default::default()); let block1 = insert_header(&backend, 1, block0, Vec::new(), Default::default()); { - let tree_route = ::client::blockchain::tree_route( - backend.blockchain(), - BlockId::Hash(block0), - BlockId::Hash(block1), - ).unwrap(); + let tree_route = tree_route(blockchain, block0, block1).unwrap(); assert_eq!(tree_route.common_block().hash, block0); assert!(tree_route.retracted().is_empty()); @@ -2100,6 +2170,64 @@ mod tests { } } + #[test] + fn lowest_common_ancestor_works() { + let backend = Backend::::new_test(1000, 100); + let blockchain = backend.blockchain(); + let block0 = insert_header(&backend, 0, Default::default(), Vec::new(), Default::default()); + + // fork from genesis: 3 prong. + let a1 = insert_header(&backend, 1, block0, Vec::new(), Default::default()); + let a2 = insert_header(&backend, 2, a1, Vec::new(), Default::default()); + let a3 = insert_header(&backend, 3, a2, Vec::new(), Default::default()); + + // fork from genesis: 2 prong. + let b1 = insert_header(&backend, 1, block0, Vec::new(), H256::from([1; 32])); + let b2 = insert_header(&backend, 2, b1, Vec::new(), Default::default()); + + { + let lca = lowest_common_ancestor(blockchain, a3, b2).unwrap(); + + assert_eq!(lca.hash, block0); + assert_eq!(lca.number, 0); + } + + { + let lca = lowest_common_ancestor(blockchain, a1, a3).unwrap(); + + assert_eq!(lca.hash, a1); + assert_eq!(lca.number, 1); + } + + { + let lca = lowest_common_ancestor(blockchain, a3, a1).unwrap(); + + assert_eq!(lca.hash, a1); + assert_eq!(lca.number, 1); + } + + { + let lca = lowest_common_ancestor(blockchain, a2, a3).unwrap(); + + assert_eq!(lca.hash, a2); + assert_eq!(lca.number, 2); + } + + { + let lca = lowest_common_ancestor(blockchain, a2, a1).unwrap(); + + assert_eq!(lca.hash, a1); + assert_eq!(lca.number, 1); + } + + { + let lca = lowest_common_ancestor(blockchain, a2, a2).unwrap(); + + assert_eq!(lca.hash, a2); + assert_eq!(lca.number, 2); + } + } + #[test] fn test_leaves_with_complex_block_tree() { let backend: Arc> = Arc::new(Backend::new_test(20, 20)); diff --git a/core/client/db/src/light.rs b/core/client/db/src/light.rs index 3e60e9e7a1c41a9f492fbd9ec2fcaa31aa352e28..19fc7fde35f3372855dd1a56e28ed47d7615478f 100644 --- a/core/client/db/src/light.rs +++ b/core/client/db/src/light.rs @@ -23,8 +23,11 @@ use parking_lot::RwLock; use kvdb::{KeyValueDB, DBTransaction}; use client::backend::{AuxStore, NewBlockState}; -use client::blockchain::{BlockStatus, Cache as BlockchainCache, - HeaderBackend as BlockchainHeaderBackend, Info as BlockchainInfo}; +use client::blockchain::{ + BlockStatus, Cache as BlockchainCache, + HeaderBackend as BlockchainHeaderBackend, Info as BlockchainInfo, + well_known_cache_keys, +}; use client::cht; use client::error::{Error as ClientError, Result as ClientResult}; use client::light::blockchain::Storage as LightBlockchainStorage; @@ -32,7 +35,7 @@ use codec::{Decode, Encode}; use primitives::Blake2Hasher; use sr_primitives::generic::{DigestItem, BlockId}; use sr_primitives::traits::{Block as BlockT, Header as HeaderT, Zero, One, NumberFor}; -use consensus_common::well_known_cache_keys; +use header_metadata::{CachedHeaderMetadata, HeaderMetadata, HeaderMetadataCache}; use crate::cache::{DbCacheSync, DbCache, ComplexBlockId, EntryType as CacheEntryType}; use crate::utils::{self, meta_keys, Meta, db_err, read_db, block_id_to_lookup_key, read_meta}; use crate::DatabaseSettings; @@ -58,6 +61,7 @@ pub struct LightStorage { db: Arc, meta: RwLock, Block::Hash>>, cache: Arc>, + header_metadata_cache: HeaderMetadataCache, } impl LightStorage @@ -107,6 +111,7 @@ impl LightStorage db, meta: RwLock::new(meta), cache: Arc::new(DbCacheSync(RwLock::new(cache))), + header_metadata_cache: HeaderMetadataCache::default(), }) } @@ -190,6 +195,31 @@ impl BlockchainHeaderBackend for LightStorage } } +impl HeaderMetadata for LightStorage { + type Error = ClientError; + + fn header_metadata(&self, hash: Block::Hash) -> Result, Self::Error> { + self.header_metadata_cache.header_metadata(hash).or_else(|_| { + self.header(BlockId::hash(hash))?.map(|header| { + let header_metadata = CachedHeaderMetadata::from(&header); + self.header_metadata_cache.insert_header_metadata( + header_metadata.hash, + header_metadata.clone(), + ); + header_metadata + }).ok_or(ClientError::UnknownBlock(format!("header not found in db: {}", hash))) + }) + } + + fn insert_header_metadata(&self, hash: Block::Hash, metadata: CachedHeaderMetadata) { + self.header_metadata_cache.insert_header_metadata(hash, metadata) + } + + fn remove_header_metadata(&self, hash: Block::Hash) { + self.header_metadata_cache.remove_header_metadata(hash); + } +} + impl LightStorage { // Get block changes trie root, if available. fn changes_trie_root(&self, block: BlockId) -> ClientResult> { @@ -206,17 +236,18 @@ impl LightStorage { /// In the case where the new best block is a block to be imported, `route_to` /// should be the parent of `best_to`. In the case where we set an existing block /// to be best, `route_to` should equal to `best_to`. - fn set_head_with_transaction(&self, transaction: &mut DBTransaction, route_to: Block::Hash, best_to: (NumberFor, Block::Hash)) -> Result<(), client::error::Error> { + fn set_head_with_transaction( + &self, + transaction: &mut DBTransaction, + route_to: Block::Hash, + best_to: (NumberFor, Block::Hash), + ) -> ClientResult<()> { let lookup_key = utils::number_and_hash_to_lookup_key(best_to.0, &best_to.1)?; // handle reorg. let meta = self.meta.read(); if meta.best_hash != Default::default() { - let tree_route = ::client::blockchain::tree_route( - self, - BlockId::Hash(meta.best_hash), - BlockId::Hash(route_to), - )?; + let tree_route = header_metadata::tree_route(self, meta.best_hash, route_to)?; // update block number to hash lookup entries. for retracted in tree_route.retracted() { @@ -416,6 +447,12 @@ impl LightBlockchainStorage for LightStorage )?; transaction.put(columns::HEADER, &lookup_key, &header.encode()); + let header_metadata = CachedHeaderMetadata::from(&header); + self.header_metadata_cache.insert_header_metadata( + header.hash().clone(), + header_metadata, + ); + let is_genesis = number.is_zero(); if is_genesis { self.cache.0.write().set_genesis_hash(hash); @@ -535,6 +572,7 @@ pub(crate) mod tests { use client::cht; use sr_primitives::generic::DigestItem; use sr_primitives::testing::{H256 as Hash, Header, Block as RawBlock, ExtrinsicWrapper}; + use header_metadata::{lowest_common_ancestor, tree_route}; use super::*; type Block = RawBlock>; @@ -562,10 +600,10 @@ pub(crate) mod tests { header } - pub fn insert_block Header>( + pub fn insert_block Header>( db: &LightStorage, cache: HashMap>, - header: F, + mut header: F, ) -> Hash { let header = header(); let hash = header.hash(); @@ -779,11 +817,7 @@ pub(crate) mod tests { let b2 = insert_block(&db, HashMap::new(), || default_header(&b1, 2)); { - let tree_route = ::client::blockchain::tree_route( - &db, - BlockId::Hash(a3), - BlockId::Hash(b2) - ).unwrap(); + let tree_route = tree_route(&db, a3, b2).unwrap(); assert_eq!(tree_route.common_block().hash, block0); assert_eq!(tree_route.retracted().iter().map(|r| r.hash).collect::>(), vec![a3, a2, a1]); @@ -791,11 +825,7 @@ pub(crate) mod tests { } { - let tree_route = ::client::blockchain::tree_route( - &db, - BlockId::Hash(a1), - BlockId::Hash(a3), - ).unwrap(); + let tree_route = tree_route(&db, a1, a3).unwrap(); assert_eq!(tree_route.common_block().hash, a1); assert!(tree_route.retracted().is_empty()); @@ -803,11 +833,7 @@ pub(crate) mod tests { } { - let tree_route = ::client::blockchain::tree_route( - &db, - BlockId::Hash(a3), - BlockId::Hash(a1), - ).unwrap(); + let tree_route = tree_route(&db, a3, a1).unwrap(); assert_eq!(tree_route.common_block().hash, a1); assert_eq!(tree_route.retracted().iter().map(|r| r.hash).collect::>(), vec![a3, a2]); @@ -815,11 +841,7 @@ pub(crate) mod tests { } { - let tree_route = ::client::blockchain::tree_route( - &db, - BlockId::Hash(a2), - BlockId::Hash(a2), - ).unwrap(); + let tree_route = tree_route(&db, a2, a2).unwrap(); assert_eq!(tree_route.common_block().hash, a2); assert!(tree_route.retracted().is_empty()); @@ -827,6 +849,63 @@ pub(crate) mod tests { } } + #[test] + fn lowest_common_ancestor_works() { + let db = LightStorage::new_test(); + let block0 = insert_block(&db, HashMap::new(), || default_header(&Default::default(), 0)); + + // fork from genesis: 3 prong. + let a1 = insert_block(&db, HashMap::new(), || default_header(&block0, 1)); + let a2 = insert_block(&db, HashMap::new(), || default_header(&a1, 2)); + let a3 = insert_block(&db, HashMap::new(), || default_header(&a2, 3)); + + // fork from genesis: 2 prong. + let b1 = insert_block(&db, HashMap::new(), || header_with_extrinsics_root(&block0, 1, Hash::from([1; 32]))); + let b2 = insert_block(&db, HashMap::new(), || default_header(&b1, 2)); + + { + let lca = lowest_common_ancestor(&db, a3, b2).unwrap(); + + assert_eq!(lca.hash, block0); + assert_eq!(lca.number, 0); + } + + { + let lca = lowest_common_ancestor(&db, a1, a3).unwrap(); + + assert_eq!(lca.hash, a1); + assert_eq!(lca.number, 1); + } + + { + let lca = lowest_common_ancestor(&db, a3, a1).unwrap(); + + assert_eq!(lca.hash, a1); + assert_eq!(lca.number, 1); + } + + { + let lca = lowest_common_ancestor(&db, a2, a3).unwrap(); + + assert_eq!(lca.hash, a2); + assert_eq!(lca.number, 2); + } + + { + let lca = lowest_common_ancestor(&db, a2, a1).unwrap(); + + assert_eq!(lca.hash, a1); + assert_eq!(lca.number, 1); + } + + { + let lca = lowest_common_ancestor(&db, a2, a2).unwrap(); + + assert_eq!(lca.hash, a2); + assert_eq!(lca.number, 2); + } + } + #[test] fn authorities_are_cached() { let db = LightStorage::new_test(); @@ -850,7 +929,7 @@ pub(crate) mod tests { fn get_authorities(cache: &dyn BlockchainCache, at: BlockId) -> Option> { cache.get_at(&well_known_cache_keys::AUTHORITIES, &at) - .and_then(|val| Decode::decode(&mut &val[..]).ok()) + .and_then(|(_, _, val)| Decode::decode(&mut &val[..]).ok()) } let auth1 = || AuthorityId::from_raw([1u8; 32]); @@ -1030,21 +1109,40 @@ pub(crate) mod tests { #[test] fn cache_can_be_initialized_after_genesis_inserted() { - let db = LightStorage::::new_test(); + let (genesis_hash, storage) = { + let db = LightStorage::::new_test(); + + // before cache is initialized => None + assert_eq!(db.cache().get_at(b"test", &BlockId::Number(0)), None); + + // insert genesis block (no value for cache is provided) + let mut genesis_hash = None; + insert_block(&db, HashMap::new(), || { + let header = default_header(&Default::default(), 0); + genesis_hash = Some(header.hash()); + header + }); - // before cache is initialized => None - assert_eq!(db.cache().get_at(b"test", &BlockId::Number(0)), None); + // after genesis is inserted => None + assert_eq!(db.cache().get_at(b"test", &BlockId::Number(0)), None); - // insert genesis block (no value for cache is provided) - insert_block(&db, HashMap::new(), || default_header(&Default::default(), 0)); + // initialize cache + db.cache().initialize(b"test", vec![42]).unwrap(); - // after genesis is inserted => None - assert_eq!(db.cache().get_at(b"test", &BlockId::Number(0)), None); + // after genesis is inserted + cache is initialized => Some + assert_eq!( + db.cache().get_at(b"test", &BlockId::Number(0)), + Some(((0, genesis_hash.unwrap()), None, vec![42])), + ); - // initialize cache - db.cache().initialize(b"test", vec![42]).unwrap(); + (genesis_hash, db.db) + }; - // after genesis is inserted + cache is initialized => Some - assert_eq!(db.cache().get_at(b"test", &BlockId::Number(0)), Some(vec![42])); + // restart && check that after restart value is read from the cache + let db = LightStorage::::from_kvdb(storage as Arc<_>).expect("failed to create test-db"); + assert_eq!( + db.cache().get_at(b"test", &BlockId::Number(0)), + Some(((0, genesis_hash.unwrap()), None, vec![42])), + ); } } diff --git a/core/client/db/src/storage_cache.rs b/core/client/db/src/storage_cache.rs index 8b3e81212ed0a1d7c8bced455ccb054f3a411bd7..af8c9e379c4c1c99d0522e1e750e429976421ea5 100644 --- a/core/client/db/src/storage_cache.rs +++ b/core/client/db/src/storage_cache.rs @@ -285,6 +285,12 @@ pub struct CachingState, B: BlockT> { pub cache: CacheChanges } +impl, B: BlockT> std::fmt::Debug for CachingState { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!(f, "Block {:?}", self.cache.parent_hash) + } +} + impl CacheChanges { /// Propagate local cache into the shared cache and synchronize /// the shared cache with the best block state. @@ -536,6 +542,10 @@ impl, B: BlockT> StateBackend for CachingState< self.state.for_keys_with_prefix(prefix, f) } + fn for_key_values_with_prefix(&self, prefix: &[u8], f: F) { + self.state.for_key_values_with_prefix(prefix, f) + } + fn for_keys_in_child_storage(&self, storage_key: &[u8], f: F) { self.state.for_keys_in_child_storage(storage_key, f) } diff --git a/core/client/header-metadata/Cargo.toml b/core/client/header-metadata/Cargo.toml new file mode 100644 index 0000000000000000000000000000000000000000..43fcebb25bf96647aae8faa8e949c973cea89784 --- /dev/null +++ b/core/client/header-metadata/Cargo.toml @@ -0,0 +1,10 @@ +[package] +name = "substrate-header-metadata" +version = "2.0.0" +authors = ["Parity Technologies "] +edition = "2018" + +[dependencies] +lru-cache = { version = "0.1.2" } +parking_lot = { version = "0.9.0" } +sr-primitives = { path = "../../sr-primitives" } diff --git a/core/client/header-metadata/src/lib.rs b/core/client/header-metadata/src/lib.rs new file mode 100644 index 0000000000000000000000000000000000000000..cce45f264e8ea08bb543323f2bfcafd6b5c3165a --- /dev/null +++ b/core/client/header-metadata/src/lib.rs @@ -0,0 +1,281 @@ +// Copyright 2019 Parity Technologies (UK) Ltd. +// This file is part of Substrate. + +// Substrate 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. + +// Substrate 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 Substrate. If not, see . + +//! Implements tree backend, cached header metadata and algorithms +//! to compute routes efficiently over the tree of headers. + +use sr_primitives::traits::{Block as BlockT, NumberFor, Header}; +use parking_lot::RwLock; +use lru_cache::LruCache; + +/// Set to the expected max difference between `best` and `finalized` blocks at sync. +const LRU_CACHE_SIZE: usize = 5_000; + +/// Get lowest common ancestor between two blocks in the tree. +/// +/// This implementation is efficient because our trees have very few and +/// small branches, and because of our current query pattern: +/// lca(best, final), lca(best + 1, final), lca(best + 2, final), etc. +/// The first call is O(h) but the others are O(1). +pub fn lowest_common_ancestor>( + backend: &T, + id_one: Block::Hash, + id_two: Block::Hash, +) -> Result, T::Error> { + let mut header_one = backend.header_metadata(id_one)?; + let mut header_two = backend.header_metadata(id_two)?; + + let mut orig_header_one = header_one.clone(); + let mut orig_header_two = header_two.clone(); + + // We move through ancestor links as much as possible, since ancestor >= parent. + + while header_one.number > header_two.number { + let ancestor_one = backend.header_metadata(header_one.ancestor)?; + + if ancestor_one.number >= header_two.number { + header_one = ancestor_one; + } else { + break + } + } + + while header_one.number < header_two.number { + let ancestor_two = backend.header_metadata(header_two.ancestor)?; + + if ancestor_two.number >= header_one.number { + header_two = ancestor_two; + } else { + break + } + } + + // Then we move the remaining path using parent links. + + while header_one.hash != header_two.hash { + if header_one.number > header_two.number { + header_one = backend.header_metadata(header_one.parent)?; + } else { + header_two = backend.header_metadata(header_two.parent)?; + } + } + + // Update cached ancestor links. + + if orig_header_one.number > header_one.number { + orig_header_one.ancestor = header_one.hash; + backend.insert_header_metadata(orig_header_one.hash, orig_header_one); + } + + if orig_header_two.number > header_one.number { + orig_header_two.ancestor = header_one.hash; + backend.insert_header_metadata(orig_header_two.hash, orig_header_two); + } + + Ok(HashAndNumber { + hash: header_one.hash, + number: header_one.number, + }) +} + +/// Compute a tree-route between two blocks. See tree-route docs for more details. +pub fn tree_route>( + backend: &T, + from: Block::Hash, + to: Block::Hash, +) -> Result, T::Error> { + let mut from = backend.header_metadata(from)?; + let mut to = backend.header_metadata(to)?; + + let mut from_branch = Vec::new(); + let mut to_branch = Vec::new(); + + while to.number > from.number { + to_branch.push(HashAndNumber { + number: to.number, + hash: to.hash, + }); + + to = backend.header_metadata(to.parent)?; + } + + while from.number > to.number { + from_branch.push(HashAndNumber { + number: from.number, + hash: from.hash, + }); + from = backend.header_metadata(from.parent)?; + } + + // numbers are equal now. walk backwards until the block is the same + + while to != from { + to_branch.push(HashAndNumber { + number: to.number, + hash: to.hash, + }); + to = backend.header_metadata(to.parent)?; + + from_branch.push(HashAndNumber { + number: from.number, + hash: from.hash, + }); + from = backend.header_metadata(from.parent)?; + } + + // add the pivot block. and append the reversed to-branch (note that it's reverse order originals) + let pivot = from_branch.len(); + from_branch.push(HashAndNumber { + number: to.number, + hash: to.hash, + }); + from_branch.extend(to_branch.into_iter().rev()); + + Ok(TreeRoute { + route: from_branch, + pivot, + }) +} + +/// Hash and number of a block. +#[derive(Debug)] +pub struct HashAndNumber { + /// The number of the block. + pub number: NumberFor, + /// The hash of the block. + pub hash: Block::Hash, +} + +/// A tree-route from one block to another in the chain. +/// +/// All blocks prior to the pivot in the deque is the reverse-order unique ancestry +/// of the first block, the block at the pivot index is the common ancestor, +/// and all blocks after the pivot is the ancestry of the second block, in +/// order. +/// +/// The ancestry sets will include the given blocks, and thus the tree-route is +/// never empty. +/// +/// ```text +/// Tree route from R1 to E2. Retracted is [R1, R2, R3], Common is C, enacted [E1, E2] +/// <- R3 <- R2 <- R1 +/// / +/// C +/// \-> E1 -> E2 +/// ``` +/// +/// ```text +/// Tree route from C to E2. Retracted empty. Common is C, enacted [E1, E2] +/// C -> E1 -> E2 +/// ``` +#[derive(Debug)] +pub struct TreeRoute { + route: Vec>, + pivot: usize, +} + +impl TreeRoute { + /// Get a slice of all retracted blocks in reverse order (towards common ancestor) + pub fn retracted(&self) -> &[HashAndNumber] { + &self.route[..self.pivot] + } + + /// Get the common ancestor block. This might be one of the two blocks of the + /// route. + pub fn common_block(&self) -> &HashAndNumber { + self.route.get(self.pivot).expect("tree-routes are computed between blocks; \ + which are included in the route; \ + thus it is never empty; qed") + } + + /// Get a slice of enacted blocks (descendents of the common ancestor) + pub fn enacted(&self) -> &[HashAndNumber] { + &self.route[self.pivot + 1 ..] + } +} + +/// Handles header metadata: hash, number, parent hash, etc. +pub trait HeaderMetadata { + /// Error used in case the header metadata is not found. + type Error; + + fn header_metadata(&self, hash: Block::Hash) -> Result, Self::Error>; + fn insert_header_metadata(&self, hash: Block::Hash, header_metadata: CachedHeaderMetadata); + fn remove_header_metadata(&self, hash: Block::Hash); +} + +/// Caches header metadata in an in-memory LRU cache. +pub struct HeaderMetadataCache { + cache: RwLock>>, +} + +impl HeaderMetadataCache { + /// Creates a new LRU header metadata cache with `capacity`. + pub fn new(capacity: usize) -> Self { + HeaderMetadataCache { + cache: RwLock::new(LruCache::new(capacity)), + } + } +} + +impl Default for HeaderMetadataCache { + fn default() -> Self { + HeaderMetadataCache { + cache: RwLock::new(LruCache::new(LRU_CACHE_SIZE)), + } + } +} + +impl HeaderMetadata for HeaderMetadataCache { + type Error = String; + + fn header_metadata(&self, hash: Block::Hash) -> Result, Self::Error> { + self.cache.write().get_mut(&hash).cloned() + .ok_or("header metadata not found in cache".to_owned()) + } + + fn insert_header_metadata(&self, hash: Block::Hash, metadata: CachedHeaderMetadata) { + self.cache.write().insert(hash, metadata); + } + + fn remove_header_metadata(&self, hash: Block::Hash) { + self.cache.write().remove(&hash); + } +} + +/// Cached header metadata. Used to efficiently traverse the tree. +#[derive(Debug, Clone, Eq, PartialEq)] +pub struct CachedHeaderMetadata { + /// Hash of the header. + pub hash: Block::Hash, + /// Block number. + pub number: NumberFor, + /// Hash of parent header. + pub parent: Block::Hash, + /// Hash of an ancestor header. Used to jump through the tree. + ancestor: Block::Hash, +} + +impl From<&Block::Header> for CachedHeaderMetadata { + fn from(header: &Block::Header) -> Self { + CachedHeaderMetadata { + hash: header.hash().clone(), + number: header.number().clone(), + parent: header.parent_hash().clone(), + ancestor: header.parent_hash().clone(), + } + } +} diff --git a/core/client/src/backend.rs b/core/client/src/backend.rs index 24b48c9b8618c730bc026df3a16b50a3d97f6e80..9b6d9ce58fbfe9b415b91d473685b2e42f1753cc 100644 --- a/core/client/src/backend.rs +++ b/core/client/src/backend.rs @@ -16,16 +16,18 @@ //! Substrate Client data backend +use std::sync::Arc; use std::collections::HashMap; use crate::error; +use crate::light::blockchain::RemoteBlockchain; use primitives::ChangesTrieConfiguration; use sr_primitives::{generic::BlockId, Justification, StorageOverlay, ChildrenStorageOverlay}; use sr_primitives::traits::{Block as BlockT, NumberFor}; use state_machine::backend::Backend as StateBackend; -use state_machine::ChangesTrieStorage as StateChangesTrieStorage; -use consensus::well_known_cache_keys; +use state_machine::{ChangesTrieStorage as StateChangesTrieStorage, ChangesTrieTransaction}; +use crate::blockchain::well_known_cache_keys; +use consensus::BlockOrigin; use hash_db::Hasher; -use trie::MemoryDB; use parking_lot::Mutex; /// In memory array of storage values. @@ -34,6 +36,26 @@ pub type StorageCollection = Vec<(Vec, Option>)>; /// In memory arrays of storage values for multiple child tries. pub type ChildStorageCollection = Vec<(Vec, StorageCollection)>; +pub(crate) struct ImportSummary { + pub(crate) hash: Block::Hash, + pub(crate) origin: BlockOrigin, + pub(crate) header: Block::Header, + pub(crate) is_new_best: bool, + pub(crate) storage_changes: Option<(StorageCollection, ChildStorageCollection)>, + pub(crate) retracted: Vec, +} + +/// Import operation wrapper +pub struct ClientImportOperation< + Block: BlockT, + H: Hasher, + B: Backend, +> { + pub(crate) op: B::BlockImportOperation, + pub(crate) notify_imported: Option>, + pub(crate) notify_finalized: Vec, +} + /// State of a new block. #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub enum NewBlockState { @@ -95,7 +117,7 @@ pub trait BlockImportOperation where child_update: ChildStorageCollection, ) -> error::Result<()>; /// Inject changes trie data into the database. - fn update_changes_trie(&mut self, update: MemoryDB) -> error::Result<()>; + fn update_changes_trie(&mut self, update: ChangesTrieTransaction>) -> error::Result<()>; /// Insert auxiliary keys. Values are `None` if should be deleted. fn insert_aux(&mut self, ops: I) -> error::Result<()> where I: IntoIterator, Option>)>; @@ -105,6 +127,45 @@ pub trait BlockImportOperation where fn mark_head(&mut self, id: BlockId) -> error::Result<()>; } +/// Finalize Facilities +pub trait Finalizer, B: Backend> { + /// Mark all blocks up to given as finalized in operation. If a + /// justification is provided it is stored with the given finalized + /// block (any other finalized blocks are left unjustified). + /// + /// If the block being finalized is on a different fork from the current + /// best block the finalized block is set as best, this might be slightly + /// inaccurate (i.e. outdated). Usages that require determining an accurate + /// best block should use `SelectChain` instead of the client. + fn apply_finality( + &self, + operation: &mut ClientImportOperation, + id: BlockId, + justification: Option, + notify: bool, + ) -> error::Result<()>; + + + /// Finalize a block. This will implicitly finalize all blocks up to it and + /// fire finality notifications. + /// + /// If the block being finalized is on a different fork from the current + /// best block, the finalized block is set as best. This might be slightly + /// inaccurate (i.e. outdated). Usages that require determining an accurate + /// best block should use `SelectChain` instead of the client. + /// + /// Pass a flag to indicate whether finality notifications should be propagated. + /// This is usually tied to some synchronization state, where we don't send notifications + /// while performing major synchronization work. + fn finalize_block( + &self, + id: BlockId, + justification: Option, + notify: bool, + ) -> error::Result<()>; + +} + /// Provides access to an auxiliary database. pub trait AuxStore { /// Insert auxiliary data into key-value store. Deletions occur after insertions. @@ -245,4 +306,7 @@ where { /// Returns true if the state for given block is available locally. fn is_local_state_available(&self, block: &BlockId) -> bool; + /// Returns reference to blockchain backend that either resolves blockchain data + /// locally, or prepares request to fetch that data from remote node. + fn remote_blockchain(&self) -> Arc>; } diff --git a/core/client/src/block_builder/block_builder.rs b/core/client/src/block_builder/block_builder.rs index 22aac577e3342f0495877ac1f080ac9c20979122..08711469e9a1b5164721bd186f914a4389805b3f 100644 --- a/core/client/src/block_builder/block_builder.rs +++ b/core/client/src/block_builder/block_builder.rs @@ -17,7 +17,6 @@ use super::api::BlockBuilder as BlockBuilderApi; use std::vec::Vec; use codec::Encode; -use sr_primitives::ApplyOutcome; use sr_primitives::generic::BlockId; use sr_primitives::traits::{ Header as HeaderT, Hash, Block as BlockT, One, HashFor, ProvideRuntimeApi, ApiRef, DigestFor, @@ -104,7 +103,7 @@ where ExecutionContext::BlockConstruction, xt.clone() )? { - Ok(ApplyOutcome::Success) | Ok(ApplyOutcome::Fail) => { + Ok(_) => { extrinsics.push(xt); Ok(()) } @@ -129,7 +128,7 @@ where debug_assert_eq!( self.header.extrinsics_root().clone(), HashFor::::ordered_trie_root( - self.extrinsics.iter().map(Encode::encode) + self.extrinsics.iter().map(Encode::encode).collect(), ), ); diff --git a/core/client/src/blockchain.rs b/core/client/src/blockchain.rs index 2bf61df704da9de3202d5f1a72ed362c4475e72c..73b7c138d020e62238750b72fe8bf202e42ec109 100644 --- a/core/client/src/blockchain.rs +++ b/core/client/src/blockchain.rs @@ -21,7 +21,10 @@ use std::sync::Arc; use sr_primitives::traits::{Block as BlockT, Header as HeaderT, NumberFor}; use sr_primitives::generic::BlockId; use sr_primitives::Justification; -use consensus::well_known_cache_keys; +use log::warn; +use parking_lot::Mutex; + +use header_metadata::HeaderMetadata; use crate::error::{Error, Result}; @@ -73,7 +76,7 @@ pub trait HeaderBackend: Send + Sync { } /// Blockchain database backend. Does not perform any validation. -pub trait Backend: HeaderBackend { +pub trait Backend: HeaderBackend + HeaderMetadata { /// Get block body. Returns `None` if block is not found. fn body(&self, id: BlockId) -> Result::Extrinsic>>>; /// Get block justification. Returns `None` if justification does not exist. @@ -90,6 +93,123 @@ pub trait Backend: HeaderBackend { /// Return hashes of all blocks that are children of the block with `parent_hash`. fn children(&self, parent_hash: Block::Hash) -> Result>; + + /// Get the most recent block hash of the best (longest) chains + /// that contain block with the given `target_hash`. + /// + /// The search space is always limited to blocks which are in the finalized + /// chain or descendents of it. + /// + /// If `maybe_max_block_number` is `Some(max_block_number)` + /// the search is limited to block `numbers <= max_block_number`. + /// in other words as if there were no blocks greater `max_block_number`. + /// Returns `Ok(None)` if `target_hash` is not found in search space. + /// TODO: document time complexity of this, see [#1444](https://github.com/paritytech/substrate/issues/1444) + fn best_containing( + &self, + target_hash: Block::Hash, + maybe_max_number: Option>, + import_lock: &Mutex<()>, + ) -> Result> { + let target_header = { + match self.header(BlockId::Hash(target_hash))? { + Some(x) => x, + // target not in blockchain + None => { return Ok(None); }, + } + }; + + if let Some(max_number) = maybe_max_number { + // target outside search range + if target_header.number() > &max_number { + return Ok(None); + } + } + + let leaves = { + // ensure no blocks are imported during this code block. + // an import could trigger a reorg which could change the canonical chain. + // we depend on the canonical chain staying the same during this code block. + let _import_guard = import_lock.lock(); + + let info = self.info(); + + // this can be `None` if the best chain is shorter than the target header. + let maybe_canon_hash = self.hash(*target_header.number())?; + + if maybe_canon_hash.as_ref() == Some(&target_hash) { + // if a `max_number` is given we try to fetch the block at the + // given depth, if it doesn't exist or `max_number` is not + // provided, we continue to search from all leaves below. + if let Some(max_number) = maybe_max_number { + if let Some(header) = self.hash(max_number)? { + return Ok(Some(header)); + } + } + } else if info.finalized_number >= *target_header.number() { + // header is on a dead fork. + return Ok(None); + } + + self.leaves()? + }; + + // for each chain. longest chain first. shortest last + for leaf_hash in leaves { + // start at the leaf + let mut current_hash = leaf_hash; + + // if search is not restricted then the leaf is the best + let mut best_hash = leaf_hash; + + // go backwards entering the search space + // waiting until we are <= max_number + if let Some(max_number) = maybe_max_number { + loop { + let current_header = self.header(BlockId::Hash(current_hash.clone()))? + .ok_or_else(|| Error::from(format!("failed to get header for hash {}", current_hash)))?; + + if current_header.number() <= &max_number { + best_hash = current_header.hash(); + break; + } + + current_hash = *current_header.parent_hash(); + } + } + + // go backwards through the chain (via parent links) + loop { + // until we find target + if current_hash == target_hash { + return Ok(Some(best_hash)); + } + + let current_header = self.header(BlockId::Hash(current_hash.clone()))? + .ok_or_else(|| Error::from(format!("failed to get header for hash {}", current_hash)))?; + + // stop search in this chain once we go below the target's block number + if current_header.number() < target_header.number() { + break; + } + + current_hash = *current_header.parent_hash(); + } + } + + // header may be on a dead fork -- the only leaves that are considered are + // those which can still be finalized. + // + // FIXME #1558 only issue this warning when not on a dead fork + warn!( + "Block {:?} exists in chain but not found when following all \ + leaves backwards. Number limit = {:?}", + target_hash, + maybe_max_number, + ); + + Ok(None) + } } /// Provides access to the optional cache. @@ -106,7 +226,13 @@ pub trait Cache: Send + Sync { /// Otherwise cache may end up in inconsistent state. fn initialize(&self, key: &well_known_cache_keys::Id, value_at_genesis: Vec) -> Result<()>; /// Returns cached value by the given key. - fn get_at(&self, key: &well_known_cache_keys::Id, block: &BlockId) -> Option>; + /// + /// Returned tuple is the range where value has been active and the value itself. + fn get_at( + &self, + key: &well_known_cache_keys::Id, + block: &BlockId, + ) -> Option<((NumberFor, Block::Hash), Option<(NumberFor, Block::Hash)>, Vec)>; } /// Blockchain info @@ -133,128 +259,17 @@ pub enum BlockStatus { Unknown, } -/// An entry in a tree route. -#[derive(Debug)] -pub struct RouteEntry { - /// The number of the block. - pub number: ::Number, - /// The hash of the block. - pub hash: Block::Hash, -} - -/// A tree-route from one block to another in the chain. -/// -/// All blocks prior to the pivot in the deque is the reverse-order unique ancestry -/// of the first block, the block at the pivot index is the common ancestor, -/// and all blocks after the pivot is the ancestry of the second block, in -/// order. -/// -/// The ancestry sets will include the given blocks, and thus the tree-route is -/// never empty. -/// -/// ```text -/// Tree route from R1 to E2. Retracted is [R1, R2, R3], Common is C, enacted [E1, E2] -/// <- R3 <- R2 <- R1 -/// / -/// C -/// \-> E1 -> E2 -/// ``` -/// -/// ```text -/// Tree route from C to E2. Retracted empty. Common is C, enacted [E1, E2] -/// C -> E1 -> E2 -/// ``` -#[derive(Debug)] -pub struct TreeRoute { - route: Vec>, - pivot: usize, -} +/// A list of all well known keys in the blockchain cache. +pub mod well_known_cache_keys { + /// The type representing cache keys. + pub type Id = consensus::import_queue::CacheKeyId; -impl TreeRoute { - /// Get a slice of all retracted blocks in reverse order (towards common ancestor) - pub fn retracted(&self) -> &[RouteEntry] { - &self.route[..self.pivot] - } + /// A list of authorities. + pub const AUTHORITIES: Id = *b"auth"; - /// Get the common ancestor block. This might be one of the two blocks of the - /// route. - pub fn common_block(&self) -> &RouteEntry { - self.route.get(self.pivot).expect("tree-routes are computed between blocks; \ - which are included in the route; \ - thus it is never empty; qed") - } - - /// Get a slice of enacted blocks (descendents of the common ancestor) - pub fn enacted(&self) -> &[RouteEntry] { - &self.route[self.pivot + 1 ..] - } -} - -/// Compute a tree-route between two blocks. See tree-route docs for more details. -pub fn tree_route>( - backend: &Backend, - from: BlockId, - to: BlockId, -) -> Result> { - use sr_primitives::traits::Header; - - let load_header = |id: BlockId| { - match backend.header(id) { - Ok(Some(hdr)) => Ok(hdr), - Ok(None) => Err(Error::UnknownBlock(format!("Unknown block {:?}", id))), - Err(e) => Err(e), - } - }; - - let mut from = load_header(from)?; - let mut to = load_header(to)?; - - let mut from_branch = Vec::new(); - let mut to_branch = Vec::new(); - - while to.number() > from.number() { - to_branch.push(RouteEntry { - number: to.number().clone(), - hash: to.hash(), - }); - - to = load_header(BlockId::Hash(*to.parent_hash()))?; - } - - while from.number() > to.number() { - from_branch.push(RouteEntry { - number: from.number().clone(), - hash: from.hash(), - }); - from = load_header(BlockId::Hash(*from.parent_hash()))?; - } - - // numbers are equal now. walk backwards until the block is the same - - while to != from { - to_branch.push(RouteEntry { - number: to.number().clone(), - hash: to.hash(), - }); - to = load_header(BlockId::Hash(*to.parent_hash()))?; - - from_branch.push(RouteEntry { - number: from.number().clone(), - hash: from.hash(), - }); - from = load_header(BlockId::Hash(*from.parent_hash()))?; - } + /// Current Epoch data. + pub const EPOCH: Id = *b"epch"; - // add the pivot block. and append the reversed to-branch (note that it's reverse order originalls) - let pivot = from_branch.len(); - from_branch.push(RouteEntry { - number: to.number().clone(), - hash: to.hash(), - }); - from_branch.extend(to_branch.into_iter().rev()); - - Ok(TreeRoute { - route: from_branch, - pivot, - }) + /// Changes trie configuration. + pub const CHANGES_TRIE_CONFIG: Id = *b"chtr"; } diff --git a/core/client/src/call_executor.rs b/core/client/src/call_executor.rs index e82bd9a22c91e5d9f2c8f1b53b84d054f92f7ccb..ebb882709d8a686cbbd0fdf271a8da2f204bfcaa 100644 --- a/core/client/src/call_executor.rs +++ b/core/client/src/call_executor.rs @@ -17,16 +17,18 @@ use std::{sync::Arc, cmp::Ord, panic::UnwindSafe, result, cell::RefCell, rc::Rc}; use codec::{Encode, Decode}; use sr_primitives::{ - generic::BlockId, traits::Block as BlockT, + generic::BlockId, traits::Block as BlockT, traits::NumberFor, }; use state_machine::{ - self, OverlayedChanges, Ext, CodeExecutor, ExecutionManager, - ExecutionStrategy, NeverOffchainExt, backend::Backend as _, + self, OverlayedChanges, Ext, ExecutionManager, StateMachine, ExecutionStrategy, + backend::Backend as _, ChangesTrieTransaction, }; use executor::{RuntimeVersion, RuntimeInfo, NativeVersion}; use hash_db::Hasher; -use trie::MemoryDB; -use primitives::{offchain, H256, Blake2Hasher, NativeOrEncoded, NeverNativeValue}; +use primitives::{ + offchain::{self, NeverOffchainExt}, H256, Blake2Hasher, NativeOrEncoded, NeverNativeValue, + traits::CodeExecutor, +}; use crate::runtime_api::{ProofRecorder, InitializeBlock}; use crate::backend; @@ -70,7 +72,7 @@ where Result, Self::Error> ) -> Result, Self::Error>, R: Encode + Decode + PartialEq, - NC: FnOnce() -> result::Result + UnwindSafe, + NC: FnOnce() -> result::Result + UnwindSafe, >( &self, initialize_block_fn: IB, @@ -102,7 +104,7 @@ where Result, Self::Error> ) -> Result, Self::Error>, R: Encode + Decode + PartialEq, - NC: FnOnce() -> result::Result + UnwindSafe, + NC: FnOnce() -> result::Result + UnwindSafe, >(&self, state: &S, overlay: &mut OverlayedChanges, @@ -111,7 +113,14 @@ where manager: ExecutionManager, native_call: Option, side_effects_handler: Option<&mut O>, - ) -> Result<(NativeOrEncoded, (S::Transaction, H::Out), Option>), error::Error>; + ) -> Result< + ( + NativeOrEncoded, + (S::Transaction, H::Out), + Option>> + ), + error::Error, + >; /// Execute a call to a contract on top of given state, gathering execution proof. /// @@ -197,7 +206,7 @@ where ) -> error::Result> { let mut changes = OverlayedChanges::default(); let state = self.backend.state_at(*id)?; - let return_data = state_machine::new( + let return_data = StateMachine::new( &state, self.backend.changes_trie_storage(), side_effects_handler, @@ -225,7 +234,7 @@ where Result, Self::Error> ) -> Result, Self::Error>, R: Encode + Decode + PartialEq, - NC: FnOnce() -> result::Result + UnwindSafe, + NC: FnOnce() -> result::Result + UnwindSafe, >( &self, initialize_block_fn: IB, @@ -270,7 +279,7 @@ where recorder.clone() ); - state_machine::new( + StateMachine::new( &backend, self.backend.changes_trie_storage(), side_effects_handler, @@ -288,7 +297,7 @@ where .map(|(result, _, _)| result) .map_err(Into::into) } - None => state_machine::new( + None => StateMachine::new( &state, self.backend.changes_trie_storage(), side_effects_handler, @@ -333,7 +342,7 @@ where Result, Self::Error> ) -> Result, Self::Error>, R: Encode + Decode + PartialEq, - NC: FnOnce() -> result::Result + UnwindSafe, + NC: FnOnce() -> result::Result + UnwindSafe, >(&self, state: &S, changes: &mut OverlayedChanges, @@ -345,9 +354,9 @@ where ) -> error::Result<( NativeOrEncoded, (S::Transaction, ::Out), - Option>, + Option>>, )> { - state_machine::new( + StateMachine::new( state, self.backend.changes_trie_storage(), side_effects_handler, diff --git a/core/client/src/cht.rs b/core/client/src/cht.rs index 37462851a96781957a40dcd7599b2c9e312766ff..63a5b39c26904d8cd783fe0581fb8b0b4ef8036f 100644 --- a/core/client/src/cht.rs +++ b/core/client/src/cht.rs @@ -23,8 +23,6 @@ //! root has. A correct proof implies that the claimed block is identical to the one //! we discarded. -use std::collections::HashSet; - use hash_db; use codec::Encode; use trie; @@ -105,15 +103,10 @@ pub fn build_proof( let mut storage = InMemoryState::::default().update(transaction); let trie_storage = storage.as_trie_backend() .expect("InMemoryState::as_trie_backend always returns Some; qed"); - let mut total_proof = HashSet::new(); - for block in blocks.into_iter() { - debug_assert_eq!(block_to_cht_number(cht_size, block), Some(cht_num)); - - let (value, proof) = prove_read_on_trie_backend(trie_storage, &encode_cht_key(block))?; - assert!(value.is_some(), "we have just built trie that includes the value for block"); - total_proof.extend(proof); - } - Ok(total_proof.into_iter().collect()) + prove_read_on_trie_backend( + trie_storage, + blocks.into_iter().map(|number| encode_cht_key(number)), + ).map_err(ClientError::Execution) } /// Check CHT-based header proof. @@ -128,9 +121,21 @@ pub fn check_proof( Hasher: hash_db::Hasher, Hasher::Out: Ord, { - do_check_proof::(local_root, local_number, remote_hash, move |local_root, local_cht_key| - read_proof_check::(local_root, remote_proof, - local_cht_key).map_err(|e| ClientError::from(e))) + do_check_proof::( + local_root, + local_number, + remote_hash, + move |local_root, local_cht_key| + read_proof_check::( + local_root, + remote_proof, + ::std::iter::once(local_cht_key), + ) + .map(|mut map| map + .remove(local_cht_key) + .expect("checked proof of local_cht_key; qed")) + .map_err(|e| ClientError::from(e)), + ) } /// Check CHT-based header proof on pre-created proving backend. @@ -145,9 +150,16 @@ pub fn check_proof_on_proving_backend( Hasher: hash_db::Hasher, Hasher::Out: Ord, { - do_check_proof::(local_root, local_number, remote_hash, |_, local_cht_key| - read_proof_check_on_proving_backend::( - proving_backend, local_cht_key).map_err(|e| ClientError::from(e))) + do_check_proof::( + local_root, + local_number, + remote_hash, + |_, local_cht_key| + read_proof_check_on_proving_backend::( + proving_backend, + local_cht_key, + ).map_err(|e| ClientError::from(e)), + ) } /// Check CHT-based header proof using passed checker function. diff --git a/core/client/src/client.rs b/core/client/src/client.rs index 0360c532d278c9c5c8c1d1f1c43160cea6d3ec43..aff099233a41e05da7441bd55517bb1ab31bedc6 100644 --- a/core/client/src/client.rs +++ b/core/client/src/client.rs @@ -21,14 +21,14 @@ use std::{ panic::UnwindSafe, result, cell::RefCell, rc::Rc, }; use log::{info, trace, warn}; -use futures::channel::mpsc; +use futures03::channel::mpsc; use parking_lot::{Mutex, RwLock}; use codec::{Encode, Decode}; use hash_db::{Hasher, Prefix}; use primitives::{ - Blake2Hasher, H256, ChangesTrieConfiguration, convert_hash, - NeverNativeValue, ExecutionContext, - storage::{StorageKey, StorageData, well_known_keys}, NativeOrEncoded + Blake2Hasher, H256, ChangesTrieConfiguration, convert_hash, NeverNativeValue, ExecutionContext, + NativeOrEncoded, storage::{StorageKey, StorageData, well_known_keys}, + offchain::{NeverOffchainExt, self}, traits::CodeExecutor, }; use substrate_telemetry::{telemetry, SUBSTRATE_INFO}; use sr_primitives::{ @@ -40,18 +40,18 @@ use sr_primitives::{ }, }; use state_machine::{ - DBValue, Backend as StateBackend, CodeExecutor, ChangesTrieAnchorBlockId, - ExecutionStrategy, ExecutionManager, prove_read, prove_child_read, - ChangesTrieRootsStorage, ChangesTrieStorage, - key_changes, key_changes_proof, OverlayedChanges, NeverOffchainExt, + DBValue, Backend as StateBackend, ChangesTrieAnchorBlockId, ExecutionStrategy, ExecutionManager, + prove_read, prove_child_read, ChangesTrieRootsStorage, ChangesTrieStorage, + ChangesTrieTransaction, ChangesTrieConfigurationRange, key_changes, key_changes_proof, + OverlayedChanges, BackendTrustLevel, }; use executor::{RuntimeVersion, RuntimeInfo}; use consensus::{ - Error as ConsensusError, BlockImportParams, + Error as ConsensusError, BlockStatus, BlockImportParams, BlockCheckParams, ImportResult, BlockOrigin, ForkChoiceStrategy, - well_known_cache_keys::Id as CacheKeyId, SelectChain, self, }; +use header_metadata::{HeaderMetadata, CachedHeaderMetadata}; use crate::{ runtime_api::{ @@ -60,11 +60,12 @@ use crate::{ }, backend::{ self, BlockImportOperation, PrunableStateChangesTrieStorage, - StorageCollection, ChildStorageCollection + ClientImportOperation, Finalizer, ImportSummary, }, blockchain::{ self, Info as ChainInfo, Backend as ChainBackend, HeaderBackend as ChainHeaderBackend, ProvideCache, Cache, + well_known_cache_keys::Id as CacheKeyId, }, call_executor::{CallExecutor, LocalCallExecutor}, notifications::{StorageNotifications, StorageEventStream}, @@ -85,7 +86,12 @@ type StorageUpdate = < >::BlockImportOperation as BlockImportOperation >::State as state_machine::Backend>::Transaction; -type ChangesUpdate = trie::MemoryDB; +type ChangesUpdate = ChangesTrieTransaction>; + +/// Expected hashes of blocks at given heights. +/// +/// This may be used as chain spec extension to filter out known, unwanted forks. +pub type ForkBlocks = Option, ::Hash>>; /// Execution strategies settings. #[derive(Debug, Clone)] @@ -123,25 +129,11 @@ pub struct Client where Block: BlockT { finality_notification_sinks: Mutex>>>, // holds the block hash currently being imported. TODO: replace this with block queue importing_block: RwLock>, + fork_blocks: ForkBlocks, execution_strategies: ExecutionStrategies, _phantom: PhantomData, } -/// Client import operation, a wrapper for the backend. -pub struct ClientImportOperation, B: backend::Backend> { - op: B::BlockImportOperation, - notify_imported: Option<( - Block::Hash, - BlockOrigin, - Block::Header, - bool, - Option<( - StorageCollection, - ChildStorageCollection, - )>)>, - notify_finalized: Vec, -} - /// A source of blockchain events. pub trait BlockchainEvents { /// Get block import event stream. Not guaranteed to be fired for every @@ -182,21 +174,8 @@ pub trait ProvideUncles { pub struct ClientInfo { /// Best block hash. pub chain: ChainInfo, -} - -/// Block status. -#[derive(Debug, PartialEq, Eq)] -pub enum BlockStatus { - /// Added to the import queue. - Queued, - /// Already in the blockchain and the state is available. - InChainWithState, - /// In the blockchain, but the state is not available. - InChainPruned, - /// Block or parent is known to be bad. - KnownBad, - /// Not in the queue or the blockchain. - Unknown, + /// State Cache Size currently used by the backend + pub used_state_cache_size: Option, } /// Summary of an imported block @@ -210,6 +189,8 @@ pub struct BlockImportNotification { pub header: Block::Header, /// Is this the new best block. pub is_new_best: bool, + /// List of retracted blocks ordered by block number. + pub retracted: Vec, } /// Summary of a finalized block. @@ -289,7 +270,7 @@ pub fn new_with_backend( B: backend::LocalBackend { let call_executor = LocalCallExecutor::new(backend.clone(), executor, keystore); - Client::new(backend, call_executor, build_genesis_storage, Default::default()) + Client::new(backend, call_executor, build_genesis_storage, Default::default(), Default::default()) } /// Figure out the block type for a given type (for now, just a `Client`). @@ -316,6 +297,7 @@ impl Client where backend: Arc, executor: E, build_genesis_storage: S, + fork_blocks: ForkBlocks, execution_strategies: ExecutionStrategies ) -> error::Result { if backend.blockchain().header(BlockId::Number(Zero::zero()))?.is_none() { @@ -344,6 +326,7 @@ impl Client where import_notification_sinks: Default::default(), finality_notification_sinks: Default::default(), importing_block: Default::default(), + fork_blocks, execution_strategies, _phantom: Default::default(), }) @@ -447,24 +430,28 @@ impl Client where } /// Reads storage value at a given block + key, returning read proof. - pub fn read_proof(&self, id: &BlockId, key: &[u8]) -> error::Result>> { + pub fn read_proof(&self, id: &BlockId, keys: I) -> error::Result>> where + I: IntoIterator, + I::Item: AsRef<[u8]>, + { self.state_at(id) - .and_then(|state| prove_read(state, key) - .map(|(_, proof)| proof) + .and_then(|state| prove_read(state, keys) .map_err(Into::into)) } /// Reads child storage value at a given block + storage_key + key, returning /// read proof. - pub fn read_child_proof( + pub fn read_child_proof( &self, id: &BlockId, storage_key: &[u8], - key: &[u8] - ) -> error::Result>> { + keys: I, + ) -> error::Result>> where + I: IntoIterator, + I::Item: AsRef<[u8]>, + { self.state_at(id) - .and_then(|state| prove_child_read(state, storage_key, key) - .map(|(_, proof)| proof) + .and_then(|state| prove_child_read(state, storage_key, keys) .map_err(Into::into)) } @@ -547,14 +534,22 @@ impl Client where &self, first: NumberFor, last: BlockId, + storage_key: Option<&StorageKey>, key: &StorageKey ) -> error::Result, u32)>> { let (config, storage) = self.require_changes_trie()?; let last_number = self.backend.blockchain().expect_block_number_from_id(&last)?; let last_hash = self.backend.blockchain().expect_block_hash_from_id(&last)?; - key_changes::<_, Blake2Hasher, _>( - &config, + // FIXME: remove this in https://github.com/paritytech/substrate/pull/3201 + let config_range = ChangesTrieConfigurationRange { + config: &config, + zero: Zero::zero(), + end: None, + }; + + key_changes::( + config_range, &*storage, first, &ChangesTrieAnchorBlockId { @@ -562,6 +557,7 @@ impl Client where number: last_number, }, self.backend.blockchain().info().best_number, + storage_key.as_ref().map(|sk| sk.0.as_slice()), &key.0) .and_then(|r| r.map(|r| r.map(|(block, tx)| (block, tx))).collect::>()) .map_err(|err| error::Error::ChangesTrieAccessFailed(err)) @@ -579,13 +575,15 @@ impl Client where last: Block::Hash, min: Block::Hash, max: Block::Hash, - key: &StorageKey + storage_key: Option<&StorageKey>, + key: &StorageKey, ) -> error::Result> { self.key_changes_proof_with_cht_size( first, last, min, max, + storage_key, key, cht::size(), ) @@ -598,6 +596,7 @@ impl Client where last: Block::Hash, min: Block::Hash, max: Block::Hash, + storage_key: Option<&StorageKey>, key: &StorageKey, cht_size: NumberFor, ) -> error::Result> { @@ -631,6 +630,18 @@ impl Client where } impl<'a, Block: BlockT> ChangesTrieStorage> for AccessedRootsRecorder<'a, Block> { + fn as_roots_storage(&self) -> &dyn state_machine::ChangesTrieRootsStorage> { + self + } + + fn with_cached_changed_keys( + &self, + root: &H256, + functor: &mut dyn FnMut(&HashMap>, HashSet>>), + ) -> bool { + self.storage.with_cached_changed_keys(root, functor) + } + fn get(&self, key: &H256, prefix: Prefix) -> Result, String> { self.storage.get(key, prefix) } @@ -650,13 +661,20 @@ impl Client where self.backend.blockchain().expect_block_number_from_id(&BlockId::Hash(max))?, ); + // FIXME: remove this in https://github.com/paritytech/substrate/pull/3201 + let config_range = ChangesTrieConfigurationRange { + config: &config, + zero: Zero::zero(), + end: None, + }; + // fetch key changes proof let first_number = self.backend.blockchain() .expect_block_number_from_id(&BlockId::Hash(first))?; let last_number = self.backend.blockchain() .expect_block_number_from_id(&BlockId::Hash(last))?; - let key_changes_proof = key_changes_proof::<_, Blake2Hasher, _>( - &config, + let key_changes_proof = key_changes_proof::( + config_range, &recording_storage, first_number, &ChangesTrieAnchorBlockId { @@ -664,7 +682,8 @@ impl Client where number: last_number, }, max_number, - &key.0 + storage_key.as_ref().map(|sk| sk.0.as_slice()), + &key.0, ) .map_err(|err| error::Error::from(error::Error::ChangesTrieAccessFailed(err)))?; @@ -809,28 +828,9 @@ impl Client where result } - /// Set a block as best block. - pub fn set_head( - &self, - id: BlockId - ) -> error::Result<()> { - self.lock_import_and_run(|operation| { - self.apply_head(operation, id) - }) - } - - /// Set a block as best block, and apply it to an operation. - pub fn apply_head( - &self, - operation: &mut ClientImportOperation, - id: BlockId, - ) -> error::Result<()> { - operation.op.mark_head(id) - } - /// Apply a checked and validated block to an operation. If a justification is provided /// then `finalized` *must* be true. - pub fn apply_block( + fn apply_block( &self, operation: &mut ClientImportOperation, import_block: BlockImportParams, @@ -886,11 +886,15 @@ impl Client where fork_choice, ); - telemetry!(SUBSTRATE_INFO; "block.import"; - "height" => height, - "best" => ?hash, - "origin" => ?origin - ); + if let Ok(ImportResult::Imported(ref aux)) = result { + if aux.is_new_best { + telemetry!(SUBSTRATE_INFO; "block.import"; + "height" => height, + "best" => ?hash, + "origin" => ?origin + ); + } + } result } @@ -916,10 +920,13 @@ impl Client where blockchain::BlockStatus::Unknown => {}, } - let (last_best, last_best_number) = { - let info = self.backend.blockchain().info(); - (info.best_hash, info.best_number) - }; + let info = self.backend.blockchain().info(); + + // the block is lower than our last finalized block so it must revert + // finality, refusing import. + if *import_headers.post().number() <= info.finalized_number { + return Err(error::Error::NotInFinalizedChain); + } // this is a fairly arbitrary choice of where to draw the line on making notifications, // but the general goal is to only make notifications when we are already fully synced @@ -934,16 +941,23 @@ impl Client where // ensure parent block is finalized to maintain invariant that // finality is called sequentially. if finalized { - self.apply_finality_with_block_hash(operation, parent_hash, None, last_best, make_notifications)?; + self.apply_finality_with_block_hash(operation, parent_hash, None, info.best_hash, make_notifications)?; } // FIXME #1232: correct path logic for when to execute this function - let (storage_update,changes_update,storage_changes) = self.block_execution(&operation.op, &import_headers, origin, hash, body.clone())?; + let (storage_update, changes_update, storage_changes) = self.block_execution( + &operation.op, + &import_headers, + origin, + hash, + body.clone(), + )?; let is_new_best = finalized || match fork_choice { - ForkChoiceStrategy::LongestChain => import_headers.post().number() > &last_best_number, + ForkChoiceStrategy::LongestChain => import_headers.post().number() > &info.best_number, ForkChoiceStrategy::Custom(v) => v, }; + let leaf_state = if finalized { crate::backend::NewBlockState::Final } else if is_new_best { @@ -952,6 +966,17 @@ impl Client where crate::backend::NewBlockState::Normal }; + let retracted = if is_new_best { + let route_from_best = header_metadata::tree_route( + self.backend.blockchain(), + info.best_hash, + parent_hash, + )?; + route_from_best.retracted().iter().rev().map(|e| e.hash.clone()).collect() + } else { + Vec::default() + }; + trace!("Imported {}, (#{}), best={}, origin={:?}", hash, import_headers.post().number(), is_new_best, origin); operation.op.set_block_data( @@ -979,10 +1004,17 @@ impl Client where operation.notify_finalized.push(hash); } - operation.notify_imported = Some((hash, origin, import_headers.into_post(), is_new_best, storage_changes)); + operation.notify_imported = Some(ImportSummary { + hash, + origin, + header: import_headers.into_post(), + is_new_best, + storage_changes, + retracted, + }) } - Ok(ImportResult::imported()) + Ok(ImportResult::imported(is_new_best)) } fn block_execution( @@ -994,7 +1026,7 @@ impl Client where body: Option>, ) -> error::Result<( Option>, - Option>, + Option>>, Option<( Vec<(Vec, Option>)>, Vec<(Vec, Vec<(Vec, Option>)>)> @@ -1009,7 +1041,7 @@ impl Client where let get_execution_manager = |execution_strategy: ExecutionStrategy| { match execution_strategy { ExecutionStrategy::NativeElseWasm => ExecutionManager::NativeElseWasm, - ExecutionStrategy::AlwaysWasm => ExecutionManager::AlwaysWasm, + ExecutionStrategy::AlwaysWasm => ExecutionManager::AlwaysWasm(BackendTrustLevel::Trusted), ExecutionStrategy::NativeWhenPossible => ExecutionManager::NativeWhenPossible, ExecutionStrategy::Both => ExecutionManager::Both(|wasm_result, native_result| { let header = import_headers.post(); @@ -1069,11 +1101,7 @@ impl Client where return Ok(()); } - let route_from_finalized = crate::blockchain::tree_route( - self.backend.blockchain(), - BlockId::Hash(last_finalized), - BlockId::Hash(block), - )?; + let route_from_finalized = header_metadata::tree_route(self.backend.blockchain(), last_finalized, block)?; if let Some(retracted) = route_from_finalized.retracted().get(0) { warn!("Safety violation: attempted to revert finalized block {:?} which is not in the \ @@ -1082,11 +1110,7 @@ impl Client where return Err(error::Error::NotInFinalizedChain); } - let route_from_best = crate::blockchain::tree_route( - self.backend.blockchain(), - BlockId::Hash(best_block), - BlockId::Hash(block), - )?; + let route_from_best = header_metadata::tree_route(self.backend.blockchain(), best_block, block)?; // if the block is not a direct ancestor of the current best chain, // then some other block is the common ancestor. @@ -1149,35 +1173,23 @@ impl Client where Ok(()) } - fn notify_imported( - &self, - notify_import: ( - Block::Hash, BlockOrigin, - Block::Header, - bool, - Option<( - Vec<(Vec, Option>)>, - Vec<(Vec, Vec<(Vec, Option>)>)>, - ) - >), - ) -> error::Result<()> { - let (hash, origin, header, is_new_best, storage_changes) = notify_import; - - if let Some(storage_changes) = storage_changes { + fn notify_imported(&self, notify_import: ImportSummary) -> error::Result<()> { + if let Some(storage_changes) = notify_import.storage_changes { // TODO [ToDr] How to handle re-orgs? Should we re-emit all storage changes? self.storage_notifications.lock() .trigger( - &hash, + ¬ify_import.hash, storage_changes.0.into_iter(), storage_changes.1.into_iter().map(|(sk, v)| (sk, v.into_iter())), ); } let notification = BlockImportNotification:: { - hash, - origin, - header, - is_new_best, + hash: notify_import.hash, + origin: notify_import.origin, + header: notify_import.header, + is_new_best: notify_import.is_new_best, + retracted: notify_import.retracted, }; self.import_notification_sinks.lock() @@ -1186,68 +1198,6 @@ impl Client where Ok(()) } - /// Apply auxiliary data insertion into an operation. - pub fn apply_aux< - 'a, - 'b: 'a, - 'c: 'a, - I: IntoIterator, - D: IntoIterator, - >( - &self, - operation: &mut ClientImportOperation, - insert: I, - delete: D - ) -> error::Result<()> { - operation.op.insert_aux( - insert.into_iter() - .map(|(k, v)| (k.to_vec(), Some(v.to_vec()))) - .chain(delete.into_iter().map(|k| (k.to_vec(), None))) - ) - } - - /// Mark all blocks up to given as finalized in operation. If a - /// justification is provided it is stored with the given finalized - /// block (any other finalized blocks are left unjustified). - /// - /// If the block being finalized is on a different fork from the current - /// best block the finalized block is set as best, this might be slightly - /// innacurate (i.e. outdated), usages that require determining an accurate - /// best block should use `SelectChain` instead of the client. - pub fn apply_finality( - &self, - operation: &mut ClientImportOperation, - id: BlockId, - justification: Option, - notify: bool, - ) -> error::Result<()> { - let last_best = self.backend.blockchain().info().best_hash; - let to_finalize_hash = self.backend.blockchain().expect_block_hash_from_id(&id)?; - self.apply_finality_with_block_hash(operation, to_finalize_hash, justification, last_best, notify) - } - - /// Finalize a block. This will implicitly finalize all blocks up to it and - /// fire finality notifications. - /// - /// If the block being finalized is on a different fork from the current - /// best block the finalized block is set as best, this might be slightly - /// innacurate (i.e. outdated), usages that require determining an accurate - /// best block should use `SelectChain` instead of the client. - /// - /// Pass a flag to indicate whether finality notifications should be propagated. - /// This is usually tied to some synchronization state, where we don't send notifications - /// while performing major synchronization work. - pub fn finalize_block(&self, id: BlockId, justification: Option, notify: bool) -> error::Result<()> { - self.lock_import_and_run(|operation| { - let last_best = self.backend.blockchain().info().best_hash; - let to_finalize_hash = self.backend.blockchain().expect_block_hash_from_id(&id)?; - self.apply_finality_with_block_hash(operation, to_finalize_hash, justification, last_best, notify) - }).map_err(|e| { - warn!("Block finalization error:\n{:?}", e); - e - }) - } - /// Attempts to revert the chain by `n` blocks. Returns the number of blocks that were /// successfully reverted. pub fn revert(&self, n: NumberFor) -> error::Result> { @@ -1259,6 +1209,7 @@ impl Client where let info = self.backend.blockchain().info(); ClientInfo { chain: info, + used_state_cache_size: self.backend.used_state_cache_size(), } } @@ -1317,7 +1268,7 @@ impl Client where let load_header = |id: Block::Hash| -> error::Result { match self.backend.blockchain().header(BlockId::Hash(id))? { Some(hdr) => Ok(hdr), - None => Err(Error::UnknownBlock(format!("Unknown block {:?}", id))), + None => Err(Error::UnknownBlock(format!("{:?}", id))), } }; @@ -1363,6 +1314,26 @@ impl Client where } } +impl HeaderMetadata for Client where + B: backend::Backend, + E: CallExecutor, + Block: BlockT, +{ + type Error = error::Error; + + fn header_metadata(&self, hash: Block::Hash) -> Result, Self::Error> { + self.backend.blockchain().header_metadata(hash) + } + + fn insert_header_metadata(&self, hash: Block::Hash, metadata: CachedHeaderMetadata) { + self.backend.blockchain().insert_header_metadata(hash, metadata) + } + + fn remove_header_metadata(&self, hash: Block::Hash) { + self.backend.blockchain().remove_header_metadata(hash) + } +} + impl ProvideUncles for Client where B: backend::Backend, E: CallExecutor, @@ -1404,6 +1375,33 @@ impl ChainHeaderBackend for Client wher } } +impl ChainHeaderBackend for &Client where + B: backend::Backend, + E: CallExecutor + Send + Sync, + Block: BlockT, + RA: Send + Sync, +{ + fn header(&self, id: BlockId) -> error::Result> { + (**self).backend.blockchain().header(id) + } + + fn info(&self) -> blockchain::Info { + (**self).backend.blockchain().info() + } + + fn status(&self, id: BlockId) -> error::Result { + (**self).status(id) + } + + fn number(&self, hash: Block::Hash) -> error::Result::Header as HeaderT>::Number>> { + (**self).number(hash) + } + + fn hash(&self, number: NumberFor) -> error::Result> { + (**self).hash(number) + } +} + impl ProvideCache for Client where B: backend::Backend, Block: BlockT, @@ -1434,7 +1432,7 @@ impl CallRuntimeAt for Client where fn call_api_at< 'a, R: Encode + Decode + PartialEq, - NC: FnOnce() -> result::Result + UnwindSafe, + NC: FnOnce() -> result::Result + UnwindSafe, C: CoreApi, >( &self, @@ -1448,8 +1446,6 @@ impl CallRuntimeAt for Client where context: ExecutionContext, recorder: &Option>>>, ) -> error::Result> { - let enable_keystore = context.enable_keystore(); - let manager = match context { ExecutionContext::BlockConstruction => self.execution_strategies.block_construction.get_manager(), @@ -1457,16 +1453,17 @@ impl CallRuntimeAt for Client where self.execution_strategies.syncing.get_manager(), ExecutionContext::Importing => self.execution_strategies.importing.get_manager(), - ExecutionContext::OffchainWorker(_) => + ExecutionContext::OffchainCall(Some((_, capabilities))) if capabilities.has_all() => self.execution_strategies.offchain_worker.get_manager(), - ExecutionContext::Other => + ExecutionContext::OffchainCall(_) => self.execution_strategies.other.get_manager(), }; + let capabilities = context.capabilities(); let mut offchain_extensions = match context { - ExecutionContext::OffchainWorker(ext) => Some(ext), + ExecutionContext::OffchainCall(ext) => ext.map(|x| x.0), _ => None, - }; + }.map(|ext| offchain::LimitedExternalities::new(capabilities, ext)); self.executor.contextual_call::<_, _, fn(_,_) -> _,_,_>( || core_api.initialize_block(at, &self.prepare_environment_block(at)?), @@ -1479,7 +1476,7 @@ impl CallRuntimeAt for Client where native_call, offchain_extensions.as_mut(), recorder, - enable_keystore, + capabilities.has(offchain::Capability::Keystore), ) } @@ -1488,6 +1485,9 @@ impl CallRuntimeAt for Client where } } +/// NOTE: only use this implementation when you are sure there are NO consensus-level BlockImport +/// objects. Otherwise, importing blocks directly into the client would be bypassing +/// important verification work. impl<'a, B, E, Block, RA> consensus::BlockImport for &'a Client where B: backend::Backend, E: CallExecutor + Clone + Send + Sync, @@ -1497,6 +1497,13 @@ impl<'a, B, E, Block, RA> consensus::BlockImport for &'a Client, @@ -1513,9 +1520,22 @@ impl<'a, B, E, Block, RA> consensus::BlockImport for &'a Client, ) -> Result { + let BlockCheckParams { hash, number, parent_hash } = block; + + if let Some(h) = self.fork_blocks.as_ref().and_then(|x| x.get(&number)) { + if &hash != h { + trace!( + "Rejecting block from known invalid fork. Got {:?}, expected: {:?} at height {}", + hash, + h, + number + ); + return Ok(ImportResult::KnownBad); + } + } + match self.block_status(&BlockId::Hash(parent_hash)) .map_err(|e| ConsensusError::ClientImport(e.to_string()))? { @@ -1532,7 +1552,8 @@ impl<'a, B, E, Block, RA> consensus::BlockImport for &'a Client return Ok(ImportResult::KnownBad), } - Ok(ImportResult::imported()) + + Ok(ImportResult::imported(false)) } } @@ -1553,10 +1574,53 @@ impl consensus::BlockImport for Client fn check_block( &mut self, - hash: Block::Hash, - parent_hash: Block::Hash, + block: BlockCheckParams, ) -> Result { - (&*self).check_block(hash, parent_hash) + (&*self).check_block(block) + } +} + +impl Finalizer for Client where + B: backend::Backend, + E: CallExecutor, + Block: BlockT, +{ + fn apply_finality( + &self, + operation: &mut ClientImportOperation, + id: BlockId, + justification: Option, + notify: bool, + ) -> error::Result<()> { + let last_best = self.backend.blockchain().info().best_hash; + let to_finalize_hash = self.backend.blockchain().expect_block_hash_from_id(&id)?; + self.apply_finality_with_block_hash(operation, to_finalize_hash, justification, last_best, notify) + } + + fn finalize_block(&self, id: BlockId, justification: Option, notify: bool) -> error::Result<()> { + self.lock_import_and_run(|operation| { + self.apply_finality(operation, id, justification, notify) + }) + } +} + +impl Finalizer for &Client where + B: backend::Backend, + E: CallExecutor, + Block: BlockT, +{ + fn apply_finality( + &self, + operation: &mut ClientImportOperation, + id: BlockId, + justification: Option, + notify: bool, + ) -> error::Result<()> { + (**self).apply_finality(operation, id, justification, notify) + } + + fn finalize_block(&self, id: BlockId, justification: Option, notify: bool) -> error::Result<()> { + (**self).finalize_block(id, justification, notify) } } @@ -1620,129 +1684,14 @@ where fn best_block_header(&self) -> error::Result<::Header> { let info = self.backend.blockchain().info(); - let best_hash = self.best_containing(info.best_hash, None)? + let import_lock = self.backend.get_import_lock(); + let best_hash = self.backend.blockchain().best_containing(info.best_hash, None, import_lock)? .unwrap_or(info.best_hash); Ok(self.backend.blockchain().header(BlockId::Hash(best_hash))? .expect("given block hash was fetched from block in db; qed")) } - /// Get the most recent block hash of the best (longest) chains - /// that contain block with the given `target_hash`. - /// - /// The search space is always limited to blocks which are in the finalized - /// chain or descendents of it. - /// - /// If `maybe_max_block_number` is `Some(max_block_number)` - /// the search is limited to block `numbers <= max_block_number`. - /// in other words as if there were no blocks greater `max_block_number`. - /// Returns `Ok(None)` if `target_hash` is not found in search space. - /// TODO: document time complexity of this, see [#1444](https://github.com/paritytech/substrate/issues/1444) - fn best_containing( - &self, - target_hash: Block::Hash, - maybe_max_number: Option> - ) -> error::Result> { - let target_header = { - match self.backend.blockchain().header(BlockId::Hash(target_hash))? { - Some(x) => x, - // target not in blockchain - None => { return Ok(None); }, - } - }; - - if let Some(max_number) = maybe_max_number { - // target outside search range - if target_header.number() > &max_number { - return Ok(None); - } - } - - let leaves = { - // ensure no blocks are imported during this code block. - // an import could trigger a reorg which could change the canonical chain. - // we depend on the canonical chain staying the same during this code block. - let _import_lock = self.backend.get_import_lock().lock(); - - let info = self.backend.blockchain().info(); - - let canon_hash = self.backend.blockchain().hash(*target_header.number())? - .ok_or_else(|| error::Error::from(format!("failed to get hash for block number {}", target_header.number())))?; - - if canon_hash == target_hash { - // if a `max_number` is given we try to fetch the block at the - // given depth, if it doesn't exist or `max_number` is not - // provided, we continue to search from all leaves below. - if let Some(max_number) = maybe_max_number { - if let Some(header) = self.backend.blockchain().hash(max_number)? { - return Ok(Some(header)); - } - } - } else if info.finalized_number >= *target_header.number() { - // header is on a dead fork. - return Ok(None); - } - - self.backend.blockchain().leaves()? - }; - - // for each chain. longest chain first. shortest last - for leaf_hash in leaves { - // start at the leaf - let mut current_hash = leaf_hash; - - // if search is not restricted then the leaf is the best - let mut best_hash = leaf_hash; - - // go backwards entering the search space - // waiting until we are <= max_number - if let Some(max_number) = maybe_max_number { - loop { - let current_header = self.backend.blockchain().header(BlockId::Hash(current_hash.clone()))? - .ok_or_else(|| error::Error::from(format!("failed to get header for hash {}", current_hash)))?; - - if current_header.number() <= &max_number { - best_hash = current_header.hash(); - break; - } - - current_hash = *current_header.parent_hash(); - } - } - - // go backwards through the chain (via parent links) - loop { - // until we find target - if current_hash == target_hash { - return Ok(Some(best_hash)); - } - - let current_header = self.backend.blockchain().header(BlockId::Hash(current_hash.clone()))? - .ok_or_else(|| error::Error::from(format!("failed to get header for hash {}", current_hash)))?; - - // stop search in this chain once we go below the target's block number - if current_header.number() < target_header.number() { - break; - } - - current_hash = *current_header.parent_hash(); - } - } - - // header may be on a dead fork -- the only leaves that are considered are - // those which can still be finalized. - // - // FIXME #1558 only issue this warning when not on a dead fork - warn!( - "Block {:?} exists in chain but not found when following all \ - leaves backwards. Number limit = {:?}", - target_hash, - maybe_max_number, - ); - - Ok(None) - } - fn leaves(&self) -> Result::Hash>, error::Error> { self.backend.blockchain().leaves() } @@ -1771,7 +1720,8 @@ where target_hash: Block::Hash, maybe_max_number: Option> ) -> Result, ConsensusError> { - LongestChain::best_containing(self, target_hash, maybe_max_number) + let import_lock = self.backend.get_import_lock(); + self.backend.blockchain().best_containing(target_hash, maybe_max_number, import_lock) .map_err(|e| ConsensusError::ChainLookup(e.to_string()).into()) } } @@ -1806,7 +1756,7 @@ impl backend::AuxStore for Client // layer, one can always use atomic operations to make sure // import is only locked once. self.lock_import_and_run(|operation| { - self.apply_aux(operation, insert, delete) + apply_aux(operation, insert, delete) }) } /// Query auxiliary data from key-value store. @@ -1815,11 +1765,55 @@ impl backend::AuxStore for Client } } + +impl backend::AuxStore for &Client + where + B: backend::Backend, + E: CallExecutor, + Block: BlockT, +{ + + fn insert_aux< + 'a, + 'b: 'a, + 'c: 'a, + I: IntoIterator, + D: IntoIterator, + >(&self, insert: I, delete: D) -> error::Result<()> { + (**self).insert_aux(insert, delete) + } + + fn get_aux(&self, key: &[u8]) -> error::Result>> { + (**self).get_aux(key) + } +} + +/// Helper function to apply auxiliary data insertion into an operation. +pub fn apply_aux<'a, 'b: 'a, 'c: 'a, B, Block, H, D, I>( + operation: &mut ClientImportOperation, + insert: I, + delete: D +) -> error::Result<()> +where + Block: BlockT, + H: Hasher, + B: backend::Backend, + I: IntoIterator, + D: IntoIterator, +{ + operation.op.insert_aux( + insert.into_iter() + .map(|(k, v)| (k.to_vec(), Some(v.to_vec()))) + .chain(delete.into_iter().map(|k| (k.to_vec(), None))) + ) +} + /// Utility methods for the client. pub mod utils { use super::*; - use crate::{backend::Backend, blockchain, error}; + use crate::error; use primitives::H256; + use std::borrow::Borrow; /// Returns a function for checking block ancestry, the returned function will /// return `true` if the given hash (second parameter) is a descendent of the @@ -1827,16 +1821,17 @@ pub mod utils { /// represent the current block `hash` and its `parent hash`, if given the /// function that's returned will assume that `hash` isn't part of the local DB /// yet, and all searches in the DB will instead reference the parent. - pub fn is_descendent_of<'a, B, E, Block: BlockT, RA>( - client: &'a Client, - current: Option<(&'a H256, &'a H256)>, + pub fn is_descendent_of<'a, Block: BlockT, T, H: Borrow + 'a>( + client: &'a T, + current: Option<(H, H)>, ) -> impl Fn(&H256, &H256) -> Result + 'a - where B: Backend, - E: CallExecutor + Send + Sync, + where T: ChainHeaderBackend + HeaderMetadata, { move |base, hash| { if base == hash { return Ok(false); } + let current = current.as_ref().map(|(c, p)| (c.borrow(), p.borrow())); + let mut hash = hash; if let Some((current_hash, current_parent_hash)) = current { if base == current_hash { return Ok(false); } @@ -1849,18 +1844,23 @@ pub mod utils { } } - let tree_route = blockchain::tree_route( - #[allow(deprecated)] - client.backend().blockchain(), - BlockId::Hash(*hash), - BlockId::Hash(*base), - )?; + let ancestor = header_metadata::lowest_common_ancestor(client, *hash, *base)?; - Ok(tree_route.common_block().hash == *base) + Ok(ancestor.hash == *base) } } } +impl consensus::block_validation::Chain for Client + where BE: backend::Backend, + E: CallExecutor, + B: BlockT +{ + fn block_status(&self, id: &BlockId) -> Result> { + Client::block_status(self, id).map_err(|e| Box::new(e) as Box<_>) + } +} + #[cfg(test)] pub(crate) mod tests { use std::collections::HashMap; @@ -1870,7 +1870,7 @@ pub(crate) mod tests { use consensus::{BlockOrigin, SelectChain}; use test_client::{ prelude::*, - client::backend::Backend as TestBackend, + client_db::{Backend, DatabaseSettings, PruningMode}, runtime::{self, Block, Transfer, RuntimeApi, TestAPI}, }; @@ -2519,7 +2519,12 @@ pub(crate) mod tests { for (index, (begin, end, key, expected_result)) in test_cases.into_iter().enumerate() { let end = client.block_hash(end).unwrap().unwrap(); - let actual_result = client.key_changes(begin, BlockId::Hash(end), &StorageKey(key)).unwrap(); + let actual_result = client.key_changes( + begin, + BlockId::Hash(end), + None, + &StorageKey(key), + ).unwrap(); match actual_result == expected_result { true => (), false => panic!(format!("Failed test {}: actual = {:?}, expected = {:?}", @@ -2530,8 +2535,6 @@ pub(crate) mod tests { #[test] fn import_with_justification() { - use test_client::blockchain::Backend; - let client = test_client::new(); // G -> A1 @@ -2547,33 +2550,29 @@ pub(crate) mod tests { let a3 = client.new_block_at(&BlockId::Hash(a2.hash()), Default::default()).unwrap().bake().unwrap(); client.import_justified(BlockOrigin::Own, a3.clone(), justification.clone()).unwrap(); - #[allow(deprecated)] - let blockchain = client.backend().blockchain(); - assert_eq!( - blockchain.last_finalized().unwrap(), + client.info().chain.finalized_hash, a3.hash(), ); assert_eq!( - blockchain.justification(BlockId::Hash(a3.hash())).unwrap(), + client.justification(&BlockId::Hash(a3.hash())).unwrap(), Some(justification), ); assert_eq!( - blockchain.justification(BlockId::Hash(a1.hash())).unwrap(), + client.justification(&BlockId::Hash(a1.hash())).unwrap(), None, ); assert_eq!( - blockchain.justification(BlockId::Hash(a2.hash())).unwrap(), + client.justification(&BlockId::Hash(a2.hash())).unwrap(), None, ); } #[test] fn importing_diverged_finalized_block_should_trigger_reorg() { - use test_client::blockchain::HeaderBackend; let client = test_client::new(); @@ -2597,12 +2596,9 @@ pub(crate) mod tests { // create but don't import B1 just yet let b1 = b1.bake().unwrap(); - #[allow(deprecated)] - let blockchain = client.backend().blockchain(); - // A2 is the current best since it's the longest chain assert_eq!( - blockchain.info().best_hash, + client.info().chain.best_hash, a2.hash(), ); @@ -2611,19 +2607,18 @@ pub(crate) mod tests { client.import_justified(BlockOrigin::Own, b1.clone(), justification).unwrap(); assert_eq!( - blockchain.info().best_hash, + client.info().chain.best_hash, b1.hash(), ); assert_eq!( - blockchain.info().finalized_hash, + client.info().chain.finalized_hash, b1.hash(), ); } #[test] fn finalizing_diverged_block_should_trigger_reorg() { - use test_client::blockchain::HeaderBackend; let (client, select_chain) = TestClientBuilder::new().build_with_longest_chain(); @@ -2650,29 +2645,26 @@ pub(crate) mod tests { let b2 = client.new_block_at(&BlockId::Hash(b1.hash()), Default::default()).unwrap().bake().unwrap(); client.import(BlockOrigin::Own, b2.clone()).unwrap(); - #[allow(deprecated)] - let blockchain = client.backend().blockchain(); - // A2 is the current best since it's the longest chain assert_eq!( - blockchain.info().best_hash, + client.info().chain.best_hash, a2.hash(), ); // we finalize block B1 which is on a different branch from current best // which should trigger a re-org. - client.finalize_block(BlockId::Hash(b1.hash()), None, false).unwrap(); + client.finalize_block(BlockId::Hash(b1.hash()), None).unwrap(); // B1 should now be the latest finalized assert_eq!( - blockchain.info().finalized_hash, + client.info().chain.finalized_hash, b1.hash(), ); // and B1 should be the new best block (`finalize_block` as no way of // knowing about B2) assert_eq!( - blockchain.info().best_hash, + client.info().chain.best_hash, b1.hash(), ); @@ -2691,7 +2683,7 @@ pub(crate) mod tests { client.import(BlockOrigin::Own, b3.clone()).unwrap(); assert_eq!( - blockchain.info().best_hash, + client.info().chain.best_hash, b3.hash(), ); } @@ -2754,40 +2746,93 @@ pub(crate) mod tests { } #[test] - fn state_reverted_on_set_head() { + fn doesnt_import_blocks_that_revert_finality() { let _ = env_logger::try_init(); - let client = test_client::new(); + let tmp = tempfile::tempdir().unwrap(); + + // we need to run with archive pruning to avoid pruning non-canonical + // states + let backend = Arc::new(Backend::new( + DatabaseSettings { + cache_size: None, + state_cache_size: 1 << 20, + state_cache_child_ratio: None, + path: tmp.path().into(), + pruning: PruningMode::ArchiveAll, + }, + u64::max_value(), + ).unwrap()); - let current_balance = || - client.runtime_api().balance_of( - &BlockId::number(client.info().chain.best_number), AccountKeyring::Alice.into() - ).unwrap(); + let client = TestClientBuilder::with_backend(backend).build(); - // G -> A1 + // -> C1 + // / + // G -> A1 -> A2 // \ - // -> B1 - let mut a1 = client.new_block_at(&BlockId::Number(0), Default::default()).unwrap(); - a1.push_transfer(Transfer { - from: AccountKeyring::Alice.into(), - to: AccountKeyring::Bob.into(), - amount: 10, - nonce: 0, - }).unwrap(); - let a1 = a1.bake().unwrap(); + // -> B1 -> B2 -> B3 + + let a1 = client.new_block_at(&BlockId::Number(0), Default::default()) + .unwrap().bake().unwrap(); client.import(BlockOrigin::Own, a1.clone()).unwrap(); + let a2 = client.new_block_at(&BlockId::Hash(a1.hash()), Default::default()) + .unwrap().bake().unwrap(); + client.import(BlockOrigin::Own, a2.clone()).unwrap(); + let mut b1 = client.new_block_at(&BlockId::Number(0), Default::default()).unwrap(); + + // needed to make sure B1 gets a different hash from A1 b1.push_transfer(Transfer { from: AccountKeyring::Alice.into(), to: AccountKeyring::Ferdie.into(), - amount: 50, + amount: 1, nonce: 0, }).unwrap(); let b1 = b1.bake().unwrap(); client.import(BlockOrigin::Own, b1.clone()).unwrap(); - assert_eq!(990, current_balance()); - // Set B1 as new best - client.set_head(BlockId::hash(b1.hash())).unwrap(); - assert_eq!(950, current_balance()); + + let b2 = client.new_block_at(&BlockId::Hash(b1.hash()), Default::default()) + .unwrap().bake().unwrap(); + client.import(BlockOrigin::Own, b2.clone()).unwrap(); + + // we will finalize A2 which should make it impossible to import a new + // B3 at the same height but that doesnt't include it + client.finalize_block(BlockId::Hash(a2.hash()), None).unwrap(); + + let b3 = client.new_block_at(&BlockId::Hash(b2.hash()), Default::default()) + .unwrap().bake().unwrap(); + + let import_err = client.import(BlockOrigin::Own, b3).err().unwrap(); + let expected_err = ConsensusError::ClientImport( + error::Error::NotInFinalizedChain.to_string() + ); + + assert_eq!( + import_err.to_string(), + expected_err.to_string(), + ); + + // adding a C1 block which is lower than the last finalized should also + // fail (with a cheaper check that doesn't require checking ancestry). + let mut c1 = client.new_block_at(&BlockId::Number(0), Default::default()).unwrap(); + + // needed to make sure C1 gets a different hash from A1 and B1 + c1.push_transfer(Transfer { + from: AccountKeyring::Alice.into(), + to: AccountKeyring::Ferdie.into(), + amount: 2, + nonce: 0, + }).unwrap(); + let c1 = c1.bake().unwrap(); + + let import_err = client.import(BlockOrigin::Own, c1).err().unwrap(); + let expected_err = ConsensusError::ClientImport( + error::Error::NotInFinalizedChain.to_string() + ); + + assert_eq!( + import_err.to_string(), + expected_err.to_string(), + ); } } diff --git a/core/client/src/error.rs b/core/client/src/error.rs index 6f087df9de3721046e772e87183fa8e402c68222..922d122b42a8b5b761e69d098fec6bc8a1db1752 100644 --- a/core/client/src/error.rs +++ b/core/client/src/error.rs @@ -131,9 +131,7 @@ impl Error { } /// Chain a state error. - pub fn from_state(e: Box) -> Self { + pub fn from_state(e: Box) -> Self { Error::Execution(e) } } - -impl state_machine::Error for Error {} diff --git a/core/client/src/genesis.rs b/core/client/src/genesis.rs index 3ac93f4f577b65540a9f0b253c6ec8b10219f389..0c0d49f8eaccc937c4a7a5f0ed2a2bc7ecbd09cf 100644 --- a/core/client/src/genesis.rs +++ b/core/client/src/genesis.rs @@ -24,7 +24,10 @@ pub fn construct_genesis_block< > ( state_root: Block::Hash ) -> Block { - let extrinsics_root = <<::Header as HeaderT>::Hashing as HashT>::trie_root(::std::iter::empty::<(&[u8], &[u8])>()); + let extrinsics_root = <<::Header as HeaderT>::Hashing as HashT>::trie_root( + Vec::new(), + ); + Block::new( <::Header as HeaderT>::new( Zero::zero(), @@ -41,21 +44,22 @@ pub fn construct_genesis_block< mod tests { use codec::{Encode, Decode, Joiner}; use executor::native_executor_instance; - use state_machine::{self, OverlayedChanges, ExecutionStrategy, InMemoryChangesTrieStorage}; + use state_machine::{ + StateMachine, OverlayedChanges, ExecutionStrategy, InMemoryChangesTrieStorage, + }; use state_machine::backend::InMemory; use test_client::{ runtime::genesismap::{GenesisConfig, insert_genesis_block}, runtime::{Hash, Transfer, Block, BlockNumber, Header, Digest}, AccountKeyring, Sr25519Keyring, }; - use primitives::Blake2Hasher; - use hex::*; + use primitives::{Blake2Hasher, map, offchain::NeverOffchainExt}; + use hex_literal::*; native_executor_instance!( Executor, test_client::runtime::api::dispatch, - test_client::runtime::native_version, - test_client::runtime::WASM_BINARY + test_client::runtime::native_version ); fn executor() -> executor::NativeExecutor { @@ -86,10 +90,10 @@ mod tests { let hash = header.hash(); let mut overlay = OverlayedChanges::default(); - state_machine::new( + StateMachine::new( backend, Some(&InMemoryChangesTrieStorage::<_, u64>::new()), - state_machine::NeverOffchainExt::new(), + NeverOffchainExt::new(), &mut overlay, &executor(), "Core_initialize_block", @@ -100,10 +104,10 @@ mod tests { ).unwrap(); for tx in transactions.iter() { - state_machine::new( + StateMachine::new( backend, Some(&InMemoryChangesTrieStorage::<_, u64>::new()), - state_machine::NeverOffchainExt::new(), + NeverOffchainExt::new(), &mut overlay, &executor(), "BlockBuilder_apply_extrinsic", @@ -114,10 +118,10 @@ mod tests { ).unwrap(); } - let (ret_data, _, _) = state_machine::new( + let (ret_data, _, _) = StateMachine::new( backend, Some(&InMemoryChangesTrieStorage::<_, u64>::new()), - state_machine::NeverOffchainExt::new(), + NeverOffchainExt::new(), &mut overlay, &executor(), "BlockBuilder_finalize_block", @@ -153,6 +157,8 @@ mod tests { vec![AccountKeyring::One.into(), AccountKeyring::Two.into()], 1000, None, + map![], + map![], ).genesis_map(); let genesis_hash = insert_genesis_block(&mut storage); @@ -160,10 +166,10 @@ mod tests { let (b1data, _b1hash) = block1(genesis_hash, &backend); let mut overlay = OverlayedChanges::default(); - let _ = state_machine::new( + let _ = StateMachine::new( &backend, Some(&InMemoryChangesTrieStorage::<_, u64>::new()), - state_machine::NeverOffchainExt::new(), + NeverOffchainExt::new(), &mut overlay, &executor(), "Core_execute_block", @@ -181,6 +187,8 @@ mod tests { vec![AccountKeyring::One.into(), AccountKeyring::Two.into()], 1000, None, + map![], + map![], ).genesis_map(); let genesis_hash = insert_genesis_block(&mut storage); @@ -188,10 +196,10 @@ mod tests { let (b1data, _b1hash) = block1(genesis_hash, &backend); let mut overlay = OverlayedChanges::default(); - let _ = state_machine::new( + let _ = StateMachine::new( &backend, Some(&InMemoryChangesTrieStorage::<_, u64>::new()), - state_machine::NeverOffchainExt::new(), + NeverOffchainExt::new(), &mut overlay, &executor(), "Core_execute_block", @@ -209,6 +217,8 @@ mod tests { vec![AccountKeyring::One.into(), AccountKeyring::Two.into()], 68, None, + map![], + map![], ).genesis_map(); let genesis_hash = insert_genesis_block(&mut storage); @@ -216,10 +226,10 @@ mod tests { let (b1data, _b1hash) = block1(genesis_hash, &backend); let mut overlay = OverlayedChanges::default(); - let r = state_machine::new( + let r = StateMachine::new( &backend, Some(&InMemoryChangesTrieStorage::<_, u64>::new()), - state_machine::NeverOffchainExt::new(), + NeverOffchainExt::new(), &mut overlay, &executor(), "Core_execute_block", diff --git a/core/client/src/in_mem.rs b/core/client/src/in_mem.rs index c43c4e3197eece80a6b8671f38c8d786bfd29f84..5c35400d7743c2a7eb054f8f3ea35cf6dacdfbf4 100644 --- a/core/client/src/in_mem.rs +++ b/core/client/src/in_mem.rs @@ -16,7 +16,7 @@ //! In memory client backend -use std::collections::HashMap; +use std::collections::{HashMap, HashSet}; use std::sync::Arc; use parking_lot::{RwLock, Mutex}; use primitives::{ChangesTrieConfiguration, storage::well_known_keys}; @@ -24,16 +24,18 @@ use sr_primitives::generic::{BlockId, DigestItem}; use sr_primitives::traits::{Block as BlockT, Header as HeaderT, Zero, NumberFor}; use sr_primitives::{Justification, StorageOverlay, ChildrenStorageOverlay}; use state_machine::backend::{Backend as StateBackend, InMemory}; -use state_machine::{self, InMemoryChangesTrieStorage, ChangesTrieAnchorBlockId}; +use state_machine::{self, InMemoryChangesTrieStorage, ChangesTrieAnchorBlockId, ChangesTrieTransaction}; use hash_db::{Hasher, Prefix}; use trie::MemoryDB; -use consensus::well_known_cache_keys::Id as CacheKeyId; +use header_metadata::{CachedHeaderMetadata, HeaderMetadata}; use crate::error; use crate::backend::{self, NewBlockState, StorageCollection, ChildStorageCollection}; use crate::light; use crate::leaves::LeafSet; -use crate::blockchain::{self, BlockStatus, HeaderBackend}; +use crate::blockchain::{ + self, BlockStatus, HeaderBackend, well_known_cache_keys::Id as CacheKeyId +}; struct PendingBlock { block: StoredBlock, @@ -222,11 +224,7 @@ impl Blockchain { if &best_hash == header.parent_hash() { None } else { - let route = crate::blockchain::tree_route( - self, - BlockId::Hash(best_hash), - BlockId::Hash(*header.parent_hash()), - )?; + let route = header_metadata::tree_route(self, best_hash, *header.parent_hash())?; Some(route) } }; @@ -321,6 +319,21 @@ impl HeaderBackend for Blockchain { } } +impl HeaderMetadata for Blockchain { + type Error = error::Error; + + fn header_metadata(&self, hash: Block::Hash) -> Result, Self::Error> { + self.header(BlockId::hash(hash))?.map(|header| CachedHeaderMetadata::from(&header)) + .ok_or(error::Error::UnknownBlock(format!("header not found: {}", hash))) + } + + fn insert_header_metadata(&self, _hash: Block::Hash, _metadata: CachedHeaderMetadata) { + // No need to implement. + } + fn remove_header_metadata(&self, _hash: Block::Hash) { + // No need to implement. + } +} impl blockchain::Backend for Blockchain { fn body(&self, id: BlockId) -> error::Result::Extrinsic>>> { @@ -484,8 +497,8 @@ where Ok(()) } - fn update_changes_trie(&mut self, update: MemoryDB) -> error::Result<()> { - self.changes_trie_update = Some(update); + fn update_changes_trie(&mut self, update: ChangesTrieTransaction>) -> error::Result<()> { + self.changes_trie_update = Some(update.0); Ok(()) } @@ -718,6 +731,10 @@ where .map(|num| num.is_zero()) .unwrap_or(false) } + + fn remote_blockchain(&self) -> Arc> { + unimplemented!() + } } /// Prunable in-memory changes trie storage. @@ -758,6 +775,18 @@ impl state_machine::ChangesTrieStorage> for Change Block: BlockT, H: Hasher, { + fn as_roots_storage(&self) -> &dyn state_machine::ChangesTrieRootsStorage> { + self + } + + fn with_cached_changed_keys( + &self, + _root: &H::Out, + _functor: &mut dyn FnMut(&HashMap>, HashSet>>), + ) -> bool { + false + } + fn get(&self, key: &H::Out, prefix: Prefix) -> Result, String> { self.0.get(key, prefix) } diff --git a/core/client/src/lib.rs b/core/client/src/lib.rs index 99cbecbe894a82184d9c3338a1004fc9a83565a4..70c9b759268fc8043f12b2c51d550747f15325d8 100644 --- a/core/client/src/lib.rs +++ b/core/client/src/lib.rs @@ -67,7 +67,8 @@ //! ), //! // This parameter provides the storage for the chain genesis. //! <(StorageOverlay, ChildrenStorageOverlay)>::default(), -//! Default::default() +//! Default::default(), +//! Default::default(), //! ); //! ``` //! @@ -113,17 +114,19 @@ pub use crate::call_executor::{CallExecutor, LocalCallExecutor}; pub use crate::client::{ new_with_backend, new_in_mem, - BlockBody, BlockStatus, ImportNotifications, FinalityNotifications, BlockchainEvents, + BlockBody, ImportNotifications, FinalityNotifications, BlockchainEvents, BlockImportNotification, Client, ClientInfo, ExecutionStrategies, FinalityNotification, - LongestChain, BlockOf, ProvideUncles, - utils, + LongestChain, BlockOf, ProvideUncles, ForkBlocks, + utils, apply_aux, }; #[cfg(feature = "std")] pub use crate::notifications::{StorageEventStream, StorageChangeSet}; #[cfg(feature = "std")] -pub use state_machine::{ExecutionStrategy, NeverOffchainExt}; +pub use state_machine::ExecutionStrategy; #[cfg(feature = "std")] pub use crate::leaves::LeafSet; +#[cfg(feature = "std")] +pub use crate::blockchain::well_known_cache_keys; #[doc(inline)] pub use sr_api_macros::{decl_runtime_apis, impl_runtime_apis}; diff --git a/core/client/src/light/backend.rs b/core/client/src/light/backend.rs index 888c9d2033f6764ab32fd64b6adc3b4890e6f2a9..300d140630d8521afd2de13a6151b694ee9b604c 100644 --- a/core/client/src/light/backend.rs +++ b/core/client/src/light/backend.rs @@ -18,36 +18,34 @@ //! Everything else is requested from full nodes on demand. use std::collections::HashMap; -use std::sync::{Arc, Weak}; +use std::sync::Arc; use parking_lot::{RwLock, Mutex}; use sr_primitives::{generic::BlockId, Justification, StorageOverlay, ChildrenStorageOverlay}; -use state_machine::{Backend as StateBackend, TrieBackend, backend::InMemory as InMemoryState}; +use state_machine::{Backend as StateBackend, TrieBackend, backend::InMemory as InMemoryState, ChangesTrieTransaction}; use sr_primitives::traits::{Block as BlockT, NumberFor, Zero, Header}; use crate::in_mem::{self, check_genesis_storage}; use crate::backend::{ AuxStore, Backend as ClientBackend, BlockImportOperation, RemoteBackend, NewBlockState, StorageCollection, ChildStorageCollection, }; -use crate::blockchain::HeaderBackend as BlockchainHeaderBackend; +use crate::blockchain::{HeaderBackend as BlockchainHeaderBackend, well_known_cache_keys}; use crate::error::{Error as ClientError, Result as ClientResult}; use crate::light::blockchain::{Blockchain, Storage as BlockchainStorage}; -use crate::light::fetcher::{Fetcher, RemoteReadRequest}; use hash_db::Hasher; use trie::MemoryDB; -use consensus::well_known_cache_keys; const IN_MEMORY_EXPECT_PROOF: &str = "InMemory state backend has Void error type and always succeeds; qed"; /// Light client backend. -pub struct Backend { - blockchain: Arc>, +pub struct Backend { + blockchain: Arc>, genesis_state: RwLock>>, import_lock: Mutex<()>, } /// Light block (header and justification) import operation. -pub struct ImportOperation { +pub struct ImportOperation { header: Option, cache: HashMap>, leaf_state: NewBlockState, @@ -55,28 +53,21 @@ pub struct ImportOperation { finalized_blocks: Vec>, set_head: Option>, storage_update: Option>, - _phantom: ::std::marker::PhantomData<(S, F)>, + _phantom: ::std::marker::PhantomData<(S)>, } -/// On-demand state. -pub struct OnDemandState { - fetcher: Weak, - blockchain: Weak>, - block: Block::Hash, - cached_header: RwLock>, -} - -/// On-demand or in-memory genesis state. -pub enum OnDemandOrGenesisState { - /// On-demand state - storage values are fetched from remote nodes. - OnDemand(OnDemandState), +/// Either in-memory genesis state, or locally-unavailable state. +pub enum GenesisOrUnavailableState { /// Genesis state - storage values are stored in-memory. Genesis(InMemoryState), + /// We know that state exists, but all calls will fail with error, because it + /// isn't locally available. + Unavailable, } -impl Backend { +impl Backend { /// Create new light backend. - pub fn new(blockchain: Arc>) -> Self { + pub fn new(blockchain: Arc>) -> Self { Self { blockchain, genesis_state: RwLock::new(None), @@ -85,12 +76,12 @@ impl Backend { } /// Get shared blockchain reference. - pub fn blockchain(&self) -> &Arc> { + pub fn blockchain(&self) -> &Arc> { &self.blockchain } } -impl AuxStore for Backend { +impl AuxStore for Backend { fn insert_aux< 'a, 'b: 'a, @@ -106,16 +97,15 @@ impl AuxStore for Backend { } } -impl ClientBackend for Backend where +impl ClientBackend for Backend where Block: BlockT, S: BlockchainStorage, - F: Fetcher, H: Hasher, H::Out: Ord, { - type BlockImportOperation = ImportOperation; - type Blockchain = Blockchain; - type State = OnDemandOrGenesisState; + type BlockImportOperation = ImportOperation; + type Blockchain = Blockchain; + type State = GenesisOrUnavailableState; type ChangesTrieStorage = in_mem::ChangesTrieStorage; type OffchainStorage = in_mem::OffchainStorage; @@ -183,7 +173,7 @@ impl ClientBackend for Backend where self.blockchain.storage().finalize_header(block) } - fn blockchain(&self) -> &Blockchain { + fn blockchain(&self) -> &Blockchain { &self.blockchain } @@ -205,22 +195,17 @@ impl ClientBackend for Backend where // special case for genesis block if block_number.is_zero() { if let Some(genesis_state) = self.genesis_state.read().clone() { - return Ok(OnDemandOrGenesisState::Genesis(genesis_state)); + return Ok(GenesisOrUnavailableState::Genesis(genesis_state)); } } - // else create on-demand state - let block_hash = self.blockchain.expect_block_hash_from_id(&block)?; - Ok(OnDemandOrGenesisState::OnDemand(OnDemandState { - fetcher: self.blockchain.fetcher(), - blockchain: Arc::downgrade(&self.blockchain), - block: block_hash, - cached_header: RwLock::new(None), - })) + // else return unavailable state. We do not return error here, because error + // would mean that we do not know this state at all. But we know that it exists + Ok(GenesisOrUnavailableState::Unavailable) } fn revert(&self, _n: NumberFor) -> ClientResult> { - Err(ClientError::NotAvailableOnLightClient.into()) + Err(ClientError::NotAvailableOnLightClient) } fn get_import_lock(&self) -> &Mutex<()> { @@ -228,11 +213,10 @@ impl ClientBackend for Backend where } } -impl RemoteBackend for Backend +impl RemoteBackend for Backend where Block: BlockT, - S: BlockchainStorage, - F: Fetcher, + S: BlockchainStorage + 'static, H: Hasher, H::Out: Ord, { @@ -242,17 +226,20 @@ where .map(|num| num.is_zero()) .unwrap_or(false) } + + fn remote_blockchain(&self) -> Arc> { + self.blockchain.clone() + } } -impl BlockImportOperation for ImportOperation +impl BlockImportOperation for ImportOperation where Block: BlockT, - F: Fetcher, S: BlockchainStorage, H: Hasher, H::Out: Ord, { - type State = OnDemandOrGenesisState; + type State = GenesisOrUnavailableState; fn state(&self) -> ClientResult> { // None means 'locally-stateless' backend @@ -280,7 +267,7 @@ where Ok(()) } - fn update_changes_trie(&mut self, _update: MemoryDB) -> ClientResult<()> { + fn update_changes_trie(&mut self, _update: ChangesTrieTransaction>) -> ClientResult<()> { // we're not storing anything locally => ignore changes Ok(()) } @@ -337,95 +324,18 @@ where } } -impl StateBackend for OnDemandState -where - Block: BlockT, - S: BlockchainStorage, - F: Fetcher, - H: Hasher, -{ - type Error = ClientError; - type Transaction = (); - type TrieBackendStorage = MemoryDB; - - fn storage(&self, key: &[u8]) -> ClientResult>> { - let mut header = self.cached_header.read().clone(); - if header.is_none() { - let cached_header = self.blockchain.upgrade() - .ok_or_else(|| ClientError::UnknownBlock(format!("{}", self.block))) - .and_then(|blockchain| blockchain.expect_header(BlockId::Hash(self.block)))?; - header = Some(cached_header.clone()); - *self.cached_header.write() = Some(cached_header); +impl std::fmt::Debug for GenesisOrUnavailableState { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match *self { + GenesisOrUnavailableState::Genesis(ref state) => state.fmt(f), + GenesisOrUnavailableState::Unavailable => write!(f, "Unavailable"), } - - futures::executor::block_on( - self.fetcher.upgrade().ok_or(ClientError::NotAvailableOnLightClient)? - .remote_read(RemoteReadRequest { - block: self.block, - header: header.expect("if block above guarantees that header is_some(); qed"), - key: key.to_vec(), - retry_count: None, - }) - ) - } - - fn child_storage(&self, _storage_key: &[u8], _key: &[u8]) -> ClientResult>> { - Err(ClientError::NotAvailableOnLightClient.into()) - } - - fn for_keys_with_prefix(&self, _prefix: &[u8], _action: A) { - // whole state is not available on light node - } - - fn for_keys_in_child_storage(&self, _storage_key: &[u8], _action: A) { - // whole state is not available on light node - } - - fn for_child_keys_with_prefix( - &self, - _storage_key: &[u8], - _prefix: &[u8], - _action: A, - ) { - // whole state is not available on light node - } - - fn storage_root(&self, _delta: I) -> (H::Out, Self::Transaction) - where - I: IntoIterator, Option>)> - { - (H::Out::default(), ()) - } - - fn child_storage_root(&self, _key: &[u8], _delta: I) -> (Vec, bool, Self::Transaction) - where - I: IntoIterator, Option>)> - { - (H::Out::default().as_ref().to_vec(), true, ()) - } - - fn pairs(&self) -> Vec<(Vec, Vec)> { - // whole state is not available on light node - Vec::new() - } - - fn keys(&self, _prefix: &[u8]) -> Vec> { - // whole state is not available on light node - Vec::new() - } - - fn as_trie_backend(&mut self) -> Option<&TrieBackend> { - None } } -impl StateBackend for OnDemandOrGenesisState -where - Block: BlockT, - F: Fetcher, - S: BlockchainStorage, - H: Hasher, - H::Out: Ord, +impl StateBackend for GenesisOrUnavailableState + where + H::Out: Ord, { type Error = ClientError; type Transaction = (); @@ -433,35 +343,39 @@ where fn storage(&self, key: &[u8]) -> ClientResult>> { match *self { - OnDemandOrGenesisState::OnDemand(ref state) => - StateBackend::::storage(state, key), - OnDemandOrGenesisState::Genesis(ref state) => + GenesisOrUnavailableState::Genesis(ref state) => Ok(state.storage(key).expect(IN_MEMORY_EXPECT_PROOF)), + GenesisOrUnavailableState::Unavailable => Err(ClientError::NotAvailableOnLightClient), } } fn child_storage(&self, storage_key: &[u8], key: &[u8]) -> ClientResult>> { match *self { - OnDemandOrGenesisState::OnDemand(ref state) => - StateBackend::::child_storage(state, storage_key, key), - OnDemandOrGenesisState::Genesis(ref state) => + GenesisOrUnavailableState::Genesis(ref state) => Ok(state.child_storage(storage_key, key).expect(IN_MEMORY_EXPECT_PROOF)), + GenesisOrUnavailableState::Unavailable => Err(ClientError::NotAvailableOnLightClient), } } fn for_keys_with_prefix(&self, prefix: &[u8], action: A) { match *self { - OnDemandOrGenesisState::OnDemand(ref state) => - StateBackend::::for_keys_with_prefix(state, prefix, action), - OnDemandOrGenesisState::Genesis(ref state) => state.for_keys_with_prefix(prefix, action), + GenesisOrUnavailableState::Genesis(ref state) => state.for_keys_with_prefix(prefix, action), + GenesisOrUnavailableState::Unavailable => (), } } + fn for_key_values_with_prefix(&self, prefix: &[u8], action: A) { + match *self { + GenesisOrUnavailableState::Genesis(ref state) => state.for_key_values_with_prefix(prefix, action), + GenesisOrUnavailableState::Unavailable => (), + } + } + + fn for_keys_in_child_storage(&self, storage_key: &[u8], action: A) { match *self { - OnDemandOrGenesisState::OnDemand(ref state) => - StateBackend::::for_keys_in_child_storage(state, storage_key, action), - OnDemandOrGenesisState::Genesis(ref state) => state.for_keys_in_child_storage(storage_key, action), + GenesisOrUnavailableState::Genesis(ref state) => state.for_keys_in_child_storage(storage_key, action), + GenesisOrUnavailableState::Unavailable => (), } } @@ -472,10 +386,9 @@ where action: A, ) { match *self { - OnDemandOrGenesisState::OnDemand(ref state) => - StateBackend::::for_child_keys_with_prefix(state, storage_key, prefix, action), - OnDemandOrGenesisState::Genesis(ref state) => + GenesisOrUnavailableState::Genesis(ref state) => state.for_child_keys_with_prefix(storage_key, prefix, action), + GenesisOrUnavailableState::Unavailable => (), } } @@ -484,12 +397,9 @@ where I: IntoIterator, Option>)> { match *self { - OnDemandOrGenesisState::OnDemand(ref state) => - StateBackend::::storage_root(state, delta), - OnDemandOrGenesisState::Genesis(ref state) => { - let (root, _) = state.storage_root(delta); - (root, ()) - }, + GenesisOrUnavailableState::Genesis(ref state) => + (state.storage_root(delta).0, ()), + GenesisOrUnavailableState::Unavailable => (H::Out::default(), ()), } } @@ -498,35 +408,32 @@ where I: IntoIterator, Option>)> { match *self { - OnDemandOrGenesisState::OnDemand(ref state) => - StateBackend::::child_storage_root(state, key, delta), - OnDemandOrGenesisState::Genesis(ref state) => { + GenesisOrUnavailableState::Genesis(ref state) => { let (root, is_equal, _) = state.child_storage_root(key, delta); (root, is_equal, ()) }, + GenesisOrUnavailableState::Unavailable => (H::Out::default().as_ref().to_vec(), true, ()), } } fn pairs(&self) -> Vec<(Vec, Vec)> { match *self { - OnDemandOrGenesisState::OnDemand(ref state) => - StateBackend::::pairs(state), - OnDemandOrGenesisState::Genesis(ref state) => state.pairs(), + GenesisOrUnavailableState::Genesis(ref state) => state.pairs(), + GenesisOrUnavailableState::Unavailable => Vec::new(), } } fn keys(&self, prefix: &[u8]) -> Vec> { match *self { - OnDemandOrGenesisState::OnDemand(ref state) => - StateBackend::::keys(state, prefix), - OnDemandOrGenesisState::Genesis(ref state) => state.keys(prefix), + GenesisOrUnavailableState::Genesis(ref state) => state.keys(prefix), + GenesisOrUnavailableState::Unavailable => Vec::new(), } } fn as_trie_backend(&mut self) -> Option<&TrieBackend> { match self { - OnDemandOrGenesisState::OnDemand(ref mut state) => state.as_trie_backend(), - OnDemandOrGenesisState::Genesis(ref mut state) => state.as_trie_backend(), + GenesisOrUnavailableState::Genesis(ref mut state) => state.as_trie_backend(), + GenesisOrUnavailableState::Unavailable => None, } } } @@ -544,24 +451,24 @@ mod tests { let def = Default::default(); let header0 = test_client::runtime::Header::new(0, def, def, def, Default::default()); - let backend: Backend<_, _, Blake2Hasher> = Backend::new(Arc::new(DummyBlockchain::new(DummyStorage::new()))); + let backend: Backend<_, Blake2Hasher> = Backend::new(Arc::new(DummyBlockchain::new(DummyStorage::new()))); let mut op = backend.begin_operation().unwrap(); op.set_block_data(header0, None, None, NewBlockState::Final).unwrap(); op.reset_storage(Default::default(), Default::default()).unwrap(); backend.commit_operation(op).unwrap(); match backend.state_at(BlockId::Number(0)).unwrap() { - OnDemandOrGenesisState::Genesis(_) => (), + GenesisOrUnavailableState::Genesis(_) => (), _ => panic!("unexpected state"), } } #[test] - fn remote_state_is_created_when_genesis_state_is_inavailable() { - let backend: Backend<_, _, Blake2Hasher> = Backend::new(Arc::new(DummyBlockchain::new(DummyStorage::new()))); + fn unavailable_state_is_created_when_genesis_state_is_unavailable() { + let backend: Backend<_, Blake2Hasher> = Backend::new(Arc::new(DummyBlockchain::new(DummyStorage::new()))); match backend.state_at(BlockId::Number(0)).unwrap() { - OnDemandOrGenesisState::OnDemand(_) => (), + GenesisOrUnavailableState::Unavailable => (), _ => panic!("unexpected state"), } } diff --git a/core/client/src/light/blockchain.rs b/core/client/src/light/blockchain.rs index a2c2fe72baf93e56ba82061fff2152aee2993b47..202f94cd74fed91b731781ef2d5311cb0bc24f28 100644 --- a/core/client/src/light/blockchain.rs +++ b/core/client/src/light/blockchain.rs @@ -17,22 +17,26 @@ //! Light client blockchain backend. Only stores headers and justifications of recent //! blocks. CHT roots are stored for headers of ancient blocks. -use std::{sync::{Weak, Arc}, collections::HashMap}; -use parking_lot::Mutex; +use std::future::Future; +use std::{sync::Arc, collections::HashMap}; use sr_primitives::{Justification, generic::BlockId}; use sr_primitives::traits::{Block as BlockT, Header as HeaderT, NumberFor, Zero}; -use consensus::well_known_cache_keys; + +use header_metadata::{HeaderMetadata, CachedHeaderMetadata}; use crate::backend::{AuxStore, NewBlockState}; -use crate::blockchain::{Backend as BlockchainBackend, BlockStatus, Cache as BlockchainCache, - HeaderBackend as BlockchainHeaderBackend, Info as BlockchainInfo, ProvideCache}; +use crate::blockchain::{ + Backend as BlockchainBackend, BlockStatus, Cache as BlockchainCache, + HeaderBackend as BlockchainHeaderBackend, Info as BlockchainInfo, ProvideCache, + well_known_cache_keys +}; use crate::cht; use crate::error::{Error as ClientError, Result as ClientResult}; -use crate::light::fetcher::{Fetcher, RemoteBodyRequest, RemoteHeaderRequest}; +use crate::light::fetcher::{Fetcher, RemoteHeaderRequest}; /// Light client blockchain storage. -pub trait Storage: AuxStore + BlockchainHeaderBackend { +pub trait Storage: AuxStore + BlockchainHeaderBackend + HeaderMetadata { /// Store new header. Should refuse to revert any finalized blocks. /// /// Takes new authorities, the leaf state of the new block, and @@ -72,65 +76,52 @@ pub trait Storage: AuxStore + BlockchainHeaderBackend { fn cache(&self) -> Option>>; } +/// Remote header. +#[derive(Debug)] +pub enum LocalOrRemote { + /// When data is available locally, it is returned. + Local(Data), + /// When data is unavailable locally, the request to fetch it from remote node is returned. + Remote(Request), + /// When data is unknown. + Unknown, +} + +/// Futures-based blockchain backend that either resolves blockchain data +/// locally, or fetches required data from remote node. +pub trait RemoteBlockchain: Send + Sync { + /// Get block header. + fn header(&self, id: BlockId) -> ClientResult, + >>; +} + /// Light client blockchain. -pub struct Blockchain { - fetcher: Mutex>, +pub struct Blockchain { storage: S, } -impl Blockchain { +impl Blockchain { /// Create new light blockchain backed with given storage. pub fn new(storage: S) -> Self { Self { - fetcher: Mutex::new(Default::default()), storage, } } - /// Sets fetcher reference. - pub fn set_fetcher(&self, fetcher: Weak) { - *self.fetcher.lock() = fetcher; - } - - /// Get fetcher weak reference. - pub fn fetcher(&self) -> Weak { - self.fetcher.lock().clone() - } - /// Get storage reference. pub fn storage(&self) -> &S { &self.storage } } -impl BlockchainHeaderBackend for Blockchain where Block: BlockT, S: Storage, F: Fetcher { +impl BlockchainHeaderBackend for Blockchain where Block: BlockT, S: Storage { fn header(&self, id: BlockId) -> ClientResult> { - match self.storage.header(id)? { - Some(header) => Ok(Some(header)), - None => { - let number = match id { - BlockId::Hash(hash) => match self.storage.number(hash)? { - Some(number) => number, - None => return Ok(None), - }, - BlockId::Number(number) => number, - }; - - // if the header is from future or genesis (we never prune genesis) => return - if number.is_zero() || self.storage.status(BlockId::Number(number))? == BlockStatus::Unknown { - return Ok(None); - } - - futures::executor::block_on( - self.fetcher().upgrade() - .ok_or(ClientError::NotAvailableOnLightClient)? - .remote_header(RemoteHeaderRequest { - cht_root: self.storage.header_cht_root(cht::size(), number)?, - block: number, - retry_count: None, - }) - ).map(Some) - } + match RemoteBlockchain::header(self, id)? { + LocalOrRemote::Local(header) => Ok(Some(header)), + LocalOrRemote::Remote(_) => Err(ClientError::NotAvailableOnLightClient), + LocalOrRemote::Unknown => Ok(None), } } @@ -151,24 +142,29 @@ impl BlockchainHeaderBackend for Blockchain where Bloc } } -impl BlockchainBackend for Blockchain where Block: BlockT, S: Storage, F: Fetcher { - fn body(&self, id: BlockId) -> ClientResult>> { - let header = match self.header(id)? { - Some(header) => header, - None => return Ok(None), - }; +impl HeaderMetadata for Blockchain where Block: BlockT, S: Storage { + type Error = ClientError; + + fn header_metadata(&self, hash: Block::Hash) -> Result, Self::Error> { + self.storage.header_metadata(hash) + } + + fn insert_header_metadata(&self, hash: Block::Hash, metadata: CachedHeaderMetadata) { + self.storage.insert_header_metadata(hash, metadata) + } + + fn remove_header_metadata(&self, hash: Block::Hash) { + self.storage.remove_header_metadata(hash) + } +} - futures::executor::block_on( - self.fetcher().upgrade().ok_or(ClientError::NotAvailableOnLightClient)? - .remote_body(RemoteBodyRequest { - header, - retry_count: None, - }) - ).map(Some) +impl BlockchainBackend for Blockchain where Block: BlockT, S: Storage { + fn body(&self, _id: BlockId) -> ClientResult>> { + Err(ClientError::NotAvailableOnLightClient) } fn justification(&self, _id: BlockId) -> ClientResult> { - Ok(None) + Err(ClientError::NotAvailableOnLightClient) } fn last_finalized(&self) -> ClientResult { @@ -180,29 +176,84 @@ impl BlockchainBackend for Blockchain where Block: Blo } fn leaves(&self) -> ClientResult> { - unimplemented!() + Err(ClientError::NotAvailableOnLightClient) } fn children(&self, _parent_hash: Block::Hash) -> ClientResult> { - unimplemented!() + Err(ClientError::NotAvailableOnLightClient) } } -impl, F, Block: BlockT> ProvideCache for Blockchain { +impl, Block: BlockT> ProvideCache for Blockchain { fn cache(&self) -> Option>> { self.storage.cache() } } +impl RemoteBlockchain for Blockchain + where + S: Storage, +{ + fn header(&self, id: BlockId) -> ClientResult, + >> { + // first, try to read header from local storage + if let Some(local_header) = self.storage.header(id)? { + return Ok(LocalOrRemote::Local(local_header)); + } + + // we need to know block number to check if it's a part of CHT + let number = match id { + BlockId::Hash(hash) => match self.storage.number(hash)? { + Some(number) => number, + None => return Ok(LocalOrRemote::Unknown), + }, + BlockId::Number(number) => number, + }; + + // if the header is genesis (never pruned), non-canonical, or from future => return + if number.is_zero() || self.storage.status(BlockId::Number(number))? == BlockStatus::Unknown { + return Ok(LocalOrRemote::Unknown); + } + + Ok(LocalOrRemote::Remote(RemoteHeaderRequest { + cht_root: self.storage.header_cht_root(cht::size(), number)?, + block: number, + retry_count: None, + })) + } +} + +/// Returns future that resolves header either locally, or remotely. +pub fn future_header>( + blockchain: &dyn RemoteBlockchain, + fetcher: &F, + id: BlockId, +) -> impl Future, ClientError>> { + use futures03::future::{ready, Either, FutureExt}; + + match blockchain.header(id) { + Ok(LocalOrRemote::Remote(request)) => Either::Left( + fetcher + .remote_header(request) + .then(|header| ready(header.map(Some))) + ), + Ok(LocalOrRemote::Unknown) => Either::Right(ready(Ok(None))), + Ok(LocalOrRemote::Local(local_header)) => Either::Right(ready(Ok(Some(local_header)))), + Err(err) => Either::Right(ready(Err(err))), + } +} + #[cfg(test)] pub mod tests { use std::collections::HashMap; + use parking_lot::Mutex; use test_client::runtime::{Hash, Block, Header}; use crate::blockchain::Info; - use crate::light::fetcher::tests::OkCallFetcher; use super::*; - pub type DummyBlockchain = Blockchain; + pub type DummyBlockchain = Blockchain; pub struct DummyStorage { pub changes_tries_cht_roots: HashMap, @@ -248,6 +299,17 @@ pub mod tests { } } + impl HeaderMetadata for DummyStorage { + type Error = ClientError; + + fn header_metadata(&self, hash: Hash) -> Result, Self::Error> { + self.header(BlockId::hash(hash))?.map(|header| CachedHeaderMetadata::from(&header)) + .ok_or(ClientError::UnknownBlock("header not found".to_owned())) + } + fn insert_header_metadata(&self, _hash: Hash, _metadata: CachedHeaderMetadata) {} + fn remove_header_metadata(&self, _hash: Hash) {} + } + impl AuxStore for DummyStorage { fn insert_aux< 'a, diff --git a/core/client/src/light/call_executor.rs b/core/client/src/light/call_executor.rs index 2367aaf806510c0f1365652a4c56fbd54398f2b1..ec182cca11fe0916262066d22a298a62feb41c25 100644 --- a/core/client/src/light/call_executor.rs +++ b/core/client/src/light/call_executor.rs @@ -14,233 +14,62 @@ // You should have received a copy of the GNU General Public License // along with Substrate. If not, see . -//! Light client call executor. Executes methods on remote full nodes, fetching -//! execution proof and checking it locally. +//! Methods that light client could use to execute runtime calls. use std::{ collections::HashSet, sync::Arc, panic::UnwindSafe, result, - marker::PhantomData, cell::RefCell, rc::Rc, + cell::RefCell, rc::Rc, }; use codec::{Encode, Decode}; -use primitives::{offchain, H256, Blake2Hasher, convert_hash, NativeOrEncoded}; +use primitives::{ + offchain, H256, Blake2Hasher, convert_hash, NativeOrEncoded, + traits::CodeExecutor, +}; use sr_primitives::generic::BlockId; -use sr_primitives::traits::{One, Block as BlockT, Header as HeaderT}; +use sr_primitives::traits::{One, Block as BlockT, Header as HeaderT, NumberFor}; use state_machine::{ - self, Backend as StateBackend, CodeExecutor, OverlayedChanges, - ExecutionStrategy, create_proof_check_backend, - execution_proof_check_on_trie_backend, ExecutionManager, NeverOffchainExt + self, Backend as StateBackend, OverlayedChanges, ExecutionStrategy, create_proof_check_backend, + execution_proof_check_on_trie_backend, ExecutionManager, ChangesTrieTransaction, }; use hash_db::Hasher; use crate::runtime_api::{ProofRecorder, InitializeBlock}; use crate::backend::RemoteBackend; -use crate::blockchain::Backend as ChainBackend; use crate::call_executor::CallExecutor; use crate::error::{Error as ClientError, Result as ClientResult}; -use crate::light::fetcher::{Fetcher, RemoteCallRequest}; +use crate::light::fetcher::RemoteCallRequest; use executor::{RuntimeVersion, NativeVersion}; -use trie::MemoryDB; - -/// Call executor that executes methods on remote node, querying execution proof -/// and checking proof by re-executing locally. -pub struct RemoteCallExecutor { - blockchain: Arc, - fetcher: Arc, -} -/// Remote or local call executor. +/// Call executor that is able to execute calls only on genesis state. /// -/// Calls are executed locally if state is available locally. Otherwise, calls -/// are redirected to remote call executor. -pub struct RemoteOrLocalCallExecutor, B, R, L> { +/// Trying to execute call on non-genesis state leads to error. +pub struct GenesisCallExecutor { backend: Arc, - remote: R, local: L, - _block: PhantomData, } -impl Clone for RemoteCallExecutor { - fn clone(&self) -> Self { - RemoteCallExecutor { - blockchain: self.blockchain.clone(), - fetcher: self.fetcher.clone(), - } - } -} - -impl RemoteCallExecutor { - /// Creates new instance of remote call executor. - pub fn new(blockchain: Arc, fetcher: Arc) -> Self { - RemoteCallExecutor { blockchain, fetcher } - } -} - -impl CallExecutor for RemoteCallExecutor -where - Block: BlockT, - B: ChainBackend, - F: Fetcher, - Block::Hash: Ord, -{ - type Error = ClientError; - - fn call< - O: offchain::Externalities, - >( - &self, - id: &BlockId, - method: &str, - call_data: &[u8], - _strategy: ExecutionStrategy, - _side_effects_handler: Option<&mut O>, - ) -> ClientResult> - { - let block_hash = self.blockchain.expect_block_hash_from_id(id)?; - let block_header = self.blockchain.expect_header(id.clone())?; - - futures::executor::block_on(self.fetcher.remote_call(RemoteCallRequest { - block: block_hash, - header: block_header, - method: method.into(), - call_data: call_data.to_vec(), - retry_count: None, - })) - } - - fn contextual_call< - 'a, - O: offchain::Externalities, - IB: Fn() -> ClientResult<()>, - EM: Fn( - Result, Self::Error>, - Result, Self::Error> - ) -> Result, Self::Error>, - R: Encode + Decode + PartialEq, - NC, - >( - &self, - _initialize_block_fn: IB, - at: &BlockId, - method: &str, - call_data: &[u8], - changes: &RefCell, - initialize_block: InitializeBlock<'a, Block>, - execution_manager: ExecutionManager, - _native_call: Option, - side_effects_handler: Option<&mut O>, - _recorder: &Option>>>, - _enable_keystore: bool, - ) -> ClientResult> where ExecutionManager: Clone { - let block_initialized = match initialize_block { - InitializeBlock::Do(ref init_block) => { - init_block.borrow().is_some() - }, - InitializeBlock::Skip => false, - }; - - // it is only possible to execute contextual call if changes are empty - if !changes.borrow().is_empty() || block_initialized { - return Err(ClientError::NotAvailableOnLightClient.into()); - } - - self.call( - at, - method, - call_data, - (&execution_manager).into(), - side_effects_handler, - ).map(NativeOrEncoded::Encoded) - } - - fn runtime_version(&self, id: &BlockId) -> ClientResult { - let call_result = self.call( - id, - "Core_version", - &[], - ExecutionStrategy::NativeElseWasm, - NeverOffchainExt::new() - )?; - RuntimeVersion::decode(&mut call_result.as_slice()) - .map_err(|_| ClientError::VersionInvalid.into()) - } - - fn call_at_state< - O: offchain::Externalities, - S: StateBackend, - FF: FnOnce( - Result, Self::Error>, - Result, Self::Error> - ) -> Result, Self::Error>, - R: Encode + Decode + PartialEq, - NC: FnOnce() -> result::Result, - >(&self, - _state: &S, - _changes: &mut OverlayedChanges, - _method: &str, - _call_data: &[u8], - _m: ExecutionManager, - _native_call: Option, - _side_effects_handler: Option<&mut O>, - ) -> ClientResult<( - NativeOrEncoded, - (S::Transaction, ::Out), - Option>, - )> { - Err(ClientError::NotAvailableOnLightClient.into()) - } - - fn prove_at_trie_state>( - &self, - _state: &state_machine::TrieBackend, - _changes: &mut OverlayedChanges, - _method: &str, - _call_data: &[u8] - ) -> ClientResult<(Vec, Vec>)> { - Err(ClientError::NotAvailableOnLightClient.into()) - } - - fn native_runtime_version(&self) -> Option<&NativeVersion> { - None +impl GenesisCallExecutor { + /// Create new genesis call executor. + pub fn new(backend: Arc, local: L) -> Self { + Self { backend, local } } } -impl Clone for RemoteOrLocalCallExecutor - where - Block: BlockT, - B: RemoteBackend, - R: CallExecutor + Clone, - L: CallExecutor + Clone, -{ +impl Clone for GenesisCallExecutor { fn clone(&self) -> Self { - RemoteOrLocalCallExecutor { + GenesisCallExecutor { backend: self.backend.clone(), - remote: self.remote.clone(), local: self.local.clone(), - _block: Default::default(), } } } -impl RemoteOrLocalCallExecutor +impl CallExecutor for + GenesisCallExecutor where Block: BlockT, B: RemoteBackend, - Remote: CallExecutor, - Local: CallExecutor, -{ - /// Creates new instance of remote/local call executor. - pub fn new(backend: Arc, remote: Remote, local: Local) -> Self { - RemoteOrLocalCallExecutor { backend, remote, local, _block: Default::default(), } - } -} - -impl CallExecutor for - RemoteOrLocalCallExecutor - where - Block: BlockT, - B: RemoteBackend, - Remote: CallExecutor, Local: CallExecutor, { type Error = ClientError; @@ -257,7 +86,7 @@ impl CallExecutor for ) -> ClientResult> { match self.backend.is_local_state_available(id) { true => self.local.call(id, method, call_data, strategy, side_effects_handler), - false => self.remote.call(id, method, call_data, strategy, side_effects_handler), + false => Err(ClientError::NotAvailableOnLightClient), } } @@ -270,7 +99,7 @@ impl CallExecutor for Result, Self::Error> ) -> Result, Self::Error>, R: Encode + Decode + PartialEq, - NC: FnOnce() -> result::Result + UnwindSafe, + NC: FnOnce() -> result::Result + UnwindSafe, >( &self, initialize_block_fn: IB, @@ -312,36 +141,14 @@ impl CallExecutor for recorder, enable_keystore, ).map_err(|e| ClientError::Execution(Box::new(e.to_string()))), - false => CallExecutor::contextual_call::< - _, - _, - fn( - Result, Remote::Error>, - Result, Remote::Error>, - ) -> Result, Remote::Error>, - _, - NC - >( - &self.remote, - initialize_block_fn, - at, - method, - call_data, - changes, - initialize_block, - ExecutionManager::NativeWhenPossible, - native_call, - side_effects_handler, - recorder, - enable_keystore, - ).map_err(|e| ClientError::Execution(Box::new(e.to_string()))), + false => Err(ClientError::NotAvailableOnLightClient), } } fn runtime_version(&self, id: &BlockId) -> ClientResult { match self.backend.is_local_state_available(id) { true => self.local.runtime_version(id), - false => self.remote.runtime_version(id), + false => Err(ClientError::NotAvailableOnLightClient), } } @@ -353,52 +160,31 @@ impl CallExecutor for Result, Self::Error> ) -> Result, Self::Error>, R: Encode + Decode + PartialEq, - NC: FnOnce() -> result::Result + UnwindSafe, + NC: FnOnce() -> result::Result + UnwindSafe, >(&self, - state: &S, - changes: &mut OverlayedChanges, - method: &str, - call_data: &[u8], + _state: &S, + _changes: &mut OverlayedChanges, + _method: &str, + _call_data: &[u8], _manager: ExecutionManager, - native_call: Option, - side_effects_handler: Option<&mut O>, + _native_call: Option, + _side_effects_handler: Option<&mut O>, ) -> ClientResult<( NativeOrEncoded, (S::Transaction, ::Out), - Option>, + Option>>, )> { - // there's no actual way/need to specify native/wasm execution strategy on light node - // => we can safely ignore passed values - - CallExecutor::call_at_state::< - _, - _, - fn( - Result, Remote::Error>, - Result, Remote::Error>, - ) -> Result, Remote::Error>, - _, - NC - >( - &self.remote, - state, - changes, - method, - call_data, - ExecutionManager::NativeWhenPossible, - native_call, - side_effects_handler, - ).map_err(|e| ClientError::Execution(Box::new(e.to_string()))) + Err(ClientError::NotAvailableOnLightClient) } fn prove_at_trie_state>( &self, - state: &state_machine::TrieBackend, - changes: &mut OverlayedChanges, - method: &str, - call_data: &[u8] + _state: &state_machine::TrieBackend, + _changes: &mut OverlayedChanges, + _method: &str, + _call_data: &[u8] ) -> ClientResult<(Vec, Vec>)> { - self.remote.prove_at_trie_state(state, changes, method, call_data) + Err(ClientError::NotAvailableOnLightClient) } fn native_runtime_version(&self) -> Option<&NativeVersion> { @@ -452,7 +238,33 @@ pub fn prove_execution( pub fn check_execution_proof( executor: &E, request: &RemoteCallRequest

, - remote_proof: Vec> + remote_proof: Vec>, +) -> ClientResult> + where + Header: HeaderT, + E: CodeExecutor, + H: Hasher, + H::Out: Ord + 'static, +{ + check_execution_proof_with_make_header( + executor, + request, + remote_proof, + |header|
::new( + *header.number() + One::one(), + Default::default(), + Default::default(), + header.hash(), + Default::default(), + ), + ) +} + +fn check_execution_proof_with_make_header Header>( + executor: &E, + request: &RemoteCallRequest
, + remote_proof: Vec>, + make_next_header: MakeNextHeader, ) -> ClientResult> where Header: HeaderT, @@ -466,51 +278,132 @@ pub fn check_execution_proof( // prepare execution environment + check preparation proof let mut changes = OverlayedChanges::default(); let trie_backend = create_proof_check_backend(root, remote_proof)?; - let next_block =
::new( - *request.header.number() + One::one(), - Default::default(), - Default::default(), - request.header.hash(), - request.header.digest().clone(), - ); + let next_header = make_next_header(&request.header); execution_proof_check_on_trie_backend::( &trie_backend, &mut changes, executor, "Core_initialize_block", - &next_block.encode(), + &next_header.encode(), None, )?; // execute method - let local_result = execution_proof_check_on_trie_backend::( + execution_proof_check_on_trie_backend::( &trie_backend, &mut changes, executor, &request.method, &request.call_data, None, - )?; - - Ok(local_result) + ).map_err(Into::into) } #[cfg(test)] mod tests { use consensus::BlockOrigin; - use test_client::{self, runtime::Header, ClientExt, TestClient}; + use primitives::offchain::NeverOffchainExt; + use test_client::{self, runtime::{Header, Digest, Block}, ClientExt, TestClient}; use executor::NativeExecutor; use crate::backend::{Backend, NewBlockState}; use crate::in_mem::Backend as InMemBackend; - use crate::light::fetcher::tests::OkCallFetcher; use super::*; + struct DummyCallExecutor; + + impl CallExecutor for DummyCallExecutor { + type Error = ClientError; + + fn call( + &self, + _id: &BlockId, + _method: &str, + _call_data: &[u8], + _strategy: ExecutionStrategy, + _side_effects_handler: Option<&mut O>, + ) -> Result, ClientError> { + Ok(vec![42]) + } + + fn contextual_call< + 'a, + O: offchain::Externalities, + IB: Fn() -> ClientResult<()>, + EM: Fn( + Result, Self::Error>, + Result, Self::Error> + ) -> Result, Self::Error>, + R: Encode + Decode + PartialEq, + NC: FnOnce() -> result::Result + UnwindSafe, + >( + &self, + _initialize_block_fn: IB, + _at: &BlockId, + _method: &str, + _call_data: &[u8], + _changes: &RefCell, + _initialize_block: InitializeBlock<'a, Block>, + _execution_manager: ExecutionManager, + _native_call: Option, + _side_effects_handler: Option<&mut O>, + _proof_recorder: &Option>>>, + _enable_keystore: bool, + ) -> ClientResult> where ExecutionManager: Clone { + unreachable!() + } + + fn runtime_version(&self, _id: &BlockId) -> Result { + unreachable!() + } + + fn call_at_state< + O: offchain::Externalities, + S: state_machine::Backend, + F: FnOnce( + Result, Self::Error>, + Result, Self::Error> + ) -> Result, Self::Error>, + R: Encode + Decode + PartialEq, + NC: FnOnce() -> result::Result + UnwindSafe, + >(&self, + _state: &S, + _overlay: &mut OverlayedChanges, + _method: &str, + _call_data: &[u8], + _manager: ExecutionManager, + _native_call: Option, + _side_effects_handler: Option<&mut O>, + ) -> Result< + ( + NativeOrEncoded, + (S::Transaction, H256), + Option>>, + ), + ClientError, + > { + unreachable!() + } + + fn prove_at_trie_state>( + &self, + _trie_state: &state_machine::TrieBackend, + _overlay: &mut OverlayedChanges, + _method: &str, + _call_data: &[u8] + ) -> Result<(Vec, Vec>), ClientError> { + unreachable!() + } + + fn native_runtime_version(&self) -> Option<&NativeVersion> { + unreachable!() + } + } + #[test] fn execution_proof_is_generated_and_checked() { fn execute(remote_client: &TestClient, at: u64, method: &'static str) -> (Vec, Vec) { let remote_block_id = BlockId::Number(at); - let remote_root = remote_client.state_at(&remote_block_id) - .unwrap().storage_root(::std::iter::empty()).0; + let remote_header = remote_client.header(&remote_block_id).unwrap().unwrap(); // 'fetch' execution proof from remote node let (remote_result, remote_execution_proof) = remote_client.execution_proof( @@ -523,13 +416,7 @@ mod tests { let local_executor = NativeExecutor::::new(None); let local_result = check_execution_proof(&local_executor, &RemoteCallRequest { block: test_client::runtime::Hash::default(), - header: test_client::runtime::Header { - state_root: remote_root.into(), - parent_hash: Default::default(), - number: at, - extrinsics_root: Default::default(), - digest: Default::default(), - }, + header: remote_header, method: method.into(), call_data: vec![], retry_count: None, @@ -538,12 +425,51 @@ mod tests { (remote_result, local_result) } + fn execute_with_proof_failure(remote_client: &TestClient, at: u64, method: &'static str) { + let remote_block_id = BlockId::Number(at); + let remote_header = remote_client.header(&remote_block_id).unwrap().unwrap(); + + // 'fetch' execution proof from remote node + let (_, remote_execution_proof) = remote_client.execution_proof( + &remote_block_id, + method, + &[] + ).unwrap(); + + // check remote execution proof locally + let local_executor = NativeExecutor::::new(None); + let execution_result = check_execution_proof_with_make_header( + &local_executor, + &RemoteCallRequest { + block: test_client::runtime::Hash::default(), + header: remote_header, + method: method.into(), + call_data: vec![], + retry_count: None, + }, + remote_execution_proof, + |header|
::new( + at + 1, + Default::default(), + Default::default(), + header.hash(), + header.digest().clone(), // this makes next header wrong + ), + ); + match execution_result { + Err(crate::error::Error::Execution(_)) => (), + _ => panic!("Unexpected execution result: {:?}", execution_result), + } + } + // prepare remote client let remote_client = test_client::new(); - for _ in 1..3 { + for i in 1u32..3u32 { + let mut digest = Digest::default(); + digest.push(sr_primitives::generic::DigestItem::Other::(i.to_le_bytes().to_vec())); remote_client.import_justified( BlockOrigin::Own, - remote_client.new_block(Default::default()).unwrap().bake().unwrap(), + remote_client.new_block(digest).unwrap().bake().unwrap(), Default::default(), ).unwrap(); } @@ -552,20 +478,29 @@ mod tests { let (remote, local) = execute(&remote_client, 0, "Core_version"); assert_eq!(remote, local); + let (remote, local) = execute(&remote_client, 2, "Core_version"); + assert_eq!(remote, local); + // check method that requires environment let (_, block) = execute(&remote_client, 0, "BlockBuilder_finalize_block"); let local_block: Header = Decode::decode(&mut &block[..]).unwrap(); assert_eq!(local_block.number, 1); - // check method that requires environment let (_, block) = execute(&remote_client, 2, "BlockBuilder_finalize_block"); let local_block: Header = Decode::decode(&mut &block[..]).unwrap(); assert_eq!(local_block.number, 3); + + // check that proof check doesn't panic even if proof is incorrect AND no panic handler is set + execute_with_proof_failure(&remote_client, 2, "Core_version"); + + // check that proof check doesn't panic even if proof is incorrect AND panic handler is set + panic_handler::set("TEST", "1.2.3"); + execute_with_proof_failure(&remote_client, 2, "Core_version"); } #[test] - fn code_is_executed_locally_or_remotely() { - let backend = Arc::new(InMemBackend::new()); + fn code_is_executed_at_genesis_only() { + let backend = Arc::new(InMemBackend::::new()); let def = H256::default(); let header0 = test_client::runtime::Header::new(0, def, def, def, Default::default()); let hash0 = header0.hash(); @@ -574,28 +509,29 @@ mod tests { backend.blockchain().insert(hash0, header0, None, None, NewBlockState::Final).unwrap(); backend.blockchain().insert(hash1, header1, None, None, NewBlockState::Final).unwrap(); - let local_executor = RemoteCallExecutor::new(Arc::new(backend.blockchain().clone()), Arc::new(OkCallFetcher::new(vec![1]))); - let remote_executor = RemoteCallExecutor::new(Arc::new(backend.blockchain().clone()), Arc::new(OkCallFetcher::new(vec![2]))); - let remote_or_local = RemoteOrLocalCallExecutor::new(backend, remote_executor, local_executor); + let genesis_executor = GenesisCallExecutor::new(backend, DummyCallExecutor); assert_eq!( - remote_or_local.call( + genesis_executor.call( &BlockId::Number(0), "test_method", &[], ExecutionStrategy::NativeElseWasm, NeverOffchainExt::new(), ).unwrap(), - vec![1], + vec![42], ); - assert_eq!( - remote_or_local.call( - &BlockId::Number(1), - "test_method", - &[], - ExecutionStrategy::NativeElseWasm, - NeverOffchainExt::new(), - ).unwrap(), - vec![2], + + let call_on_unavailable = genesis_executor.call( + &BlockId::Number(1), + "test_method", + &[], + ExecutionStrategy::NativeElseWasm, + NeverOffchainExt::new(), ); + + match call_on_unavailable { + Err(ClientError::NotAvailableOnLightClient) => (), + _ => unreachable!("unexpected result: {:?}", call_on_unavailable), + } } } diff --git a/core/client/src/light/fetcher.rs b/core/client/src/light/fetcher.rs index 22d3e8fdb7d4edfcd2c3163eaf09d7f5fcd1b802..3c4387209a49078abaf9b59ca144e46478fd2fc8 100644 --- a/core/client/src/light/fetcher.rs +++ b/core/client/src/light/fetcher.rs @@ -17,20 +17,22 @@ //! Light client data fetcher. Fetches requested data from remote full nodes. use std::sync::Arc; -use std::collections::BTreeMap; +use std::collections::{BTreeMap, HashMap}; use std::marker::PhantomData; use std::future::Future; use hash_db::{HashDB, Hasher, EMPTY_PREFIX}; use codec::{Decode, Encode}; -use primitives::{ChangesTrieConfiguration, convert_hash}; +use primitives::{ChangesTrieConfiguration, convert_hash, traits::CodeExecutor}; use sr_primitives::traits::{ Block as BlockT, Header as HeaderT, Hash, HashFor, NumberFor, - SimpleArithmetic, CheckedConversion, + SimpleArithmetic, CheckedConversion, Zero, +}; +use state_machine::{ + ChangesTrieRootsStorage, ChangesTrieAnchorBlockId, ChangesTrieConfigurationRange, + TrieBackend, read_proof_check, key_changes_proof_check, create_proof_check_backend_storage, + read_child_proof_check, }; -use state_machine::{CodeExecutor, ChangesTrieRootsStorage, ChangesTrieAnchorBlockId, - TrieBackend, read_proof_check, key_changes_proof_check, - create_proof_check_backend_storage, read_child_proof_check}; use crate::cht; use crate::error::{Error as ClientError, Result as ClientResult}; @@ -71,7 +73,7 @@ pub struct RemoteReadRequest { /// Header of block at which read is performed. pub header: Header, /// Storage key to read. - pub key: Vec, + pub keys: Vec>, /// Number of times to retry request. None means that default RETRY_COUNT is used. pub retry_count: Option, } @@ -86,7 +88,7 @@ pub struct RemoteReadChildRequest { /// Storage key for child. pub storage_key: Vec, /// Child storage key to read. - pub key: Vec, + pub keys: Vec>, /// Number of times to retry request. None means that default RETRY_COUNT is used. pub retry_count: Option, } @@ -107,6 +109,8 @@ pub struct RemoteChangesRequest { /// Known changes trie roots for the range of blocks [tries_roots.0..max_block]. /// Proofs for roots of ascendants of tries_roots.0 are provided by the remote node. pub tries_roots: (Header::Number, Header::Hash, Vec), + /// Optional Child Storage key to read. + pub storage_key: Option>, /// Storage key to read. pub key: Vec, /// Number of times to retry request. None means that default RETRY_COUNT is used. @@ -141,15 +145,15 @@ pub struct RemoteBodyRequest { /// is correct (see FetchedDataChecker) and return already checked data. pub trait Fetcher: Send + Sync { /// Remote header future. - type RemoteHeaderResult: Future>; + type RemoteHeaderResult: Future> + Send + 'static; /// Remote storage read future. - type RemoteReadResult: Future>, ClientError>>; + type RemoteReadResult: Future, Option>>, ClientError>> + Send + 'static; /// Remote call result future. - type RemoteCallResult: Future, ClientError>>; + type RemoteCallResult: Future, ClientError>> + Send + 'static; /// Remote changes result future. - type RemoteChangesResult: Future, u32)>, ClientError>>; + type RemoteChangesResult: Future, u32)>, ClientError>> + Send + 'static; /// Remote block body result future. - type RemoteBodyResult: Future, ClientError>>; + type RemoteBodyResult: Future, ClientError>> + Send + 'static; /// Fetch remote header. fn remote_header(&self, request: RemoteHeaderRequest) -> Self::RemoteHeaderResult; @@ -189,13 +193,13 @@ pub trait FetchChecker: Send + Sync { &self, request: &RemoteReadRequest, remote_proof: Vec> - ) -> ClientResult>>; + ) -> ClientResult, Option>>>; /// Check remote storage read proof. fn check_read_child_proof( &self, request: &RemoteReadChildRequest, remote_proof: Vec> - ) -> ClientResult>>; + ) -> ClientResult, Option>>>; /// Check remote method execution proof. fn check_execution_proof( &self, @@ -217,15 +221,15 @@ pub trait FetchChecker: Send + Sync { } /// Remote data checker. -pub struct LightDataChecker, F> { - blockchain: Arc>, +pub struct LightDataChecker> { + blockchain: Arc>, executor: E, _hasher: PhantomData<(B, H)>, } -impl, F> LightDataChecker { +impl> LightDataChecker { /// Create new light data checker. - pub fn new(blockchain: Arc>, executor: E) -> Self { + pub fn new(blockchain: Arc>, executor: E) -> Self { Self { blockchain, executor, _hasher: PhantomData } @@ -283,9 +287,16 @@ impl, F> LightDataChecker( - &request.changes_trie_config, + key_changes_proof_check::( + changes_trie_config_range, &RootsStorage { roots: (request.tries_roots.0, &request.tries_roots.2), prev_roots: remote_roots, @@ -297,6 +308,7 @@ impl, F> LightDataChecker, F> LightDataChecker FetchChecker for LightDataChecker +impl FetchChecker for LightDataChecker where Block: BlockT, E: CodeExecutor, H: Hasher, H::Out: Ord + 'static, S: BlockchainStorage, - F: Send + Sync, { fn check_header_proof( &self, @@ -384,23 +395,26 @@ impl FetchChecker for LightDataChecker, - remote_proof: Vec> - ) -> ClientResult>> { - read_proof_check::(convert_hash(request.header.state_root()), remote_proof, &request.key) - .map_err(Into::into) + remote_proof: Vec>, + ) -> ClientResult, Option>>> { + read_proof_check::( + convert_hash(request.header.state_root()), + remote_proof, + request.keys.iter(), + ).map_err(Into::into) } fn check_read_child_proof( &self, request: &RemoteReadChildRequest, remote_proof: Vec> - ) -> ClientResult>> { - read_child_proof_check::( + ) -> ClientResult, Option>>> { + read_child_proof_check::( convert_hash(request.header.state_root()), remote_proof, &request.storage_key, - &request.key) - .map_err(Into::into) + request.keys.iter(), + ).map_err(Into::into) } fn check_execution_proof( @@ -425,7 +439,9 @@ impl FetchChecker for LightDataChecker ) -> ClientResult> { // TODO: #2621 - let extrinsics_root = HashFor::::ordered_trie_root(body.iter().map(Encode::encode)); + let extrinsics_root = HashFor::::ordered_trie_root( + body.iter().map(Encode::encode).collect(), + ); if *request.header.extrinsics_root() == extrinsics_root { Ok(body) } else { @@ -447,7 +463,7 @@ struct RootsStorage<'a, Number: SimpleArithmetic, Hash: 'a> { impl<'a, H, Number, Hash> ChangesTrieRootsStorage for RootsStorage<'a, Number, Hash> where H: Hasher, - Number: ::std::fmt::Display + Clone + SimpleArithmetic + Encode + Decode + Send + Sync + 'static, + Number: ::std::fmt::Display + ::std::hash::Hash + Clone + SimpleArithmetic + Encode + Decode + Send + Sync + 'static, Hash: 'a + Send + Sync + Clone + AsRef<[u8]>, { fn build_anchor( @@ -483,7 +499,7 @@ impl<'a, H, Number, Hash> ChangesTrieRootsStorage for RootsStorage<'a #[cfg(test)] pub mod tests { - use futures::future::Ready; + use futures03::future::Ready; use parking_lot::Mutex; use codec::Decode; use crate::client::tests::prepare_client_with_key_changes; @@ -511,12 +527,12 @@ pub mod tests { where E: std::convert::From<&'static str>, { - futures::future::ready(Err("Not implemented on test node".into())) + futures03::future::ready(Err("Not implemented on test node".into())) } impl Fetcher for OkCallFetcher { type RemoteHeaderResult = Ready>; - type RemoteReadResult = Ready>, ClientError>>; + type RemoteReadResult = Ready, Option>>, ClientError>>; type RemoteCallResult = Ready, ClientError>>; type RemoteChangesResult = Ready, u32)>, ClientError>>; type RemoteBodyResult = Ready, ClientError>>; @@ -534,7 +550,7 @@ pub mod tests { } fn remote_call(&self, _request: RemoteCallRequest
) -> Self::RemoteCallResult { - futures::future::ready(Ok((*self.lock()).clone())) + futures03::future::ready(Ok((*self.lock()).clone())) } fn remote_changes(&self, _request: RemoteChangesRequest
) -> Self::RemoteChangesResult { @@ -551,7 +567,6 @@ pub mod tests { Blake2Hasher, Block, DummyStorage, - OkCallFetcher, >; fn prepare_for_read_proof_check() -> (TestChecker, Header, Vec>, u32) { @@ -560,13 +575,17 @@ pub mod tests { let remote_block_id = BlockId::Number(0); let remote_block_hash = remote_client.block_hash(0).unwrap().unwrap(); let mut remote_block_header = remote_client.header(&remote_block_id).unwrap().unwrap(); - remote_block_header.state_root = remote_client.state_at(&remote_block_id).unwrap().storage_root(::std::iter::empty()).0.into(); + remote_block_header.state_root = remote_client.state_at(&remote_block_id).unwrap() + .storage_root(::std::iter::empty()).0.into(); // 'fetch' read proof from remote node let heap_pages = remote_client.storage(&remote_block_id, &StorageKey(well_known_keys::HEAP_PAGES.to_vec())) .unwrap() .and_then(|v| Decode::decode(&mut &v.0[..]).ok()).unwrap(); - let remote_read_proof = remote_client.read_proof(&remote_block_id, well_known_keys::HEAP_PAGES).unwrap(); + let remote_read_proof = remote_client.read_proof( + &remote_block_id, + &[well_known_keys::HEAP_PAGES], + ).unwrap(); // check remote read proof locally let local_storage = InMemoryBlockchain::::new(); @@ -582,6 +601,46 @@ pub mod tests { (local_checker, remote_block_header, remote_read_proof, heap_pages) } + fn prepare_for_read_child_proof_check() -> (TestChecker, Header, Vec>, Vec) { + use test_client::DefaultTestClientBuilderExt; + use test_client::TestClientBuilderExt; + // prepare remote client + let remote_client = test_client::TestClientBuilder::new() + .add_extra_child_storage(b":child_storage:default:child1".to_vec(), b"key1".to_vec(), b"value1".to_vec()) + .build(); + let remote_block_id = BlockId::Number(0); + let remote_block_hash = remote_client.block_hash(0).unwrap().unwrap(); + let mut remote_block_header = remote_client.header(&remote_block_id).unwrap().unwrap(); + remote_block_header.state_root = remote_client.state_at(&remote_block_id).unwrap() + .storage_root(::std::iter::empty()).0.into(); + + // 'fetch' child read proof from remote node + let child_value = remote_client.child_storage( + &remote_block_id, + &StorageKey(b":child_storage:default:child1".to_vec()), + &StorageKey(b"key1".to_vec()), + ).unwrap().unwrap().0; + assert_eq!(b"value1"[..], child_value[..]); + let remote_read_proof = remote_client.read_child_proof( + &remote_block_id, + b":child_storage:default:child1", + &[b"key1"], + ).unwrap(); + + // check locally + let local_storage = InMemoryBlockchain::::new(); + local_storage.insert( + remote_block_hash, + remote_block_header.clone(), + None, + None, + crate::backend::NewBlockState::Final, + ).unwrap(); + let local_executor = NativeExecutor::::new(None); + let local_checker = LightDataChecker::new(Arc::new(DummyBlockchain::new(DummyStorage::new())), local_executor); + (local_checker, remote_block_header, remote_read_proof, child_value) + } + fn prepare_for_header_proof_check(insert_cht: bool) -> (TestChecker, Hash, Header, Vec>) { // prepare remote client let remote_client = test_client::new(); @@ -623,9 +682,29 @@ pub mod tests { assert_eq!((&local_checker as &dyn FetchChecker).check_read_proof(&RemoteReadRequest::
{ block: remote_block_header.hash(), header: remote_block_header, - key: well_known_keys::HEAP_PAGES.to_vec(), + keys: vec![well_known_keys::HEAP_PAGES.to_vec()], retry_count: None, - }, remote_read_proof).unwrap().unwrap()[0], heap_pages as u8); + }, remote_read_proof).unwrap().remove(well_known_keys::HEAP_PAGES).unwrap().unwrap()[0], heap_pages as u8); + } + + #[test] + fn storage_child_read_proof_is_generated_and_checked() { + let ( + local_checker, + remote_block_header, + remote_read_proof, + result, + ) = prepare_for_read_child_proof_check(); + assert_eq!((&local_checker as &dyn FetchChecker).check_read_child_proof( + &RemoteReadChildRequest::
{ + block: remote_block_header.hash(), + header: remote_block_header, + storage_key: b":child_storage:default:child1".to_vec(), + keys: vec![b"key1".to_vec()], + retry_count: None, + }, + remote_read_proof + ).unwrap().remove(b"key1".as_ref()).unwrap().unwrap(), result); } #[test] @@ -678,7 +757,7 @@ pub mod tests { // 'fetch' changes proof from remote node let key = StorageKey(key); let remote_proof = remote_client.key_changes_proof( - begin_hash, end_hash, begin_hash, max_hash, &key + begin_hash, end_hash, begin_hash, max_hash, None, &key ).unwrap(); // check proof on local client @@ -690,6 +769,7 @@ pub mod tests { max_block: (max, max_hash), tries_roots: (begin, begin_hash, local_roots_range), key: key.0, + storage_key: None, retry_count: None, }; let local_result = local_checker.check_changes_proof(&request, ChangesProof { @@ -724,7 +804,7 @@ pub mod tests { let b3 = remote_client.block_hash_from_id(&BlockId::Number(3)).unwrap().unwrap(); let b4 = remote_client.block_hash_from_id(&BlockId::Number(4)).unwrap().unwrap(); let remote_proof = remote_client.key_changes_proof_with_cht_size( - b1, b4, b3, b4, &dave, 4 + b1, b4, b3, b4, None, &dave, 4 ).unwrap(); // prepare local checker, having a root of changes trie CHT#0 @@ -743,6 +823,7 @@ pub mod tests { last_block: (4, b4), max_block: (4, b4), tries_roots: (3, b3, vec![remote_roots[2].clone(), remote_roots[3].clone()]), + storage_key: None, key: dave.0, retry_count: None, }; @@ -774,7 +855,7 @@ pub mod tests { // 'fetch' changes proof from remote node let key = StorageKey(key); let remote_proof = remote_client.key_changes_proof( - begin_hash, end_hash, begin_hash, max_hash, &key).unwrap(); + begin_hash, end_hash, begin_hash, max_hash, None, &key).unwrap(); let local_roots_range = local_roots.clone()[(begin - 1) as usize..].to_vec(); let request = RemoteChangesRequest::
{ @@ -783,6 +864,7 @@ pub mod tests { last_block: (end, end_hash), max_block: (max, max_hash), tries_roots: (begin, begin_hash, local_roots_range.clone()), + storage_key: None, key: key.0, retry_count: None, }; @@ -836,7 +918,7 @@ pub mod tests { let b3 = remote_client.block_hash_from_id(&BlockId::Number(3)).unwrap().unwrap(); let b4 = remote_client.block_hash_from_id(&BlockId::Number(4)).unwrap().unwrap(); let remote_proof = remote_client.key_changes_proof_with_cht_size( - b1, b4, b3, b4, &dave, 4 + b1, b4, b3, b4, None, &dave, 4 ).unwrap(); // fails when changes trie CHT is missing from the local db diff --git a/core/client/src/light/mod.rs b/core/client/src/light/mod.rs index 89d3c60ddc3727f7fb67ef8b1c332b92ed12d4b3..c9d2e6040be2b2b4f6311e5b182ace27ed28e351 100644 --- a/core/client/src/light/mod.rs +++ b/core/client/src/light/mod.rs @@ -24,65 +24,57 @@ pub mod fetcher; use std::sync::Arc; use executor::RuntimeInfo; -use primitives::{H256, Blake2Hasher}; +use primitives::{H256, Blake2Hasher, traits::CodeExecutor}; use sr_primitives::BuildStorage; use sr_primitives::traits::Block as BlockT; -use state_machine::CodeExecutor; use crate::call_executor::LocalCallExecutor; use crate::client::Client; use crate::error::Result as ClientResult; use crate::light::backend::Backend; use crate::light::blockchain::{Blockchain, Storage as BlockchainStorage}; -use crate::light::call_executor::{RemoteCallExecutor, RemoteOrLocalCallExecutor}; -use crate::light::fetcher::{Fetcher, LightDataChecker}; +use crate::light::call_executor::GenesisCallExecutor; +use crate::light::fetcher::LightDataChecker; /// Create an instance of light client blockchain backend. -pub fn new_light_blockchain, F>(storage: S) -> Arc> { +pub fn new_light_blockchain>(storage: S) -> Arc> { Arc::new(Blockchain::new(storage)) } /// Create an instance of light client backend. -pub fn new_light_backend(blockchain: Arc>, fetcher: Arc) -> Arc> +pub fn new_light_backend(blockchain: Arc>) -> Arc> where B: BlockT, S: BlockchainStorage, - F: Fetcher, { - blockchain.set_fetcher(Arc::downgrade(&fetcher)); Arc::new(Backend::new(blockchain)) } /// Create an instance of light client. -pub fn new_light( - backend: Arc>, - fetcher: Arc, +pub fn new_light( + backend: Arc>, genesis_storage: GS, code_executor: E, -) -> ClientResult, RemoteOrLocalCallExecutor< - B, - Backend, - RemoteCallExecutor, F>, - LocalCallExecutor, E> +) -> ClientResult, GenesisCallExecutor< + Backend, + LocalCallExecutor, E> >, B, RA>> where B: BlockT, - S: BlockchainStorage, - F: Fetcher, + S: BlockchainStorage + 'static, GS: BuildStorage, E: CodeExecutor + RuntimeInfo, { - let remote_executor = RemoteCallExecutor::new(backend.blockchain().clone(), fetcher); let local_executor = LocalCallExecutor::new(backend.clone(), code_executor, None); - let executor = RemoteOrLocalCallExecutor::new(backend.clone(), remote_executor, local_executor); - Client::new(backend, executor, genesis_storage, Default::default()) + let executor = GenesisCallExecutor::new(backend.clone(), local_executor); + Client::new(backend, executor, genesis_storage, Default::default(), Default::default()) } /// Create an instance of fetch data checker. -pub fn new_fetch_checker, F>( - blockchain: Arc>, +pub fn new_fetch_checker>( + blockchain: Arc>, executor: E, -) -> LightDataChecker +) -> LightDataChecker where E: CodeExecutor, { diff --git a/core/client/src/notifications.rs b/core/client/src/notifications.rs index 0ddc4c72cdb5530aba3570a2586a3132a353df24..37f90dcc0ba64a0bb10a5a4b31cc70a988582edc 100644 --- a/core/client/src/notifications.rs +++ b/core/client/src/notifications.rs @@ -22,7 +22,7 @@ use std::{ }; use fnv::{FnvHashSet, FnvHashMap}; -use futures::channel::mpsc; +use futures03::channel::mpsc; use primitives::storage::{StorageKey, StorageData}; use sr_primitives::traits::Block as BlockT; @@ -347,7 +347,7 @@ mod tests { // given let mut notifications = StorageNotifications::::default(); let child_filter = [(StorageKey(vec![4]), None)]; - let mut recv = futures::executor::block_on_stream( + let mut recv = futures03::executor::block_on_stream( notifications.listen(None, Some(&child_filter[..])) ); @@ -382,13 +382,13 @@ mod tests { // given let mut notifications = StorageNotifications::::default(); let child_filter = [(StorageKey(vec![4]), Some(vec![StorageKey(vec![5])]))]; - let mut recv1 = futures::executor::block_on_stream( + let mut recv1 = futures03::executor::block_on_stream( notifications.listen(Some(&[StorageKey(vec![1])]), None) ); - let mut recv2 = futures::executor::block_on_stream( + let mut recv2 = futures03::executor::block_on_stream( notifications.listen(Some(&[StorageKey(vec![2])]), None) ); - let mut recv3 = futures::executor::block_on_stream( + let mut recv3 = futures03::executor::block_on_stream( notifications.listen(Some(&[]), Some(&child_filter)) ); @@ -429,16 +429,16 @@ mod tests { let mut notifications = StorageNotifications::::default(); { let child_filter = [(StorageKey(vec![4]), Some(vec![StorageKey(vec![5])]))]; - let _recv1 = futures::executor::block_on_stream( + let _recv1 = futures03::executor::block_on_stream( notifications.listen(Some(&[StorageKey(vec![1])]), None) ); - let _recv2 = futures::executor::block_on_stream( + let _recv2 = futures03::executor::block_on_stream( notifications.listen(Some(&[StorageKey(vec![2])]), None) ); - let _recv3 = futures::executor::block_on_stream( + let _recv3 = futures03::executor::block_on_stream( notifications.listen(None, None) ); - let _recv4 = futures::executor::block_on_stream( + let _recv4 = futures03::executor::block_on_stream( notifications.listen(None, Some(&child_filter)) ); assert_eq!(notifications.listeners.len(), 2); @@ -465,7 +465,7 @@ mod tests { // given let mut recv = { let mut notifications = StorageNotifications::::default(); - let recv = futures::executor::block_on_stream(notifications.listen(None, None)); + let recv = futures03::executor::block_on_stream(notifications.listen(None, None)); // when let changeset = vec![]; diff --git a/core/client/src/runtime_api.rs b/core/client/src/runtime_api.rs index ed5c9fad48dc3dc4968cd7a154d2d442445a36de..a5700951e9c4c64d1266f6f4f3054d22a93b1af5 100644 --- a/core/client/src/runtime_api.rs +++ b/core/client/src/runtime_api.rs @@ -136,7 +136,7 @@ pub trait CallRuntimeAt { fn call_api_at< 'a, R: Encode + Decode + PartialEq, - NC: FnOnce() -> result::Result + UnwindSafe, + NC: FnOnce() -> result::Result + UnwindSafe, C: Core, >( &self, diff --git a/core/consensus/aura/Cargo.toml b/core/consensus/aura/Cargo.toml index d6ce48841b8592514dffce78ee340202a175f3e9..b63987ecb70d89bb6ed05a5c798735ba23c74c61 100644 --- a/core/consensus/aura/Cargo.toml +++ b/core/consensus/aura/Cargo.toml @@ -21,11 +21,12 @@ substrate-telemetry = { path = "../../telemetry" } keystore = { package = "substrate-keystore", path = "../../keystore" } consensus_common = { package = "substrate-consensus-common", path = "../common" } sr-primitives = { path = "../../sr-primitives" } -futures-preview = { version = "=0.3.0-alpha.17", features = ["compat"] } +futures-preview = { version = "0.3.0-alpha.19", features = ["compat"] } futures01 = { package = "futures", version = "0.1" } -futures-timer = "0.2.1" +futures-timer = "0.4.0" parking_lot = "0.9.0" -log = "0.4" +log = "0.4.8" +derive_more = "0.15.0" [dev-dependencies] keyring = { package = "substrate-keyring", path = "../../keyring" } @@ -33,6 +34,6 @@ substrate-executor = { path = "../../executor" } network = { package = "substrate-network", path = "../../network", features = ["test-helpers"]} service = { package = "substrate-service", path = "../../service" } test-client = { package = "substrate-test-runtime-client", path = "../../test-runtime/client" } -tokio = "0.1.7" -env_logger = "0.6" -tempfile = "3.1" +tokio = "0.1.22" +env_logger = "0.6.2" +tempfile = "3.1.0" diff --git a/core/consensus/aura/primitives/Cargo.toml b/core/consensus/aura/primitives/Cargo.toml index ac2c2c791b2b1920f656a3f90bba926afbbaa1fd..7fd3f3d05d9bfc43ba1d0d8ea2d073b1417ba013 100644 --- a/core/consensus/aura/primitives/Cargo.toml +++ b/core/consensus/aura/primitives/Cargo.toml @@ -10,7 +10,7 @@ codec = { package = "parity-scale-codec", version = "1.0.0", default-features = substrate-client = { path = "../../../client", default-features = false } app-crypto = { package = "substrate-application-crypto", path = "../../../application-crypto", default-features = false } rstd = { package = "sr-std", path = "../../../sr-std", default-features = false } -sr-primitives = { path = "../../../sr-primitives", default-features = false } +sr-primitives = { path = "../../../sr-primitives", default-features = false } [features] default = ["std"] diff --git a/core/consensus/aura/primitives/src/lib.rs b/core/consensus/aura/primitives/src/lib.rs index 070eb6c6a91a44d0c93e66d7317616a1a3ea4366..e4620fcdbfdd44e6c3873db6eb80e318075fa051 100644 --- a/core/consensus/aura/primitives/src/lib.rs +++ b/core/consensus/aura/primitives/src/lib.rs @@ -23,45 +23,45 @@ use substrate_client::decl_runtime_apis; use rstd::vec::Vec; use sr_primitives::ConsensusEngineId; -mod app_sr25519 { - use app_crypto::{app_crypto, key_types::AURA, sr25519}; - app_crypto!(sr25519, AURA); -} - pub mod sr25519 { + mod app_sr25519 { + use app_crypto::{app_crypto, key_types::AURA, sr25519}; + app_crypto!(sr25519, AURA); + } + /// An Aura authority keypair using S/R 25519 as its crypto. #[cfg(feature = "std")] - pub type AuthorityPair = super::app_sr25519::Pair; + pub type AuthorityPair = app_sr25519::Pair; /// An Aura authority signature using S/R 25519 as its crypto. - pub type AuthoritySignature = super::app_sr25519::Signature; + pub type AuthoritySignature = app_sr25519::Signature; /// An Aura authority identifier using S/R 25519 as its crypto. - pub type AuthorityId = super::app_sr25519::Public; -} - -mod app_ed25519 { - use app_crypto::{app_crypto, key_types::AURA, ed25519}; - app_crypto!(ed25519, AURA); + pub type AuthorityId = app_sr25519::Public; } pub mod ed25519 { + mod app_ed25519 { + use app_crypto::{app_crypto, key_types::AURA, ed25519}; + app_crypto!(ed25519, AURA); + } + /// An Aura authority keypair using Ed25519 as its crypto. #[cfg(feature = "std")] - pub type AuthorityPair = super::app_ed25519::Pair; + pub type AuthorityPair = app_ed25519::Pair; /// An Aura authority signature using Ed25519 as its crypto. - pub type AuthoritySignature = super::app_ed25519::Signature; + pub type AuthoritySignature = app_ed25519::Signature; /// An Aura authority identifier using Ed25519 as its crypto. - pub type AuthorityId = super::app_ed25519::Public; + pub type AuthorityId = app_ed25519::Public; } /// The `ConsensusEngineId` of AuRa. pub const AURA_ENGINE_ID: ConsensusEngineId = [b'a', b'u', b'r', b'a']; /// The index of an authority. -pub type AuthorityIndex = u64; +pub type AuthorityIndex = u32; /// An consensus log item for Aura. #[derive(Decode, Encode)] diff --git a/core/consensus/aura/src/lib.rs b/core/consensus/aura/src/lib.rs index 74799837c4047db21259d85813b02b10b8d1bbab..eb2d1dba20f1b7750d9f7780f71b63ad4c6c98e7 100644 --- a/core/consensus/aura/src/lib.rs +++ b/core/consensus/aura/src/lib.rs @@ -33,7 +33,7 @@ use std::{sync::Arc, time::Duration, thread, marker::PhantomData, hash::Hash, fm use codec::{Encode, Decode, Codec}; use consensus_common::{self, BlockImport, Environment, Proposer, ForkChoiceStrategy, BlockImportParams, BlockOrigin, Error as ConsensusError, - SelectChain, well_known_cache_keys::{self, Id as CacheKeyId} + SelectChain, }; use consensus_common::import_queue::{ Verifier, BasicQueue, BoxBlockImport, BoxJustificationImport, BoxFinalityProofImport, @@ -41,27 +41,27 @@ use consensus_common::import_queue::{ use client::{ block_builder::api::BlockBuilder as BlockBuilderApi, blockchain::ProvideCache, runtime_api::ApiExt, error::Result as CResult, backend::AuxStore, BlockOf, + well_known_cache_keys::{self, Id as CacheKeyId}, }; -use sr_primitives::{generic::{self, BlockId, OpaqueDigestItemId}, Justification}; +use sr_primitives::{generic::{BlockId, OpaqueDigestItemId}, Justification}; use sr_primitives::traits::{Block as BlockT, Header, DigestItemFor, ProvideRuntimeApi, Zero, Member}; use primitives::crypto::Pair; -use inherents::{InherentDataProviders, InherentData}; +use inherents::{InherentDataProviders, InherentData, RuntimeString}; -use futures::{prelude::*, future}; +use futures::prelude::*; use parking_lot::Mutex; -use futures_timer::Delay; -use log::{error, warn, debug, info, trace}; +use log::{debug, info, trace}; use srml_aura::{ InherentType as AuraInherent, AuraInherentData, timestamp::{TimestampInherentData, InherentType as TimestampInherent, InherentError as TIError} }; -use substrate_telemetry::{telemetry, CONSENSUS_TRACE, CONSENSUS_DEBUG, CONSENSUS_WARN, CONSENSUS_INFO}; +use substrate_telemetry::{telemetry, CONSENSUS_TRACE, CONSENSUS_DEBUG, CONSENSUS_INFO}; use slots::{CheckedHeader, SlotData, SlotWorker, SlotInfo, SlotCompatible}; -use slots::{SignedDuration, check_equivocation}; +use slots::check_equivocation; use keystore::KeyStorePtr; @@ -139,19 +139,19 @@ pub fn start_aura( sync_oracle: SO, inherent_data_providers: InherentDataProviders, force_authoring: bool, - keystore: Option, + keystore: KeyStorePtr, ) -> Result, consensus_common::Error> where B: BlockT, C: ProvideRuntimeApi + BlockOf + ProvideCache + AuxStore + Send + Sync, C::Api: AuraApi>, SC: SelectChain, + E: Environment + Send + Sync + 'static, E::Proposer: Proposer, - >::Create: Unpin + Send + 'static, - P: Pair + Send + Sync + 'static, + >::Create: Unpin + Send, + P: Pair + Send + Sync, P::Public: Hash + Member + Encode + Decode, P::Signature: Hash + Member + Encode + Decode, H: Header, - E: Environment, I: BlockImport + Send + Sync + 'static, Error: ::std::error::Error + Send + From<::consensus_common::Error> + From + 'static, SO: SyncOracle + Send + Sync + Clone, @@ -183,149 +183,82 @@ struct AuraWorker { client: Arc, block_import: Arc>, env: E, - keystore: Option, + keystore: KeyStorePtr, sync_oracle: SO, force_authoring: bool, _key_type: PhantomData

, } -impl SlotWorker for AuraWorker where +impl slots::SimpleSlotWorker for AuraWorker where B: BlockT, C: ProvideRuntimeApi + BlockOf + ProvideCache + Sync, C::Api: AuraApi>, E: Environment, E::Proposer: Proposer, - >::Create: Unpin + Send + 'static, + >::Create: Unpin + Send, H: Header, I: BlockImport + Send + Sync + 'static, - P: Pair + Send + Sync + 'static, + P: Pair + Send + Sync, P::Public: Member + Encode + Decode + Hash, P::Signature: Member + Encode + Decode + Hash + Debug, SO: SyncOracle + Send + Clone, Error: ::std::error::Error + Send + From<::consensus_common::Error> + From + 'static, { - type OnSlot = Pin> + Send>>; - - fn on_slot( - &mut self, - chain_head: B::Header, - slot_info: SlotInfo, - ) -> Self::OnSlot { - let client = self.client.clone(); - let block_import = self.block_import.clone(); - - let (timestamp, slot_num, slot_duration) = - (slot_info.timestamp, slot_info.number, slot_info.duration); - - let authorities = match authorities(client.as_ref(), &BlockId::Hash(chain_head.hash())) { - Ok(authorities) => authorities, - Err(e) => { - warn!("Unable to fetch authorities at block {:?}: {:?}", chain_head.hash(), e); - - telemetry!( - CONSENSUS_WARN; "aura.unable_fetching_authorities"; - "slot" => ?chain_head.hash(), - "err" => ?e, - ); - return Box::pin(future::ready(Ok(()))); - } - }; - - if !self.force_authoring && self.sync_oracle.is_offline() && authorities.len() > 1 { - debug!(target: "aura", "Skipping proposal slot. Waiting for the network."); - telemetry!( - CONSENSUS_DEBUG; - "aura.skipping_proposal_slot"; - "authorities_len" => authorities.len(), - ); - return Box::pin(future::ready(Ok(()))); - } - let maybe_author = slot_author::

(slot_num, &authorities); - let maybe_pair = maybe_author.and_then(|p| - self.keystore.as_ref().and_then(|k| - k.read().key_pair_by_type::

(&p, app_crypto::key_types::AURA).ok() - ) - ); - let proposal_work = match maybe_pair { - None => return Box::pin(future::ready(Ok(()))), - Some(pair) => { - debug!( - target: "aura", "Starting authorship at slot {}; timestamp = {}", - slot_num, - timestamp, - ); - telemetry!(CONSENSUS_DEBUG; "aura.starting_authorship"; - "slot_num" => slot_num, - "timestamp" => timestamp, - ); + type EpochData = Vec>; + type Claim = P; + type SyncOracle = SO; + type Proposer = E::Proposer; + type BlockImport = I; + + fn logging_target(&self) -> &'static str { + "aura" + } - // we are the slot author. make a block and sign it. - let mut proposer = match self.env.init(&chain_head) { - Ok(p) => p, - Err(e) => { - warn!("Unable to author block in slot {:?}: {:?}", slot_num, e); - telemetry!(CONSENSUS_WARN; "aura.unable_authoring_block"; - "slot" => slot_num, "err" => ?e - ); - return Box::pin(future::ready(Ok(()))) - } - }; + fn block_import(&self) -> Arc> { + self.block_import.clone() + } - let remaining_duration = slot_info.remaining_duration(); - // deadline our production to approx. the end of the - // slot - futures::future::select( - proposer.propose( - slot_info.inherent_data, - generic::Digest { - logs: vec![ - as CompatibleDigestItem

>::aura_pre_digest(slot_num), - ], - }, - remaining_duration, - ).map_err(|e| consensus_common::Error::ClientImport(format!("{:?}", e)).into()), - Delay::new(remaining_duration) - .map_err(|err| consensus_common::Error::FaultyTimer(err).into()) - ).map(|v| match v { - futures::future::Either::Left((v, _)) => v.map(|v| (v, pair)), - futures::future::Either::Right((Ok(_), _)) => - Err(consensus_common::Error::ClientImport("Timeout in the AuRa proposer".into())), - futures::future::Either::Right((Err(err), _)) => Err(err), - }) - } - }; + fn epoch_data(&self, header: &B::Header, _slot_number: u64) -> Result { + authorities(self.client.as_ref(), &BlockId::Hash(header.hash())) + } - Box::pin(proposal_work.map_ok(move |(b, pair)| { - // minor hack since we don't have access to the timestamp - // that is actually set by the proposer. - let slot_after_building = SignedDuration::default().slot_now(slot_duration); - if slot_after_building != slot_num { - info!("Discarding proposal for slot {}; block production took too long", slot_num); - telemetry!(CONSENSUS_INFO; "aura.discarding_proposal_took_too_long"; - "slot" => slot_num, - ); - return - } + fn authorities_len(&self, epoch_data: &Self::EpochData) -> usize { + epoch_data.len() + } - let (header, body) = b.deconstruct(); - let pre_digest: Result = find_pre_digest::(&header); - if let Err(e) = pre_digest { - error!(target: "aura", "FATAL ERROR: Invalid pre-digest: {}!", e); - return - } else { - trace!(target: "aura", "Got correct number of seals. Good!") - }; + fn claim_slot( + &self, + _header: &B::Header, + slot_number: u64, + epoch_data: &Self::EpochData, + ) -> Option { + let expected_author = slot_author::

(slot_number, epoch_data); + + expected_author.and_then(|p| { + self.keystore.read() + .key_pair_by_type::

(&p, app_crypto::key_types::AURA).ok() + }) + } - let header_num = header.number().clone(); - let parent_hash = header.parent_hash().clone(); + fn pre_digest_data(&self, slot_number: u64, _claim: &Self::Claim) -> Vec> { + vec![ + as CompatibleDigestItem

>::aura_pre_digest(slot_number), + ] + } + fn block_import_params(&self) -> Box, + Self::Claim, + ) -> consensus_common::BlockImportParams + Send> { + Box::new(|header, header_hash, body, pair| { // sign the pre-sealed hash of the block and then // add it to a digest item. - let header_hash = header.hash(); let signature = pair.sign(header_hash.as_ref()); let signature_digest_item = as CompatibleDigestItem

>::aura_seal(signature); - let import_block: BlockImportParams = BlockImportParams { + BlockImportParams { origin: BlockOrigin::Own, header, justification: None, @@ -334,40 +267,74 @@ impl SlotWorker for AuraWorker w finalized: false, auxiliary: Vec::new(), fork_choice: ForkChoiceStrategy::LongestChain, - }; + } + }) + } - info!("Pre-sealed block for proposal at {}. Hash now {:?}, previously {:?}.", - header_num, - import_block.post_header().hash(), - header_hash - ); - telemetry!(CONSENSUS_INFO; "aura.pre_sealed_block"; - "header_num" => ?header_num, - "hash_now" => ?import_block.post_header().hash(), - "hash_previously" => ?header_hash, - ); + fn force_authoring(&self) -> bool { + self.force_authoring + } - if let Err(e) = block_import.lock().import_block(import_block, Default::default()) { - warn!(target: "aura", "Error with block built on {:?}: {:?}", parent_hash, e); + fn sync_oracle(&mut self) -> &mut Self::SyncOracle { + &mut self.sync_oracle + } - telemetry!(CONSENSUS_WARN; "aura.err_with_block_built_on"; - "hash" => ?parent_hash, "err" => ?e, - ); - } - })) + fn proposer(&mut self, block: &B::Header) -> Result { + self.env.init(block).map_err(|e| { + consensus_common::Error::ClientImport(format!("{:?}", e)).into() + }) } } -macro_rules! aura_err { - ($($i: expr),+) => { - { - debug!(target: "aura", $( $i ),+); - format!($( $i ),+) - } - }; +impl SlotWorker for AuraWorker where + B: BlockT, + C: ProvideRuntimeApi + BlockOf + ProvideCache + Sync + Send, + C::Api: AuraApi>, + E: Environment + Send + Sync, + E::Proposer: Proposer, + >::Create: Unpin + Send + 'static, + H: Header, + I: BlockImport + Send + Sync + 'static, + P: Pair + Send + Sync, + P::Public: Member + Encode + Decode + Hash, + P::Signature: Member + Encode + Decode + Hash + Debug, + SO: SyncOracle + Send + Sync + Clone, + Error: ::std::error::Error + Send + From<::consensus_common::Error> + From + 'static, +{ + type OnSlot = Pin> + Send>>; + + fn on_slot(&mut self, chain_head: B::Header, slot_info: SlotInfo) -> Self::OnSlot { + >::on_slot(self, chain_head, slot_info) + } +} + +fn aura_err(error: Error) -> Error { + debug!(target: "aura", "{}", error); + error } -fn find_pre_digest(header: &B::Header) -> Result +#[derive(derive_more::Display)] +enum Error { + #[display(fmt = "Multiple Aura pre-runtime headers")] + MultipleHeaders, + #[display(fmt = "No Aura pre-runtime digest found")] + NoDigestFound, + #[display(fmt = "Header {:?} is unsealed", _0)] + HeaderUnsealed(B::Hash), + #[display(fmt = "Header {:?} has a bad seal", _0)] + HeaderBadSeal(B::Hash), + #[display(fmt = "Slot Author not found")] + SlotAuthorNotFound, + #[display(fmt = "Bad signature on {:?}", _0)] + BadSignature(B::Hash), + #[display(fmt = "Rejecting block too far in future")] + TooFarInFuture, + Client(client::error::Error), + DataProvider(String), + Runtime(RuntimeString) +} + +fn find_pre_digest(header: &B::Header) -> Result> where DigestItemFor: CompatibleDigestItem

, P::Signature: Decode, P::Public: Encode + Decode + PartialEq + Clone, @@ -376,21 +343,20 @@ fn find_pre_digest(header: &B::Header) -> Result Err(aura_err!("Multiple AuRa pre-runtime headers, rejecting!"))?, + (Some(_), true) => Err(aura_err(Error::MultipleHeaders))?, (None, _) => trace!(target: "aura", "Ignoring digest not meant for us"), (s, false) => pre_digest = s, } } - pre_digest.ok_or_else(|| aura_err!("No AuRa pre-runtime digest found")) + pre_digest.ok_or_else(|| aura_err(Error::NoDigestFound)) } - /// check a header has been signed by the right key. If the slot is too far in the future, an error will be returned. /// if it's successful, returns the pre-header and the digest item containing the seal. /// /// This digest item will always return `Some` when used with `as_aura_seal`. // -// FIXME #1018 needs misbehavior types. The `transaction_pool` parameter will be +// FIXME #1018 needs misbehavior types. The `transaction_pool` parameter will be // used to submit such misbehavior reports. fn check_header( client: &C, @@ -399,7 +365,7 @@ fn check_header( hash: B::Hash, authorities: &[AuthorityId

], _transaction_pool: Option<&T>, -) -> Result)>, String> where +) -> Result)>, Error> where DigestItemFor: CompatibleDigestItem

, P::Signature: Decode, C: client::backend::AuxStore, @@ -408,11 +374,11 @@ fn check_header( { let seal = match header.digest_mut().pop() { Some(x) => x, - None => return Err(format!("Header {:?} is unsealed", hash)), + None => return Err(Error::HeaderUnsealed(hash)), }; let sig = seal.as_aura_seal().ok_or_else(|| { - aura_err!("Header {:?} has a bad seal", hash) + aura_err(Error::HeaderBadSeal(hash)) })?; let slot_num = find_pre_digest::(&header)?; @@ -424,7 +390,7 @@ fn check_header( // check the signature is valid under the expected authority and // chain state. let expected_author = match slot_author::

(slot_num, &authorities) { - None => return Err("Slot Author not found".to_string()), + None => return Err(Error::SlotAuthorNotFound), Some(author) => author, }; @@ -437,7 +403,7 @@ fn check_header( slot_num, &header, expected_author, - ).map_err(|e| e.to_string())? { + ).map_err(Error::Client)? { info!( "Slot author is equivocating at slot {} with headers {:?} and {:?}", slot_num, @@ -448,7 +414,7 @@ fn check_header( Ok(CheckedHeader::Checked(header, (slot_num, seal))) } else { - Err(format!("Bad signature on {:?}", hash)) + Err(Error::BadSignature(hash)) } } } @@ -470,7 +436,7 @@ impl AuraVerifier block_id: BlockId, inherent_data: InherentData, timestamp_now: u64, - ) -> Result<(), String> + ) -> Result<(), Error> where C: ProvideRuntimeApi, C::Api: BlockBuilderApi { const MAX_TIMESTAMP_DRIFT_SECS: u64 = 60; @@ -479,7 +445,7 @@ impl AuraVerifier &block_id, block, inherent_data, - ).map_err(|e| format!("{:?}", e))?; + ).map_err(Error::Client)?; if !inherent_res.ok() { inherent_res @@ -489,7 +455,7 @@ impl AuraVerifier // halt import until timestamp is valid. // reject when too far ahead. if timestamp > timestamp_now + MAX_TIMESTAMP_DRIFT_SECS { - return Err("Rejecting block too far in future".into()); + return Err(Error::TooFarInFuture); } let diff = timestamp.saturating_sub(timestamp_now); @@ -504,8 +470,10 @@ impl AuraVerifier thread::sleep(Duration::from_secs(diff)); Ok(()) }, - Some(TIError::Other(e)) => Err(e.into()), - None => Err(self.inherent_data_providers.error_to_string(&i, &e)), + Some(TIError::Other(e)) => Err(Error::Runtime(e)), + None => Err(Error::DataProvider( + self.inherent_data_providers.error_to_string(&i, &e) + )), }) } else { Ok(()) @@ -548,7 +516,7 @@ impl Verifier for AuraVerifier where hash, &authorities[..], self.transaction_pool.as_ref().map(|x| &**x), - )?; + ).map_err(|e| e.to_string())?; match checked_header { CheckedHeader::Checked(pre_header, (slot_num, seal)) => { // if the body is passed through, we need to use the runtime @@ -569,7 +537,7 @@ impl Verifier for AuraVerifier where BlockId::Hash(parent_hash), inherent_data, timestamp_now, - )?; + ).map_err(|e| e.to_string())?; } let (_, inner_body) = block.deconstruct(); @@ -593,7 +561,7 @@ impl Verifier for AuraVerifier where _ => None, }); - let import_block = BlockImportParams { + let block_import_params = BlockImportParams { origin, header: pre_header, post_digests: vec![seal], @@ -604,7 +572,7 @@ impl Verifier for AuraVerifier where fork_choice: ForkChoiceStrategy::LongestChain, }; - Ok((import_block, maybe_keys)) + Ok((block_import_params, maybe_keys)) } CheckedHeader::Deferred(a, b) => { debug!(target: "aura", "Checking {:?} failed; {:?}, {:?}.", hash, a, b); @@ -633,7 +601,7 @@ fn initialize_authorities_cache(client: &C) -> Result<(), ConsensusErro let genesis_id = BlockId::Number(Zero::zero()); let genesis_authorities: Option> = cache .get_at(&well_known_cache_keys::AUTHORITIES, &genesis_id) - .and_then(|v| Decode::decode(&mut &v[..]).ok()); + .and_then(|(_, _, v)| Decode::decode(&mut &v[..]).ok()); if genesis_authorities.is_some() { return Ok(()); } @@ -661,7 +629,7 @@ fn authorities(client: &C, at: &BlockId) -> Result, Consensus .cache() .and_then(|cache| cache .get_at(&well_known_cache_keys::AUTHORITIES, at) - .and_then(|v| Decode::decode(&mut &v[..]).ok()) + .and_then(|(_, _, v)| Decode::decode(&mut &v[..]).ok()) ) .or_else(|| AuraApi::authorities(&*client.runtime_api(), at).ok()) .ok_or_else(|| consensus_common::Error::InvalidAuthoritiesSet.into()) @@ -732,7 +700,7 @@ mod tests { use parking_lot::Mutex; use tokio::runtime::current_thread; use keyring::sr25519::Keyring; - use client::{LongestChain, BlockchainEvents}; + use client::BlockchainEvents; use test_client; use aura_primitives::sr25519::AuthorityPair; @@ -792,11 +760,11 @@ mod tests { } } - fn make_verifier(&self, client: PeersClient, _cfg: &ProtocolConfig) + fn make_verifier(&self, client: PeersClient, _cfg: &ProtocolConfig, _peer_data: &()) -> Self::Verifier { match client { - PeersClient::Full(client) => { + PeersClient::Full(client, _) => { let slot_duration = SlotDuration::get_or_compute(&*client) .expect("slot duration available"); let inherent_data_providers = InherentDataProviders::new(); @@ -813,7 +781,7 @@ mod tests { phantom: Default::default(), } }, - PeersClient::Light(_) => unreachable!("No (yet) tests for light client + Aura"), + PeersClient::Light(_, _) => unreachable!("No (yet) tests for light client + Aura"), } } @@ -848,6 +816,10 @@ mod tests { let mut runtime = current_thread::Runtime::new().unwrap(); let mut keystore_paths = Vec::new(); for (peer_id, key) in peers { + let mut net = net.lock(); + let peer = net.peer(*peer_id); + let client = peer.client().as_full().expect("full clients are created").clone(); + let select_chain = peer.select_chain().expect("full client has a select chain"); let keystore_path = tempfile::tempdir().expect("Creates keystore path"); let keystore = keystore::Store::open(keystore_path.path(), None).expect("Creates keystore."); @@ -855,11 +827,6 @@ mod tests { .expect("Creates authority key"); keystore_paths.push(keystore_path); - let client = net.lock().peer(*peer_id).client().as_full().expect("full clients are created").clone(); - #[allow(deprecated)] - let select_chain = LongestChain::new( - client.backend().clone(), - ); let environ = DummyFactory(client.clone()); import_notifications.push( client.import_notification_stream() @@ -884,7 +851,7 @@ mod tests { DummyOracle, inherent_data_providers, false, - Some(keystore), + keystore, ).expect("Starts aura"); runtime.spawn(aura); diff --git a/core/consensus/babe/Cargo.toml b/core/consensus/babe/Cargo.toml index 9490887ba34bced36527613052f78164da18c1bb..e225c2503a0f6d054992cc273478c98f256de07a 100644 --- a/core/consensus/babe/Cargo.toml +++ b/core/consensus/babe/Cargo.toml @@ -10,9 +10,9 @@ codec = { package = "parity-scale-codec", version = "1.0.0", features = ["derive babe_primitives = { package = "substrate-consensus-babe-primitives", path = "primitives" } primitives = { package = "substrate-primitives", path = "../../primitives" } app-crypto = { package = "substrate-application-crypto", path = "../../application-crypto" } -num-bigint = "0.2" -num-rational = "0.2" -num-traits = "0.2" +num-bigint = "0.2.3" +num-rational = "0.2.2" +num-traits = "0.2.8" runtime-support = { package = "srml-support", path = "../../../srml/support" } runtime-version = { package = "sr-version", path = "../../sr-version" } runtime-io = { package = "sr-io", path = "../../sr-io" } @@ -21,19 +21,21 @@ substrate-telemetry = { path = "../../telemetry" } keystore = { package = "substrate-keystore", path = "../../keystore" } srml-babe = { path = "../../../srml/babe" } client = { package = "substrate-client", path = "../../client" } +header-metadata = { package = "substrate-header-metadata", path = "../../client/header-metadata" } consensus-common = { package = "substrate-consensus-common", path = "../common" } uncles = { package = "substrate-consensus-uncles", path = "../uncles" } slots = { package = "substrate-consensus-slots", path = "../slots" } sr-primitives = { path = "../../sr-primitives" } fork-tree = { path = "../../utils/fork-tree" } -futures-preview = { version = "=0.3.0-alpha.17", features = ["compat"] } +futures-preview = { version = "0.3.0-alpha.19", features = ["compat"] } futures01 = { package = "futures", version = "0.1" } -futures-timer = "0.2.1" +futures-timer = "0.4.0" parking_lot = "0.9.0" -log = "0.4.6" -schnorrkel = { version = "0.8.4", features = ["preaudit_deprecated"] } -rand = "0.6.5" -merlin = "1.0.3" +log = "0.4.8" +schnorrkel = { version = "0.8.5", features = ["preaudit_deprecated"] } +rand = "0.7.2" +merlin = "1.2.1" +pdqselect = "0.1.0" [dev-dependencies] keyring = { package = "substrate-keyring", path = "../../keyring" } @@ -41,9 +43,9 @@ substrate-executor = { path = "../../executor" } network = { package = "substrate-network", path = "../../network", features = ["test-helpers"]} service = { package = "substrate-service", path = "../../service" } test-client = { package = "substrate-test-runtime-client", path = "../../test-runtime/client" } -tokio = "0.1.18" -env_logger = "0.6.1" -tempfile = "3.1" +tokio = "0.1.22" +env_logger = "0.6.2" +tempfile = "3.1.0" [features] test-helpers = [] diff --git a/core/consensus/babe/primitives/Cargo.toml b/core/consensus/babe/primitives/Cargo.toml index 5f7fbe4fd812944ad992fd73b26b08e5bc35f49e..79e817d08102825456f5822199caa33de4deab75 100644 --- a/core/consensus/babe/primitives/Cargo.toml +++ b/core/consensus/babe/primitives/Cargo.toml @@ -11,7 +11,7 @@ rstd = { package = "sr-std", path = "../../../sr-std", default-features = false sr-primitives = { path = "../../../sr-primitives", default-features = false } app-crypto = { package = "substrate-application-crypto", path = "../../../application-crypto", default-features = false } slots = { package = "substrate-consensus-slots", path = "../../slots", optional = true } -schnorrkel = { version = "0.8.4", features = ["preaudit_deprecated"], optional = true } +schnorrkel = { version = "0.8.5", features = ["preaudit_deprecated"], optional = true } codec = { package = "parity-scale-codec", version = "1.0.0", default-features = false } [features] diff --git a/core/consensus/babe/primitives/src/digest.rs b/core/consensus/babe/primitives/src/digest.rs index 3b6e3221bd8a87ab5aa1fe399c4ba5e8edb44e5e..3f275ecdb6341e900069b5234a19a28c92cf4153 100644 --- a/core/consensus/babe/primitives/src/digest.rs +++ b/core/consensus/babe/primitives/src/digest.rs @@ -17,12 +17,10 @@ //! Private implementation details of BABE digests. #[cfg(feature = "std")] -use super::AuthoritySignature; -#[cfg(feature = "std")] -use super::{BABE_ENGINE_ID, Epoch}; +use super::{BABE_ENGINE_ID, AuthoritySignature}; #[cfg(not(feature = "std"))] use super::{VRF_OUTPUT_LENGTH, VRF_PROOF_LENGTH}; -use super::SlotNumber; +use super::{AuthorityId, AuthorityIndex, SlotNumber, BabeAuthorityWeight}; #[cfg(feature = "std")] use sr_primitives::{DigestItem, generic::OpaqueDigestItemId}; #[cfg(feature = "std")] @@ -35,19 +33,61 @@ use schnorrkel::{ SignatureError, errors::MultiSignatureStage, vrf::{VRFProof, VRFOutput, VRF_OUTPUT_LENGTH, VRF_PROOF_LENGTH} }; +use rstd::vec::Vec; + -/// A BABE pre-digest +/// A BABE pre-runtime digest. This contains all data required to validate a +/// block and for the BABE runtime module. Slots can be assigned to a primary +/// (VRF based) and to a secondary (slot number based). #[cfg(feature = "std")] #[derive(Clone, Debug)] -pub struct BabePreDigest { - /// VRF output - pub vrf_output: VRFOutput, - /// VRF proof - pub vrf_proof: VRFProof, - /// Authority index - pub authority_index: super::AuthorityIndex, - /// Slot number - pub slot_number: SlotNumber, +pub enum BabePreDigest { + /// A primary VRF-based slot assignment. + Primary { + /// VRF output + vrf_output: VRFOutput, + /// VRF proof + vrf_proof: VRFProof, + /// Authority index + authority_index: super::AuthorityIndex, + /// Slot number + slot_number: SlotNumber, + }, + /// A secondary deterministic slot assignment. + Secondary { + /// Authority index + authority_index: super::AuthorityIndex, + /// Slot number + slot_number: SlotNumber, + }, +} + +#[cfg(feature = "std")] +impl BabePreDigest { + /// Returns the slot number of the pre digest. + pub fn authority_index(&self) -> AuthorityIndex { + match self { + BabePreDigest::Primary { authority_index, .. } => *authority_index, + BabePreDigest::Secondary { authority_index, .. } => *authority_index, + } + } + + /// Returns the slot number of the pre digest. + pub fn slot_number(&self) -> SlotNumber { + match self { + BabePreDigest::Primary { slot_number, .. } => *slot_number, + BabePreDigest::Secondary { slot_number, .. } => *slot_number, + } + } + + /// Returns the weight _added_ by this digest, not the cumulative weight + /// of the chain. + pub fn added_weight(&self) -> crate::BabeBlockWeight { + match self { + BabePreDigest::Primary { .. } => 1, + BabePreDigest::Secondary { .. } => 0, + } + } } /// The prefix used by BABE for its VRF keys. @@ -55,27 +95,73 @@ pub const BABE_VRF_PREFIX: &'static [u8] = b"substrate-babe-vrf"; /// A raw version of `BabePreDigest`, usable on `no_std`. #[derive(Copy, Clone, Encode, Decode)] -pub struct RawBabePreDigest { - /// Slot number - pub slot_number: SlotNumber, - /// Authority index - pub authority_index: super::AuthorityIndex, - /// VRF output - pub vrf_output: [u8; VRF_OUTPUT_LENGTH], - /// VRF proof - pub vrf_proof: [u8; VRF_PROOF_LENGTH], +pub enum RawBabePreDigest { + /// A primary VRF-based slot assignment. + #[codec(index = "1")] + Primary { + /// Authority index + authority_index: AuthorityIndex, + /// Slot number + slot_number: SlotNumber, + /// VRF output + vrf_output: [u8; VRF_OUTPUT_LENGTH], + /// VRF proof + vrf_proof: [u8; VRF_PROOF_LENGTH], + }, + /// A secondary deterministic slot assignment. + #[codec(index = "2")] + Secondary { + /// Authority index + /// + /// This is not strictly-speaking necessary, since the secondary slots + /// are assigned based on slot number and epoch randomness. But including + /// it makes things easier for higher-level users of the chain data to + /// be aware of the author of a secondary-slot block. + authority_index: AuthorityIndex, + /// Slot number + slot_number: SlotNumber, + }, +} + +impl RawBabePreDigest { + /// Returns the slot number of the pre digest. + pub fn slot_number(&self) -> SlotNumber { + match self { + RawBabePreDigest::Primary { slot_number, .. } => *slot_number, + RawBabePreDigest::Secondary { slot_number, .. } => *slot_number, + } + } } #[cfg(feature = "std")] impl Encode for BabePreDigest { fn encode(&self) -> Vec { - let tmp = RawBabePreDigest { - vrf_output: *self.vrf_output.as_bytes(), - vrf_proof: self.vrf_proof.to_bytes(), - authority_index: self.authority_index, - slot_number: self.slot_number, + let raw = match self { + BabePreDigest::Primary { + vrf_output, + vrf_proof, + authority_index, + slot_number, + } => { + RawBabePreDigest::Primary { + vrf_output: *vrf_output.as_bytes(), + vrf_proof: vrf_proof.to_bytes(), + authority_index: *authority_index, + slot_number: *slot_number, + } + }, + BabePreDigest::Secondary { + authority_index, + slot_number, + } => { + RawBabePreDigest::Secondary { + authority_index: *authority_index, + slot_number: *slot_number, + } + }, }; - codec::Encode::encode(&tmp) + + codec::Encode::encode(&raw) } } @@ -85,22 +171,40 @@ impl codec::EncodeLike for BabePreDigest {} #[cfg(feature = "std")] impl Decode for BabePreDigest { fn decode(i: &mut R) -> Result { - let RawBabePreDigest { vrf_output, vrf_proof, authority_index, slot_number } = Decode::decode(i)?; - - // Verify (at compile time) that the sizes in babe_primitives are correct - let _: [u8; super::VRF_OUTPUT_LENGTH] = vrf_output; - let _: [u8; super::VRF_PROOF_LENGTH] = vrf_proof; - Ok(BabePreDigest { - vrf_proof: VRFProof::from_bytes(&vrf_proof) - .map_err(convert_error)?, - vrf_output: VRFOutput::from_bytes(&vrf_output) - .map_err(convert_error)?, - authority_index, - slot_number, - }) + let pre_digest = match Decode::decode(i)? { + RawBabePreDigest::Primary { vrf_output, vrf_proof, authority_index, slot_number } => { + // Verify (at compile time) that the sizes in babe_primitives are correct + let _: [u8; super::VRF_OUTPUT_LENGTH] = vrf_output; + let _: [u8; super::VRF_PROOF_LENGTH] = vrf_proof; + + BabePreDigest::Primary { + vrf_proof: VRFProof::from_bytes(&vrf_proof).map_err(convert_error)?, + vrf_output: VRFOutput::from_bytes(&vrf_output).map_err(convert_error)?, + authority_index, + slot_number, + } + }, + RawBabePreDigest::Secondary { authority_index, slot_number } => { + BabePreDigest::Secondary { authority_index, slot_number } + }, + }; + + Ok(pre_digest) } } +/// Information about the next epoch. This is broadcast in the first block +/// of the epoch. +#[derive(Decode, Encode, Default, PartialEq, Eq, Clone)] +#[cfg_attr(any(feature = "std", test), derive(Debug))] +pub struct NextEpochDescriptor { + /// The authorities. + pub authorities: Vec<(AuthorityId, BabeAuthorityWeight)>, + + /// The value of randomness to use for the slot-assignment. + pub randomness: [u8; VRF_OUTPUT_LENGTH], +} + /// A digest item which is usable with BABE consensus. #[cfg(feature = "std")] pub trait CompatibleDigestItem: Sized { @@ -117,7 +221,7 @@ pub trait CompatibleDigestItem: Sized { fn as_babe_seal(&self) -> Option; /// If this item is a BABE epoch, return it. - fn as_babe_epoch(&self) -> Option; + fn as_next_epoch_descriptor(&self) -> Option; } #[cfg(feature = "std")] @@ -140,8 +244,12 @@ impl CompatibleDigestItem for DigestItem where self.try_to(OpaqueDigestItemId::Seal(&BABE_ENGINE_ID)) } - fn as_babe_epoch(&self) -> Option { + fn as_next_epoch_descriptor(&self) -> Option { self.try_to(OpaqueDigestItemId::Consensus(&BABE_ENGINE_ID)) + .and_then(|x: super::ConsensusLog| match x { + super::ConsensusLog::NextEpochData(n) => Some(n), + _ => None, + }) } } diff --git a/core/consensus/babe/primitives/src/lib.rs b/core/consensus/babe/primitives/src/lib.rs index f4da908080c8b524112827ba935fde7d1c8f1ac5..1293b7c8baa0027bc65b61419562b80c5d50f1e5 100644 --- a/core/consensus/babe/primitives/src/lib.rs +++ b/core/consensus/babe/primitives/src/lib.rs @@ -28,7 +28,7 @@ use substrate_client::decl_runtime_apis; #[cfg(feature = "std")] pub use digest::{BabePreDigest, CompatibleDigestItem}; -pub use digest::{BABE_VRF_PREFIX, RawBabePreDigest}; +pub use digest::{BABE_VRF_PREFIX, RawBabePreDigest, NextEpochDescriptor}; mod app { use app_crypto::{app_crypto, key_types::BABE, sr25519}; @@ -59,6 +59,11 @@ pub const VRF_PROOF_LENGTH: usize = 64; /// The length of the public key pub const PUBLIC_KEY_LENGTH: usize = 32; +/// How many blocks to wait before running the median algorithm for relative time +/// This will not vary from chain to chain as it is not dependent on slot duration +/// or epoch length. +pub const MEDIAN_ALGORITHM_CARDINALITY: usize = 1200; // arbitrary suggestion by w3f-research. + /// The index of an authority. pub type AuthorityIndex = u32; @@ -68,7 +73,10 @@ pub type SlotNumber = u64; /// The weight of an authority. // NOTE: we use a unique name for the weight to avoid conflicts with other // `Weight` types, since the metadata isn't able to disambiguate. -pub type BabeWeight = u64; +pub type BabeAuthorityWeight = u64; + +/// The weight of a BABE block. +pub type BabeBlockWeight = u32; /// BABE epoch information #[derive(Decode, Encode, Default, PartialEq, Eq, Clone)] @@ -77,31 +85,50 @@ pub struct Epoch { /// The epoch index pub epoch_index: u64, /// The starting slot of the epoch, - pub start_slot: u64, + pub start_slot: SlotNumber, /// The duration of this epoch pub duration: SlotNumber, /// The authorities and their weights - pub authorities: Vec<(AuthorityId, BabeWeight)>, + pub authorities: Vec<(AuthorityId, BabeAuthorityWeight)>, /// Randomness for this epoch pub randomness: [u8; VRF_OUTPUT_LENGTH], } +impl Epoch { + /// "increment" the epoch, with given descriptor for the next. + pub fn increment(&self, descriptor: NextEpochDescriptor) -> Epoch { + Epoch { + epoch_index: self.epoch_index + 1, + start_slot: self.start_slot + self.duration, + duration: self.duration, + authorities: descriptor.authorities, + randomness: descriptor.randomness, + } + } + + /// Produce the "end slot" of the epoch. This is NOT inclusive to the epoch, + // i.e. the slots covered by the epoch are `self.start_slot .. self.end_slot()`. + pub fn end_slot(&self) -> SlotNumber { + self.start_slot + self.duration + } +} + /// An consensus log item for BABE. #[derive(Decode, Encode, Clone, PartialEq, Eq)] pub enum ConsensusLog { - /// The epoch has changed. This provides information about the - /// epoch _after_ next: what slot number it will start at, who are the authorities (and their weights) - /// and the next epoch randomness. The information for the _next_ epoch should already - /// be available. + /// The epoch has changed. This provides information about the _next_ + /// epoch - information about the _current_ epoch (i.e. the one we've just + /// entered) should already be available earlier in the chain. #[codec(index = "1")] - NextEpochData(Epoch), + NextEpochData(NextEpochDescriptor), /// Disable the authority with given index. #[codec(index = "2")] OnDisabled(AuthorityIndex), } /// Configuration data used by the BABE consensus engine. -#[derive(Copy, Clone, Hash, PartialEq, Eq, Debug, Encode, Decode)] +#[derive(Clone, PartialEq, Eq, Encode, Decode)] +#[cfg_attr(any(feature = "std", test), derive(Debug))] pub struct BabeConfiguration { /// The slot duration in milliseconds for BABE. Currently, only /// the value provided by this type at genesis will be used. @@ -109,35 +136,35 @@ pub struct BabeConfiguration { /// Dynamic slot duration may be supported in the future. pub slot_duration: u64, + /// The duration of epochs in slots. + pub epoch_length: SlotNumber, + /// A constant value that is used in the threshold calculation formula. - /// Expressed as a fraction where the first member of the tuple is the - /// numerator and the second is the denominator. The fraction should + /// Expressed as a rational where the first member of the tuple is the + /// numerator and the second is the denominator. The rational should /// represent a value between 0 and 1. /// In the threshold formula calculation, `1 - c` represents the probability /// of a slot being empty. pub c: (u64, u64), - /// The minimum number of blocks that must be received before running the - /// median algorithm to compute the offset between the on-chain time and the - /// local time. Currently, only the value provided by this type at genesis - /// will be used, but this is subject to change. - /// - /// Blocks less than `self.median_required_blocks` must be generated by an - /// *initial validator* ― that is, a node that was a validator at genesis. - pub median_required_blocks: u64, + /// The authorities for the genesis epoch. + pub genesis_authorities: Vec<(AuthorityId, BabeAuthorityWeight)>, + + /// The randomness for the genesis epoch. + pub randomness: [u8; VRF_OUTPUT_LENGTH], + + /// Whether this chain should run with secondary slots, which are assigned + /// in round-robin manner. + pub secondary_slots: bool, } #[cfg(feature = "std")] impl slots::SlotData for BabeConfiguration { - /// Return the slot duration in milliseconds for BABE. Currently, only - /// the value provided by this type at genesis will be used. - /// - /// Dynamic slot duration may be supported in the future. fn slot_duration(&self) -> u64 { self.slot_duration } - const SLOT_KEY: &'static [u8] = b"babe_bootstrap_data"; + const SLOT_KEY: &'static [u8] = b"babe_configuration"; } decl_runtime_apis! { @@ -147,9 +174,6 @@ decl_runtime_apis! { /// only the value provided by this type at genesis will be used. /// /// Dynamic configuration may be supported in the future. - fn startup_data() -> BabeConfiguration; - - /// Get the current epoch data for Babe. - fn epoch() -> Epoch; + fn configuration() -> BabeConfiguration; } } diff --git a/core/consensus/babe/src/authorship.rs b/core/consensus/babe/src/authorship.rs new file mode 100644 index 0000000000000000000000000000000000000000..93405ff7776e62c739a07212594ffac540fa1eea --- /dev/null +++ b/core/consensus/babe/src/authorship.rs @@ -0,0 +1,214 @@ +// Copyright 2019 Parity Technologies (UK) Ltd. +// This file is part of Substrate. + +// Substrate 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. + +// Substrate 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 Substrate. If not, see . + +//! BABE authority selection and slot claiming. + +use merlin::Transcript; +use babe_primitives::{AuthorityId, BabeAuthorityWeight, BABE_ENGINE_ID, BABE_VRF_PREFIX}; +use babe_primitives::{Epoch, SlotNumber, AuthorityPair, BabePreDigest, BabeConfiguration}; +use primitives::{U256, blake2_256}; +use codec::Encode; +use schnorrkel::vrf::VRFInOut; +use primitives::Pair; +use keystore::KeyStorePtr; + +/// Calculates the primary selection threshold for a given authority, taking +/// into account `c` (`1 - c` represents the probability of a slot being empty). +pub(super) fn calculate_primary_threshold( + c: (u64, u64), + authorities: &[(AuthorityId, BabeAuthorityWeight)], + authority_index: usize, +) -> u128 { + use num_bigint::BigUint; + use num_rational::BigRational; + use num_traits::{cast::ToPrimitive, identities::One}; + + let c = c.0 as f64 / c.1 as f64; + + let theta = + authorities[authority_index].1 as f64 / + authorities.iter().map(|(_, weight)| weight).sum::() as f64; + + let calc = || { + let p = BigRational::from_float(1f64 - (1f64 - c).powf(theta))?; + let numer = p.numer().to_biguint()?; + let denom = p.denom().to_biguint()?; + ((BigUint::one() << 128) * numer / denom).to_u128() + }; + + calc().unwrap_or(u128::max_value()) +} + +/// Returns true if the given VRF output is lower than the given threshold, +/// false otherwise. +pub(super) fn check_primary_threshold(inout: &VRFInOut, threshold: u128) -> bool { + u128::from_le_bytes(inout.make_bytes::<[u8; 16]>(BABE_VRF_PREFIX)) < threshold +} + +/// Get the expected secondary author for the given slot and with given +/// authorities. This should always assign the slot to some authority unless the +/// authorities list is empty. +pub(super) fn secondary_slot_author( + slot_number: u64, + authorities: &[(AuthorityId, BabeAuthorityWeight)], + randomness: [u8; 32], +) -> Option<&AuthorityId> { + if authorities.is_empty() { + return None; + } + + let rand = U256::from((randomness, slot_number).using_encoded(blake2_256)); + + let authorities_len = U256::from(authorities.len()); + let idx = rand % authorities_len; + + let expected_author = authorities.get(idx.as_u32() as usize) + .expect("authorities not empty; index constrained to list length; \ + this is a valid index; qed"); + + Some(&expected_author.0) +} + +#[allow(deprecated)] +pub(super) fn make_transcript( + randomness: &[u8], + slot_number: u64, + epoch: u64, +) -> Transcript { + let mut transcript = Transcript::new(&BABE_ENGINE_ID); + transcript.commit_bytes(b"slot number", &slot_number.to_le_bytes()); + transcript.commit_bytes(b"current epoch", &epoch.to_le_bytes()); + transcript.commit_bytes(b"chain randomness", randomness); + transcript +} + + +/// Claim a secondary slot if it is our turn to propose, returning the +/// pre-digest to use when authoring the block, or `None` if it is not our turn +/// to propose. +fn claim_secondary_slot( + slot_number: SlotNumber, + authorities: &[(AuthorityId, BabeAuthorityWeight)], + keystore: &KeyStorePtr, + randomness: [u8; 32], +) -> Option<(BabePreDigest, AuthorityPair)> { + if authorities.is_empty() { + return None; + } + + let expected_author = super::authorship::secondary_slot_author( + slot_number, + authorities, + randomness, + )?; + + let keystore = keystore.read(); + + for (pair, authority_index) in authorities.iter() + .enumerate() + .flat_map(|(i, a)| { + keystore.key_pair::(&a.0).ok().map(|kp| (kp, i)) + }) + { + if pair.public() == *expected_author { + let pre_digest = BabePreDigest::Secondary { + slot_number, + authority_index: authority_index as u32, + }; + + return Some((pre_digest, pair)); + } + } + + None +} + +/// Tries to claim the given slot number. This method starts by trying to claim +/// a primary VRF based slot. If we are not able to claim it, then if we have +/// secondary slots enabled for the given epoch, we will fallback to trying to +/// claim a secondary slot. +pub(super) fn claim_slot( + slot_number: SlotNumber, + epoch: &Epoch, + config: &BabeConfiguration, + keystore: &KeyStorePtr, +) -> Option<(BabePreDigest, AuthorityPair)> { + claim_primary_slot(slot_number, epoch, config.c, keystore) + .or_else(|| { + if config.secondary_slots { + claim_secondary_slot( + slot_number, + &epoch.authorities, + keystore, + epoch.randomness, + ) + } else { + None + } + }) +} + +fn get_keypair(q: &AuthorityPair) -> &schnorrkel::Keypair { + use primitives::crypto::IsWrappedBy; + primitives::sr25519::Pair::from_ref(q).as_ref() +} + +/// Claim a primary slot if it is our turn. Returns `None` if it is not our turn. +/// This hashes the slot number, epoch, genesis hash, and chain randomness into +/// the VRF. If the VRF produces a value less than `threshold`, it is our turn, +/// so it returns `Some(_)`. Otherwise, it returns `None`. +fn claim_primary_slot( + slot_number: SlotNumber, + epoch: &Epoch, + c: (u64, u64), + keystore: &KeyStorePtr, +) -> Option<(BabePreDigest, AuthorityPair)> { + let Epoch { authorities, randomness, epoch_index, .. } = epoch; + let keystore = keystore.read(); + + for (pair, authority_index) in authorities.iter() + .enumerate() + .flat_map(|(i, a)| { + keystore.key_pair::(&a.0).ok().map(|kp| (kp, i)) + }) + { + let transcript = super::authorship::make_transcript(randomness, slot_number, *epoch_index); + + // Compute the threshold we will use. + // + // We already checked that authorities contains `key.public()`, so it can't + // be empty. Therefore, this division in `calculate_threshold` is safe. + let threshold = super::authorship::calculate_primary_threshold(c, authorities, authority_index); + + let pre_digest = get_keypair(&pair) + .vrf_sign_after_check(transcript, |inout| super::authorship::check_primary_threshold(inout, threshold)) + .map(|s| { + BabePreDigest::Primary { + slot_number, + vrf_output: s.0.to_output(), + vrf_proof: s.1, + authority_index: authority_index as u32, + } + }); + + // early exit on first successful claim + if let Some(pre_digest) = pre_digest { + return Some((pre_digest, pair)); + } + } + + None +} diff --git a/core/consensus/babe/src/aux_schema.rs b/core/consensus/babe/src/aux_schema.rs index ac90b4ce52dc4357ab64f62e044ecde5004321c3..67f61050fa31a6bcb059e8b7b61ae76666de40e5 100644 --- a/core/consensus/babe/src/aux_schema.rs +++ b/core/consensus/babe/src/aux_schema.rs @@ -22,11 +22,16 @@ use codec::{Decode, Encode}; use client::backend::AuxStore; use client::error::{Result as ClientResult, Error as ClientError}; use sr_primitives::traits::Block as BlockT; +use babe_primitives::BabeBlockWeight; -use super::{EpochChanges, SharedEpochChanges}; +use super::{epoch_changes::EpochChangesFor, SharedEpochChanges}; const BABE_EPOCH_CHANGES: &[u8] = b"babe_epoch_changes"; +fn block_weight_key(block_hash: H) -> Vec { + (b"block_weight", block_hash).encode() +} + fn load_decode(backend: &B, key: &[u8]) -> ClientResult> where B: AuxStore, @@ -45,7 +50,7 @@ fn load_decode(backend: &B, key: &[u8]) -> ClientResult> pub(crate) fn load_epoch_changes( backend: &B, ) -> ClientResult> { - let epoch_changes = load_decode::<_, EpochChanges>(backend, BABE_EPOCH_CHANGES)? + let epoch_changes = load_decode::<_, EpochChangesFor>(backend, BABE_EPOCH_CHANGES)? .map(Into::into) .unwrap_or_else(|| { info!(target: "babe", @@ -59,7 +64,7 @@ pub(crate) fn load_epoch_changes( /// Update the epoch changes on disk after a change. pub(crate) fn write_epoch_changes( - epoch_changes: &EpochChanges, + epoch_changes: &EpochChangesFor, write_aux: F, ) -> R where F: FnOnce(&[(&'static [u8], &[u8])]) -> R, @@ -69,3 +74,28 @@ pub(crate) fn write_epoch_changes( &[(BABE_EPOCH_CHANGES, encoded_epoch_changes.as_slice())], ) } + +/// Write the cumulative chain-weight of a block ot aux storage. +pub(crate) fn write_block_weight( + block_hash: H, + block_weight: &BabeBlockWeight, + write_aux: F, +) -> R where + F: FnOnce(&[(Vec, &[u8])]) -> R, +{ + + let key = block_weight_key(block_hash); + block_weight.using_encoded(|s| + write_aux( + &[(key, s)], + ) + ) +} + +/// Load the cumulative chain-weight associated with a block. +pub(crate) fn load_block_weight( + backend: &B, + block_hash: H, +) -> ClientResult> { + load_decode(backend, block_weight_key(block_hash).as_slice()) +} diff --git a/core/consensus/babe/src/epoch_changes.rs b/core/consensus/babe/src/epoch_changes.rs new file mode 100644 index 0000000000000000000000000000000000000000..09a14d286426d966c145f160a52816eca05427eb --- /dev/null +++ b/core/consensus/babe/src/epoch_changes.rs @@ -0,0 +1,656 @@ +// Copyright 2019 Parity Technologies (UK) Ltd. +// This file is part of Substrate. + +// Substrate 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. + +// Substrate 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 Substrate. If not, see . + +//! Handling epoch changes in BABE. +//! +//! This exposes the `SharedEpochChanges`, which is a wrapper around a +//! persistent DAG superimposed over the forks of the blockchain. + +use std::sync::Arc; +use babe_primitives::{Epoch, SlotNumber, NextEpochDescriptor}; +use fork_tree::ForkTree; +use parking_lot::{Mutex, MutexGuard}; +use sr_primitives::traits::{Block as BlockT, NumberFor, One, Zero}; +use codec::{Encode, Decode}; +use client::error::Error as ClientError; +use client::utils as client_utils; +use client::blockchain::HeaderBackend; +use header_metadata::HeaderMetadata; +use primitives::H256; +use std::ops::Add; + +/// A builder for `is_descendent_of` functions. +pub trait IsDescendentOfBuilder { + /// The error returned by the function. + type Error: std::error::Error; + /// A function that can tell you if the second parameter is a descendent of + /// the first. + type IsDescendentOf: Fn(&Hash, &Hash) -> Result; + + /// Build an `is_descendent_of` function. + /// + /// The `current` parameter can be `Some` with the details a fresh block whose + /// details aren't yet stored, but its parent is. + /// + /// The format of `current` when `Some` is `(current, current_parent)`. + fn build_is_descendent_of(&self, current: Option<(Hash, Hash)>) + -> Self::IsDescendentOf; +} + +/// Produce a descendent query object given the client. +pub(crate) fn descendent_query(client: &H) -> HeaderBackendDescendentBuilder<&H, Block> { + HeaderBackendDescendentBuilder(client, std::marker::PhantomData) +} + +/// Wrapper to get around unconstrained type errors when implementing +/// `IsDescendentOfBuilder` for header backends. +pub(crate) struct HeaderBackendDescendentBuilder(H, std::marker::PhantomData); + +// TODO: relying on Hash = H256 is awful. +// https://github.com/paritytech/substrate/issues/3624 +impl<'a, H, Block> IsDescendentOfBuilder + for HeaderBackendDescendentBuilder<&'a H, Block> where + H: HeaderBackend + HeaderMetadata, + Block: BlockT, +{ + type Error = ClientError; + type IsDescendentOf = Box Result + 'a>; + + fn build_is_descendent_of(&self, current: Option<(H256, H256)>) + -> Self::IsDescendentOf + { + Box::new(client_utils::is_descendent_of(self.0, current)) + } +} + +/// An unimported genesis epoch. +pub struct UnimportedGenesis(Epoch); + +/// The viable epoch under which a block can be verified. +/// +/// If this is the first non-genesis block in the chain, then it will +/// hold an `UnimportedGenesis` epoch. +pub enum ViableEpoch { + Genesis(UnimportedGenesis), + Regular(Epoch), +} + +impl From for ViableEpoch { + fn from(epoch: Epoch) -> ViableEpoch { + ViableEpoch::Regular(epoch) + } +} + +impl AsRef for ViableEpoch { + fn as_ref(&self) -> &Epoch { + match *self { + ViableEpoch::Genesis(UnimportedGenesis(ref e)) => e, + ViableEpoch::Regular(ref e) => e, + } + } +} + +impl ViableEpoch { + /// Extract the underlying epoch, disregarding the fact that a genesis + /// epoch may be unimported. + pub fn into_inner(self) -> Epoch { + match self { + ViableEpoch::Genesis(UnimportedGenesis(e)) => e, + ViableEpoch::Regular(e) => e, + } + } + + /// Increment the epoch, yielding an `IncrementedEpoch` to be imported + /// into the fork-tree. + pub fn increment(&self, next_descriptor: NextEpochDescriptor) -> IncrementedEpoch { + let next = self.as_ref().increment(next_descriptor); + let to_persist = match *self { + ViableEpoch::Genesis(UnimportedGenesis(ref epoch_0)) => + PersistedEpoch::Genesis(epoch_0.clone(), next), + ViableEpoch::Regular(_) => PersistedEpoch::Regular(next), + }; + + IncrementedEpoch(to_persist) + } +} + +/// The datatype encoded on disk. +// This really shouldn't be public, but the encode/decode derives force it to be. +#[derive(Clone, Encode, Decode)] +pub enum PersistedEpoch { + // epoch_0, epoch_1, + Genesis(Epoch, Epoch), + // epoch_n + Regular(Epoch), +} + +/// A fresh, incremented epoch to import into the underlying fork-tree. +/// +/// Create this with `ViableEpoch::increment`. +#[must_use = "Freshly-incremented epoch must be imported with `EpochChanges::import`"] +pub struct IncrementedEpoch(PersistedEpoch); + +impl AsRef for IncrementedEpoch { + fn as_ref(&self) -> &Epoch { + match self.0 { + PersistedEpoch::Genesis(_, ref epoch_1) => epoch_1, + PersistedEpoch::Regular(ref epoch_n) => epoch_n, + } + } +} + +/// Tree of all epoch changes across all *seen* forks. Data stored in tree is +/// the hash and block number of the block signaling the epoch change, and the +/// epoch that was signalled at that block. +/// +/// BABE special-cases the first epoch, epoch_0, by saying that it starts at +/// slot number of the first block in the chain. When bootstrapping a chain, +/// there can be multiple competing block #1s, so we have to ensure that the overlayed +/// DAG doesn't get confused. +/// +/// The first block of every epoch should be producing a descriptor for the next +/// epoch - this is checked in higher-level code. So the first block of epoch_0 contains +/// a descriptor for epoch_1. We special-case these and bundle them together in the +/// same DAG entry, pinned to a specific block #1. +/// +/// Further epochs (epoch_2, ..., epoch_n) each get their own entry. +#[derive(Clone, Encode, Decode)] +pub struct EpochChanges { + inner: ForkTree, +} + +// create a fake header hash which hasn't been included in the chain. +fn fake_head_hash + AsMut<[u8]> + Clone>(parent_hash: &H) -> H { + let mut h = parent_hash.clone(); + // dirty trick: flip the first bit of the parent hash to create a hash + // which has not been in the chain before (assuming a strong hash function). + h.as_mut()[0] ^= 0b10000000; + h +} + +impl EpochChanges where + Hash: PartialEq + AsRef<[u8]> + AsMut<[u8]> + Copy, + Number: Ord + One + Zero + Add + Copy, +{ + /// Create a new epoch-change tracker. + fn new() -> Self { + EpochChanges { inner: ForkTree::new() } + } + + /// Prune out finalized epochs, except for the ancestor of the finalized + /// block. The given slot should be the slot number at which the finalized + /// block was authored. + pub fn prune_finalized>( + &mut self, + descendent_of_builder: D, + hash: &Hash, + number: Number, + slot: SlotNumber, + ) -> Result<(), fork_tree::Error> { + let is_descendent_of = descendent_of_builder + .build_is_descendent_of(None); + + let predicate = |epoch: &PersistedEpoch| match *epoch { + PersistedEpoch::Genesis(_, ref epoch_1) => + slot >= epoch_1.end_slot(), + PersistedEpoch::Regular(ref epoch_n) => + slot >= epoch_n.end_slot(), + }; + + // prune any epochs which could not be _live_ as of the children of the + // finalized block, i.e. re-root the fork tree to the oldest ancestor of + // (hash, number) where epoch.end_slot() >= finalized_slot + self.inner.prune( + hash, + &number, + &is_descendent_of, + &predicate, + )?; + + Ok(()) + } + + /// Finds the epoch for a child of the given block, assuming the given slot number. + /// + /// If the returned epoch is an `UnimportedGenesis` epoch, it should be imported into the + /// tree. + pub fn epoch_for_child_of, G>( + &self, + descendent_of_builder: D, + parent_hash: &Hash, + parent_number: Number, + slot_number: SlotNumber, + make_genesis: G, + ) -> Result, fork_tree::Error> + where G: FnOnce(SlotNumber) -> Epoch + { + // find_node_where will give you the node in the fork-tree which is an ancestor + // of the `parent_hash` by default. if the last epoch was signalled at the parent_hash, + // then it won't be returned. we need to create a new fake chain head hash which + // "descends" from our parent-hash. + let fake_head_hash = fake_head_hash(parent_hash); + + let is_descendent_of = descendent_of_builder + .build_is_descendent_of(Some((fake_head_hash, *parent_hash))); + + if parent_number == Zero::zero() { + // need to insert the genesis epoch. + let genesis_epoch = make_genesis(slot_number); + return Ok(Some(ViableEpoch::Genesis(UnimportedGenesis(genesis_epoch)))); + } + + // We want to find the deepest node in the tree which is an ancestor + // of our block and where the start slot of the epoch was before the + // slot of our block. The genesis special-case doesn't need to look + // at epoch_1 -- all we're doing here is figuring out which node + // we need. + let predicate = |epoch: &PersistedEpoch| match *epoch { + PersistedEpoch::Genesis(ref epoch_0, _) => + epoch_0.start_slot <= slot_number, + PersistedEpoch::Regular(ref epoch_n) => + epoch_n.start_slot <= slot_number, + }; + + self.inner.find_node_where( + &fake_head_hash, + &(parent_number + One::one()), + &is_descendent_of, + &predicate, + ) + .map(|n| n.map(|node| ViableEpoch::Regular(match node.data { + // Ok, we found our node. + // and here we figure out which of the internal epochs + // of a genesis node to use based on their start slot. + PersistedEpoch::Genesis(ref epoch_0, ref epoch_1) => + if epoch_1.start_slot <= slot_number { + epoch_1.clone() + } else { + epoch_0.clone() + }, + PersistedEpoch::Regular(ref epoch_n) => epoch_n.clone(), + }))) + } + + /// Import a new epoch-change, signalled at the given block. + /// + /// This assumes that the given block is prospective (i.e. has not been + /// imported yet), but its parent has. This is why the parent hash needs + /// to be provided. + pub fn import>( + &mut self, + descendent_of_builder: D, + hash: Hash, + number: Number, + parent_hash: Hash, + epoch: IncrementedEpoch, + ) -> Result<(), fork_tree::Error> { + let is_descendent_of = descendent_of_builder + .build_is_descendent_of(Some((hash, parent_hash))); + + let res = self.inner.import( + hash, + number, + epoch.0, + &is_descendent_of, + ); + + match res { + Ok(_) | Err(fork_tree::Error::Duplicate) => Ok(()), + Err(e) => Err(e), + } + } + + /// Return the inner fork tree, useful for testing purposes. + #[cfg(test)] + pub fn tree(&self) -> &ForkTree { + &self.inner + } +} + +/// Type alias to produce the epoch-changes tree from a block type. +pub type EpochChangesFor = EpochChanges<::Hash, NumberFor>; + +/// A shared epoch changes tree. +#[derive(Clone)] +pub struct SharedEpochChanges { + inner: Arc>>, +} + +impl SharedEpochChanges { + /// Create a new instance of the `SharedEpochChanges`. + pub fn new() -> Self { + SharedEpochChanges { + inner: Arc::new(Mutex::new(EpochChanges::<_, _>::new())) + } + } + + /// Lock the shared epoch changes, + pub fn lock(&self) -> MutexGuard> { + self.inner.lock() + } +} + +impl From> for SharedEpochChanges { + fn from(epoch_changes: EpochChangesFor) -> Self { + SharedEpochChanges { + inner: Arc::new(Mutex::new(epoch_changes)) + } + } +} + +#[cfg(test)] +mod tests { + use super::*; + + #[derive(Debug, PartialEq)] + pub struct TestError; + + impl std::fmt::Display for TestError { + fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { + write!(f, "TestError") + } + } + + impl std::error::Error for TestError {} + + impl<'a, F: 'a , H: 'a + PartialEq + std::fmt::Debug> IsDescendentOfBuilder for &'a F + where F: Fn(&H, &H) -> Result + { + type Error = TestError; + type IsDescendentOf = Box Result + 'a>; + + fn build_is_descendent_of(&self, current: Option<(H, H)>) + -> Self::IsDescendentOf + { + let f = *self; + Box::new(move |base, head| { + let mut head = head; + + if let Some((ref c_head, ref c_parent)) = current { + if head == c_head { + if base == c_parent { + return Ok(true); + } else { + head = c_parent; + } + } + } + + f(base, head) + }) + } + } + + type Hash = [u8; 1]; + + #[test] + fn genesis_epoch_is_created_but_not_imported() { + // + // A - B + // \ + // — C + // + let is_descendent_of = |base: &Hash, block: &Hash| -> Result { + match (base, *block) { + (b"A", b) => Ok(b == *b"B" || b == *b"C" || b == *b"D"), + (b"B", b) | (b"C", b) => Ok(b == *b"D"), + (b"0", _) => Ok(true), + _ => Ok(false), + } + }; + + let make_genesis = |slot| Epoch { + epoch_index: 0, + start_slot: slot, + duration: 100, + authorities: Vec::new(), + randomness: [0; 32], + }; + + let epoch_changes = EpochChanges::new(); + let genesis_epoch = epoch_changes.epoch_for_child_of( + &is_descendent_of, + b"0", + 0, + 10101, + &make_genesis, + ).unwrap().unwrap(); + + match genesis_epoch { + ViableEpoch::Genesis(_) => {}, + _ => panic!("should be unimported genesis"), + }; + assert_eq!(genesis_epoch.as_ref(), &make_genesis(10101)); + + let genesis_epoch_2 = epoch_changes.epoch_for_child_of( + &is_descendent_of, + b"0", + 0, + 10102, + &make_genesis, + ).unwrap().unwrap(); + + match genesis_epoch_2 { + ViableEpoch::Genesis(_) => {}, + _ => panic!("should be unimported genesis"), + }; + assert_eq!(genesis_epoch_2.as_ref(), &make_genesis(10102)); + } + + #[test] + fn epoch_changes_between_blocks() { + // + // A - B + // \ + // — C + // + let is_descendent_of = |base: &Hash, block: &Hash| -> Result { + match (base, *block) { + (b"A", b) => Ok(b == *b"B" || b == *b"C" || b == *b"D"), + (b"B", b) | (b"C", b) => Ok(b == *b"D"), + (b"0", _) => Ok(true), + _ => Ok(false), + } + }; + + let make_genesis = |slot| Epoch { + epoch_index: 0, + start_slot: slot, + duration: 100, + authorities: Vec::new(), + randomness: [0; 32], + }; + + let mut epoch_changes = EpochChanges::new(); + let genesis_epoch = epoch_changes.epoch_for_child_of( + &is_descendent_of, + b"0", + 0, + 100, + &make_genesis, + ).unwrap().unwrap(); + + assert_eq!(genesis_epoch.as_ref(), &make_genesis(100)); + + let import_epoch_1 = genesis_epoch.increment(NextEpochDescriptor { + authorities: Vec::new(), + randomness: [1; 32], + }); + let epoch_1 = import_epoch_1.as_ref().clone(); + + epoch_changes.import( + &is_descendent_of, + *b"A", + 1, + *b"0", + import_epoch_1, + ).unwrap(); + let genesis_epoch = genesis_epoch.into_inner(); + + assert!(is_descendent_of(b"0", b"A").unwrap()); + + let end_slot = genesis_epoch.end_slot(); + assert_eq!(end_slot, epoch_1.start_slot); + + { + // x is still within the genesis epoch. + let x = epoch_changes.epoch_for_child_of( + &is_descendent_of, + b"A", + 1, + end_slot - 1, + &make_genesis, + ).unwrap().unwrap().into_inner(); + + assert_eq!(x, genesis_epoch); + } + + { + // x is now at the next epoch, because the block is now at the + // start slot of epoch 1. + let x = epoch_changes.epoch_for_child_of( + &is_descendent_of, + b"A", + 1, + end_slot, + &make_genesis, + ).unwrap().unwrap().into_inner(); + + assert_eq!(x, epoch_1); + } + + { + // x is now at the next epoch, because the block is now after + // start slot of epoch 1. + let x = epoch_changes.epoch_for_child_of( + &is_descendent_of, + b"A", + 1, + epoch_1.end_slot() - 1, + &make_genesis, + ).unwrap().unwrap().into_inner(); + + assert_eq!(x, epoch_1); + } + } + + #[test] + fn two_block_ones_dont_conflict() { + // X - Y + // / + // 0 - A - B + // + let is_descendent_of = |base: &Hash, block: &Hash| -> Result { + match (base, *block) { + (b"A", b) => Ok(b == *b"B"), + (b"X", b) => Ok(b == *b"Y"), + (b"0", _) => Ok(true), + _ => Ok(false), + } + }; + + let duration = 100; + + let make_genesis = |slot| Epoch { + epoch_index: 0, + start_slot: slot, + duration, + authorities: Vec::new(), + randomness: [0; 32], + }; + + let mut epoch_changes = EpochChanges::new(); + let next_descriptor = NextEpochDescriptor { + authorities: Vec::new(), + randomness: [0; 32], + }; + + // insert genesis epoch for A + { + let genesis_epoch_a = epoch_changes.epoch_for_child_of( + &is_descendent_of, + b"0", + 0, + 100, + &make_genesis, + ).unwrap().unwrap(); + + epoch_changes.import( + &is_descendent_of, + *b"A", + 1, + *b"0", + genesis_epoch_a.increment(next_descriptor.clone()), + ).unwrap(); + + } + + // insert genesis epoch for X + { + let genesis_epoch_x = epoch_changes.epoch_for_child_of( + &is_descendent_of, + b"0", + 0, + 1000, + &make_genesis, + ).unwrap().unwrap(); + + epoch_changes.import( + &is_descendent_of, + *b"X", + 1, + *b"0", + genesis_epoch_x.increment(next_descriptor.clone()), + ).unwrap(); + } + + // now check that the genesis epochs for our respective block 1s + // respect the chain structure. + { + let epoch_for_a_child = epoch_changes.epoch_for_child_of( + &is_descendent_of, + b"A", + 1, + 101, + &make_genesis, + ).unwrap().unwrap(); + + assert_eq!(epoch_for_a_child.into_inner(), make_genesis(100)); + + let epoch_for_x_child = epoch_changes.epoch_for_child_of( + &is_descendent_of, + b"X", + 1, + 1001, + &make_genesis, + ).unwrap().unwrap(); + + assert_eq!(epoch_for_x_child.into_inner(), make_genesis(1000)); + + let epoch_for_x_child_before_genesis = epoch_changes.epoch_for_child_of( + &is_descendent_of, + b"X", + 1, + 101, + &make_genesis, + ).unwrap(); + + // even though there is a genesis epoch at that slot, it's not in + // this chain. + assert!(epoch_for_x_child_before_genesis.is_none()); + } + } +} diff --git a/core/consensus/babe/src/lib.rs b/core/consensus/babe/src/lib.rs index e46594dd1e8761ec4cff8abf447e8d154b1926b5..4f69c176ceb312610e663eae512435da8102dfd7 100644 --- a/core/consensus/babe/src/lib.rs +++ b/core/consensus/babe/src/lib.rs @@ -14,91 +14,139 @@ // You should have received a copy of the GNU General Public License // along with Substrate. If not, see . -//! # BABE consensus +//! # BABE (Blind Assignment for Blockchain Extension) //! -//! BABE (Blind Assignment for Blockchain Extension) consensus in Substrate. +//! BABE is a slot-based block production mechanism which uses a VRF PRNG to +//! randomly perform the slot allocation. On every slot, all the authorities +//! generate a new random number with the VRF function and if it is lower than a +//! given threshold (which is proportional to their weight/stake) they have a +//! right to produce a block. The proof of the VRF function execution will be +//! used by other peer to validate the legitimacy of the slot claim. +//! +//! The engine is also responsible for collecting entropy on-chain which will be +//! used to seed the given VRF PRNG. An epoch is a contiguous number of slots +//! under which we will be using the same authority set. During an epoch all VRF +//! outputs produced as a result of block production will be collected on an +//! on-chain randomness pool. Epoch changes are announced one epoch in advance, +//! i.e. when ending epoch N, we announce the parameters (randomness, +//! authorities, etc.) for epoch N+2. +//! +//! Since the slot assignment is randomized, it is possible that a slot is +//! assigned to multiple validators in which case we will have a temporary fork, +//! or that a slot is assigned to no validator in which case no block is +//! produced. Which means that block times are not deterministic. +//! +//! The protocol has a parameter `c` [0, 1] for which `1 - c` is the probability +//! of a slot being empty. The choice of this parameter affects the security of +//! the protocol relating to maximum tolerable network delays. +//! +//! In addition to the VRF-based slot assignment described above, which we will +//! call primary slots, the engine also supports a deterministic secondary slot +//! assignment. Primary slots take precedence over secondary slots, when +//! authoring the node starts by trying to claim a primary slot and falls back +//! to a secondary slot claim attempt. The secondary slot assignment is done +//! by picking the authority at index: +//! +//! `blake2_256(epoch_randomness ++ slot_number) % authorities_len`. +//! +//! The fork choice rule is weight-based, where weight equals the number of +//! primary blocks in the chain. We will pick the heaviest chain (more primary +//! blocks) and will go with the longest one in case of a tie. +//! +//! An in-depth description and analysis of the protocol can be found here: +//! -#![forbid(unsafe_code, missing_docs)] +#![forbid(unsafe_code)] +#![warn(missing_docs)] pub use babe_primitives::*; pub use consensus_common::SyncOracle; -use std::{collections::HashMap, sync::Arc, u64, fmt::{Debug, Display}, pin::Pin, time::{Instant, Duration}}; +use std::{collections::HashMap, sync::Arc, u64, pin::Pin, time::{Instant, Duration}}; use babe_primitives; use consensus_common::ImportResult; use consensus_common::import_queue::{ BoxJustificationImport, BoxFinalityProofImport, }; -use consensus_common::well_known_cache_keys::Id as CacheKeyId; -use sr_primitives::{generic, generic::{BlockId, OpaqueDigestItemId}, Justification}; +use sr_primitives::{generic::{BlockId, OpaqueDigestItemId}, Justification}; use sr_primitives::traits::{ - Block as BlockT, Header, DigestItemFor, NumberFor, ProvideRuntimeApi, - SimpleBitOps, Zero, + Block as BlockT, Header, DigestItemFor, ProvideRuntimeApi, + Zero, }; use keystore::KeyStorePtr; -use runtime_support::serde::{Serialize, Deserialize}; -use codec::{Decode, Encode}; -use parking_lot::{Mutex, MutexGuard}; -use primitives::{Blake2Hasher, H256, Pair, Public}; -use merlin::Transcript; +use parking_lot::Mutex; +use primitives::{Blake2Hasher, H256, Pair}; use inherents::{InherentDataProviders, InherentData}; use substrate_telemetry::{ telemetry, CONSENSUS_TRACE, CONSENSUS_DEBUG, - CONSENSUS_WARN, - CONSENSUS_INFO, -}; -use schnorrkel::{ - keys::Keypair, - vrf::{ - VRFProof, VRFProofBatchable, VRFInOut, - }, }; use consensus_common::{ - self, BlockImport, Environment, Proposer, + self, BlockImport, Environment, Proposer, BlockCheckParams, ForkChoiceStrategy, BlockImportParams, BlockOrigin, Error as ConsensusError, }; use srml_babe::{ BabeInherentData, timestamp::{TimestampInherentData, InherentType as TimestampInherent} }; -use consensus_common::{SelectChain, well_known_cache_keys}; -use consensus_common::import_queue::{Verifier, BasicQueue}; +use consensus_common::SelectChain; +use consensus_common::import_queue::{Verifier, BasicQueue, CacheKeyId}; use client::{ block_builder::api::BlockBuilder as BlockBuilderApi, blockchain::{self, HeaderBackend, ProvideCache}, BlockchainEvents, CallExecutor, Client, - runtime_api::ApiExt, error::Result as ClientResult, backend::{AuxStore, Backend}, + error::Result as ClientResult, error::Error as ClientError, backend::{AuxStore, Backend}, ProvideUncles, - utils::is_descendent_of, }; -use fork_tree::ForkTree; use slots::{CheckedHeader, check_equivocation}; -use futures::{prelude::*, future}; -use futures01::Stream as _; -use futures_timer::Delay; -use log::{error, warn, debug, info, trace}; - -use slots::{SlotWorker, SlotData, SlotInfo, SlotCompatible, SignedDuration}; +use futures::prelude::*; +use log::{warn, debug, info, trace}; +use slots::{SlotWorker, SlotData, SlotInfo, SlotCompatible}; +use epoch_changes::descendent_query; +use header_metadata::HeaderMetadata; mod aux_schema; +mod verification; +mod epoch_changes; +mod authorship; #[cfg(test)] mod tests; -pub use babe_primitives::{AuthorityId, AuthorityPair, AuthoritySignature}; +pub use babe_primitives::{ + AuthorityId, AuthorityPair, AuthoritySignature, Epoch, NextEpochDescriptor, +}; +pub use epoch_changes::{EpochChanges, EpochChangesFor, SharedEpochChanges}; + +macro_rules! babe_err { + ($($i: expr),+) => { + { + debug!(target: "babe", $($i),+); + format!($($i),+) + } + }; +} + +macro_rules! babe_info { + ($($i: expr),+) => { + { + info!(target: "babe", $($i),+); + format!($($i),+) + } + }; +} /// A slot duration. Create with `get_or_compute`. // FIXME: Once Rust has higher-kinded types, the duplication between this // and `super::babe::Config` can be eliminated. // https://github.com/paritytech/substrate/issues/2434 +#[derive(Clone)] pub struct Config(slots::SlotDuration); impl Config { /// Either fetch the slot duration from disk or compute it from the genesis /// state. - pub fn get_or_compute(client: &C) -> ClientResult - where + pub fn get_or_compute(client: &C) -> ClientResult where C: AuxStore + ProvideRuntimeApi, C::Api: BabeApi, { trace!(target: "babe", "Getting slot duration"); - match slots::SlotDuration::get_or_compute(client, |a, b| a.startup_data(b)).map(Self) { + match slots::SlotDuration::get_or_compute(client, |a, b| a.configuration(b)).map(Self) { Ok(s) => Ok(s), Err(s) => { warn!(target: "babe", "Failed to get slot duration"); @@ -107,37 +155,29 @@ impl Config { } } - /// Get the slot duration in milliseconds. - pub fn get(&self) -> u64 { - self.0.slot_duration - } - - /// Retrieve the threshold calculation constant `c`. - pub fn c(&self) -> (u64, u64) { - self.0.c + /// Create the genesis epoch (epoch #0). This is defined to start at the slot of + /// the first block, so that has to be provided. + pub fn genesis_epoch(&self, slot_number: SlotNumber) -> Epoch { + Epoch { + epoch_index: 0, + start_slot: slot_number, + duration: self.epoch_length, + authorities: self.genesis_authorities.clone(), + randomness: self.randomness.clone(), + } } } -impl SlotCompatible for BabeLink { - fn extract_timestamp_and_slot( - &self, - data: &InherentData, - ) -> Result<(TimestampInherent, u64, std::time::Duration), consensus_common::Error> { - trace!(target: "babe", "extract timestamp"); - data.timestamp_inherent_data() - .and_then(|t| data.babe_inherent_data().map(|a| (t, a))) - .map_err(Into::into) - .map_err(consensus_common::Error::InherentData) - .map(|(x, y)| (x, y, self.0.lock().0.take().unwrap_or_default())) +impl std::ops::Deref for Config { + type Target = BabeConfiguration; + + fn deref(&self) -> &BabeConfiguration { + &*self.0 } } /// Parameters for BABE. -pub struct BabeParams { - /// The configuration for BABE. Includes the slot duration, threshold, and - /// other parameters. - pub config: Config, - +pub struct BabeParams { /// The keystore that manages the keys of the node. pub keystore: KeyStorePtr, @@ -147,12 +187,14 @@ pub struct BabeParams { /// The SelectChain Strategy pub select_chain: SC, - /// A block importer - pub block_import: I, - - /// The environment + /// The environment we are producing blocks for. pub env: E, + /// The underlying block-import object to supply our produced blocks to. + /// This must be a `BabeBlockImport` or a wrapper of it, otherwise + /// critical consensus logic will be omitted. + pub block_import: I, + /// A sync oracle pub sync_oracle: SO, @@ -163,268 +205,222 @@ pub struct BabeParams { pub force_authoring: bool, /// The source of timestamps for relative slots - pub time_source: BabeLink, + pub babe_link: BabeLink, } /// Start the babe worker. The returned future should be run in a tokio runtime. -pub fn start_babe(BabeParams { - config, - client, +pub fn start_babe(BabeParams { keystore, + client, select_chain, - block_import, env, + block_import, sync_oracle, inherent_data_providers, force_authoring, - time_source, -}: BabeParams) -> Result< + babe_link, +}: BabeParams) -> Result< impl futures01::Future, consensus_common::Error, > where - B: BlockT, - C: ProvideRuntimeApi + ProvideCache + ProvideUncles + Send + Sync + 'static, + B: BlockT, + C: ProvideRuntimeApi + ProvideCache + ProvideUncles + BlockchainEvents + + HeaderBackend + HeaderMetadata + Send + Sync + 'static, C::Api: BabeApi, SC: SelectChain + 'static, + E: Environment + Send + Sync, E::Proposer: Proposer, >::Create: Unpin + Send + 'static, - H: Header, - E: Environment, - I: BlockImport + Send + Sync + 'static, + I: BlockImport + Send + Sync + 'static, Error: std::error::Error + Send + From<::consensus_common::Error> + From + 'static, SO: SyncOracle + Send + Sync + Clone, { + let config = babe_link.config; let worker = BabeWorker { client: client.clone(), block_import: Arc::new(Mutex::new(block_import)), env, sync_oracle: sync_oracle.clone(), force_authoring, - c: config.c(), keystore, + epoch_changes: babe_link.epoch_changes.clone(), + config: config.clone(), }; - register_babe_inherent_data_provider(&inherent_data_providers, config.0.slot_duration())?; + + register_babe_inherent_data_provider(&inherent_data_providers, config.slot_duration())?; uncles::register_uncles_inherent_data_provider( client.clone(), select_chain.clone(), &inherent_data_providers, )?; - Ok(slots::start_slot_worker( + + babe_info!("Starting BABE Authorship worker"); + let slot_worker = slots::start_slot_worker( config.0, select_chain, worker, sync_oracle, inherent_data_providers, - time_source, - ).map(|()| Ok::<(), ()>(())).compat()) + babe_link.time_source, + ); + + Ok(slot_worker.map(|_| Ok::<(), ()>(())).compat()) } -struct BabeWorker { +struct BabeWorker { client: Arc, block_import: Arc>, env: E, sync_oracle: SO, force_authoring: bool, - c: (u64, u64), keystore: KeyStorePtr, + epoch_changes: SharedEpochChanges, + config: Config, } -impl SlotWorker for BabeWorker where - B: BlockT, - C: ProvideRuntimeApi + ProvideCache, +impl slots::SimpleSlotWorker for BabeWorker where + B: BlockT, + C: ProvideRuntimeApi + ProvideCache + HeaderBackend + HeaderMetadata, C::Api: BabeApi, E: Environment, E::Proposer: Proposer, >::Create: Unpin + Send + 'static, - Hash: Debug + Eq + Copy + SimpleBitOps + Encode + Decode + Serialize + - for<'de> Deserialize<'de> + Debug + Default + AsRef<[u8]> + AsMut<[u8]> + - std::hash::Hash + Display + Send + Sync + 'static, - H: Header, I: BlockImport + Send + Sync + 'static, SO: SyncOracle + Send + Clone, Error: std::error::Error + Send + From<::consensus_common::Error> + From + 'static, { - type OnSlot = Pin> + Send>>; - - fn on_slot( - &mut self, - chain_head: B::Header, - slot_info: SlotInfo, - ) -> Self::OnSlot { - let ref client = self.client; - let block_import = self.block_import.clone(); - - let (timestamp, slot_number, slot_duration) = - (slot_info.timestamp, slot_info.number, slot_info.duration); - - let epoch = match epoch(client.as_ref(), &BlockId::Hash(chain_head.hash())) { - Ok(authorities) => authorities, - Err(e) => { - error!( - target: "babe", - "Unable to fetch authorities at block {:?}: {:?}", - chain_head.hash(), - e - ); - telemetry!(CONSENSUS_WARN; "babe.unable_fetching_authorities"; - "slot" => ?chain_head.hash(), "err" => ?e - ); - return Box::pin(future::ready(Ok(()))); - } - }; + type EpochData = Epoch; + type Claim = (BabePreDigest, AuthorityPair); + type SyncOracle = SO; + type Proposer = E::Proposer; + type BlockImport = I; + + fn logging_target(&self) -> &'static str { + "babe" + } - let Epoch { ref authorities, .. } = epoch; + fn block_import(&self) -> Arc> { + self.block_import.clone() + } - if authorities.is_empty() { - error!(target: "babe", "No authorities at block {:?}", chain_head.hash()); - } + fn epoch_data(&self, parent: &B::Header, slot_number: u64) -> Result { + self.epoch_changes.lock().epoch_for_child_of( + descendent_query(&*self.client), + &parent.hash(), + parent.number().clone(), + slot_number, + |slot| self.config.genesis_epoch(slot) + ) + .map_err(|e| ConsensusError::ChainLookup(format!("{:?}", e)))? + .map(|e| e.into_inner()) + .ok_or(consensus_common::Error::InvalidAuthoritiesSet) + } - if !self.force_authoring && self.sync_oracle.is_offline() && authorities.len() > 1 { - debug!(target: "babe", "Skipping proposal slot. Waiting for the network."); - telemetry!(CONSENSUS_DEBUG; "babe.skipping_proposal_slot"; - "authorities_len" => authorities.len() - ); - return Box::pin(future::ready(Ok(()))); - } + fn authorities_len(&self, epoch_data: &Self::EpochData) -> usize { + epoch_data.authorities.len() + } - let proposal_work = if let Some(claim) = claim_slot( - slot_info.number, - epoch, - self.c, + fn claim_slot( + &self, + _parent_header: &B::Header, + slot_number: SlotNumber, + epoch_data: &Epoch, + ) -> Option { + debug!(target: "babe", "Attempting to claim slot {}", slot_number); + let s = authorship::claim_slot( + slot_number, + epoch_data, + &*self.config, &self.keystore, - ) { - let ((inout, vrf_proof, _batchable_proof), authority_index, key) = claim; - - debug!( - target: "babe", "Starting authorship at slot {}; timestamp = {}", - slot_number, - timestamp, - ); - telemetry!(CONSENSUS_DEBUG; "babe.starting_authorship"; - "slot_number" => slot_number, "timestamp" => timestamp - ); - - // we are the slot author. make a block and sign it. - let mut proposer = match self.env.init(&chain_head) { - Ok(p) => p, - Err(e) => { - warn!(target: "babe", - "Unable to author block in slot {:?}: {:?}", - slot_number, - e, - ); - telemetry!(CONSENSUS_WARN; "babe.unable_authoring_block"; - "slot" => slot_number, "err" => ?e - ); - return Box::pin(future::ready(Ok(()))) - } - }; - - let inherent_digest = BabePreDigest { - vrf_proof, - vrf_output: inout.to_output(), - authority_index: authority_index as u32, - slot_number, - }; + ); - // deadline our production to approx. the end of the slot - let remaining_duration = slot_info.remaining_duration(); - futures::future::select( - proposer.propose( - slot_info.inherent_data, - generic::Digest { - logs: vec![ - generic::DigestItem::babe_pre_digest(inherent_digest.clone()), - ], - }, - remaining_duration, - ).map_err(|e| consensus_common::Error::ClientImport(format!("{:?}", e)).into()), - Delay::new(remaining_duration) - .map_err(|err| consensus_common::Error::FaultyTimer(err).into()) - ).map(|v| match v { - futures::future::Either::Left((v, _)) => v.map(|v| (v, key)), - futures::future::Either::Right((Ok(_), _)) => - Err(consensus_common::Error::ClientImport("Timeout in the BaBe proposer".into())), - futures::future::Either::Right((Err(err), _)) => Err(err), - }) - } else { - return Box::pin(future::ready(Ok(()))); - }; + if let Some(_) = s { + debug!(target: "babe", "Claimed slot {}", slot_number); + } - Box::pin(proposal_work.map_ok(move |(b, key)| { - // minor hack since we don't have access to the timestamp - // that is actually set by the proposer. - let slot_after_building = SignedDuration::default().slot_now(slot_duration); - if slot_after_building != slot_number { - info!( - target: "babe", - "Discarding proposal for slot {}; block production took too long", - slot_number - ); - telemetry!(CONSENSUS_INFO; "babe.discarding_proposal_took_too_long"; - "slot" => slot_number - ); - return; - } + s + } - let (header, body) = b.deconstruct(); - let header_num = header.number().clone(); - let parent_hash = header.parent_hash().clone(); + fn pre_digest_data(&self, _slot_number: u64, claim: &Self::Claim) -> Vec> { + vec![ + as CompatibleDigestItem>::babe_pre_digest(claim.0.clone()), + ] + } + fn block_import_params(&self) -> Box, + Self::Claim, + ) -> consensus_common::BlockImportParams + Send> { + Box::new(|header, header_hash, body, (_, pair)| { // sign the pre-sealed hash of the block and then // add it to a digest item. - let header_hash = header.hash(); - let signature = key.sign(header_hash.as_ref()); - let signature_digest_item = DigestItemFor::::babe_seal(signature); + let signature = pair.sign(header_hash.as_ref()); + let signature_digest_item = as CompatibleDigestItem>::babe_seal(signature); - let import_block = BlockImportParams:: { + BlockImportParams { origin: BlockOrigin::Own, header, justification: None, post_digests: vec![signature_digest_item], body: Some(body), finalized: false, - auxiliary: Vec::new(), + auxiliary: Vec::new(), // block-weight is written in block import. + // TODO: block-import handles fork choice and this shouldn't even have the + // option to specify one. + // https://github.com/paritytech/substrate/issues/3623 fork_choice: ForkChoiceStrategy::LongestChain, - }; + } + }) + } - info!(target: "babe", - "Pre-sealed block for proposal at {}. Hash now {:?}, previously {:?}.", - header_num, - import_block.post_header().hash(), - header_hash, - ); + fn force_authoring(&self) -> bool { + self.force_authoring + } - telemetry!(CONSENSUS_INFO; "babe.pre_sealed_block"; - "header_num" => ?header_num, - "hash_now" => ?import_block.post_header().hash(), - "hash_previously" => ?header_hash, - ); + fn sync_oracle(&mut self) -> &mut Self::SyncOracle { + &mut self.sync_oracle + } - if let Err(e) = block_import.lock().import_block(import_block, Default::default()) { - warn!(target: "babe", "Error with block built on {:?}: {:?}", - parent_hash, e); - telemetry!(CONSENSUS_WARN; "babe.err_with_block_built_on"; - "hash" => ?parent_hash, "err" => ?e - ); - } - })) + fn proposer(&mut self, block: &B::Header) -> Result { + self.env.init(block).map_err(|e| { + consensus_common::Error::ClientImport(format!("{:?}", e)).into() + }) } } -macro_rules! babe_err { - ($($i: expr),+) => { - { debug!(target: "babe", $($i),+) - ; format!($($i),+) - } - }; +impl SlotWorker for BabeWorker where + B: BlockT, + C: ProvideRuntimeApi + ProvideCache + HeaderBackend + HeaderMetadata + Send + Sync, + C::Api: BabeApi, + E: Environment + Send + Sync, + E::Proposer: Proposer, + >::Create: Unpin + Send + 'static, + I: BlockImport + Send + Sync + 'static, + SO: SyncOracle + Send + Sync + Clone, + Error: std::error::Error + Send + From<::consensus_common::Error> + From + 'static, +{ + type OnSlot = Pin> + Send>>; + + fn on_slot(&mut self, chain_head: B::Header, slot_info: SlotInfo) -> Self::OnSlot { + >::on_slot(self, chain_head, slot_info) + } } /// Extract the BABE pre digest from the given header. Pre-runtime digests are /// mandatory, the function will return `Err` if none is found. -fn find_pre_digest(header: &B::Header) -> Result - where DigestItemFor: CompatibleDigestItem, +fn find_pre_digest(header: &H) -> Result { + // genesis block doesn't contain a pre digest so let's generate a + // dummy one to not break any invariants in the rest of the code + if header.number().is_zero() { + return Ok(BabePreDigest::Secondary { + slot_number: 0, + authority_index: 0, + }); + } + let mut pre_digest: Option<_> = None; for log in header.digest().logs() { trace!(target: "babe", "Checking log {:?}, looking for pre runtime digest", log); @@ -438,7 +434,8 @@ fn find_pre_digest(header: &B::Header) -> Result(header: &B::Header) -> Result, String> +fn find_next_epoch_digest(header: &B::Header) + -> Result, String> where DigestItemFor: CompatibleDigestItem, { let mut epoch_digest: Option<_> = None; @@ -455,118 +452,49 @@ fn find_next_epoch_digest(header: &B::Header) -> Result Ok(epoch_digest) } -/// Check a header has been signed by the right key. If the slot is too far in -/// the future, an error will be returned. If successful, returns the pre-header -/// and the digest item containing the seal. -/// -/// The seal must be the last digest. Otherwise, the whole header is considered -/// unsigned. This is required for security and must not be changed. -/// -/// This digest item will always return `Some` when used with `as_babe_pre_digest`. -// FIXME #1018 needs misbehavior types. The `transaction_pool` parameter will be -// used to submit such misbehavior reports. -fn check_header( - client: &C, - slot_now: u64, - mut header: B::Header, - hash: B::Hash, - authorities: &[(AuthorityId, BabeWeight)], - randomness: [u8; 32], - epoch_index: u64, - c: (u64, u64), - _transaction_pool: Option<&T>, -) -> Result, DigestItemFor)>, String> where - DigestItemFor: CompatibleDigestItem, - T: Send + Sync + 'static, -{ - trace!(target: "babe", "Checking header"); - let seal = match header.digest_mut().pop() { - Some(x) => x, - None => return Err(babe_err!("Header {:?} is unsealed", hash)), - }; - - let sig = seal.as_babe_seal().ok_or_else(|| { - babe_err!("Header {:?} has a bad seal", hash) - })?; - - let pre_digest = find_pre_digest::(&header)?; - let BabePreDigest { slot_number, authority_index, ref vrf_proof, ref vrf_output } = pre_digest; +#[derive(Default, Clone)] +struct TimeSource(Arc, Vec<(Instant, u64)>)>>); - if slot_number > slot_now { - header.digest_mut().push(seal); - Ok(CheckedHeader::Deferred(header, slot_number)) - } else if authority_index > authorities.len() as u32 { - Err(babe_err!("Slot author not found")) - } else { - let (pre_hash, author) = (header.hash(), &authorities[authority_index as usize].0); - - if AuthorityPair::verify(&sig, pre_hash, &author) { - let (inout, _batchable_proof) = { - let transcript = make_transcript( - &randomness, - slot_number, - epoch_index, - ); - - schnorrkel::PublicKey::from_bytes(author.as_slice()).and_then(|p| { - p.vrf_verify(transcript, vrf_output, vrf_proof) - }).map_err(|s| { - babe_err!("VRF verification failed: {:?}", s) - })? - }; - - let threshold = calculate_threshold(c, authorities, authority_index as usize); - if !check(&inout, threshold) { - return Err(babe_err!("VRF verification of block by author {:?} failed: \ - threshold {} exceeded", author, threshold)); - } - - if let Some(equivocation_proof) = check_equivocation( - client, - slot_now, - slot_number, - &header, - author, - ).map_err(|e| e.to_string())? { - info!( - "Slot author {:?} is equivocating at slot {} with headers {:?} and {:?}", - author, - slot_number, - equivocation_proof.fst_header().hash(), - equivocation_proof.snd_header().hash(), - ); - } - - let pre_digest = CompatibleDigestItem::babe_pre_digest(pre_digest); - Ok(CheckedHeader::Checked(header, (pre_digest, seal))) - } else { - Err(babe_err!("Bad signature on {:?}", hash)) - } +impl SlotCompatible for TimeSource { + fn extract_timestamp_and_slot( + &self, + data: &InherentData, + ) -> Result<(TimestampInherent, u64, std::time::Duration), consensus_common::Error> { + trace!(target: "babe", "extract timestamp"); + data.timestamp_inherent_data() + .and_then(|t| data.babe_inherent_data().map(|a| (t, a))) + .map_err(Into::into) + .map_err(consensus_common::Error::InherentData) + .map(|(x, y)| (x, y, self.0.lock().0.take().unwrap_or_default())) } } /// State that must be shared between the import queue and the authoring logic. -#[derive(Default, Clone, Debug)] -pub struct BabeLink(Arc, Vec<(Instant, u64)>)>>); - +#[derive(Clone)] +pub struct BabeLink { + time_source: TimeSource, + epoch_changes: SharedEpochChanges, + config: Config, +} /// A verifier for Babe blocks. -pub struct BabeVerifier { - api: Arc, +pub struct BabeVerifier { + client: Arc>, + api: Arc, inherent_data_providers: inherents::InherentDataProviders, config: Config, - time_source: BabeLink, - transaction_pool: Option>, + epoch_changes: SharedEpochChanges, + time_source: TimeSource, } -impl BabeVerifier { - fn check_inherents( +impl BabeVerifier { + fn check_inherents( &self, - block: B, - block_id: BlockId, + block: Block, + block_id: BlockId, inherent_data: InherentData, ) -> Result<(), String> - where C: ProvideRuntimeApi, C::Api: BlockBuilderApi + where PRA: ProvideRuntimeApi, PRA::Api: BlockBuilderApi { let inherent_res = self.api.runtime_api().check_inherents( &block_id, @@ -598,7 +526,7 @@ fn median_algorithm( if num_timestamps as u64 >= median_required_blocks && median_required_blocks > 0 { let mut new_list: Vec<_> = time_source.1.iter().map(|&(t, sl)| { let offset: u128 = u128::from(slot_duration) - .checked_mul(1_000_000u128) // self.config.get() returns *milliseconds* + .checked_mul(1_000_000u128) // self.config.slot_duration returns milliseconds .and_then(|x| { x.checked_mul(u128::from(slot_number).saturating_sub(u128::from(sl))) }) @@ -611,8 +539,8 @@ fn median_algorithm( t + Duration::new(secs, nanos) }).collect(); - // FIXME #2926: use a selection algorithm instead of a full sorting algorithm. - new_list.sort_unstable(); + // Use a partial sort to move the median timestamp to the middle of the list + pdqselect::select(&mut new_list, num_timestamps / 2); let &median = new_list .get(num_timestamps / 2) @@ -629,18 +557,21 @@ fn median_algorithm( } } -impl Verifier for BabeVerifier where - C: ProvideRuntimeApi + Send + Sync + AuxStore + ProvideCache, - C::Api: BlockBuilderApi + BabeApi, - T: Send + Sync + 'static, +impl Verifier for BabeVerifier where + Block: BlockT, + B: Backend + 'static, + E: CallExecutor + 'static + Clone + Send + Sync, + RA: Send + Sync, + PRA: ProvideRuntimeApi + Send + Sync + AuxStore + ProvideCache, + PRA::Api: BlockBuilderApi + BabeApi, { fn verify( &mut self, origin: BlockOrigin, - header: B::Header, + header: Block::Header, justification: Option, - mut body: Option>, - ) -> Result<(BlockImportParams, Option)>>), String> { + mut body: Option>, + ) -> Result<(BlockImportParams, Option)>>), String> { trace!( target: "babe", "Verifying origin: {:?} header: {:?} justification: {:?} body: {:?}", @@ -661,35 +592,67 @@ impl Verifier for BabeVerifier where let hash = header.hash(); let parent_hash = *header.parent_hash(); - let Epoch { authorities, randomness, epoch_index, .. } = - epoch(self.api.as_ref(), &BlockId::Hash(parent_hash)) - .map_err(|e| format!("Could not fetch epoch at {:?}: {:?}", parent_hash, e))?; - // We add one to allow for some small drift. + let parent_header_metadata = self.client.header_metadata(parent_hash) + .map_err(|e| format!("Could not fetch parent header: {:?}", e))?; + + let pre_digest = find_pre_digest::(&header)?; + let epoch = { + let epoch_changes = self.epoch_changes.lock(); + epoch_changes.epoch_for_child_of( + descendent_query(&*self.client), + &parent_hash, + parent_header_metadata.number, + pre_digest.slot_number(), + |slot| self.config.genesis_epoch(slot), + ) + .map_err(|e| format!("{:?}", e))? + .ok_or_else(|| format!("Could not fetch epoch at {:?}", parent_hash))? + }; + + // We add one to the current slot to allow for some small drift. // FIXME #1019 in the future, alter this queue to allow deferring of headers - let checked_header = check_header::( - &self.api, - slot_now + 1, - header, - hash, - &authorities, - randomness, - epoch_index, - self.config.c(), - self.transaction_pool.as_ref().map(|x| &**x), - )?; - - match checked_header { - CheckedHeader::Checked(pre_header, (pre_digest, seal)) => { - let BabePreDigest { slot_number, .. } = pre_digest.as_babe_pre_digest() + let v_params = verification::VerificationParams { + header: header.clone(), + pre_digest: Some(pre_digest.clone()), + slot_now: slot_now + 1, + epoch: epoch.as_ref(), + config: &self.config, + }; + + match verification::check_header::(v_params)? { + CheckedHeader::Checked(pre_header, verified_info) => { + let babe_pre_digest = verified_info.pre_digest.as_babe_pre_digest() .expect("check_header always returns a pre-digest digest item; qed"); + let slot_number = babe_pre_digest.slot_number(); + + let author = verified_info.author; + + // the header is valid but let's check if there was something else already + // proposed at the same slot by the given author + if let Some(equivocation_proof) = check_equivocation( + &*self.api, + slot_now, + babe_pre_digest.slot_number(), + &header, + &author, + ).map_err(|e| e.to_string())? { + info!( + "Slot author {:?} is equivocating at slot {} with headers {:?} and {:?}", + author, + babe_pre_digest.slot_number(), + equivocation_proof.fst_header().hash(), + equivocation_proof.snd_header().hash(), + ); + } + // if the body is passed through, we need to use the runtime // to check that the internally-set timestamp in the inherents // actually matches the slot set in the seal. if let Some(inner_body) = body.take() { inherent_data.babe_replace_inherent_data(slot_number); - let block = B::new(pre_header.clone(), inner_body); + let block = Block::new(pre_header.clone(), inner_body); self.check_inherents( block.clone(), @@ -707,18 +670,21 @@ impl Verifier for BabeVerifier where "babe.checked_and_importing"; "pre_header" => ?pre_header); - let import_block = BlockImportParams { + let block_import_params = BlockImportParams { origin, header: pre_header, - post_digests: vec![seal], + post_digests: vec![verified_info.seal], body, finalized: false, justification, auxiliary: Vec::new(), + // TODO: block-import handles fork choice and this shouldn't even have the + // option to specify one. + // https://github.com/paritytech/substrate/issues/3623 fork_choice: ForkChoiceStrategy::LongestChain, }; - Ok((import_block, Default::default())) + Ok((block_import_params, Default::default())) } CheckedHeader::Deferred(a, b) => { debug!(target: "babe", "Checking {:?} failed; {:?}, {:?}.", hash, a, b); @@ -731,33 +697,6 @@ impl Verifier for BabeVerifier where } } -/// Extract current epoch data from cache and fallback to querying the runtime -/// if the cache isn't populated. -fn epoch(client: &C, at: &BlockId) -> Result where - B: BlockT, - C: ProvideRuntimeApi + ProvideCache, - C::Api: BabeApi, -{ - client - .cache() - .and_then(|cache| cache.get_at(&well_known_cache_keys::EPOCH, at) - .and_then(|v| Decode::decode(&mut &v[..]).ok())) - .or_else(|| { - if client.runtime_api().has_api::>(at).unwrap_or(false) { - let s = BabeApi::epoch(&*client.runtime_api(), at).ok()?; - if s.authorities.is_empty() { - error!("No authorities!"); - None - } else { - Some(s) - } - } else { - error!("bad api!"); - None - } - }).ok_or(consensus_common::Error::InvalidAuthoritiesSet) -} - /// The BABE import queue type. pub type BabeImportQueue = BasicQueue; @@ -777,149 +716,6 @@ fn register_babe_inherent_data_provider( } } -fn get_keypair(q: &AuthorityPair) -> &Keypair { - use primitives::crypto::IsWrappedBy; - primitives::sr25519::Pair::from_ref(q).as_ref() -} - -#[allow(deprecated)] -fn make_transcript( - randomness: &[u8], - slot_number: u64, - epoch: u64, -) -> Transcript { - let mut transcript = Transcript::new(&BABE_ENGINE_ID); - transcript.commit_bytes(b"slot number", &slot_number.to_le_bytes()); - transcript.commit_bytes(b"current epoch", &epoch.to_le_bytes()); - transcript.commit_bytes(b"chain randomness", randomness); - transcript -} - -fn check(inout: &VRFInOut, threshold: u128) -> bool { - u128::from_le_bytes(inout.make_bytes::<[u8; 16]>(BABE_VRF_PREFIX)) < threshold -} - -fn calculate_threshold( - c: (u64, u64), - authorities: &[(AuthorityId, BabeWeight)], - authority_index: usize, -) -> u128 { - use num_bigint::BigUint; - use num_rational::BigRational; - use num_traits::{cast::ToPrimitive, identities::One}; - - let c = c.0 as f64 / c.1 as f64; - - let theta = - authorities[authority_index].1 as f64 / - authorities.iter().map(|(_, weight)| weight).sum::() as f64; - - let calc = || { - let p = BigRational::from_float(1f64 - (1f64 - c).powf(theta))?; - let numer = p.numer().to_biguint()?; - let denom = p.denom().to_biguint()?; - ((BigUint::one() << 128) * numer / denom).to_u128() - }; - - calc().unwrap_or(u128::max_value()) -} - -/// Claim a slot if it is our turn. Returns `None` if it is not our turn. -/// -/// This hashes the slot number, epoch, genesis hash, and chain randomness into -/// the VRF. If the VRF produces a value less than `threshold`, it is our turn, -/// so it returns `Some(_)`. Otherwise, it returns `None`. -fn claim_slot( - slot_number: u64, - Epoch { ref authorities, ref randomness, epoch_index, .. }: Epoch, - c: (u64, u64), - keystore: &KeyStorePtr, -) -> Option<((VRFInOut, VRFProof, VRFProofBatchable), usize, AuthorityPair)> { - let keystore = keystore.read(); - let (key_pair, authority_index) = authorities.iter() - .enumerate() - .find_map(|(i, a)| { - keystore.key_pair::(&a.0).ok().map(|kp| (kp, i)) - })?; - let transcript = make_transcript(randomness, slot_number, epoch_index); - - // Compute the threshold we will use. - // - // We already checked that authorities contains `key.public()`, so it can't - // be empty. Therefore, this division in `calculate_threshold` is safe. - let threshold = calculate_threshold(c, authorities, authority_index); - - get_keypair(&key_pair) - .vrf_sign_after_check(transcript, |inout| check(inout, threshold)) - .map(|s|(s, authority_index, key_pair)) -} - -fn initialize_authorities_cache(client: &C) -> Result<(), ConsensusError> where - B: BlockT, - C: ProvideRuntimeApi + ProvideCache, - C::Api: BabeApi, -{ - // no cache => no initialization - let cache = match client.cache() { - Some(cache) => cache, - None => return Ok(()), - }; - - // check if we already have initialized the cache - let genesis_id = BlockId::Number(Zero::zero()); - let genesis_epoch: Option = cache - .get_at(&well_known_cache_keys::EPOCH, &genesis_id) - .and_then(|v| Decode::decode(&mut &v[..]).ok()); - if genesis_epoch.is_some() { - return Ok(()); - } - - let map_err = |error| consensus_common::Error::from(consensus_common::Error::ClientImport( - format!( - "Error initializing authorities cache: {}", - error, - ))); - - let genesis_epoch = epoch(client, &genesis_id)?; - cache.initialize(&well_known_cache_keys::EPOCH, genesis_epoch.encode()) - .map_err(map_err) -} - -/// Tree of all epoch changes across all *seen* forks. Data stored in tree is -/// the hash and block number of the block signaling the epoch change, and the -/// epoch that was signalled at that block. -type EpochChanges = ForkTree< - ::Hash, - NumberFor, - Epoch, ->; - -/// A shared epoch changes tree. -#[derive(Clone)] -struct SharedEpochChanges { - inner: Arc>>, -} - -impl SharedEpochChanges { - fn new() -> Self { - SharedEpochChanges { - inner: Arc::new(Mutex::new(EpochChanges::::new())) - } - } - - fn lock(&self) -> MutexGuard> { - self.inner.lock() - } -} - -impl From> for SharedEpochChanges { - fn from(epoch_changes: EpochChanges) -> Self { - SharedEpochChanges { - inner: Arc::new(Mutex::new(epoch_changes)) - } - } -} - /// A block-import handler for BABE. /// /// This scans each imported block for epoch change signals. The signals are @@ -933,6 +729,7 @@ pub struct BabeBlockImport { client: Arc>, api: Arc, epoch_changes: SharedEpochChanges, + config: Config, } impl Clone for BabeBlockImport { @@ -942,6 +739,7 @@ impl Clone for BabeBlockImport BabeBlockImport { api: Arc, epoch_changes: SharedEpochChanges, block_import: I, + config: Config, ) -> Self { BabeBlockImport { client, api, inner: block_import, epoch_changes, + config, } } } @@ -977,78 +777,92 @@ impl BlockImport for BabeBlockImport, - mut new_cache: HashMap>, + new_cache: HashMap>, ) -> Result { let hash = block.post_header().hash(); let number = block.header.number().clone(); // early exit if block already in chain, otherwise the check for // epoch changes will error when trying to re-import an epoch change - #[allow(deprecated)] - match self.client.backend().blockchain().status(BlockId::Hash(hash)) { + match self.client.status(BlockId::Hash(hash)) { Ok(blockchain::BlockStatus::InChain) => return Ok(ImportResult::AlreadyInChain), Ok(blockchain::BlockStatus::Unknown) => {}, Err(e) => return Err(ConsensusError::ClientImport(e.to_string()).into()), } - let slot_number = { - let pre_digest = find_pre_digest::(&block.header) - .expect("valid babe headers must contain a predigest; \ - header has been already verified; qed"); - let BabePreDigest { slot_number, .. } = pre_digest; - slot_number - }; - - // returns a function for checking whether a block is a descendent of another - // consistent with querying client directly after importing the block. - let parent_hash = *block.header.parent_hash(); - let is_descendent_of = is_descendent_of(&self.client, Some((&hash, &parent_hash))); + let pre_digest = find_pre_digest::(&block.header) + .expect("valid babe headers must contain a predigest; \ + header has been already verified; qed"); + let slot_number = pre_digest.slot_number(); - // check if there's any epoch change expected to happen at this slot let mut epoch_changes = self.epoch_changes.lock(); - let enacted_epoch = epoch_changes.find_node_where( - &hash, - &number, - &is_descendent_of, - &|epoch| epoch.start_slot <= slot_number, - ).map_err(|e| ConsensusError::from(ConsensusError::ClientImport(e.to_string())))?; - - let check_roots = || -> Result { - // this can only happen when the chain starts, since there's no - // epoch change at genesis. afterwards every time we expect an epoch - // change it means we will import another one. - for (root, _, _) in epoch_changes.roots() { - let is_descendent_of = is_descendent_of(root, &hash) - .map_err(|e| { - ConsensusError::from(ConsensusError::ClientImport(e.to_string())) - })?; - - if is_descendent_of { - return Ok(false); - } - } - Ok(true) + // check if there's any epoch change expected to happen at this slot. + // `epoch` is the epoch to verify the block under, and `first_in_epoch` is true + // if this is the first block in its chain for that epoch. + // + // also provides the total weight of the chain, including the imported block. + let (epoch, first_in_epoch, parent_weight) = { + let parent_hash = *block.header.parent_hash(); + let parent_header = self.client.header(&BlockId::Hash(parent_hash)) + .map_err(|e| ConsensusError::ChainLookup(e.to_string()))? + .ok_or_else(|| ConsensusError::ChainLookup(babe_err!( + "Parent ({}) of {} unavailable. Cannot import", + parent_hash, + hash + )))?; + + let parent_slot = find_pre_digest::(&parent_header) + .map(|d| d.slot_number()) + .expect("parent is non-genesis; valid BABE headers contain a pre-digest; \ + header has already been verified; qed"); + + let parent_weight = if *parent_header.number() == Zero::zero() { + 0 + } else { + aux_schema::load_block_weight(&*self.client, parent_hash) + .map_err(|e| ConsensusError::ClientImport(e.to_string()))? + .ok_or_else(|| ConsensusError::ClientImport( + babe_err!("Parent block of {} has no associated weight", hash) + ))? + }; + + let epoch = epoch_changes.epoch_for_child_of( + descendent_query(&*self.client), + &parent_hash, + *parent_header.number(), + slot_number, + |slot| self.config.genesis_epoch(slot), + ) + .map_err(|e: fork_tree::Error| ConsensusError::ChainLookup( + babe_err!("Could not look up epoch: {:?}", e) + ))? + .ok_or_else(|| ConsensusError::ClientImport( + babe_err!("Block {} is not valid under any epoch.", hash) + ))?; + + let first_in_epoch = parent_slot < epoch.as_ref().start_slot; + (epoch, first_in_epoch, parent_weight) }; - let expected_epoch_change = enacted_epoch.is_some(); + let total_weight = parent_weight + pre_digest.added_weight(); + + // search for this all the time so we can reject unexpected announcements. let next_epoch_digest = find_next_epoch_digest::(&block.header) .map_err(|e| ConsensusError::from(ConsensusError::ClientImport(e.to_string())))?; - match (expected_epoch_change, next_epoch_digest.is_some()) { + match (first_in_epoch, next_epoch_digest.is_some()) { (true, true) => {}, (false, false) => {}, (true, false) => { return Err( ConsensusError::ClientImport( - "Expected epoch change to happen by this block".into(), + babe_err!("Expected epoch change to happen at {:?}, s{}", hash, slot_number), ) ); }, (false, true) => { - if !check_roots()? { - return Err(ConsensusError::ClientImport("Unexpected epoch change".into())); - } + return Err(ConsensusError::ClientImport("Unexpected epoch change".into())); }, } @@ -1056,48 +870,46 @@ impl BlockImport for BabeBlockImport= start slot {}).", + epoch.as_ref().epoch_index, hash, slot_number, epoch.as_ref().start_slot); + babe_info!("Next epoch starts at slot {}", next_epoch.as_ref().start_slot); + + // prune the tree of epochs not part of the finalized chain or + // that are not live anymore, and then track the given epoch change + // in the tree. + // NOTE: it is important that these operations are done in this + // order, otherwise if pruning after import the `is_descendent_of` + // used by pruning may not know about the block that is being + // imported. + let prune_and_import = || { + prune_finalized( + &self.client, + &mut epoch_changes, + )?; + + epoch_changes.import( + descendent_query(&*self.client), + hash, + number, + *block.header.parent_hash(), + next_epoch, + ).map_err(|e| ConsensusError::ClientImport(format!("{:?}", e)))?; + + Ok(()) + }; + + if let Err(e) = prune_and_import() { + babe_err!("Failed to launch next epoch: {:?}", e); + *epoch_changes = old_epoch_changes.expect("set `Some` above and not taken; qed"); + return Err(e); + } crate::aux_schema::write_epoch_changes::( &*epoch_changes, @@ -1107,6 +919,41 @@ impl BlockImport for BabeBlockImport last_best_weight { + true + } else if total_weight == last_best_weight { + number > last_best_number + } else { + false + }) + }; + let import_result = self.inner.import_block(block, new_cache); // revert to the original epoch changes in case there's an error @@ -1122,88 +969,129 @@ impl BlockImport for BabeBlockImport, ) -> Result { - self.inner.check_block(hash, parent_hash).map_err(Into::into) + self.inner.check_block(block).map_err(Into::into) } } -/// Start an import queue for the BABE consensus algorithm. This method returns -/// the import queue, some data that needs to be passed to the block authoring -/// logic (`BabeLink`), a `BabeBlockImport` which should be used by the -/// authoring when importing its own blocks, and a future that must be run to +/// Gets the best finalized block and its slot, and prunes the given epoch tree. +fn prune_finalized( + client: &Client, + epoch_changes: &mut EpochChangesFor, +) -> Result<(), ConsensusError> where + Block: BlockT, + E: CallExecutor + Send + Sync, + B: Backend, + RA: Send + Sync, +{ + let info = client.info().chain; + + let finalized_slot = { + let finalized_header = client.header(&BlockId::Hash(info.finalized_hash)) + .map_err(|e| ConsensusError::ClientImport(format!("{:?}", e)))? + .expect("best finalized hash was given by client; \ + finalized headers must exist in db; qed"); + + find_pre_digest::(&finalized_header) + .expect("finalized header must be valid; \ + valid blocks have a pre-digest; qed") + .slot_number() + }; + + epoch_changes.prune_finalized( + descendent_query(&*client), + &info.finalized_hash, + info.finalized_number, + finalized_slot, + ).map_err(|e| ConsensusError::ClientImport(format!("{:?}", e)))?; + + Ok(()) +} + +/// Produce a BABE block-import object to be used later on in the construction of +/// an import-queue. +/// +/// Also returns a link object used to correctly instantiate the import queue +/// and background worker. +pub fn block_import, I, RA, PRA>( + config: Config, + wrapped_block_import: I, + client: Arc>, + api: Arc, +) -> ClientResult<(BabeBlockImport, BabeLink)> where + B: Backend, + E: CallExecutor + Send + Sync, + RA: Send + Sync, +{ + let epoch_changes = aux_schema::load_epoch_changes(&*client)?; + let link = BabeLink { + epoch_changes: epoch_changes.clone(), + time_source: Default::default(), + config: config.clone(), + }; + + // NOTE: this isn't entirely necessary, but since we didn't use to prune the + // epoch tree it is useful as a migration, so that nodes prune long trees on + // startup rather than waiting until importing the next epoch change block. + prune_finalized( + &client, + &mut epoch_changes.lock(), + )?; + + let import = BabeBlockImport::new( + client, + api, + epoch_changes, + wrapped_block_import, + config, + ); + + Ok((import, link)) +} + +/// Start an import queue for the BABE consensus algorithm. +/// +/// This method returns the import queue, some data that needs to be passed to the block authoring +/// logic (`BabeLink`), and a future that must be run to /// completion and is responsible for listening to finality notifications and /// pruning the epoch changes tree. -pub fn import_queue, I, RA, PRA, T>( - config: Config, +/// +/// The block import object provided must be the `BabeBlockImport` or a wrapper +/// of it, otherwise crucial import logic will be omitted. +pub fn import_queue, I, RA, PRA>( + babe_link: BabeLink, block_import: I, justification_import: Option>, finality_proof_import: Option>, client: Arc>, api: Arc, inherent_data_providers: InherentDataProviders, - transaction_pool: Option>, -) -> ClientResult<( - BabeImportQueue, - BabeLink, - BabeBlockImport, - impl futures01::Future, -)> where +) -> ClientResult> where B: Backend + 'static, - I: BlockImport + Clone + Send + Sync + 'static, - I::Error: Into, + I: BlockImport + Send + Sync + 'static, E: CallExecutor + Clone + Send + Sync + 'static, RA: Send + Sync + 'static, PRA: ProvideRuntimeApi + ProvideCache + Send + Sync + AuxStore + 'static, PRA::Api: BlockBuilderApi + BabeApi, - T: Send + Sync + 'static, { - register_babe_inherent_data_provider(&inherent_data_providers, config.get())?; - initialize_authorities_cache(&*api)?; + register_babe_inherent_data_provider(&inherent_data_providers, babe_link.config.slot_duration)?; let verifier = BabeVerifier { - api: api.clone(), + client: client.clone(), + api, inherent_data_providers, - time_source: Default::default(), - config, - transaction_pool, + config: babe_link.config, + epoch_changes: babe_link.epoch_changes, + time_source: babe_link.time_source, }; - #[allow(deprecated)] - let epoch_changes = aux_schema::load_epoch_changes(&**client.backend())?; - - let block_import = BabeBlockImport::new( - client.clone(), - api, - epoch_changes.clone(), - block_import, - ); - - let pruning_task = client.finality_notification_stream() - .map(|v| Ok::<_, ()>(v)).compat() - .for_each(move |notification| { - let is_descendent_of = is_descendent_of(&client, None); - epoch_changes.lock().prune( - ¬ification.hash, - *notification.header.number(), - &is_descendent_of, - ).map_err(|e| { - debug!(target: "babe", "Error pruning epoch changes fork tree: {:?}", e) - })?; - - Ok(()) - }); - - let timestamp_core = verifier.time_source.clone(); - let queue = BasicQueue::new( + Ok(BasicQueue::new( verifier, - Box::new(block_import.clone()), + Box::new(block_import), justification_import, finality_proof_import, - ); - - Ok((queue, timestamp_core, block_import, pruning_task)) + )) } /// BABE test helpers. Utility methods for manually authoring blocks. @@ -1214,30 +1102,29 @@ pub mod test_helpers { /// Try to claim the given slot and return a `BabePreDigest` if /// successful. pub fn claim_slot( - client: &C, - at: &BlockId, slot_number: u64, - c: (u64, u64), + parent: &B::Header, + client: &C, keystore: &KeyStorePtr, + link: &BabeLink, ) -> Option where - B: BlockT, - C: ProvideRuntimeApi + ProvideCache, + B: BlockT, + C: ProvideRuntimeApi + ProvideCache + HeaderBackend + HeaderMetadata, C::Api: BabeApi, { - let epoch = epoch(client, at).unwrap(); + let epoch = link.epoch_changes.lock().epoch_for_child_of( + descendent_query(client), + &parent.hash(), + parent.number().clone(), + slot_number, + |slot| link.config.genesis_epoch(slot), + ).unwrap().unwrap(); - super::claim_slot( + authorship::claim_slot( slot_number, - epoch, - c, + epoch.as_ref(), + &link.config, keystore, - ).map(|((inout, vrf_proof, _), authority_index, _)| { - BabePreDigest { - vrf_proof, - vrf_output: inout.to_output(), - authority_index: authority_index as u32, - slot_number, - } - }) + ).map(|(digest, _)| digest) } } diff --git a/core/consensus/babe/src/tests.rs b/core/consensus/babe/src/tests.rs index 01e0acb96402abc568eac216b2e5025b2b1a7991..46c038b187b93471d1f9c317fd39c4e49c5cf879 100644 --- a/core/consensus/babe/src/tests.rs +++ b/core/consensus/babe/src/tests.rs @@ -20,22 +20,26 @@ // https://github.com/paritytech/substrate/issues/2532 #![allow(deprecated)] use super::*; -use super::generic::DigestItem; +use authorship::claim_slot; -use babe_primitives::AuthorityPair; -use client::{LongestChain, block_builder::BlockBuilder}; +use babe_primitives::{AuthorityPair, SlotNumber}; +use client::block_builder::BlockBuilder; use consensus_common::NoNetwork as DummyOracle; +use consensus_common::import_queue::{ + BoxBlockImport, BoxJustificationImport, BoxFinalityProofImport, +}; use network::test::*; use network::test::{Block as TestBlock, PeersClient}; -use sr_primitives::traits::{Block as BlockT, DigestFor}; +use network::config::BoxFinalityProofRequestBuilder; +use sr_primitives::{generic::DigestItem, traits::{Block as BlockT, DigestFor}}; use network::config::ProtocolConfig; use tokio::runtime::current_thread; -use keyring::sr25519::Keyring; use client::BlockchainEvents; use test_client; use log::debug; -use std::{time::Duration, borrow::Borrow, cell::RefCell}; -type Item = generic::DigestItem; +use std::{time::Duration, cell::RefCell}; + +type Item = DigestItem; type Error = client::error::Error; @@ -46,8 +50,28 @@ type TestClient = client::Client< test_client::runtime::RuntimeApi, >; -struct DummyFactory(Arc); -struct DummyProposer(u64, Arc); +#[derive(Copy, Clone, PartialEq)] +enum Stage { + PreSeal, + PostSeal, +} + +type Mutator = Arc; + +#[derive(Clone)] +struct DummyFactory { + client: Arc, + epoch_changes: crate::SharedEpochChanges, + config: Config, + mutator: Mutator, +} + +struct DummyProposer { + factory: DummyFactory, + parent_hash: Hash, + parent_number: u64, + parent_slot: SlotNumber, +} impl Environment for DummyFactory { type Proposer = DummyProposer; @@ -56,7 +80,71 @@ impl Environment for DummyFactory { fn init(&mut self, parent_header: &::Header) -> Result { - Ok(DummyProposer(parent_header.number + 1, self.0.clone())) + + let parent_slot = crate::find_pre_digest(parent_header) + .expect("parent header has a pre-digest") + .slot_number(); + + Ok(DummyProposer { + factory: self.clone(), + parent_hash: parent_header.hash(), + parent_number: *parent_header.number(), + parent_slot, + }) + } +} + +impl DummyProposer { + fn propose_with(&mut self, pre_digests: DigestFor) + -> future::Ready> + { + use codec::Encode; + let block_builder = self.factory.client.new_block_at( + &BlockId::Hash(self.parent_hash), + pre_digests, + ).unwrap(); + + let mut block = match block_builder.bake().map_err(|e| e.into()) { + Ok(b) => b, + Err(e) => return future::ready(Err(e)), + }; + + let this_slot = crate::find_pre_digest(block.header()) + .expect("baked block has valid pre-digest") + .slot_number(); + + // figure out if we should add a consensus digest, since the test runtime + // doesn't. + let epoch_changes = self.factory.epoch_changes.lock(); + let epoch = epoch_changes.epoch_for_child_of( + descendent_query(&*self.factory.client), + &self.parent_hash, + self.parent_number, + this_slot, + |slot| self.factory.config.genesis_epoch(slot), + ) + .expect("client has data to find epoch") + .expect("can compute epoch for baked block") + .into_inner(); + + let first_in_epoch = self.parent_slot < epoch.start_slot; + if first_in_epoch { + // push a `Consensus` digest signalling next change. + // we just reuse the same randomness and authorities as the prior + // epoch. this will break when we add light client support, since + // that will re-check the randomness logic off-chain. + let digest_data = ConsensusLog::NextEpochData(NextEpochDescriptor { + authorities: epoch.authorities.clone(), + randomness: epoch.randomness.clone(), + }).encode(); + let digest = DigestItem::Consensus(BABE_ENGINE_ID, digest_data); + block.header.digest_mut().push(digest) + } + + // mutate the block header according to the mutator. + (self.factory.mutator)(&mut block.header, Stage::PreSeal); + + future::ready(Ok(block)) } } @@ -67,28 +155,54 @@ impl Proposer for DummyProposer { fn propose( &mut self, _: InherentData, - digests: DigestFor, + pre_digests: DigestFor, _: Duration, ) -> Self::Create { - future::ready(self.1.new_block(digests).unwrap().bake().map_err(|e| e.into())) + self.propose_with(pre_digests) } } -type Mutator = Arc Fn(&'r mut TestHeader) + Send + Sync>; - thread_local! { - static MUTATOR: RefCell = RefCell::new(Arc::new(|_|())); + static MUTATOR: RefCell = RefCell::new(Arc::new(|_, _|())); +} + +#[derive(Clone)] +struct PanickingBlockImport(B); + +impl> BlockImport for PanickingBlockImport { + type Error = B::Error; + + fn import_block( + &mut self, + block: BlockImportParams, + new_cache: HashMap>, + ) -> Result { + Ok(self.0.import_block(block, new_cache).expect("importing block failed")) + } + + fn check_block( + &mut self, + block: BlockCheckParams, + ) -> Result { + Ok(self.0.check_block(block).expect("checking block failed")) + } } pub struct BabeTestNet { - peers: Vec>, + peers: Vec, DummySpecialization>>, } type TestHeader = ::Header; type TestExtrinsic = ::Extrinsic; pub struct TestVerifier { - inner: BabeVerifier, + inner: BabeVerifier< + test_client::Backend, + test_client::Executor, + TestBlock, + test_client::runtime::RuntimeApi, + PeersFullClient, + >, mutator: Mutator, } @@ -103,16 +217,22 @@ impl Verifier for TestVerifier { justification: Option, body: Option>, ) -> Result<(BlockImportParams, Option)>>), String> { - let cb: &(dyn Fn(&mut TestHeader) + Send + Sync) = self.mutator.borrow(); - cb(&mut header); + // apply post-sealing mutations (i.e. stripping seal, if desired). + (self.mutator)(&mut header, Stage::PostSeal); Ok(self.inner.verify(origin, header, justification, body).expect("verification failed!")) } } +pub struct PeerData { + link: BabeLink, + inherent_data_providers: InherentDataProviders, + block_import: Mutex>>, +} + impl TestNetFactory for BabeTestNet { type Specialization = DummySpecialization; type Verifier = TestVerifier; - type PeerData = (); + type PeerData = Option; /// Create new test network with peers and given config. fn from_config(_config: &ProtocolConfig) -> Self { @@ -122,30 +242,62 @@ impl TestNetFactory for BabeTestNet { } } - /// KLUDGE: this function gets the mutator from thread-local storage. - fn make_verifier(&self, client: PeersClient, _cfg: &ProtocolConfig) + fn make_block_import(&self, client: PeersClient) + -> ( + BoxBlockImport, + Option>, + Option>, + Option>, + Option, + ) + { + let client = client.as_full().expect("only full clients are tested"); + let inherent_data_providers = InherentDataProviders::new(); + + let config = Config::get_or_compute(&*client).expect("config available"); + let (block_import, link) = crate::block_import( + config, + client.clone(), + client.clone(), + client.clone(), + ).expect("can initialize block-import"); + + let block_import = PanickingBlockImport(block_import); + + let data_block_import = Mutex::new(Some(Box::new(block_import.clone()) as BoxBlockImport<_>)); + ( + Box::new(block_import), + None, + None, + None, + Some(PeerData { link, inherent_data_providers, block_import: data_block_import }), + ) + } + + fn make_verifier( + &self, + client: PeersClient, + _cfg: &ProtocolConfig, + maybe_link: &Option, + ) -> Self::Verifier { - let api = client.as_full().expect("only full clients are used in test"); + let client = client.as_full().expect("only full clients are used in test"); trace!(target: "babe", "Creating a verifier"); - let config = Config::get_or_compute(&*api) - .expect("slot duration available"); - let inherent_data_providers = InherentDataProviders::new(); - register_babe_inherent_data_provider( - &inherent_data_providers, - config.get() - ).expect("Registers babe inherent data provider"); - trace!(target: "babe", "Provider registered"); + + // ensure block import and verifier are linked correctly. + let data = maybe_link.as_ref().expect("babe link always provided to verifier instantiation"); TestVerifier { inner: BabeVerifier { - api, - inherent_data_providers, - config, - time_source: Default::default(), - transaction_pool : Default::default(), + client: client.clone(), + api: client, + inherent_data_providers: data.inherent_data_providers.clone(), + config: data.link.config.clone(), + epoch_changes: data.link.epoch_changes.clone(), + time_source: data.link.time_source.clone(), }, - mutator: MUTATOR.with(|s| s.borrow().clone()), + mutator: MUTATOR.with(|m| m.borrow().clone()), } } @@ -180,8 +332,13 @@ fn rejects_empty_block() { }) } -fn run_one_test() { +fn run_one_test( + mutator: impl Fn(&mut TestHeader, Stage) + Send + Sync + 'static, +) { let _ = env_logger::try_init(); + let mutator = Arc::new(mutator) as Mutator; + + MUTATOR.with(|m| *m.borrow_mut() = mutator.clone()); let net = BabeTestNet::new(3); let peers = &[ @@ -194,40 +351,58 @@ fn run_one_test() { let mut import_notifications = Vec::new(); let mut runtime = current_thread::Runtime::new().unwrap(); let mut keystore_paths = Vec::new(); + for (peer_id, seed) in peers { + let mut net = net.lock(); + let peer = net.peer(*peer_id); + let client = peer.client().as_full().expect("Only full clients are used in tests").clone(); + let select_chain = peer.select_chain().expect("Full client has select_chain"); + let keystore_path = tempfile::tempdir().expect("Creates keystore path"); let keystore = keystore::Store::open(keystore_path.path(), None).expect("Creates keystore"); keystore.write().insert_ephemeral_from_seed::(seed).expect("Generates authority key"); keystore_paths.push(keystore_path); - let client = net.lock().peer(*peer_id).client().as_full().unwrap(); - let environ = DummyFactory(client.clone()); + let mut got_own = false; + let mut got_other = false; + + let data = peer.data.as_ref().expect("babe link set up during initialization"); + + let environ = DummyFactory { + client: client.clone(), + config: data.link.config.clone(), + epoch_changes: data.link.epoch_changes.clone(), + mutator: mutator.clone(), + }; + import_notifications.push( + // run each future until we get one of our own blocks with number higher than 5 + // that was produced locally. client.import_notification_stream() - .take_while(|n| future::ready(!(n.origin != BlockOrigin::Own && n.header.number() < &5))) - .for_each(move |_| future::ready(())) + .take_while(move |n| future::ready(n.header.number() < &5 || { + if n.origin == BlockOrigin::Own { + got_own = true; + } else { + got_other = true; + } + + // continue until we have at least one block of our own + // and one of another peer. + !(got_own && got_other) + })) + .for_each(|_| future::ready(()) ) ); - let config = Config::get_or_compute(&*client).expect("slot duration available"); - - let inherent_data_providers = InherentDataProviders::new(); - register_babe_inherent_data_provider( - &inherent_data_providers, config.get() - ).expect("Registers babe inherent data provider"); - - #[allow(deprecated)] - let select_chain = LongestChain::new(client.backend().clone()); runtime.spawn(start_babe(BabeParams { - config, - block_import: client.clone(), + block_import: data.block_import.lock().take().expect("import set up during init"), select_chain, client, env: environ, sync_oracle: DummyOracle, - inherent_data_providers, + inherent_data_providers: data.inherent_data_providers.clone(), force_authoring: false, - time_source: Default::default(), + babe_link: data.link.clone(), keystore, }).expect("Starts babe")); } @@ -242,45 +417,41 @@ fn run_one_test() { } #[test] -fn authoring_blocks() { run_one_test() } +fn authoring_blocks() { + run_one_test(|_, _| ()) +} #[test] #[should_panic] fn rejects_missing_inherent_digest() { - MUTATOR.with(|s| *s.borrow_mut() = Arc::new(move |header: &mut TestHeader| { + run_one_test(|header: &mut TestHeader, stage| { let v = std::mem::replace(&mut header.digest_mut().logs, vec![]); header.digest_mut().logs = v.into_iter() - .filter(|v| v.as_babe_pre_digest().is_none()) + .filter(|v| stage == Stage::PostSeal || v.as_babe_pre_digest().is_none()) .collect() - })); - run_one_test() + }) } #[test] #[should_panic] fn rejects_missing_seals() { - MUTATOR.with(|s| *s.borrow_mut() = Arc::new(move |header: &mut TestHeader| { + run_one_test(|header: &mut TestHeader, stage| { let v = std::mem::replace(&mut header.digest_mut().logs, vec![]); header.digest_mut().logs = v.into_iter() - .filter(|v| v.as_babe_seal().is_none()) + .filter(|v| stage == Stage::PreSeal || v.as_babe_seal().is_none()) .collect() - })); - run_one_test() + }) } -// TODO: this test assumes that the test runtime will trigger epoch changes -// which isn't the case since it doesn't include the session module. #[test] #[should_panic] -#[ignore] fn rejects_missing_consensus_digests() { - MUTATOR.with(|s| *s.borrow_mut() = Arc::new(move |header: &mut TestHeader| { + run_one_test(|header: &mut TestHeader, stage| { let v = std::mem::replace(&mut header.digest_mut().logs, vec![]); header.digest_mut().logs = v.into_iter() - .filter(|v| v.as_babe_epoch().is_none()) + .filter(|v| stage == Stage::PostSeal || v.as_next_epoch_descriptor().is_none()) .collect() - })); - run_one_test() + }); } #[test] @@ -324,26 +495,266 @@ fn can_author_block() { epoch_index: 1, duration: 100, }; + + let mut config = crate::BabeConfiguration { + slot_duration: 1000, + epoch_length: 100, + c: (3, 10), + genesis_authorities: Vec::new(), + randomness: [0; 32], + secondary_slots: true, + }; + + // with secondary slots enabled it should never be empty + match claim_slot(i, &epoch, &config, &keystore) { + None => i += 1, + Some(s) => debug!(target: "babe", "Authored block {:?}", s.0), + } + + // otherwise with only vrf-based primary slots we might need to try a couple + // of times. + config.secondary_slots = false; loop { - match claim_slot(i, epoch.clone(), (3, 10), &keystore) { + match claim_slot(i, &epoch, &config, &keystore) { None => i += 1, Some(s) => { debug!(target: "babe", "Authored block {:?}", s.0); - break + break; } } } } #[test] -fn authorities_call_works() { - let _ = env_logger::try_init(); - let client = test_client::new(); - - assert_eq!(client.info().chain.best_number, 0); - assert_eq!(epoch(&client, &BlockId::Number(0)).unwrap().authorities, vec![ - (Keyring::Alice.public().into(), 1), - (Keyring::Bob.public().into(), 1), - (Keyring::Charlie.public().into(), 1), - ]); +fn importing_block_one_sets_genesis_epoch() { + let mut net = BabeTestNet::new(1); + + let peer = net.peer(0); + let data = peer.data.as_ref().expect("babe link set up during initialization"); + let client = peer.client().as_full().expect("Only full clients are used in tests").clone(); + + let mut environ = DummyFactory { + client: client.clone(), + config: data.link.config.clone(), + epoch_changes: data.link.epoch_changes.clone(), + mutator: Arc::new(|_, _| ()), + }; + + let genesis_header = client.header(&BlockId::Number(0)).unwrap().unwrap(); + + let mut proposer = environ.init(&genesis_header).unwrap(); + let babe_claim = Item::babe_pre_digest(babe_primitives::BabePreDigest::Secondary { + authority_index: 0, + slot_number: 999, + }); + let pre_digest = sr_primitives::generic::Digest { logs: vec![babe_claim] }; + + let genesis_epoch = data.link.config.genesis_epoch(999); + + let mut block = futures::executor::block_on(proposer.propose_with(pre_digest)).unwrap(); + + // seal by alice. + let seal = { + // sign the pre-sealed hash of the block and then + // add it to a digest item. + let pair = AuthorityPair::from_seed(&[1; 32]); + let pre_hash = block.header.hash(); + let signature = pair.sign(pre_hash.as_ref()); + Item::babe_seal(signature) + }; + + let post_hash = { + block.header.digest_mut().push(seal.clone()); + let h = block.header.hash(); + block.header.digest_mut().pop(); + h + }; + assert_eq!(*block.header.number(), 1); + let (header, body) = block.deconstruct(); + + let post_digests = vec![seal]; + let mut block_import = data.block_import.lock().take().expect("import set up during init"); + block_import.import_block( + BlockImportParams { + origin: BlockOrigin::Own, + header, + justification: None, + post_digests, + body: Some(body), + finalized: false, + auxiliary: Vec::new(), + fork_choice: ForkChoiceStrategy::LongestChain, + }, + Default::default(), + ).unwrap(); + + let epoch_changes = data.link.epoch_changes.lock(); + let epoch_for_second_block = epoch_changes.epoch_for_child_of( + descendent_query(&*client), + &post_hash, + 1, + 1000, + |slot| data.link.config.genesis_epoch(slot), + ).unwrap().unwrap().into_inner(); + assert_eq!(epoch_for_second_block, genesis_epoch); +} + +#[test] +fn importing_epoch_change_block_prunes_tree() { + use client::backend::Finalizer; + + let mut net = BabeTestNet::new(1); + + let peer = net.peer(0); + let data = peer.data.as_ref().expect("babe link set up during initialization"); + + let client = peer.client().as_full().expect("Only full clients are used in tests").clone(); + let mut block_import = data.block_import.lock().take().expect("import set up during init"); + let epoch_changes = data.link.epoch_changes.clone(); + + // This is just boilerplate code for proposing and importing a valid BABE + // block that's built on top of the given parent. The proposer takes care + // of producing epoch change digests according to the epoch duration (which + // is set to 6 slots in the test runtime). + let mut propose_and_import_block = |parent_header| { + let mut environ = DummyFactory { + client: client.clone(), + config: data.link.config.clone(), + epoch_changes: data.link.epoch_changes.clone(), + mutator: Arc::new(|_, _| ()), + }; + + let mut proposer = environ.init(&parent_header).unwrap(); + let parent_pre_digest = find_pre_digest(&parent_header).unwrap(); + + let pre_digest = sr_primitives::generic::Digest { + logs: vec![ + Item::babe_pre_digest( + BabePreDigest::Secondary { + authority_index: 0, + slot_number: parent_pre_digest.slot_number() + 1, + }, + ), + ], + }; + + let mut block = futures::executor::block_on(proposer.propose_with(pre_digest)).unwrap(); + + let seal = { + // sign the pre-sealed hash of the block and then + // add it to a digest item. + let pair = AuthorityPair::from_seed(&[1; 32]); + let pre_hash = block.header.hash(); + let signature = pair.sign(pre_hash.as_ref()); + Item::babe_seal(signature) + }; + + let post_hash = { + block.header.digest_mut().push(seal.clone()); + let h = block.header.hash(); + block.header.digest_mut().pop(); + h + }; + + let next_epoch_digest = + find_next_epoch_digest::(&block.header).unwrap(); + + let import_result = block_import.import_block( + BlockImportParams { + origin: BlockOrigin::Own, + header: block.header, + justification: None, + post_digests: vec![seal], + body: Some(block.extrinsics), + finalized: false, + auxiliary: Vec::new(), + fork_choice: ForkChoiceStrategy::LongestChain, + }, + Default::default(), + ).unwrap(); + + match import_result { + ImportResult::Imported(_) => {}, + _ => panic!("expected block to be imported"), + } + + (post_hash, next_epoch_digest) + }; + + let mut propose_and_import_blocks = |parent_id, n| { + let mut hashes = Vec::new(); + let mut parent_header = client.header(&parent_id).unwrap().unwrap(); + + for _ in 0..n { + let (block_hash, _) = propose_and_import_block(parent_header); + hashes.push(block_hash); + parent_header = client.header(&BlockId::Hash(block_hash)).unwrap().unwrap(); + } + + hashes + }; + + // This is the block tree that we're going to use in this test. Each node + // represents an epoch change block, the epoch duration is 6 slots. + // + // *---- F (#7) + // / *------ G (#19) - H (#25) + // / / + // A (#1) - B (#7) - C (#13) - D (#19) - E (#25) + // \ + // *------ I (#25) + + // Create and import the canon chain and keep track of fork blocks (A, C, D) + // from the diagram above. + let canon_hashes = propose_and_import_blocks(BlockId::Number(0), 30); + + // Create the forks + let fork_1 = propose_and_import_blocks(BlockId::Hash(canon_hashes[0]), 10); + let fork_2 = propose_and_import_blocks(BlockId::Hash(canon_hashes[12]), 15); + let fork_3 = propose_and_import_blocks(BlockId::Hash(canon_hashes[18]), 10); + + // We should be tracking a total of 9 epochs in the fork tree + assert_eq!( + epoch_changes.lock().tree().iter().count(), + 9, + ); + + // And only one root + assert_eq!( + epoch_changes.lock().tree().roots().count(), + 1, + ); + + // We finalize block #13 from the canon chain, so on the next epoch + // change the tree should be pruned, to not contain F (#7). + client.finalize_block(BlockId::Hash(canon_hashes[12]), None, false).unwrap(); + propose_and_import_blocks(BlockId::Hash(client.info().chain.best_hash), 7); + + // at this point no hashes from the first fork must exist on the tree + assert!( + !epoch_changes.lock().tree().iter().map(|(h, _, _)| h).any(|h| fork_1.contains(h)), + ); + + // but the epoch changes from the other forks must still exist + assert!( + epoch_changes.lock().tree().iter().map(|(h, _, _)| h).any(|h| fork_2.contains(h)) + ); + + assert!( + epoch_changes.lock().tree().iter().map(|(h, _, _)| h).any(|h| fork_3.contains(h)), + ); + + // finalizing block #25 from the canon chain should prune out the second fork + client.finalize_block(BlockId::Hash(canon_hashes[24]), None, false).unwrap(); + propose_and_import_blocks(BlockId::Hash(client.info().chain.best_hash), 8); + + // at this point no hashes from the second fork must exist on the tree + assert!( + !epoch_changes.lock().tree().iter().map(|(h, _, _)| h).any(|h| fork_2.contains(h)), + ); + + // while epoch changes from the last fork should still exist + assert!( + epoch_changes.lock().tree().iter().map(|(h, _, _)| h).any(|h| fork_3.contains(h)), + ); } diff --git a/core/consensus/babe/src/verification.rs b/core/consensus/babe/src/verification.rs new file mode 100644 index 0000000000000000000000000000000000000000..05d610245060b75359b7e3d296afd79af707b0f1 --- /dev/null +++ b/core/consensus/babe/src/verification.rs @@ -0,0 +1,232 @@ +// Copyright 2019 Parity Technologies (UK) Ltd. +// This file is part of Substrate. + +// Substrate 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. + +// Substrate 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 Substrate. If not, see . + +//! Verification for BABE headers. +use schnorrkel::vrf::{VRFOutput, VRFProof}; +use sr_primitives::{traits::Header, traits::DigestItemFor}; +use primitives::{Pair, Public}; +use babe_primitives::{Epoch, BabePreDigest, CompatibleDigestItem, AuthorityId}; +use babe_primitives::{AuthoritySignature, SlotNumber, AuthorityIndex, AuthorityPair}; +use slots::CheckedHeader; +use log::{debug, trace}; +use super::{find_pre_digest, BlockT}; +use super::authorship::{make_transcript, calculate_primary_threshold, check_primary_threshold, secondary_slot_author}; + +/// BABE verification parameters +pub(super) struct VerificationParams<'a, B: 'a + BlockT> { + /// the header being verified. + pub(super) header: B::Header, + /// the pre-digest of the header being verified. this is optional - if prior + /// verification code had to read it, it can be included here to avoid duplicate + /// work. + pub(super) pre_digest: Option, + /// the slot number of the current time. + pub(super) slot_now: SlotNumber, + /// epoch descriptor of the epoch this block _should_ be under, if it's valid. + pub(super) epoch: &'a Epoch, + /// genesis config of this BABE chain. + pub(super) config: &'a super::Config, +} + +macro_rules! babe_err { + ($($i: expr),+) => { + { + debug!(target: "babe", $($i),+); + format!($($i),+) + } + }; +} + +/// Check a header has been signed by the right key. If the slot is too far in +/// the future, an error will be returned. If successful, returns the pre-header +/// and the digest item containing the seal. +/// +/// The seal must be the last digest. Otherwise, the whole header is considered +/// unsigned. This is required for security and must not be changed. +/// +/// This digest item will always return `Some` when used with `as_babe_pre_digest`. +/// +/// The given header can either be from a primary or secondary slot assignment, +/// with each having different validation logic. +pub(super) fn check_header( + params: VerificationParams, +) -> Result>, String> where + DigestItemFor: CompatibleDigestItem, +{ + let VerificationParams { + mut header, + pre_digest, + slot_now, + epoch, + config, + } = params; + + let authorities = &epoch.authorities; + let pre_digest = pre_digest.map(Ok).unwrap_or_else(|| find_pre_digest::(&header))?; + + trace!(target: "babe", "Checking header"); + let seal = match header.digest_mut().pop() { + Some(x) => x, + None => return Err(babe_err!("Header {:?} is unsealed", header.hash())), + }; + + let sig = seal.as_babe_seal().ok_or_else(|| { + babe_err!("Header {:?} has a bad seal", header.hash()) + })?; + + // the pre-hash of the header doesn't include the seal + // and that's what we sign + let pre_hash = header.hash(); + + if pre_digest.slot_number() > slot_now { + header.digest_mut().push(seal); + return Ok(CheckedHeader::Deferred(header, pre_digest.slot_number())); + } + + let author = match authorities.get(pre_digest.authority_index() as usize) { + Some(author) => author.0.clone(), + None => return Err(babe_err!("Slot author not found")), + }; + + match &pre_digest { + BabePreDigest::Primary { vrf_output, vrf_proof, authority_index, slot_number } => { + debug!(target: "babe", "Verifying Primary block"); + + let digest = (vrf_output, vrf_proof, *authority_index, *slot_number); + + check_primary_header::( + pre_hash, + digest, + sig, + &epoch, + config.c, + )?; + }, + BabePreDigest::Secondary { authority_index, slot_number } if config.secondary_slots => { + debug!(target: "babe", "Verifying Secondary block"); + + let digest = (*authority_index, *slot_number); + + check_secondary_header::( + pre_hash, + digest, + sig, + &epoch, + )?; + }, + _ => { + return Err(babe_err!("Secondary slot assignments are disabled for the current epoch.")); + } + } + + let info = VerifiedHeaderInfo { + pre_digest: CompatibleDigestItem::babe_pre_digest(pre_digest), + seal, + author, + }; + Ok(CheckedHeader::Checked(header, info)) +} + +pub(super) struct VerifiedHeaderInfo { + pub(super) pre_digest: DigestItemFor, + pub(super) seal: DigestItemFor, + pub(super) author: AuthorityId, +} + +/// Check a primary slot proposal header. We validate that the given header is +/// properly signed by the expected authority, and that the contained VRF proof +/// is valid. Additionally, the weight of this block must increase compared to +/// its parent since it is a primary block. +fn check_primary_header( + pre_hash: B::Hash, + pre_digest: (&VRFOutput, &VRFProof, AuthorityIndex, SlotNumber), + signature: AuthoritySignature, + epoch: &Epoch, + c: (u64, u64), +) -> Result<(), String> { + let (vrf_output, vrf_proof, authority_index, slot_number) = pre_digest; + + let author = &epoch.authorities[authority_index as usize].0; + + if AuthorityPair::verify(&signature, pre_hash, &author) { + let (inout, _) = { + let transcript = make_transcript( + &epoch.randomness, + slot_number, + epoch.epoch_index, + ); + + schnorrkel::PublicKey::from_bytes(author.as_slice()).and_then(|p| { + p.vrf_verify(transcript, vrf_output, vrf_proof) + }).map_err(|s| { + babe_err!("VRF verification failed: {:?}", s) + })? + }; + + let threshold = calculate_primary_threshold( + c, + &epoch.authorities, + authority_index as usize, + ); + + if !check_primary_threshold(&inout, threshold) { + return Err(babe_err!("VRF verification of block by author {:?} failed: \ + threshold {} exceeded", author, threshold)); + } + + Ok(()) + } else { + Err(babe_err!("Bad signature on {:?}", pre_hash)) + } +} + +/// Check a secondary slot proposal header. We validate that the given header is +/// properly signed by the expected authority, which we have a deterministic way +/// of computing. Additionally, the weight of this block must stay the same +/// compared to its parent since it is a secondary block. +fn check_secondary_header( + pre_hash: B::Hash, + pre_digest: (AuthorityIndex, SlotNumber), + signature: AuthoritySignature, + epoch: &Epoch, +) -> Result<(), String> { + let (authority_index, slot_number) = pre_digest; + + // check the signature is valid under the expected authority and + // chain state. + let expected_author = secondary_slot_author( + slot_number, + &epoch.authorities, + epoch.randomness, + ).ok_or_else(|| "No secondary author expected.".to_string())?; + + let author = &epoch.authorities[authority_index as usize].0; + + if expected_author != author { + let msg = format!("Invalid author: Expected secondary author: {:?}, got: {:?}.", + expected_author, + author, + ); + + return Err(msg); + } + + if AuthorityPair::verify(&signature, pre_hash.as_ref(), author) { + Ok(()) + } else { + Err(format!("Bad signature on {:?}", pre_hash)) + } +} diff --git a/core/consensus/common/Cargo.toml b/core/consensus/common/Cargo.toml index 46c8121207562240ac073059c497fd49a0c3b192..73a74c7ced30d58d58f008eadeab4bafe2aa759a 100644 --- a/core/consensus/common/Cargo.toml +++ b/core/consensus/common/Cargo.toml @@ -6,13 +6,13 @@ description = "Common utilities for substrate consensus" edition = "2018" [dependencies] -derive_more = "0.14.0" -libp2p = { version = "0.11.0", default-features = false } -log = "0.4" +derive_more = "0.15.0" +libp2p = { version = "0.12.0", default-features = false } +log = "0.4.8" primitives = { package = "substrate-primitives", path= "../../primitives" } inherents = { package = "substrate-inherents", path = "../../inherents" } -futures-preview = "=0.3.0-alpha.17" -futures-timer = "0.2.1" +futures-preview = "0.3.0-alpha.19" +futures-timer = "0.4.0" rstd = { package = "sr-std", path = "../../sr-std" } runtime_version = { package = "sr-version", path = "../../sr-version" } sr-primitives = { path = "../../sr-primitives" } diff --git a/core/consensus/common/primitives/Cargo.toml b/core/consensus/common/primitives/Cargo.toml deleted file mode 100644 index de59c3723dd7d984a56cda9c383052a7fda1069d..0000000000000000000000000000000000000000 --- a/core/consensus/common/primitives/Cargo.toml +++ /dev/null @@ -1,21 +0,0 @@ -[package] -name = "substrate-consensus-common-primitives" -version = "2.0.0" -authors = ["Parity Technologies "] -description = "Common consensus primitives" -edition = "2018" - -[dependencies] -codec = { package = "parity-scale-codec", default-features = false, version = "1.0.3" } -client = { package = "substrate-client", path = "../../../client", default-features = false } -sr-primitives = { path = "../../../sr-primitives", default-features = false } -rstd = { package = "sr-std", path = "../../../sr-std", default-features = false } - -[features] -default = ["std"] -std = [ - "rstd/std", - "client/std", - "codec/std", - "sr-primitives/std" -] diff --git a/core/consensus/common/src/block_import.rs b/core/consensus/common/src/block_import.rs index 1910a7e7751ace52512380ea349d3e137e6bef63..4342ee38df10a7626302bd57205e347fe05d3f6b 100644 --- a/core/consensus/common/src/block_import.rs +++ b/core/consensus/common/src/block_import.rs @@ -21,9 +21,8 @@ use sr_primitives::Justification; use std::borrow::Cow; use std::collections::HashMap; use std::sync::Arc; -use crate::well_known_cache_keys; -use crate::import_queue::Verifier; +use crate::import_queue::{Verifier, CacheKeyId}; /// Block import result. #[derive(Debug, PartialEq, Eq)] @@ -39,7 +38,7 @@ pub enum ImportResult { } /// Auxiliary data associated with an imported block result. -#[derive(Debug, PartialEq, Eq)] +#[derive(Debug, Default, PartialEq, Eq)] pub struct ImportedAux { /// Clear all pending justification requests. pub clear_justification_requests: bool, @@ -49,24 +48,19 @@ pub struct ImportedAux { pub bad_justification: bool, /// Request a finality proof for the given block. pub needs_finality_proof: bool, -} - -impl Default for ImportedAux { - fn default() -> ImportedAux { - ImportedAux { - clear_justification_requests: false, - needs_justification: false, - bad_justification: false, - needs_finality_proof: false, - } - } + /// Whether the block that was imported is the new best block. + pub is_new_best: bool, } impl ImportResult { - /// Returns default value for `ImportResult::Imported` with both - /// `clear_justification_requests` and `needs_justification` set to false. - pub fn imported() -> ImportResult { - ImportResult::Imported(ImportedAux::default()) + /// Returns default value for `ImportResult::Imported` with + /// `clear_justification_requests`, `needs_justification`, + /// `bad_justification` and `needs_finality_proof` set to false. + pub fn imported(is_new_best: bool) -> ImportResult { + let mut aux = ImportedAux::default(); + aux.is_new_best = is_new_best; + + ImportResult::Imported(aux) } } @@ -96,7 +90,17 @@ pub enum ForkChoiceStrategy { Custom(bool), } -/// Data required to import a Block +/// Data required to check validity of a Block. +pub struct BlockCheckParams { + /// Hash of the block that we verify. + pub hash: Block::Hash, + /// Block number of the block that we verify. + pub number: NumberFor, + /// Parent hash of the block that we verify. + pub parent_hash: Block::Hash, +} + +/// Data required to import a Block. pub struct BlockImportParams { /// Origin of the Block pub origin: BlockOrigin, @@ -126,7 +130,8 @@ pub struct BlockImportParams { /// Contains a list of key-value pairs. If values are `None`, the keys /// will be deleted. pub auxiliary: Vec<(Vec, Option>)>, - /// Fork choice strategy of this import. + /// Fork choice strategy of this import. This should only be set by a + /// synchronous import, otherwise it may race against other imports. pub fork_choice: ForkChoiceStrategy, } @@ -177,8 +182,7 @@ pub trait BlockImport { /// Check block preconditions. fn check_block( &mut self, - hash: B::Hash, - parent_hash: B::Hash, + block: BlockCheckParams, ) -> Result; /// Import a block. @@ -187,27 +191,49 @@ pub trait BlockImport { fn import_block( &mut self, block: BlockImportParams, - cache: HashMap>, + cache: HashMap>, ) -> Result; } -impl BlockImport for Arc +impl BlockImport for crate::import_queue::BoxBlockImport { + type Error = crate::error::Error; + + /// Check block preconditions. + fn check_block( + &mut self, + block: BlockCheckParams, + ) -> Result { + (**self).check_block(block) + } + + /// Import a block. + /// + /// Cached data can be accessed through the blockchain cache. + fn import_block( + &mut self, + block: BlockImportParams, + cache: HashMap>, + ) -> Result { + (**self).import_block(block, cache) + } +} + +impl BlockImport for Arc where for<'r> &'r T: BlockImport { type Error = E; fn check_block( &mut self, - hash: B::Hash, - parent_hash: B::Hash, + block: BlockCheckParams, ) -> Result { - (&**self).check_block(hash, parent_hash) + (&**self).check_block(block) } fn import_block( &mut self, block: BlockImportParams, - cache: HashMap>, + cache: HashMap>, ) -> Result { (&**self).import_block(block, cache) } diff --git a/core/consensus/common/src/block_validation.rs b/core/consensus/common/src/block_validation.rs new file mode 100644 index 0000000000000000000000000000000000000000..be181b05c6f4d2085f5dfca2012fa067911fdbd6 --- /dev/null +++ b/core/consensus/common/src/block_validation.rs @@ -0,0 +1,66 @@ +// Copyright 2019 Parity Technologies (UK) Ltd. +// This file is part of Substrate. +// +// Substrate 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. +// +// Substrate 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 Substrate. If not, see . + +//! Block announcement validation. + +use crate::BlockStatus; +use sr_primitives::{generic::BlockId, traits::Block}; +use std::{error::Error, sync::Arc}; + +/// A type which provides access to chain information. +pub trait Chain { + /// Retrieve the status of the block denoted by the given [`BlockId`]. + fn block_status(&self, id: &BlockId) -> Result>; +} + +impl, B: Block> Chain for Arc { + fn block_status(&self, id: &BlockId) -> Result> { + (&**self).block_status(id) + } +} + +/// Result of `BlockAnnounceValidator::validate`. +#[derive(Debug, PartialEq, Eq)] +pub enum Validation { + /// Valid block announcement. + Success, + /// Invalid block announcement. + Failure, +} + +/// Type which checks incoming block announcements. +pub trait BlockAnnounceValidator { + /// Validate the announced header and its associated data. + fn validate(&mut self, header: &B::Header, data: &[u8]) -> Result>; +} + +/// Default implementation of `BlockAnnounceValidator`. +#[derive(Debug)] +pub struct DefaultBlockAnnounceValidator { + chain: C +} + +impl DefaultBlockAnnounceValidator { + pub fn new(chain: C) -> Self { + Self { chain } + } +} + +impl> BlockAnnounceValidator for DefaultBlockAnnounceValidator { + fn validate(&mut self, _h: &B::Header, _d: &[u8]) -> Result> { + Ok(Validation::Success) + } +} diff --git a/core/consensus/common/src/import_queue.rs b/core/consensus/common/src/import_queue.rs index f4febb5e2396b404bdc9e05de555b33f787d6b37..dc1678fcf189d8f5aa00a514b0ca05dd9870d38e 100644 --- a/core/consensus/common/src/import_queue.rs +++ b/core/consensus/common/src/import_queue.rs @@ -27,10 +27,10 @@ use std::collections::HashMap; use sr_primitives::{Justification, traits::{Block as BlockT, Header as _, NumberFor}}; -use crate::{error::Error as ConsensusError, well_known_cache_keys::Id as CacheKeyId}; +use crate::error::Error as ConsensusError; use crate::block_import::{ BlockImport, BlockOrigin, BlockImportParams, ImportedAux, JustificationImport, ImportResult, - FinalityProofImport, + BlockCheckParams, FinalityProofImport, }; pub use basic_queue::BasicQueue; @@ -65,6 +65,9 @@ pub struct IncomingBlock { pub origin: Option, } +/// Type of keys in the blockchain cache that consensus module could use for its needs. +pub type CacheKeyId = [u8; 4]; + /// Verify a justification of a block pub trait Verifier: Send + Sync { /// Verify the given data and return the BlockImportParams and an optional @@ -102,6 +105,7 @@ pub trait ImportQueue: Send { number: NumberFor, finality_proof: Vec ); + /// Polls for actions to perform on the network. /// /// This method should behave in a way similar to `Future::poll`. It can register the current @@ -190,7 +194,7 @@ pub fn import_single_block>( let number = header.number().clone(); let hash = header.hash(); - let parent = header.parent_hash().clone(); + let parent_hash = header.parent_hash().clone(); let import_error = |e| { match e { @@ -200,7 +204,7 @@ pub fn import_single_block>( }, Ok(ImportResult::Imported(aux)) => Ok(BlockImportResult::ImportedUnknown(number, aux, peer.clone())), Ok(ImportResult::UnknownParent) => { - debug!(target: "sync", "Block with unknown parent {}: {:?}, parent: {:?}", number, hash, parent); + debug!(target: "sync", "Block with unknown parent {}: {:?}, parent: {:?}", number, hash, parent_hash); Err(BlockImportError::UnknownParent) }, Ok(ImportResult::KnownBad) => { @@ -213,8 +217,7 @@ pub fn import_single_block>( } } }; - - match import_error(import_handle.check_block(hash, parent))? { + match import_error(import_handle.check_block(BlockCheckParams { hash, number, parent_hash }))? { BlockImportResult::ImportedUnknown { .. } => (), r => return Ok(r), // Any other successful result means that the block is already imported. } diff --git a/core/consensus/common/src/import_queue/basic_queue.rs b/core/consensus/common/src/import_queue/basic_queue.rs index da6dcd02934e54562d54fd1a91d86bcde4d2fa4b..2ab6d0c5e3b7dd43e12834a2ac3813348387ade7 100644 --- a/core/consensus/common/src/import_queue/basic_queue.rs +++ b/core/consensus/common/src/import_queue/basic_queue.rs @@ -15,7 +15,7 @@ // along with Substrate. If not, see . use std::{mem, pin::Pin, time::Duration}; -use futures::{prelude::*, channel::mpsc, task::SpawnExt as _, task::Context, task::Poll}; +use futures::{prelude::*, channel::mpsc, task::Context, task::Poll}; use futures_timer::Delay; use sr_primitives::{Justification, traits::{Block as BlockT, Header as HeaderT, NumberFor}}; @@ -70,9 +70,7 @@ impl BasicQueue { let manual_poll; if let Some(pool) = &mut pool { - // TODO: this expect() can be removed once - // https://github.com/rust-lang-nursery/futures-rs/pull/1750 is merged and deployed - pool.spawn(future).expect("ThreadPool can never fail to spawn tasks; QED"); + pool.spawn_ok(future); manual_poll = None; } else { manual_poll = Some(Box::pin(future) as Pin>); diff --git a/core/consensus/common/src/lib.rs b/core/consensus/common/src/lib.rs index 3fd0a0c694c7e9f85e0b00a63939c2a351937bf1..154ea7bb52f7c78c03b38d1cee86179cdaf179f4 100644 --- a/core/consensus/common/src/lib.rs +++ b/core/consensus/common/src/lib.rs @@ -35,6 +35,7 @@ use sr_primitives::traits::{Block as BlockT, DigestFor}; use futures::prelude::*; pub use inherents::InherentData; +pub mod block_validation; pub mod offline_tracker; pub mod error; pub mod block_import; @@ -47,11 +48,26 @@ const MAX_BLOCK_SIZE: usize = 4 * 1024 * 1024 + 512; pub use self::error::Error; pub use block_import::{ - BlockImport, BlockOrigin, ForkChoiceStrategy, ImportedAux, BlockImportParams, ImportResult, + BlockImport, BlockOrigin, ForkChoiceStrategy, ImportedAux, BlockImportParams, BlockCheckParams, ImportResult, JustificationImport, FinalityProofImport, }; pub use select_chain::SelectChain; +/// Block status. +#[derive(Debug, PartialEq, Eq)] +pub enum BlockStatus { + /// Added to the import queue. + Queued, + /// Already in the blockchain and the state is available. + InChainWithState, + /// In the blockchain, but the state is not available. + InChainPruned, + /// Block or parent is known to be bad. + KnownBad, + /// Not in the queue or the blockchain. + Unknown, +} + /// Environment producer for a Consensus instance. Creates proposer instance and communication streams. pub trait Environment { /// The proposer type this creates. @@ -117,15 +133,3 @@ where T: ?Sized, for<'r> &'r T: SyncOracle <&T>::is_offline(&mut &**self) } } - -/// A list of all well known keys in the cache. -pub mod well_known_cache_keys { - /// The type representing cache keys. - pub type Id = [u8; 4]; - - /// A list of authorities. - pub const AUTHORITIES: Id = *b"auth"; - - /// Current Epoch data. - pub const EPOCH: Id = *b"epch"; -} diff --git a/core/consensus/pow/Cargo.toml b/core/consensus/pow/Cargo.toml new file mode 100644 index 0000000000000000000000000000000000000000..54dd58c46709e302a2e459eed58c28b9d24906e8 --- /dev/null +++ b/core/consensus/pow/Cargo.toml @@ -0,0 +1,18 @@ +[package] +name = "substrate-consensus-pow" +version = "2.0.0" +authors = ["Parity Technologies "] +description = "PoW consensus algorithm for substrate" +edition = "2018" + +[dependencies] +codec = { package = "parity-scale-codec", version = "1.0.0", features = ["derive"] } +primitives = { package = "substrate-primitives", path = "../../primitives" } +sr-primitives = { path = "../../sr-primitives" } +client = { package = "substrate-client", path = "../../client" } +srml-timestamp = { path = "../../../srml/timestamp" } +inherents = { package = "substrate-inherents", path = "../../inherents" } +pow-primitives = { package = "substrate-consensus-pow-primitives", path = "primitives" } +consensus-common = { package = "substrate-consensus-common", path = "../common" } +log = "0.4.8" +futures-preview = { version = "0.3.0-alpha.19", features = ["compat"] } diff --git a/core/consensus/pow/primitives/Cargo.toml b/core/consensus/pow/primitives/Cargo.toml new file mode 100644 index 0000000000000000000000000000000000000000..021e4c80a754c245367b5e71290f6eb984c38db0 --- /dev/null +++ b/core/consensus/pow/primitives/Cargo.toml @@ -0,0 +1,23 @@ +[package] +name = "substrate-consensus-pow-primitives" +version = "2.0.0" +authors = ["Parity Technologies "] +description = "Primitives for Aura consensus" +edition = "2018" + +[dependencies] +substrate-client = { path = "../../../client", default-features = false } +rstd = { package = "sr-std", path = "../../../sr-std", default-features = false } +sr-primitives = { path = "../../../sr-primitives", default-features = false } +primitives = { package = "substrate-primitives", path = "../../../primitives", default-features = false } +codec = { package = "parity-scale-codec", version = "1.0.0", default-features = false, features = ["derive"] } + +[features] +default = ["std"] +std = [ + "rstd/std", + "substrate-client/std", + "sr-primitives/std", + "primitives/std", + "codec/std", +] diff --git a/core/consensus/pow/primitives/src/lib.rs b/core/consensus/pow/primitives/src/lib.rs new file mode 100644 index 0000000000000000000000000000000000000000..2079b1cbe7e88712499e93320f710169fb7c5722 --- /dev/null +++ b/core/consensus/pow/primitives/src/lib.rs @@ -0,0 +1,65 @@ +// Copyright 2017-2019 Parity Technologies (UK) Ltd. +// This file is part of Substrate. + +// Substrate 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. + +// Substrate 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 Substrate. If not, see . + +//! Primitives for Substrate Proof-of-Work (PoW) consensus. + +#![cfg_attr(not(feature = "std"), no_std)] + +use rstd::vec::Vec; +use sr_primitives::ConsensusEngineId; +use codec::Decode; +use substrate_client::decl_runtime_apis; + +/// The `ConsensusEngineId` of PoW. +pub const POW_ENGINE_ID: ConsensusEngineId = [b'p', b'o', b'w', b'_']; + +/// Type of seal. +pub type Seal = Vec; + +/// Define methods that total difficulty should implement. +pub trait TotalDifficulty { + fn increment(&mut self, other: Self); +} + +impl TotalDifficulty for primitives::U256 { + fn increment(&mut self, other: Self) { + let ret = self.saturating_add(other); + *self = ret; + } +} + +impl TotalDifficulty for u128 { + fn increment(&mut self, other: Self) { + let ret = self.saturating_add(other); + *self = ret; + } +} + +decl_runtime_apis! { + /// API necessary for timestamp-based difficulty adjustment algorithms. + pub trait TimestampApi { + /// Return the timestamp in the current block. + fn timestamp() -> Moment; + } + + /// API for those chains that put their difficulty adjustment algorithm directly + /// onto runtime. Note that while putting difficulty adjustment algorithm to + /// runtime is safe, putting the PoW algorithm on runtime is not. + pub trait DifficultyApi { + /// Return the target difficulty of the next block. + fn difficulty() -> Difficulty; + } +} diff --git a/core/consensus/pow/src/lib.rs b/core/consensus/pow/src/lib.rs new file mode 100644 index 0000000000000000000000000000000000000000..766c1c63e0509bf83f89714d7875d305441a28a2 --- /dev/null +++ b/core/consensus/pow/src/lib.rs @@ -0,0 +1,498 @@ +// Copyright 2017-2019 Parity Technologies (UK) Ltd. +// This file is part of Substrate. + +// Substrate 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. + +// Substrate 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 Substrate. If not, see . + +//! Proof of work consensus for Substrate. +//! +//! To use this engine, you can need to have a struct that implements +//! `PowAlgorithm`. After that, pass an instance of the struct, along +//! with other necessary client references to `import_queue` to setup +//! the queue. Use the `start_mine` function for basic CPU mining. +//! +//! The auxiliary storage for PoW engine only stores the total difficulty. +//! For other storage requirements for particular PoW algorithm (such as +//! the actual difficulty for each particular blocks), you can take a client +//! reference in your `PowAlgorithm` implementation, and use a separate prefix +//! for the auxiliary storage. It is also possible to just use the runtime +//! as the storage, but it is not recommended as it won't work well with light +//! clients. + +use std::sync::Arc; +use std::thread; +use std::collections::HashMap; +use client::{ + BlockOf, blockchain::{HeaderBackend, ProvideCache}, + block_builder::api::BlockBuilder as BlockBuilderApi, backend::AuxStore, + well_known_cache_keys::Id as CacheKeyId, +}; +use sr_primitives::Justification; +use sr_primitives::generic::{BlockId, Digest, DigestItem}; +use sr_primitives::traits::{Block as BlockT, Header as HeaderT, ProvideRuntimeApi}; +use srml_timestamp::{TimestampInherentData, InherentError as TIError}; +use pow_primitives::{Seal, TotalDifficulty, POW_ENGINE_ID}; +use primitives::H256; +use inherents::{InherentDataProviders, InherentData}; +use consensus_common::{ + BlockImportParams, BlockOrigin, ForkChoiceStrategy, SyncOracle, Environment, Proposer, + SelectChain, +}; +use consensus_common::import_queue::{BoxBlockImport, BasicQueue, Verifier}; +use codec::{Encode, Decode}; +use log::*; + +/// Auxiliary storage prefix for PoW engine. +pub const POW_AUX_PREFIX: [u8; 4] = *b"PoW:"; + +/// Get the auxiliary storage key used by engine to store total difficulty. +fn aux_key(hash: &H256) -> Vec { + POW_AUX_PREFIX.iter().chain(&hash[..]) + .cloned().collect::>() +} + +/// Auxiliary storage data for PoW. +#[derive(Encode, Decode, Clone, Debug, Default)] +pub struct PowAux { + /// Difficulty of the current block. + pub difficulty: Difficulty, + /// Total difficulty up to current block. + pub total_difficulty: Difficulty, +} + +impl PowAux where + Difficulty: Decode + Default, +{ + /// Read the auxiliary from client. + pub fn read(client: &C, hash: &H256) -> Result { + let key = aux_key(hash); + + match client.get_aux(&key).map_err(|e| format!("{:?}", e))? { + Some(bytes) => Self::decode(&mut &bytes[..]) + .map_err(|e| format!("{:?}", e)), + None => Ok(Self::default()), + } + } +} + +/// Algorithm used for proof of work. +pub trait PowAlgorithm { + /// Difficulty for the algorithm. + type Difficulty: TotalDifficulty + Default + Encode + Decode + Ord + Clone + Copy; + + /// Get the next block's difficulty. + fn difficulty(&self, parent: &BlockId) -> Result; + /// Verify proof of work against the given difficulty. + fn verify( + &self, + parent: &BlockId, + pre_hash: &H256, + seal: &Seal, + difficulty: Self::Difficulty, + ) -> Result; + /// Mine a seal that satisfies the given difficulty. + fn mine( + &self, + parent: &BlockId, + pre_hash: &H256, + difficulty: Self::Difficulty, + round: u32, + ) -> Result, String>; +} + +/// A verifier for PoW blocks. +pub struct PowVerifier, C, S, Algorithm> { + client: Arc, + algorithm: Algorithm, + inherent_data_providers: inherents::InherentDataProviders, + select_chain: Option, + check_inherents_after: <::Header as HeaderT>::Number, +} + +impl, C, S, Algorithm> PowVerifier { + pub fn new( + client: Arc, + algorithm: Algorithm, + check_inherents_after: <::Header as HeaderT>::Number, + select_chain: Option, + inherent_data_providers: inherents::InherentDataProviders, + ) -> Self { + Self { client, algorithm, inherent_data_providers, select_chain, check_inherents_after } + } + + fn check_header( + &self, + mut header: B::Header, + parent_block_id: BlockId, + ) -> Result<(B::Header, Algorithm::Difficulty, DigestItem), String> where + Algorithm: PowAlgorithm, + { + let hash = header.hash(); + + let (seal, inner_seal) = match header.digest_mut().pop() { + Some(DigestItem::Seal(id, seal)) => { + if id == POW_ENGINE_ID { + (DigestItem::Seal(id, seal.clone()), seal) + } else { + return Err(format!("Header uses the wrong engine {:?}", id)) + } + }, + _ => return Err(format!("Header {:?} is unsealed", hash)), + }; + + let pre_hash = header.hash(); + let difficulty = self.algorithm.difficulty(&parent_block_id)?; + + if !self.algorithm.verify( + &parent_block_id, + &pre_hash, + &inner_seal, + difficulty, + )? { + return Err("PoW validation error: invalid seal".into()); + } + + Ok((header, difficulty, seal)) + } + + fn check_inherents( + &self, + block: B, + block_id: BlockId, + inherent_data: InherentData, + timestamp_now: u64, + ) -> Result<(), String> where + C: ProvideRuntimeApi, C::Api: BlockBuilderApi + { + const MAX_TIMESTAMP_DRIFT_SECS: u64 = 60; + + if *block.header().number() < self.check_inherents_after { + return Ok(()) + } + + let inherent_res = self.client.runtime_api().check_inherents( + &block_id, + block, + inherent_data, + ).map_err(|e| format!("{:?}", e))?; + + if !inherent_res.ok() { + inherent_res + .into_errors() + .try_for_each(|(i, e)| match TIError::try_from(&i, &e) { + Some(TIError::ValidAtTimestamp(timestamp)) => { + if timestamp > timestamp_now + MAX_TIMESTAMP_DRIFT_SECS { + return Err("Rejecting block too far in future".into()); + } + + Ok(()) + }, + Some(TIError::Other(e)) => Err(e.into()), + None => Err(self.inherent_data_providers.error_to_string(&i, &e)), + }) + } else { + Ok(()) + } + } +} + +impl, C, S, Algorithm> Verifier for PowVerifier where + C: ProvideRuntimeApi + Send + Sync + HeaderBackend + AuxStore + ProvideCache + BlockOf, + C::Api: BlockBuilderApi, + S: SelectChain, + Algorithm: PowAlgorithm + Send + Sync, +{ + fn verify( + &mut self, + origin: BlockOrigin, + header: B::Header, + justification: Option, + mut body: Option>, + ) -> Result<(BlockImportParams, Option)>>), String> { + let inherent_data = self.inherent_data_providers + .create_inherent_data().map_err(String::from)?; + let timestamp_now = inherent_data.timestamp_inherent_data().map_err(String::from)?; + + let best_hash = match self.select_chain.as_ref() { + Some(select_chain) => select_chain.best_chain() + .map_err(|e| format!("Fetch best chain failed via select chain: {:?}", e))? + .hash(), + None => self.client.info().best_hash, + }; + let hash = header.hash(); + let parent_hash = *header.parent_hash(); + let best_aux = PowAux::read(self.client.as_ref(), &best_hash)?; + let mut aux = PowAux::read(self.client.as_ref(), &parent_hash)?; + + let (checked_header, difficulty, seal) = self.check_header( + header, + BlockId::Hash(parent_hash), + )?; + aux.difficulty = difficulty; + aux.total_difficulty.increment(difficulty); + + if let Some(inner_body) = body.take() { + let block = B::new(checked_header.clone(), inner_body); + + self.check_inherents( + block.clone(), + BlockId::Hash(parent_hash), + inherent_data, + timestamp_now + )?; + + let (_, inner_body) = block.deconstruct(); + body = Some(inner_body); + } + let key = aux_key(&hash); + let import_block = BlockImportParams { + origin, + header: checked_header, + post_digests: vec![seal], + body, + finalized: false, + justification, + auxiliary: vec![(key, Some(aux.encode()))], + fork_choice: ForkChoiceStrategy::Custom(aux.total_difficulty > best_aux.total_difficulty), + }; + + Ok((import_block, None)) + } +} + +/// Register the PoW inherent data provider, if not registered already. +pub fn register_pow_inherent_data_provider( + inherent_data_providers: &InherentDataProviders, +) -> Result<(), consensus_common::Error> { + if !inherent_data_providers.has_provider(&srml_timestamp::INHERENT_IDENTIFIER) { + inherent_data_providers + .register_provider(srml_timestamp::InherentDataProvider) + .map_err(Into::into) + .map_err(consensus_common::Error::InherentData) + } else { + Ok(()) + } +} + +/// The PoW import queue type. +pub type PowImportQueue = BasicQueue; + +/// Import queue for PoW engine. +pub fn import_queue( + block_import: BoxBlockImport, + client: Arc, + algorithm: Algorithm, + check_inherents_after: <::Header as HeaderT>::Number, + select_chain: Option, + inherent_data_providers: InherentDataProviders, +) -> Result, consensus_common::Error> where + B: BlockT, + C: ProvideRuntimeApi + HeaderBackend + BlockOf + ProvideCache + AuxStore, + C: Send + Sync + AuxStore + 'static, + C::Api: BlockBuilderApi, + Algorithm: PowAlgorithm + Send + Sync + 'static, + S: SelectChain + 'static, +{ + register_pow_inherent_data_provider(&inherent_data_providers)?; + + let verifier = PowVerifier::new( + client.clone(), + algorithm, + check_inherents_after, + select_chain, + inherent_data_providers, + ); + + Ok(BasicQueue::new( + verifier, + block_import, + None, + None + )) +} + +/// Start the background mining thread for PoW. Note that because PoW mining +/// is CPU-intensive, it is not possible to use an async future to define this. +/// However, it's not recommended to use background threads in the rest of the +/// codebase. +/// +/// `preruntime` is a parameter that allows a custom additional pre-runtime +/// digest to be inserted for blocks being built. This can encode authorship +/// information, or just be a graffiti. `round` is for number of rounds the +/// CPU miner runs each time. This parameter should be tweaked so that each +/// mining round is within sub-second time. +pub fn start_mine, C, Algorithm, E, SO, S>( + mut block_import: BoxBlockImport, + client: Arc, + algorithm: Algorithm, + mut env: E, + preruntime: Option>, + round: u32, + mut sync_oracle: SO, + build_time: std::time::Duration, + select_chain: Option, + inherent_data_providers: inherents::InherentDataProviders, +) where + C: HeaderBackend + AuxStore + 'static, + Algorithm: PowAlgorithm + Send + Sync + 'static, + E: Environment + Send + Sync + 'static, + E::Error: std::fmt::Debug, + SO: SyncOracle + Send + Sync + 'static, + S: SelectChain + 'static, +{ + if let Err(_) = register_pow_inherent_data_provider(&inherent_data_providers) { + warn!("Registering inherent data provider for timestamp failed"); + } + + thread::spawn(move || { + loop { + match mine_loop( + &mut block_import, + client.as_ref(), + &algorithm, + &mut env, + preruntime.as_ref(), + round, + &mut sync_oracle, + build_time.clone(), + select_chain.as_ref(), + &inherent_data_providers + ) { + Ok(()) => (), + Err(e) => error!( + "Mining block failed with {:?}. Sleep for 1 second before restarting...", + e + ), + } + std::thread::sleep(std::time::Duration::new(1, 0)); + } + }); +} + +fn mine_loop, C, Algorithm, E, SO, S>( + block_import: &mut BoxBlockImport, + client: &C, + algorithm: &Algorithm, + env: &mut E, + preruntime: Option<&Vec>, + round: u32, + sync_oracle: &mut SO, + build_time: std::time::Duration, + select_chain: Option<&S>, + inherent_data_providers: &inherents::InherentDataProviders, +) -> Result<(), String> where + C: HeaderBackend + AuxStore, + Algorithm: PowAlgorithm, + E: Environment, + E::Error: std::fmt::Debug, + SO: SyncOracle, + S: SelectChain, +{ + 'outer: loop { + if sync_oracle.is_major_syncing() { + debug!(target: "pow", "Skipping proposal due to sync."); + std::thread::sleep(std::time::Duration::new(1, 0)); + continue 'outer + } + + let (best_hash, best_header) = match select_chain { + Some(select_chain) => { + let header = select_chain.best_chain() + .map_err(|e| format!("Fetching best header failed using select chain: {:?}", e))?; + let hash = header.hash(); + (hash, header) + }, + None => { + let hash = client.info().best_hash; + let header = client.header(BlockId::Hash(hash)) + .map_err(|e| format!("Fetching best header failed: {:?}", e))? + .ok_or("Best header does not exist")?; + (hash, header) + }, + }; + let mut aux = PowAux::read(client, &best_hash)?; + let mut proposer = env.init(&best_header).map_err(|e| format!("{:?}", e))?; + + let inherent_data = inherent_data_providers + .create_inherent_data().map_err(String::from)?; + let mut inherent_digest = Digest::default(); + if let Some(preruntime) = &preruntime { + inherent_digest.push(DigestItem::PreRuntime(POW_ENGINE_ID, preruntime.to_vec())); + } + let block = futures::executor::block_on(proposer.propose( + inherent_data, + inherent_digest, + build_time.clone(), + )).map_err(|e| format!("Block proposing error: {:?}", e))?; + + let (header, body) = block.deconstruct(); + let (difficulty, seal) = { + let difficulty = algorithm.difficulty( + &BlockId::Hash(best_hash), + )?; + + loop { + let seal = algorithm.mine( + &BlockId::Hash(best_hash), + &header.hash(), + difficulty, + round, + )?; + + if let Some(seal) = seal { + break (difficulty, seal) + } + + if best_hash != client.info().best_hash { + continue 'outer + } + } + }; + + aux.difficulty = difficulty; + aux.total_difficulty.increment(difficulty); + let hash = { + let mut header = header.clone(); + header.digest_mut().push(DigestItem::Seal(POW_ENGINE_ID, seal.clone())); + header.hash() + }; + + let key = aux_key(&hash); + let best_hash = match select_chain { + Some(select_chain) => select_chain.best_chain() + .map_err(|e| format!("Fetch best hash failed via select chain: {:?}", e))? + .hash(), + None => client.info().best_hash, + }; + let best_aux = PowAux::::read(client, &best_hash)?; + + // if the best block has changed in the meantime drop our proposal + if best_aux.total_difficulty > aux.total_difficulty { + continue 'outer + } + + let import_block = BlockImportParams { + origin: BlockOrigin::Own, + header, + justification: None, + post_digests: vec![DigestItem::Seal(POW_ENGINE_ID, seal)], + body: Some(body), + finalized: false, + auxiliary: vec![(key, Some(aux.encode()))], + fork_choice: ForkChoiceStrategy::Custom(true), + }; + + block_import.import_block(import_block, HashMap::default()) + .map_err(|e| format!("Error with block built on {:?}: {:?}", best_hash, e))?; + } +} diff --git a/core/consensus/rhd/Cargo.toml b/core/consensus/rhd/Cargo.toml index 801605c3f64ca2c5e4f25ebbb24074330d3c4101..48d0840b5592d5403f028008f7b5fafcaee67f85 100644 --- a/core/consensus/rhd/Cargo.toml +++ b/core/consensus/rhd/Cargo.toml @@ -6,8 +6,8 @@ description = "Rhododendron Round-Based consensus-algorithm for substrate" edition = "2018" [dependencies] -derive_more = "0.14.0" -futures = "0.1.17" +derive_more = "0.15.0" +futures = "0.1.29" codec = { package = "parity-scale-codec", version = "1.0.0", features = ["derive"] } primitives = { package = "substrate-primitives", path = "../../primitives" } consensus = { package = "substrate-consensus-common", path = "../common" } @@ -18,11 +18,11 @@ srml-system = { path = "../../../srml/system" } sr-primitives = { path = "../../sr-primitives" } runtime_version = { package = "sr-version", path = "../../sr-version" } runtime_io = { package = "sr-io", path = "../../sr-io" } -tokio = "0.1.7" +tokio = "0.1.22" parking_lot = "0.9.0" -log = "0.4" +log = "0.4.8" rhododendron = { version = "0.7.0", features = ["codec"] } -exit-future = "0.1" +exit-future = "0.1.4" [dev-dependencies] keyring = { package = "substrate-keyring", path = "../../keyring" } diff --git a/core/consensus/slots/Cargo.toml b/core/consensus/slots/Cargo.toml index f74837a62f9de36970ccea2e8915276a4956c5ec..4074242502b7192e26c13372eb77411d0bd32ff0 100644 --- a/core/consensus/slots/Cargo.toml +++ b/core/consensus/slots/Cargo.toml @@ -4,18 +4,20 @@ version = "2.0.0" authors = ["Parity Technologies "] description = "Generic slots-based utilities for consensus" edition = "2018" +build = "build.rs" [dependencies] codec = { package = "parity-scale-codec", version = "1.0.0" } client = { package = "substrate-client", path = "../../client" } primitives = { package = "substrate-primitives", path = "../../primitives" } sr-primitives = { path = "../../sr-primitives" } +substrate-telemetry = { path = "../../telemetry" } consensus_common = { package = "substrate-consensus-common", path = "../common" } inherents = { package = "substrate-inherents", path = "../../inherents" } -futures-preview = "=0.3.0-alpha.17" -futures-timer = "0.2.1" +futures-preview = "0.3.0-alpha.19" +futures-timer = "0.4.0" parking_lot = "0.9.0" -log = "0.4" +log = "0.4.8" [dev-dependencies] test-client = { package = "substrate-test-runtime-client", path = "../../test-runtime/client" } diff --git a/core/consensus/common/primitives/src/lib.rs b/core/consensus/slots/build.rs similarity index 66% rename from core/consensus/common/primitives/src/lib.rs rename to core/consensus/slots/build.rs index f6c1800081f90c4f07b51d20e4ffb8f368d2155b..36730271c715eaa1daf6e957e4b1e01443a2bc7a 100644 --- a/core/consensus/common/primitives/src/lib.rs +++ b/core/consensus/slots/build.rs @@ -14,18 +14,10 @@ // You should have received a copy of the GNU General Public License // along with Substrate. If not, see . -//! Common consensus primitives. +use std::env; -#![cfg_attr(not(feature = "std"), no_std)] - -use codec::Codec; -use client::decl_runtime_apis; -use rstd::vec::Vec; - -decl_runtime_apis! { - /// Common consensus runtime api. - pub trait ConsensusApi { - /// Returns the set of authorities of the currently active consensus mechanism. - fn authorities() -> Vec; +fn main() { + if let Ok(profile) = env::var("PROFILE") { + println!("cargo:rustc-cfg=build_type=\"{}\"", profile); } } diff --git a/core/consensus/slots/src/lib.rs b/core/consensus/slots/src/lib.rs index fc0134f746af79a72ec1224515ac595e3b0b1006..fd86a0f277331e74b73773683532092d13d479cb 100644 --- a/core/consensus/slots/src/lib.rs +++ b/core/consensus/slots/src/lib.rs @@ -31,13 +31,16 @@ use slots::Slots; pub use aux_schema::{check_equivocation, MAX_SLOT_CAPACITY, PRUNING_BOUND}; use codec::{Decode, Encode}; -use consensus_common::{SyncOracle, SelectChain}; +use consensus_common::{BlockImport, Proposer, SyncOracle, SelectChain}; use futures::{prelude::*, future::{self, Either}}; +use futures_timer::Delay; use inherents::{InherentData, InherentDataProviders}; use log::{debug, error, info, warn}; use sr_primitives::generic::BlockId; -use sr_primitives::traits::{ApiRef, Block as BlockT, ProvideRuntimeApi}; -use std::{fmt::Debug, ops::Deref}; +use sr_primitives::traits::{ApiRef, Block as BlockT, Header, ProvideRuntimeApi}; +use std::{fmt::Debug, ops::Deref, pin::Pin, sync::Arc}; +use substrate_telemetry::{telemetry, CONSENSUS_DEBUG, CONSENSUS_WARN, CONSENSUS_INFO}; +use parking_lot::Mutex; /// A worker that should be invoked at every new slot. pub trait SlotWorker { @@ -49,6 +52,212 @@ pub trait SlotWorker { fn on_slot(&mut self, chain_head: B::Header, slot_info: SlotInfo) -> Self::OnSlot; } +/// A skeleton implementation for `SlotWorker` which tries to claim a slot at +/// its beginning and tries to produce a block if successfully claimed, timing +/// out if block production takes too long. +pub trait SimpleSlotWorker { + /// A handle to a `BlockImport`. + type BlockImport: BlockImport + Send + 'static; + + /// A handle to a `SyncOracle`. + type SyncOracle: SyncOracle; + + /// The type of proposer to use to build blocks. + type Proposer: Proposer; + + /// Data associated with a slot claim. + type Claim: Send + 'static; + + /// Epoch data necessary for authoring. + type EpochData; + + /// The logging target to use when logging messages. + fn logging_target(&self) -> &'static str; + + /// A handle to a `BlockImport`. + fn block_import(&self) -> Arc>; + + /// Returns the epoch data necessary for authoring. For time-dependent epochs, + /// use the provided slot number as a canonical source of time. + fn epoch_data(&self, header: &B::Header, slot_number: u64) -> Result; + + /// Returns the number of authorities given the epoch data. + fn authorities_len(&self, epoch_data: &Self::EpochData) -> usize; + + /// Tries to claim the given slot, returning an object with claim data if successful. + fn claim_slot( + &self, + header: &B::Header, + slot_number: u64, + epoch_data: &Self::EpochData, + ) -> Option; + + /// Return the pre digest data to include in a block authored with the given claim. + fn pre_digest_data(&self, slot_number: u64, claim: &Self::Claim) -> Vec>; + + /// Returns a function which produces a `BlockImportParams`. + fn block_import_params(&self) -> Box, + Self::Claim, + ) -> consensus_common::BlockImportParams + Send>; + + /// Whether to force authoring if offline. + fn force_authoring(&self) -> bool; + + /// Returns a handle to a `SyncOracle`. + fn sync_oracle(&mut self) -> &mut Self::SyncOracle; + + /// Returns a `Proposer` to author on top of the given block. + fn proposer(&mut self, block: &B::Header) -> Result; + + /// Implements the `on_slot` functionality from `SlotWorker`. + fn on_slot(&mut self, chain_head: B::Header, slot_info: SlotInfo) + -> Pin> + Send>> where + Self: Send + Sync, + >::Create: Unpin + Send + 'static, + { + let (timestamp, slot_number, slot_duration) = + (slot_info.timestamp, slot_info.number, slot_info.duration); + + let epoch_data = match self.epoch_data(&chain_head, slot_number) { + Ok(epoch_data) => epoch_data, + Err(err) => { + warn!("Unable to fetch epoch data at block {:?}: {:?}", chain_head.hash(), err); + + telemetry!( + CONSENSUS_WARN; "slots.unable_fetching_authorities"; + "slot" => ?chain_head.hash(), + "err" => ?err, + ); + + return Box::pin(future::ready(Ok(()))); + } + }; + + let authorities_len = self.authorities_len(&epoch_data); + + if !self.force_authoring() && self.sync_oracle().is_offline() && authorities_len > 1 { + debug!(target: self.logging_target(), "Skipping proposal slot. Waiting for the network."); + telemetry!( + CONSENSUS_DEBUG; + "slots.skipping_proposal_slot"; + "authorities_len" => authorities_len, + ); + + return Box::pin(future::ready(Ok(()))); + } + + let claim = match self.claim_slot(&chain_head, slot_number, &epoch_data) { + None => return Box::pin(future::ready(Ok(()))), + Some(claim) => claim, + }; + + debug!( + target: self.logging_target(), "Starting authorship at slot {}; timestamp = {}", + slot_number, + timestamp, + ); + + telemetry!(CONSENSUS_DEBUG; "slots.starting_authorship"; + "slot_num" => slot_number, + "timestamp" => timestamp, + ); + + let mut proposer = match self.proposer(&chain_head) { + Ok(proposer) => proposer, + Err(err) => { + warn!("Unable to author block in slot {:?}: {:?}", slot_number, err); + + telemetry!(CONSENSUS_WARN; "slots.unable_authoring_block"; + "slot" => slot_number, "err" => ?err + ); + + return Box::pin(future::ready(Ok(()))); + }, + }; + + let remaining_duration = slot_info.remaining_duration(); + let logs = self.pre_digest_data(slot_number, &claim); + + // deadline our production to approx. the end of the slot + let proposal_work = futures::future::select( + proposer.propose( + slot_info.inherent_data, + sr_primitives::generic::Digest { + logs, + }, + remaining_duration, + ).map_err(|e| consensus_common::Error::ClientImport(format!("{:?}", e)).into()), + Delay::new(remaining_duration) + .map_err(|err| consensus_common::Error::FaultyTimer(err).into()) + ).map(|v| match v { + futures::future::Either::Left((b, _)) => b.map(|b| (b, claim)), + futures::future::Either::Right((Ok(_), _)) => + Err(consensus_common::Error::ClientImport("Timeout in the Slots proposer".into())), + futures::future::Either::Right((Err(err), _)) => Err(err), + }); + + let block_import_params_maker = self.block_import_params(); + let block_import = self.block_import(); + let logging_target = self.logging_target(); + + Box::pin(proposal_work.map_ok(move |(block, claim)| { + // minor hack since we don't have access to the timestamp + // that is actually set by the proposer. + let slot_after_building = SignedDuration::default().slot_now(slot_duration); + if slot_after_building != slot_number { + info!("Discarding proposal for slot {}; block production took too long", slot_number); + // If the node was compiled with debug, tell the user to use release optimizations. + #[cfg(build_type="debug")] + info!("Recompile your node in `--release` mode to mitigate this problem."); + telemetry!(CONSENSUS_INFO; "slots.discarding_proposal_took_too_long"; + "slot" => slot_number, + ); + + return; + } + + let (header, body) = block.deconstruct(); + let header_num = header.number().clone(); + let header_hash = header.hash(); + let parent_hash = header.parent_hash().clone(); + + let block_import_params = block_import_params_maker( + header, + &header_hash, + body, + claim, + ); + + info!("Pre-sealed block for proposal at {}. Hash now {:?}, previously {:?}.", + header_num, + block_import_params.post_header().hash(), + header_hash, + ); + + telemetry!(CONSENSUS_INFO; "slots.pre_sealed_block"; + "header_num" => ?header_num, + "hash_now" => ?block_import_params.post_header().hash(), + "hash_previously" => ?header_hash, + ); + + if let Err(err) = block_import.lock().import_block(block_import_params, Default::default()) { + warn!(target: logging_target, + "Error with block built on {:?}: {:?}", + parent_hash, + err, + ); + + telemetry!(CONSENSUS_WARN; "slots.err_with_block_built_on"; + "hash" => ?parent_hash, "err" => ?err, + ); + } + })) + } +} + /// Slot compatible inherent data. pub trait SlotCompatible { /// Extract timestamp and slot from inherent data. @@ -151,7 +360,8 @@ impl SlotData for u64 { } /// A slot duration. Create with `get_or_compute`. -// The internal member should stay private here. +// The internal member should stay private here to maintain invariants of +// `get_or_compute`. #[derive(Clone, Copy, Debug, Encode, Decode, Hash, PartialOrd, Ord, PartialEq, Eq)] pub struct SlotDuration(T); @@ -189,7 +399,7 @@ impl SlotDuration { Some(v) => ::decode(&mut &v[..]) .map(SlotDuration) .map_err(|_| { - ::client::error::Error::Backend({ + client::error::Error::Backend({ error!(target: "slots", "slot duration kept in invalid format"); format!("slot duration kept in invalid format") }) diff --git a/core/consensus/uncles/Cargo.toml b/core/consensus/uncles/Cargo.toml index 98b8adee8b7930ef94859492a84b632b4706b887..48203248709291e7f503b76887a46fd5b04ccb1e 100644 --- a/core/consensus/uncles/Cargo.toml +++ b/core/consensus/uncles/Cargo.toml @@ -12,4 +12,4 @@ sr-primitives = { path = "../../sr-primitives" } srml-authorship = { path = "../../../srml/authorship" } consensus_common = { package = "substrate-consensus-common", path = "../common" } inherents = { package = "substrate-inherents", path = "../../inherents" } -log = "0.4" +log = "0.4.8" diff --git a/core/executor/Cargo.toml b/core/executor/Cargo.toml index a4707fb89e3d408880db28cd7fb008e951c2a0f9..1f53cd4099dab6aeeebf7e141a2c89d76790b192 100644 --- a/core/executor/Cargo.toml +++ b/core/executor/Cargo.toml @@ -5,31 +5,31 @@ authors = ["Parity Technologies "] edition = "2018" [dependencies] -derive_more = "0.14.0" +derive_more = "0.15.0" codec = { package = "parity-scale-codec", version = "1.0.0" } runtime_io = { package = "sr-io", path = "../sr-io" } primitives = { package = "substrate-primitives", path = "../primitives" } trie = { package = "substrate-trie", path = "../trie" } serializer = { package = "substrate-serializer", path = "../serializer" } -state_machine = { package = "substrate-state-machine", path = "../state-machine" } runtime_version = { package = "sr-version", path = "../sr-version" } panic-handler = { package = "substrate-panic-handler", path = "../panic-handler" } -wasmi = "0.5.0" -parity-wasm = "0.31" -byteorder = "1.3" -lazy_static = "1.3" +wasmi = "0.5.1" +parity-wasm = "0.40.3" +lazy_static = "1.4.0" +wasm-interface = { package = "substrate-wasm-interface", path = "../wasm-interface" } parking_lot = "0.9.0" -log = "0.4" -libsecp256k1 = "0.2.1" -tiny-keccak = "1.4.2" +log = "0.4.8" +libsecp256k1 = "0.3.0" +tiny-keccak = "1.5.0" [dev-dependencies] -assert_matches = "1.1" -wabt = "~0.7.4" -hex-literal = "0.2.0" +assert_matches = "1.3.0" +wabt = "0.9.2" +hex-literal = "0.2.1" runtime-test = { package = "substrate-runtime-test", path = "runtime-test" } substrate-client = { path = "../client" } substrate-offchain = { path = "../offchain/" } +state_machine = { package = "substrate-state-machine", path = "../state-machine" } [features] default = [] diff --git a/core/executor/runtime-test/Cargo.toml b/core/executor/runtime-test/Cargo.toml index 28a0ed2b874aaa5fbf71ef4b17ea192524fa8a45..153c5c9a1f49fa58e5b1b7cc5cceb2cb46cca443 100644 --- a/core/executor/runtime-test/Cargo.toml +++ b/core/executor/runtime-test/Cargo.toml @@ -10,11 +10,11 @@ rstd = { package = "sr-std", path = "../../sr-std", default-features = false } runtime_io = { package = "sr-io", path = "../../sr-io", default-features = false } sandbox = { package = "sr-sandbox", path = "../../sr-sandbox", default-features = false } primitives = { package = "substrate-primitives", path = "../../primitives", default-features = false } +sr-primitives = { package = "sr-primitives", path = "../../sr-primitives", default-features = false } [build-dependencies] wasm-builder-runner = { package = "substrate-wasm-builder-runner", version = "1.0.2", path = "../../utils/wasm-builder-runner" } [features] default = [ "std" ] -std = [] -no_std = [] +std = ["runtime_io/std", "sandbox/std", "rstd/std"] diff --git a/core/executor/runtime-test/build.rs b/core/executor/runtime-test/build.rs index 86bc3ad7fab28626123baf07d64780fa4fc5a053..136dc793986b541681a44da901b9ea1d42c1630c 100644 --- a/core/executor/runtime-test/build.rs +++ b/core/executor/runtime-test/build.rs @@ -21,7 +21,7 @@ fn main() { "wasm_binary.rs", WasmBuilderSource::CratesOrPath { path: "../../utils/wasm-builder", - version: "1.0.4", + version: "1.0.7", }, // This instructs LLD to export __heap_base as a global variable, which is used by the // external memory allocator. diff --git a/core/executor/runtime-test/src/lib.rs b/core/executor/runtime-test/src/lib.rs index 5e276a88141684eb520cea68bd0a114117a67881..35f3191ffdf5cc13260aabe377d34c2b95481246 100644 --- a/core/executor/runtime-test/src/lib.rs +++ b/core/executor/runtime-test/src/lib.rs @@ -8,9 +8,10 @@ include!(concat!(env!("OUT_DIR"), "/wasm_binary.rs")); use rstd::{vec::Vec, slice, vec}; use runtime_io::{ - set_storage, storage, clear_prefix, print, blake2_128, blake2_256, - twox_128, twox_256, ed25519_verify, sr25519_verify, ordered_trie_root + set_storage, storage, clear_prefix, blake2_128, blake2_256, + twox_128, twox_256, ed25519_verify, sr25519_verify, }; +use sr_primitives::{print, traits::{BlakeTwo256, Hash}}; use primitives::{ed25519, sr25519}; macro_rules! impl_stubs { @@ -94,12 +95,12 @@ impl_stubs!( [sr25519_verify(&sr25519::Signature(sig), &msg[..], &sr25519::Public(pubkey)) as u8].to_vec() }, test_ordered_trie_root => |_| { - ordered_trie_root::( - &[ - &b"zero"[..], - &b"one"[..], - &b"two"[..], - ] + BlakeTwo256::ordered_trie_root( + vec![ + b"zero"[..].into(), + b"one"[..].into(), + b"two"[..].into(), + ], ).as_ref().to_vec() }, test_sandbox => |code: &[u8]| { diff --git a/core/executor/src/allocator.rs b/core/executor/src/allocator.rs index 4cc8174f705b0840b143aaa3ad12251e763889e1..523499db71c6bdb13979b40d1ee198659fd995ab 100644 --- a/core/executor/src/allocator.rs +++ b/core/executor/src/allocator.rs @@ -15,14 +15,45 @@ // along with Substrate. If not, see . //! This module implements a freeing-bump allocator. -//! See more details at https://github.com/paritytech/substrate/issues/1615. +//! +//! The algorithm is as follows: +//! We store `N` linked list heads, where `N` is the total number of sizes +//! of allocations to support. A simple set is powers of two from 8 bytes +//! to 16,777,216 bytes (2^3 - 2^24 inclusive), resulting in `N = 22`: +//! +//! ```ignore +//! let mut heads [u64; N] = [0; N]; +//! fn size(n: u64) -> u64 { 8 << n } +//! let mut bumper = 0; +//! fn bump(n: u64) -> u64 { let res = bumper; bumper += n; res } +//! ``` +//! +//! We assume there is a slab of heap to be allocated: +//! +//! ```ignore +//! let mut heap = [0u8; HEAP_SIZE]; +//! ``` +//! +//! Whenever we allocate, we select the lowest linked list item size that +//! will fit the allocation (i.e. the next highest power of two). +//! We then check to see if the linked list is empty. If empty, we use +//! the bump allocator to get the allocation with an extra 8 bytes +//! preceding it. We initialise those preceding 8 bytes to identify the +//! list to which it belongs. If it is not empty, we unlink the first item from +//! the linked list and then reset the 8 preceding bytes so they now record +//! the identity of the linked list. +//! +//! To deallocate we use the preceding 8 bytes of the allocation to knit +//! back the allocation into the linked list from the head. use crate::error::{Error, Result}; use log::trace; -use wasmi::MemoryRef; -use wasmi::memory_units::Bytes; +use std::convert::{TryFrom, TryInto}; +use std::ops::Range; +use wasm_interface::{Pointer, WordSize}; -// The pointers need to be aligned to 8 bytes. +// The pointers need to be aligned to 8 bytes. This is because the +// maximum value type handled by wasm32 is u64. const ALIGNMENT: u32 = 8; // The pointer returned by `allocate()` needs to fulfill the alignment @@ -32,12 +63,15 @@ const ALIGNMENT: u32 = 8; // index) and then a subsequent item of 2^x bytes, where x = [3..24]. const N: usize = 22; const MAX_POSSIBLE_ALLOCATION: u32 = 16777216; // 2^24 bytes +const MIN_POSSIBLE_ALLOCATION: u32 = 8; + +// Each pointer is prefixed with 8 bytes, which identify the list index +// to which it belongs. +const PREFIX_SIZE: u32 = 8; pub struct FreeingBumpHeapAllocator { bumper: u32, heads: [u32; N], - heap: MemoryRef, - max_heap_size: u32, ptr_offset: u32, total_size: u32, } @@ -53,40 +87,41 @@ impl FreeingBumpHeapAllocator { /// /// # Arguments /// - /// - `mem` - reference to the linear memory instance on which this allocator operates. /// - `heap_base` - the offset from the beginning of the linear memory where the heap starts. - pub fn new(mem: MemoryRef, heap_base: u32) -> Self { - let current_size: Bytes = mem.current_size().into(); - let current_size = current_size.0 as u32; - - let mut ptr_offset = heap_base; - let padding = ptr_offset % ALIGNMENT; - if padding != 0 { - ptr_offset += ALIGNMENT - padding; - } - - let heap_size = current_size - ptr_offset; + pub fn new(heap_base: u32) -> Self { + // ptr_offset is the next alignment boundary on or after heap_base. + let ptr_offset = (heap_base + ALIGNMENT - 1) / ALIGNMENT * ALIGNMENT; FreeingBumpHeapAllocator { bumper: 0, heads: [0; N], - heap: mem, - max_heap_size: heap_size, - ptr_offset: ptr_offset, + ptr_offset, total_size: 0, } } /// Gets requested number of bytes to allocate and returns a pointer. /// The maximum size which can be allocated at once is 16 MiB. - pub fn allocate(&mut self, size: u32) -> Result { + /// There is no minimum size, but whatever size is passed into + /// this function is rounded to the next power of two. If the requested + /// size is below 8 bytes it will be rounded up to 8 bytes. + /// + /// # Arguments + /// + /// - `mem` - a slice representing the linear memory on which this allocator operates. + /// - `size` - size in bytes of the allocation request + pub fn allocate(&mut self, mem: &mut [u8], size: WordSize) -> Result> { + let mem_size = u32::try_from(mem.len()) + .expect("size of Wasm linear memory is <2^32"); + let max_heap_size = mem_size - self.ptr_offset; + if size > MAX_POSSIBLE_ALLOCATION { return Err(Error::RequestedAllocationTooLarge); } - let size = size.max(8); + let size = size.max(MIN_POSSIBLE_ALLOCATION); let item_size = size.next_power_of_two(); - if item_size + 8 + self.total_size > self.max_heap_size { + if item_size + PREFIX_SIZE + self.total_size > max_heap_size { return Err(Error::AllocatorOutOfSpace); } @@ -94,61 +129,72 @@ impl FreeingBumpHeapAllocator { let ptr: u32 = if self.heads[list_index] != 0 { // Something from the free list let item = self.heads[list_index]; - let four_bytes = self.get_heap_4bytes(item)?; - self.heads[list_index] = FreeingBumpHeapAllocator::le_bytes_to_u32(four_bytes); - item + 8 + let ptr = item + PREFIX_SIZE; + assert!( + ptr + item_size <= max_heap_size, + "Pointer is looked up in list of free entries, into which + only valid values are inserted; qed" + ); + + self.heads[list_index] = self.get_heap_u64(mem, item)? + .try_into() + .map_err(|_| error("read invalid free list pointer"))?; + ptr } else { // Nothing to be freed. Bump. - self.bump(item_size + 8) + 8 + self.bump(item_size, max_heap_size)? + PREFIX_SIZE }; - (1..8).try_for_each(|i| self.set_heap(ptr - i, 255))?; - - self.set_heap(ptr - 8, list_index as u8)?; + self.set_heap_u64(mem, ptr - PREFIX_SIZE, list_index as u64)?; - self.total_size = self.total_size + item_size + 8; + self.total_size = self.total_size + item_size + PREFIX_SIZE; trace!(target: "wasm-heap", "Heap size is {} bytes after allocation", self.total_size); - Ok(self.ptr_offset + ptr) + Ok(Pointer::new(self.ptr_offset + ptr)) } /// Deallocates the space which was allocated for a pointer. - pub fn deallocate(&mut self, ptr: u32) -> Result<()> { - let ptr = ptr - self.ptr_offset; - if ptr < 8 { + /// + /// # Arguments + /// + /// - `mem` - a slice representing the linear memory on which this allocator operates. + /// - `ptr` - pointer to the allocated chunk + pub fn deallocate(&mut self, mem: &mut [u8], ptr: Pointer) -> Result<()> { + let ptr = u32::from(ptr) - self.ptr_offset; + if ptr < PREFIX_SIZE { return Err(error("Invalid pointer for deallocation")); } - let list_index = usize::from(self.get_heap_byte(ptr - 8)?); - (1..8).try_for_each(|i| self.get_heap_byte(ptr - i).map(|byte| assert!(byte == 255)))?; - let tail = self.heads[list_index]; - self.heads[list_index] = ptr - 8; - - let mut slice = self.get_heap_4bytes(ptr - 8)?; - FreeingBumpHeapAllocator::write_u32_into_le_bytes(tail, &mut slice); - self.set_heap_4bytes(ptr - 8, slice)?; + let list_index: usize = self.get_heap_u64(mem, ptr - PREFIX_SIZE)? + .try_into() + .map_err(|_| error("read invalid list index"))?; + if list_index > self.heads.len() { + return Err(error("read invalid list index")); + } + self.set_heap_u64(mem, ptr - PREFIX_SIZE, self.heads[list_index] as u64)?; + self.heads[list_index] = ptr - PREFIX_SIZE; - let item_size = FreeingBumpHeapAllocator::get_item_size_from_index(list_index); - self.total_size = self.total_size.checked_sub(item_size as u32 + 8) + let item_size = Self::get_item_size_from_index(list_index); + self.total_size = self.total_size.checked_sub(item_size as u32 + PREFIX_SIZE) .ok_or_else(|| error("Unable to subtract from total heap size without overflow"))?; trace!(target: "wasm-heap", "Heap size is {} bytes after deallocation", self.total_size); Ok(()) } - fn bump(&mut self, n: u32) -> u32 { - let res = self.bumper; - self.bumper += n; - res - } - - fn le_bytes_to_u32(arr: [u8; 4]) -> u32 { - u32::from_le_bytes(arr) - } + /// Increases the `bumper` by `item_size + PREFIX_SIZE`. + /// + /// Returns the `bumper` from before the increase. + /// Returns an `Error::AllocatorOutOfSpace` if the operation + /// would exhaust the heap. + fn bump(&mut self, item_size: u32, max_heap_size: u32) -> Result { + if self.bumper + PREFIX_SIZE + item_size > max_heap_size { + return Err(Error::AllocatorOutOfSpace); + } - fn write_u32_into_le_bytes(bytes: u32, slice: &mut [u8]) { - let bytes: [u8; 4] = unsafe { std::mem::transmute::(bytes.to_le()) }; - for i in 0..4 { slice[i] = bytes[i]; } + let res = self.bumper; + self.bumper += item_size + PREFIX_SIZE; + Ok(res) } fn get_item_size_from_index(index: usize) -> usize { @@ -156,304 +202,329 @@ impl FreeingBumpHeapAllocator { 1 << 3 << index } - fn get_heap_4bytes(&mut self, ptr: u32) -> Result<[u8; 4]> { - let mut arr = [0u8; 4]; - self.heap.get_into(self.ptr_offset + ptr, &mut arr)?; - Ok(arr) + // Read a u64 from the heap in LE form. Used to read heap allocation prefixes. + fn get_heap_u64(&self, heap: &[u8], offset: u32) -> Result { + let range = self.heap_range(offset, 8, heap.len()) + .ok_or_else(|| error("read out of heap bounds"))?; + let bytes = heap[range].try_into() + .expect("[u8] slice of length 8 must be convertible to [u8; 8]"); + Ok(u64::from_le_bytes(bytes)) } - fn get_heap_byte(&mut self, ptr: u32) -> Result { - let mut arr = [0u8; 1]; - self.heap.get_into(self.ptr_offset + ptr, &mut arr)?; - Ok(arr[0]) - } - - fn set_heap(&mut self, ptr: u32, value: u8) -> Result<()> { - self.heap.set(self.ptr_offset + ptr, &[value]).map_err(Into::into) + // Write a u64 to the heap in LE form. Used to write heap allocation prefixes. + fn set_heap_u64(&self, heap: &mut [u8], offset: u32, val: u64) -> Result<()> { + let range = self.heap_range(offset, 8, heap.len()) + .ok_or_else(|| error("write out of heap bounds"))?; + let bytes = val.to_le_bytes(); + &mut heap[range].copy_from_slice(&bytes[..]); + Ok(()) } - fn set_heap_4bytes(&mut self, ptr: u32, value: [u8; 4]) -> Result<()> { - self.heap.set(self.ptr_offset + ptr, &value).map_err(Into::into) + fn heap_range(&self, offset: u32, length: u32, heap_len: usize) -> Option> { + let start = offset + .checked_add(self.ptr_offset)? + as usize; + let end = offset + .checked_add(self.ptr_offset)? + .checked_add(length)? + as usize; + if end <= heap_len { + Some(start..end) + } else { + None + } } - } #[cfg(test)] mod tests { use super::*; - use wasmi::MemoryInstance; - use wasmi::memory_units::*; const PAGE_SIZE: u32 = 65536; + /// Makes a pointer out of the given address. + fn to_pointer(address: u32) -> Pointer { + Pointer::new(address) + } + #[test] fn should_allocate_properly() { // given - let mem = MemoryInstance::alloc(Pages(1), None).unwrap(); - let mut heap = FreeingBumpHeapAllocator::new(mem, 0); + let mut mem = [0u8; PAGE_SIZE as usize]; + let mut heap = FreeingBumpHeapAllocator::new(0); // when - let ptr = heap.allocate(1).unwrap(); + let ptr = heap.allocate(&mut mem[..], 1).unwrap(); // then - assert_eq!(ptr, 8); + // returned pointer must start right after `PREFIX_SIZE` + assert_eq!(ptr, to_pointer(PREFIX_SIZE)); } #[test] fn should_always_align_pointers_to_multiples_of_8() { // given - let mem = MemoryInstance::alloc(Pages(1), None).unwrap(); - let mut heap = FreeingBumpHeapAllocator::new(mem, 13); + let mut mem = [0u8; PAGE_SIZE as usize]; + let mut heap = FreeingBumpHeapAllocator::new(13); // when - let ptr = heap.allocate(1).unwrap(); + let ptr = heap.allocate(&mut mem[..], 1).unwrap(); // then // the pointer must start at the next multiple of 8 from 13 // + the prefix of 8 bytes. - assert_eq!(ptr, 24); + assert_eq!(ptr, to_pointer(24)); } #[test] fn should_increment_pointers_properly() { // given - let mem = MemoryInstance::alloc(Pages(1), None).unwrap(); - let mut heap = FreeingBumpHeapAllocator::new(mem, 0); + let mut mem = [0u8; PAGE_SIZE as usize]; + let mut heap = FreeingBumpHeapAllocator::new(0); // when - let ptr1 = heap.allocate(1).unwrap(); - let ptr2 = heap.allocate(9).unwrap(); - let ptr3 = heap.allocate(1).unwrap(); + let ptr1 = heap.allocate(&mut mem[..], 1).unwrap(); + let ptr2 = heap.allocate(&mut mem[..], 9).unwrap(); + let ptr3 = heap.allocate(&mut mem[..], 1).unwrap(); // then // a prefix of 8 bytes is prepended to each pointer - assert_eq!(ptr1, 8); + assert_eq!(ptr1, to_pointer(PREFIX_SIZE)); // the prefix of 8 bytes + the content of ptr1 padded to the lowest possible // item size of 8 bytes + the prefix of ptr1 - assert_eq!(ptr2, 24); + assert_eq!(ptr2, to_pointer(24)); // ptr2 + its content of 16 bytes + the prefix of 8 bytes - assert_eq!(ptr3, 24 + 16 + 8); + assert_eq!(ptr3, to_pointer(24 + 16 + PREFIX_SIZE)); } #[test] fn should_free_properly() { // given - let mem = MemoryInstance::alloc(Pages(1), None).unwrap(); - let mut heap = FreeingBumpHeapAllocator::new(mem, 0); - let ptr1 = heap.allocate(1).unwrap(); + let mut mem = [0u8; PAGE_SIZE as usize]; + let mut heap = FreeingBumpHeapAllocator::new(0); + let ptr1 = heap.allocate(&mut mem[..], 1).unwrap(); // the prefix of 8 bytes is prepended to the pointer - assert_eq!(ptr1, 8); + assert_eq!(ptr1, to_pointer(PREFIX_SIZE)); - let ptr2 = heap.allocate(1).unwrap(); + let ptr2 = heap.allocate(&mut mem[..], 1).unwrap(); // the prefix of 8 bytes + the content of ptr 1 is prepended to the pointer - assert_eq!(ptr2, 24); + assert_eq!(ptr2, to_pointer(24)); // when - heap.deallocate(ptr2).unwrap(); + heap.deallocate(&mut mem[..], ptr2).unwrap(); // then // then the heads table should contain a pointer to the // prefix of ptr2 in the leftmost entry - assert_eq!(heap.heads[0], ptr2 - 8); + assert_eq!(heap.heads[0], u32::from(ptr2) - PREFIX_SIZE); } #[test] fn should_deallocate_and_reallocate_properly() { // given - let mem = MemoryInstance::alloc(Pages(1), None).unwrap(); + let mut mem = [0u8; PAGE_SIZE as usize]; let padded_offset = 16; - let mut heap = FreeingBumpHeapAllocator::new(mem, 13); + let mut heap = FreeingBumpHeapAllocator::new(13); - let ptr1 = heap.allocate(1).unwrap(); + let ptr1 = heap.allocate(&mut mem[..], 1).unwrap(); // the prefix of 8 bytes is prepended to the pointer - assert_eq!(ptr1, padded_offset + 8); + assert_eq!(ptr1, to_pointer(padded_offset + PREFIX_SIZE)); - let ptr2 = heap.allocate(9).unwrap(); + let ptr2 = heap.allocate(&mut mem[..], 9).unwrap(); // the padded_offset + the previously allocated ptr (8 bytes prefix + // 8 bytes content) + the prefix of 8 bytes which is prepended to the // current pointer - assert_eq!(ptr2, padded_offset + 16 + 8); + assert_eq!(ptr2, to_pointer(padded_offset + 16 + PREFIX_SIZE)); // when - heap.deallocate(ptr2).unwrap(); - let ptr3 = heap.allocate(9).unwrap(); + heap.deallocate(&mut mem[..], ptr2).unwrap(); + let ptr3 = heap.allocate(&mut mem[..], 9).unwrap(); // then // should have re-allocated - assert_eq!(ptr3, padded_offset + 16 + 8); + assert_eq!(ptr3, to_pointer(padded_offset + 16 + PREFIX_SIZE)); assert_eq!(heap.heads, [0; N]); } #[test] fn should_build_linked_list_of_free_areas_properly() { // given - let mem = MemoryInstance::alloc(Pages(1), None).unwrap(); - let mut heap = FreeingBumpHeapAllocator::new(mem, 0); + let mut mem = [0u8; PAGE_SIZE as usize]; + let mut heap = FreeingBumpHeapAllocator::new(0); - let ptr1 = heap.allocate(8).unwrap(); - let ptr2 = heap.allocate(8).unwrap(); - let ptr3 = heap.allocate(8).unwrap(); + let ptr1 = heap.allocate(&mut mem[..], 8).unwrap(); + let ptr2 = heap.allocate(&mut mem[..], 8).unwrap(); + let ptr3 = heap.allocate(&mut mem[..], 8).unwrap(); // when - heap.deallocate(ptr1).unwrap(); - heap.deallocate(ptr2).unwrap(); - heap.deallocate(ptr3).unwrap(); + heap.deallocate(&mut mem[..], ptr1).unwrap(); + heap.deallocate(&mut mem[..], ptr2).unwrap(); + heap.deallocate(&mut mem[..], ptr3).unwrap(); // then - let mut expected = [0; N]; - expected[0] = ptr3 - 8; - assert_eq!(heap.heads, expected); + assert_eq!(heap.heads[0], u32::from(ptr3) - PREFIX_SIZE); - let ptr4 = heap.allocate(8).unwrap(); + let ptr4 = heap.allocate(&mut mem[..], 8).unwrap(); assert_eq!(ptr4, ptr3); - expected[0] = ptr2 - 8; - assert_eq!(heap.heads, expected); + assert_eq!(heap.heads[0], u32::from(ptr2) - PREFIX_SIZE); } #[test] fn should_not_allocate_if_too_large() { // given - let mem = MemoryInstance::alloc(Pages(1), Some(Pages(1))).unwrap(); - let mut heap = FreeingBumpHeapAllocator::new(mem, 13); + let mut mem = [0u8; PAGE_SIZE as usize]; + let mut heap = FreeingBumpHeapAllocator::new(13); // when - let ptr = heap.allocate(PAGE_SIZE - 13); + let ptr = heap.allocate(&mut mem[..], PAGE_SIZE - 13); // then - assert_eq!(ptr.is_err(), true); - if let Err(err) = ptr { - match err { - Error::AllocatorOutOfSpace => {}, - _ => panic!("Expected out of space error"), - } + match ptr.unwrap_err() { + Error::AllocatorOutOfSpace => {}, + e => panic!("Expected allocator out of space error, got: {:?}", e), } } #[test] fn should_not_allocate_if_full() { // given - let mem = MemoryInstance::alloc(Pages(1), Some(Pages(1))).unwrap(); - let mut heap = FreeingBumpHeapAllocator::new(mem, 0); - let ptr1 = heap.allocate((PAGE_SIZE / 2) - 8).unwrap(); - assert_eq!(ptr1, 8); + let mut mem = [0u8; PAGE_SIZE as usize]; + let mut heap = FreeingBumpHeapAllocator::new(0); + let ptr1 = heap.allocate(&mut mem[..], (PAGE_SIZE / 2) - PREFIX_SIZE).unwrap(); + assert_eq!(ptr1, to_pointer(PREFIX_SIZE)); // when - let ptr2 = heap.allocate(PAGE_SIZE / 2); + let ptr2 = heap.allocate(&mut mem[..], PAGE_SIZE / 2); // then // there is no room for another half page incl. its 8 byte prefix - assert_eq!(ptr2.is_err(), true); - if let Err(err) = ptr2 { - match err { - Error::AllocatorOutOfSpace => {}, - _ => panic!("Expected out of space error"), - } + match ptr2.unwrap_err() { + Error::AllocatorOutOfSpace => {}, + e => panic!("Expected allocator out of space error, got: {:?}", e), } } #[test] fn should_allocate_max_possible_allocation_size() { // given - let pages_needed = (MAX_POSSIBLE_ALLOCATION as usize / PAGE_SIZE as usize) + 1; - let mem = MemoryInstance::alloc(Pages(pages_needed), Some(Pages(pages_needed))).unwrap(); - let mut heap = FreeingBumpHeapAllocator::new(mem, 0); + let mut mem = vec![0u8; (MAX_POSSIBLE_ALLOCATION + PAGE_SIZE) as usize]; + let mut heap = FreeingBumpHeapAllocator::new(0); // when - let ptr = heap.allocate(MAX_POSSIBLE_ALLOCATION).unwrap(); + let ptr = heap.allocate(&mut mem[..], MAX_POSSIBLE_ALLOCATION).unwrap(); // then - assert_eq!(ptr, 8); + assert_eq!(ptr, to_pointer(PREFIX_SIZE)); } #[test] fn should_not_allocate_if_requested_size_too_large() { // given - let mem = MemoryInstance::alloc(Pages(1), None).unwrap(); - let mut heap = FreeingBumpHeapAllocator::new(mem, 0); + let mut mem = [0u8; PAGE_SIZE as usize]; + let mut heap = FreeingBumpHeapAllocator::new(0); // when - let ptr = heap.allocate(MAX_POSSIBLE_ALLOCATION + 1); + let ptr = heap.allocate(&mut mem[..], MAX_POSSIBLE_ALLOCATION + 1); // then - assert_eq!(ptr.is_err(), true); - if let Err(err) = ptr { - match err { - Error::RequestedAllocationTooLarge => {}, - e => panic!("Expected out of space error, got: {:?}", e), - } + match ptr.unwrap_err() { + Error::RequestedAllocationTooLarge => {}, + e => panic!("Expected allocation size too large error, got: {:?}", e), } } #[test] - fn should_include_prefixes_in_total_heap_size() { + fn should_return_error_when_bumper_greater_than_heap_size() { // given - let mem = MemoryInstance::alloc(Pages(1), None).unwrap(); - let mut heap = FreeingBumpHeapAllocator::new(mem, 1); + let mut mem = [0u8; 64]; + let mut heap = FreeingBumpHeapAllocator::new(0); + + let ptr1 = heap.allocate(&mut mem[..], 32).unwrap(); + assert_eq!(ptr1, to_pointer(PREFIX_SIZE)); + heap.deallocate(&mut mem[..], ptr1).expect("failed freeing ptr1"); + assert_eq!(heap.total_size, 0); + assert_eq!(heap.bumper, 40); + + let ptr2 = heap.allocate(&mut mem[..], 16).unwrap(); + assert_eq!(ptr2, to_pointer(48)); + heap.deallocate(&mut mem[..], ptr2).expect("failed freeing ptr2"); + assert_eq!(heap.total_size, 0); + assert_eq!(heap.bumper, 64); // when - // an item size of 16 must be used then - heap.allocate(9).unwrap(); + // the `bumper` value is equal to `max_heap_size` here and any + // further allocation which would increment the bumper must fail. + // we try to allocate 8 bytes here, which will increment the + // bumper since no 8 byte item has been allocated+freed before. + let ptr = heap.allocate(&mut mem[..], 8); // then - assert_eq!(heap.total_size, 8 + 16); + match ptr.unwrap_err() { + Error::AllocatorOutOfSpace => {}, + e => panic!("Expected allocator out of space error, got: {:?}", e), + } } #[test] - fn should_calculate_total_heap_size_to_zero() { + fn should_include_prefixes_in_total_heap_size() { // given - let mem = MemoryInstance::alloc(Pages(1), None).unwrap(); - let mut heap = FreeingBumpHeapAllocator::new(mem, 13); + let mut mem = [0u8; PAGE_SIZE as usize]; + let mut heap = FreeingBumpHeapAllocator::new(1); // when - let ptr = heap.allocate(42).unwrap(); - assert_eq!(ptr, 16 + 8); - heap.deallocate(ptr).unwrap(); + // an item size of 16 must be used then + heap.allocate(&mut mem[..], 9).unwrap(); // then - assert_eq!(heap.total_size, 0); + assert_eq!(heap.total_size, PREFIX_SIZE + 16); } #[test] - fn should_calculate_total_size_of_zero() { + fn should_calculate_total_heap_size_to_zero() { // given - let mem = MemoryInstance::alloc(Pages(1), None).unwrap(); - let mut heap = FreeingBumpHeapAllocator::new(mem, 19); + let mut mem = [0u8; PAGE_SIZE as usize]; + let mut heap = FreeingBumpHeapAllocator::new(13); // when - for _ in 1..10 { - let ptr = heap.allocate(42).unwrap(); - heap.deallocate(ptr).unwrap(); - } + let ptr = heap.allocate(&mut mem[..], 42).unwrap(); + assert_eq!(ptr, to_pointer(16 + PREFIX_SIZE)); + heap.deallocate(&mut mem[..], ptr).unwrap(); // then assert_eq!(heap.total_size, 0); } #[test] - fn should_write_u32_correctly_into_le() { + fn should_calculate_total_size_of_zero() { // given - let mut heap = vec![0; 5]; + let mut mem = [0u8; PAGE_SIZE as usize]; + let mut heap = FreeingBumpHeapAllocator::new(19); // when - FreeingBumpHeapAllocator::write_u32_into_le_bytes(1, &mut heap[0..4]); + for _ in 1..10 { + let ptr = heap.allocate(&mut mem[..], 42).unwrap(); + heap.deallocate(&mut mem[..], ptr).unwrap(); + } // then - assert_eq!(heap, [1, 0, 0, 0, 0]); + assert_eq!(heap.total_size, 0); } #[test] - fn should_write_u32_max_correctly_into_le() { + fn should_read_and_write_u64_correctly() { // given - let mut heap = vec![0; 5]; + let mut mem = [0u8; PAGE_SIZE as usize]; + let heap = FreeingBumpHeapAllocator::new(16); // when - FreeingBumpHeapAllocator::write_u32_into_le_bytes(u32::max_value(), &mut heap[0..4]); + heap.set_heap_u64(&mut mem[..], 40, 4480113).unwrap(); // then - assert_eq!(heap, [255, 255, 255, 255, 0]); + let value = heap.get_heap_u64(&mut mem[..], 40).unwrap(); + assert_eq!(value, 4480113); } #[test] diff --git a/core/executor/src/error.rs b/core/executor/src/error.rs index 9bfa05ff5f534f08a442b3c11a97cf3d8611df12..c5148241eea5a0b4050abc820784427878022605 100644 --- a/core/executor/src/error.rs +++ b/core/executor/src/error.rs @@ -16,7 +16,6 @@ //! Rust executor possible errors. -use state_machine; use serializer; use wasmi; @@ -66,16 +65,19 @@ pub enum Error { #[display(fmt="The runtime has the `start` function")] RuntimeHasStartFn, /// Some other error occurred - Other(&'static str), + Other(String), /// Some error occurred in the allocator #[display(fmt="Error in allocator: {}", _0)] Allocator(&'static str), - /// The allocator run out of space. - #[display(fmt="Allocator run out of space")] + /// The allocator ran out of space. + #[display(fmt="Allocator ran out of space")] AllocatorOutOfSpace, /// Someone tried to allocate more memory than the allowed maximum per allocation. #[display(fmt="Requested allocation size is too large")] RequestedAllocationTooLarge, + /// Executing the given function failed with the given error. + #[display(fmt="Function execution failed with: {}", _0)] + FunctionExecution(String), } impl std::error::Error for Error { @@ -89,12 +91,10 @@ impl std::error::Error for Error { } } -impl state_machine::Error for Error {} - impl wasmi::HostError for Error {} -impl From<&'static str> for Error { - fn from(err: &'static str) -> Error { +impl From for Error { + fn from(err: String) -> Error { Error::Other(err) } } diff --git a/core/executor/src/lib.rs b/core/executor/src/lib.rs index 065de451c19dc65c241ee6cd90bd1b45af38886f..b5c502795142fa6d2f6c10b13a98802d2348aac3 100644 --- a/core/executor/src/lib.rs +++ b/core/executor/src/lib.rs @@ -14,16 +14,17 @@ // You should have received a copy of the GNU General Public License // along with Substrate. If not, see . -//! Temporary crate for contracts implementations. +//! A crate that provides means of executing/dispatching calls into the runtime. //! -//! This will be replaced with WASM contracts stored on-chain. -//! ** NOTE *** -//! This is entirely deprecated with the idea of a single-module Wasm module for state transition. -//! The dispatch table should be replaced with the specific functions needed: -//! - execute_block(bytes) -//! - init_block(PrevBlock?) -> InProgressBlock -//! - add_transaction(InProgressBlock) -> InProgressBlock -//! It is left as is for now as it might be removed before this is ever done. +//! There are a few responsibilities of this crate at the moment: +//! +//! - It provides an implementation of a common entrypoint for calling into the runtime, both +//! wasm and compiled. +//! - It defines the environment for the wasm execution, namely the host functions that are to be +//! provided into the wasm runtime module. +//! - It also provides the required infrastructure for executing the current wasm runtime (specified +//! by the current value of `:code` in the provided externalities), i.e. interfacing with +//! wasm engine used, instance cache. #![warn(missing_docs)] #![recursion_limit="128"] @@ -42,11 +43,12 @@ pub use wasmi; pub use wasm_executor::WasmExecutor; pub use native_executor::{with_native_environment, NativeExecutor, NativeExecutionDispatch}; pub use wasm_runtimes_cache::RuntimesCache; -pub use state_machine::Externalities; pub use runtime_version::{RuntimeVersion, NativeVersion}; pub use codec::Codec; #[doc(hidden)] -pub use primitives::Blake2Hasher; +pub use primitives::{Blake2Hasher, traits::Externalities}; +#[doc(hidden)] +pub use wasm_interface; /// Provides runtime information. pub trait RuntimeInfo { diff --git a/core/executor/src/native_executor.rs b/core/executor/src/native_executor.rs index 937e0033539f0ea3dbd8abf0638be2f507cf443e..cdf0be7f76c6dd400230e92547a6047d9420755c 100644 --- a/core/executor/src/native_executor.rs +++ b/core/executor/src/native_executor.rs @@ -16,12 +16,11 @@ use std::{result, cell::RefCell, panic::UnwindSafe}; use crate::error::{Error, Result}; -use state_machine::{CodeExecutor, Externalities}; use crate::wasm_executor::WasmExecutor; use runtime_version::{NativeVersion, RuntimeVersion}; use codec::{Decode, Encode}; use crate::RuntimeInfo; -use primitives::{Blake2Hasher, NativeOrEncoded}; +use primitives::{Blake2Hasher, NativeOrEncoded, traits::{CodeExecutor, Externalities}}; use log::{trace, warn}; use crate::RuntimesCache; @@ -35,7 +34,7 @@ fn safe_call(f: F) -> Result { // Substrate uses custom panic hook that terminates process on panic. Disable termination for the native call. let _guard = panic_handler::AbortGuard::force_unwind(); - ::std::panic::catch_unwind(f).map_err(|_| Error::Runtime) + std::panic::catch_unwind(f).map_err(|_| Error::Runtime) } /// Set up the externalities and safe calling environment to execute calls to a native runtime. @@ -44,15 +43,16 @@ fn safe_call(f: F) -> Result pub fn with_native_environment(ext: &mut dyn Externalities, f: F) -> Result where F: UnwindSafe + FnOnce() -> U { - ::runtime_io::with_externalities(ext, move || safe_call(f)) + runtime_io::with_externalities(ext, move || safe_call(f)) } -/// Delegate for dispatching a CodeExecutor call to native code. +/// Delegate for dispatching a CodeExecutor call. +/// +/// By dispatching we mean that we execute a runtime function specified by it's name. pub trait NativeExecutionDispatch: Send + Sync { - /// Get the wasm code that the native dispatch will be equivalent to. - fn native_equivalent() -> &'static [u8]; - - /// Dispatch a method and input data to be executed natively. + /// Dispatch a method in the runtime. + /// + /// If the method with the specified name doesn't exist then `Err` is returned. fn dispatch(ext: &mut dyn Externalities, method: &str, data: &[u8]) -> Result>; /// Provide native runtime version. @@ -126,7 +126,7 @@ impl CodeExecutor for NativeExecutor, R:Decode + Encode + PartialEq, - NC: FnOnce() -> result::Result + UnwindSafe + NC: FnOnce() -> result::Result + UnwindSafe >( &self, ext: &mut E, @@ -211,19 +211,13 @@ impl CodeExecutor for NativeExecutor { + ( $pub:vis $name:ident, $dispatcher:path, $version:path $(,)?) => { /// A unit struct which implements `NativeExecutionDispatch` feeding in the hard-coded runtime. $pub struct $name; - $crate::native_executor_instance!(IMPL $name, $dispatcher, $version, $code); + $crate::native_executor_instance!(IMPL $name, $dispatcher, $version); }; - (IMPL $name:ident, $dispatcher:path, $version:path, $code:expr) => { + (IMPL $name:ident, $dispatcher:path, $version:path) => { impl $crate::NativeExecutionDispatch for $name { - fn native_equivalent() -> &'static [u8] { - // WARNING!!! This assumes that the runtime was built *before* the main project. Until we - // get a proper build script, this must be strictly adhered to or things will go wrong. - $code - } - fn dispatch( ext: &mut $crate::Externalities<$crate::Blake2Hasher>, method: &str, diff --git a/core/executor/src/sandbox.rs b/core/executor/src/sandbox.rs index 6687738abc89750acefae9b9dbdc39bba5a27ec1..f09c246679e5d2e85440ad97960ea9dd8c656e47 100644 --- a/core/executor/src/sandbox.rs +++ b/core/executor/src/sandbox.rs @@ -23,16 +23,23 @@ use std::{collections::HashMap, rc::Rc}; use codec::{Decode, Encode}; use primitives::sandbox as sandbox_primitives; use wasmi::{ - Externals, FuncRef, ImportResolver, MemoryInstance, MemoryRef, Module, ModuleInstance, + Externals, ImportResolver, MemoryInstance, MemoryRef, Module, ModuleInstance, ModuleRef, RuntimeArgs, RuntimeValue, Trap, TrapKind, memory_units::Pages, }; +use wasm_interface::{Pointer, WordSize}; /// Index of a function inside the supervisor. /// /// This is a typically an index in the default table of the supervisor, however /// the exact meaning of this index is depends on the implementation of dispatch function. #[derive(Copy, Clone, Debug, PartialEq)] -struct SupervisorFuncIndex(usize); +pub struct SupervisorFuncIndex(usize); + +impl From for usize { + fn from(index: SupervisorFuncIndex) -> Self { + index.0 + } +} /// Index of a function within guest index space. /// @@ -72,7 +79,7 @@ impl ImportResolver for Imports { module_name: &str, field_name: &str, signature: &::wasmi::Signature, - ) -> std::result::Result { + ) -> std::result::Result { let key = ( module_name.as_bytes().to_owned(), field_name.as_bytes().to_owned(), @@ -137,11 +144,14 @@ impl ImportResolver for Imports { /// /// Note that this functions are only called in the `supervisor` context. pub trait SandboxCapabilities { + /// Represents a function reference into the supervisor environment. + type SupervisorFuncRef; + /// Returns a reference to an associated sandbox `Store`. - fn store(&self) -> &Store; + fn store(&self) -> &Store; /// Returns a mutable reference to an associated sandbox `Store`. - fn store_mut(&mut self) -> &mut Store; + fn store_mut(&mut self) -> &mut Store; /// Allocate space of the specified length in the supervisor memory. /// @@ -150,7 +160,7 @@ pub trait SandboxCapabilities { /// Returns `Err` if allocation not possible or errors during heap management. /// /// Returns pointer to the allocated block. - fn allocate(&mut self, len: u32) -> Result; + fn allocate(&mut self, len: WordSize) -> Result>; /// Deallocate space specified by the pointer that was previously returned by [`allocate`]. /// @@ -159,35 +169,57 @@ pub trait SandboxCapabilities { /// Returns `Err` if deallocation not possible or because of errors in heap management. /// /// [`allocate`]: #tymethod.allocate - fn deallocate(&mut self, ptr: u32) -> Result<()>; + fn deallocate(&mut self, ptr: Pointer) -> Result<()>; /// Write `data` into the supervisor memory at offset specified by `ptr`. /// /// # Errors /// /// Returns `Err` if `ptr + data.len()` is out of bounds. - fn write_memory(&mut self, ptr: u32, data: &[u8]) -> Result<()>; + fn write_memory(&mut self, ptr: Pointer, data: &[u8]) -> Result<()>; /// Read `len` bytes from the supervisor memory. /// /// # Errors /// /// Returns `Err` if `ptr + len` is out of bounds. - fn read_memory(&self, ptr: u32, len: u32) -> Result>; + fn read_memory(&self, ptr: Pointer, len: WordSize) -> Result>; + + /// Invoke a function in the supervisor environment. + /// + /// This first invokes the dispatch_thunk function, passing in the function index of the + /// desired function to call and serialized arguments. The thunk calls the desired function + /// with the deserialized arguments, then serializes the result into memory and returns + /// reference. The pointer to and length of the result in linear memory is encoded into an i64, + /// with the upper 32 bits representing the pointer and the lower 32 bits representing the + /// length. + /// + /// # Errors + /// + /// Returns `Err` if the dispatch_thunk function has an incorrect signature or traps during + /// execution. + fn invoke( + &mut self, + dispatch_thunk: &Self::SupervisorFuncRef, + invoke_args_ptr: Pointer, + invoke_args_len: WordSize, + state: u32, + func_idx: SupervisorFuncIndex, + ) -> Result; } /// Implementation of [`Externals`] that allows execution of guest module with /// [externals][`Externals`] that might refer functions defined by supervisor. /// /// [`Externals`]: ../../wasmi/trait.Externals.html -pub struct GuestExternals<'a, FE: SandboxCapabilities + Externals + 'a> { +pub struct GuestExternals<'a, FE: SandboxCapabilities + 'a> { supervisor_externals: &'a mut FE, - sandbox_instance: &'a SandboxInstance, + sandbox_instance: &'a SandboxInstance, state: u32, } fn trap(msg: &'static str) -> Trap { - TrapKind::Host(Box::new(Error::Other(msg))).into() + TrapKind::Host(Box::new(Error::Other(msg.into()))).into() } fn deserialize_result(serialized_result: &[u8]) -> std::result::Result, Trap> { @@ -204,7 +236,7 @@ fn deserialize_result(serialized_result: &[u8]) -> std::result::Result Externals for GuestExternals<'a, FE> { +impl<'a, FE: SandboxCapabilities + 'a> Externals for GuestExternals<'a, FE> { fn invoke_index( &mut self, index: usize, @@ -213,7 +245,6 @@ impl<'a, FE: SandboxCapabilities + Externals + 'a> Externals for GuestExternals< // Make `index` typesafe again. let index = GuestFuncIndex(index); - let dispatch_thunk = self.sandbox_instance.dispatch_thunk.clone(); let func_idx = self.sandbox_instance .guest_to_supervisor_mapping .func_by_guest_index(index) @@ -236,34 +267,26 @@ impl<'a, FE: SandboxCapabilities + Externals + 'a> Externals for GuestExternals< // Move serialized arguments inside the memory and invoke dispatch thunk and // then free allocated memory. - let invoke_args_ptr = self.supervisor_externals - .allocate(invoke_args_data.len() as u32)?; - self.supervisor_externals - .write_memory(invoke_args_ptr, &invoke_args_data)?; - let result = ::wasmi::FuncInstance::invoke( - &dispatch_thunk, - &[ - RuntimeValue::I32(invoke_args_ptr as i32), - RuntimeValue::I32(invoke_args_data.len() as i32), - RuntimeValue::I32(state as i32), - RuntimeValue::I32(func_idx.0 as i32), - ], - self.supervisor_externals, - ); + let invoke_args_len = invoke_args_data.len() as WordSize; + let invoke_args_ptr = self.supervisor_externals.allocate(invoke_args_len)?; + self.supervisor_externals.write_memory(invoke_args_ptr, &invoke_args_data)?; + let result = self.supervisor_externals.invoke( + &self.sandbox_instance.dispatch_thunk, + invoke_args_ptr, + invoke_args_len, + state, + func_idx, + )?; self.supervisor_externals.deallocate(invoke_args_ptr)?; // dispatch_thunk returns pointer to serialized arguments. - let (serialized_result_val_ptr, serialized_result_val_len) = match result { - // Unpack pointer and len of the serialized result data. - Ok(Some(RuntimeValue::I64(v))) => { - // Cast to u64 to use zero-extension. - let v = v as u64; - let ptr = (v as u64 >> 32) as u32; - let len = (v & 0xFFFFFFFF) as u32; - (ptr, len) - } - Ok(_) => return Err(trap("Supervisor function returned unexpected result!")), - Err(_) => return Err(trap("Supervisor function trapped!")), + // Unpack pointer and len of the serialized result data. + let (serialized_result_val_ptr, serialized_result_val_len) = { + // Cast to u64 to use zero-extension. + let v = result as u64; + let ptr = (v as u64 >> 32) as u32; + let len = (v & 0xFFFFFFFF) as u32; + (Pointer::new(ptr), len) }; let serialized_result_val = self.supervisor_externals @@ -271,21 +294,18 @@ impl<'a, FE: SandboxCapabilities + Externals + 'a> Externals for GuestExternals< self.supervisor_externals .deallocate(serialized_result_val_ptr)?; - // We do not have to check the signature here, because it's automatically - // checked by wasmi. - deserialize_result(&serialized_result_val) } } fn with_guest_externals( supervisor_externals: &mut FE, - sandbox_instance: &SandboxInstance, + sandbox_instance: &SandboxInstance, state: u32, f: F, ) -> R where - FE: SandboxCapabilities + Externals, + FE: SandboxCapabilities, F: FnOnce(&mut GuestExternals) -> R, { let mut guest_externals = GuestExternals { @@ -307,14 +327,16 @@ where /// it's required to provide supervisor externals: it will be used to execute /// code in the supervisor context. /// +/// This is generic over a supervisor function reference type. +/// /// [`invoke`]: #method.invoke -pub struct SandboxInstance { +pub struct SandboxInstance { instance: ModuleRef, - dispatch_thunk: FuncRef, + dispatch_thunk: FR, guest_to_supervisor_mapping: GuestToSupervisorFunctionMapping, } -impl SandboxInstance { +impl SandboxInstance { /// Invoke an exported function by a name. /// /// `supervisor_externals` is required to execute the implementations @@ -322,7 +344,7 @@ impl SandboxInstance { /// /// The `state` parameter can be used to provide custom data for /// these syscall implementations. - pub fn invoke( + pub fn invoke>( &self, export_name: &str, args: &[RuntimeValue], @@ -411,9 +433,9 @@ fn decode_environment_definition( /// - Module in `wasm` is invalid or couldn't be instantiated. /// /// [`EnvironmentDefinition`]: ../../sandbox/struct.EnvironmentDefinition.html -pub fn instantiate( +pub fn instantiate( supervisor_externals: &mut FE, - dispatch_thunk: FuncRef, + dispatch_thunk: FE::SupervisorFuncRef, wasm: &[u8], raw_env_def: &[u8], state: u32, @@ -452,15 +474,17 @@ pub fn instantiate( } /// This struct keeps track of all sandboxed components. -pub struct Store { +/// +/// This is generic over a supervisor function reference type. +pub struct Store { // Memories and instances are `Some` untill torndown. - instances: Vec>>, + instances: Vec>>>, memories: Vec>, } -impl Store { +impl Store { /// Create a new empty sandbox store. - pub fn new() -> Store { + pub fn new() -> Self { Store { instances: Vec::new(), memories: Vec::new(), @@ -496,7 +520,7 @@ impl Store { /// /// Returns `Err` If `instance_idx` isn't a valid index of an instance or /// instance is already torndown. - pub fn instance(&self, instance_idx: u32) -> Result> { + pub fn instance(&self, instance_idx: u32) -> Result>> { self.instances .get(instance_idx as usize) .cloned() @@ -552,7 +576,7 @@ impl Store { } } - fn register_sandbox_instance(&mut self, sandbox_instance: Rc) -> u32 { + fn register_sandbox_instance(&mut self, sandbox_instance: Rc>) -> u32 { let instance_idx = self.instances.len(); self.instances.push(Some(sandbox_instance)); instance_idx as u32 @@ -643,7 +667,10 @@ mod tests { if let Err(err) = res { assert_eq!( format!("{}", err), - format!("{}", wasmi::Error::Trap(Error::AllocatorOutOfSpace.into())) + format!( + "{}", + wasmi::Error::Trap(Error::FunctionExecution("AllocatorOutOfSpace".into()).into()), + ), ); } } diff --git a/core/executor/src/wasm_executor.rs b/core/executor/src/wasm_executor.rs index 3eed549773f1a03cc2994b42831bb8191b069e19..6ded0adad63cdaf7d3a285f6afd19648a480a3ae 100644 --- a/core/executor/src/wasm_executor.rs +++ b/core/executor/src/wasm_executor.rs @@ -14,9 +14,12 @@ // You should have received a copy of the GNU General Public License // along with Substrate. If not, see . -//! Rust implementation of Substrate contracts. +//! Wasm interface module. +//! +//! This module defines and implements the wasm part of Substrate Host Interface and provides +//! an interface for calling into the wasm runtime. -use std::{collections::HashMap, convert::TryFrom, str}; +use std::{convert::TryFrom, str, panic}; use tiny_keccak; use secp256k1; @@ -24,92 +27,277 @@ use wasmi::{ Module, ModuleInstance, MemoryInstance, MemoryRef, TableRef, ImportsBuilder, ModuleRef, memory_units::Pages, RuntimeValue::{I32, I64, self}, }; -use state_machine::{Externalities, ChildStorageKey}; -use crate::error::{Error, Result}; -use codec::Encode; +use super::{sandbox, allocator, error::{Error, Result}}; +use codec::{Encode, Decode}; use primitives::{ blake2_128, blake2_256, twox_64, twox_128, twox_256, ed25519, sr25519, Pair, crypto::KeyTypeId, - offchain, hexdisplay::HexDisplay, sandbox as sandbox_primitives, H256, Blake2Hasher, + offchain, sandbox as sandbox_primitives, Blake2Hasher, + traits::Externalities, }; -use trie::{TrieConfiguration, trie_types::Layout}; -use crate::sandbox; -use crate::allocator; +use trie::TrieConfiguration; +use trie::trie_types::Layout; use log::trace; +use wasm_interface::{ + FunctionContext, HostFunctions, Pointer, WordSize, Sandbox, MemoryId, PointerType, + Result as WResult, +}; #[cfg(feature="wasm-extern-trace")] macro_rules! debug_trace { ( $( $x:tt )* ) => ( trace!( $( $x )* ) ) } + #[cfg(not(feature="wasm-extern-trace"))] macro_rules! debug_trace { ( $( $x:tt )* ) => () } -struct FunctionExecutor<'e, E: Externalities + 'e> { - sandbox_store: sandbox::Store, +struct FunctionExecutor { + sandbox_store: sandbox::Store, heap: allocator::FreeingBumpHeapAllocator, memory: MemoryRef, table: Option, - ext: &'e mut E, - hash_lookup: HashMap, Vec>, } -impl<'e, E: Externalities> FunctionExecutor<'e, E> { - fn new(m: MemoryRef, heap_base: u32, t: Option, e: &'e mut E) -> Result { +impl FunctionExecutor { + fn new(m: MemoryRef, heap_base: u32, t: Option) -> Result { Ok(FunctionExecutor { sandbox_store: sandbox::Store::new(), - heap: allocator::FreeingBumpHeapAllocator::new(m.clone(), heap_base), + heap: allocator::FreeingBumpHeapAllocator::new(heap_base), memory: m, table: t, - ext: e, - hash_lookup: HashMap::new(), }) } } -impl<'e, E: Externalities> sandbox::SandboxCapabilities for FunctionExecutor<'e, E> { - fn store(&self) -> &sandbox::Store { +impl sandbox::SandboxCapabilities for FunctionExecutor { + type SupervisorFuncRef = wasmi::FuncRef; + + fn store(&self) -> &sandbox::Store { &self.sandbox_store } - fn store_mut(&mut self) -> &mut sandbox::Store { + fn store_mut(&mut self) -> &mut sandbox::Store { &mut self.sandbox_store } - fn allocate(&mut self, len: u32) -> Result { - self.heap.allocate(len) + fn allocate(&mut self, len: WordSize) -> Result> { + let heap = &mut self.heap; + self.memory.with_direct_access_mut(|mem| { + heap.allocate(mem, len) + }) } - fn deallocate(&mut self, ptr: u32) -> Result<()> { - self.heap.deallocate(ptr) + fn deallocate(&mut self, ptr: Pointer) -> Result<()> { + let heap = &mut self.heap; + self.memory.with_direct_access_mut(|mem| { + heap.deallocate(mem, ptr) + }) } - fn write_memory(&mut self, ptr: u32, data: &[u8]) -> Result<()> { - self.memory.set(ptr, data).map_err(Into::into) + fn write_memory(&mut self, ptr: Pointer, data: &[u8]) -> Result<()> { + self.memory.set(ptr.into(), data).map_err(Into::into) } - fn read_memory(&self, ptr: u32, len: u32) -> Result> { - self.memory.get(ptr, len as usize).map_err(Into::into) + fn read_memory(&self, ptr: Pointer, len: WordSize) -> Result> { + self.memory.get(ptr.into(), len as usize).map_err(Into::into) + } + + fn invoke( + &mut self, + dispatch_thunk: &Self::SupervisorFuncRef, + invoke_args_ptr: Pointer, + invoke_args_len: WordSize, + state: u32, + func_idx: sandbox::SupervisorFuncIndex, + ) -> Result + { + let result = wasmi::FuncInstance::invoke( + dispatch_thunk, + &[ + RuntimeValue::I32(u32::from(invoke_args_ptr) as i32), + RuntimeValue::I32(invoke_args_len as i32), + RuntimeValue::I32(state as i32), + RuntimeValue::I32(usize::from(func_idx) as i32), + ], + self, + ); + match result { + Ok(Some(RuntimeValue::I64(val))) => Ok(val), + Ok(_) => return Err("Supervisor function returned unexpected result!".into()), + Err(err) => Err(Error::Trap(err)), + } } } -trait WritePrimitive { - fn write_primitive(&self, offset: u32, t: T) -> Result<()>; +impl FunctionContext for FunctionExecutor { + fn read_memory_into(&self, address: Pointer, dest: &mut [u8]) -> WResult<()> { + self.memory.get_into(address.into(), dest).map_err(|e| format!("{:?}", e)) + } + + fn write_memory(&mut self, address: Pointer, data: &[u8]) -> WResult<()> { + self.memory.set(address.into(), data).map_err(|e| format!("{:?}", e)) + } + + fn allocate_memory(&mut self, size: WordSize) -> WResult> { + let heap = &mut self.heap; + self.memory.with_direct_access_mut(|mem| { + heap.allocate(mem, size).map_err(|e| format!("{:?}", e)) + }) + } + + fn deallocate_memory(&mut self, ptr: Pointer) -> WResult<()> { + let heap = &mut self.heap; + self.memory.with_direct_access_mut(|mem| { + heap.deallocate(mem, ptr).map_err(|e| format!("{:?}", e)) + }) + } + + fn sandbox(&mut self) -> &mut dyn Sandbox { + self + } } -impl WritePrimitive for MemoryInstance { - fn write_primitive(&self, offset: u32, t: u32) -> Result<()> { - use byteorder::{LittleEndian, ByteOrder}; - let mut r = [0u8; 4]; - LittleEndian::write_u32(&mut r, t); - self.set(offset, &r).map_err(Into::into) +impl Sandbox for FunctionExecutor { + fn memory_get( + &self, + memory_id: MemoryId, + offset: WordSize, + buf_ptr: Pointer, + buf_len: WordSize, + ) -> WResult { + let sandboxed_memory = self.sandbox_store.memory(memory_id).map_err(|e| format!("{:?}", e))?; + + match MemoryInstance::transfer( + &sandboxed_memory, + offset as usize, + &self.memory, + buf_ptr.into(), + buf_len as usize, + ) { + Ok(()) => Ok(sandbox_primitives::ERR_OK), + Err(_) => Ok(sandbox_primitives::ERR_OUT_OF_BOUNDS), + } + } + + fn memory_set( + &mut self, + memory_id: MemoryId, + offset: WordSize, + val_ptr: Pointer, + val_len: WordSize, + ) -> WResult { + let sandboxed_memory = self.sandbox_store.memory(memory_id).map_err(|e| format!("{:?}", e))?; + + match MemoryInstance::transfer( + &self.memory, + val_ptr.into(), + &sandboxed_memory, + offset as usize, + val_len as usize, + ) { + Ok(()) => Ok(sandbox_primitives::ERR_OK), + Err(_) => Ok(sandbox_primitives::ERR_OUT_OF_BOUNDS), + } + } + + fn memory_teardown(&mut self, memory_id: MemoryId) -> WResult<()> { + self.sandbox_store.memory_teardown(memory_id).map_err(|e| format!("{:?}", e)) + } + + fn memory_new( + &mut self, + initial: u32, + maximum: u32, + ) -> WResult { + self.sandbox_store.new_memory(initial, maximum).map_err(|e| format!("{:?}", e)) + } + + fn invoke( + &mut self, + instance_id: u32, + export_name: &str, + args: &[u8], + return_val: Pointer, + return_val_len: WordSize, + state: u32, + ) -> WResult { + trace!(target: "sr-sandbox", "invoke, instance_idx={}", instance_id); + + // Deserialize arguments and convert them into wasmi types. + let args = Vec::::decode(&mut &args[..]) + .map_err(|_| "Can't decode serialized arguments for the invocation")? + .into_iter() + .map(Into::into) + .collect::>(); + + let instance = self.sandbox_store.instance(instance_id).map_err(|e| format!("{:?}", e))?; + let result = instance.invoke(export_name, &args, self, state); + + match result { + Ok(None) => Ok(sandbox_primitives::ERR_OK), + Ok(Some(val)) => { + // Serialize return value and write it back into the memory. + sandbox_primitives::ReturnValue::Value(val.into()).using_encoded(|val| { + if val.len() > return_val_len as usize { + Err("Return value buffer is too small")?; + } + self.write_memory(return_val, val).map_err(|_| "Return value buffer is OOB")?; + Ok(sandbox_primitives::ERR_OK) + }) + } + Err(_) => Ok(sandbox_primitives::ERR_EXECUTION), + } + } + + fn instance_teardown(&mut self, instance_id: u32) -> WResult<()> { + self.sandbox_store.instance_teardown(instance_id).map_err(|e| format!("{:?}", e)) + } + + fn instance_new( + &mut self, + dispatch_thunk_id: u32, + wasm: &[u8], + raw_env_def: &[u8], + state: u32, + ) -> WResult { + // Extract a dispatch thunk from instance's table by the specified index. + let dispatch_thunk = { + let table = self.table.as_ref() + .ok_or_else(|| "Runtime doesn't have a table; sandbox is unavailable")?; + table.get(dispatch_thunk_id) + .map_err(|_| "dispatch_thunk_idx is out of the table bounds")? + .ok_or_else(|| "dispatch_thunk_idx points on an empty table entry")? + .clone() + }; + + let instance_idx_or_err_code = + match sandbox::instantiate(self, dispatch_thunk, wasm, raw_env_def, state) { + Ok(instance_idx) => instance_idx, + Err(sandbox::InstantiationError::StartTrapped) => + sandbox_primitives::ERR_EXECUTION, + Err(_) => sandbox_primitives::ERR_MODULE, + }; + + Ok(instance_idx_or_err_code as u32) } } -trait ReadPrimitive { - fn read_primitive(&self, offset: u32) -> Result; +trait WritePrimitive { + fn write_primitive(&mut self, ptr: Pointer, t: T) -> WResult<()>; } -impl ReadPrimitive for MemoryInstance { - fn read_primitive(&self, offset: u32) -> Result { - use byteorder::{LittleEndian, ByteOrder}; - let result = self.get(offset, 4)?; - Ok(LittleEndian::read_u32(&result)) +impl WritePrimitive for &mut dyn FunctionContext { + fn write_primitive(&mut self, ptr: Pointer, t: u32) -> WResult<()> { + let r = t.to_le_bytes(); + self.write_memory(ptr.cast(), &r) + } +} + +trait ReadPrimitive { + fn read_primitive(&self, offset: Pointer) -> WResult; +} + +impl ReadPrimitive for &mut dyn FunctionContext { + fn read_primitive(&self, ptr: Pointer) -> WResult { + let mut r = [0u8; 4]; + self.read_memory_into(ptr.cast(), &mut r)?; + Ok(u32::from_le_bytes(r)) } } @@ -121,1167 +309,1115 @@ fn deadline_to_timestamp(deadline: u64) -> Option { } } -impl_function_executor!(this: FunctionExecutor<'e, E>, - ext_print_utf8(utf8_data: *const u8, utf8_len: u32) => { - if let Ok(utf8) = this.memory.get(utf8_data, utf8_len as usize) { - if let Ok(message) = String::from_utf8(utf8) { - println!("{}", message); +impl FunctionExecutor { + fn resolver() -> &'static dyn wasmi::ModuleImportResolver { + struct Resolver; + impl wasmi::ModuleImportResolver for Resolver { + fn resolve_func(&self, name: &str, signature: &wasmi::Signature) + -> std::result::Result + { + let signature = wasm_interface::Signature::from(signature); + + if let Some((index, func)) = SubstrateExternals::functions().iter() + .enumerate() + .find(|f| name == f.1.name()) + { + if signature == func.signature() { + Ok(wasmi::FuncInstance::alloc_host(signature.into(), index)) + } else { + Err(wasmi::Error::Instantiation( + format!( + "Invalid signature for function `{}` expected `{:?}`, got `{:?}`", + func.name(), + signature, + func.signature(), + ) + )) + } + } else { + Err(wasmi::Error::Instantiation( + format!("Export {} not found", name), + )) + } } } - Ok(()) - }, - ext_print_hex(data: *const u8, len: u32) => { - if let Ok(hex) = this.memory.get(data, len as usize) { - println!("{}", HexDisplay::from(&hex)); - } - Ok(()) - }, - ext_print_num(number: u64) => { - println!("{}", number); - Ok(()) - }, - ext_malloc(size: usize) -> *mut u8 => { - let r = this.heap.allocate(size)?; - debug_trace!(target: "sr-io", "malloc {} bytes at {}", size, r); - Ok(r) - }, - ext_free(addr: *mut u8) => { - this.heap.deallocate(addr)?; - debug_trace!(target: "sr-io", "free {}", addr); - Ok(()) - }, - ext_set_storage(key_data: *const u8, key_len: u32, value_data: *const u8, value_len: u32) => { - let key = this.memory.get(key_data, key_len as usize) - .map_err(|_| "Invalid attempt to determine key in ext_set_storage")?; - let value = this.memory.get(value_data, value_len as usize) - .map_err(|_| "Invalid attempt to determine value in ext_set_storage")?; - if let Some(_preimage) = this.hash_lookup.get(&key) { - debug_trace!( - target: "wasm-trace", - "*** Setting storage: %{} -> {} [k={}]", - primitives::hexdisplay::ascii_format(&_preimage), - HexDisplay::from(&value), - HexDisplay::from(&key), - ); - } else { - debug_trace!( - target: "wasm-trace", - "*** Setting storage: {} -> {} [k={}]", - primitives::hexdisplay::ascii_format(&key), - HexDisplay::from(&value), - HexDisplay::from(&key), - ); + &Resolver + } +} + +impl wasmi::Externals for FunctionExecutor { + fn invoke_index(&mut self, index: usize, args: wasmi::RuntimeArgs) + -> std::result::Result, wasmi::Trap> + { + let mut args = args.as_ref().iter().copied().map(Into::into); + let function = SubstrateExternals::functions().get(index).ok_or_else(|| + Error::from( + format!("Could not find host function with index: {}", index), + ) + )?; + + function.execute(self, &mut args) + .map_err(Error::FunctionExecution) + .map_err(wasmi::Trap::from) + .map(|v| v.map(Into::into)) + } +} +struct SubstrateExternals; + +impl_wasm_host_interface! { + impl SubstrateExternals where context { + ext_malloc(size: WordSize) -> Pointer { + let r = context.allocate_memory(size)?; + debug_trace!(target: "sr-io", "malloc {} bytes at {:?}", size, r); + Ok(r) } - this.ext.set_storage(key, value); - Ok(()) - }, - ext_set_child_storage( - storage_key_data: *const u8, - storage_key_len: u32, - key_data: *const u8, - key_len: u32, - value_data: *const u8, - value_len: u32 - ) => { - let storage_key = this.memory.get(storage_key_data, storage_key_len as usize) - .map_err(|_| "Invalid attempt to determine storage_key in ext_set_child_storage")?; - let key = this.memory.get(key_data, key_len as usize) - .map_err(|_| "Invalid attempt to determine key in ext_set_child_storage")?; - let value = this.memory.get(value_data, value_len as usize) - .map_err(|_| "Invalid attempt to determine value in ext_set_child_storage")?; - if let Some(_preimage) = this.hash_lookup.get(&key) { - debug_trace!( - target: "wasm-trace", "*** Setting child storage: {} -> %{} -> {} [k={}]", - primitives::hexdisplay::ascii_format(&storage_key), - primitives::hexdisplay::ascii_format(&_preimage), - HexDisplay::from(&value), - HexDisplay::from(&key) - ); - } else { - debug_trace!( - target: "wasm-trace", "*** Setting child storage: {} -> {} -> {} [k={}]", - primitives::hexdisplay::ascii_format(&storage_key), - primitives::hexdisplay::ascii_format(&key), - HexDisplay::from(&value), - HexDisplay::from(&key) - ); + + ext_free(addr: Pointer) { + context.deallocate_memory(addr)?; + debug_trace!(target: "sr-io", "free {:?}", addr); + Ok(()) + } + + ext_sandbox_instantiate( + dispatch_thunk_idx: u32, + wasm_ptr: Pointer, + wasm_len: WordSize, + imports_ptr: Pointer, + imports_len: WordSize, + state: u32, + ) -> u32 { + let wasm = context.read_memory(wasm_ptr, wasm_len) + .map_err(|_| "OOB while ext_sandbox_instantiate: wasm")?; + let raw_env_def = context.read_memory(imports_ptr, imports_len) + .map_err(|_| "OOB while ext_sandbox_instantiate: imports")?; + + context.sandbox().instance_new(dispatch_thunk_idx, &wasm, &raw_env_def, state) + } + + ext_sandbox_instance_teardown(instance_idx: u32) { + context.sandbox().instance_teardown(instance_idx) + } + + ext_sandbox_invoke( + instance_idx: u32, + export_ptr: Pointer, + export_len: WordSize, + args_ptr: Pointer, + args_len: WordSize, + return_val_ptr: Pointer, + return_val_len: WordSize, + state: u32, + ) -> u32 { + let export = context.read_memory(export_ptr, export_len) + .map_err(|_| "OOB while ext_sandbox_invoke: export") + .and_then(|b| + String::from_utf8(b) + .map_err(|_| "Export name should be a valid utf-8 sequence") + )?; + + // Deserialize arguments and convert them into wasmi types. + let serialized_args = context.read_memory(args_ptr, args_len) + .map_err(|_| "OOB while ext_sandbox_invoke: args")?; + + context.sandbox().invoke( + instance_idx, + &export, + &serialized_args, + return_val_ptr, + return_val_len, + state, + ) + } + + ext_sandbox_memory_new(initial: WordSize, maximum: WordSize) -> u32 { + context.sandbox().memory_new(initial, maximum) + } + + ext_sandbox_memory_get( + memory_idx: u32, + offset: WordSize, + buf_ptr: Pointer, + buf_len: WordSize, + ) -> u32 { + context.sandbox().memory_get(memory_idx, offset, buf_ptr, buf_len) + } + + ext_sandbox_memory_set( + memory_idx: u32, + offset: WordSize, + val_ptr: Pointer, + val_len: WordSize, + ) -> u32 { + context.sandbox().memory_set(memory_idx, offset, val_ptr, val_len) + } + + ext_sandbox_memory_teardown(memory_idx: u32) { + context.sandbox().memory_teardown(memory_idx) + } + + ext_print_utf8(utf8_data: Pointer, utf8_len: WordSize) { + if let Ok(utf8) = context.read_memory(utf8_data, utf8_len) { + runtime_io::print_utf8(&utf8); + } + Ok(()) + } + + ext_print_hex(data: Pointer, len: WordSize) { + if let Ok(hex) = context.read_memory(data, len) { + runtime_io::print_hex(&hex); + } + Ok(()) + } + + ext_print_num(number: u64) { + runtime_io::print_num(number); + Ok(()) + } + + ext_set_storage( + key_data: Pointer, + key_len: WordSize, + value_data: Pointer, + value_len: WordSize, + ) { + let key = context.read_memory(key_data, key_len) + .map_err(|_| "Invalid attempt to determine key in ext_set_storage")?; + let value = context.read_memory(value_data, value_len) + .map_err(|_| "Invalid attempt to determine value in ext_set_storage")?; + with_external_storage(move || + Ok(runtime_io::set_storage(&key, &value)) + )?; + Ok(()) } - let storage_key = ChildStorageKey::from_vec(storage_key) - .ok_or_else(|| "ext_set_child_storage: child storage key is invalid")?; - this.ext.set_child_storage(storage_key, key, value); - Ok(()) - }, - ext_clear_child_storage( - storage_key_data: *const u8, - storage_key_len: u32, - key_data: *const u8, - key_len: u32 - ) => { - let storage_key = this.memory.get( - storage_key_data, - storage_key_len as usize - ).map_err(|_| "Invalid attempt to determine storage_key in ext_clear_child_storage")?; - let key = this.memory.get(key_data, key_len as usize) - .map_err(|_| "Invalid attempt to determine key in ext_clear_child_storage")?; - debug_trace!( - target: "wasm-trace", "*** Clearing child storage: {} -> {} [k={}]", - primitives::hexdisplay::ascii_format(&storage_key), - if let Some(_preimage) = this.hash_lookup.get(&key) { - format!("%{}", primitives::hexdisplay::ascii_format(&_preimage)) + + ext_set_child_storage( + storage_key_data: Pointer, + storage_key_len: WordSize, + key_data: Pointer, + key_len: WordSize, + value_data: Pointer, + value_len: WordSize, + ) { + let storage_key = context.read_memory(storage_key_data, storage_key_len) + .map_err(|_| "Invalid attempt to determine storage_key in ext_set_child_storage")?; + let key = context.read_memory(key_data, key_len) + .map_err(|_| "Invalid attempt to determine key in ext_set_child_storage")?; + let value = context.read_memory(value_data, value_len) + .map_err(|_| "Invalid attempt to determine value in ext_set_child_storage")?; + + with_external_storage(move || + Ok(runtime_io::set_child_storage(&storage_key, &key, &value)) + )?; + Ok(()) + } + + ext_clear_child_storage( + storage_key_data: Pointer, + storage_key_len: WordSize, + key_data: Pointer, + key_len: WordSize, + ) { + let storage_key = context.read_memory(storage_key_data, storage_key_len) + .map_err(|_| "Invalid attempt to determine storage_key in ext_clear_child_storage")?; + let key = context.read_memory(key_data, key_len) + .map_err(|_| "Invalid attempt to determine key in ext_clear_child_storage")?; + + with_external_storage(move || + Ok(runtime_io::clear_child_storage(&storage_key, &key)) + )?; + Ok(()) + } + + ext_clear_storage(key_data: Pointer, key_len: WordSize) { + let key = context.read_memory(key_data, key_len) + .map_err(|_| "Invalid attempt to determine key in ext_clear_storage")?; + with_external_storage(move || + Ok(runtime_io::clear_storage(&key)) + )?; + Ok(()) + } + + ext_exists_storage(key_data: Pointer, key_len: WordSize) -> u32 { + let key = context.read_memory(key_data, key_len) + .map_err(|_| "Invalid attempt to determine key in ext_exists_storage")?; + with_external_storage(move || + Ok(if runtime_io::exists_storage(&key) { 1 } else { 0 }) + ) + } + + ext_exists_child_storage( + storage_key_data: Pointer, + storage_key_len: WordSize, + key_data: Pointer, + key_len: WordSize, + ) -> u32 { + let storage_key = context.read_memory(storage_key_data, storage_key_len) + .map_err(|_| "Invalid attempt to determine storage_key in ext_exists_child_storage")?; + let key = context.read_memory(key_data, key_len) + .map_err(|_| "Invalid attempt to determine key in ext_exists_child_storage")?; + + with_external_storage(move || + Ok(if runtime_io::exists_child_storage(&storage_key, &key) { 1 } else { 0 }) + ) + } + + ext_clear_prefix(prefix_data: Pointer, prefix_len: WordSize) { + let prefix = context.read_memory(prefix_data, prefix_len) + .map_err(|_| "Invalid attempt to determine prefix in ext_clear_prefix")?; + with_external_storage(move || + Ok(runtime_io::clear_prefix(&prefix)) + )?; + Ok(()) + } + + ext_clear_child_prefix( + storage_key_data: Pointer, + storage_key_len: WordSize, + prefix_data: Pointer, + prefix_len: WordSize, + ) { + let storage_key = context.read_memory(storage_key_data, storage_key_len) + .map_err(|_| "Invalid attempt to determine storage_key in ext_clear_child_prefix")?; + let prefix = context.read_memory(prefix_data, prefix_len) + .map_err(|_| "Invalid attempt to determine prefix in ext_clear_child_prefix")?; + with_external_storage(move || + Ok(runtime_io::clear_child_prefix(&storage_key, &prefix)) + )?; + + Ok(()) + } + + ext_kill_child_storage(storage_key_data: Pointer, storage_key_len: WordSize) { + let storage_key = context.read_memory(storage_key_data, storage_key_len) + .map_err(|_| "Invalid attempt to determine storage_key in ext_kill_child_storage")?; + with_external_storage(move || + Ok(runtime_io::kill_child_storage(&storage_key)) + )?; + + Ok(()) + } + + ext_get_allocated_storage( + key_data: Pointer, + key_len: WordSize, + written_out: Pointer, + ) -> Pointer { + let key = context.read_memory(key_data, key_len) + .map_err(|_| "Invalid attempt to determine key in ext_get_allocated_storage")?; + let maybe_value = with_external_storage(move || + Ok(runtime_io::storage(&key)) + )?; + + if let Some(value) = maybe_value { + let offset = context.allocate_memory(value.len() as u32)?; + context.write_memory(offset, &value) + .map_err(|_| "Invalid attempt to set memory in ext_get_allocated_storage")?; + context.write_primitive(written_out, value.len() as u32) + .map_err(|_| "Invalid attempt to write written_out in ext_get_allocated_storage")?; + Ok(offset) } else { - format!(" {}", primitives::hexdisplay::ascii_format(&key)) - }, - HexDisplay::from(&key) - ); - let storage_key = ChildStorageKey::from_vec(storage_key) - .ok_or_else(|| "ext_clear_child_storage: child storage key is not valid")?; - - this.ext.clear_child_storage(storage_key, &key); - Ok(()) - }, - ext_clear_storage(key_data: *const u8, key_len: u32) => { - let key = this.memory.get(key_data, key_len as usize) - .map_err(|_| "Invalid attempt to determine key in ext_clear_storage")?; - debug_trace!( - target: "wasm-trace", "*** Clearing storage: {} [k={}]", - if let Some(_preimage) = this.hash_lookup.get(&key) { - format!("%{}", ::primitives::hexdisplay::ascii_format(&_preimage)) + context.write_primitive(written_out, u32::max_value()) + .map_err(|_| "Invalid attempt to write failed written_out in ext_get_allocated_storage")?; + Ok(Pointer::null()) + } + } + + ext_get_allocated_child_storage( + storage_key_data: Pointer, + storage_key_len: WordSize, + key_data: Pointer, + key_len: WordSize, + written_out: Pointer, + ) -> Pointer { + let storage_key = context.read_memory(storage_key_data, storage_key_len) + .map_err(|_| "Invalid attempt to determine storage_key in ext_get_allocated_child_storage")?; + let key = context.read_memory(key_data, key_len) + .map_err(|_| "Invalid attempt to determine key in ext_get_allocated_child_storage")?; + + let maybe_value = with_external_storage(move || + Ok(runtime_io::child_storage(&storage_key, &key)) + )?; + + if let Some(value) = maybe_value { + let offset = context.allocate_memory(value.len() as u32)?; + context.write_memory(offset, &value) + .map_err(|_| "Invalid attempt to set memory in ext_get_allocated_child_storage")?; + context.write_primitive(written_out, value.len() as u32) + .map_err(|_| "Invalid attempt to write written_out in ext_get_allocated_child_storage")?; + Ok(offset) } else { - format!(" {}", ::primitives::hexdisplay::ascii_format(&key)) - }, - HexDisplay::from(&key) - ); - this.ext.clear_storage(&key); - Ok(()) - }, - ext_exists_storage(key_data: *const u8, key_len: u32) -> u32 => { - let key = this.memory.get(key_data, key_len as usize) - .map_err(|_| "Invalid attempt to determine key in ext_exists_storage")?; - Ok(if this.ext.exists_storage(&key) { 1 } else { 0 }) - }, - ext_exists_child_storage( - storage_key_data: *const u8, - storage_key_len: u32, - key_data: *const u8, - key_len: u32 - ) -> u32 => { - let storage_key = this.memory.get( - storage_key_data, - storage_key_len as usize - ).map_err(|_| "Invalid attempt to determine storage_key in ext_exists_child_storage")?; - let key = this.memory.get(key_data, key_len as usize) - .map_err(|_| "Invalid attempt to determine key in ext_exists_child_storage")?; - let storage_key = ChildStorageKey::from_vec(storage_key) - .ok_or_else(|| "ext_exists_child_storage: child storage key is not valid")?; - Ok(if this.ext.exists_child_storage(storage_key, &key) { 1 } else { 0 }) - }, - ext_clear_prefix(prefix_data: *const u8, prefix_len: u32) => { - let prefix = this.memory.get(prefix_data, prefix_len as usize) - .map_err(|_| "Invalid attempt to determine prefix in ext_clear_prefix")?; - this.ext.clear_prefix(&prefix); - Ok(()) - }, - ext_clear_child_prefix( - storage_key_data: *const u8, - storage_key_len: u32, - prefix_data: *const u8, - prefix_len: u32 - ) => { - let storage_key = this.memory.get( - storage_key_data, - storage_key_len as usize - ).map_err(|_| "Invalid attempt to determine storage_key in ext_clear_child_prefix")?; - let storage_key = ChildStorageKey::from_vec(storage_key) - .ok_or_else(|| "ext_clear_child_prefix: child storage key is not valid")?; - let prefix = this.memory.get(prefix_data, prefix_len as usize) - .map_err(|_| "Invalid attempt to determine prefix in ext_clear_child_prefix")?; - this.ext.clear_child_prefix(storage_key, &prefix); - Ok(()) - }, - ext_kill_child_storage(storage_key_data: *const u8, storage_key_len: u32) => { - let storage_key = this.memory.get( - storage_key_data, - storage_key_len as usize - ).map_err(|_| "Invalid attempt to determine storage_key in ext_kill_child_storage")?; - let storage_key = ChildStorageKey::from_vec(storage_key) - .ok_or_else(|| "ext_exists_child_storage: child storage key is not valid")?; - this.ext.kill_child_storage(storage_key); - Ok(()) - }, - // return 0 and place u32::max_value() into written_out if no value exists for the key. - ext_get_allocated_storage(key_data: *const u8, key_len: u32, written_out: *mut u32) -> *mut u8 => { - let key = this.memory.get( - key_data, - key_len as usize - ).map_err(|_| "Invalid attempt to determine key in ext_get_allocated_storage")?; - let maybe_value = this.ext.storage(&key); - - debug_trace!( - target: "wasm-trace", "*** Getting storage: {} == {} [k={}]", - if let Some(_preimage) = this.hash_lookup.get(&key) { - format!("%{}", ::primitives::hexdisplay::ascii_format(&_preimage)) + context.write_primitive(written_out, u32::max_value()) + .map_err(|_| "Invalid attempt to write failed written_out in ext_get_allocated_child_storage")?; + Ok(Pointer::null()) + } + } + + ext_get_storage_into( + key_data: Pointer, + key_len: WordSize, + value_data: Pointer, + value_len: WordSize, + value_offset: WordSize, + ) -> WordSize { + let key = context.read_memory(key_data, key_len) + .map_err(|_| "Invalid attempt to get key in ext_get_storage_into")?; + let maybe_value = with_external_storage(move || + Ok(runtime_io::storage(&key)) + )?; + + if let Some(value) = maybe_value { + let data = &value[value.len().min(value_offset as usize)..]; + let written = std::cmp::min(value_len as usize, data.len()); + context.write_memory(value_data, &data[..written]) + .map_err(|_| "Invalid attempt to set value in ext_get_storage_into")?; + Ok(value.len() as u32) } else { - format!(" {}", ::primitives::hexdisplay::ascii_format(&key)) - }, - if let Some(ref b) = maybe_value { - &format!("{}", HexDisplay::from(b)) + Ok(u32::max_value()) + } + } + + ext_get_child_storage_into( + storage_key_data: Pointer, + storage_key_len: WordSize, + key_data: Pointer, + key_len: WordSize, + value_data: Pointer, + value_len: WordSize, + value_offset: WordSize, + ) -> WordSize { + let storage_key = context.read_memory(storage_key_data, storage_key_len) + .map_err(|_| "Invalid attempt to determine storage_key in ext_get_child_storage_into")?; + let key = context.read_memory(key_data, key_len) + .map_err(|_| "Invalid attempt to get key in ext_get_child_storage_into")?; + + let maybe_value = with_external_storage(move || + Ok(runtime_io::child_storage(&storage_key, &key)) + )?; + + if let Some(value) = maybe_value { + let data = &value[value.len().min(value_offset as usize)..]; + let written = std::cmp::min(value_len as usize, data.len()); + context.write_memory(value_data, &data[..written]) + .map_err(|_| "Invalid attempt to get value in ext_get_child_storage_into")?; + Ok(value.len() as u32) } else { - "" - }, - HexDisplay::from(&key), - ); + Ok(u32::max_value()) + } + } + + ext_storage_root(result: Pointer) { + let r = with_external_storage(move || + Ok(runtime_io::storage_root()) + )?; + context.write_memory(result, r.as_ref()) + .map_err(|_| "Invalid attempt to set memory in ext_storage_root")?; + Ok(()) + } + + ext_child_storage_root( + storage_key_data: Pointer, + storage_key_len: WordSize, + written_out: Pointer, + ) -> Pointer { + let storage_key = context.read_memory(storage_key_data, storage_key_len) + .map_err(|_| "Invalid attempt to determine storage_key in ext_child_storage_root")?; + let value = with_external_storage(move || + Ok(runtime_io::child_storage_root(&storage_key)) + )?; - if let Some(value) = maybe_value { - let offset = this.heap.allocate(value.len() as u32)? as u32; - this.memory.set(offset, &value) - .map_err(|_| "Invalid attempt to set memory in ext_get_allocated_storage")?; - this.memory.write_primitive(written_out, value.len() as u32) - .map_err(|_| "Invalid attempt to write written_out in ext_get_allocated_storage")?; + let offset = context.allocate_memory(value.len() as u32)?; + context.write_memory(offset, &value) + .map_err(|_| "Invalid attempt to set memory in ext_child_storage_root")?; + context.write_primitive(written_out, value.len() as u32) + .map_err(|_| "Invalid attempt to write written_out in ext_child_storage_root")?; Ok(offset) - } else { - this.memory.write_primitive(written_out, u32::max_value()) - .map_err(|_| "Invalid attempt to write failed written_out in ext_get_allocated_storage")?; - Ok(0) } - }, - // return 0 and place u32::max_value() into written_out if no value exists for the key. - ext_get_allocated_child_storage( - storage_key_data: *const u8, - storage_key_len: u32, - key_data: *const u8, - key_len: u32, - written_out: *mut u32 - ) -> *mut u8 => { - let storage_key = this.memory.get( - storage_key_data, - storage_key_len as usize - ).map_err(|_| "Invalid attempt to determine storage_key in ext_get_allocated_child_storage")?; - let key = this.memory.get( - key_data, - key_len as usize - ).map_err(|_| "Invalid attempt to determine key in ext_get_allocated_child_storage")?; - - let maybe_value = { - let storage_key = ChildStorageKey::from_slice(&storage_key) - .ok_or_else(|| "ext_get_allocated_child_storage: child storage key is not valid")?; - this.ext.child_storage(storage_key, &key) - }; - debug_trace!( - target: "wasm-trace", "*** Getting child storage: {} -> {} == {} [k={}]", - primitives::hexdisplay::ascii_format(&storage_key), - if let Some(_preimage) = this.hash_lookup.get(&key) { - format!("%{}", ::primitives::hexdisplay::ascii_format(&_preimage)) + ext_storage_changes_root( + parent_hash_data: Pointer, + _len: WordSize, + result: Pointer, + ) -> u32 { + let mut parent_hash = [0u8; 32]; + context.read_memory_into(parent_hash_data, &mut parent_hash[..]) + .map_err(|_| "Invalid attempt to get parent_hash in ext_storage_changes_root")?; + let r = with_external_storage(move || + Ok(runtime_io::storage_changes_root(parent_hash)) + )?; + + if let Some(r) = r { + context.write_memory(result, &r[..]) + .map_err(|_| "Invalid attempt to set memory in ext_storage_changes_root")?; + Ok(1) } else { - format!(" {}", ::primitives::hexdisplay::ascii_format(&key)) - }, - if let Some(ref b) = maybe_value { - &format!("{}", HexDisplay::from(b)) + Ok(0) + } + } + + ext_blake2_256_enumerated_trie_root( + values_data: Pointer, + lens_data: Pointer, + lens_len: WordSize, + result: Pointer, + ) { + let values = (0..lens_len) + .map(|i| context.read_primitive(lens_data.offset(i).ok_or("Pointer overflow")?)) + .collect::, _>>()? + .into_iter() + .scan(0u32, |acc, v| { let o = *acc; *acc += v; Some((o, v)) }) + .map(|(offset, len)| + context.read_memory(values_data.offset(offset).ok_or("Pointer overflow")?, len) + .map_err(|_| + "Invalid attempt to get memory in ext_blake2_256_enumerated_trie_root" + ) + ) + .collect::, _>>()?; + let r = Layout::::ordered_trie_root(values.into_iter()); + context.write_memory(result, &r[..]) + .map_err(|_| "Invalid attempt to set memory in ext_blake2_256_enumerated_trie_root")?; + Ok(()) + } + + ext_chain_id() -> u64 { + Ok(runtime_io::chain_id()) + } + + ext_twox_64(data: Pointer, len: WordSize, out: Pointer) { + let result: [u8; 8] = if len == 0 { + let hashed = twox_64(&[0u8; 0]); + hashed } else { - "" - }, - HexDisplay::from(&key), - ); + let key = context.read_memory(data, len) + .map_err(|_| "Invalid attempt to get key in ext_twox_64")?; + let hashed_key = twox_64(&key); + hashed_key + }; - if let Some(value) = maybe_value { - let offset = this.heap.allocate(value.len() as u32)? as u32; - this.memory.set(offset, &value) - .map_err(|_| "Invalid attempt to set memory in ext_get_allocated_child_storage")?; - this.memory.write_primitive(written_out, value.len() as u32) - .map_err(|_| "Invalid attempt to write written_out in ext_get_allocated_child_storage")?; - Ok(offset) - } else { - this.memory.write_primitive(written_out, u32::max_value()) - .map_err(|_| "Invalid attempt to write failed written_out in ext_get_allocated_child_storage")?; - Ok(0) + context.write_memory(out, &result) + .map_err(|_| "Invalid attempt to set result in ext_twox_64")?; + Ok(()) } - }, - // return u32::max_value() if no value exists for the key. - ext_get_storage_into( - key_data: *const u8, - key_len: u32, - value_data: *mut u8, - value_len: u32, - value_offset: u32 - ) -> u32 => { - let key = this.memory.get(key_data, key_len as usize) - .map_err(|_| "Invalid attempt to get key in ext_get_storage_into")?; - let maybe_value = this.ext.storage(&key); - debug_trace!( - target: "wasm-trace", "*** Getting storage: {} == {} [k={}]", - if let Some(_preimage) = this.hash_lookup.get(&key) { - format!("%{}", primitives::hexdisplay::ascii_format(&_preimage)) + + ext_twox_128(data: Pointer, len: WordSize, out: Pointer) { + let result: [u8; 16] = if len == 0 { + let hashed = twox_128(&[0u8; 0]); + hashed } else { - format!(" {}", primitives::hexdisplay::ascii_format(&key)) - }, - if let Some(ref b) = maybe_value { - &format!("{}", HexDisplay::from(b)) + let key = context.read_memory(data, len) + .map_err(|_| "Invalid attempt to get key in ext_twox_128")?; + let hashed_key = twox_128(&key); + hashed_key + }; + + context.write_memory(out, &result) + .map_err(|_| "Invalid attempt to set result in ext_twox_128")?; + Ok(()) + } + + ext_twox_256(data: Pointer, len: WordSize, out: Pointer) { + let result: [u8; 32] = if len == 0 { + twox_256(&[0u8; 0]) } else { - "" - }, - HexDisplay::from(&key), - ); + let mem = context.read_memory(data, len) + .map_err(|_| "Invalid attempt to get data in ext_twox_256")?; + twox_256(&mem) + }; + context.write_memory(out, &result) + .map_err(|_| "Invalid attempt to set result in ext_twox_256")?; + Ok(()) + } - if let Some(value) = maybe_value { - let value = &value[value_offset as usize..]; - let written = std::cmp::min(value_len as usize, value.len()); - this.memory.set(value_data, &value[..written]) - .map_err(|_| "Invalid attempt to set value in ext_get_storage_into")?; - Ok(value.len() as u32) - } else { - Ok(u32::max_value()) - } - }, - // return u32::max_value() if no value exists for the key. - ext_get_child_storage_into( - storage_key_data: *const u8, - storage_key_len: u32, - key_data: *const u8, - key_len: u32, - value_data: *mut u8, - value_len: u32, - value_offset: u32 - ) -> u32 => { - let storage_key = this.memory.get( - storage_key_data, - storage_key_len as usize - ).map_err(|_| "Invalid attempt to determine storage_key in ext_get_child_storage_into")?; - let key = this.memory.get( - key_data, - key_len as usize - ).map_err(|_| "Invalid attempt to get key in ext_get_child_storage_into")?; - - let maybe_value = { - let storage_key = ChildStorageKey::from_slice(&*storage_key) - .ok_or_else(|| "ext_get_child_storage_into: child storage key is not valid")?; - this.ext.child_storage(storage_key, &key) - }; - debug_trace!( - target: "wasm-trace", "*** Getting storage: {} -> {} == {} [k={}]", - primitives::hexdisplay::ascii_format(&storage_key), - if let Some(_preimage) = this.hash_lookup.get(&key) { - format!("%{}", ::primitives::hexdisplay::ascii_format(&_preimage)) + ext_blake2_128(data: Pointer, len: WordSize, out: Pointer) { + let result: [u8; 16] = if len == 0 { + let hashed = blake2_128(&[0u8; 0]); + hashed } else { - format!(" {}", ::primitives::hexdisplay::ascii_format(&key)) - }, - if let Some(ref b) = maybe_value { - &format!("{}", HexDisplay::from(b)) + let key = context.read_memory(data, len) + .map_err(|_| "Invalid attempt to get key in ext_blake2_128")?; + let hashed_key = blake2_128(&key); + hashed_key + }; + + context.write_memory(out, &result) + .map_err(|_| "Invalid attempt to set result in ext_blake2_128")?; + Ok(()) + } + + ext_blake2_256(data: Pointer, len: WordSize, out: Pointer) { + let result: [u8; 32] = if len == 0 { + blake2_256(&[0u8; 0]) } else { - "" - }, - HexDisplay::from(&key), - ); + let mem = context.read_memory(data, len) + .map_err(|_| "Invalid attempt to get data in ext_blake2_256")?; + blake2_256(&mem) + }; + context.write_memory(out, &result) + .map_err(|_| "Invalid attempt to set result in ext_blake2_256")?; + Ok(()) + } - if let Some(value) = maybe_value { - let value = &value[value_offset as usize..]; - let written = std::cmp::min(value_len as usize, value.len()); - this.memory.set(value_data, &value[..written]) - .map_err(|_| "Invalid attempt to set value in ext_get_child_storage_into")?; - Ok(value.len() as u32) - } else { - Ok(u32::max_value()) - } - }, - ext_storage_root(result: *mut u8) => { - let r = this.ext.storage_root(); - this.memory.set(result, r.as_ref()) - .map_err(|_| "Invalid attempt to set memory in ext_storage_root")?; - Ok(()) - }, - ext_child_storage_root( - storage_key_data: *const u8, - storage_key_len: u32, - written_out: *mut u32 - ) -> *mut u8 => { - let storage_key = this.memory.get(storage_key_data, storage_key_len as usize) - .map_err(|_| "Invalid attempt to determine storage_key in ext_child_storage_root")?; - let storage_key = ChildStorageKey::from_slice(&*storage_key) - .ok_or_else(|| "ext_child_storage_root: child storage key is not valid")?; - let value = this.ext.child_storage_root(storage_key); - - let offset = this.heap.allocate(value.len() as u32)? as u32; - this.memory.set(offset, &value) - .map_err(|_| "Invalid attempt to set memory in ext_child_storage_root")?; - this.memory.write_primitive(written_out, value.len() as u32) - .map_err(|_| "Invalid attempt to write written_out in ext_child_storage_root")?; - Ok(offset) - }, - ext_storage_changes_root(parent_hash_data: *const u8, parent_hash_len: u32, result: *mut u8) -> u32 => { - let mut parent_hash = H256::default(); - if parent_hash_len != parent_hash.as_ref().len() as u32 { - return Err("Invalid parent_hash_len in ext_storage_changes_root".into()); - } - let raw_parent_hash = this.memory.get(parent_hash_data, parent_hash_len as usize) - .map_err(|_| "Invalid attempt to get parent_hash in ext_storage_changes_root")?; - parent_hash.as_mut().copy_from_slice(&raw_parent_hash[..]); - let r = this.ext.storage_changes_root(parent_hash) - .map_err(|_| "Invaid parent_hash passed to ext_storage_changes_root")?; - if let Some(r) = r { - this.memory.set(result, &r[..]) - .map_err(|_| "Invalid attempt to set memory in ext_storage_changes_root")?; - Ok(1) - } else { - Ok(0) + ext_keccak_256(data: Pointer, len: WordSize, out: Pointer) { + let result: [u8; 32] = if len == 0 { + tiny_keccak::keccak256(&[0u8; 0]) + } else { + let mem = context.read_memory(data, len) + .map_err(|_| "Invalid attempt to get data in ext_keccak_256")?; + tiny_keccak::keccak256(&mem) + }; + context.write_memory(out, &result) + .map_err(|_| "Invalid attempt to set result in ext_keccak_256")?; + Ok(()) } - }, - ext_blake2_256_enumerated_trie_root( - values_data: *const u8, - lens_data: *const u32, - lens_len: u32, - result: *mut u8 - ) => { - let values = (0..lens_len) - .map(|i| this.memory.read_primitive(lens_data + i * 4)) - .collect::>>()? - .into_iter() - .scan(0u32, |acc, v| { let o = *acc; *acc += v; Some((o, v)) }) - .map(|(offset, len)| - this.memory.get(values_data + offset, len as usize) - .map_err(|_| - Error::from( - "Invalid attempt to get memory in ext_blake2_256_enumerated_trie_root" - ) - ) - ) - .collect::>>()?; - let r = Layout::::ordered_trie_root(values.into_iter()); - this.memory.set(result, &r[..]) - .map_err(|_| "Invalid attempt to set memory in ext_blake2_256_enumerated_trie_root")?; - Ok(()) - }, - ext_chain_id() -> u64 => { - Ok(this.ext.chain_id()) - }, - ext_twox_64(data: *const u8, len: u32, out: *mut u8) => { - let result: [u8; 8] = if len == 0 { - let hashed = twox_64(&[0u8; 0]); - debug_trace!(target: "xxhash", "XXhash: '' -> {}", HexDisplay::from(&hashed)); - this.hash_lookup.insert(hashed.to_vec(), vec![]); - hashed - } else { - let key = this.memory.get(data, len as usize) - .map_err(|_| "Invalid attempt to get key in ext_twox_64")?; - let hashed_key = twox_64(&key); - - debug_trace!( - target: "xxhash", "XXhash: {} -> {}", - if let Ok(_skey) = str::from_utf8(&key) { - _skey - } else { - &format!("{}", HexDisplay::from(&key)) + + ext_ed25519_public_keys(id_data: Pointer, result_len: Pointer) -> Pointer { + let mut id = [0u8; 4]; + context.read_memory_into(id_data, &mut id[..]) + .map_err(|_| "Invalid attempt to get id in ext_ed25519_public_keys")?; + let key_type = KeyTypeId(id); + + let keys = runtime_io::ed25519_public_keys(key_type).encode(); + + let len = keys.len() as u32; + let offset = context.allocate_memory(len)?; + + context.write_memory(offset, keys.as_ref()) + .map_err(|_| "Invalid attempt to set memory in ext_ed25519_public_keys")?; + context.write_primitive(result_len, len) + .map_err(|_| "Invalid attempt to write result_len in ext_ed25519_public_keys")?; + + Ok(offset) + } + + ext_ed25519_verify( + msg_data: Pointer, + msg_len: WordSize, + sig_data: Pointer, + pubkey_data: Pointer, + ) -> u32 { + let mut sig = [0u8; 64]; + context.read_memory_into(sig_data, &mut sig[..]) + .map_err(|_| "Invalid attempt to get signature in ext_ed25519_verify")?; + let mut pubkey = [0u8; 32]; + context.read_memory_into(pubkey_data, &mut pubkey[..]) + .map_err(|_| "Invalid attempt to get pubkey in ext_ed25519_verify")?; + let msg = context.read_memory(msg_data, msg_len) + .map_err(|_| "Invalid attempt to get message in ext_ed25519_verify")?; + + Ok(if ed25519::Pair::verify_weak(&sig, &msg, &pubkey) { + 0 + } else { + 1 + }) + } + + ext_ed25519_generate( + id_data: Pointer, + seed: Pointer, + seed_len: WordSize, + out: Pointer, + ) { + let mut id = [0u8; 4]; + context.read_memory_into(id_data, &mut id[..]) + .map_err(|_| "Invalid attempt to get id in ext_ed25519_generate")?; + let key_type = KeyTypeId(id); + + let seed = if seed_len == 0 { + None + } else { + Some( + context.read_memory(seed, seed_len) + .map_err(|_| "Invalid attempt to get seed in ext_ed25519_generate")? + ) + }; + + let seed = seed.as_ref() + .map(|seed| + std::str::from_utf8(&seed) + .map_err(|_| "Seed not a valid utf8 string in ext_sr25119_generate") + ).transpose()?; + + let pubkey = runtime_io::ed25519_generate(key_type, seed); + + context.write_memory(out, pubkey.as_ref()) + .map_err(|_| "Invalid attempt to set out in ext_ed25519_generate".into()) + } + + ext_ed25519_sign( + id_data: Pointer, + pubkey_data: Pointer, + msg_data: Pointer, + msg_len: WordSize, + out: Pointer, + ) -> u32 { + let mut id = [0u8; 4]; + context.read_memory_into(id_data, &mut id[..]) + .map_err(|_| "Invalid attempt to get id in ext_ed25519_sign")?; + let key_type = KeyTypeId(id); + + let mut pubkey = [0u8; 32]; + context.read_memory_into(pubkey_data, &mut pubkey[..]) + .map_err(|_| "Invalid attempt to get pubkey in ext_ed25519_sign")?; + + let msg = context.read_memory(msg_data, msg_len) + .map_err(|_| "Invalid attempt to get message in ext_ed25519_sign")?; + + let pub_key = ed25519::Public::try_from(pubkey.as_ref()) + .map_err(|_| "Invalid `ed25519` public key")?; + + let signature = runtime_io::ed25519_sign(key_type, &pub_key, &msg); + + match signature { + Some(signature) => { + context.write_memory(out, signature.as_ref()) + .map_err(|_| "Invalid attempt to set out in ext_ed25519_sign")?; + Ok(0) }, - HexDisplay::from(&hashed_key), - ); + None => Ok(1), + } + } - this.hash_lookup.insert(hashed_key.to_vec(), key); - hashed_key - }; + ext_sr25519_public_keys(id_data: Pointer, result_len: Pointer) -> Pointer { + let mut id = [0u8; 4]; + context.read_memory_into(id_data, &mut id[..]) + .map_err(|_| "Invalid attempt to get id in ext_sr25519_public_keys")?; + let key_type = KeyTypeId(id); - this.memory.set(out, &result).map_err(|_| "Invalid attempt to set result in ext_twox_64")?; - Ok(()) - }, - ext_twox_128(data: *const u8, len: u32, out: *mut u8) => { - let result: [u8; 16] = if len == 0 { - let hashed = twox_128(&[0u8; 0]); - debug_trace!(target: "xxhash", "XXhash: '' -> {}", HexDisplay::from(&hashed)); - this.hash_lookup.insert(hashed.to_vec(), vec![]); - hashed - } else { - let key = this.memory.get(data, len as usize) - .map_err(|_| "Invalid attempt to get key in ext_twox_128")?; - let hashed_key = twox_128(&key); - debug_trace!( - target: "xxhash", "XXhash: {} -> {}", - &if let Ok(_skey) = str::from_utf8(&key) { - *_skey - } else { - format!("{}", HexDisplay::from(&key)) + let keys = runtime_io::sr25519_public_keys(key_type).encode(); + + let len = keys.len() as u32; + let offset = context.allocate_memory(len)?; + + context.write_memory(offset, keys.as_ref()) + .map_err(|_| "Invalid attempt to set memory in ext_sr25519_public_keys")?; + context.write_primitive(result_len, len) + .map_err(|_| "Invalid attempt to write result_len in ext_sr25519_public_keys")?; + + Ok(offset) + } + + ext_sr25519_verify( + msg_data: Pointer, + msg_len: WordSize, + sig_data: Pointer, + pubkey_data: Pointer, + ) -> u32 { + let mut sig = [0u8; 64]; + context.read_memory_into(sig_data, &mut sig[..]) + .map_err(|_| "Invalid attempt to get signature in ext_sr25519_verify")?; + let mut pubkey = [0u8; 32]; + context.read_memory_into(pubkey_data, &mut pubkey[..]) + .map_err(|_| "Invalid attempt to get pubkey in ext_sr25519_verify")?; + let msg = context.read_memory(msg_data, msg_len) + .map_err(|_| "Invalid attempt to get message in ext_sr25519_verify")?; + + Ok(if sr25519::Pair::verify_weak(&sig, &msg, &pubkey) { + 0 + } else { + 1 + }) + } + + ext_sr25519_generate( + id_data: Pointer, + seed: Pointer, + seed_len: WordSize, + out: Pointer, + ) { + let mut id = [0u8; 4]; + context.read_memory_into(id_data, &mut id[..]) + .map_err(|_| "Invalid attempt to get id in ext_sr25519_generate")?; + let key_type = KeyTypeId(id); + let seed = if seed_len == 0 { + None + } else { + Some( + context.read_memory(seed, seed_len) + .map_err(|_| "Invalid attempt to get seed in ext_sr25519_generate")? + ) + }; + + let seed = seed.as_ref() + .map(|seed| + std::str::from_utf8(&seed) + .map_err(|_| "Seed not a valid utf8 string in ext_sr25119_generate") + ) + .transpose()?; + + let pubkey = runtime_io::sr25519_generate(key_type, seed); + + context.write_memory(out, pubkey.as_ref()) + .map_err(|_| "Invalid attempt to set out in ext_sr25519_generate".into()) + } + + ext_sr25519_sign( + id_data: Pointer, + pubkey_data: Pointer, + msg_data: Pointer, + msg_len: WordSize, + out: Pointer, + ) -> u32 { + let mut id = [0u8; 4]; + context.read_memory_into(id_data, &mut id[..]) + .map_err(|_| "Invalid attempt to get id in ext_sr25519_sign")?; + let key_type = KeyTypeId(id); + + let mut pubkey = [0u8; 32]; + context.read_memory_into(pubkey_data, &mut pubkey[..]) + .map_err(|_| "Invalid attempt to get pubkey in ext_sr25519_sign")?; + + let msg = context.read_memory(msg_data, msg_len) + .map_err(|_| "Invalid attempt to get message in ext_sr25519_sign")?; + + let pub_key = sr25519::Public::try_from(pubkey.as_ref()) + .map_err(|_| "Invalid `sr25519` public key")?; + + let signature = runtime_io::sr25519_sign(key_type, &pub_key, &msg); + + match signature { + Some(signature) => { + context.write_memory(out, signature.as_ref()) + .map_err(|_| "Invalid attempt to set out in ext_sr25519_sign")?; + Ok(0) }, - HexDisplay::from(&hashed_key), - ); - this.hash_lookup.insert(hashed_key.to_vec(), key); - hashed_key - }; + None => Ok(1), + } + } - this.memory.set(out, &result) - .map_err(|_| "Invalid attempt to set result in ext_twox_128")?; - Ok(()) - }, - ext_twox_256(data: *const u8, len: u32, out: *mut u8) => { - let result: [u8; 32] = if len == 0 { - twox_256(&[0u8; 0]) - } else { - let mem = this.memory.get(data, len as usize) - .map_err(|_| "Invalid attempt to get data in ext_twox_256")?; - twox_256(&mem) - }; - this.memory.set(out, &result).map_err(|_| "Invalid attempt to set result in ext_twox_256")?; - Ok(()) - }, - ext_blake2_128(data: *const u8, len: u32, out: *mut u8) => { - let result: [u8; 16] = if len == 0 { - let hashed = blake2_128(&[0u8; 0]); - this.hash_lookup.insert(hashed.to_vec(), vec![]); - hashed - } else { - let key = this.memory.get(data, len as usize) - .map_err(|_| "Invalid attempt to get key in ext_blake2_128")?; - let hashed_key = blake2_128(&key); - this.hash_lookup.insert(hashed_key.to_vec(), key); - hashed_key - }; + ext_secp256k1_ecdsa_recover( + msg_data: Pointer, + sig_data: Pointer, + pubkey_data: Pointer, + ) -> u32 { + let mut sig = [0u8; 65]; + context.read_memory_into(sig_data, &mut sig[..]) + .map_err(|_| "Invalid attempt to get signature in ext_secp256k1_ecdsa_recover")?; + let rs = match secp256k1::Signature::parse_slice(&sig[0..64]) { + Ok(rs) => rs, + _ => return Ok(1), + }; - this.memory.set(out, &result) - .map_err(|_| "Invalid attempt to set result in ext_blake2_128")?; - Ok(()) - }, - ext_blake2_256(data: *const u8, len: u32, out: *mut u8) => { - let result: [u8; 32] = if len == 0 { - blake2_256(&[0u8; 0]) - } else { - let mem = this.memory.get(data, len as usize) - .map_err(|_| "Invalid attempt to get data in ext_blake2_256")?; - blake2_256(&mem) - }; - this.memory.set(out, &result).map_err(|_| "Invalid attempt to set result in ext_blake2_256")?; - Ok(()) - }, - ext_keccak_256(data: *const u8, len: u32, out: *mut u8) => { - let result: [u8; 32] = if len == 0 { - tiny_keccak::keccak256(&[0u8; 0]) - } else { - let mem = this.memory.get(data, len as usize) - .map_err(|_| "Invalid attempt to get data in ext_keccak_256")?; - tiny_keccak::keccak256(&mem) - }; - this.memory.set(out, &result).map_err(|_| "Invalid attempt to set result in ext_keccak_256")?; - Ok(()) - }, - ext_ed25519_public_keys(id_data: *const u8, result_len: *mut u32) -> *mut u8 => { - let mut id = [0u8; 4]; - this.memory.get_into(id_data, &mut id[..]) - .map_err(|_| "Invalid attempt to get id in ext_ed25519_public_keys")?; - let key_type = KeyTypeId(id); - - let keys = runtime_io::ed25519_public_keys(key_type).encode(); - - let len = keys.len() as u32; - let offset = this.heap.allocate(len)? as u32; - - this.memory.set(offset, keys.as_ref()) - .map_err(|_| "Invalid attempt to set memory in ext_ed25519_public_keys")?; - this.memory.write_primitive(result_len, len) - .map_err(|_| "Invalid attempt to write result_len in ext_ed25519_public_keys")?; - - Ok(offset) - }, - ext_ed25519_verify( - msg_data: *const u8, - msg_len: u32, - sig_data: *const u8, - pubkey_data: *const u8, - ) -> u32 => { - let mut sig = [0u8; 64]; - this.memory.get_into(sig_data, &mut sig[..]) - .map_err(|_| "Invalid attempt to get signature in ext_ed25519_verify")?; - let mut pubkey = [0u8; 32]; - this.memory.get_into(pubkey_data, &mut pubkey[..]) - .map_err(|_| "Invalid attempt to get pubkey in ext_ed25519_verify")?; - let msg = this.memory.get(msg_data, msg_len as usize) - .map_err(|_| "Invalid attempt to get message in ext_ed25519_verify")?; - - Ok(if ed25519::Pair::verify_weak(&sig, &msg, &pubkey) { - 0 - } else { - 5 - }) - }, - ext_ed25519_generate(id_data: *const u8, seed: *const u8, seed_len: u32, out: *mut u8) => { - let mut id = [0u8; 4]; - this.memory.get_into(id_data, &mut id[..]) - .map_err(|_| "Invalid attempt to get id in ext_ed25519_generate")?; - let key_type = KeyTypeId(id); - - let seed = if seed_len == 0 { - None - } else { - Some( - this.memory.get(seed, seed_len as usize) - .map_err(|_| "Invalid attempt to get seed in ext_ed25519_generate")? - ) - }; + let recovery_id = if sig[64] > 26 { sig[64] - 27 } else { sig[64] } as u8; + let v = match secp256k1::RecoveryId::parse(recovery_id) { + Ok(v) => v, + _ => return Ok(2), + }; - let seed = seed.as_ref() - .map(|seed| - std::str::from_utf8(&seed) - .map_err(|_| "Seed not a valid utf8 string in ext_sr25119_generate") - ).transpose()?; - - let pubkey = runtime_io::ed25519_generate(key_type, seed); - - this.memory.set(out, pubkey.as_ref()) - .map_err(|_| "Invalid attempt to set out in ext_ed25519_generate".into()) - }, - ext_ed25519_sign( - id_data: *const u8, - pubkey_data: *const u8, - msg_data: *const u8, - msg_len: u32, - out: *mut u8, - ) -> u32 => { - let mut id = [0u8; 4]; - this.memory.get_into(id_data, &mut id[..]) - .map_err(|_| "Invalid attempt to get id in ext_ed25519_sign")?; - let key_type = KeyTypeId(id); - - let mut pubkey = [0u8; 32]; - this.memory.get_into(pubkey_data, &mut pubkey[..]) - .map_err(|_| "Invalid attempt to get pubkey in ext_ed25519_sign")?; - - let msg = this.memory.get(msg_data, msg_len as usize) - .map_err(|_| "Invalid attempt to get message in ext_ed25519_sign")?; - - let signature = runtime_io::ed25519_sign(key_type, &ed25519::Public(pubkey), &msg); - - match signature { - Some(signature) => { - this.memory - .set(out, signature.as_ref()) - .map_err(|_| "Invalid attempt to set out in ext_ed25519_sign")?; - Ok(0) - }, - None => Ok(1), - } - }, - ext_sr25519_public_keys(id_data: *const u8, result_len: *mut u32) -> *mut u8 => { - let mut id = [0u8; 4]; - this.memory.get_into(id_data, &mut id[..]) - .map_err(|_| "Invalid attempt to get id in ext_sr25519_public_keys")?; - let key_type = KeyTypeId(id); - - let keys = runtime_io::sr25519_public_keys(key_type).encode(); - - let len = keys.len() as u32; - let offset = this.heap.allocate(len)? as u32; - - this.memory.set(offset, keys.as_ref()) - .map_err(|_| "Invalid attempt to set memory in ext_sr25519_public_keys")?; - this.memory.write_primitive(result_len, len) - .map_err(|_| "Invalid attempt to write result_len in ext_sr25519_public_keys")?; - - Ok(offset) - }, - ext_sr25519_verify( - msg_data: *const u8, - msg_len: u32, - sig_data: *const u8, - pubkey_data: *const u8, - ) -> u32 => { - let mut sig = [0u8; 64]; - this.memory.get_into(sig_data, &mut sig[..]) - .map_err(|_| "Invalid attempt to get signature in ext_sr25519_verify")?; - let mut pubkey = [0u8; 32]; - this.memory.get_into(pubkey_data, &mut pubkey[..]) - .map_err(|_| "Invalid attempt to get pubkey in ext_sr25519_verify")?; - let msg = this.memory.get(msg_data, msg_len as usize) - .map_err(|_| "Invalid attempt to get message in ext_sr25519_verify")?; - - Ok(if sr25519::Pair::verify_weak(&sig, &msg, &pubkey) { - 0 - } else { - 5 - }) - }, - ext_sr25519_generate(id_data: *const u8, seed: *const u8, seed_len: u32, out: *mut u8) => { - let mut id = [0u8; 4]; - this.memory.get_into(id_data, &mut id[..]) - .map_err(|_| "Invalid attempt to get id in ext_sr25519_generate")?; - let key_type = KeyTypeId(id); - let seed = if seed_len == 0 { - None - } else { - Some( - this.memory.get(seed, seed_len as usize) - .map_err(|_| "Invalid attempt to get seed in ext_sr25519_generate")? - ) - }; + let mut msg = [0u8; 32]; + context.read_memory_into(msg_data, &mut msg[..]) + .map_err(|_| "Invalid attempt to get message in ext_secp256k1_ecdsa_recover")?; - let seed = seed.as_ref() - .map(|seed| - std::str::from_utf8(&seed) - .map_err(|_| "Seed not a valid utf8 string in ext_sr25119_generate") - ) - .transpose()?; - - let pubkey = runtime_io::sr25519_generate(key_type, seed); - - this.memory.set(out, pubkey.as_ref()) - .map_err(|_| "Invalid attempt to set out in ext_sr25519_generate".into()) - }, - ext_sr25519_sign( - id_data: *const u8, - pubkey_data: *const u8, - msg_data: *const u8, - msg_len: u32, - out: *mut u8, - ) -> u32 => { - let mut id = [0u8; 4]; - this.memory.get_into(id_data, &mut id[..]) - .map_err(|_| "Invalid attempt to get id in ext_sr25519_sign")?; - let key_type = KeyTypeId(id); - - let mut pubkey = [0u8; 32]; - this.memory.get_into(pubkey_data, &mut pubkey[..]) - .map_err(|_| "Invalid attempt to get pubkey in ext_sr25519_sign")?; - - let msg = this.memory.get(msg_data, msg_len as usize) - .map_err(|_| "Invalid attempt to get message in ext_sr25519_sign")?; - - let signature = runtime_io::sr25519_sign(key_type, &sr25519::Public(pubkey), &msg); - - match signature { - Some(signature) => { - this.memory.set(out, signature.as_ref()) - .map_err(|_| "Invalid attempt to set out in ext_sr25519_sign")?; - Ok(0) - }, - None => Ok(1), - } - }, - ext_secp256k1_ecdsa_recover(msg_data: *const u8, sig_data: *const u8, pubkey_data: *mut u8) -> u32 => { - let mut sig = [0u8; 65]; - this.memory.get_into(sig_data, &mut sig[..]) - .map_err(|_| "Invalid attempt to get signature in ext_secp256k1_ecdsa_recover")?; - let rs = match secp256k1::Signature::parse_slice(&sig[0..64]) { - Ok(rs) => rs, - _ => return Ok(1), - }; - let v = match secp256k1::RecoveryId::parse(if sig[64] > 26 { sig[64] - 27 } else { sig[64] } as u8) { - Ok(v) => v, - _ => return Ok(2), - }; + let pubkey = match secp256k1::recover(&secp256k1::Message::parse(&msg), &rs, &v) { + Ok(pk) => pk, + _ => return Ok(3), + }; + context.write_memory(pubkey_data, &pubkey.serialize()[1..65]) + .map_err(|_| "Invalid attempt to set pubkey in ext_secp256k1_ecdsa_recover")?; - let mut msg = [0u8; 32]; - this.memory.get_into(msg_data, &mut msg[..]) - .map_err(|_| "Invalid attempt to get message in ext_secp256k1_ecdsa_recover")?; + Ok(0) + } - let pubkey = match secp256k1::recover(&secp256k1::Message::parse(&msg), &rs, &v) { - Ok(pk) => pk, - _ => return Ok(3), - }; + ext_is_validator() -> u32 { + if runtime_io::is_validator() { Ok(1) } else { Ok(0) } + } - this.memory.set(pubkey_data, &pubkey.serialize()[1..65]) - .map_err(|_| "Invalid attempt to set pubkey in ext_secp256k1_ecdsa_recover")?; + ext_submit_transaction(msg_data: Pointer, len: WordSize) -> u32 { + let extrinsic = context.read_memory(msg_data, len) + .map_err(|_| "OOB while ext_submit_transaction: wasm")?; - Ok(0) - }, - ext_is_validator() -> u32 => { - Ok(if runtime_io::is_validator() { - 1 - } else { - 0 - }) - }, - ext_submit_transaction(msg_data: *const u8, len: u32) -> u32 => { - let extrinsic = this.memory.get(msg_data, len as usize) - .map_err(|_| "OOB while ext_submit_transaction: wasm")?; - - let res = this.ext.offchain() - .map(|api| api.submit_transaction(extrinsic)) - .ok_or_else(|| "Calling unavailable API ext_submit_transaction: wasm")?; - - Ok(if res.is_ok() { 0 } else { 1 }) - }, - ext_network_state(written_out: *mut u32) -> *mut u8 => { - let res = this.ext.offchain() - .map(|api| api.network_state()) - .ok_or_else(|| "Calling unavailable API ext_network_state: wasm")?; - - let encoded = res.encode(); - let len = encoded.len() as u32; - let offset = this.heap.allocate(len)? as u32; - this.memory.set(offset, &encoded) - .map_err(|_| "Invalid attempt to set memory in ext_network_state")?; - - this.memory.write_primitive(written_out, len) - .map_err(|_| "Invalid attempt to write written_out in ext_network_state")?; - - Ok(offset) - }, - ext_timestamp() -> u64 => { - let timestamp = this.ext.offchain() - .map(|api| api.timestamp()) - .ok_or_else(|| "Calling unavailable API ext_timestamp: wasm")?; - Ok(timestamp.unix_millis()) - }, - ext_sleep_until(deadline: u64) => { - this.ext.offchain() - .map(|api| api.sleep_until(offchain::Timestamp::from_unix_millis(deadline))) - .ok_or_else(|| "Calling unavailable API ext_sleep_until: wasm")?; - Ok(()) - }, - ext_random_seed(seed_data: *mut u8) => { - // NOTE the runtime as assumptions about seed size. - let seed: [u8; 32] = this.ext.offchain() - .map(|api| api.random_seed()) - .ok_or_else(|| "Calling unavailable API ext_random_seed: wasm")?; - - this.memory.set(seed_data, &seed) - .map_err(|_| "Invalid attempt to set value in ext_random_seed")?; - Ok(()) - }, - ext_local_storage_set(kind: u32, key: *const u8, key_len: u32, value: *const u8, value_len: u32) => { - let kind = offchain::StorageKind::try_from(kind) - .map_err(|_| "storage kind OOB while ext_local_storage_set: wasm")?; - let key = this.memory.get(key, key_len as usize) - .map_err(|_| "OOB while ext_local_storage_set: wasm")?; - let value = this.memory.get(value, value_len as usize) - .map_err(|_| "OOB while ext_local_storage_set: wasm")?; - - this.ext.offchain() - .map(|api| api.local_storage_set(kind, &key, &value)) - .ok_or_else(|| "Calling unavailable API ext_local_storage_set: wasm")?; - - Ok(()) - }, - ext_local_storage_get(kind: u32, key: *const u8, key_len: u32, value_len: *mut u32) -> *mut u8 => { - let kind = offchain::StorageKind::try_from(kind) - .map_err(|_| "storage kind OOB while ext_local_storage_get: wasm")?; - let key = this.memory.get(key, key_len as usize) - .map_err(|_| "OOB while ext_local_storage_get: wasm")?; - - let maybe_value = this.ext.offchain() - .map(|api| api.local_storage_get(kind, &key)) - .ok_or_else(|| "Calling unavailable API ext_local_storage_get: wasm")?; - - let (offset, len) = if let Some(value) = maybe_value { - let offset = this.heap.allocate(value.len() as u32)? as u32; - this.memory.set(offset, &value) - .map_err(|_| "Invalid attempt to set memory in ext_local_storage_get")?; - (offset, value.len() as u32) - } else { - (0, u32::max_value()) - }; + let res = runtime_io::submit_transaction(extrinsic); + + Ok(if res.is_ok() { 0 } else { 1 }) + } + + ext_network_state(written_out: Pointer) -> Pointer { + let res = runtime_io::network_state(); + + let encoded = res.encode(); + let len = encoded.len() as u32; + let offset = context.allocate_memory(len)?; + context.write_memory(offset, &encoded) + .map_err(|_| "Invalid attempt to set memory in ext_network_state")?; + + context.write_primitive(written_out, len) + .map_err(|_| "Invalid attempt to write written_out in ext_network_state")?; + + Ok(offset) + } + + ext_timestamp() -> u64 { + Ok(runtime_io::timestamp().unix_millis()) + } + + ext_sleep_until(deadline: u64) { + runtime_io::sleep_until(offchain::Timestamp::from_unix_millis(deadline)); + Ok(()) + } - this.memory.write_primitive(value_len, len) - .map_err(|_| "Invalid attempt to write value_len in ext_local_storage_get")?; - - Ok(offset) - }, - ext_local_storage_compare_and_set( - kind: u32, - key: *const u8, - key_len: u32, - old_value: *const u8, - old_value_len: u32, - new_value: *const u8, - new_value_len: u32 - ) -> u32 => { - let kind = offchain::StorageKind::try_from(kind) - .map_err(|_| "storage kind OOB while ext_local_storage_compare_and_set: wasm")?; - let key = this.memory.get(key, key_len as usize) - .map_err(|_| "OOB while ext_local_storage_compare_and_set: wasm")?; - let new_value = this.memory.get(new_value, new_value_len as usize) - .map_err(|_| "OOB while ext_local_storage_compare_and_set: wasm")?; - - let res = { - if old_value == u32::max_value() { - this.ext.offchain() - .map(|api| api.local_storage_compare_and_set(kind, &key, None, &new_value)) - .ok_or_else(|| "Calling unavailable API ext_local_storage_compare_and_set: wasm")? + ext_random_seed(seed_data: Pointer) { + // NOTE the runtime as assumptions about seed size. + let seed = runtime_io::random_seed(); + + context.write_memory(seed_data, &seed) + .map_err(|_| "Invalid attempt to set value in ext_random_seed")?; + Ok(()) + } + + ext_local_storage_set( + kind: u32, + key: Pointer, + key_len: WordSize, + value: Pointer, + value_len: WordSize, + ) { + let kind = offchain::StorageKind::try_from(kind) + .map_err(|_| "storage kind OOB while ext_local_storage_set: wasm")?; + let key = context.read_memory(key, key_len) + .map_err(|_| "OOB while ext_local_storage_set: wasm")?; + let value = context.read_memory(value, value_len) + .map_err(|_| "OOB while ext_local_storage_set: wasm")?; + + runtime_io::local_storage_set(kind, &key, &value); + + Ok(()) + } + + ext_local_storage_get( + kind: u32, + key: Pointer, + key_len: WordSize, + value_len: Pointer, + ) -> Pointer { + let kind = offchain::StorageKind::try_from(kind) + .map_err(|_| "storage kind OOB while ext_local_storage_get: wasm")?; + let key = context.read_memory(key, key_len) + .map_err(|_| "OOB while ext_local_storage_get: wasm")?; + + let maybe_value = runtime_io::local_storage_get(kind, &key); + + let (offset, len) = if let Some(value) = maybe_value { + let offset = context.allocate_memory(value.len() as u32)?; + context.write_memory(offset, &value) + .map_err(|_| "Invalid attempt to set memory in ext_local_storage_get")?; + (offset, value.len() as u32) + } else { + (Pointer::null(), u32::max_value()) + }; + + context.write_primitive(value_len, len) + .map_err(|_| "Invalid attempt to write value_len in ext_local_storage_get")?; + + Ok(offset) + } + + ext_local_storage_compare_and_set( + kind: u32, + key: Pointer, + key_len: WordSize, + old_value: Pointer, + old_value_len: WordSize, + new_value: Pointer, + new_value_len: WordSize, + ) -> u32 { + let kind = offchain::StorageKind::try_from(kind) + .map_err(|_| "storage kind OOB while ext_local_storage_compare_and_set: wasm")?; + let key = context.read_memory(key, key_len) + .map_err(|_| "OOB while ext_local_storage_compare_and_set: wasm")?; + let new_value = context.read_memory(new_value, new_value_len) + .map_err(|_| "OOB while ext_local_storage_compare_and_set: wasm")?; + + let old_value = if old_value_len == u32::max_value() { + None } else { - let v = this.memory.get(old_value, old_value_len as usize) - .map_err(|_| "OOB while ext_local_storage_compare_and_set: wasm")?; - this.ext.offchain() - .map(|api| api.local_storage_compare_and_set(kind, &key, Some(v.as_slice()), &new_value)) - .ok_or_else(|| "Calling unavailable API ext_local_storage_compare_and_set: wasm")? + Some( + context.read_memory(old_value, old_value_len) + .map_err(|_| "OOB while ext_local_storage_compare_and_set: wasm")? + ) + }; + + let res = runtime_io::local_storage_compare_and_set( + kind, + &key, + old_value.as_ref().map(|v| v.as_ref()), + &new_value, + ); + + Ok(if res { 0 } else { 1 }) + } + + ext_http_request_start( + method: Pointer, + method_len: WordSize, + url: Pointer, + url_len: WordSize, + meta: Pointer, + meta_len: WordSize, + ) -> u32 { + let method = context.read_memory(method, method_len) + .map_err(|_| "OOB while ext_http_request_start: wasm")?; + let url = context.read_memory(url, url_len) + .map_err(|_| "OOB while ext_http_request_start: wasm")?; + let meta = context.read_memory(meta, meta_len) + .map_err(|_| "OOB while ext_http_request_start: wasm")?; + + let method_str = str::from_utf8(&method) + .map_err(|_| "invalid str while ext_http_request_start: wasm")?; + let url_str = str::from_utf8(&url) + .map_err(|_| "invalid str while ext_http_request_start: wasm")?; + + let id = runtime_io::http_request_start(method_str, url_str, &meta); + + if let Ok(id) = id { + Ok(id.into()) + } else { + Ok(u32::max_value()) } - }; + } - Ok(if res { 0 } else { 1 }) - }, - ext_http_request_start( - method: *const u8, - method_len: u32, - url: *const u8, - url_len: u32, - meta: *const u8, - meta_len: u32 - ) -> u32 => { - let method = this.memory.get(method, method_len as usize) - .map_err(|_| "OOB while ext_http_request_start: wasm")?; - let url = this.memory.get(url, url_len as usize) - .map_err(|_| "OOB while ext_http_request_start: wasm")?; - let meta = this.memory.get(meta, meta_len as usize) - .map_err(|_| "OOB while ext_http_request_start: wasm")?; - - let method_str = str::from_utf8(&method) - .map_err(|_| "invalid str while ext_http_request_start: wasm")?; - let url_str = str::from_utf8(&url) - .map_err(|_| "invalid str while ext_http_request_start: wasm")?; - - let id = this.ext.offchain() - .map(|api| api.http_request_start(method_str, url_str, &*meta)) - .ok_or_else(|| "Calling unavailable API ext_http_request_start: wasm")?; - - if let Ok(id) = id { - Ok(id.into()) - } else { - Ok(u32::max_value()) - } - }, - ext_http_request_add_header( - request_id: u32, - name: *const u8, - name_len: u32, - value: *const u8, - value_len: u32 - ) -> u32 => { - let name = this.memory.get(name, name_len as usize) - .map_err(|_| "OOB while ext_http_request_add_header: wasm")?; - let value = this.memory.get(value, value_len as usize) - .map_err(|_| "OOB while ext_http_request_add_header: wasm")?; - - let name_str = str::from_utf8(&name) - .map_err(|_| "Invalid str while ext_http_request_add_header: wasm")?; - let value_str = str::from_utf8(&value) - .map_err(|_| "Invalid str while ext_http_request_add_header: wasm")?; - - let res = this.ext.offchain() - .map(|api| api.http_request_add_header( - offchain::HttpRequestId(request_id as u16), - &name_str, - &value_str, - )) - .ok_or_else(|| "Calling unavailable API ext_http_request_add_header: wasm")?; - - Ok(if res.is_ok() { 0 } else { 1 }) - }, - ext_http_request_write_body( - request_id: u32, - chunk: *const u8, - chunk_len: u32, - deadline: u64 - ) -> u32 => { - let chunk = this.memory.get(chunk, chunk_len as usize) - .map_err(|_| "OOB while ext_http_request_write_body: wasm")?; - - let res = this.ext.offchain() - .map(|api| api.http_request_write_body( + ext_http_request_add_header( + request_id: u32, + name: Pointer, + name_len: WordSize, + value: Pointer, + value_len: WordSize, + ) -> u32 { + let name = context.read_memory(name, name_len) + .map_err(|_| "OOB while ext_http_request_add_header: wasm")?; + let value = context.read_memory(value, value_len) + .map_err(|_| "OOB while ext_http_request_add_header: wasm")?; + + let name_str = str::from_utf8(&name) + .map_err(|_| "Invalid str while ext_http_request_add_header: wasm")?; + let value_str = str::from_utf8(&value) + .map_err(|_| "Invalid str while ext_http_request_add_header: wasm")?; + + let res = runtime_io::http_request_add_header( offchain::HttpRequestId(request_id as u16), - &chunk, - deadline_to_timestamp(deadline) - )) - .ok_or_else(|| "Calling unavailable API ext_http_request_write_body: wasm")?; + name_str, + value_str, + ); - Ok(match res { - Ok(()) => 0, - Err(e) => e.into(), - }) - }, - ext_http_response_wait( - ids: *const u32, - ids_len: u32, - statuses: *mut u32, - deadline: u64 - ) => { - let ids = (0..ids_len) - .map(|i| - this.memory.read_primitive(ids + i * 4) - .map(|id: u32| offchain::HttpRequestId(id as u16)) - .map_err(|_| "OOB while ext_http_response_wait: wasm") - ) - .collect::<::std::result::Result, _>>()?; + Ok(if res.is_ok() { 0 } else { 1 }) + } - let res = this.ext.offchain() - .map(|api| api.http_response_wait(&ids, deadline_to_timestamp(deadline))) - .ok_or_else(|| "Calling unavailable API ext_http_response_wait: wasm")? - .into_iter() - .map(|status| status.into()) - .enumerate() - // make sure to take up to `ids_len` to avoid exceeding the mem. - .take(ids_len as usize); - - for (i, status) in res { - this.memory.write_primitive(statuses + i as u32 * 4, status) - .map_err(|_| "Invalid attempt to set memory in ext_http_response_wait")?; - } - - Ok(()) - }, - ext_http_response_headers( - request_id: u32, - written_out: *mut u32 - ) -> *mut u8 => { - use codec::Encode; - - let headers = this.ext.offchain() - .map(|api| api.http_response_headers(offchain::HttpRequestId(request_id as u16))) - .ok_or_else(|| "Calling unavailable API ext_http_response_headers: wasm")?; - - let encoded = headers.encode(); - let len = encoded.len() as u32; - let offset = this.heap.allocate(len)? as u32; - this.memory.set(offset, &encoded) - .map_err(|_| "Invalid attempt to set memory in ext_http_response_headers")?; - this.memory.write_primitive(written_out, len) - .map_err(|_| "Invalid attempt to write written_out in ext_http_response_headers")?; - - Ok(offset) - }, - ext_http_response_read_body( - request_id: u32, - buffer: *mut u8, - buffer_len: u32, - deadline: u64 - ) -> u32 => { - let mut internal_buffer = Vec::with_capacity(buffer_len as usize); - internal_buffer.resize(buffer_len as usize, 0); - - let res = this.ext.offchain() - .map(|api| api.http_response_read_body( + ext_http_request_write_body( + request_id: u32, + chunk: Pointer, + chunk_len: WordSize, + deadline: u64, + ) -> u32 { + let chunk = context.read_memory(chunk, chunk_len) + .map_err(|_| "OOB while ext_http_request_write_body: wasm")?; + + let res = runtime_io::http_request_write_body( offchain::HttpRequestId(request_id as u16), - &mut internal_buffer, + &chunk, deadline_to_timestamp(deadline), - )) - .ok_or_else(|| "Calling unavailable API ext_http_response_read_body: wasm")?; + ); - Ok(match res { - Ok(read) => { - this.memory.set(buffer, &internal_buffer[..read]) - .map_err(|_| "Invalid attempt to set memory in ext_http_response_read_body")?; + Ok(match res { + Ok(()) => 0, + Err(e) => e.into(), + }) + } - read as u32 - }, - Err(err) => { - u32::max_value() - u32::from(err) + 1 + ext_http_response_wait( + ids: Pointer, + ids_len: WordSize, + statuses: Pointer, + deadline: u64, + ) { + let ids = (0..ids_len) + .map(|i| + context.read_primitive(ids.offset(i).ok_or("Point overflow")?) + .map(|id: u32| offchain::HttpRequestId(id as u16)) + .map_err(|_| "OOB while ext_http_response_wait: wasm") + ) + .collect::, _>>()?; + + let res = runtime_io::http_response_wait(&ids, deadline_to_timestamp(deadline)) + .into_iter() + .map(|status| u32::from(status)) + .enumerate() + // make sure to take up to `ids_len` to avoid exceeding the mem. + .take(ids_len as usize); + + for (i, status) in res { + context.write_primitive(statuses.offset(i as u32).ok_or("Point overflow")?, status) + .map_err(|_| "Invalid attempt to set memory in ext_http_response_wait")?; } - }) - }, - ext_sandbox_instantiate( - dispatch_thunk_idx: usize, - wasm_ptr: *const u8, - wasm_len: usize, - imports_ptr: *const u8, - imports_len: usize, - state: usize - ) -> u32 => { - let wasm = this.memory.get(wasm_ptr, wasm_len as usize) - .map_err(|_| "OOB while ext_sandbox_instantiate: wasm")?; - let raw_env_def = this.memory.get(imports_ptr, imports_len as usize) - .map_err(|_| "OOB while ext_sandbox_instantiate: imports")?; - // Extract a dispatch thunk from instance's table by the specified index. - let dispatch_thunk = { - let table = this.table.as_ref() - .ok_or_else(|| "Runtime doesn't have a table; sandbox is unavailable")?; - table.get(dispatch_thunk_idx) - .map_err(|_| "dispatch_thunk_idx is out of the table bounds")? - .ok_or_else(|| "dispatch_thunk_idx points on an empty table entry")? - .clone() - }; + Ok(()) + } - let instance_idx_or_err_code = - match sandbox::instantiate(this, dispatch_thunk, &wasm, &raw_env_def, state) { - Ok(instance_idx) => instance_idx, - Err(sandbox::InstantiationError::StartTrapped) => sandbox_primitives::ERR_EXECUTION, - Err(_) => sandbox_primitives::ERR_MODULE, - }; + ext_http_response_headers( + request_id: u32, + written_out: Pointer, + ) -> Pointer { + use codec::Encode; - Ok(instance_idx_or_err_code as u32) - }, - ext_sandbox_instance_teardown(instance_idx: u32) => { - this.sandbox_store.instance_teardown(instance_idx)?; - Ok(()) - }, - ext_sandbox_invoke( - instance_idx: u32, - export_ptr: *const u8, - export_len: usize, - args_ptr: *const u8, - args_len: usize, - return_val_ptr: *const u8, - return_val_len: usize, - state: usize - ) -> u32 => { - use codec::{Decode, Encode}; - - trace!(target: "sr-sandbox", "invoke, instance_idx={}", instance_idx); - let export = this.memory.get(export_ptr, export_len as usize) - .map_err(|_| "OOB while ext_sandbox_invoke: export") - .and_then(|b| - String::from_utf8(b) - .map_err(|_| "Export name should be a valid utf-8 sequence") - )?; + let headers = runtime_io::http_response_headers(offchain::HttpRequestId(request_id as u16)); - // Deserialize arguments and convert them into wasmi types. - let serialized_args = this.memory.get(args_ptr, args_len as usize) - .map_err(|_| "OOB while ext_sandbox_invoke: args")?; - let args = Vec::::decode(&mut &serialized_args[..]) - .map_err(|_| "Can't decode serialized arguments for the invocation")? - .into_iter() - .map(Into::into) - .collect::>(); + let encoded = headers.encode(); + let len = encoded.len() as u32; + let offset = context.allocate_memory(len)?; - let instance = this.sandbox_store.instance(instance_idx)?; - let result = instance.invoke(&export, &args, this, state); + context.write_memory(offset, &encoded) + .map_err(|_| "Invalid attempt to set memory in ext_http_response_headers")?; + context.write_primitive(written_out, len) + .map_err(|_| "Invalid attempt to write written_out in ext_http_response_headers")?; - match result { - Ok(None) => Ok(sandbox_primitives::ERR_OK), - Ok(Some(val)) => { - // Serialize return value and write it back into the memory. - sandbox_primitives::ReturnValue::Value(val.into()).using_encoded(|val| { - if val.len() > return_val_len as usize { - Err("Return value buffer is too small")?; - } - this.memory - .set(return_val_ptr, val) - .map_err(|_| "Return value buffer is OOB")?; - Ok(sandbox_primitives::ERR_OK) - }) - } - Err(_) => Ok(sandbox_primitives::ERR_EXECUTION), + Ok(offset) } - }, - ext_sandbox_memory_new(initial: u32, maximum: u32) -> u32 => { - let mem_idx = this.sandbox_store.new_memory(initial, maximum)?; - Ok(mem_idx) - }, - ext_sandbox_memory_get(memory_idx: u32, offset: u32, buf_ptr: *mut u8, buf_len: u32) -> u32 => { - let sandboxed_memory = this.sandbox_store.memory(memory_idx)?; - match MemoryInstance::transfer( - &sandboxed_memory, - offset as usize, - &this.memory, - buf_ptr as usize, - buf_len as usize, - ) { - Ok(()) => Ok(sandbox_primitives::ERR_OK), - Err(_) => Ok(sandbox_primitives::ERR_OUT_OF_BOUNDS), - } - }, - ext_sandbox_memory_set(memory_idx: u32, offset: u32, val_ptr: *const u8, val_len: u32) -> u32 => { - let sandboxed_memory = this.sandbox_store.memory(memory_idx)?; + ext_http_response_read_body( + request_id: u32, + buffer: Pointer, + buffer_len: WordSize, + deadline: u64, + ) -> WordSize { + let mut internal_buffer = Vec::with_capacity(buffer_len as usize); + internal_buffer.resize(buffer_len as usize, 0); - match MemoryInstance::transfer( - &this.memory, - val_ptr as usize, - &sandboxed_memory, - offset as usize, - val_len as usize, - ) { - Ok(()) => Ok(sandbox_primitives::ERR_OK), - Err(_) => Ok(sandbox_primitives::ERR_OUT_OF_BOUNDS), + let res = runtime_io::http_response_read_body( + offchain::HttpRequestId(request_id as u16), + &mut internal_buffer, + deadline_to_timestamp(deadline), + ); + + Ok(match res { + Ok(read) => { + context.write_memory(buffer, &internal_buffer[..read]) + .map_err(|_| "Invalid attempt to set memory in ext_http_response_read_body")?; + + read as u32 + }, + Err(err) => { + u32::max_value() - u32::from(err) + 1 + } + }) } - }, - ext_sandbox_memory_teardown(memory_idx: u32) => { - this.sandbox_store.memory_teardown(memory_idx)?; - Ok(()) - }, - => <'e, E: Externalities + 'e> -); + } +} + +/// Execute closure that access external storage. +/// +/// All panics that happen within closure are captured and transformed into +/// runtime error. This requires special panic handler mode to be enabled +/// during the call (see `panic_handler::AbortGuard::never_abort`). +/// If this mode isn't enabled, then all panics within externalities are +/// leading to process abort. +fn with_external_storage(f: F) -> std::result::Result + where + F: panic::UnwindSafe + FnOnce() -> Result +{ + // it is safe beause basic methods of StorageExternalities are guaranteed to touch only + // its internal state + we should discard it on error + panic::catch_unwind(move || f()) + .map_err(|_| Error::Runtime) + .and_then(|result| result) + .map_err(|err| format!("{}", err)) +} /// Wasm rust executor for contracts. /// @@ -1290,7 +1426,6 @@ impl_function_executor!(this: FunctionExecutor<'e, E>, pub struct WasmExecutor; impl WasmExecutor { - /// Create a new instance. pub fn new() -> Self { WasmExecutor @@ -1309,8 +1444,9 @@ impl WasmExecutor { method: &str, data: &[u8], ) -> Result> { - let module = ::wasmi::Module::from_buffer(code)?; - let module = Self::instantiate_module::(heap_pages, &module)?; + let module = wasmi::Module::from_buffer(code)?; + let module = Self::instantiate_module(heap_pages, &module)?; + self.call_in_wasm_module(ext, &module, method, data) } @@ -1332,7 +1468,8 @@ impl WasmExecutor { filter_result: FR, ) -> Result { let module = wasmi::Module::from_buffer(code)?; - let module = Self::instantiate_module::(heap_pages, &module)?; + let module = Self::instantiate_module(heap_pages, &module)?; + self.call_in_wasm_module_with_custom_signature( ext, &module, @@ -1361,10 +1498,10 @@ impl WasmExecutor { .ok_or_else(|| Error::HeapBaseNotFoundOrInvalid)? .get(); - Ok(match heap_base_val { - wasmi::RuntimeValue::I32(v) => v as u32, - _ => return Err(Error::HeapBaseNotFoundOrInvalid), - }) + match heap_base_val { + wasmi::RuntimeValue::I32(v) => Ok(v as u32), + _ => Err(Error::HeapBaseNotFoundOrInvalid), + } } /// Call a given method in the given wasm-module runtime. @@ -1417,34 +1554,40 @@ impl WasmExecutor { .and_then(|e| e.as_table().cloned()); let heap_base = Self::get_heap_base(module_instance)?; - let mut fec = FunctionExecutor::new(memory.clone(), heap_base, table, ext)?; + let mut fec = FunctionExecutor::new( + memory.clone(), + heap_base, + table, + )?; + let parameters = create_parameters(&mut |data: &[u8]| { - let offset = fec.heap.allocate(data.len() as u32)?; - memory.set(offset, &data)?; - Ok(offset) + let offset = fec.allocate_memory(data.len() as u32)?; + fec.write_memory(offset, data).map(|_| offset.into()).map_err(Into::into) })?; - let result = module_instance.invoke_export( - method, - ¶meters, - &mut fec + let result = runtime_io::with_externalities( + ext, + || module_instance.invoke_export(method, ¶meters, &mut fec), ); - let result = match result { + + match result { Ok(val) => match filter_result(val, &memory)? { Some(val) => Ok(val), None => Err(Error::InvalidReturn), }, Err(e) => { - trace!(target: "wasm-executor", "Failed to execute code with {} pages", memory.current_size().0); + trace!( + target: "wasm-executor", + "Failed to execute code with {} pages", + memory.current_size().0 + ); Err(e.into()) }, - }; - - result + } } /// Prepare module instance - pub fn instantiate_module>( + pub fn instantiate_module( heap_pages: usize, module: &Module, ) -> Result { @@ -1452,7 +1595,7 @@ impl WasmExecutor { let intermediate_instance = ModuleInstance::new( module, &ImportsBuilder::new() - .with_resolver("env", FunctionExecutor::::resolver()) + .with_resolver("env", FunctionExecutor::resolver()) )?; // Verify that the module has the heap base global variable. @@ -1585,11 +1728,11 @@ mod tests { let test_code = WASM_BINARY; assert_eq!( WasmExecutor::new().call(&mut ext, 8, &test_code[..], "test_twox_256", &[]).unwrap(), - hex!("99e9d85137db46ef4bbea33613baafd56f963c64b1f3685a4eb4abd67ff6203a") + hex!("99e9d85137db46ef4bbea33613baafd56f963c64b1f3685a4eb4abd67ff6203a"), ); assert_eq!( WasmExecutor::new().call(&mut ext, 8, &test_code[..], "test_twox_256", b"Hello world!").unwrap(), - hex!("b27dfd7f223f177f2a13647b533599af0c07f68bda23d96d059da2b451a35a74") + hex!("b27dfd7f223f177f2a13647b533599af0c07f68bda23d96d059da2b451a35a74"), ); } @@ -1698,7 +1841,7 @@ mod tests { body: vec![1, 2, 3, 4], headers: vec![("X-Auth".to_owned(), "test".to_owned())], sent: true, - response: vec![1, 2, 3], + response: Some(vec![1, 2, 3]), response_headers: vec![("X-Auth".to_owned(), "hello".to_owned())], ..Default::default() }, diff --git a/core/executor/src/wasm_runtimes_cache.rs b/core/executor/src/wasm_runtimes_cache.rs index 110a28fe7d305e8fe1ee5785caa50a85c09f4ccb..a615660777c78ef49dbdd7decb72c92b3931f085 100644 --- a/core/executor/src/wasm_runtimes_cache.rs +++ b/core/executor/src/wasm_runtimes_cache.rs @@ -21,13 +21,9 @@ use crate::wasm_executor::WasmExecutor; use log::{trace, warn}; use codec::Decode; use parity_wasm::elements::{deserialize_buffer, DataSegment, Instruction, Module as RawModule}; -use primitives::storage::well_known_keys; -use primitives::Blake2Hasher; +use primitives::{storage::well_known_keys, Blake2Hasher, traits::Externalities}; use runtime_version::RuntimeVersion; -use state_machine::Externalities; -use std::collections::hash_map::{Entry, HashMap}; -use std::mem; -use std::rc::Rc; +use std::{collections::hash_map::{Entry, HashMap}, mem, rc::Rc}; use wasmi::{Module as WasmModule, ModuleRef as WasmModuleInstanceRef, RuntimeValue}; #[derive(Debug)] @@ -86,7 +82,7 @@ struct StateSnapshot { data_segments: Vec<(u32, Vec)>, /// The list of all global mutable variables of the module in their sequential order. global_mut_values: Vec, - heap_pages: u32, + heap_pages: u64, } impl StateSnapshot { @@ -94,7 +90,7 @@ impl StateSnapshot { fn take( module_instance: &WasmModuleInstanceRef, data_segments: Vec, - heap_pages: u32, + heap_pages: u64, ) -> Option { let prepared_segments = data_segments .into_iter() @@ -103,7 +99,12 @@ impl StateSnapshot { // anyway. let contents = mem::replace(segment.value_mut(), vec![]); - let init_expr = segment.offset().code(); + let init_expr = match segment.offset() { + Some(offset) => offset.code(), + // Return if the segment is passive + None => return None + }; + // [op, End] if init_expr.len() != 2 { return None; @@ -250,6 +251,12 @@ impl RuntimesCache { .original_storage_hash(well_known_keys::CODE) .ok_or(Error::InvalidCode("`CODE` not found in storage.".into()))?; + let heap_pages = ext + .storage(well_known_keys::HEAP_PAGES) + .and_then(|pages| u64::decode(&mut &pages[..]).ok()) + .or(default_heap_pages) + .unwrap_or(DEFAULT_HEAP_PAGES); + // This is direct result from fighting with borrowck. let handle_result = |cached_result: &Result, CacheError>| match *cached_result { @@ -258,10 +265,29 @@ impl RuntimesCache { }; match self.instances.entry(code_hash.into()) { - Entry::Occupied(o) => handle_result(o.get()), + Entry::Occupied(mut o) => { + let result = o.get_mut(); + if let Ok(ref cached_runtime) = result { + if cached_runtime.state_snapshot.heap_pages != heap_pages { + trace!( + target: "runtimes_cache", + "heap_pages were changed. Reinstantiating the instance" + ); + *result = Self::create_wasm_instance(wasm_executor, ext, heap_pages); + if let Err(ref err) = result { + warn!(target: "runtimes_cache", "cannot create a runtime: {:?}", err); + } + } + } + handle_result(result) + }, Entry::Vacant(v) => { trace!(target: "runtimes_cache", "no instance found in cache, creating now."); - let result = Self::create_wasm_instance(wasm_executor, ext, default_heap_pages); + let result = Self::create_wasm_instance( + wasm_executor, + ext, + heap_pages, + ); if let Err(ref err) = result { warn!(target: "runtimes_cache", "cannot create a runtime: {:?}", err); } @@ -273,7 +299,7 @@ impl RuntimesCache { fn create_wasm_instance>( wasm_executor: &WasmExecutor, ext: &mut E, - default_heap_pages: Option, + heap_pages: u64, ) -> Result, CacheError> { let code = ext .original_storage(well_known_keys::CODE) @@ -284,20 +310,14 @@ impl RuntimesCache { // // A return of this error actually indicates that there is a problem in logic, since // we just loaded and validated the `module` above. - let data_segments = extract_data_segments(&code).ok_or(CacheError::CantDeserializeWasm)?; - - let heap_pages = ext - .storage(well_known_keys::HEAP_PAGES) - .and_then(|pages| u64::decode(&mut &pages[..]).ok()) - .or(default_heap_pages) - .unwrap_or(DEFAULT_HEAP_PAGES); + let data_segments = extract_data_segments(&code)?; // Instantiate this module. - let instance = WasmExecutor::instantiate_module::(heap_pages as usize, &module) + let instance = WasmExecutor::instantiate_module(heap_pages as usize, &module) .map_err(CacheError::Instantiation)?; // Take state snapshot before executing anything. - let state_snapshot = StateSnapshot::take(&instance, data_segments, heap_pages as u32) + let state_snapshot = StateSnapshot::take(&instance, data_segments, heap_pages) .expect( "`take` returns `Err` if the module is not valid; we already loaded module above, thus the `Module` is proven to be valid at this point; @@ -320,12 +340,14 @@ impl RuntimesCache { /// Extract the data segments from the given wasm code. /// /// Returns `Err` if the given wasm code cannot be deserialized. -fn extract_data_segments(wasm_code: &[u8]) -> Option> { - let raw_module: RawModule = deserialize_buffer(wasm_code).ok()?; +fn extract_data_segments(wasm_code: &[u8]) -> Result, CacheError> { + let raw_module: RawModule = deserialize_buffer(wasm_code) + .map_err(|_| CacheError::CantDeserializeWasm)?; + let segments = raw_module .data_section() .map(|ds| ds.entries()) .unwrap_or(&[]) .to_vec(); - Some(segments) + Ok(segments) } diff --git a/core/executor/src/wasm_utils.rs b/core/executor/src/wasm_utils.rs index 80ef376df5212dcb8a329169d85d8e8bb376859e..b217350ac6fc4c4e4a894305214b13a529e13b3d 100644 --- a/core/executor/src/wasm_utils.rs +++ b/core/executor/src/wasm_utils.rs @@ -14,131 +14,96 @@ // You should have received a copy of the GNU General Public License // along with Substrate. If not, see . -//! Rust implementation of Substrate contracts. - -use wasmi::{ValueType, RuntimeValue}; -use wasmi::nan_preserving_float::{F32, F64}; - -pub trait ConvertibleToWasm { - const VALUE_TYPE: ValueType; - type NativeType; fn to_runtime_value(self) -> RuntimeValue; -} - -impl ConvertibleToWasm for i32 { - type NativeType = i32; - const VALUE_TYPE: ValueType = ValueType::I32; - fn to_runtime_value(self) -> RuntimeValue { RuntimeValue::I32(self) } -} - -impl ConvertibleToWasm for u32 { - type NativeType = u32; - const VALUE_TYPE: ValueType = ValueType::I32; - fn to_runtime_value(self) -> RuntimeValue { RuntimeValue::I32(self as i32) } -} - -impl ConvertibleToWasm for i64 { - type NativeType = i64; - const VALUE_TYPE: ValueType = ValueType::I64; - fn to_runtime_value(self) -> RuntimeValue { RuntimeValue::I64(self) } -} - -impl ConvertibleToWasm for u64 { - type NativeType = u64; - const VALUE_TYPE: ValueType = ValueType::I64; - fn to_runtime_value(self) -> RuntimeValue { RuntimeValue::I64(self as i64) } -} - -impl ConvertibleToWasm for F32 { - type NativeType = F32; - const VALUE_TYPE: ValueType = ValueType::F32; - fn to_runtime_value(self) -> RuntimeValue { RuntimeValue::F32(self) } -} - -impl ConvertibleToWasm for F64 { - type NativeType = F64; - const VALUE_TYPE: ValueType = ValueType::F64; - fn to_runtime_value(self) -> RuntimeValue { RuntimeValue::F64(self) } -} - -impl ConvertibleToWasm for isize { - type NativeType = i32; - const VALUE_TYPE: ValueType = ValueType::I32; - fn to_runtime_value(self) -> RuntimeValue { RuntimeValue::I32(self as i32) } -} - -impl ConvertibleToWasm for usize { - type NativeType = u32; - const VALUE_TYPE: ValueType = ValueType::I32; - fn to_runtime_value(self) -> RuntimeValue { RuntimeValue::I32(self as u32 as i32) } -} - -impl ConvertibleToWasm for *const T { - type NativeType = u32; - const VALUE_TYPE: ValueType = ValueType::I32; - fn to_runtime_value(self) -> RuntimeValue { RuntimeValue::I32(self as isize as i32) } -} - -impl ConvertibleToWasm for *mut T { - type NativeType = u32; - const VALUE_TYPE: ValueType = ValueType::I32; - fn to_runtime_value(self) -> RuntimeValue { RuntimeValue::I32(self as isize as i32) } -} +//! Utilities for defining the wasm host environment. /// Converts arguments into respective WASM types. #[macro_export] macro_rules! convert_args { () => ([]); - ( $( $t:ty ),* ) => ( [ $( { use $crate::wasm_utils::ConvertibleToWasm; <$t>::VALUE_TYPE }, )* ] ); + ( $( $t:ty ),* ) => ( [ $( <$t as $crate::wasm_interface::IntoValue>::VALUE_TYPE, )* ] ); } /// Generates a WASM signature for given list of parameters. #[macro_export] macro_rules! gen_signature { ( ( $( $params: ty ),* ) ) => ( - { - $crate::wasmi::Signature::new(&convert_args!($($params),*)[..], None) + $crate::wasm_interface::Signature { + args: std::borrow::Cow::Borrowed(&convert_args!( $( $params ),* )[..]), + return_value: None, } ); - - ( ( $( $params: ty ),* ) -> $returns: ty ) => ( - { - $crate::wasmi::Signature::new(&convert_args!($($params),*)[..], Some({ - use $crate::wasm_utils::ConvertibleToWasm; <$returns>::VALUE_TYPE - })) + ( ( $( $params: ty ),* ) -> $returns:ty ) => ( + $crate::wasm_interface::Signature { + args: std::borrow::Cow::Borrowed(&convert_args!( $( $params ),* )[..]), + return_value: Some(<$returns as $crate::wasm_interface::IntoValue>::VALUE_TYPE), } ); } -macro_rules! resolve_fn { - (@iter $index:expr, $sig_var:ident, $name_var:ident) => (); - (@iter $index:expr, $sig_var:ident, $name_var:ident $name:ident ( $( $params:ty ),* ) $( -> $returns:ty )* => $($tail:tt)* ) => ( - if $name_var == stringify!($name) { - let signature = gen_signature!( ( $( $params ),* ) $( -> $returns )* ); - if $sig_var != &signature { - return Err($crate::wasmi::Error::Instantiation( - format!("Export {} has different signature {:?}", $name_var, $sig_var), - )); +macro_rules! gen_functions { + (@INTERNAL + { $( $generated:tt )* } + $context:ident, + ) => ( + &[ $( $generated )* ] + ); + (@INTERNAL + { $( $generated:tt )* } + $context:ident, + $name:ident ( $( $names:ident: $params:ty ),* ) $( -> $returns:ty )? { $( $body:tt )* } + $( $tail:tt )* + ) => ( + gen_functions! { + @INTERNAL + { + $( $generated )* + { + struct $name; + + #[allow(unused)] + impl $crate::wasm_interface::Function for $name { + fn name(&self) -> &str { + stringify!($name) + } + fn signature(&self) -> $crate::wasm_interface::Signature { + gen_signature!( ( $( $params ),* ) $( -> $returns )? ) + } + fn execute( + &self, + context: &mut dyn $crate::wasm_interface::FunctionContext, + args: &mut dyn Iterator, + ) -> ::std::result::Result, String> { + let mut $context = context; + marshall! { + args, + ( $( $names : $params ),* ) $( -> $returns )? => { $( $body )* } + } + } + } + + &$name as &dyn $crate::wasm_interface::Function + }, } - return Ok($crate::wasmi::FuncInstance::alloc_host(signature, $index)); + $context, + $( $tail )* } - resolve_fn!(@iter $index + 1, $sig_var, $name_var $($tail)*) ); - ($sig_var:ident, $name_var:ident, $($tail:tt)* ) => ( - resolve_fn!(@iter 0, $sig_var, $name_var $($tail)*); + ( $context:ident, $( $tail:tt )* ) => ( + gen_functions!(@INTERNAL {} $context, $($tail)*); ); } /// Converts the list of arguments coming from WASM into their native types. #[macro_export] macro_rules! unmarshall_args { - ( $body:tt, $objectname:ident, $args_iter:ident, $( $names:ident : $params:ty ),*) => ({ + ( $body:tt, $args_iter:ident, $( $names:ident : $params:ty ),*) => ({ $( - let $names : <$params as $crate::wasm_utils::ConvertibleToWasm>::NativeType = + let $names : $params = $args_iter.next() - .and_then(|rt_val| rt_val.try_into()) + .and_then(|val| <$params as $crate::wasm_interface::TryFromValue>::try_from_value(val)) .expect( - "`$args_iter` comes from an argument of Externals::invoke_index; + "`$args_iter` comes from an argument of Externals::execute_function; args to an external call always matches the signature of the external; external signatures are built with count and types and in order defined by `$params`; here, we iterating on `$params`; @@ -160,7 +125,7 @@ macro_rules! unmarshall_args { #[inline(always)] pub fn constrain_closure(f: F) -> F where - F: FnOnce() -> Result + F: FnOnce() -> Result { f } @@ -168,103 +133,40 @@ where /// Pass the list of parameters by converting them to respective WASM types. #[macro_export] macro_rules! marshall { - ( $args_iter:ident, $objectname:ident, ( $( $names:ident : $params:ty ),* ) -> $returns:ty => $body:tt ) => ({ - let body = $crate::wasm_utils::constrain_closure::< - <$returns as $crate::wasm_utils::ConvertibleToWasm>::NativeType, _ - >(|| { - unmarshall_args!($body, $objectname, $args_iter, $( $names : $params ),*) + ( $args_iter:ident, ( $( $names:ident : $params:ty ),* ) -> $returns:ty => $body:tt ) => ({ + let body = $crate::wasm_utils::constrain_closure::<$returns, _>(|| { + unmarshall_args!($body, $args_iter, $( $names : $params ),*) }); - let r = body().map_err(wasmi::Trap::from)?; - return Ok(Some({ use $crate::wasm_utils::ConvertibleToWasm; r.to_runtime_value() })) + let r = body()?; + return Ok(Some($crate::wasm_interface::IntoValue::into_value(r))) }); - ( $args_iter:ident, $objectname:ident, ( $( $names:ident : $params:ty ),* ) => $body:tt ) => ({ + ( $args_iter:ident, ( $( $names:ident : $params:ty ),* ) => $body:tt ) => ({ let body = $crate::wasm_utils::constrain_closure::<(), _>(|| { - unmarshall_args!($body, $objectname, $args_iter, $( $names : $params ),*) + unmarshall_args!($body, $args_iter, $( $names : $params ),*) }); - body().map_err(wasmi::Trap::from)?; + body()?; return Ok(None) }) } -macro_rules! dispatch_fn { - ( @iter $index:expr, $index_ident:ident, $objectname:ident, $args_iter:ident) => { - // `$index` comes from an argument of Externals::invoke_index; - // externals are always invoked with index given by resolve_fn! at resolve time; - // For each next function resolve_fn! gives new index, starting from 0; - // Both dispatch_fn! and resolve_fn! are called with the same list of functions; - // qed; - panic!("fn with index {} is undefined", $index); - }; - - (@iter - $index:expr, - $index_ident:ident, - $objectname:ident, - $args_iter:ident, - $name:ident ( $( $names:ident : $params:ty ),* ) $( -> $returns:ty )* => $body:tt $($tail:tt)* - ) => ( - if $index_ident == $index { - { marshall!($args_iter, $objectname, ( $( $names : $params ),* ) $( -> $returns )* => $body) } - } - dispatch_fn!( @iter $index + 1, $index_ident, $objectname, $args_iter $($tail)*) - ); - - ( $index_ident:ident, $objectname:ident, $args_iter:ident, $($tail:tt)* ) => ( - dispatch_fn!( @iter 0, $index_ident, $objectname, $args_iter, $($tail)*); - ); -} - -/// Implements `wasmi::Externals` trait and `Resolver` for given struct. +/// Implements the wasm host interface for the given type. #[macro_export] -macro_rules! impl_function_executor { +macro_rules! impl_wasm_host_interface { ( - $objectname:ident : $structname:ty, - $( - $name:ident - ( $( $names:ident : $params:ty ),* $(,)? ) - $( -> $returns:ty )? => { $( $body:tt )* }, - )* - => $( $pre:tt )+ - ) => ( - impl $( $pre ) + $structname { - #[allow(unused)] - fn resolver() -> &'static dyn $crate::wasmi::ModuleImportResolver { - struct Resolver; - impl $crate::wasmi::ModuleImportResolver for Resolver { - fn resolve_func( - &self, - name: &str, - signature: &$crate::wasmi::Signature - ) -> std::result::Result<$crate::wasmi::FuncRef, $crate::wasmi::Error> { - resolve_fn!( - signature, - name, - $( $name( $( $params ),* ) $( -> $returns )? => )* - ); - - Err($crate::wasmi::Error::Instantiation( - format!("Export {} not found", name), - )) - } - } - &Resolver - } + impl $interface_name:ident where $context:ident { + $( + $name:ident($( $names:ident : $params:ty ),* $(,)? ) $( -> $returns:ty )? + { $( $body:tt )* } + )* } - - impl $( $pre ) + $crate::wasmi::Externals for $structname { - fn invoke_index( - &mut self, - index: usize, - args: $crate::wasmi::RuntimeArgs, - ) -> std::result::Result, $crate::wasmi::Trap> { - let $objectname = self; - let mut args = args.as_ref().iter(); - dispatch_fn! { - index, - $objectname, - args, - $( $name( $( $names : $params ),* ) $( -> $returns )? => { $( $body )* } ),* - }; + ) => ( + impl $crate::wasm_interface::HostFunctions for $interface_name { + #[allow(non_camel_case_types)] + fn functions() -> &'static [&'static dyn $crate::wasm_interface::Function] { + gen_functions!( + $context, + $( $name( $( $names: $params ),* ) $( -> $returns )? { $( $body )* } )* + ) } } ); diff --git a/core/finality-grandpa/Cargo.toml b/core/finality-grandpa/Cargo.toml index 22237c5a0b5a0f886fe2853604270627b272cf79..0a42ff4531fbe00dbb037d8aadca4f4806a392af 100644 --- a/core/finality-grandpa/Cargo.toml +++ b/core/finality-grandpa/Cargo.toml @@ -6,24 +6,24 @@ edition = "2018" [dependencies] fork-tree = { path = "../../core/utils/fork-tree" } -futures = "0.1" -futures03 = { package = "futures-preview", version = "=0.3.0-alpha.17", features = ["compat"] } -log = "0.4" +futures = "0.1.29" +futures03 = { package = "futures-preview", version = "0.3.0-alpha.19", features = ["compat"] } +log = "0.4.8" parking_lot = "0.9.0" -tokio-executor = "0.1.7" +tokio-executor = "0.1.8" tokio-timer = "0.2.11" -rand = "0.6" +rand = "0.7.2" codec = { package = "parity-scale-codec", version = "1.0.0", features = ["derive"] } sr-primitives = { path = "../sr-primitives" } consensus_common = { package = "substrate-consensus-common", path = "../consensus/common" } primitives = { package = "substrate-primitives", path = "../primitives" } substrate-telemetry = { path = "../telemetry" } keystore = { package = "substrate-keystore", path = "../keystore" } -serde_json = "1.0" +serde_json = "1.0.40" client = { package = "substrate-client", path = "../client" } +header-metadata = { package = "substrate-header-metadata", path = "../client/header-metadata" } inherents = { package = "substrate-inherents", path = "../../core/inherents" } network = { package = "substrate-network", path = "../network" } -service = { package = "substrate-service", path = "../service", optional = true } srml-finality-tracker = { path = "../../srml/finality-tracker" } fg_primitives = { package = "substrate-finality-grandpa-primitives", path = "primitives" } grandpa = { package = "finality-grandpa", version = "0.9.0", features = ["derive-codec"] } @@ -34,10 +34,6 @@ network = { package = "substrate-network", path = "../network", features = ["tes keyring = { package = "substrate-keyring", path = "../keyring" } test-client = { package = "substrate-test-runtime-client", path = "../test-runtime/client"} babe_primitives = { package = "substrate-consensus-babe-primitives", path = "../consensus/babe/primitives" } -env_logger = "0.6" -tokio = "0.1.17" -tempfile = "3.1" - -[features] -default = ["service-integration"] -service-integration = ["service"] +env_logger = "0.6.2" +tokio = "0.1.22" +tempfile = "3.1.0" diff --git a/core/finality-grandpa/primitives/Cargo.toml b/core/finality-grandpa/primitives/Cargo.toml index ecbaf2e1ecc70b8bce006fc710137ae915c00e8f..02439d4150d81016d6bd37a6253f17bc73ba7f4d 100644 --- a/core/finality-grandpa/primitives/Cargo.toml +++ b/core/finality-grandpa/primitives/Cargo.toml @@ -10,7 +10,7 @@ app-crypto = { package = "substrate-application-crypto", path = "../../applicati codec = { package = "parity-scale-codec", version = "1.0.0", default-features = false, features = ["derive"] } sr-primitives = { path = "../../sr-primitives", default-features = false } rstd = { package = "sr-std", path = "../../sr-std", default-features = false } -serde = { version = "1.0", optional = true, features = ["derive"] } +serde = { version = "1.0.101", optional = true, features = ["derive"] } [features] default = ["std"] diff --git a/core/finality-grandpa/primitives/src/lib.rs b/core/finality-grandpa/primitives/src/lib.rs index b92444e26295ce20415e7db64eaf638bdbd7fc2d..384319a2982bcab0e31bd49ba852a2471dbe076a 100644 --- a/core/finality-grandpa/primitives/src/lib.rs +++ b/core/finality-grandpa/primitives/src/lib.rs @@ -24,7 +24,7 @@ extern crate alloc; #[cfg(feature = "std")] use serde::Serialize; use codec::{Encode, Decode, Codec}; -use sr_primitives::{ConsensusEngineId, traits::{DigestFor, NumberFor}}; +use sr_primitives::ConsensusEngineId; use client::decl_runtime_apis; use rstd::vec::Vec; @@ -52,6 +52,12 @@ pub type AuthorityWeight = u64; /// The index of an authority. pub type AuthorityIndex = u64; +/// The identifier of a GRANDPA set. +pub type SetId = u64; + +/// The round indicator. +pub type RoundNumber = u64; + /// A scheduled change of authority set. #[cfg_attr(feature = "std", derive(Debug, Serialize))] #[derive(Clone, Eq, PartialEq, Encode, Decode)] @@ -68,8 +74,9 @@ pub struct ScheduledChange { pub enum ConsensusLog { /// Schedule an authority set change. /// - /// Precedence towards earlier or later digest items can be given - /// based on the rules of the chain. + /// The earliest digest of this type in a single block will be respected, + /// provided that there is no `ForcedChange` digest. If there is, then the + /// `ForcedChange` will take precedence. /// /// No change should be scheduled if one is already and the delay has not /// passed completely. @@ -84,8 +91,8 @@ pub enum ConsensusLog { /// Forced changes are applied after a delay of _imported_ blocks, /// while pending changes are applied after a delay of _finalized_ blocks. /// - /// Precedence towards earlier or later digest items can be given - /// based on the rules of the chain. + /// The earliest digest of this type in a single block will be respected, + /// with others ignored. /// /// No change should be scheduled if one is already and the delay has not /// passed completely. @@ -159,43 +166,6 @@ decl_runtime_apis! { /// The consensus protocol will coordinate the handoff externally. #[api_version(2)] pub trait GrandpaApi { - /// Check a digest for pending changes. - /// Return `None` if there are no pending changes. - /// - /// Precedence towards earlier or later digest items can be given - /// based on the rules of the chain. - /// - /// No change should be scheduled if one is already and the delay has not - /// passed completely. - /// - /// This should be a pure function: i.e. as long as the runtime can interpret - /// the digest type it should return the same result regardless of the current - /// state. - fn grandpa_pending_change(digest: &DigestFor) - -> Option>>; - - /// Check a digest for forced changes. - /// Return `None` if there are no forced changes. Otherwise, return a - /// tuple containing the pending change and the median last finalized - /// block number at the time the change was signaled. - /// - /// Added in version 2. - /// - /// Forced changes are applied after a delay of _imported_ blocks, - /// while pending changes are applied after a delay of _finalized_ blocks. - /// - /// Precedence towards earlier or later digest items can be given - /// based on the rules of the chain. - /// - /// No change should be scheduled if one is already and the delay has not - /// passed completely. - /// - /// This should be a pure function: i.e. as long as the runtime can interpret - /// the digest type it should return the same result regardless of the current - /// state. - fn grandpa_forced_change(digest: &DigestFor) - -> Option<(NumberFor, ScheduledChange>)>; - /// Get the current GRANDPA authorities and weights. This should not change except /// for when changes are scheduled and the corresponding delay has passed. /// diff --git a/core/finality-grandpa/src/aux_schema.rs b/core/finality-grandpa/src/aux_schema.rs index 78c1741d519037fdd6adcde19a1f4be883f3118d..a2b05a0cd60e1f4b237b45549b1efd1cf56ccc95 100644 --- a/core/finality-grandpa/src/aux_schema.rs +++ b/core/finality-grandpa/src/aux_schema.rs @@ -25,8 +25,7 @@ use fork_tree::ForkTree; use grandpa::round::State as RoundState; use sr_primitives::traits::{Block as BlockT, NumberFor}; use log::{info, warn}; -use substrate_telemetry::{telemetry, CONSENSUS_INFO}; -use fg_primitives::AuthorityId; +use fg_primitives::{AuthorityId, AuthorityWeight, SetId, RoundNumber}; use crate::authorities::{AuthoritySet, SharedAuthoritySet, PendingChange, DelayKind}; use crate::consensus_changes::{SharedConsensusChanges, ConsensusChanges}; @@ -47,16 +46,16 @@ const CURRENT_VERSION: u32 = 2; #[cfg_attr(test, derive(PartialEq))] pub enum V1VoterSetState { /// The voter set state, currently paused. - Paused(u64, RoundState), + Paused(RoundNumber, RoundState), /// The voter set state, currently live. - Live(u64, RoundState), + Live(RoundNumber, RoundState), } -type V0VoterSetState = (u64, RoundState); +type V0VoterSetState = (RoundNumber, RoundState); #[derive(Debug, Clone, Encode, Decode, PartialEq)] struct V0PendingChange { - next_authorities: Vec<(AuthorityId, u64)>, + next_authorities: Vec<(AuthorityId, AuthorityWeight)>, delay: N, canon_height: N, canon_hash: H, @@ -64,8 +63,8 @@ struct V0PendingChange { #[derive(Debug, Clone, Encode, Decode, PartialEq)] struct V0AuthoritySet { - current_authorities: Vec<(AuthorityId, u64)>, - set_id: u64, + current_authorities: Vec<(AuthorityId, AuthorityWeight)>, + set_id: SetId, pending_changes: Vec>, } @@ -267,7 +266,7 @@ pub(crate) fn load_persistent( -> ClientResult> where B: AuxStore, - G: FnOnce() -> ClientResult>, + G: FnOnce() -> ClientResult>, { let version: Option = load_decode(backend, VERSION_KEY)?; let consensus_changes = load_decode(backend, CONSENSUS_CHANGES_KEY)? @@ -376,17 +375,6 @@ pub(crate) fn update_authority_set( let encoded_set = set.encode(); if let Some(new_set) = new_set { - telemetry!(CONSENSUS_INFO; "afg.authority_set"; - "hash" => ?new_set.canon_hash, - "number" => ?new_set.canon_number, - "authority_set_id" => ?new_set.set_id, - "authorities" => { - let authorities: Vec = - new_set.authorities.iter().map(|(id, _)| format!("{}", id)).collect(); - format!("{:?}", authorities) - } - ); - // we also overwrite the "last completed round" entry with a blank slate // because from the perspective of the finality gadget, the chain has // reset. @@ -448,7 +436,7 @@ mod test { let authorities = vec![(AuthorityId::default(), 100)]; let set_id = 3; - let round_number: u64 = 42; + let round_number: RoundNumber = 42; let round_state = RoundState:: { prevote_ghost: Some((H256::random(), 32)), finalized: None, @@ -536,7 +524,7 @@ mod test { let authorities = vec![(AuthorityId::default(), 100)]; let set_id = 3; - let round_number: u64 = 42; + let round_number: RoundNumber = 42; let round_state = RoundState:: { prevote_ghost: Some((H256::random(), 32)), finalized: None, diff --git a/core/finality-grandpa/src/communication/gossip.rs b/core/finality-grandpa/src/communication/gossip.rs index 20a629b6ae378142db98edc4f38a71d17775974c..831be7ad145310cb8fa419a4cb18ff675bb1c0aa 100644 --- a/core/finality-grandpa/src/communication/gossip.rs +++ b/core/finality-grandpa/src/communication/gossip.rs @@ -386,12 +386,14 @@ impl Misbehavior { struct PeerInfo { view: View, + roles: Roles, } impl PeerInfo { - fn new() -> Self { + fn new(roles: Roles) -> Self { PeerInfo { view: View::default(), + roles, } } } @@ -408,8 +410,8 @@ impl Default for Peers { } impl Peers { - fn new_peer(&mut self, who: PeerId) { - self.inner.insert(who, PeerInfo::new()); + fn new_peer(&mut self, who: PeerId, roles: Roles) { + self.inner.insert(who, PeerInfo::new(roles)); } fn peer_disconnected(&mut self, who: &PeerId) { @@ -503,12 +505,13 @@ struct Inner { config: crate::Config, next_rebroadcast: Instant, pending_catch_up: PendingCatchUp, + catch_up_enabled: bool, } type MaybeMessage = Option<(Vec, NeighborPacket>)>; impl Inner { - fn new(config: crate::Config) -> Self { + fn new(config: crate::Config, catch_up_enabled: bool) -> Self { Inner { local_view: None, peers: Peers::default(), @@ -516,6 +519,7 @@ impl Inner { next_rebroadcast: Instant::now() + REBROADCAST_AFTER, authorities: Vec::new(), pending_catch_up: PendingCatchUp::None, + catch_up_enabled, config, } } @@ -729,7 +733,9 @@ impl Inner { // race where the peer sent us the request before it observed that // we had transitioned to a new set. In this case we charge a lower // cost. - if local_view.round.0.saturating_sub(CATCH_UP_THRESHOLD) == 0 { + if request.set_id.0.saturating_add(1) == local_view.set_id.0 && + local_view.round.0.saturating_sub(CATCH_UP_THRESHOLD) == 0 + { return (None, Action::Discard(cost::HONEST_OUT_OF_SCOPE_CATCH_UP)); } @@ -802,14 +808,21 @@ impl Inner { } fn try_catch_up(&mut self, who: &PeerId) -> (Option>, Option) { + if !self.catch_up_enabled { + return (None, None); + } + let mut catch_up = None; let mut report = None; // if the peer is on the same set and ahead of us by a margin bigger // than `CATCH_UP_THRESHOLD` then we should ask it for a catch up - // message. + // message. we only send catch-up requests to authorities, observers + // won't be able to reply since they don't follow the full GRANDPA + // protocol and therefore might not have the vote data available. if let (Some(peer), Some(local_view)) = (self.peers.peer(who), &self.local_view) { - if peer.view.set_id == local_view.set_id && + if peer.roles.is_authority() && + peer.view.set_id == local_view.set_id && peer.view.round.0.saturating_sub(CATCH_UP_THRESHOLD) > local_view.round.0 { // send catch up request if allowed @@ -915,13 +928,17 @@ pub(super) struct GossipValidator { } impl GossipValidator { - /// Create a new gossip-validator. This initialized the current set to 0. - pub(super) fn new(config: crate::Config, set_state: environment::SharedVoterSetState) - -> (GossipValidator, ReportStream) - { + /// Create a new gossip-validator. The current set is initialized to 0. If + /// `catch_up_enabled` is set to false then the validator will not issue any + /// catch up requests (useful e.g. when running just the GRANDPA observer). + pub(super) fn new( + config: crate::Config, + set_state: environment::SharedVoterSetState, + catch_up_enabled: bool, + ) -> (GossipValidator, ReportStream) { let (tx, rx) = mpsc::unbounded(); let val = GossipValidator { - inner: parking_lot::RwLock::new(Inner::new(config)), + inner: parking_lot::RwLock::new(Inner::new(config, catch_up_enabled)), set_state, report_sender: tx, }; @@ -1021,10 +1038,10 @@ impl GossipValidator { } impl network_gossip::Validator for GossipValidator { - fn new_peer(&self, context: &mut dyn ValidatorContext, who: &PeerId, _roles: Roles) { + fn new_peer(&self, context: &mut dyn ValidatorContext, who: &PeerId, roles: Roles) { let packet = { let mut inner = self.inner.write(); - inner.peers.new_peer(who.clone()); + inner.peers.new_peer(who.clone(), roles); inner.local_view.as_ref().map(|v| { NeighborPacket { @@ -1312,7 +1329,7 @@ mod tests { assert!(res.unwrap().is_none()); // connect & disconnect. - peers.new_peer(id.clone()); + peers.new_peer(id.clone(), Roles::AUTHORITY); peers.peer_disconnected(&id); let res = peers.update_peer_state(&id, update.clone()); @@ -1348,7 +1365,7 @@ mod tests { let mut peers = Peers::default(); let id = PeerId::random(); - peers.new_peer(id.clone()); + peers.new_peer(id.clone(), Roles::AUTHORITY); let mut check_update = move |update: NeighborPacket<_>| { let view = peers.update_peer_state(&id, update.clone()).unwrap().unwrap(); @@ -1368,7 +1385,7 @@ mod tests { let mut peers = Peers::default(); let id = PeerId::random(); - peers.new_peer(id.clone()); + peers.new_peer(id.clone(), Roles::AUTHORITY); peers.update_peer_state(&id, NeighborPacket { round: Round(10), @@ -1406,6 +1423,7 @@ mod tests { let (val, _) = GossipValidator::::new( config(), voter_set_state(), + true, ); let set_id = 1; @@ -1441,6 +1459,7 @@ mod tests { let (val, _) = GossipValidator::::new( config(), voter_set_state(), + true, ); let set_id = 1; let auth = AuthorityId::from_slice(&[1u8; 32]); @@ -1485,6 +1504,7 @@ mod tests { let (val, _) = GossipValidator::::new( config(), voter_set_state(), + true, ); let set_id = 1; @@ -1553,6 +1573,7 @@ mod tests { let (val, _) = GossipValidator::::new( config(), set_state.clone(), + true, ); let set_id = 1; @@ -1565,7 +1586,7 @@ mod tests { // add the peer making the request to the validator, // otherwise it is discarded let mut inner = val.inner.write(); - inner.peers.new_peer(peer.clone()); + inner.peers.new_peer(peer.clone(), Roles::AUTHORITY); let res = inner.handle_catch_up_request( &peer, @@ -1600,4 +1621,232 @@ mod tests { _ => panic!("expected catch up message"), }; } + + #[test] + fn detects_honest_out_of_scope_catch_requests() { + let set_state = voter_set_state(); + let (val, _) = GossipValidator::::new( + config(), + set_state.clone(), + true, + ); + + // the validator starts at set id 2 + val.note_set(SetId(2), Vec::new(), |_, _| {}); + + // add the peer making the request to the validator, + // otherwise it is discarded + let peer = PeerId::random(); + val.inner.write().peers.new_peer(peer.clone(), Roles::AUTHORITY); + + let send_request = |set_id, round| { + let mut inner = val.inner.write(); + inner.handle_catch_up_request( + &peer, + CatchUpRequestMessage { + set_id: SetId(set_id), + round: Round(round), + }, + &set_state, + ) + }; + + let assert_res = |res: (Option<_>, Action<_>), honest| { + assert!(res.0.is_none()); + assert_eq!( + res.1, + if honest { + Action::Discard(cost::HONEST_OUT_OF_SCOPE_CATCH_UP) + } else { + Action::Discard(Misbehavior::OutOfScopeMessage.cost()) + }, + ); + }; + + // the validator is at set id 2 and round 0. requests for set id 1 + // should not be answered but they should be considered an honest + // mistake + assert_res( + send_request(1, 1), + true, + ); + + assert_res( + send_request(1, 10), + true, + ); + + // requests for set id 0 should be considered out of scope + assert_res( + send_request(0, 1), + false, + ); + + assert_res( + send_request(0, 10), + false, + ); + + // after the validator progresses further than CATCH_UP_THRESHOLD in set + // id 2, any request for set id 1 should no longer be considered an + // honest mistake. + val.note_round(Round(3), |_, _| {}); + + assert_res( + send_request(1, 1), + false, + ); + + assert_res( + send_request(1, 2), + false, + ); + } + + #[test] + fn issues_catch_up_request_on_neighbor_packet_import() { + let (val, _) = GossipValidator::::new( + config(), + voter_set_state(), + true, + ); + + // the validator starts at set id 1. + val.note_set(SetId(1), Vec::new(), |_, _| {}); + + // add the peer making the request to the validator, + // otherwise it is discarded. + let peer = PeerId::random(); + val.inner.write().peers.new_peer(peer.clone(), Roles::AUTHORITY); + + let import_neighbor_message = |set_id, round| { + let (_, _, catch_up_request, _) = val.inner.write().import_neighbor_message( + &peer, + NeighborPacket { + round: Round(round), + set_id: SetId(set_id), + commit_finalized_height: 42, + }, + ); + + catch_up_request + }; + + // importing a neighbor message from a peer in the same set in a later + // round should lead to a catch up request for the previous round. + match import_neighbor_message(1, 42) { + Some(GossipMessage::CatchUpRequest(request)) => { + assert_eq!(request.set_id, SetId(1)); + assert_eq!(request.round, Round(41)); + }, + _ => panic!("expected catch up message"), + } + + // we note that we're at round 41. + val.note_round(Round(41), |_, _| {}); + + // if we import a neighbor message within CATCH_UP_THRESHOLD then we + // won't request a catch up. + match import_neighbor_message(1, 42) { + None => {}, + _ => panic!("expected no catch up message"), + } + + // or if the peer is on a lower round. + match import_neighbor_message(1, 40) { + None => {}, + _ => panic!("expected no catch up message"), + } + + // we also don't request a catch up if the peer is in a different set. + match import_neighbor_message(2, 42) { + None => {}, + _ => panic!("expected no catch up message"), + } + } + + #[test] + fn doesnt_send_catch_up_requests_when_disabled() { + // we create a gossip validator with catch up requests disabled. + let (val, _) = GossipValidator::::new( + config(), + voter_set_state(), + false, + ); + + // the validator starts at set id 1. + val.note_set(SetId(1), Vec::new(), |_, _| {}); + + // add the peer making the request to the validator, + // otherwise it is discarded. + let peer = PeerId::random(); + val.inner.write().peers.new_peer(peer.clone(), Roles::AUTHORITY); + + // importing a neighbor message from a peer in the same set in a later + // round should lead to a catch up request but since they're disabled + // we should get `None`. + let (_, _, catch_up_request, _) = val.inner.write().import_neighbor_message( + &peer, + NeighborPacket { + round: Round(42), + set_id: SetId(1), + commit_finalized_height: 50, + }, + ); + + match catch_up_request { + None => {}, + _ => panic!("expected no catch up message"), + } + } + + #[test] + fn doesnt_send_catch_up_requests_to_non_authorities() { + let (val, _) = GossipValidator::::new( + config(), + voter_set_state(), + true, + ); + + // the validator starts at set id 1. + val.note_set(SetId(1), Vec::new(), |_, _| {}); + + // add the peers making the requests to the validator, + // otherwise it is discarded. + let peer_authority = PeerId::random(); + let peer_full = PeerId::random(); + + val.inner.write().peers.new_peer(peer_authority.clone(), Roles::AUTHORITY); + val.inner.write().peers.new_peer(peer_full.clone(), Roles::FULL); + + let import_neighbor_message = |peer| { + let (_, _, catch_up_request, _) = val.inner.write().import_neighbor_message( + &peer, + NeighborPacket { + round: Round(42), + set_id: SetId(1), + commit_finalized_height: 50, + }, + ); + + catch_up_request + }; + + // importing a neighbor message from a peer in the same set in a later + // round should lead to a catch up request but since the node is not an + // authority we should get `None`. + if import_neighbor_message(peer_full).is_some() { + panic!("expected no catch up message"); + } + + // importing the same neighbor message from a peer who is an authority + // should lead to a catch up request. + match import_neighbor_message(peer_authority) { + Some(GossipMessage::CatchUpRequest(request)) => { + assert_eq!(request.set_id, SetId(1)); + assert_eq!(request.round, Round(41)); + }, + _ => panic!("expected catch up message"), + } + } } diff --git a/core/finality-grandpa/src/communication/mod.rs b/core/finality-grandpa/src/communication/mod.rs index 2aa2618535948821e99984b9934c17b79a46f95e..652c33c0262a598d8ba3202ba908eae78c370de1 100644 --- a/core/finality-grandpa/src/communication/mod.rs +++ b/core/finality-grandpa/src/communication/mod.rs @@ -50,7 +50,9 @@ use crate::environment::HasVoted; use gossip::{ GossipMessage, FullCatchUpMessage, FullCommitMessage, VoteOrPrecommitMessage, GossipValidator }; -use fg_primitives::{AuthorityPair, AuthorityId, AuthoritySignature}; +use fg_primitives::{ + AuthorityPair, AuthorityId, AuthoritySignature, SetId as SetIdNumber, RoundNumber, +}; pub mod gossip; mod periodic; @@ -125,16 +127,16 @@ pub trait Network: Clone + Send + 'static { fn report(&self, who: network::PeerId, cost_benefit: i32); /// Inform peers that a block with given hash should be downloaded. - fn announce(&self, block: Block::Hash); + fn announce(&self, block: Block::Hash, associated_data: Vec); } /// Create a unique topic for a round and set-id combo. -pub(crate) fn round_topic(round: u64, set_id: u64) -> B::Hash { +pub(crate) fn round_topic(round: RoundNumber, set_id: SetIdNumber) -> B::Hash { <::Hashing as HashT>::hash(format!("{}-{}", set_id, round).as_bytes()) } /// Create a unique topic for global messages on a set ID. -pub(crate) fn global_topic(set_id: u64) -> B::Hash { +pub(crate) fn global_topic(set_id: SetIdNumber) -> B::Hash { <::Hashing as HashT>::hash(format!("{}-GLOBAL", set_id).as_bytes()) } @@ -195,8 +197,8 @@ impl Network for Arc> where self.report_peer(who, cost_benefit) } - fn announce(&self, block: B::Hash) { - self.announce_block(block) + fn announce(&self, block: B::Hash, associated_data: Vec) { + self.announce_block(block, associated_data) } } @@ -231,24 +233,31 @@ pub(crate) struct NetworkBridge> { service: N, validator: Arc>, neighbor_sender: periodic::NeighborPacketSender, + announce_sender: periodic::BlockAnnounceSender, } impl> NetworkBridge { /// Create a new NetworkBridge to the given NetworkService. Returns the service /// handle and a future that must be polled to completion to finish startup. - /// If a voter set state is given it registers previous round votes with the - /// gossip service. + /// On creation it will register previous rounds' votes with the gossip + /// service taken from the VoterSetState. pub(crate) fn new( service: N, config: crate::Config, set_state: crate::environment::SharedVoterSetState, on_exit: impl Future + Clone + Send + 'static, + catch_up_enabled: bool, ) -> ( Self, impl futures::Future + Send + 'static, ) { - let (validator, report_stream) = GossipValidator::new(config, set_state.clone()); + let (validator, report_stream) = GossipValidator::new( + config, + set_state.clone(), + catch_up_enabled, + ); + let validator = Arc::new(validator); service.register_validator(validator.clone()); @@ -291,9 +300,10 @@ impl> NetworkBridge { } let (rebroadcast_job, neighbor_sender) = periodic::neighbor_packet_worker(service.clone()); + let (announce_job, announce_sender) = periodic::block_announce_worker(service.clone()); let reporting_job = report_stream.consume(service.clone()); - let bridge = NetworkBridge { service, validator, neighbor_sender }; + let bridge = NetworkBridge { service, validator, neighbor_sender, announce_sender }; let startup_work = futures::future::lazy(move || { // lazily spawn these jobs onto their own tasks. the lazy future has access @@ -301,6 +311,8 @@ impl> NetworkBridge { let mut executor = tokio_executor::DefaultExecutor::current(); executor.spawn(Box::new(rebroadcast_job.select(on_exit.clone()).then(|_| Ok(())))) .expect("failed to spawn grandpa rebroadcast job task"); + executor.spawn(Box::new(announce_job.select(on_exit.clone()).then(|_| Ok(())))) + .expect("failed to spawn grandpa block announce job task"); executor.spawn(Box::new(reporting_job.select(on_exit.clone()).then(|_| Ok(())))) .expect("failed to spawn grandpa reporting job task"); Ok(()) @@ -320,18 +332,12 @@ impl> NetworkBridge { self.validator.note_set( set_id, voters.voters().iter().map(|(v, _)| v.clone()).collect(), - |to, neighbor| self.service.send_message( - to, - GossipMessage::::from(neighbor).encode() - ), + |to, neighbor| self.neighbor_sender.send(to, neighbor), ); self.validator.note_round( round, - |to, neighbor| self.service.send_message( - to, - GossipMessage::::from(neighbor).encode() - ), + |to, neighbor| self.neighbor_sender.send(to, neighbor), ); } @@ -422,6 +428,7 @@ impl> NetworkBridge { network: self.service.clone(), locals, sender: tx, + announce_sender: self.announce_sender.clone(), has_voted, }; @@ -447,18 +454,25 @@ impl> NetworkBridge { self.validator.note_set( set_id, voters.voters().iter().map(|(v, _)| v.clone()).collect(), - |to, neighbor| self.service.send_message(to, GossipMessage::::from(neighbor).encode()), + |to, neighbor| self.neighbor_sender.send(to, neighbor), ); let service = self.service.clone(); let topic = global_topic::(set_id.0); - let incoming = incoming_global(service, topic, voters, self.validator.clone()); + let incoming = incoming_global( + service, + topic, + voters, + self.validator.clone(), + self.neighbor_sender.clone(), + ); let outgoing = CommitsOut::::new( self.service.clone(), set_id.0, is_voter, self.validator.clone(), + self.neighbor_sender.clone(), ); let outgoing = outgoing.with(|out| { @@ -475,6 +489,7 @@ fn incoming_global>( topic: B::Hash, voters: Arc>, gossip_validator: Arc>, + neighbor_sender: periodic::NeighborPacketSender, ) -> impl Stream, Error = Error> { let process_commit = move | msg: FullCommitMessage, @@ -512,6 +527,7 @@ fn incoming_global>( let finalized_number = commit.target_number; let gossip_validator = gossip_validator.clone(); let service = service.clone(); + let neighbor_sender = neighbor_sender.clone(); let cb = move |outcome| match outcome { voter::CommitProcessingOutcome::Good(_) => { // if it checks out, gossip it. not accounting for @@ -519,10 +535,7 @@ fn incoming_global>( // finalized number. gossip_validator.note_commit_finalized( finalized_number, - |to, neighbor_msg| service.send_message( - to, - GossipMessage::::from(neighbor_msg).encode(), - ), + |to, neighbor| neighbor_sender.send(to, neighbor), ); service.gossip_message(topic, notification.message.clone(), false); @@ -608,29 +621,30 @@ impl> Clone for NetworkBridge { service: self.service.clone(), validator: Arc::clone(&self.validator), neighbor_sender: self.neighbor_sender.clone(), + announce_sender: self.announce_sender.clone(), } } } -fn localized_payload(round: u64, set_id: u64, message: &E) -> Vec { +fn localized_payload(round: RoundNumber, set_id: SetIdNumber, message: &E) -> Vec { (message, round, set_id).encode() } -/// Type-safe wrapper around u64 when indicating that it's a round number. +/// Type-safe wrapper around a round number. #[derive(Debug, Clone, Copy, Eq, PartialEq, PartialOrd, Ord, Encode, Decode)] -pub struct Round(pub u64); +pub struct Round(pub RoundNumber); -/// Type-safe wrapper around u64 when indicating that it's a set ID. +/// Type-safe wrapper around a set ID. #[derive(Debug, Clone, Copy, Eq, PartialEq, PartialOrd, Ord, Encode, Decode)] -pub struct SetId(pub u64); +pub struct SetId(pub SetIdNumber); // check a message. pub(crate) fn check_message_sig( message: &Message, id: &AuthorityId, signature: &AuthoritySignature, - round: u64, - set_id: u64, + round: RoundNumber, + set_id: SetIdNumber, ) -> Result<(), ()> { let as_public = id.clone(); let encoded_raw = localized_payload(round, set_id, message); @@ -650,10 +664,11 @@ pub(crate) fn check_message_sig( /// `ed25519` and `BLS` signatures (which we might use in the future), care must /// be taken when switching to different key types. struct OutgoingMessages> { - round: u64, - set_id: u64, + round: RoundNumber, + set_id: SetIdNumber, locals: Option<(AuthorityPair, AuthorityId)>, sender: mpsc::UnboundedSender>, + announce_sender: periodic::BlockAnnounceSender, network: N, has_voted: HasVoted, } @@ -711,10 +726,10 @@ impl> Sink for OutgoingMessages "block" => ?target_hash, "round" => ?self.round, "set_id" => ?self.set_id, ); - // announce our block hash to peers and propagate the - // message. - self.network.announce(target_hash); + // send the target block hash to the background block announcer + self.announce_sender.send(target_hash, Vec::new()); + // propagate the message to peers let topic = round_topic::(self.round, self.set_id); self.network.gossip_message(topic, message.encode(), false); @@ -845,8 +860,8 @@ fn check_catch_up( fn check_signatures<'a, B, I>( messages: I, - round: u64, - set_id: u64, + round: RoundNumber, + set_id: SetIdNumber, mut signatures_checked: usize, ) -> Result where B: BlockT, @@ -907,30 +922,33 @@ struct CommitsOut> { set_id: SetId, is_voter: bool, gossip_validator: Arc>, + neighbor_sender: periodic::NeighborPacketSender, } impl> CommitsOut { /// Create a new commit output stream. pub(crate) fn new( network: N, - set_id: u64, + set_id: SetIdNumber, is_voter: bool, gossip_validator: Arc>, + neighbor_sender: periodic::NeighborPacketSender, ) -> Self { CommitsOut { network, set_id: SetId(set_id), is_voter, gossip_validator, + neighbor_sender, } } } impl> Sink for CommitsOut { - type SinkItem = (u64, Commit); + type SinkItem = (RoundNumber, Commit); type SinkError = Error; - fn start_send(&mut self, input: (u64, Commit)) -> StartSend { + fn start_send(&mut self, input: (RoundNumber, Commit)) -> StartSend { if !self.is_voter { return Ok(AsyncSink::Ready); } @@ -964,10 +982,7 @@ impl> Sink for CommitsOut { // before gossiping self.gossip_validator.note_commit_finalized( commit.target_number, - |to, neighbor| self.network.send_message( - to, - GossipMessage::::from(neighbor).encode(), - ), + |to, neighbor| self.neighbor_sender.send(to, neighbor), ); self.network.gossip_message(topic, message.encode(), false); diff --git a/core/finality-grandpa/src/communication/periodic.rs b/core/finality-grandpa/src/communication/periodic.rs index 7265fe34a2a8659783c9b7cd2e5afa1bed05b560..81c18891d03b52f6aae572c8768433218322aa05 100644 --- a/core/finality-grandpa/src/communication/periodic.rs +++ b/core/finality-grandpa/src/communication/periodic.rs @@ -16,26 +16,49 @@ //! Periodic rebroadcast of neighbor packets. -use super::{gossip::{NeighborPacket, GossipMessage}, Network}; +use std::collections::VecDeque; +use std::time::{Instant, Duration}; + +use codec::Encode; use futures::prelude::*; use futures::sync::mpsc; -use sr_primitives::traits::{NumberFor, Block as BlockT}; -use network::PeerId; +use log::{debug, warn}; use tokio_timer::Delay; -use log::warn; -use codec::Encode; -use std::time::{Instant, Duration}; +use network::PeerId; +use sr_primitives::traits::{NumberFor, Block as BlockT}; +use super::{gossip::{NeighborPacket, GossipMessage}, Network}; // how often to rebroadcast, if no other const REBROADCAST_AFTER: Duration = Duration::from_secs(2 * 60); +/// The number of block hashes that we have previously voted on that we should +/// keep around for announcement. The current value should be enough for 3 +/// rounds assuming we have prevoted and precommited on different blocks. +const LATEST_VOTED_BLOCKS_TO_ANNOUNCE: usize = 6; + fn rebroadcast_instant() -> Instant { Instant::now() + REBROADCAST_AFTER } /// A sender used to send neighbor packets to a background job. -pub(super) type NeighborPacketSender = mpsc::UnboundedSender<(Vec, NeighborPacket>)>; +#[derive(Clone)] +pub(super) struct NeighborPacketSender( + mpsc::UnboundedSender<(Vec, NeighborPacket>)> +); + +impl NeighborPacketSender { + /// Send a neighbor packet for the background worker to gossip to peers. + pub fn send( + &self, + who: Vec, + neighbor_packet: NeighborPacket>, + ) { + if let Err(err) = self.0.unbounded_send((who, neighbor_packet)) { + debug!(target: "afg", "Failed to send neighbor packet: {:?}", err); + } + } +} /// Does the work of sending neighbor packets, asynchronously. /// @@ -89,5 +112,141 @@ pub(super) fn neighbor_packet_worker(net: N) -> ( } }); - (work, tx) + (work, NeighborPacketSender(tx)) +} + +/// A background worker for performing block announcements. +struct BlockAnnouncer { + net: N, + block_rx: mpsc::UnboundedReceiver<(B::Hash, Vec)>, + latest_voted_blocks: VecDeque, + reannounce_after: Duration, + delay: Delay, +} + +/// A background worker for announcing block hashes to peers. The worker keeps +/// track of `LATEST_VOTED_BLOCKS_TO_ANNOUNCE` and periodically announces these +/// blocks to all peers if no new blocks to announce are noted (i.e. presumably +/// GRANDPA progress is stalled). +pub(super) fn block_announce_worker>(net: N) -> ( + impl Future, + BlockAnnounceSender, +) { + block_announce_worker_aux(net, REBROADCAST_AFTER) +} + +#[cfg(test)] +pub(super) fn block_announce_worker_with_delay>( + net: N, + reannounce_after: Duration, +) -> ( + impl Future, + BlockAnnounceSender, +) { + block_announce_worker_aux(net, reannounce_after) +} + +fn block_announce_worker_aux>( + net: N, + reannounce_after: Duration, +) -> ( + impl Future, + BlockAnnounceSender, +) { + let latest_voted_blocks = VecDeque::with_capacity(LATEST_VOTED_BLOCKS_TO_ANNOUNCE); + + let (block_tx, block_rx) = mpsc::unbounded(); + + let announcer = BlockAnnouncer { + net, + block_rx, + latest_voted_blocks, + reannounce_after, + delay: Delay::new(Instant::now() + reannounce_after), + }; + + (announcer, BlockAnnounceSender(block_tx)) +} + + +impl BlockAnnouncer { + fn note_block(&mut self, block: B::Hash) -> bool { + if !self.latest_voted_blocks.contains(&block) { + if self.latest_voted_blocks.len() >= LATEST_VOTED_BLOCKS_TO_ANNOUNCE { + self.latest_voted_blocks.pop_front(); + } + + self.latest_voted_blocks.push_back(block); + + true + } else { + false + } + } + + fn reset_delay(&mut self) { + self.delay.reset(Instant::now() + self.reannounce_after); + } +} + +impl> Future for BlockAnnouncer { + type Item = (); + type Error = (); + + fn poll(&mut self) -> Poll { + // note any new blocks to announce and announce them + loop { + match self.block_rx.poll().expect("unbounded receivers do not error; qed") { + Async::Ready(None) => return Ok(Async::Ready(())), + Async::Ready(Some(block)) => { + if self.note_block(block.0) { + self.net.announce(block.0, block.1); + self.reset_delay(); + } + }, + Async::NotReady => break, + } + } + + // check the reannouncement delay timer, has to be done in a loop + // because it needs to be polled after re-scheduling. + loop { + match self.delay.poll() { + Err(e) => { + warn!(target: "afg", "Error in periodic block announcer timer: {:?}", e); + self.reset_delay(); + }, + // after the delay fires announce all blocks that we have + // stored. note that this only happens if we don't receive any + // new blocks above for the duration of `reannounce_after`. + Ok(Async::Ready(())) => { + self.reset_delay(); + + debug!( + target: "afg", + "Re-announcing latest voted blocks due to lack of progress: {:?}", + self.latest_voted_blocks, + ); + + for block in self.latest_voted_blocks.iter() { + self.net.announce(*block, Vec::new()); + } + }, + Ok(Async::NotReady) => return Ok(Async::NotReady), + } + } + } +} + +/// A sender used to send block hashes to announce to a background job. +#[derive(Clone)] +pub(super) struct BlockAnnounceSender(mpsc::UnboundedSender<(B::Hash, Vec)>); + +impl BlockAnnounceSender { + /// Send a block hash for the background worker to announce. + pub fn send(&self, block: B::Hash, associated_data: Vec) { + if let Err(err) = self.0.unbounded_send((block, associated_data)) { + debug!(target: "afg", "Failed to send block to background announcer: {:?}", err); + } + } } diff --git a/core/finality-grandpa/src/communication/tests.rs b/core/finality-grandpa/src/communication/tests.rs index de5a084039268193e840f7511e322cf41155940e..6215e30b809660518f7945efe6f8de0fa4c25b1f 100644 --- a/core/finality-grandpa/src/communication/tests.rs +++ b/core/finality-grandpa/src/communication/tests.rs @@ -88,7 +88,7 @@ impl super::Network for TestNetwork { } /// Inform peers that a block with given hash should be downloaded. - fn announce(&self, block: Hash) { + fn announce(&self, block: Hash, _associated_data: Vec) { let _ = self.sender.unbounded_send(Event::Announce(block)); } } @@ -182,6 +182,7 @@ fn make_test_network() -> ( config(), voter_set_state(), Exit, + true, ); ( @@ -447,8 +448,8 @@ fn peer_with_higher_view_leads_to_catch_up_request() { let (tester, mut net) = make_test_network(); let test = tester .and_then(move |tester| { - // register a peer. - tester.gossip_validator.new_peer(&mut NoopContext, &id, network::config::Roles::FULL); + // register a peer with authority role. + tester.gossip_validator.new_peer(&mut NoopContext, &id, network::config::Roles::AUTHORITY); Ok((tester, id)) }) .and_then(move |(tester, id)| { @@ -497,3 +498,79 @@ fn peer_with_higher_view_leads_to_catch_up_request() { current_thread::block_on_all(test).unwrap(); } + +#[test] +fn periodically_reannounce_voted_blocks_on_stall() { + use futures::try_ready; + use std::collections::HashSet; + use std::sync::Arc; + use std::time::Duration; + use parking_lot::Mutex; + + let (tester, net) = make_test_network(); + let (announce_worker, announce_sender) = super::periodic::block_announce_worker_with_delay( + net, + Duration::from_secs(1), + ); + + let hashes = Arc::new(Mutex::new(Vec::new())); + + fn wait_all(tester: Tester, hashes: &[Hash]) -> impl Future { + struct WaitAll { + remaining_hashes: Arc>>, + events_fut: Box>, + } + + impl Future for WaitAll { + type Item = Tester; + type Error = (); + + fn poll(&mut self) -> Poll { + let tester = try_ready!(self.events_fut.poll()); + + if self.remaining_hashes.lock().is_empty() { + return Ok(Async::Ready(tester)); + } + + let remaining_hashes = self.remaining_hashes.clone(); + self.events_fut = Box::new(tester.filter_network_events(move |event| match event { + Event::Announce(h) => + remaining_hashes.lock().remove(&h) || panic!("unexpected announce"), + _ => false, + })); + + self.poll() + } + } + + WaitAll { + remaining_hashes: Arc::new(Mutex::new(hashes.iter().cloned().collect())), + events_fut: Box::new(futures::future::ok(tester)), + } + } + + let test = tester + .and_then(move |tester| { + current_thread::spawn(announce_worker); + Ok(tester) + }) + .and_then(|tester| { + // announce 12 blocks + for _ in 0..=12 { + let hash = Hash::random(); + hashes.lock().push(hash); + announce_sender.send(hash, Vec::new()); + } + + // we should see an event for each of those announcements + wait_all(tester, &hashes.lock()) + }) + .and_then(|tester| { + // after a period of inactivity we should see the last + // `LATEST_VOTED_BLOCKS_TO_ANNOUNCE` being rebroadcast + wait_all(tester, &hashes.lock()[7..=12]) + }); + + let mut runtime = current_thread::Runtime::new().unwrap(); + runtime.block_on(test).unwrap(); +} diff --git a/core/finality-grandpa/src/environment.rs b/core/finality-grandpa/src/environment.rs index 5761093c5eb676a2c5e3ec56c01d636a1216d033..70e45848be1dd10192cc477466cb81d5aa973cb7 100644 --- a/core/finality-grandpa/src/environment.rs +++ b/core/finality-grandpa/src/environment.rs @@ -26,8 +26,9 @@ use tokio_timer::Delay; use parking_lot::RwLock; use client::{ - backend::Backend, BlockchainEvents, CallExecutor, Client, error::Error as ClientError, - utils::is_descendent_of, + backend::Backend, apply_aux, BlockchainEvents, CallExecutor, + Client, error::Error as ClientError, utils::is_descendent_of, + blockchain::HeaderBackend, backend::Finalizer, }; use grandpa::{ BlockNumberOps, Equivocation, Error as GrandpaError, round::State as RoundState, @@ -51,7 +52,7 @@ use crate::authorities::{AuthoritySet, SharedAuthoritySet}; use crate::consensus_changes::SharedConsensusChanges; use crate::justification::GrandpaJustification; use crate::until_imported::UntilVoteTargetImported; -use fg_primitives::{AuthorityId, AuthoritySignature}; +use fg_primitives::{AuthorityId, AuthoritySignature, SetId, RoundNumber}; type HistoricalVotes = grandpa::HistoricalVotes< ::Hash, @@ -65,7 +66,7 @@ type HistoricalVotes = grandpa::HistoricalVotes< #[derive(Debug, Clone, Decode, Encode, PartialEq)] pub struct CompletedRound { /// The round number. - pub number: u64, + pub number: RoundNumber, /// The round state (prevote ghost, estimate, finalized, etc.) pub state: RoundState>, /// The target block base used for voting in the round. @@ -80,7 +81,7 @@ pub struct CompletedRound { #[derive(Debug, Clone, PartialEq)] pub struct CompletedRounds { rounds: Vec>, - set_id: u64, + set_id: SetId, voters: Vec, } @@ -100,7 +101,7 @@ impl codec::EncodeLike for CompletedRounds {} impl Decode for CompletedRounds { fn decode(value: &mut I) -> Result { - <(Vec>, u64, Vec)>::decode(value) + <(Vec>, SetId, Vec)>::decode(value) .map(|(rounds, set_id, voters)| CompletedRounds { rounds: rounds.into(), set_id, @@ -113,7 +114,7 @@ impl CompletedRounds { /// Create a new completed rounds tracker with NUM_LAST_COMPLETED_ROUNDS capacity. pub(crate) fn new( genesis: CompletedRound, - set_id: u64, + set_id: SetId, voters: &AuthoritySet>, ) -> CompletedRounds @@ -126,7 +127,7 @@ impl CompletedRounds { } /// Get the set-id and voter set of the completed rounds. - pub fn set_info(&self) -> (u64, &[AuthorityId]) { + pub fn set_info(&self) -> (SetId, &[AuthorityId]) { (self.set_id, &self.voters[..]) } @@ -162,7 +163,7 @@ impl CompletedRounds { /// A map with voter status information for currently live rounds, /// which votes have we cast and what are they. -pub type CurrentRounds = BTreeMap>; +pub type CurrentRounds = BTreeMap>; /// The state of the current voter set, whether it is currently active or not /// and information related to the previously completed rounds. Current round @@ -190,7 +191,7 @@ impl VoterSetState { /// the given genesis state and the given authorities. Round 1 is added as a /// current round (with state `HasVoted::No`). pub(crate) fn live( - set_id: u64, + set_id: SetId, authority_set: &AuthoritySet>, genesis_state: (Block::Hash, NumberFor), ) -> VoterSetState { @@ -237,7 +238,7 @@ impl VoterSetState { /// Returns the voter set state validating that it includes the given round /// in current rounds and that the voter isn't paused. - pub fn with_current_round(&self, round: u64) + pub fn with_current_round(&self, round: RoundNumber) -> Result<(&CompletedRounds, &CurrentRounds), Error> { if let VoterSetState::Live { completed_rounds, current_rounds } = self { @@ -344,7 +345,7 @@ impl SharedVoterSetState { } /// Return vote status information for the current round. - pub(crate) fn has_voted(&self, round: u64) -> HasVoted { + pub(crate) fn has_voted(&self, round: RoundNumber) -> HasVoted { match &*self.inner.read() { VoterSetState::Live { current_rounds, .. } => { current_rounds.get(&round).and_then(|has_voted| match has_voted { @@ -375,7 +376,7 @@ pub(crate) struct Environment, RA, SC> { pub(crate) authority_set: SharedAuthoritySet>, pub(crate) consensus_changes: SharedConsensusChanges>, pub(crate) network: crate::communication::NetworkBridge, - pub(crate) set_id: u64, + pub(crate) set_id: SetId, pub(crate) voter_set_state: SharedVoterSetState, } @@ -497,12 +498,7 @@ pub(crate) fn ancestry, E, RA>( { if base == block { return Err(GrandpaError::NotDescendent) } - let tree_route_res = ::client::blockchain::tree_route( - #[allow(deprecated)] - client.backend().blockchain(), - BlockId::Hash(block), - BlockId::Hash(base), - ); + let tree_route_res = header_metadata::tree_route(client, block, base); let tree_route = match tree_route_res { Ok(tree_route) => tree_route, @@ -554,7 +550,7 @@ where fn round_data( &self, - round: u64 + round: RoundNumber, ) -> voter::RoundData { let now = Instant::now(); let prevote_timer = Delay::new(now + self.config.gossip_duration * 2); @@ -587,6 +583,7 @@ where self.inner.import_notification_stream(), self.inner.clone(), incoming, + "round", ).map_err(Into::into)); // schedule network message cleanup when sink drops. @@ -601,7 +598,7 @@ where } } - fn proposed(&self, round: u64, propose: PrimaryPropose) -> Result<(), Self::Error> { + fn proposed(&self, round: RoundNumber, propose: PrimaryPropose) -> Result<(), Self::Error> { let local_id = crate::is_voter(&self.voters, &self.config.keystore); let local_id = match local_id { @@ -632,8 +629,7 @@ where current_rounds, }; - #[allow(deprecated)] - crate::aux_schema::write_voter_set_state(&**self.inner.backend(), &set_state)?; + crate::aux_schema::write_voter_set_state(&*self.inner, &set_state)?; Ok(Some(set_state)) })?; @@ -641,7 +637,7 @@ where Ok(()) } - fn prevoted(&self, round: u64, prevote: Prevote) -> Result<(), Self::Error> { + fn prevoted(&self, round: RoundNumber, prevote: Prevote) -> Result<(), Self::Error> { let local_id = crate::is_voter(&self.voters, &self.config.keystore); let local_id = match local_id { @@ -674,8 +670,7 @@ where current_rounds, }; - #[allow(deprecated)] - crate::aux_schema::write_voter_set_state(&**self.inner.backend(), &set_state)?; + crate::aux_schema::write_voter_set_state(&*self.inner, &set_state)?; Ok(Some(set_state)) })?; @@ -683,7 +678,7 @@ where Ok(()) } - fn precommitted(&self, round: u64, precommit: Precommit) -> Result<(), Self::Error> { + fn precommitted(&self, round: RoundNumber, precommit: Precommit) -> Result<(), Self::Error> { let local_id = crate::is_voter(&self.voters, &self.config.keystore); let local_id = match local_id { @@ -726,8 +721,7 @@ where current_rounds, }; - #[allow(deprecated)] - crate::aux_schema::write_voter_set_state(&**self.inner.backend(), &set_state)?; + crate::aux_schema::write_voter_set_state(&*self.inner, &set_state)?; Ok(Some(set_state)) })?; @@ -737,7 +731,7 @@ where fn completed( &self, - round: u64, + round: RoundNumber, state: RoundState>, base: (Block::Hash, NumberFor), historical_votes: &HistoricalVotes, @@ -785,8 +779,7 @@ where current_rounds, }; - #[allow(deprecated)] - crate::aux_schema::write_voter_set_state(&**self.inner.backend(), &set_state)?; + crate::aux_schema::write_voter_set_state(&*self.inner, &set_state)?; Ok(Some(set_state)) })?; @@ -794,25 +787,13 @@ where Ok(()) } - fn finalize_block(&self, hash: Block::Hash, number: NumberFor, round: u64, commit: Commit) -> Result<(), Self::Error> { - use client::blockchain::HeaderBackend; - - #[allow(deprecated)] - let blockchain = self.inner.backend().blockchain(); - let status = blockchain.info(); - if number <= status.finalized_number && blockchain.hash(number)? == Some(hash) { - // This can happen after a forced change (triggered by the finality tracker when finality is stalled), since - // the voter will be restarted at the median last finalized block, which can be lower than the local best - // finalized block. - warn!(target: "afg", "Re-finalized block #{:?} ({:?}) in the canonical chain, current best finalized is #{:?}", - hash, - number, - status.finalized_number, - ); - - return Ok(()); - } - + fn finalize_block( + &self, + hash: Block::Hash, + number: NumberFor, + round: RoundNumber, + commit: Commit, + ) -> Result<(), Self::Error> { finalize_block( &*self.inner, &self.authority_set, @@ -836,7 +817,7 @@ where fn prevote_equivocation( &self, - _round: u64, + _round: RoundNumber, equivocation: ::grandpa::Equivocation, Self::Signature> ) { warn!(target: "afg", "Detected prevote equivocation in the finality worker: {:?}", equivocation); @@ -845,7 +826,7 @@ where fn precommit_equivocation( &self, - _round: u64, + _round: RoundNumber, equivocation: Equivocation, Self::Signature> ) { warn!(target: "afg", "Detected precommit equivocation in the finality worker: {:?}", equivocation); @@ -855,11 +836,11 @@ where pub(crate) enum JustificationOrCommit { Justification(GrandpaJustification), - Commit((u64, Commit)), + Commit((RoundNumber, Commit)), } -impl From<(u64, Commit)> for JustificationOrCommit { - fn from(commit: (u64, Commit)) -> JustificationOrCommit { +impl From<(RoundNumber, Commit)> for JustificationOrCommit { + fn from(commit: (RoundNumber, Commit)) -> JustificationOrCommit { JustificationOrCommit::Commit(commit) } } @@ -887,9 +868,25 @@ pub(crate) fn finalize_block, E, RA>( E: CallExecutor + Send + Sync, RA: Send + Sync, { - // lock must be held through writing to DB to avoid race + // NOTE: lock must be held through writing to DB to avoid race. this lock + // also implicitly synchronizes the check for last finalized number + // below. let mut authority_set = authority_set.inner().write(); + let status = client.info().chain; + if number <= status.finalized_number && client.hash(number)? == Some(hash) { + // This can happen after a forced change (triggered by the finality tracker when finality is stalled), since + // the voter will be restarted at the median last finalized block, which can be lower than the local best + // finalized block. + warn!(target: "afg", "Re-finalized block #{:?} ({:?}) in the canonical chain, current best finalized is #{:?}", + hash, + number, + status.finalized_number, + ); + + return Ok(()); + } + // FIXME #1483: clone only when changed let old_authority_set = authority_set.clone(); // holds the old consensus changes in case it is changed below, needed for @@ -906,7 +903,7 @@ pub(crate) fn finalize_block, E, RA>( let status = authority_set.apply_standard_changes( hash, number, - &is_descendent_of(client, None), + &is_descendent_of::<_, _, Block::Hash>(client, None), ).map_err(|e| Error::Safety(e.to_string()))?; // check if this is this is the first finalization of some consensus changes @@ -918,7 +915,7 @@ pub(crate) fn finalize_block, E, RA>( let write_result = crate::aux_schema::update_consensus_changes( &*consensus_changes, - |insert| client.apply_aux(import_op, insert, &[]), + |insert| apply_aux(import_op, insert, &[]), ); if let Err(e) = write_result { @@ -1011,7 +1008,7 @@ pub(crate) fn finalize_block, E, RA>( let write_result = crate::aux_schema::update_authority_set::( &authority_set, new_authorities.as_ref(), - |insert| client.apply_aux(import_op, insert, &[]), + |insert| apply_aux(import_op, insert, &[]), ); if let Err(e) = write_result { @@ -1042,15 +1039,12 @@ pub(crate) fn finalize_block, E, RA>( /// Using the given base get the block at the given height on this chain. The /// target block must be an ancestor of base, therefore `height <= base.height`. -pub(crate) fn canonical_at_height, RA>( - client: &Client, +pub(crate) fn canonical_at_height, C: HeaderBackend>( + provider: C, base: (Block::Hash, NumberFor), base_is_canonical: bool, height: NumberFor, -) -> Result, ClientError> where - B: Backend, - E: CallExecutor + Send + Sync, -{ +) -> Result, ClientError> { if height > base.1 { return Ok(None); } @@ -1059,17 +1053,17 @@ pub(crate) fn canonical_at_height, RA>( if base_is_canonical { return Ok(Some(base.0)); } else { - return Ok(client.block_hash(height).unwrap_or(None)); + return Ok(provider.hash(height).unwrap_or(None)); } } else if base_is_canonical { - return Ok(client.block_hash(height).unwrap_or(None)); + return Ok(provider.hash(height).unwrap_or(None)); } let one = NumberFor::::one(); // start by getting _canonical_ block with number at parent position and then iterating // backwards by hash. - let mut current = match client.header(&BlockId::Number(base.1 - one))? { + let mut current = match provider.header(BlockId::Number(base.1 - one))? { Some(header) => header, _ => return Ok(None), }; @@ -1078,7 +1072,7 @@ pub(crate) fn canonical_at_height, RA>( let mut steps = base.1 - height - one; while steps > NumberFor::::zero() { - current = match client.header(&BlockId::Hash(*current.parent_hash()))? { + current = match provider.header(BlockId::Hash(*current.parent_hash()))? { Some(header) => header, _ => return Ok(None), }; diff --git a/core/finality-grandpa/src/finality_proof.rs b/core/finality-grandpa/src/finality_proof.rs index 6262ad74a7acb2e6a120af422367472057cef77b..bae6c8ebc09ead035997f3b176187f50c3570396 100644 --- a/core/finality-grandpa/src/finality_proof.rs +++ b/core/finality-grandpa/src/finality_proof.rs @@ -40,16 +40,15 @@ use log::{trace, warn}; use client::{ backend::Backend, blockchain::Backend as BlockchainBackend, CallExecutor, Client, error::{Error as ClientError, Result as ClientResult}, - light::fetcher::{FetchChecker, RemoteCallRequest}, - ExecutionStrategy, NeverOffchainExt, + light::fetcher::{FetchChecker, RemoteCallRequest}, ExecutionStrategy, }; use codec::{Encode, Decode}; use grandpa::BlockNumberOps; -use sr_primitives::{Justification, generic::BlockId}; -use sr_primitives::traits::{ - NumberFor, Block as BlockT, Header as HeaderT, One, +use sr_primitives::{ + Justification, generic::BlockId, + traits::{NumberFor, Block as BlockT, Header as HeaderT, One}, }; -use primitives::{H256, Blake2Hasher}; +use primitives::{H256, Blake2Hasher, offchain::NeverOffchainExt}; use substrate_telemetry::{telemetry, CONSENSUS_INFO}; use fg_primitives::AuthorityId; @@ -130,36 +129,31 @@ impl AuthoritySetForFinalityChecker for Arc, RA> { - client: Arc>, +pub struct FinalityProofProvider> { + backend: Arc, authority_provider: Arc>, } -impl, RA> FinalityProofProvider - where - B: Backend + Send + Sync + 'static, - E: CallExecutor + 'static + Clone + Send + Sync, - RA: Send + Sync, +impl> FinalityProofProvider + where B: Backend + Send + Sync + 'static { /// Create new finality proof provider using: /// - /// - client for accessing blockchain data; + /// - backend for accessing blockchain data; /// - authority_provider for calling and proving runtime methods. pub fn new( - client: Arc>, + backend: Arc, authority_provider: Arc>, ) -> Self { - FinalityProofProvider { client, authority_provider } + FinalityProofProvider { backend, authority_provider } } } -impl network::FinalityProofProvider for FinalityProofProvider +impl network::FinalityProofProvider for FinalityProofProvider where Block: BlockT, NumberFor: BlockNumberOps, B: Backend + Send + Sync + 'static, - E: CallExecutor + 'static + Clone + Send + Sync, - RA: Send + Sync, { fn prove_finality( &self, @@ -173,8 +167,7 @@ impl network::FinalityProofProvider for FinalityProofPro })?; match request { FinalityProofRequest::Original(request) => prove_finality::<_, _, GrandpaJustification>( - #[allow(deprecated)] - &*self.client.backend().blockchain(), + &*self.backend.blockchain(), &*self.authority_provider, request.authorities_set_id, request.last_finalized, diff --git a/core/finality-grandpa/src/import.rs b/core/finality-grandpa/src/import.rs index 4144a279c530ea590b39a88afb491297c0940b05..758f6f18dbb0100b07c1ee4be85e9e1dd0e8ec5f 100644 --- a/core/finality-grandpa/src/import.rs +++ b/core/finality-grandpa/src/import.rs @@ -21,22 +21,20 @@ use codec::Encode; use futures::sync::mpsc; use parking_lot::RwLockWriteGuard; -use client::{blockchain, CallExecutor, Client}; +use client::{blockchain, CallExecutor, Client, well_known_cache_keys}; use client::blockchain::HeaderBackend; use client::backend::Backend; -use client::runtime_api::ApiExt; use client::utils::is_descendent_of; use consensus_common::{ BlockImport, Error as ConsensusError, - BlockImportParams, ImportResult, JustificationImport, well_known_cache_keys, + BlockCheckParams, BlockImportParams, ImportResult, JustificationImport, SelectChain, }; -use fg_primitives::GrandpaApi; +use fg_primitives::{GRANDPA_ENGINE_ID, ScheduledChange, ConsensusLog}; use sr_primitives::Justification; -use sr_primitives::generic::BlockId; +use sr_primitives::generic::{BlockId, OpaqueDigestItemId}; use sr_primitives::traits::{ - Block as BlockT, DigestFor, - Header as HeaderT, NumberFor, ProvideRuntimeApi, + Block as BlockT, DigestFor, Header as HeaderT, NumberFor, }; use primitives::{H256, Blake2Hasher}; @@ -55,17 +53,16 @@ use crate::justification::GrandpaJustification; /// /// When using GRANDPA, the block import worker should be using this block import /// object. -pub struct GrandpaBlockImport, RA, PRA, SC> { +pub struct GrandpaBlockImport, RA, SC> { inner: Arc>, select_chain: SC, authority_set: SharedAuthoritySet>, send_voter_commands: mpsc::UnboundedSender>>, consensus_changes: SharedConsensusChanges>, - api: Arc, } -impl, RA, PRA, SC: Clone> Clone for - GrandpaBlockImport +impl, RA, SC: Clone> Clone for + GrandpaBlockImport { fn clone(&self) -> Self { GrandpaBlockImport { @@ -74,20 +71,17 @@ impl, RA, PRA, SC: Clone> Clone for authority_set: self.authority_set.clone(), send_voter_commands: self.send_voter_commands.clone(), consensus_changes: self.consensus_changes.clone(), - api: self.api.clone(), } } } -impl, RA, PRA, SC> JustificationImport - for GrandpaBlockImport where +impl, RA, SC> JustificationImport + for GrandpaBlockImport where NumberFor: grandpa::BlockNumberOps, B: Backend + 'static, E: CallExecutor + 'static + Clone + Send + Sync, DigestFor: Encode, RA: Send + Sync, - PRA: ProvideRuntimeApi, - PRA::Api: GrandpaApi, SC: SelectChain, { type Error = ConsensusError; @@ -174,75 +168,69 @@ impl<'a, Block: 'a + BlockT> Drop for PendingSetChanges<'a, Block> { } } -impl, RA, PRA, SC> - GrandpaBlockImport +fn find_scheduled_change(header: &B::Header) + -> Option>> +{ + let id = OpaqueDigestItemId::Consensus(&GRANDPA_ENGINE_ID); + + let filter_log = |log: ConsensusLog>| match log { + ConsensusLog::ScheduledChange(change) => Some(change), + _ => None, + }; + + // find the first consensus digest with the right ID which converts to + // the right kind of consensus log. + header.digest().convert_first(|l| l.try_to(id).and_then(filter_log)) +} + +fn find_forced_change(header: &B::Header) + -> Option<(NumberFor, ScheduledChange>)> +{ + let id = OpaqueDigestItemId::Consensus(&GRANDPA_ENGINE_ID); + + let filter_log = |log: ConsensusLog>| match log { + ConsensusLog::ForcedChange(delay, change) => Some((delay, change)), + _ => None, + }; + + // find the first consensus digest with the right ID which converts to + // the right kind of consensus log. + header.digest().convert_first(|l| l.try_to(id).and_then(filter_log)) +} + +impl, RA, SC> + GrandpaBlockImport where NumberFor: grandpa::BlockNumberOps, B: Backend + 'static, E: CallExecutor + 'static + Clone + Send + Sync, DigestFor: Encode, RA: Send + Sync, - PRA: ProvideRuntimeApi, - PRA::Api: GrandpaApi, { // check for a new authority set change. fn check_new_change(&self, header: &Block::Header, hash: Block::Hash) - -> Result>>, ConsensusError> + -> Option>> { - let at = BlockId::hash(*header.parent_hash()); - let digest = header.digest(); - - let api = self.api.runtime_api(); - // check for forced change. - { - let maybe_change = api.grandpa_forced_change( - &at, - digest, - ); - - match maybe_change { - Err(e) => match api.has_api_with::, _>(&at, |v| v >= 2) { - Err(e) => return Err(ConsensusError::ClientImport(e.to_string()).into()), - Ok(true) => { - // API version is high enough to support forced changes - // but got error, so it is legitimate. - return Err(ConsensusError::ClientImport(e.to_string()).into()) - }, - Ok(false) => { - // API version isn't high enough to support forced changes - }, - }, - Ok(None) => {}, - Ok(Some((median_last_finalized, change))) => return Ok(Some(PendingChange { - next_authorities: change.next_authorities, - delay: change.delay, - canon_height: *header.number(), - canon_hash: hash, - delay_kind: DelayKind::Best { median_last_finalized }, - })), - } + if let Some((median_last_finalized, change)) = find_forced_change::(header) { + return Some(PendingChange { + next_authorities: change.next_authorities, + delay: change.delay, + canon_height: *header.number(), + canon_hash: hash, + delay_kind: DelayKind::Best { median_last_finalized }, + }); } // check normal scheduled change. - { - let maybe_change = api.grandpa_pending_change( - &at, - digest, - ); - - match maybe_change { - Err(e) => Err(ConsensusError::ClientImport(e.to_string()).into()), - Ok(Some(change)) => Ok(Some(PendingChange { - next_authorities: change.next_authorities, - delay: change.delay, - canon_height: *header.number(), - canon_hash: hash, - delay_kind: DelayKind::Finalized, - })), - Ok(None) => Ok(None), - } - } + let change = find_scheduled_change::(header)?; + Some(PendingChange { + next_authorities: change.next_authorities, + delay: change.delay, + canon_height: *header.number(), + canon_hash: hash, + delay_kind: DelayKind::Finalized, + }) } fn make_authorities_changes<'a>(&'a self, block: &mut BlockImportParams, hash: Block::Hash) @@ -289,12 +277,12 @@ where let maybe_change = self.check_new_change( &block.header, hash, - )?; + ); // returns a function for checking whether a block is a descendent of another // consistent with querying client directly after importing the block. let parent_hash = *block.header.parent_hash(); - let is_descendent_of = is_descendent_of(&self.inner, Some((&hash, &parent_hash))); + let is_descendent_of = is_descendent_of(&*self.inner, Some((&hash, &parent_hash))); let mut guard = InnerGuard { guard: Some(self.authority_set.inner().write()), @@ -333,16 +321,10 @@ where // for the canon block the new authority set should start // with. we use the minimum between the median and the local // best finalized block. - - #[allow(deprecated)] - let best_finalized_number = self.inner.backend().blockchain().info() - .finalized_number; - + let best_finalized_number = self.inner.info().chain.finalized_number; let canon_number = best_finalized_number.min(median_last_finalized_number); - - #[allow(deprecated)] let canon_hash = - self.inner.backend().blockchain().header(BlockId::Number(canon_number)) + self.inner.header(&BlockId::Number(canon_number)) .map_err(|e| ConsensusError::ClientImport(e.to_string()))? .expect("the given block number is less or equal than the current best finalized number; \ current best finalized number must exist in chain; qed.") @@ -394,28 +376,27 @@ where } } -impl, RA, PRA, SC> BlockImport - for GrandpaBlockImport where +impl, RA, SC> BlockImport + for GrandpaBlockImport where NumberFor: grandpa::BlockNumberOps, B: Backend + 'static, E: CallExecutor + 'static + Clone + Send + Sync, DigestFor: Encode, RA: Send + Sync, - PRA: ProvideRuntimeApi, - PRA::Api: GrandpaApi, { type Error = ConsensusError; - fn import_block(&mut self, mut block: BlockImportParams, new_cache: HashMap>) - -> Result - { + fn import_block( + &mut self, + mut block: BlockImportParams, + new_cache: HashMap>, + ) -> Result { let hash = block.post_header().hash(); let number = block.header.number().clone(); // early exit if block already in chain, otherwise the check for // authority changes will error when trying to re-import a change block - #[allow(deprecated)] - match self.inner.backend().blockchain().status(BlockId::Hash(hash)) { + match self.inner.status(BlockId::Hash(hash)) { Ok(blockchain::BlockStatus::InChain) => return Ok(ImportResult::AlreadyInChain), Ok(blockchain::BlockStatus::Unknown) => {}, Err(e) => return Err(ConsensusError::ClientImport(e.to_string()).into()), @@ -425,7 +406,7 @@ impl, RA, PRA, SC> BlockImport // we don't want to finalize on `inner.import_block` let mut justification = block.justification.take(); - let enacts_consensus_change = new_cache.contains_key(&well_known_cache_keys::AUTHORITIES); + let enacts_consensus_change = !new_cache.is_empty(); let import_result = (&*self.inner).import_block(block, new_cache); let mut imported_aux = { @@ -504,6 +485,8 @@ impl, RA, PRA, SC> BlockImport "Imported unjustified block #{} that enacts authority set change, waiting for finality for enactment.", number, ); + + imported_aux.needs_justification = true; } // we have imported block with consensus data changes, but without justification @@ -511,8 +494,6 @@ impl, RA, PRA, SC> BlockImport if enacts_consensus_change { self.consensus_changes.lock().note_change((number, hash)); } - - imported_aux.needs_justification = true; } } @@ -521,15 +502,14 @@ impl, RA, PRA, SC> BlockImport fn check_block( &mut self, - hash: Block::Hash, - parent_hash: Block::Hash, + block: BlockCheckParams, ) -> Result { - self.inner.check_block(hash, parent_hash) + self.inner.check_block(block) } } -impl, RA, PRA, SC> - GrandpaBlockImport +impl, RA, SC> + GrandpaBlockImport { pub(crate) fn new( inner: Arc>, @@ -537,21 +517,19 @@ impl, RA, PRA, SC> authority_set: SharedAuthoritySet>, send_voter_commands: mpsc::UnboundedSender>>, consensus_changes: SharedConsensusChanges>, - api: Arc, - ) -> GrandpaBlockImport { + ) -> GrandpaBlockImport { GrandpaBlockImport { inner, select_chain, authority_set, send_voter_commands, consensus_changes, - api, } } } -impl, RA, PRA, SC> - GrandpaBlockImport +impl, RA, SC> + GrandpaBlockImport where NumberFor: grandpa::BlockNumberOps, B: Backend + 'static, @@ -597,9 +575,8 @@ where info!(target: "finality", "Imported justification for block #{} that triggers \ command {}, signaling voter.", number, command); - if let Err(e) = self.send_voter_commands.unbounded_send(command) { - return Err(ConsensusError::ClientImport(e.to_string()).into()); - } + // send the command to the voter + let _ = self.send_voter_commands.unbounded_send(command); }, Err(CommandOrError::Error(e)) => { return Err(match e { diff --git a/core/finality-grandpa/src/justification.rs b/core/finality-grandpa/src/justification.rs index a6554b1e90d1b8ea3d33689061ed9fa3ebb55524..b4de8ff058684dbba3f452b7c65096143c685bb0 100644 --- a/core/finality-grandpa/src/justification.rs +++ b/core/finality-grandpa/src/justification.rs @@ -18,7 +18,6 @@ use std::collections::{HashMap, HashSet}; use client::{CallExecutor, Client}; use client::backend::Backend; -use client::blockchain::HeaderBackend; use client::error::Error as ClientError; use codec::{Encode, Decode}; use grandpa::voter_set::VoterSet; @@ -71,8 +70,7 @@ impl> GrandpaJustification { loop { if current_hash == commit.target_hash { break; } - #[allow(deprecated)] - match client.backend().blockchain().header(BlockId::Hash(current_hash))? { + match client.header(&BlockId::Hash(current_hash))? { Some(current_header) => { if *current_header.number() <= commit.target_number { return error(); diff --git a/core/finality-grandpa/src/lib.rs b/core/finality-grandpa/src/lib.rs index 5c6835e3bb4df92a0082d0e6327c164eeb49c398..e4b71acbec463243a4adfd56f075efc094a539db 100644 --- a/core/finality-grandpa/src/lib.rs +++ b/core/finality-grandpa/src/lib.rs @@ -68,7 +68,7 @@ use fg_primitives::{GrandpaApi, AuthorityPair}; use keystore::KeyStorePtr; use inherents::InherentDataProviders; use consensus_common::SelectChain; -use primitives::{H256, Blake2Hasher}; +use primitives::{H256, Blake2Hasher, Pair}; use substrate_telemetry::{telemetry, CONSENSUS_INFO, CONSENSUS_DEBUG, CONSENSUS_WARN}; use serde_json; @@ -93,22 +93,17 @@ mod light_import; mod observer; mod until_imported; -#[cfg(feature="service-integration")] -mod service_integration; -#[cfg(feature="service-integration")] -pub use service_integration::{LinkHalfForService, BlockImportForService, BlockImportForLightService}; pub use communication::Network; pub use finality_proof::FinalityProofProvider; pub use light_import::light_block_import; pub use observer::run_grandpa_observer; use aux_schema::PersistentData; -use environment::{Environment, SharedVoterSetState, VoterSetState}; +use environment::{Environment, VoterSetState}; use import::GrandpaBlockImport; use until_imported::UntilGlobalMessageBlocksImported; use communication::NetworkBridge; -use service::TelemetryOnConnect; -use fg_primitives::AuthoritySignature; +use fg_primitives::{AuthoritySignature, SetId, AuthorityWeight}; // Re-export these two because it's just so damn convenient. pub use fg_primitives::{AuthorityId, ScheduledChange}; @@ -267,8 +262,8 @@ impl, RA> BlockStatus for Arc { pub(crate) canon_number: N, pub(crate) canon_hash: H, - pub(crate) set_id: u64, - pub(crate) authorities: Vec<(AuthorityId, u64)>, + pub(crate) set_id: SetId, + pub(crate) authorities: Vec<(AuthorityId, AuthorityWeight)>, } /// Commands issued to the voter. @@ -344,10 +339,10 @@ pub struct LinkHalf, RA, SC> { /// to it. pub fn block_import, RA, PRA, SC>( client: Arc>, - api: Arc, + api: &PRA, select_chain: SC, ) -> Result<( - GrandpaBlockImport, + GrandpaBlockImport, LinkHalf ), ClientError> where @@ -364,8 +359,7 @@ where let genesis_hash = chain_info.chain.genesis_hash; let persistent_data = aux_schema::load_persistent( - #[allow(deprecated)] - &**client.backend(), + &*client, genesis_hash, >::zero(), || { @@ -387,7 +381,6 @@ where persistent_data.authority_set.clone(), voter_commands_tx, persistent_data.consensus_changes.clone(), - api, ), LinkHalf { client, @@ -399,7 +392,7 @@ where } fn global_communication, B, E, N, RA>( - set_id: u64, + set_id: SetId, voters: &Arc>, client: &Arc>, network: &NetworkBridge, @@ -434,6 +427,7 @@ fn global_communication, B, E, N, RA>( client.import_notification_stream(), client.clone(), global_in, + "global", ); let global_in = global_in.map_err(CommandOrError::from); @@ -457,7 +451,7 @@ fn register_finality_tracker_inherent_data_provider ?info.finalized_number, "finalized_hash" => ?info.finalized_hash, @@ -484,7 +478,7 @@ pub struct GrandpaParams, N, RA, SC, X> { /// Handle to a future that will resolve on exit. pub on_exit: X, /// If supplied, can be used to hook on telemetry connection established events. - pub telemetry_on_connect: Option, + pub telemetry_on_connect: Option>, } /// Run a GRANDPA voter as a task. Provide configuration and a link to a @@ -512,8 +506,6 @@ pub fn run_grandpa_voter, N, RA, SC, X>( telemetry_on_connect, } = grandpa_params; - use futures::future::{self, Loop as FutureLoop}; - let LinkHalf { client, select_chain, @@ -521,31 +513,35 @@ pub fn run_grandpa_voter, N, RA, SC, X>( voter_commands_rx, } = link; - let PersistentData { authority_set, set_state, consensus_changes } = persistent_data; - let (network, network_startup) = NetworkBridge::new( network, config.clone(), - set_state.clone(), + persistent_data.set_state.clone(), on_exit.clone(), + true, ); register_finality_tracker_inherent_data_provider(client.clone(), &inherent_data_providers)?; + let conf = config.clone(); let telemetry_task = if let Some(telemetry_on_connect) = telemetry_on_connect { - let authorities = authority_set.clone(); - let events = telemetry_on_connect.telemetry_connection_sinks + let authorities = persistent_data.authority_set.clone(); + let events = telemetry_on_connect .for_each(move |_| { + let curr = authorities.current_authorities(); + let mut auths = curr.voters().into_iter().map(|(p, _)| p); + let maybe_authority_id = authority_id(&mut auths, &conf.keystore) + .unwrap_or(Default::default()); + telemetry!(CONSENSUS_INFO; "afg.authority_set"; - "authority_set_id" => ?authorities.set_id(), - "authorities" => { - let curr = authorities.current_authorities(); - let voters = curr.voters(); - let authorities: Vec = - voters.iter().map(|(id, _)| id.to_string()).collect(); + "authority_id" => maybe_authority_id.to_string(), + "authority_set_id" => ?authorities.set_id(), + "authorities" => { + let authorities: Vec = curr.voters() + .iter().map(|(id, _)| id.to_string()).collect(); serde_json::to_string(&authorities) .expect("authorities is always at least an empty vector; elements are always of type string") - } + } ); Ok(()) }) @@ -555,171 +551,261 @@ pub fn run_grandpa_voter, N, RA, SC, X>( futures::future::Either::B(futures::future::empty()) }; - let voters = authority_set.current_authorities(); - let initial_environment = Arc::new(Environment { - inner: client.clone(), - config: config.clone(), - select_chain: select_chain.clone(), - voters: Arc::new(voters), - network: network.clone(), - set_id: authority_set.set_id(), - authority_set: authority_set.clone(), - consensus_changes: consensus_changes.clone(), - voter_set_state: set_state.clone(), - }); - - let initial_state = (initial_environment, voter_commands_rx.into_future()); - let voter_work = future::loop_fn(initial_state, move |params| { - let (env, voter_commands_rx) = params; - debug!(target: "afg", "{}: Starting new voter with set ID {}", config.name(), env.set_id); + let voter_work = VoterWork::new( + client, + config, + network, + select_chain, + persistent_data, + voter_commands_rx + ); + + let voter_work = voter_work + .map(|_| ()) + .map_err(|e| { + error!("GRANDPA Voter failed: {:?}", e); + telemetry!(CONSENSUS_WARN; "afg.voter_failed"; "e" => ?e); + }); + + let voter_work = network_startup.and_then(move |()| voter_work); + + // Make sure that `telemetry_task` doesn't accidentally finish and kill grandpa. + let telemetry_task = telemetry_task + .then(|_| futures::future::empty::<(), ()>()); + + Ok(voter_work.select(on_exit).select2(telemetry_task).then(|_| Ok(()))) +} + +/// Future that powers the voter. +#[must_use] +struct VoterWork, RA, SC> { + voter: Box>> + Send>, + env: Arc>, + voter_commands_rx: mpsc::UnboundedReceiver>>, +} + +impl VoterWork +where + Block: BlockT, + N: Network + Sync, + N::In: Send + 'static, + NumberFor: BlockNumberOps, + RA: 'static + Send + Sync, + E: CallExecutor + Send + Sync + 'static, + B: Backend + 'static, + SC: SelectChain + 'static, +{ + fn new( + client: Arc>, + config: Config, + network: NetworkBridge, + select_chain: SC, + persistent_data: PersistentData, + voter_commands_rx: mpsc::UnboundedReceiver>>, + ) -> Self { + + let voters = persistent_data.authority_set.current_authorities(); + let env = Arc::new(Environment { + inner: client, + select_chain, + voters: Arc::new(voters), + config, + network, + set_id: persistent_data.authority_set.set_id(), + authority_set: persistent_data.authority_set.clone(), + consensus_changes: persistent_data.consensus_changes.clone(), + voter_set_state: persistent_data.set_state.clone(), + }); + + let mut work = VoterWork { + // `voter` is set to a temporary value and replaced below when + // calling `rebuild_voter`. + voter: Box::new(futures::empty()) as Box<_>, + env, + voter_commands_rx, + }; + work.rebuild_voter(); + work + } + + /// Rebuilds the `self.voter` field using the current authority set + /// state. This method should be called when we know that the authority set + /// has changed (e.g. as signalled by a voter command). + fn rebuild_voter(&mut self) { + debug!(target: "afg", "{}: Starting new voter with set ID {}", self.env.config.name(), self.env.set_id); + + let authority_id = is_voter(&self.env.voters, &self.env.config.keystore) + .map(|ap| ap.public()) + .unwrap_or(Default::default()); + telemetry!(CONSENSUS_DEBUG; "afg.starting_new_voter"; - "name" => ?config.name(), "set_id" => ?env.set_id + "name" => ?self.env.config.name(), + "set_id" => ?self.env.set_id, + "authority_id" => authority_id.to_string(), ); - let mut maybe_voter = match &*env.voter_set_state.read() { - VoterSetState::Live { completed_rounds, .. } => { - let chain_info = client.info(); + let chain_info = self.env.inner.info(); + telemetry!(CONSENSUS_INFO; "afg.authority_set"; + "number" => ?chain_info.chain.finalized_number, + "hash" => ?chain_info.chain.finalized_hash, + "authority_id" => authority_id.to_string(), + "authority_set_id" => ?self.env.set_id, + "authorities" => { + let authorities: Vec = self.env.voters.voters() + .iter().map(|(id, _)| id.to_string()).collect(); + serde_json::to_string(&authorities) + .expect("authorities is always at least an empty vector; elements are always of type string") + }, + ); + match &*self.env.voter_set_state.read() { + VoterSetState::Live { completed_rounds, .. } => { let last_finalized = ( chain_info.chain.finalized_hash, chain_info.chain.finalized_number, ); let global_comms = global_communication( - env.set_id, - &env.voters, - &client, - &network, - &config.keystore, + self.env.set_id, + &self.env.voters, + &self.env.inner, + &self.env.network, + &self.env.config.keystore, ); let last_completed_round = completed_rounds.last(); - Some(voter::Voter::new( - env.clone(), - (*env.voters).clone(), + let voter = voter::Voter::new( + self.env.clone(), + (*self.env.voters).clone(), global_comms, last_completed_round.number, last_completed_round.state.clone(), last_finalized, - )) + ); + + self.voter = Box::new(voter); }, - VoterSetState::Paused { .. } => None, + VoterSetState::Paused { .. } => + self.voter = Box::new(futures::empty()), }; + } - // needs to be combined with another future otherwise it can deadlock. - let poll_voter = future::poll_fn(move || match maybe_voter { - Some(ref mut voter) => voter.poll(), - None => Ok(Async::NotReady), - }); - - let client = client.clone(); - let config = config.clone(); - let network = network.clone(); - let select_chain = select_chain.clone(); - let authority_set = authority_set.clone(); - let consensus_changes = consensus_changes.clone(); - - let handle_voter_command = move |command: VoterCommand<_, _>, voter_commands_rx| { - match command { - VoterCommand::ChangeAuthorities(new) => { - let voters: Vec = new.authorities.iter().map(move |(a, _)| { - format!("{}", a) - }).collect(); - telemetry!(CONSENSUS_INFO; "afg.voter_command_change_authorities"; - "number" => ?new.canon_number, - "hash" => ?new.canon_hash, - "voters" => ?voters, - "set_id" => ?new.set_id, - ); + fn handle_voter_command( + &mut self, + command: VoterCommand> + ) -> Result<(), Error> { + match command { + VoterCommand::ChangeAuthorities(new) => { + let voters: Vec = new.authorities.iter().map(move |(a, _)| { + format!("{}", a) + }).collect(); + telemetry!(CONSENSUS_INFO; "afg.voter_command_change_authorities"; + "number" => ?new.canon_number, + "hash" => ?new.canon_hash, + "voters" => ?voters, + "set_id" => ?new.set_id, + ); + self.env.update_voter_set_state(|_| { // start the new authority set using the block where the // set changed (not where the signal happened!) as the base. let set_state = VoterSetState::live( new.set_id, - &*authority_set.inner().read(), + &*self.env.authority_set.inner().read(), (new.canon_hash, new.canon_number), ); - #[allow(deprecated)] - aux_schema::write_voter_set_state(&**client.backend(), &set_state)?; - - let set_state: SharedVoterSetState<_> = set_state.into(); + aux_schema::write_voter_set_state(&*self.env.inner, &set_state)?; + Ok(Some(set_state)) + })?; + + self.env = Arc::new(Environment { + voters: Arc::new(new.authorities.into_iter().collect()), + set_id: new.set_id, + voter_set_state: self.env.voter_set_state.clone(), + // Fields below are simply transferred and not updated. + inner: self.env.inner.clone(), + select_chain: self.env.select_chain.clone(), + config: self.env.config.clone(), + authority_set: self.env.authority_set.clone(), + consensus_changes: self.env.consensus_changes.clone(), + network: self.env.network.clone(), + }); + + self.rebuild_voter(); + Ok(()) + } + VoterCommand::Pause(reason) => { + info!(target: "afg", "Pausing old validator set: {}", reason); - let env = Arc::new(Environment { - inner: client, - select_chain, - config, - voters: Arc::new(new.authorities.into_iter().collect()), - set_id: new.set_id, - network, - authority_set, - consensus_changes, - voter_set_state: set_state, - }); + // not racing because old voter is shut down. + self.env.update_voter_set_state(|voter_set_state| { + let completed_rounds = voter_set_state.completed_rounds(); + let set_state = VoterSetState::Paused { completed_rounds }; - Ok(FutureLoop::Continue((env, voter_commands_rx))) - } - VoterCommand::Pause(reason) => { - info!(target: "afg", "Pausing old validator set: {}", reason); + aux_schema::write_voter_set_state(&*self.env.inner, &set_state)?; + Ok(Some(set_state)) + })?; - // not racing because old voter is shut down. - env.update_voter_set_state(|voter_set_state| { - let completed_rounds = voter_set_state.completed_rounds(); - let set_state = VoterSetState::Paused { completed_rounds }; + self.rebuild_voter(); + Ok(()) + } + } + } +} - #[allow(deprecated)] - aux_schema::write_voter_set_state(&**client.backend(), &set_state)?; - Ok(Some(set_state)) - })?; +impl Future for VoterWork +where + Block: BlockT, + N: Network + Sync, + N::In: Send + 'static, + NumberFor: BlockNumberOps, + RA: 'static + Send + Sync, + E: CallExecutor + Send + Sync + 'static, + B: Backend + 'static, + SC: SelectChain + 'static, +{ + type Item = (); + type Error = Error; - Ok(FutureLoop::Continue((env, voter_commands_rx))) - }, + fn poll(&mut self) -> Poll { + match self.voter.poll() { + Ok(Async::NotReady) => {} + Ok(Async::Ready(())) => { + // voters don't conclude naturally + return Err(Error::Safety("GRANDPA voter has concluded.".into())) } - }; + Err(CommandOrError::Error(e)) => { + // return inner observer error + return Err(e) + } + Err(CommandOrError::VoterCommand(command)) => { + // some command issued internally + self.handle_voter_command(command)?; + futures::task::current().notify(); + } + } - poll_voter.select2(voter_commands_rx).then(move |res| match res { - Ok(future::Either::A(((), _))) => { - // voters don't conclude naturally - Err(Error::Safety("GRANDPA voter has concluded.".into())) - }, - Err(future::Either::B(_)) => { + match self.voter_commands_rx.poll() { + Ok(Async::NotReady) => {} + Err(_) => { // the `voter_commands_rx` stream should not fail. - Ok(FutureLoop::Break(())) - }, - Ok(future::Either::B(((None, _), _))) => { + return Ok(Async::Ready(())) + } + Ok(Async::Ready(None)) => { // the `voter_commands_rx` stream should never conclude since it's never closed. - Ok(FutureLoop::Break(())) - }, - Err(future::Either::A((CommandOrError::Error(e), _))) => { - // return inner voter error - Err(e) + return Ok(Async::Ready(())) } - Ok(future::Either::B(((Some(command), voter_commands_rx), _))) => { - // some command issued externally. - handle_voter_command(command, voter_commands_rx.into_future()) + Ok(Async::Ready(Some(command))) => { + // some command issued externally + self.handle_voter_command(command)?; + futures::task::current().notify(); } - Err(future::Either::A((CommandOrError::VoterCommand(command), voter_commands_rx))) => { - // some command issued internally. - handle_voter_command(command, voter_commands_rx) - }, - }) - }); - - let voter_work = voter_work - .map(|_| ()) - .map_err(|e| { - error!("GRANDPA Voter failed: {:?}", e); - telemetry!(CONSENSUS_WARN; "afg.voter_failed"; "e" => ?e); - }); - - let voter_work = network_startup.and_then(move |()| voter_work); - - // Make sure that `telemetry_task` doesn't accidentally finish and kill grandpa. - let telemetry_task = telemetry_task - .then(|_| futures::future::empty::<(), ()>()); + } - Ok(voter_work.select(on_exit).select2(telemetry_task).then(|_| Ok(()))) + Ok(Async::NotReady) + } } #[deprecated(since = "1.1", note = "Please switch to run_grandpa_voter.")] @@ -780,3 +866,23 @@ fn is_voter( None => None, } } + +/// Returns the authority id of this node, if available. +fn authority_id<'a, I>( + authorities: &mut I, + keystore: &Option, +) -> Option where + I: Iterator, +{ + match keystore { + Some(keystore) => { + authorities + .find_map(|p| { + keystore.read().key_pair::(&p) + .ok() + .map(|ap| ap.public()) + }) + } + None => None, + } +} diff --git a/core/finality-grandpa/src/light_import.rs b/core/finality-grandpa/src/light_import.rs index 6ecc24bd2bca86803d788af840b44215a242ea3c..30af3a06d3f760fb405900b418be582b2bc17072 100644 --- a/core/finality-grandpa/src/light_import.rs +++ b/core/finality-grandpa/src/light_import.rs @@ -21,22 +21,23 @@ use parking_lot::RwLock; use client::{ CallExecutor, Client, - backend::{AuxStore, Backend}, + backend::{AuxStore, Backend, Finalizer}, blockchain::HeaderBackend, error::Error as ClientError, + well_known_cache_keys, }; use codec::{Encode, Decode}; use consensus_common::{ - import_queue::Verifier, well_known_cache_keys, + import_queue::Verifier, BlockOrigin, BlockImport, FinalityProofImport, BlockImportParams, ImportResult, ImportedAux, - Error as ConsensusError, + BlockCheckParams, Error as ConsensusError, }; use network::config::{BoxFinalityProofRequestBuilder, FinalityProofRequestBuilder}; use sr_primitives::Justification; use sr_primitives::traits::{ NumberFor, Block as BlockT, Header as HeaderT, ProvideRuntimeApi, DigestFor, }; -use fg_primitives::{GrandpaApi, AuthorityId}; +use fg_primitives::{self, GrandpaApi, AuthorityId}; use sr_primitives::generic::BlockId; use primitives::{H256, Blake2Hasher}; @@ -54,6 +55,7 @@ const LIGHT_CONSENSUS_CHANGES_KEY: &[u8] = b"grandpa_consensus_changes"; /// Create light block importer. pub fn light_block_import, RA, PRA>( client: Arc>, + backend: Arc, authority_set_provider: Arc>, api: Arc, ) -> Result, ClientError> @@ -65,10 +67,10 @@ pub fn light_block_import, RA, PRA>( PRA::Api: GrandpaApi, { let info = client.info(); - #[allow(deprecated)] - let import_data = load_aux_import_data(info.chain.finalized_hash, &**client.backend(), api)?; + let import_data = load_aux_import_data(info.chain.finalized_hash, &*client, api)?; Ok(GrandpaLightBlockImport { client, + backend, authority_set_provider, data: Arc::new(RwLock::new(import_data)), }) @@ -81,6 +83,7 @@ pub fn light_block_import, RA, PRA>( /// - fetching finality proofs for blocks that are enacting consensus changes. pub struct GrandpaLightBlockImport, RA> { client: Arc>, + backend: Arc, authority_set_provider: Arc>, data: Arc>>, } @@ -89,6 +92,7 @@ impl, RA> Clone for GrandpaLightBlockImport Self { GrandpaLightBlockImport { client: self.client.clone(), + backend: self.backend.clone(), authority_set_provider: self.authority_set_provider.clone(), data: self.data.clone(), } @@ -131,17 +135,16 @@ impl, RA> BlockImport block: BlockImportParams, new_cache: HashMap>, ) -> Result { - do_import_block::<_, _, _, _, GrandpaJustification>( + do_import_block::<_, _, _, GrandpaJustification>( &*self.client, &mut *self.data.write(), block, new_cache ) } fn check_block( &mut self, - hash: Block::Hash, - parent_hash: Block::Hash, + block: BlockCheckParams, ) -> Result { - self.client.check_block(hash, parent_hash) + self.client.check_block(block) } } @@ -176,8 +179,9 @@ impl, RA> FinalityProofImport finality_proof: Vec, verifier: &mut dyn Verifier, ) -> Result<(Block::Hash, NumberFor), Self::Error> { - do_import_finality_proof::<_, _, _, _, GrandpaJustification>( + do_import_finality_proof::<_, _, _, GrandpaJustification>( &*self.client, + self.backend.clone(), &*self.authority_set_provider, &mut *self.data.write(), hash, @@ -192,7 +196,7 @@ impl LightAuthoritySet { /// Get a genesis set with given authorities. pub fn genesis(initial: Vec<(AuthorityId, u64)>) -> Self { LightAuthoritySet { - set_id: 0, + set_id: fg_primitives::SetId::default(), authorities: initial, } } @@ -227,16 +231,19 @@ impl> FinalityProofRequestBuilder for GrandpaFinalityPro } /// Try to import new block. -fn do_import_block, RA, J>( - mut client: &Client, +fn do_import_block, J>( + mut client: C, data: &mut LightImportData, mut block: BlockImportParams, new_cache: HashMap>, ) -> Result where + C: HeaderBackend + + AuxStore + + Finalizer + + BlockImport + + Clone, B: Backend + 'static, - E: CallExecutor + 'static + Clone + Send + Sync, - RA: Send + Sync, NumberFor: grandpa::BlockNumberOps, DigestFor: Encode, J: ProvableJustification, @@ -246,8 +253,8 @@ fn do_import_block, RA, J>( // we don't want to finalize on `inner.import_block` let justification = block.justification.take(); - let enacts_consensus_change = new_cache.contains_key(&well_known_cache_keys::AUTHORITIES); - let import_result = BlockImport::import_block(&mut client, block, new_cache); + let enacts_consensus_change = !new_cache.is_empty(); + let import_result = client.import_block(block, new_cache); let mut imported_aux = match import_result { Ok(ImportResult::Imported(aux)) => aux, @@ -264,7 +271,7 @@ fn do_import_block, RA, J>( hash, ); - do_import_justification::<_, _, _, _, J>(client, data, hash, number, justification) + do_import_justification::<_, _, _, J>(client, data, hash, number, justification) }, None if enacts_consensus_change => { trace!( @@ -283,8 +290,9 @@ fn do_import_block, RA, J>( } /// Try to import finality proof. -fn do_import_finality_proof, RA, J>( - client: &Client, +fn do_import_finality_proof, J>( + client: C, + backend: Arc, authority_set_provider: &dyn AuthoritySetForFinalityChecker, data: &mut LightImportData, _hash: Block::Hash, @@ -293,9 +301,12 @@ fn do_import_finality_proof, RA, J>( verifier: &mut dyn Verifier, ) -> Result<(Block::Hash, NumberFor), ConsensusError> where + C: HeaderBackend + + AuxStore + + Finalizer + + BlockImport + + Clone, B: Backend + 'static, - E: CallExecutor + 'static + Clone + Send + Sync, - RA: Send + Sync, DigestFor: Encode, NumberFor: grandpa::BlockNumberOps, J: ProvableJustification, @@ -303,8 +314,7 @@ fn do_import_finality_proof, RA, J>( let authority_set_id = data.authority_set.set_id(); let authorities = data.authority_set.authorities(); let finality_effects = crate::finality_proof::check_finality_proof( - #[allow(deprecated)] - &*client.backend().blockchain(), + backend.blockchain(), authority_set_id, authorities, authority_set_provider, @@ -322,13 +332,12 @@ fn do_import_finality_proof, RA, J>( if let Some(authorities) = new_authorities { cache.insert(well_known_cache_keys::AUTHORITIES, authorities.encode()); } - do_import_block::<_, _, _, _, J>(client, data, block_to_import, cache)?; + do_import_block::<_, _, _, J>(client.clone(), data, block_to_import, cache)?; } // try to import latest justification let finalized_block_hash = finality_effects.block; - #[allow(deprecated)] - let finalized_block_number = client.backend().blockchain() + let finalized_block_number = backend.blockchain() .expect_block_number_from_id(&BlockId::Hash(finality_effects.block)) .map_err(|e| ConsensusError::ClientImport(e.to_string()))?; do_finalize_block( @@ -349,17 +358,19 @@ fn do_import_finality_proof, RA, J>( } /// Try to import justification. -fn do_import_justification, RA, J>( - client: &Client, +fn do_import_justification, J>( + client: C, data: &mut LightImportData, hash: Block::Hash, number: NumberFor, justification: Justification, ) -> Result where + C: HeaderBackend + + AuxStore + + Finalizer + + Clone, B: Backend + 'static, - E: CallExecutor + 'static + Clone + Send + Sync, - RA: Send + Sync, NumberFor: grandpa::BlockNumberOps, J: ProvableJustification, { @@ -418,17 +429,19 @@ fn do_import_justification, RA, J>( } /// Finalize the block. -fn do_finalize_block, RA>( - client: &Client, +fn do_finalize_block>( + client: C, data: &mut LightImportData, hash: Block::Hash, number: NumberFor, justification: Justification, ) -> Result where + C: HeaderBackend + + AuxStore + + Finalizer + + Clone, B: Backend + 'static, - E: CallExecutor + 'static + Clone + Send + Sync, - RA: Send + Sync, NumberFor: grandpa::BlockNumberOps, { // finalize the block @@ -439,7 +452,7 @@ fn do_finalize_block, RA>( // forget obsoleted consensus changes let consensus_finalization_res = data.consensus_changes - .finalize((number, hash), |at_height| canonical_at_height(&client, (hash, number), true, at_height)); + .finalize((number, hash), |at_height| canonical_at_height(client.clone(), (hash, number), true, at_height)); match consensus_finalization_res { Ok((true, _)) => require_insert_aux( &client, @@ -454,7 +467,8 @@ fn do_finalize_block, RA>( // update last finalized block reference data.last_finalized = hash; - Ok(ImportResult::imported()) + // we just finalized this block, so if we were importing it, it is now the new best + Ok(ImportResult::imported(true)) } /// Load light import aux data from the store. @@ -506,20 +520,14 @@ fn load_aux_import_data, PRA>( } /// Insert into aux store. If failed, return error && show inconsistency warning. -fn require_insert_aux, RA>( - client: &Client, +fn require_insert_aux( + store: &A, key: &[u8], value: &T, value_type: &str, -) -> Result<(), ConsensusError> - where - B: Backend + 'static, - E: CallExecutor + 'static + Clone + Send + Sync, -{ - #[allow(deprecated)] - let backend = &**client.backend(); +) -> Result<(), ConsensusError> { let encoded = value.encode(); - let update_res = Backend::insert_aux(backend, &[(key, &encoded[..])], &[]); + let update_res = store.insert_aux(&[(key, &encoded[..])], &[]); if let Err(error) = update_res { return Err(on_post_finalization_error(error, value_type)); } @@ -582,10 +590,9 @@ pub mod tests { fn check_block( &mut self, - hash: Block::Hash, - parent_hash: Block::Hash, + block: BlockCheckParams, ) -> Result { - self.0.check_block(hash, parent_hash) + self.0.check_block(block) } } @@ -617,6 +624,7 @@ pub mod tests { /// Creates light block import that ignores justifications that came outside of finality proofs. pub fn light_block_import_without_justifications, RA, PRA>( client: Arc>, + backend: Arc, authority_set_provider: Arc>, api: Arc, ) -> Result, ClientError> @@ -627,14 +635,14 @@ pub mod tests { PRA: ProvideRuntimeApi, PRA::Api: GrandpaApi, { - light_block_import(client, authority_set_provider, api).map(NoJustificationsImport) + light_block_import(client, backend, authority_set_provider, api).map(NoJustificationsImport) } fn import_block( new_cache: HashMap>, justification: Option, ) -> ImportResult { - let client = test_client::new_light(); + let (client, _backend) = test_client::new_light(); let mut import_data = LightImportData { last_finalized: Default::default(), authority_set: LightAuthoritySet::genesis(vec![(AuthorityId::from_slice(&[1; 32]), 1)]), @@ -656,7 +664,7 @@ pub mod tests { auxiliary: Vec::new(), fork_choice: ForkChoiceStrategy::LongestChain, }; - do_import_block::<_, _, _, _, TestJustification>( + do_import_block::<_, _, _, TestJustification>( &client, &mut import_data, block, @@ -671,6 +679,7 @@ pub mod tests { needs_justification: false, bad_justification: false, needs_finality_proof: false, + is_new_best: true, })); } @@ -682,6 +691,7 @@ pub mod tests { needs_justification: false, bad_justification: false, needs_finality_proof: false, + is_new_best: true, })); } @@ -694,6 +704,7 @@ pub mod tests { needs_justification: false, bad_justification: false, needs_finality_proof: true, + is_new_best: true, })); } @@ -709,6 +720,7 @@ pub mod tests { needs_justification: false, bad_justification: false, needs_finality_proof: true, + is_new_best: false, }, )); } diff --git a/core/finality-grandpa/src/observer.rs b/core/finality-grandpa/src/observer.rs index bce292262e028792aeb5a02a2796e052b3a45ef2..39eeafcb1b141ebedc0f40087b05e5bb197ad51b 100644 --- a/core/finality-grandpa/src/observer.rs +++ b/core/finality-grandpa/src/observer.rs @@ -175,8 +175,10 @@ pub fn run_grandpa_observer, N, RA, SC>( network, config.clone(), persistent_data.set_state.clone(), - on_exit.clone() + on_exit.clone(), + false, ); + let observer_work = ObserverWork::new( client, network, @@ -299,8 +301,7 @@ where let completed_rounds = self.persistent_data.set_state.read().completed_rounds(); let set_state = VoterSetState::Paused { completed_rounds }; - #[allow(deprecated)] - crate::aux_schema::write_voter_set_state(&**self.client.backend(), &set_state)?; + crate::aux_schema::write_voter_set_state(&*self.client, &set_state)?; set_state }, @@ -313,8 +314,7 @@ where (new.canon_hash, new.canon_number), ); - #[allow(deprecated)] - crate::aux_schema::write_voter_set_state(&**self.client.backend(), &set_state)?; + crate::aux_schema::write_voter_set_state(&*self.client, &set_state)?; set_state }, diff --git a/core/finality-grandpa/src/service_integration.rs b/core/finality-grandpa/src/service_integration.rs deleted file mode 100644 index 9f19b9204190bdcc16f3766db3c20a400ed40331..0000000000000000000000000000000000000000 --- a/core/finality-grandpa/src/service_integration.rs +++ /dev/null @@ -1,49 +0,0 @@ -// Copyright 2018-2019 Parity Technologies (UK) Ltd. -// This file is part of Substrate. - -// Substrate 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. - -// Substrate 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 Substrate. If not, see . - -/// Integrate grandpa finality with substrate service - -use client; -use service::{FullBackend, FullExecutor, LightBackend, LightExecutor, ServiceFactory}; - -pub type BlockImportForService = crate::GrandpaBlockImport< - FullBackend, - FullExecutor, - ::Block, - ::RuntimeApi, - client::Client< - FullBackend, - FullExecutor, - ::Block, - ::RuntimeApi - >, - ::SelectChain, ->; - -pub type LinkHalfForService = crate::LinkHalf< - FullBackend, - FullExecutor, - ::Block, - ::RuntimeApi, - ::SelectChain ->; - -pub type BlockImportForLightService = crate::light_import::GrandpaLightBlockImport< - LightBackend, - LightExecutor, - ::Block, - ::RuntimeApi, ->; diff --git a/core/finality-grandpa/src/tests.rs b/core/finality-grandpa/src/tests.rs index bbaae1e9b7e018929cb55c367327e35a97818d3c..1957ab5c4fbb35abcb0b6232153dbd420ecc32c3 100644 --- a/core/finality-grandpa/src/tests.rs +++ b/core/finality-grandpa/src/tests.rs @@ -37,9 +37,9 @@ use std::collections::{HashMap, HashSet}; use std::result; use codec::Decode; use sr_primitives::traits::{ApiRef, ProvideRuntimeApi, Header as HeaderT}; -use sr_primitives::generic::BlockId; +use sr_primitives::generic::{BlockId, DigestItem}; use primitives::{NativeOrEncoded, ExecutionContext, crypto::Public}; -use fg_primitives::AuthorityId; +use fg_primitives::{GRANDPA_ENGINE_ID, AuthorityId}; use authorities::AuthoritySet; use finality_proof::{FinalityProofProvider, AuthoritySetForFinalityProver, AuthoritySetForFinalityChecker}; @@ -98,7 +98,12 @@ impl TestNetFactory for GrandpaTestNet { } } - fn make_verifier(&self, _client: PeersClient, _cfg: &ProtocolConfig) -> Self::Verifier { + fn make_verifier( + &self, + _client: PeersClient, + _cfg: &ProtocolConfig, + _: &PeerData, + ) -> Self::Verifier { PassThroughVerifier(false) // use non-instant finality. } @@ -112,21 +117,17 @@ impl TestNetFactory for GrandpaTestNet { ) { match client { - PeersClient::Full(ref client) => { - #[allow(deprecated)] - let select_chain = LongestChain::new( - client.backend().clone() - ); + PeersClient::Full(ref client, ref backend) => { let (import, link) = block_import( client.clone(), - Arc::new(self.test_config.clone()), - select_chain, + &self.test_config, + LongestChain::new(backend.clone()), ).expect("Could not create block import for fresh peer."); let justification_import = Box::new(import.clone()); let block_import = Box::new(import); (block_import, Some(justification_import), None, None, Mutex::new(Some(link))) }, - PeersClient::Light(ref client) => { + PeersClient::Light(ref client, ref backend) => { use crate::light_import::tests::light_block_import_without_justifications; let authorities_provider = Arc::new(self.test_config.clone()); @@ -134,6 +135,7 @@ impl TestNetFactory for GrandpaTestNet { // => light clients will try to fetch finality proofs let import = light_block_import_without_justifications( client.clone(), + backend.clone(), authorities_provider, Arc::new(self.test_config.clone()) ).expect("Could not create block import for fresh peer."); @@ -150,11 +152,11 @@ impl TestNetFactory for GrandpaTestNet { client: PeersClient ) -> Option>> { match client { - PeersClient::Full(ref client) => { + PeersClient::Full(_, ref backend) => { let authorities_provider = Arc::new(self.test_config.clone()); - Some(Arc::new(FinalityProofProvider::new(client.clone(), authorities_provider))) + Some(Arc::new(FinalityProofProvider::new(backend.clone(), authorities_provider))) }, - PeersClient::Light(_) => None, + PeersClient::Light(_, _) => None, } } @@ -186,16 +188,12 @@ impl Future for Exit { #[derive(Default, Clone)] pub(crate) struct TestApi { genesis_authorities: Vec<(AuthorityId, u64)>, - scheduled_changes: Arc>>>, - forced_changes: Arc)>>>, } impl TestApi { pub fn new(genesis_authorities: Vec<(AuthorityId, u64)>) -> Self { TestApi { genesis_authorities, - scheduled_changes: Arc::new(Mutex::new(HashMap::new())), - forced_changes: Arc::new(Mutex::new(HashMap::new())), } } } @@ -275,41 +273,6 @@ impl GrandpaApi for RuntimeApi { ) -> Result>> { Ok(self.inner.genesis_authorities.clone()).map(NativeOrEncoded::Native) } - - fn GrandpaApi_grandpa_pending_change_runtime_api_impl( - &self, - at: &BlockId, - _: ExecutionContext, - _: Option<(&DigestFor)>, - _: Vec, - ) -> Result>>>> { - let parent_hash = match at { - &BlockId::Hash(at) => at, - _ => panic!("not requested by block hash!!"), - }; - - // we take only scheduled changes at given block number where there are no - // extrinsics. - Ok(self.inner.scheduled_changes.lock().get(&parent_hash).map(|c| c.clone())).map(NativeOrEncoded::Native) - } - - fn GrandpaApi_grandpa_forced_change_runtime_api_impl( - &self, - at: &BlockId, - _: ExecutionContext, - _: Option<(&DigestFor)>, - _: Vec, - ) - -> Result, ScheduledChange>)>>> { - let parent_hash = match at { - &BlockId::Hash(at) => at, - _ => panic!("not requested by block hash!!"), - }; - - // we take only scheduled changes at given block number where there are no - // extrinsics. - Ok(self.inner.forced_changes.lock().get(&parent_hash).map(|c| c.clone())).map(NativeOrEncoded::Native) - } } impl AuthoritySetForFinalityProver for TestApi { @@ -451,6 +414,24 @@ fn run_to_completion( run_to_completion_with(runtime, blocks, net, peers, |_| None) } +fn add_scheduled_change(block: &mut Block, change: ScheduledChange) { + block.header.digest_mut().push(DigestItem::Consensus( + GRANDPA_ENGINE_ID, + fg_primitives::ConsensusLog::ScheduledChange(change).encode(), + )); +} + +fn add_forced_change( + block: &mut Block, + median_last_finalized: BlockNumber, + change: ScheduledChange, +) { + block.header.digest_mut().push(DigestItem::Consensus( + GRANDPA_ENGINE_ID, + fg_primitives::ConsensusLog::ForcedChange(median_last_finalized, change).encode(), + )); +} + #[test] fn finalize_3_voters_no_observers() { let _ = env_logger::try_init(); @@ -576,7 +557,6 @@ fn transition_3_voters_twice_1_full_observer() { let genesis_voters = make_ids(peers_a); let api = TestApi::new(genesis_voters); - let transitions = api.scheduled_changes.clone(); let net = Arc::new(Mutex::new(GrandpaTestNet::new(api, 8))); let mut runtime = current_thread::Runtime::new().unwrap(); @@ -589,10 +569,7 @@ fn transition_3_voters_twice_1_full_observer() { assert_eq!(full_client.info().chain.best_number, 1, "Peer #{} failed to sync", i); - let set: AuthoritySet = crate::aux_schema::load_authorities( - #[allow(deprecated)] - &**full_client.backend() - ).unwrap(); + let set: AuthoritySet = crate::aux_schema::load_authorities(&*full_client).unwrap(); assert_eq!(set.current(), (0, make_ids(peers_a).as_slice())); assert_eq!(set.pending_changes().count(), 0); @@ -601,10 +578,6 @@ fn transition_3_voters_twice_1_full_observer() { { let net = net.clone(); let client = net.lock().peers[0].client().clone(); - let transitions = transitions.clone(); - let add_transition = move |parent_hash, change| { - transitions.lock().insert(parent_hash, change); - }; let peers_c = peers_c.clone(); // wait for blocks to be finalized before generating new ones @@ -620,8 +593,8 @@ fn transition_3_voters_twice_1_full_observer() { 14 => { // generate transition at block 15, applied at 20. net.lock().peer(0).generate_blocks(1, BlockOrigin::File, |builder| { - let block = builder.bake().unwrap(); - add_transition(*block.header.parent_hash(), ScheduledChange { + let mut block = builder.bake().unwrap(); + add_scheduled_change(&mut block, ScheduledChange { next_authorities: make_ids(peers_b), delay: 4, }); @@ -634,8 +607,8 @@ fn transition_3_voters_twice_1_full_observer() { // at block 21 we do another transition, but this time instant. // add more until we have 30. net.lock().peer(0).generate_blocks(1, BlockOrigin::File, |builder| { - let block = builder.bake().unwrap(); - add_transition(*block.header.parent_hash(), ScheduledChange { + let mut block = builder.bake().unwrap(); + add_scheduled_change(&mut block, ScheduledChange { next_authorities: make_ids(&peers_c), delay: 0, }); @@ -685,10 +658,7 @@ fn transition_3_voters_twice_1_full_observer() { .for_each(move |_| Ok(())) .map(move |()| { let full_client = client.as_full().expect("only full clients are used in test"); - let set: AuthoritySet = crate::aux_schema::load_authorities( - #[allow(deprecated)] - &**full_client.backend() - ).unwrap(); + let set: AuthoritySet = crate::aux_schema::load_authorities(&*full_client).unwrap(); assert_eq!(set.current(), (2, make_ids(peers_c).as_slice())); assert_eq!(set.pending_changes().count(), 0); @@ -787,7 +757,6 @@ fn sync_justifications_on_change_blocks() { // 4 peers, 3 of them are authorities and participate in grandpa let api = TestApi::new(voters); - let transitions = api.scheduled_changes.clone(); let mut net = GrandpaTestNet::new(api, 4); // add 20 blocks @@ -795,8 +764,8 @@ fn sync_justifications_on_change_blocks() { // at block 21 we do add a transition which is instant net.peer(0).generate_blocks(1, BlockOrigin::File, |builder| { - let block = builder.bake().unwrap(); - transitions.lock().insert(*block.header.parent_hash(), ScheduledChange { + let mut block = builder.bake().unwrap(); + add_scheduled_change(&mut block, ScheduledChange { next_authorities: make_ids(peers_b), delay: 0, }); @@ -849,7 +818,6 @@ fn finalizes_multiple_pending_changes_in_order() { // 6 peers, 3 of them are authorities and participate in grandpa from genesis let api = TestApi::new(genesis_voters); - let transitions = api.scheduled_changes.clone(); let mut net = GrandpaTestNet::new(api, 6); // add 20 blocks @@ -857,8 +825,8 @@ fn finalizes_multiple_pending_changes_in_order() { // at block 21 we do add a transition which is instant net.peer(0).generate_blocks(1, BlockOrigin::File, |builder| { - let block = builder.bake().unwrap(); - transitions.lock().insert(*block.header.parent_hash(), ScheduledChange { + let mut block = builder.bake().unwrap(); + add_scheduled_change(&mut block, ScheduledChange { next_authorities: make_ids(peers_b), delay: 0, }); @@ -870,8 +838,8 @@ fn finalizes_multiple_pending_changes_in_order() { // at block 26 we add another which is enacted at block 30 net.peer(0).generate_blocks(1, BlockOrigin::File, |builder| { - let block = builder.bake().unwrap(); - transitions.lock().insert(*block.header.parent_hash(), ScheduledChange { + let mut block = builder.bake().unwrap(); + add_scheduled_change(&mut block, ScheduledChange { next_authorities: make_ids(peers_c), delay: 4, }); @@ -933,27 +901,26 @@ fn force_change_to_new_set() { let api = TestApi::new(make_ids(genesis_authorities)); let voters = make_ids(peers_a); - let normal_transitions = api.scheduled_changes.clone(); - let forced_transitions = api.forced_changes.clone(); let net = GrandpaTestNet::new(api, 3); let net = Arc::new(Mutex::new(net)); - net.lock().peer(0).push_blocks(1, false); + net.lock().peer(0).generate_blocks(1, BlockOrigin::File, |builder| { + let mut block = builder.bake().unwrap(); - { // add a forced transition at block 12. - let parent_hash = net.lock().peer(0).client().info().chain.best_hash; - forced_transitions.lock().insert(parent_hash, (0, ScheduledChange { + add_forced_change(&mut block, 0, ScheduledChange { next_authorities: voters.clone(), delay: 10, - })); + }); // add a normal transition too to ensure that forced changes take priority. - normal_transitions.lock().insert(parent_hash, ScheduledChange { + add_scheduled_change(&mut block, ScheduledChange { next_authorities: make_ids(genesis_authorities), delay: 5, }); - } + + block + }); net.lock().peer(0).push_blocks(25, false); net.lock().block_until_sync(&mut runtime); @@ -963,10 +930,7 @@ fn force_change_to_new_set() { "Peer #{} failed to sync", i); let full_client = peer.client().as_full().expect("only full clients are used in test"); - let set: AuthoritySet = crate::aux_schema::load_authorities( - #[allow(deprecated)] - &**full_client.backend() - ).unwrap(); + let set: AuthoritySet = crate::aux_schema::load_authorities(&*full_client).unwrap(); assert_eq!(set.current(), (1, voters.as_slice())); assert_eq!(set.pending_changes().count(), 0); @@ -991,8 +955,8 @@ fn allows_reimporting_change_blocks() { let full_client = client.as_full().unwrap(); let builder = full_client.new_block_at(&BlockId::Number(0), Default::default()).unwrap(); - let block = builder.bake().unwrap(); - api.scheduled_changes.lock().insert(*block.header.parent_hash(), ScheduledChange { + let mut block = builder.bake().unwrap(); + add_scheduled_change(&mut block, ScheduledChange { next_authorities: make_ids(peers_b), delay: 0, }); @@ -1018,6 +982,7 @@ fn allows_reimporting_change_blocks() { clear_justification_requests: false, bad_justification: false, needs_finality_proof: false, + is_new_best: true, }), ); @@ -1040,8 +1005,9 @@ fn test_bad_justification() { let full_client = client.as_full().expect("only full clients are used in test"); let builder = full_client.new_block_at(&BlockId::Number(0), Default::default()).unwrap(); - let block = builder.bake().unwrap(); - api.scheduled_changes.lock().insert(*block.header.parent_hash(), ScheduledChange { + let mut block = builder.bake().unwrap(); + + add_scheduled_change(&mut block, ScheduledChange { next_authorities: make_ids(peers_b), delay: 0, }); @@ -1066,6 +1032,7 @@ fn test_bad_justification() { needs_justification: true, clear_justification_requests: false, bad_justification: true, + is_new_best: true, ..Default::default() }), ); @@ -1099,9 +1066,13 @@ fn voter_persists_its_votes() { assert_eq!(net.peer(0).client().info().chain.best_number, 20, "Peer #{} failed to sync", 0); - let client = net.peer(0).client().clone(); + + let peer = net.peer(0); + let client = peer.client().clone(); let net = Arc::new(Mutex::new(net)); + // channel between the voter and the main controller. + // sending a message on the `voter_tx` restarts the voter. let (voter_tx, voter_rx) = mpsc::unbounded::<()>(); let mut keystore_paths = Vec::new(); @@ -1110,61 +1081,79 @@ fn voter_persists_its_votes() { // channel. whenever a message is received the voter is restarted. when the // sender is dropped the voter is stopped. { - let net = net.clone(); - let client = client.clone(); - let (keystore, keystore_path) = create_keystore(peers[0]); keystore_paths.push(keystore_path); - let voter = future::loop_fn(voter_rx, move |rx| { - let (_block_import, _, _, _, link) = net.lock().make_block_import(client.clone()); - let link = link.lock().take().unwrap(); + struct ResettableVoter { + voter: Box + Send>, + voter_rx: mpsc::UnboundedReceiver<()>, + net: Arc>, + client: PeersClient, + keystore: KeyStorePtr, + } - let grandpa_params = GrandpaParams { - config: Config { - gossip_duration: TEST_GOSSIP_DURATION, - justification_period: 32, - keystore: Some(keystore.clone()), - name: Some(format!("peer#{}", 0)), - }, - link, - network: net.lock().peers[0].network_service().clone(), - inherent_data_providers: InherentDataProviders::new(), - on_exit: Exit, - telemetry_on_connect: None, - }; + impl Future for ResettableVoter { + type Item = (); + type Error = (); - let voter = run_grandpa_voter(grandpa_params) - .expect("all in order with client and network") - .then(move |r| { - // we need to keep the block_import alive since it owns the - // sender for the voter commands channel, if that gets dropped - // then the voter will stop - drop(_block_import); - r - }); - - voter.select2(rx.into_future()).then(|res| match res { - Ok(future::Either::A(x)) => { - panic!("voter stopped unexpectedly: {:?}", x); - }, - Ok(future::Either::B(((Some(()), rx), _))) => { - Ok(future::Loop::Continue(rx)) - }, - Ok(future::Either::B(((None, _), _))) => { - Ok(future::Loop::Break(())) - }, - Err(future::Either::A(err)) => { - panic!("unexpected error: {:?}", err); - }, - Err(future::Either::B(..)) => { - // voter_rx dropped, stop the voter. - Ok(future::Loop::Break(())) - }, - }) - }); + fn poll(&mut self) -> Poll { + match self.voter.poll() { + Ok(Async::Ready(())) | Err(_) => panic!("error in the voter"), + Ok(Async::NotReady) => {}, + } - runtime.spawn(voter); + match self.voter_rx.poll() { + Err(_) | Ok(Async::Ready(None)) => return Ok(Async::Ready(())), + Ok(Async::NotReady) => {} + Ok(Async::Ready(Some(()))) => { + let (_block_import, _, _, _, link) = + self.net.lock().make_block_import(self.client.clone()); + let link = link.lock().take().unwrap(); + + let grandpa_params = GrandpaParams { + config: Config { + gossip_duration: TEST_GOSSIP_DURATION, + justification_period: 32, + keystore: Some(self.keystore.clone()), + name: Some(format!("peer#{}", 0)), + }, + link, + network: self.net.lock().peers[0].network_service().clone(), + inherent_data_providers: InherentDataProviders::new(), + on_exit: Exit, + telemetry_on_connect: None, + }; + + let voter = run_grandpa_voter(grandpa_params) + .expect("all in order with client and network") + .then(move |r| { + // we need to keep the block_import alive since it owns the + // sender for the voter commands channel, if that gets dropped + // then the voter will stop + drop(_block_import); + r + }); + + self.voter = Box::new(voter); + // notify current task in order to poll the voter + futures::task::current().notify(); + } + }; + + Ok(Async::NotReady) + } + } + + // we create a "dummy" voter by setting it to `empty` and triggering the `tx`. + // this way, the `ResettableVoter` will reset its `voter` field to a value ASAP. + voter_tx.unbounded_send(()).unwrap(); + runtime.spawn(ResettableVoter { + voter: Box::new(futures::future::empty()), + voter_rx, + net: net.clone(), + client: client.clone(), + keystore, + }); } let (exit_tx, exit_rx) = futures::sync::oneshot::channel::<()>(); @@ -1195,6 +1184,7 @@ fn voter_persists_its_votes() { config.clone(), set_state, Exit, + true, ); runtime.block_on(routing_work).unwrap(); @@ -1237,9 +1227,8 @@ fn voter_persists_its_votes() { }) .for_each(|_| Ok(())) .and_then(move |_| { - #[allow(deprecated)] let block_30_hash = - net.lock().peer(0).client().as_full().unwrap().backend().blockchain().hash(30).unwrap().unwrap(); + net.lock().peer(0).client().as_full().unwrap().hash(30).unwrap().unwrap(); // we restart alice's voter voter_tx.unbounded_send(()).unwrap(); @@ -1396,20 +1385,21 @@ fn empty_finality_proof_is_returned_to_light_client_when_authority_set_is_differ let api = TestApi::new(make_ids(&genesis_authorities)); let voters = make_ids(peers_a); - let forced_transitions = api.forced_changes.clone(); let net = GrandpaTestNet::new(api, 3); let net = Arc::new(Mutex::new(net)); - net.lock().peer(0).push_blocks(1, false); // best is #1 - - // add a forced transition at block 5. - if FORCE_CHANGE { - let parent_hash = net.lock().peer(0).client().info().chain.best_hash; - forced_transitions.lock().insert(parent_hash, (0, ScheduledChange { - next_authorities: voters.clone(), - delay: 3, - })); - } + // best is #1 + net.lock().peer(0).generate_blocks(1, BlockOrigin::File, |builder| { + // add a forced transition at block 5. + let mut block = builder.bake().unwrap(); + if FORCE_CHANGE { + add_forced_change(&mut block, 0, ScheduledChange { + next_authorities: voters.clone(), + delay: 3, + }); + } + block + }); // ensure block#10 enacts authorities set change => justification is generated // normally it will reach light client, but because of the forced change, it will not diff --git a/core/finality-grandpa/src/until_imported.rs b/core/finality-grandpa/src/until_imported.rs index af797c99ab39bdda781ee6d1fecfb4d781573746..b8568c1f8510b0f335e494a160ac3a34b9962fe2 100644 --- a/core/finality-grandpa/src/until_imported.rs +++ b/core/finality-grandpa/src/until_imported.rs @@ -71,6 +71,7 @@ pub(crate) struct UntilImported, check_pending: Interval, pending: HashMap)>, + identifier: &'static str, } impl UntilImported @@ -81,6 +82,7 @@ impl UntilImported import_notifications: ImportNotifications, status_check: Status, stream: I, + identifier: &'static str, ) -> Self { // how often to check if pending messages that are waiting for blocks to be // imported can be checked. @@ -101,6 +103,7 @@ impl UntilImported ready: VecDeque::new(), check_pending, pending: HashMap::new(), + identifier, } } } @@ -170,8 +173,9 @@ impl Stream for UntilImported if Instant::now() <= next_log { debug!( target: "afg", - "Waiting to import block {} before {} votes can be imported. \ + "Waiting to import block {} before {} {} messages can be imported. \ Possible fork?", + self.identifier, block_hash, v.len(), ); @@ -472,6 +476,7 @@ mod tests { origin: BlockOrigin::File, header, is_new_best: false, + retracted: vec![], }).unwrap(); } } @@ -532,6 +537,7 @@ mod tests { import_notifications, block_status, global_rx.map_err(|_| panic!("should never error")), + "global", ); global_tx.unbounded_send(msg).unwrap(); @@ -557,6 +563,7 @@ mod tests { import_notifications, block_status, global_rx.map_err(|_| panic!("should never error")), + "global", ); global_tx.unbounded_send(msg).unwrap(); diff --git a/core/keyring/Cargo.toml b/core/keyring/Cargo.toml index 1a58dc133e35891acc816082dc3ae36eab089de9..0147689985fa95b7565a07e3e94893dd63a165e7 100644 --- a/core/keyring/Cargo.toml +++ b/core/keyring/Cargo.toml @@ -7,6 +7,6 @@ edition = "2018" [dependencies] primitives = { package = "substrate-primitives", path = "../primitives" } sr-primitives = { path = "../sr-primitives" } -lazy_static = { version = "1.0" } +lazy_static = "1.4.0" strum = "0.15.0" strum_macros = "0.15.0" diff --git a/core/keystore/Cargo.toml b/core/keystore/Cargo.toml index c56b9ba67dcbdf055697fac19b56c0ad97b16274..ff5696ab374b7130f05db0714991c739fb52be3e 100644 --- a/core/keystore/Cargo.toml +++ b/core/keystore/Cargo.toml @@ -8,11 +8,11 @@ edition = "2018" derive_more = "0.15.0" primitives = { package = "substrate-primitives", path = "../primitives" } app-crypto = { package = "substrate-application-crypto", path = "../application-crypto" } -hex = "0.3" -rand = "0.6" -serde_json = "1.0" -subtle = "2.0" +hex = "0.3.2" +rand = "0.7.2" +serde_json = "1.0.40" +subtle = "2.1.1" parking_lot = "0.9.0" [dev-dependencies] -tempdir = "0.3" +tempdir = "0.3.7" diff --git a/core/keystore/src/lib.rs b/core/keystore/src/lib.rs index 9125ddbda650228f4ace7233248b7b84083dac12..c86e9f8b8850ce6d64da82f3bd6fcfb06c4f8694 100644 --- a/core/keystore/src/lib.rs +++ b/core/keystore/src/lib.rs @@ -318,7 +318,7 @@ impl BareCryptoStore for Store { mod tests { use super::*; use tempdir::TempDir; - use primitives::crypto::{Ss58Codec, key_types}; + use primitives::{testing::{SR25519}, crypto::{Ss58Codec}}; #[test] fn basic_store() { @@ -410,14 +410,14 @@ mod tests { let key_pair = sr25519::AppPair::from_string(secret_uri, None).expect("Generates key pair"); store.write().insert_unknown( - key_types::SR25519, + SR25519, secret_uri, key_pair.public().as_ref(), ).expect("Inserts unknown key"); let store_key_pair = store.read().key_pair_by_type::( &key_pair.public(), - key_types::SR25519, + SR25519, ).expect("Gets key pair from keystore"); assert_eq!(key_pair.public(), store_key_pair.public()); diff --git a/core/network/Cargo.toml b/core/network/Cargo.toml index dac6ecdd72cf27a533e0b628f9cbac7a4e9cd4b9..453fbbeee350451549515975285c075dfb7f3e11 100644 --- a/core/network/Cargo.toml +++ b/core/network/Cargo.toml @@ -7,54 +7,55 @@ authors = ["Parity Technologies "] edition = "2018" [dependencies] -bytes = "0.4" -derive_more = "0.14.0" -either = "1.5.2" -log = "0.4" +bytes = "0.4.12" +derive_more = "0.15.0" +either = "1.5.3" +log = "0.4.8" parking_lot = "0.9.0" -bitflags = "1.0" -fnv = "1.0" -futures = "0.1.17" -futures03 = { package = "futures-preview", version = "=0.3.0-alpha.17", features = ["compat"] } -futures-timer = "0.2.1" -linked-hash-map = "0.5" +bitflags = "1.2.0" +fnv = "1.0.6" +futures = "0.1.29" +futures03 = { package = "futures-preview", version = "0.3.0-alpha.19", features = ["compat"] } +futures-timer = "0.4.0" +linked-hash-map = "0.5.2" linked_hash_set = "0.1.3" -lru-cache = "0.1.1" -rustc-hex = "2.0" -rand = "0.6" -libp2p = { version = "0.11.0", default-features = false, features = ["secp256k1", "libp2p-websocket"] } +lru-cache = "0.1.2" +rustc-hex = "2.0.1" +rand = "0.7.2" +libp2p = { version = "0.12.0", default-features = false, features = ["secp256k1", "libp2p-websocket"] } fork-tree = { path = "../../core/utils/fork-tree" } consensus = { package = "substrate-consensus-common", path = "../../core/consensus/common" } client = { package = "substrate-client", path = "../../core/client" } +header_metadata = { package = "substrate-header-metadata", path = "../../core/client/header-metadata" } sr-primitives = { path = "../../core/sr-primitives" } primitives = { package = "substrate-primitives", path = "../../core/primitives" } codec = { package = "parity-scale-codec", version = "1.0.0", features = ["derive"] } peerset = { package = "substrate-peerset", path = "../../core/peerset" } -serde = { version = "1.0.70", features = ["derive"] } -serde_json = "1.0.24" -slog = { version = "^2", features = ["nested-values"] } +serde = { version = "1.0.101", features = ["derive"] } +serde_json = "1.0.40" +slog = { version = "2.5.2", features = ["nested-values"] } slog_derive = "0.1.1" -smallvec = "0.6" -tokio-io = "0.1" -tokio = { version = "0.1.11", optional = true } -unsigned-varint = { version = "0.2.1", features = ["codec"] } +smallvec = "0.6.10" +tokio-io = "0.1.12" +tokio = { version = "0.1.22", optional = true } +unsigned-varint = { version = "0.2.2", features = ["codec"] } keyring = { package = "substrate-keyring", path = "../../core/keyring", optional = true } test_client = { package = "substrate-test-client", path = "../../core/test-client", optional = true } test-client = { package = "substrate-test-runtime-client", path = "../../core/test-runtime/client", optional = true } erased-serde = "0.3.9" -void = "1.0" -zeroize = "0.9.0" +void = "1.0.2" +zeroize = "0.10.1" babe-primitives = { package = "substrate-consensus-babe-primitives", path = "../consensus/babe/primitives" } [dev-dependencies] -env_logger = { version = "0.6" } +env_logger = "0.6.2" keyring = { package = "substrate-keyring", path = "../../core/keyring" } -quickcheck = "0.8.5" -rand = "0.6.5" +quickcheck = "0.9.0" +rand = "0.7.2" test-client = { package = "substrate-test-runtime-client", path = "../../core/test-runtime/client" } test_runtime = { package = "substrate-test-runtime", path = "../../core/test-runtime" } -tempdir = "0.3" -tokio = "0.1.11" +tempdir = "0.3.7" +tokio = "0.1.22" [features] default = [] diff --git a/core/network/src/behaviour.rs b/core/network/src/behaviour.rs index f2144c89a5654e1278706fb6112acfb7366f2825..2471cbcaaf26aa79c1a9c727a0cb7ee2e75a5003 100644 --- a/core/network/src/behaviour.rs +++ b/core/network/src/behaviour.rs @@ -23,9 +23,9 @@ use crate::protocol::{CustomMessageOutcome, Protocol}; use futures::prelude::*; use libp2p::NetworkBehaviour; use libp2p::core::{Multiaddr, PeerId, PublicKey}; +use libp2p::kad::record; use libp2p::swarm::{NetworkBehaviourAction, NetworkBehaviourEventProcess}; use libp2p::core::{nodes::Substream, muxing::StreamMuxerBox}; -use libp2p::multihash::Multihash; use log::warn; use sr_primitives::traits::Block as BlockT; use std::iter; @@ -101,12 +101,12 @@ impl, H: ExHashT> Behaviour { } /// Start querying a record from the DHT. Will later produce either a `ValueFound` or a `ValueNotFound` event. - pub fn get_value(&mut self, key: &Multihash) { + pub fn get_value(&mut self, key: &record::Key) { self.discovery.get_value(key); } /// Starts putting a record into DHT. Will later produce either a `ValuePut` or a `ValuePutFailed` event. - pub fn put_value(&mut self, key: Multihash, value: Vec) { + pub fn put_value(&mut self, key: record::Key, value: Vec) { self.discovery.put_value(key, value); } } diff --git a/core/network/src/chain.rs b/core/network/src/chain.rs index e857aa095c9f97eefc7bd462cd8f534a64bf73ec..f68942fd96d38fbf6b798ab2b90940cd3ee8d9c4 100644 --- a/core/network/src/chain.rs +++ b/core/network/src/chain.rs @@ -16,10 +16,10 @@ //! Blockchain access trait -use client::{self, Client as SubstrateClient, ClientInfo, BlockStatus, CallExecutor}; +use client::{self, Client as SubstrateClient, ClientInfo, CallExecutor}; use client::error::Error; use client::light::fetcher::ChangesProof; -use consensus::{BlockImport, Error as ConsensusError}; +use consensus::{BlockImport, BlockStatus, Error as ConsensusError}; use sr_primitives::traits::{Block as BlockT, Header as HeaderT}; use sr_primitives::generic::{BlockId}; use sr_primitives::Justification; @@ -49,7 +49,15 @@ pub trait Client: Send + Sync { fn header_proof(&self, block_number: ::Number) -> Result<(Block::Header, Vec>), Error>; /// Get storage read execution proof. - fn read_proof(&self, block: &Block::Hash, key: &[u8]) -> Result>, Error>; + fn read_proof(&self, block: &Block::Hash, keys: &[Vec]) -> Result>, Error>; + + /// Get child storage read execution proof. + fn read_child_proof( + &self, + block: &Block::Hash, + storage_key: &[u8], + keys: &[Vec], + ) -> Result>, Error>; /// Get method execution proof. fn execution_proof(&self, block: &Block::Hash, method: &str, data: &[u8]) -> Result<(Vec, Vec>), Error>; @@ -61,6 +69,7 @@ pub trait Client: Send + Sync { last: Block::Hash, min: Block::Hash, max: Block::Hash, + storage_key: Option<&StorageKey>, key: &StorageKey ) -> Result, Error>; @@ -74,6 +83,12 @@ pub trait FinalityProofProvider: Send + Sync { fn prove_finality(&self, for_block: Block::Hash, request: &[u8]) -> Result>, Error>; } +impl FinalityProofProvider for () { + fn prove_finality(&self, _for_block: Block::Hash, _request: &[u8]) -> Result>, Error> { + Ok(None) + } +} + impl Client for SubstrateClient where B: client::backend::Backend + Send + Sync + 'static, E: CallExecutor + Send + Sync + 'static, @@ -109,8 +124,18 @@ impl Client for SubstrateClient where (self as &SubstrateClient).header_proof(&BlockId::Number(block_number)) } - fn read_proof(&self, block: &Block::Hash, key: &[u8]) -> Result>, Error> { - (self as &SubstrateClient).read_proof(&BlockId::Hash(block.clone()), key) + fn read_proof(&self, block: &Block::Hash, keys: &[Vec]) -> Result>, Error> { + (self as &SubstrateClient).read_proof(&BlockId::Hash(block.clone()), keys) + } + + fn read_child_proof( + &self, + block: &Block::Hash, + storage_key: &[u8], + keys: &[Vec], + ) -> Result>, Error> { + (self as &SubstrateClient) + .read_child_proof(&BlockId::Hash(block.clone()), storage_key, keys) } fn execution_proof(&self, block: &Block::Hash, method: &str, data: &[u8]) -> Result<(Vec, Vec>), Error> { @@ -123,9 +148,10 @@ impl Client for SubstrateClient where last: Block::Hash, min: Block::Hash, max: Block::Hash, - key: &StorageKey + storage_key: Option<&StorageKey>, + key: &StorageKey, ) -> Result, Error> { - (self as &SubstrateClient).key_changes_proof(first, last, min, max, key) + (self as &SubstrateClient).key_changes_proof(first, last, min, max, storage_key, key) } fn is_descendent_of(&self, base: &Block::Hash, block: &Block::Hash) -> Result { @@ -133,13 +159,8 @@ impl Client for SubstrateClient where return Ok(false); } - let tree_route = ::client::blockchain::tree_route( - #[allow(deprecated)] - self.backend().blockchain(), - BlockId::Hash(*block), - BlockId::Hash(*base), - )?; + let ancestor = header_metadata::lowest_common_ancestor(self, *block, *base)?; - Ok(tree_route.common_block().hash == *base) + Ok(ancestor.hash == *base) } } diff --git a/core/network/src/config.rs b/core/network/src/config.rs index 46bb8aeff4ddd69deb3de94cdfaa0b561b6a214a..0582fcb300f1ea590811d143aea36f60b31b0586 100644 --- a/core/network/src/config.rs +++ b/core/network/src/config.rs @@ -26,7 +26,7 @@ use crate::chain::{Client, FinalityProofProvider}; use crate::on_demand_layer::OnDemand; use crate::service::{ExHashT, TransactionPool}; use bitflags::bitflags; -use consensus::import_queue::ImportQueue; +use consensus::{block_validation::BlockAnnounceValidator, import_queue::ImportQueue}; use sr_primitives::traits::{Block as BlockT}; use std::sync::Arc; use libp2p::identity::{Keypair, secp256k1, ed25519}; @@ -80,6 +80,9 @@ pub struct Params { /// Customization of the network. Use this to plug additional networking capabilities. pub specialization: S, + + /// Type to check incoming block announcements. + pub block_announce_validator: Box + Send> } bitflags! { @@ -205,23 +208,23 @@ pub enum ParseErr { } impl fmt::Display for ParseErr { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - match self { - ParseErr::MultiaddrParse(err) => write!(f, "{}", err), - ParseErr::InvalidPeerId => write!(f, "Peer id at the end of the address is invalid"), - ParseErr::PeerIdMissing => write!(f, "Peer id is missing from the address"), - } - } + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + match self { + ParseErr::MultiaddrParse(err) => write!(f, "{}", err), + ParseErr::InvalidPeerId => write!(f, "Peer id at the end of the address is invalid"), + ParseErr::PeerIdMissing => write!(f, "Peer id is missing from the address"), + } + } } impl std::error::Error for ParseErr { - fn source(&self) -> Option<&(dyn std::error::Error + 'static)> { - match self { - ParseErr::MultiaddrParse(err) => Some(err), - ParseErr::InvalidPeerId => None, - ParseErr::PeerIdMissing => None, - } - } + fn source(&self) -> Option<&(dyn std::error::Error + 'static)> { + match self { + ParseErr::MultiaddrParse(err) => Some(err), + ParseErr::InvalidPeerId => None, + ParseErr::PeerIdMissing => None, + } + } } impl From for ParseErr { diff --git a/core/network/src/discovery.rs b/core/network/src/discovery.rs index 9fa6b2a80fc895c69ccc5170e5692bd85dda9b6c..a9cf61d040f0fde981ebc8903e6a407f5b226588 100644 --- a/core/network/src/discovery.rs +++ b/core/network/src/discovery.rs @@ -52,14 +52,13 @@ use libp2p::core::{ConnectedPoint, Multiaddr, PeerId, PublicKey}; use libp2p::swarm::{ProtocolsHandler, NetworkBehaviour, NetworkBehaviourAction, PollParameters}; use libp2p::kad::{Kademlia, KademliaEvent, Quorum, Record}; use libp2p::kad::GetClosestPeersError; -use libp2p::kad::record::store::MemoryStore; +use libp2p::kad::record::{self, store::MemoryStore}; #[cfg(not(target_os = "unknown"))] use libp2p::{swarm::toggle::Toggle}; #[cfg(not(target_os = "unknown"))] use libp2p::core::{nodes::Substream, muxing::StreamMuxerBox}; #[cfg(not(target_os = "unknown"))] use libp2p::mdns::{Mdns, MdnsEvent}; -use libp2p::multihash::Multihash; use libp2p::multiaddr::Protocol; use log::{debug, info, trace, warn}; use std::{cmp, collections::VecDeque, time::Duration}; @@ -159,7 +158,7 @@ impl DiscoveryBehaviour { /// Start fetching a record from the DHT. /// /// A corresponding `ValueFound` or `ValueNotFound` event will later be generated. - pub fn get_value(&mut self, key: &Multihash) { + pub fn get_value(&mut self, key: &record::Key) { self.kademlia.get_record(key, Quorum::One) } @@ -167,7 +166,7 @@ impl DiscoveryBehaviour { /// `get_value`. /// /// A corresponding `ValuePut` or `ValuePutFailed` event will later be generated. - pub fn put_value(&mut self, key: Multihash, value: Vec) { + pub fn put_value(&mut self, key: record::Key, value: Vec) { self.kademlia.put_record(Record::new(key, value), Quorum::All); } } @@ -187,16 +186,16 @@ pub enum DiscoveryOut { UnroutablePeer(PeerId), /// The DHT yeided results for the record request, grouped in (key, value) pairs. - ValueFound(Vec<(Multihash, Vec)>), + ValueFound(Vec<(record::Key, Vec)>), /// The record requested was not found in the DHT. - ValueNotFound(Multihash), + ValueNotFound(record::Key), /// The record with a given key was successfully inserted into the DHT. - ValuePut(Multihash), + ValuePut(record::Key), /// Inserting a value into the DHT failed. - ValuePutFailed(Multihash), + ValuePutFailed(record::Key), } impl NetworkBehaviour for DiscoveryBehaviour diff --git a/core/network/src/lib.rs b/core/network/src/lib.rs index e5714c66f20a52a9762e3c8687b48d12b53f4a8a..7e9fd51a41533b12b3aa84f7ec1d9584bc2a1b70 100644 --- a/core/network/src/lib.rs +++ b/core/network/src/lib.rs @@ -192,6 +192,7 @@ pub use service::{ NetworkStateInfo, }; pub use protocol::{PeerInfo, Context, consensus_gossip, message, specialization}; +pub use protocol::event::{Event, DhtEvent}; pub use protocol::sync::SyncState; pub use libp2p::{Multiaddr, PeerId}; #[doc(inline)] @@ -286,8 +287,8 @@ pub enum NetworkStatePeerEndpoint { Dialing(Multiaddr), /// We are listening. Listening { - /// Address we're listening on that received the connection. - listen_addr: Multiaddr, + /// Local address of the connection. + local_addr: Multiaddr, /// Address data is sent back to. send_back_addr: Multiaddr, }, @@ -298,9 +299,9 @@ impl From for NetworkStatePeerEndpoint { match endpoint { ConnectedPoint::Dialer { address } => NetworkStatePeerEndpoint::Dialing(address), - ConnectedPoint::Listener { listen_addr, send_back_addr } => + ConnectedPoint::Listener { local_addr, send_back_addr } => NetworkStatePeerEndpoint::Listening { - listen_addr, + local_addr, send_back_addr } } diff --git a/core/network/src/on_demand_layer.rs b/core/network/src/on_demand_layer.rs index 818230eea54b8c3ad741fa0467a141192c914c69..cdcb99a25f99e4854c66f28101af7b44ff698276 100644 --- a/core/network/src/on_demand_layer.rs +++ b/core/network/src/on_demand_layer.rs @@ -17,6 +17,7 @@ //! On-demand requests service. use crate::protocol::light_dispatch::RequestData; +use std::collections::HashMap; use std::sync::Arc; use futures::{prelude::*, sync::mpsc, sync::oneshot}; use futures03::compat::{Compat01As03, Future01CompatExt as _}; @@ -84,7 +85,7 @@ impl Fetcher for OnDemand where B::Header: HeaderT, { type RemoteHeaderResult = Compat01As03>; - type RemoteReadResult = Compat01As03>>>; + type RemoteReadResult = Compat01As03, Option>>>>; type RemoteCallResult = Compat01As03>>; type RemoteChangesResult = Compat01As03, u32)>>>; type RemoteBodyResult = Compat01As03>>; diff --git a/core/network/src/protocol.rs b/core/network/src/protocol.rs index b561322b5bbf8342d7729508152cf4116f7d8da5..dc9e6688e74ee8c25d30bc5b1a53bcd7977affeb 100644 --- a/core/network/src/protocol.rs +++ b/core/network/src/protocol.rs @@ -23,14 +23,17 @@ use libp2p::core::{ConnectedPoint, nodes::Substream, muxing::StreamMuxerBox}; use libp2p::swarm::{ProtocolsHandler, IntoProtocolsHandler}; use libp2p::swarm::{NetworkBehaviour, NetworkBehaviourAction, PollParameters}; use primitives::storage::StorageKey; -use consensus::{import_queue::IncomingBlock, import_queue::Origin, BlockOrigin}; +use consensus::{ + BlockOrigin, + block_validation::BlockAnnounceValidator, + import_queue::{BlockImportResult, BlockImportError, IncomingBlock, Origin} +}; use sr_primitives::{generic::BlockId, ConsensusEngineId, Justification}; use sr_primitives::traits::{ Block as BlockT, Header as HeaderT, NumberFor, One, Zero, CheckedSub, SaturatedConversion }; -use consensus::import_queue::{BlockImportResult, BlockImportError}; -use message::{BlockAttributes, Direction, FromBlock, Message, RequestId}; +use message::{BlockAnnounce, BlockAttributes, Direction, FromBlock, Message, RequestId}; use message::generic::{Message as GenericMessage, ConsensusMessage}; use event::Event; use consensus_gossip::{ConsensusGossip, MessageRecipient as GossipMessageRecipient}; @@ -64,9 +67,9 @@ const TICK_TIMEOUT: time::Duration = time::Duration::from_millis(1100); const PROPAGATE_TIMEOUT: time::Duration = time::Duration::from_millis(2900); /// Current protocol version. -pub(crate) const CURRENT_VERSION: u32 = 3; +pub(crate) const CURRENT_VERSION: u32 = 4; /// Lowest version we support -pub(crate) const MIN_VERSION: u32 = 2; +pub(crate) const MIN_VERSION: u32 = 3; // Maximum allowed entries in `BlockResponse` const MAX_BLOCK_DATA_RESPONSE: u32 = 128; @@ -172,11 +175,17 @@ impl<'a, B: BlockT> LightDispatchNetwork for LightDispatchIn<'a, B> { self.behaviour.send_packet(who, message) } - fn send_read_request(&mut self, who: &PeerId, id: RequestId, block: ::Hash, key: Vec) { + fn send_read_request( + &mut self, + who: &PeerId, + id: RequestId, + block: ::Hash, + keys: Vec>, + ) { let message = message::generic::Message::RemoteReadRequest(message::RemoteReadRequest { id, block, - key, + keys, }); self.behaviour.send_packet(who, message) @@ -188,13 +197,13 @@ impl<'a, B: BlockT> LightDispatchNetwork for LightDispatchIn<'a, B> { id: RequestId, block: ::Hash, storage_key: Vec, - key: Vec + keys: Vec>, ) { let message = message::generic::Message::RemoteReadChildRequest(message::RemoteReadChildRequest { id, block, storage_key, - key, + keys, }); self.behaviour.send_packet(who, message) @@ -226,7 +235,8 @@ impl<'a, B: BlockT> LightDispatchNetwork for LightDispatchIn<'a, B> { last: ::Hash, min: ::Hash, max: ::Hash, - key: Vec + storage_key: Option>, + key: Vec, ) { let message = message::generic::Message::RemoteChangesRequest(message::RemoteChangesRequest { id, @@ -234,6 +244,7 @@ impl<'a, B: BlockT> LightDispatchNetwork for LightDispatchIn<'a, B> { last, min, max, + storage_key, key, }); @@ -358,9 +369,16 @@ impl, H: ExHashT> Protocol { finality_proof_request_builder: Option>, protocol_id: ProtocolId, peerset_config: peerset::PeersetConfig, + block_announce_validator: Box + Send> ) -> error::Result<(Protocol, peerset::PeersetHandle)> { let info = chain.info(); - let sync = ChainSync::new(config.roles, chain.clone(), &info, finality_proof_request_builder); + let sync = ChainSync::new( + config.roles, + chain.clone(), + &info, + finality_proof_request_builder, + block_announce_validator, + ); let (peerset, peerset_handle) = peerset::Peerset::from_config(peerset_config); let versions = &((MIN_VERSION as u8)..=(CURRENT_VERSION as u8)).collect::>(); let behaviour = LegacyProto::new(protocol_id, versions, peerset); @@ -368,7 +386,7 @@ impl, H: ExHashT> Protocol { let protocol = Protocol { tick_timeout: Box::new(futures_timer::Interval::new(TICK_TIMEOUT).map(|v| Ok::<_, ()>(v)).compat()), propagate_timeout: Box::new(futures_timer::Interval::new(PROPAGATE_TIMEOUT).map(|v| Ok::<_, ()>(v)).compat()), - config: config, + config, context_data: ContextData { peers: HashMap::new(), chain, @@ -376,7 +394,7 @@ impl, H: ExHashT> Protocol { light_dispatch: LightDispatch::new(checker), genesis_hash: info.chain.genesis_hash, sync, - specialization: specialization, + specialization, consensus_gossip: ConsensusGossip::new(), handshaking_peers: HashMap::new(), transaction_pool, @@ -547,7 +565,8 @@ impl, H: ExHashT> Protocol { self.on_finality_proof_request(who, request), GenericMessage::FinalityProofResponse(response) => return self.on_finality_proof_response(who, response), - GenericMessage::RemoteReadChildRequest(_) => {} + GenericMessage::RemoteReadChildRequest(request) => + self.on_remote_read_child_request(who, request), GenericMessage::Consensus(msg) => { if self.context_data.peers.get(&who).map_or(false, |peer| peer.info.protocol_version > 2) { self.consensus_gossip.on_incoming( @@ -944,6 +963,14 @@ impl, H: ExHashT> Protocol { who: PeerId, extrinsics: message::Transactions ) { + // sending extrinsic to light node is considered a bad behavior + if !self.config.roles.is_full() { + trace!(target: "sync", "Peer {} is trying to send extrinsic to the light node", who); + self.behaviour.disconnect_peer(&who); + self.peerset_handle.report_peer(who, i32::min_value()); + return; + } + // Accept extrinsics only when fully synced if self.sync.status().state != SyncState::Idle { trace!(target: "sync", "{} Ignoring extrinsics while syncing", who); @@ -952,12 +979,15 @@ impl, H: ExHashT> Protocol { trace!(target: "sync", "Received {} extrinsics from {}", extrinsics.len(), who); if let Some(ref mut peer) = self.context_data.peers.get_mut(&who) { for t in extrinsics { - if let Some(hash) = self.transaction_pool.import(&t) { - self.peerset_handle.report_peer(who.clone(), NEW_EXTRINSIC_REPUTATION_CHANGE); - peer.known_extrinsics.insert(hash); - } else { - trace!(target: "sync", "Extrinsic rejected"); - } + let hash = self.transaction_pool.hash_of(&t); + peer.known_extrinsics.insert(hash); + + self.transaction_pool.import( + self.peerset_handle.clone().into(), + who.clone(), + NEW_EXTRINSIC_REPUTATION_CHANGE, + t, + ); } } } @@ -976,6 +1006,11 @@ impl, H: ExHashT> Protocol { let extrinsics = self.transaction_pool.transactions(); let mut propagated_to = HashMap::new(); for (who, peer) in self.context_data.peers.iter_mut() { + // never send extrinsics to the light node + if !peer.info.roles.is_full() { + continue; + } + let (hashes, to_send): (Vec<_>, Vec<_>) = extrinsics .iter() .filter(|&(ref hash, _)| peer.known_extrinsics.insert(hash.clone())) @@ -1001,7 +1036,7 @@ impl, H: ExHashT> Protocol { /// /// In chain-based consensus, we often need to make sure non-best forks are /// at least temporarily synced. - pub fn announce_block(&mut self, hash: B::Hash) { + pub fn announce_block(&mut self, hash: B::Hash, data: Vec) { let header = match self.context_data.chain.header(&BlockId::Hash(hash)) { Ok(Some(header)) => header, Ok(None) => { @@ -1019,14 +1054,38 @@ impl, H: ExHashT> Protocol { return; } - let hash = header.hash(); + let is_best = self.context_data.chain.info().chain.best_hash == hash; + debug!(target: "sync", "Reannouncing block {:?}", hash); + self.send_announcement(&header, data, is_best, true) + } - let message = GenericMessage::BlockAnnounce(message::BlockAnnounce { header: header.clone() }); + fn send_announcement(&mut self, header: &B::Header, data: Vec, is_best: bool, force: bool) { + let hash = header.hash(); for (who, ref mut peer) in self.context_data.peers.iter_mut() { - trace!(target: "sync", "Reannouncing block {:?} to {}", hash, who); - peer.known_blocks.insert(hash); - self.behaviour.send_packet(who, message.clone()) + trace!(target: "sync", "Announcing block {:?} to {}", hash, who); + let inserted = peer.known_blocks.insert(hash); + if inserted || force { + let message = GenericMessage::BlockAnnounce(message::BlockAnnounce { + header: header.clone(), + state: if peer.info.protocol_version >= 4 { + if is_best { + Some(message::BlockState::Best) + } else { + Some(message::BlockState::Normal) + } + } else { + None + }, + data: if peer.info.protocol_version >= 4 { + Some(data.clone()) + } else { + None + }, + }); + + self.behaviour.send_packet(who, message) + } } } @@ -1046,24 +1105,22 @@ impl, H: ExHashT> Protocol { self.send_message(who, GenericMessage::Status(status)) } - fn on_block_announce( - &mut self, - who: PeerId, - announce: message::BlockAnnounce - ) -> CustomMessageOutcome { - let header = announce.header; - let hash = header.hash(); - { - if let Some(ref mut peer) = self.context_data.peers.get_mut(&who) { - peer.known_blocks.insert(hash.clone()); - } + fn on_block_announce(&mut self, who: PeerId, announce: BlockAnnounce) -> CustomMessageOutcome { + let hash = announce.header.hash(); + if let Some(ref mut peer) = self.context_data.peers.get_mut(&who) { + peer.known_blocks.insert(hash.clone()); } self.light_dispatch.update_best_number(LightDispatchIn { behaviour: &mut self.behaviour, peerset: self.peerset_handle.clone(), - }, who.clone(), *header.number()); + }, who.clone(), *announce.header.number()); + + let is_their_best = match announce.state.unwrap_or(message::BlockState::Best) { + message::BlockState::Best => true, + message::BlockState::Normal => false, + }; - match self.sync.on_block_announce(who.clone(), hash, &header) { + match self.sync.on_block_announce(who.clone(), hash, &announce, is_their_best) { sync::OnBlockAnnounce::Request(peer, req) => { self.send_message(peer, GenericMessage::BlockRequest(req)); return CustomMessageOutcome::None @@ -1098,7 +1155,7 @@ impl, H: ExHashT> Protocol { blocks: vec![ message::generic::BlockData { hash: hash, - header: Some(header), + header: Some(announce.header), body: None, receipt: None, message_queue: None, @@ -1123,8 +1180,10 @@ impl, H: ExHashT> Protocol { /// Call this when a block has been imported in the import queue and we should announce it on /// the network. - pub fn on_block_imported(&mut self, hash: B::Hash, header: &B::Header) { - self.sync.update_chain_info(header); + pub fn on_block_imported(&mut self, hash: B::Hash, header: &B::Header, data: Vec, is_best: bool) { + if is_best { + self.sync.update_chain_info(header); + } self.specialization.on_block_imported( &mut ProtocolContext::new(&mut self.context_data, &mut self.behaviour, &self.peerset_handle), hash.clone(), @@ -1137,15 +1196,7 @@ impl, H: ExHashT> Protocol { } // send out block announcements - - let message = GenericMessage::BlockAnnounce(message::BlockAnnounce { header: header.clone() }); - - for (who, ref mut peer) in self.context_data.peers.iter_mut() { - if peer.known_blocks.insert(hash.clone()) { - trace!(target: "sync", "Announcing block {:?} to {}", hash, who); - self.behaviour.send_packet(who, message.clone()) - } - } + self.send_announcement(header, data, is_best, false); } /// Call this when a block has been finalized. The sync layer may have some additional @@ -1201,6 +1252,13 @@ impl, H: ExHashT> Protocol { self.sync.request_justification(&hash, number) } + /// Request syncing for the given block from given set of peers. + /// Uses `protocol` to queue a new block download request and tries to dispatch all pending + /// requests. + pub fn set_sync_fork_request(&mut self, peers: Vec, hash: &B::Hash, number: NumberFor) { + self.sync.set_sync_fork_request(peers, hash, number) + } + /// A batch of blocks have been processed, with or without errors. /// Call this when a batch of blocks have been processed by the importqueue, with or without /// errors. @@ -1269,15 +1327,67 @@ impl, H: ExHashT> Protocol { who: PeerId, request: message::RemoteReadRequest, ) { + let keys_str = || match request.keys.len() { + 1 => request.keys[0].to_hex::(), + _ => format!( + "{}..{}", + request.keys[0].to_hex::(), + request.keys[request.keys.len() - 1].to_hex::(), + ), + }; + trace!(target: "sync", "Remote read request {} from {} ({} at {})", - request.id, who, request.key.to_hex::(), request.block); - let proof = match self.context_data.chain.read_proof(&request.block, &request.key) { + request.id, who, keys_str(), request.block); + let proof = match self.context_data.chain.read_proof(&request.block, &request.keys) { Ok(proof) => proof, Err(error) => { trace!(target: "sync", "Remote read request {} from {} ({} at {}) failed with: {}", request.id, who, - request.key.to_hex::(), + keys_str(), + request.block, + error + ); + Default::default() + } + }; + self.send_message( + who, + GenericMessage::RemoteReadResponse(message::RemoteReadResponse { + id: request.id, + proof, + }), + ); + } + + fn on_remote_read_child_request( + &mut self, + who: PeerId, + request: message::RemoteReadChildRequest, + ) { + let keys_str = || match request.keys.len() { + 1 => request.keys[0].to_hex::(), + _ => format!( + "{}..{}", + request.keys[0].to_hex::(), + request.keys[request.keys.len() - 1].to_hex::(), + ), + }; + + trace!(target: "sync", "Remote read child request {} from {} ({} {} at {})", + request.id, who, request.storage_key.to_hex::(), keys_str(), request.block); + let proof = match self.context_data.chain.read_child_proof( + &request.block, + &request.storage_key, + &request.keys, + ) { + Ok(proof) => proof, + Err(error) => { + trace!(target: "sync", "Remote read child request {} from {} ({} {} at {}) failed with: {}", + request.id, + who, + request.storage_key.to_hex::(), + keys_str(), request.block, error ); @@ -1354,24 +1464,34 @@ impl, H: ExHashT> Protocol { trace!(target: "sync", "Remote changes proof request {} from {} for key {} ({}..{})", request.id, who, - request.key.to_hex::(), + if let Some(sk) = request.storage_key.as_ref() { + format!("{} : {}", sk.to_hex::(), request.key.to_hex::()) + } else { + request.key.to_hex::() + }, request.first, request.last ); + let storage_key = request.storage_key.map(|sk| StorageKey(sk)); let key = StorageKey(request.key); let proof = match self.context_data.chain.key_changes_proof( request.first, request.last, request.min, request.max, - &key + storage_key.as_ref(), + &key, ) { Ok(proof) => proof, Err(error) => { trace!(target: "sync", "Remote changes proof request {} from {} for key {} ({}..{}) failed with: {}", request.id, who, - key.0.to_hex::(), + if let Some(sk) = storage_key { + format!("{} : {}", sk.0.to_hex::(), key.0.to_hex::()) + } else { + key.0.to_hex::() + }, request.first, request.last, error diff --git a/core/network/src/protocol/consensus_gossip.rs b/core/network/src/protocol/consensus_gossip.rs index 328fe197ea54055ed0a3cde9c70437dae4128b19..d916e9aace7044cd1a048b641ba91cd0696ef120 100644 --- a/core/network/src/protocol/consensus_gossip.rs +++ b/core/network/src/protocol/consensus_gossip.rs @@ -14,8 +14,34 @@ // You should have received a copy of the GNU General Public License // along with Substrate. If not, see . -//! Utility for gossip of network messages between authorities. +//! Utility for gossip of network messages between nodes. //! Handles chain-specific and standard BFT messages. +//! +//! Gossip messages are separated by two categories: "topics" and consensus engine ID. +//! The consensus engine ID is sent over the wire with the message, while the topic is not, +//! with the expectation that the topic can be derived implicitly from the content of the +//! message, assuming it is valid. +//! +//! Topics are a single 32-byte tag associated with a message, used to group those messages +//! in an opaque way. Consensus code can invoke `broadcast_topic` to attempt to send all messages +//! under a single topic to all peers who don't have them yet, and `send_topic` to +//! send all messages under a single topic to a specific peer. +//! +//! Each consensus engine ID must have an associated, +//! registered `Validator` for all gossip messages. The primary role of this `Validator` is +//! to process incoming messages from peers, and decide whether to discard them or process +//! them. It also decides whether to re-broadcast the message. +//! +//! The secondary role of the `Validator` is to check if a message is allowed to be sent to a given +//! peer. All messages, before being sent, will be checked against this filter. +//! This enables the validator to use information it's aware of about connected peers to decide +//! whether to send messages to them at any given moment in time - In particular, to wait until +//! peers can accept and process the message before sending it. +//! +//! Lastly, the fact that gossip validators can decide not to rebroadcast messages +//! opens the door for neighbor status packets to be baked into the gossip protocol. +//! These status packets will typically contain light pieces of information +//! used to inform peers of a current view of protocol state. use std::collections::{HashMap, HashSet, hash_map::Entry}; use std::sync::Arc; diff --git a/core/network/src/protocol/event.rs b/core/network/src/protocol/event.rs index 2edbb0fbf7563120dd2378f2c4ccb5eab97c115a..c8bee5588c704f09a9c2c14d1b5b8245cf6bd1cc 100644 --- a/core/network/src/protocol/event.rs +++ b/core/network/src/protocol/event.rs @@ -17,24 +17,26 @@ //! Network event types. These are are not the part of the protocol, but rather //! events that happen on the network like DHT get/put results received. -use libp2p::multihash::Multihash; +use libp2p::kad::record::Key; /// Events generated by DHT as a response to get_value and put_value requests. +#[derive(Debug, Clone)] pub enum DhtEvent { /// The value was found. - ValueFound(Vec<(Multihash, Vec)>), + ValueFound(Vec<(Key, Vec)>), /// The requested record has not been found in the DHT. - ValueNotFound(Multihash), + ValueNotFound(Key), /// The record has been successfully inserted into the DHT. - ValuePut(Multihash), + ValuePut(Key), /// An error has occured while putting a record into the DHT. - ValuePutFailed(Multihash), + ValuePutFailed(Key), } /// Type for events generated by networking layer. +#[derive(Debug, Clone)] pub enum Event { /// Event generated by a DHT. Dht(DhtEvent), diff --git a/core/network/src/protocol/light_dispatch.rs b/core/network/src/protocol/light_dispatch.rs index e56ed3a08eee9a778c4d451cb1228ed8865e3de5..33ff23c909d1060f7ede1b599008f1705966fb8f 100644 --- a/core/network/src/protocol/light_dispatch.rs +++ b/core/network/src/protocol/light_dispatch.rs @@ -53,7 +53,13 @@ pub trait LightDispatchNetwork { fn send_header_request(&mut self, who: &PeerId, id: RequestId, block: <::Header as HeaderT>::Number); /// Send to `who` a read request. - fn send_read_request(&mut self, who: &PeerId, id: RequestId, block: ::Hash, key: Vec); + fn send_read_request( + &mut self, + who: &PeerId, + id: RequestId, + block: ::Hash, + keys: Vec>, + ); /// Send to `who` a child read request. fn send_read_child_request( @@ -62,7 +68,7 @@ pub trait LightDispatchNetwork { id: RequestId, block: ::Hash, storage_key: Vec, - key: Vec + keys: Vec>, ); /// Send to `who` a call request. @@ -84,7 +90,8 @@ pub trait LightDispatchNetwork { last: ::Hash, min: ::Hash, max: ::Hash, - key: Vec + storage_key: Option>, + key: Vec, ); /// Send to `who` a body request. @@ -134,10 +141,13 @@ struct Request { pub(crate) enum RequestData { RemoteBody(RemoteBodyRequest, OneShotSender, ClientError>>), RemoteHeader(RemoteHeaderRequest, OneShotSender>), - RemoteRead(RemoteReadRequest, OneShotSender>, ClientError>>), + RemoteRead( + RemoteReadRequest, + OneShotSender, Option>>, ClientError>>, + ), RemoteReadChild( RemoteReadChildRequest, - OneShotSender>, ClientError>> + OneShotSender, Option>>, ClientError>> ), RemoteCall(RemoteCallRequest, OneShotSender, ClientError>>), RemoteChanges( @@ -173,7 +183,7 @@ impl FetchChecker for AlwaysBadChecker { &self, _request: &RemoteReadRequest, _remote_proof: Vec> - ) -> Result>, ClientError> { + ) -> Result,Option>>, ClientError> { Err(ClientError::Msg("AlwaysBadChecker".into())) } @@ -181,7 +191,7 @@ impl FetchChecker for AlwaysBadChecker { &self, _request: &RemoteReadChildRequest, _remote_proof: Vec> - ) -> Result>, ClientError> { + ) -> Result, Option>>, ClientError> { Err(ClientError::Msg("AlwaysBadChecker".into())) } @@ -603,7 +613,7 @@ impl Request { peer, self.id, data.block, - data.key.clone(), + data.keys.clone(), ), RequestData::RemoteReadChild(ref data, _) => out.send_read_child_request( @@ -611,7 +621,7 @@ impl Request { self.id, data.block, data.storage_key.clone(), - data.key.clone(), + data.keys.clone(), ), RequestData::RemoteCall(ref data, _) => out.send_call_request( @@ -629,6 +639,7 @@ impl Request { data.last_block.1.clone(), data.tries_roots.1.clone(), data.max_block.1.clone(), + data.storage_key.clone(), data.key.clone(), ), RequestData::RemoteBody(ref data, _) => @@ -661,7 +672,7 @@ impl RequestData { #[cfg(test)] pub mod tests { - use std::collections::HashSet; + use std::collections::{HashMap, HashSet}; use std::sync::Arc; use std::time::Instant; use futures::{Future, sync::oneshot}; @@ -691,20 +702,34 @@ pub mod tests { } } - fn check_read_proof(&self, _: &RemoteReadRequest

, _: Vec>) -> ClientResult>> { + fn check_read_proof( + &self, + request: &RemoteReadRequest
, + _: Vec>, + ) -> ClientResult, Option>>> { match self.ok { - true => Ok(Some(vec![42])), + true => Ok(request.keys + .iter() + .cloned() + .map(|k| (k, Some(vec![42]))) + .collect() + ), false => Err(ClientError::Backend("Test error".into())), } } fn check_read_child_proof( &self, - _: &RemoteReadChildRequest
, + request: &RemoteReadChildRequest
, _: Vec> - ) -> ClientResult>> { + ) -> ClientResult, Option>>> { match self.ok { - true => Ok(Some(vec![42])), + true => Ok(request.keys + .iter() + .cloned() + .map(|k| (k, Some(vec![42]))) + .collect() + ), false => Err(ClientError::Backend("Test error".into())), } } @@ -780,12 +805,12 @@ pub mod tests { self.disconnected_peers.insert(who.clone()); } fn send_header_request(&mut self, _: &PeerId, _: RequestId, _: <::Header as HeaderT>::Number) {} - fn send_read_request(&mut self, _: &PeerId, _: RequestId, _: ::Hash, _: Vec) {} + fn send_read_request(&mut self, _: &PeerId, _: RequestId, _: ::Hash, _: Vec>) {} fn send_read_child_request(&mut self, _: &PeerId, _: RequestId, _: ::Hash, _: Vec, - _: Vec) {} + _: Vec>) {} fn send_call_request(&mut self, _: &PeerId, _: RequestId, _: ::Hash, _: String, _: Vec) {} fn send_changes_request(&mut self, _: &PeerId, _: RequestId, _: ::Hash, _: ::Hash, - _: ::Hash, _: ::Hash, _: Vec) {} + _: ::Hash, _: ::Hash, _: Option>, _: Vec) {} fn send_body_request(&mut self, _: &PeerId, _: RequestId, _: BlockAttributes, _: FromBlock<::Hash, <::Header as HeaderT>::Number>, _: Option, _: Direction, _: Option) {} } @@ -982,7 +1007,7 @@ pub mod tests { light_dispatch.add_request(&mut network_interface, RequestData::RemoteRead(RemoteReadRequest { header: dummy_header(), block: Default::default(), - key: b":key".to_vec(), + keys: vec![b":key".to_vec()], retry_count: None, }, tx)); @@ -990,7 +1015,7 @@ pub mod tests { id: 0, proof: vec![vec![2]], }); - assert_eq!(response.wait().unwrap().unwrap(), Some(vec![42])); + assert_eq!(response.wait().unwrap().unwrap().remove(b":key".as_ref()).unwrap(), Some(vec![42])); } #[test] @@ -1005,7 +1030,7 @@ pub mod tests { header: dummy_header(), block: Default::default(), storage_key: b":child_storage:sub".to_vec(), - key: b":key".to_vec(), + keys: vec![b":key".to_vec()], retry_count: None, }, tx)); @@ -1014,7 +1039,7 @@ pub mod tests { id: 0, proof: vec![vec![2]], }); - assert_eq!(response.wait().unwrap().unwrap(), Some(vec![42])); + assert_eq!(response.wait().unwrap().unwrap().remove(b":key".as_ref()).unwrap(), Some(vec![42])); } #[test] @@ -1063,6 +1088,7 @@ pub mod tests { max_block: (100, Default::default()), tries_roots: (1, Default::default(), vec![]), key: vec![], + storage_key: None, retry_count: None, }, tx)); diff --git a/core/network/src/protocol/message.rs b/core/network/src/protocol/message.rs index 4110970f99cec48c97a5e706ea4dafa4567cd1ba..6560ed0f13a52c92c172e42b5f2796e6ee55a4d8 100644 --- a/core/network/src/protocol/message.rs +++ b/core/network/src/protocol/message.rs @@ -107,6 +107,15 @@ pub enum Direction { Descending = 1, } +/// Block state in the chain. +#[derive(Debug, PartialEq, Eq, Clone, Copy, Encode, Decode)] +pub enum BlockState { + /// Block is not part of the best chain. + Normal, + /// Latest best block. + Best, +} + /// Remote call response. #[derive(Debug, PartialEq, Eq, Clone, Encode, Decode)] pub struct RemoteCallResponse { @@ -127,12 +136,13 @@ pub struct RemoteReadResponse { /// Generic types. pub mod generic { - use codec::{Encode, Decode}; + use codec::{Encode, Decode, Input, Output}; use sr_primitives::Justification; use crate::config::Roles; use super::{ RemoteReadResponse, Transactions, Direction, RequestId, BlockAttributes, RemoteCallResponse, ConsensusEngineId, + BlockState, }; /// Consensus is mostly opaque to us #[derive(Debug, PartialEq, Eq, Clone, Encode, Decode)] @@ -257,10 +267,42 @@ pub mod generic { } /// Announce a new complete relay chain block on the network. - #[derive(Debug, PartialEq, Eq, Clone, Encode, Decode)] + #[derive(Debug, PartialEq, Eq, Clone)] pub struct BlockAnnounce { /// New block header. pub header: H, + /// Block state. TODO: Remove `Option` and custom encoding when v4 becomes common. + pub state: Option, + /// Data associated with this block announcement, e.g. a candidate message. + pub data: Option>, + } + + // Custom Encode/Decode impl to maintain backwards compatibility with v3. + // This assumes that the packet contains nothing but the announcement message. + // TODO: Get rid of it once protocol v4 is common. + impl Encode for BlockAnnounce { + fn encode_to(&self, dest: &mut T) { + self.header.encode_to(dest); + if let Some(state) = &self.state { + state.encode_to(dest); + } + if let Some(data) = &self.data { + data.encode_to(dest) + } + } + } + + impl Decode for BlockAnnounce { + fn decode(input: &mut I) -> Result { + let header = H::decode(input)?; + let state = BlockState::decode(input).ok(); + let data = Vec::decode(input).ok(); + Ok(BlockAnnounce { + header, + state, + data, + }) + } } #[derive(Debug, PartialEq, Eq, Clone, Encode, Decode)] @@ -284,7 +326,7 @@ pub mod generic { /// Block at which to perform call. pub block: H, /// Storage key. - pub key: Vec, + pub keys: Vec>, } #[derive(Debug, PartialEq, Eq, Clone, Encode, Decode)] @@ -297,7 +339,7 @@ pub mod generic { /// Child Storage key. pub storage_key: Vec, /// Storage key. - pub key: Vec, + pub keys: Vec>, } #[derive(Debug, PartialEq, Eq, Clone, Encode, Decode)] @@ -334,6 +376,8 @@ pub mod generic { pub min: H, /// Hash of the last block that we can use when querying changes. pub max: H, + /// Storage child node key which changes are requested. + pub storage_key: Option>, /// Storage key which changes are requested. pub key: Vec, } diff --git a/core/network/src/protocol/sync.rs b/core/network/src/protocol/sync.rs index bd67c6cde7e6c868b95f340cff32ca398c5aee09..9f9db92289cb6a0f6777b089453208974407690e 100644 --- a/core/network/src/protocol/sync.rs +++ b/core/network/src/protocol/sync.rs @@ -28,11 +28,15 @@ //! use blocks::BlockCollection; -use client::{BlockStatus, ClientInfo, error::Error as ClientError}; -use consensus::{BlockOrigin, import_queue::{IncomingBlock, BlockImportResult, BlockImportError}}; +use client::{ClientInfo, error::Error as ClientError}; +use consensus::{BlockOrigin, BlockStatus, + block_validation::{BlockAnnounceValidator, Validation}, + import_queue::{IncomingBlock, BlockImportResult, BlockImportError} +}; use crate::{ config::{Roles, BoxFinalityProofRequestBuilder}, - message::{self, generic::FinalityProofRequest, BlockAttributes, BlockRequest, BlockResponse, FinalityProofResponse}, + message::{self, generic::FinalityProofRequest, BlockAnnounce, BlockAttributes, BlockRequest, BlockResponse, + FinalityProofResponse}, protocol }; use either::Either; @@ -119,9 +123,14 @@ pub struct ChainSync { queue_blocks: HashSet, /// The best block number that we are currently importing. best_importing_number: NumberFor, + /// Finality proof handler. request_builder: Option>, + /// Explicit sync requests. + sync_requests: HashMap>, /// A flag that caches idle state with no pending requests. is_idle: bool, + /// A type to check incoming block announcements. + block_announce_validator: Box + Send> } /// All the data we have about a Peer that we are trying to sync with @@ -151,6 +160,11 @@ pub struct PeerInfo { pub best_number: NumberFor } +struct SyncRequest { + number: NumberFor, + peers: HashSet, +} + /// The state of syncing between a Peer and ourselves. /// /// Generally two categories, "busy" or `Available`. If busy, the enum @@ -271,7 +285,8 @@ impl ChainSync { role: Roles, client: Arc>, info: &ClientInfo, - request_builder: Option> + request_builder: Option>, + block_announce_validator: Box + Send> ) -> Self { let mut required_block_attributes = BlockAttributes::HEADER | BlockAttributes::JUSTIFICATION; @@ -292,7 +307,9 @@ impl ChainSync { queue_blocks: Default::default(), best_importing_number: Zero::zero(), request_builder, + sync_requests: Default::default(), is_idle: false, + block_announce_validator, } } @@ -441,6 +458,51 @@ impl ChainSync { }) } + /// Request syncing for the given block from given set of peers. + // The implementation is similar to on_block_announce with unknown parent hash. + pub fn set_sync_fork_request(&mut self, peers: Vec, hash: &B::Hash, number: NumberFor) { + if peers.is_empty() { + if let Some(_) = self.sync_requests.remove(hash) { + debug!(target: "sync", "Cleared sync request for block {:?} with {:?}", hash, peers); + } + return; + } + debug!(target: "sync", "Explicit sync request for block {:?} with {:?}", hash, peers); + if self.is_known(&hash) { + debug!(target: "sync", "Refusing to sync known hash {:?}", hash); + return; + } + + let block_status = self.client.block_status(&BlockId::Number(number - One::one())) + .unwrap_or(BlockStatus::Unknown); + if block_status == BlockStatus::InChainPruned { + trace!(target: "sync", "Refusing to sync ancient block {:?}", hash); + return; + } + + self.is_idle = false; + for peer_id in &peers { + if let Some(peer) = self.peers.get_mut(peer_id) { + if let PeerSyncState::AncestorSearch(_, _) = peer.state { + continue; + } + + if number > peer.best_number { + peer.best_number = number; + peer.best_hash = hash.clone(); + } + } + } + + self.sync_requests + .entry(hash.clone()) + .or_insert_with(|| SyncRequest { + number, + peers: Default::default(), + }) + .peers.extend(peers); + } + /// Get an iterator over all scheduled justification requests. pub fn justification_requests(&mut self) -> impl Iterator)> + '_ { let peers = &mut self.peers; @@ -500,13 +562,21 @@ impl ChainSync { } let blocks = &mut self.blocks; let attrs = &self.required_block_attributes; + let sync_requests = &self.sync_requests; let mut have_requests = false; + let last_finalized = self.client.info().chain.finalized_number; + let best_queued = self.best_queued_number; let iter = self.peers.iter_mut().filter_map(move |(id, peer)| { if !peer.state.is_available() { trace!(target: "sync", "Peer {} is busy", id); return None } - if let Some((range, req)) = peer_block_request(id, peer, blocks, attrs) { + if let Some((hash, req)) = explicit_sync_request(id, sync_requests, best_queued, last_finalized, attrs) { + trace!(target: "sync", "Downloading explicitly requested block {:?} from {}", hash, id); + peer.state = PeerSyncState::DownloadingStale(hash); + have_requests = true; + Some((id.clone(), req)) + } else if let Some((range, req)) = peer_block_request(id, peer, blocks, attrs) { peer.state = PeerSyncState::DownloadingNew(range.start); trace!(target: "sync", "New block request for {}", id); have_requests = true; @@ -659,8 +729,6 @@ impl ChainSync { peer.state = PeerSyncState::Available; // We only request one justification at a time - debug_assert_eq!(1, response.blocks.len()); - if let Some(block) = response.blocks.into_iter().next() { if hash != block.hash { info!( @@ -815,12 +883,7 @@ impl ChainSync { /// with or without errors. pub fn on_justification_import(&mut self, hash: B::Hash, number: NumberFor, success: bool) { let finalization_result = if success { Ok((hash, number)) } else { Err(()) }; - if !self.extra_justifications.try_finalize_root((hash, number), finalization_result, true) { - debug!(target: "sync", "Got justification import result for unknown justification {:?} {:?} request.", - hash, - number, - ) - } + self.extra_justifications.try_finalize_root((hash, number), finalization_result, true); self.is_idle = false; } @@ -859,6 +922,9 @@ impl ChainSync { self.best_queued_number = number; self.best_queued_hash = *hash; } + if let Some(_) = self.sync_requests.remove(&hash) { + trace!(target: "sync", "Completed explicit sync request {:?}", hash); + } // Update common blocks for (n, peer) in self.peers.iter_mut() { if let PeerSyncState::AncestorSearch(_, _) = peer.state { @@ -890,7 +956,10 @@ impl ChainSync { /// header (call `on_block_data`). The network request isn't sent /// in this case. Both hash and header is passed as an optimization /// to avoid rehashing the header. - pub fn on_block_announce(&mut self, who: PeerId, hash: B::Hash, header: &B::Header) -> OnBlockAnnounce { + pub fn on_block_announce(&mut self, who: PeerId, hash: B::Hash, announce: &BlockAnnounce, is_best: bool) + -> OnBlockAnnounce + { + let header = &announce.header; let number = *header.number(); debug!(target: "sync", "Received block announcement with number {:?}", number); if number.is_zero() { @@ -912,7 +981,7 @@ impl ChainSync { peer.recently_announced.pop_front(); } peer.recently_announced.push_back(hash.clone()); - if number > peer.best_number { + if is_best && number > peer.best_number { // update their best block peer.best_number = number; peer.best_hash = hash; @@ -920,12 +989,12 @@ impl ChainSync { if let PeerSyncState::AncestorSearch(_, _) = peer.state { return OnBlockAnnounce::Nothing } - // We assume that the announced block is the latest they have seen, and so our common number + // If the announced block is the best they have seen, our common number // is either one further ahead or it's the one they just announced, if we know about it. - if header.parent_hash() == &self.best_queued_hash || known_parent { - peer.common_number = number - One::one(); - } else if known { + if known && is_best { peer.common_number = number + } else if header.parent_hash() == &self.best_queued_hash || known_parent { + peer.common_number = number - One::one(); } self.is_idle = false; @@ -935,6 +1004,20 @@ impl ChainSync { return OnBlockAnnounce::Nothing } + // Let external validator check the block announcement. + let assoc_data = announce.data.as_ref().map_or(&[][..], |v| v.as_slice()); + match self.block_announce_validator.validate(&header, assoc_data) { + Ok(Validation::Success) => (), + Ok(Validation::Failure) => { + debug!(target: "sync", "block announcement validation of block {} from {} failed", hash, who); + return OnBlockAnnounce::Nothing + } + Err(e) => { + error!(target: "sync", "block announcement validation errored: {}", e); + return OnBlockAnnounce::Nothing + } + } + // stale block case let requires_additional_data = !self.role.is_light(); if number <= self.best_queued_number { @@ -1214,3 +1297,31 @@ fn peer_block_request( None } } + +/// Get pending explicit sync request for a peer. +fn explicit_sync_request( + id: &PeerId, + requests: &HashMap>, + best_num: NumberFor, + finalized: NumberFor, + attributes: &message::BlockAttributes, +) -> Option<(B::Hash, BlockRequest)> +{ + for (hash, r) in requests { + if !r.peers.contains(id) { + continue + } + if r.number <= best_num { + trace!(target: "sync", "Downloading requested fork {:?} from {}", hash, id); + return Some((hash.clone(), message::generic::BlockRequest { + id: 0, + fields: attributes.clone(), + from: message::FromBlock::Hash(hash.clone()), + to: None, + direction: message::Direction::Descending, + max: Some((r.number - finalized).saturated_into::()), // up to the last finalized block + })) + } + } + None +} diff --git a/core/network/src/protocol/sync/extra_requests.rs b/core/network/src/protocol/sync/extra_requests.rs index 0ee009cab8689a63a1831ee2f94fab6b722731d2..28ed5fed9f6829a7894f7cc18b7c578a6977ff2c 100644 --- a/core/network/src/protocol/sync/extra_requests.rs +++ b/core/network/src/protocol/sync/extra_requests.rs @@ -18,8 +18,8 @@ use client::error::Error as ClientError; use crate::protocol::sync::{PeerSync, PeerSyncState}; use fork_tree::ForkTree; use libp2p::PeerId; -use log::warn; -use sr_primitives::traits::{Block as BlockT, NumberFor}; +use log::{debug, warn}; +use sr_primitives::traits::{Block as BlockT, NumberFor, Zero}; use std::collections::{HashMap, HashSet, VecDeque}; use std::time::{Duration, Instant}; @@ -38,6 +38,8 @@ pub(crate) type ExtraRequest = (::Hash, NumberFor); #[derive(Debug)] pub(crate) struct ExtraRequests { tree: ForkTree, ()>, + /// best finalized block number that we have seen since restart + best_seen_finalized_number: NumberFor, /// requests which have been queued for later processing pending_requests: VecDeque>, /// requests which are currently underway to some peer @@ -52,6 +54,7 @@ impl ExtraRequests { pub(crate) fn new() -> Self { ExtraRequests { tree: ForkTree::new(), + best_seen_finalized_number: Zero::zero(), pending_requests: VecDeque::new(), active_requests: HashMap::new(), failed_requests: HashMap::new(), @@ -80,11 +83,17 @@ impl ExtraRequests { match self.tree.import(request.0, request.1, (), &is_descendent_of) { Ok(true) => { // this is a new root so we add it to the current `pending_requests` - self.pending_requests.push_back((request.0, request.1)) + self.pending_requests.push_back((request.0, request.1)); } + Err(fork_tree::Error::Revert) => { + // we have finalized further than the given request, presumably + // by some other part of the system (not sync). we can safely + // ignore the `Revert` error. + return; + }, Err(err) => { - warn!(target: "sync", "Failed to insert request {:?} into tree: {:?}", request, err); - return + debug!(target: "sync", "Failed to insert request {:?} into tree: {:?}", request, err); + return; } _ => () } @@ -93,7 +102,7 @@ impl ExtraRequests { /// Retry any pending request if a peer disconnected. pub(crate) fn peer_disconnected(&mut self, who: &PeerId) { if let Some(request) = self.active_requests.remove(who) { - self.pending_requests.push_front(request) + self.pending_requests.push_front(request); } } @@ -128,7 +137,25 @@ impl ExtraRequests { return Ok(()) } - self.tree.finalize(best_finalized_hash, best_finalized_number, &is_descendent_of)?; + if best_finalized_number > self.best_seen_finalized_number { + // normally we'll receive finality notifications for every block => finalize would be enough + // but if many blocks are finalized at once, some notifications may be omitted + // => let's use finalize_with_ancestors here + match self.tree.finalize_with_ancestors( + best_finalized_hash, + best_finalized_number, + &is_descendent_of, + ) { + Err(fork_tree::Error::Revert) => { + // we might have finalized further already in which case we + // will get a `Revert` error which we can safely ignore. + }, + Err(err) => return Err(err), + Ok(_) => {}, + } + + self.best_seen_finalized_number = best_finalized_number; + } let roots = self.tree.roots().collect::>(); @@ -176,6 +203,7 @@ impl ExtraRequests { self.active_requests.clear(); self.pending_requests.clear(); self.pending_requests.extend(self.tree.roots().map(|(&h, &n, _)| (h, n))); + self.best_seen_finalized_number = finalized_number; true } @@ -412,6 +440,26 @@ mod tests { assert_eq!(finality_proofs.pending_requests.iter().collect::>(), Vec::<&(Hash, u64)>::new()); } + #[test] + fn anecstor_roots_are_finalized_when_finality_notification_is_missed() { + let mut finality_proofs = ExtraRequests::::new(); + + let hash4 = [4; 32].into(); + let hash5 = [5; 32].into(); + + fn is_descendent_of(base: &Hash, target: &Hash) -> Result { + Ok(target[0] >= base[0]) + } + + // schedule request for #4 + finality_proofs.schedule((hash4, 4), is_descendent_of); + + // receive finality notification for #5 (missing notification for #4!!!) + finality_proofs.importing_requests.insert((hash4, 5)); + finality_proofs.on_block_finalized(&hash5, 5, is_descendent_of).unwrap(); + assert_eq!(finality_proofs.tree.roots().count(), 0); + } + // Some Arbitrary instances to allow easy construction of random peer sets: #[derive(Debug, Clone)] diff --git a/core/network/src/service.rs b/core/network/src/service.rs index d5ba8db7ae4885c0c7449043c1085339653c85ea..5e8d41340c1bfc1b523fb5510a142114922387c8 100644 --- a/core/network/src/service.rs +++ b/core/network/src/service.rs @@ -33,7 +33,7 @@ use consensus::import_queue::{BlockImportResult, BlockImportError}; use futures::{prelude::*, sync::mpsc}; use futures03::TryFutureExt as _; use log::{warn, error, info}; -use libp2p::{PeerId, Multiaddr, multihash::Multihash}; +use libp2p::{PeerId, Multiaddr, kad::record}; use libp2p::core::{transport::boxed::Boxed, muxing::StreamMuxerBox}; use libp2p::swarm::NetworkBehaviour; use parking_lot::Mutex; @@ -65,8 +65,18 @@ impl ExHashT for T where pub trait TransactionPool: Send + Sync { /// Get transactions from the pool that are ready to be propagated. fn transactions(&self) -> Vec<(H, B::Extrinsic)>; + /// Get hash of transaction. + fn hash_of(&self, transaction: &B::Extrinsic) -> H; /// Import a transaction into the pool. - fn import(&self, transaction: &B::Extrinsic) -> Option; + /// + /// Peer reputation is changed by reputation_change if transaction is accepted by the pool. + fn import( + &self, + report_handle: ReportHandle, + who: PeerId, + reputation_change: i32, + transaction: B::Extrinsic, + ); /// Notify the pool about transactions broadcast. fn on_broadcasted(&self, propagations: HashMap>); } @@ -77,6 +87,12 @@ pub struct ReportHandle { inner: PeersetHandle, // wraps it so we don't have to worry about breaking API. } +impl From for ReportHandle { + fn from(peerset_handle: PeersetHandle) -> Self { + ReportHandle { inner: peerset_handle } + } +} + impl ReportHandle { /// Report a given peer as either beneficial (+) or costly (-) according to the /// given scalar. @@ -113,9 +129,7 @@ impl, H: ExHashT> NetworkWorker /// Returns a `NetworkWorker` that implements `Future` and must be regularly polled in order /// for the network processing to advance. From it, you can extract a `NetworkService` using /// `worker.service()`. The `NetworkService` can be shared through the codebase. - pub fn new( - params: Params, - ) -> Result, Error> { + pub fn new(params: Params) -> Result, Error> { let (to_worker, from_worker) = mpsc::unbounded(); if let Some(ref path) = params.network_config.net_config_path { @@ -178,6 +192,7 @@ impl, H: ExHashT> NetworkWorker params.finality_proof_request_builder, params.protocol_id, peerset_config, + params.block_announce_validator )?; // Build the swarm. @@ -297,8 +312,8 @@ impl, H: ExHashT> NetworkWorker } /// You must call this when a new block is imported by the client. - pub fn on_block_imported(&mut self, hash: B::Hash, header: B::Header) { - self.network_service.user_protocol_mut().on_block_imported(hash, &header); + pub fn on_block_imported(&mut self, hash: B::Hash, header: B::Header, data: Vec, is_best: bool) { + self.network_service.user_protocol_mut().on_block_imported(hash, &header, data, is_best); } /// You must call this when a new block is finalized by the client. @@ -394,8 +409,8 @@ impl, H: ExHashT> NetworkServic /// /// In chain-based consensus, we often need to make sure non-best forks are /// at least temporarily synced. This function forces such an announcement. - pub fn announce_block(&self, hash: B::Hash) { - let _ = self.to_worker.unbounded_send(ServerToWorkerMsg::AnnounceBlock(hash)); + pub fn announce_block(&self, hash: B::Hash, data: Vec) { + let _ = self.to_worker.unbounded_send(ServerToWorkerMsg::AnnounceBlock(hash, data)); } /// Send a consensus message through the gossip @@ -456,7 +471,7 @@ impl, H: ExHashT> NetworkServic /// /// This will generate either a `ValueFound` or a `ValueNotFound` event and pass it to /// `on_event` on the network specialization. - pub fn get_value(&self, key: &Multihash) { + pub fn get_value(&self, key: &record::Key) { let _ = self .to_worker .unbounded_send(ServerToWorkerMsg::GetValue(key.clone())); @@ -466,7 +481,7 @@ impl, H: ExHashT> NetworkServic /// /// This will generate either a `ValuePut` or a `ValuePutFailed` event and pass it to /// `on_event` on the network specialization. - pub fn put_value(&self, key: Multihash, value: Vec) { + pub fn put_value(&self, key: record::Key, value: Vec) { let _ = self .to_worker .unbounded_send(ServerToWorkerMsg::PutValue(key, value)); @@ -497,6 +512,18 @@ impl, H: ExHashT> NetworkServic Ok(()) } + /// Configure an explicit fork sync request. + /// Note that this function should not be used for recent blocks. + /// Sync should be able to download all the recent forks normally. + /// `set_sync_fork_request` should only be used if external code detects that there's + /// a stale fork missing. + /// Passing empty `peers` set effectively removes the sync request. + pub fn set_sync_fork_request(&self, peers: Vec, hash: B::Hash, number: NumberFor) { + let _ = self + .to_worker + .unbounded_send(ServerToWorkerMsg::SyncFork(peers, hash, number)); + } + /// Modify a peerset priority group. pub fn set_priority_group(&self, group_id: String, peers: HashSet) -> Result<(), String> { let peers = peers.into_iter().map(|p| { @@ -580,13 +607,14 @@ impl NetworkStateInfo for NetworkService enum ServerToWorkerMsg> { PropagateExtrinsics, RequestJustification(B::Hash, NumberFor), - AnnounceBlock(B::Hash), + AnnounceBlock(B::Hash, Vec), ExecuteWithSpec(Box) + Send>), ExecuteWithGossip(Box, &mut dyn Context) + Send>), GossipConsensusMessage(B::Hash, ConsensusEngineId, Vec, GossipMessageRecipient), - GetValue(Multihash), - PutValue(Multihash, Vec), + GetValue(record::Key), + PutValue(record::Key, Vec), AddKnownAddress(PeerId, Multiaddr), + SyncFork(Vec, B::Hash, NumberFor), } /// Main network worker. Must be polled in order for the network to advance. @@ -612,11 +640,11 @@ pub struct NetworkWorker, H: Ex light_client_rqs: Option>>, } -impl, H: ExHashT> Future for NetworkWorker { - type Item = (); +impl, H: ExHashT> Stream for NetworkWorker { + type Item = Event; type Error = io::Error; - fn poll(&mut self) -> Poll { + fn poll(&mut self) -> Poll, Self::Error> { // Poll the import queue for actions to perform. let _ = futures03::future::poll_fn(|cx| { self.import_queue.poll_actions(cx, &mut NetworkLink { @@ -636,7 +664,7 @@ impl, H: ExHashT> Future for Ne // Process the next message coming from the `NetworkService`. let msg = match self.from_worker.poll() { Ok(Async::Ready(Some(msg))) => msg, - Ok(Async::Ready(None)) | Err(_) => return Ok(Async::Ready(())), + Ok(Async::Ready(None)) | Err(_) => return Ok(Async::Ready(None)), Ok(Async::NotReady) => break, }; @@ -653,8 +681,8 @@ impl, H: ExHashT> Future for Ne } ServerToWorkerMsg::GossipConsensusMessage(topic, engine_id, message, recipient) => self.network_service.user_protocol_mut().gossip_consensus_message(topic, engine_id, message, recipient), - ServerToWorkerMsg::AnnounceBlock(hash) => - self.network_service.user_protocol_mut().announce_block(hash), + ServerToWorkerMsg::AnnounceBlock(hash, data) => + self.network_service.user_protocol_mut().announce_block(hash, data), ServerToWorkerMsg::RequestJustification(hash, number) => self.network_service.user_protocol_mut().request_justification(&hash, number), ServerToWorkerMsg::PropagateExtrinsics => @@ -665,6 +693,8 @@ impl, H: ExHashT> Future for Ne self.network_service.put_value(key, value), ServerToWorkerMsg::AddKnownAddress(peer_id, addr) => self.network_service.add_known_address(peer_id, addr), + ServerToWorkerMsg::SyncFork(peer_ids, hash, number) => + self.network_service.user_protocol_mut().set_sync_fork_request(peer_ids, &hash, number), } } @@ -677,8 +707,9 @@ impl, H: ExHashT> Future for Ne Ok(Async::Ready(Some(BehaviourOut::SubstrateAction(outcome)))) => outcome, Ok(Async::Ready(Some(BehaviourOut::Dht(ev)))) => { self.network_service.user_protocol_mut() - .on_event(Event::Dht(ev)); - CustomMessageOutcome::None + .on_event(Event::Dht(ev.clone())); + + return Ok(Async::Ready(Some(Event::Dht(ev)))); }, Ok(Async::Ready(None)) => CustomMessageOutcome::None, Err(err) => { diff --git a/core/network/src/test/block_import.rs b/core/network/src/test/block_import.rs index ceb0451166c9e0d14f023ec9d2818ea2dba73adf..f2830548a501a500420282b6034d2dd62b7be03c 100644 --- a/core/network/src/test/block_import.rs +++ b/core/network/src/test/block_import.rs @@ -16,8 +16,9 @@ //! Testing block import logic. +use consensus::ImportedAux; use consensus::import_queue::{ - import_single_block, IncomingBlock, BasicQueue, BlockImportError, BlockImportResult + import_single_block, BasicQueue, BlockImportError, BlockImportResult, IncomingBlock, }; use test_client::{self, prelude::*}; use test_client::runtime::{Block, Hash}; @@ -45,9 +46,13 @@ fn prepare_good_block() -> (TestClient, Hash, u64, PeerId, IncomingBlock) #[test] fn import_single_good_block_works() { let (_, _hash, number, peer_id, block) = prepare_good_block(); + + let mut expected_aux = ImportedAux::default(); + expected_aux.is_new_best = true; + match import_single_block(&mut test_client::new(), BlockOrigin::File, block, &mut PassThroughVerifier(true)) { Ok(BlockImportResult::ImportedUnknown(ref num, ref aux, ref org)) - if *num == number && *aux == Default::default() && *org == Some(peer_id) => {} + if *num == number && *aux == expected_aux && *org == Some(peer_id) => {} _ => panic!() } } diff --git a/core/network/src/test/mod.rs b/core/network/src/test/mod.rs index 091047394b688f1b096f9fc43fb246ce038dd753..2c87ba1ac8593e9d8cacf0e1830cd164c0a6439a 100644 --- a/core/network/src/test/mod.rs +++ b/core/network/src/test/mod.rs @@ -27,25 +27,31 @@ use std::sync::Arc; use crate::config::build_multiaddr; use log::trace; use crate::chain::FinalityProofProvider; -use client::{self, ClientInfo, BlockchainEvents, BlockImportNotification, FinalityNotifications, FinalityNotification}; -use client::{in_mem::Backend as InMemoryBackend, error::Result as ClientResult}; +use client::{ + self, ClientInfo, BlockchainEvents, BlockImportNotification, + FinalityNotifications, ImportNotifications, + FinalityNotification, LongestChain, + error::Result as ClientResult, + well_known_cache_keys::{self, Id as CacheKeyId}, +}; use client::block_builder::BlockBuilder; -use client::backend::AuxStore; +use client::backend::{AuxStore, Backend, Finalizer}; use crate::config::Roles; +use consensus::block_validation::DefaultBlockAnnounceValidator; use consensus::import_queue::BasicQueue; use consensus::import_queue::{ BoxBlockImport, BoxJustificationImport, Verifier, BoxFinalityProofImport, }; use consensus::block_import::{BlockImport, ImportResult}; -use consensus::{Error as ConsensusError, well_known_cache_keys::{self, Id as CacheKeyId}}; -use consensus::{BlockOrigin, ForkChoiceStrategy, BlockImportParams, JustificationImport}; +use consensus::Error as ConsensusError; +use consensus::{BlockOrigin, ForkChoiceStrategy, BlockImportParams, BlockCheckParams, JustificationImport}; use futures::prelude::*; use futures03::{StreamExt as _, TryStreamExt as _}; -use crate::{NetworkWorker, NetworkService, config::ProtocolId}; +use crate::{NetworkWorker, NetworkService, ReportHandle, config::ProtocolId}; use crate::config::{NetworkConfiguration, TransportConfig, BoxFinalityProofRequestBuilder}; use libp2p::PeerId; use parking_lot::Mutex; -use primitives::{H256, Blake2Hasher}; +use primitives::H256; use crate::protocol::{Context, ProtocolConfig}; use sr_primitives::generic::{BlockId, OpaqueDigestItemId}; use sr_primitives::traits::{Block as BlockT, Header, NumberFor}; @@ -55,13 +61,14 @@ use crate::specialization::NetworkSpecialization; use test_client::{self, AccountKeyring}; pub use test_client::runtime::{Block, Extrinsic, Hash, Transfer}; -pub use test_client::TestClient; +pub use test_client::{TestClient, TestClientBuilder, TestClientBuilderExt}; type AuthorityId = babe_primitives::AuthorityId; #[cfg(any(test, feature = "test-helpers"))] /// A Verifier that accepts all blocks and passes them on with the configured /// finality to be imported. +#[derive(Clone)] pub struct PassThroughVerifier(pub bool); #[cfg(any(test, feature = "test-helpers"))] @@ -131,66 +138,64 @@ pub type PeersLightClient = #[derive(Clone)] pub enum PeersClient { - Full(Arc), - Light(Arc), + Full(Arc, Arc), + Light(Arc, Arc), } impl PeersClient { pub fn as_full(&self) -> Option> { match *self { - PeersClient::Full(ref client) => Some(client.clone()), + PeersClient::Full(ref client, ref _backend) => Some(client.clone()), _ => None, } } pub fn as_block_import(&self) -> BoxBlockImport { match *self { - PeersClient::Full(ref client) => Box::new(client.clone()) as _, - PeersClient::Light(ref client) => Box::new(client.clone()) as _, - } - } - - pub fn as_in_memory_backend(&self) -> InMemoryBackend { - #[allow(deprecated)] - match *self { - PeersClient::Full(ref client) => client.backend().as_in_memory(), - PeersClient::Light(_) => unimplemented!("TODO"), + PeersClient::Full(ref client, ref _backend) => Box::new(client.clone()) as _, + PeersClient::Light(ref client, ref _backend) => Box::new(client.clone()) as _, } } pub fn get_aux(&self, key: &[u8]) -> ClientResult>> { - #[allow(deprecated)] match *self { - PeersClient::Full(ref client) => client.backend().get_aux(key), - PeersClient::Light(ref client) => client.backend().get_aux(key), + PeersClient::Full(ref client, ref _backend) => client.get_aux(key), + PeersClient::Light(ref client, ref _backend) => client.get_aux(key), } } pub fn info(&self) -> ClientInfo { match *self { - PeersClient::Full(ref client) => client.info(), - PeersClient::Light(ref client) => client.info(), + PeersClient::Full(ref client, ref _backend) => client.info(), + PeersClient::Light(ref client, ref _backend) => client.info(), } } pub fn header(&self, block: &BlockId) -> ClientResult::Header>> { match *self { - PeersClient::Full(ref client) => client.header(block), - PeersClient::Light(ref client) => client.header(block), + PeersClient::Full(ref client, ref _backend) => client.header(block), + PeersClient::Light(ref client, ref _backend) => client.header(block), } } pub fn justification(&self, block: &BlockId) -> ClientResult> { match *self { - PeersClient::Full(ref client) => client.justification(block), - PeersClient::Light(ref client) => client.justification(block), + PeersClient::Full(ref client, ref _backend) => client.justification(block), + PeersClient::Light(ref client, ref _backend) => client.justification(block), } } pub fn finality_notification_stream(&self) -> FinalityNotifications { match *self { - PeersClient::Full(ref client) => client.finality_notification_stream(), - PeersClient::Light(ref client) => client.finality_notification_stream(), + PeersClient::Full(ref client, ref _backend) => client.finality_notification_stream(), + PeersClient::Light(ref client, ref _backend) => client.finality_notification_stream(), + } + } + + pub fn import_notification_stream(&self) -> ImportNotifications{ + match *self { + PeersClient::Full(ref client, ref _backend) => client.import_notification_stream(), + PeersClient::Light(ref client, ref _backend) => client.import_notification_stream(), } } @@ -201,8 +206,8 @@ impl PeersClient { notify: bool ) -> ClientResult<()> { match *self { - PeersClient::Full(ref client) => client.finalize_block(id, justification, notify), - PeersClient::Light(ref client) => client.finalize_block(id, justification, notify), + PeersClient::Full(ref client, ref _backend) => client.finalize_block(id, justification, notify), + PeersClient::Light(ref client, ref _backend) => client.finalize_block(id, justification, notify), } } } @@ -216,17 +221,29 @@ pub struct Peer> { /// We keep a copy of the block_import so that we can invoke it for locally-generated blocks, /// instead of going through the import queue. block_import: Box>, + select_chain: Option>, + backend: Option>, network: NetworkWorker::Hash>, imported_blocks_stream: Box, Error = ()> + Send>, finality_notification_stream: Box, Error = ()> + Send>, } impl> Peer { + /// Get this peer ID. + pub fn id(&self) -> PeerId { + self.network.service().local_peer_id() + } + /// Returns true if we're major syncing. pub fn is_major_syncing(&self) -> bool { self.network.service().is_major_syncing() } + // Returns a clone of the local SelectChain, only available on full nodes + pub fn select_chain(&self) -> Option> { + self.select_chain.clone() + } + /// Returns the number of peers we're connected to. pub fn num_peers(&self) -> usize { self.network.num_connected_peers() @@ -243,8 +260,13 @@ impl> Peer { } /// Announces an important block on the network. - pub fn announce_block(&self, hash: ::Hash) { - self.network.service().announce_block(hash); + pub fn announce_block(&self, hash: ::Hash, data: Vec) { + self.network.service().announce_block(hash, data); + } + + /// Request explicit fork sync. + pub fn set_sync_fork_request(&self, peers: Vec, hash: ::Hash, number: NumberFor) { + self.network.service().set_sync_fork_request(peers, hash, number); } /// Add blocks to the peer -- edit the block before adding @@ -291,11 +313,11 @@ impl> Peer { Default::default() }; self.block_import.import_block(import_block, cache).expect("block_import failed"); - self.network.on_block_imported(hash, header); + self.network.on_block_imported(hash, header, Vec::new(), true); at = hash; } - self.network.service().announce_block(at.clone()); + self.network.service().announce_block(at.clone(), Vec::new()); at } @@ -342,6 +364,33 @@ impl> Peer { pub fn network_service(&self) -> &Arc::Hash>> { &self.network.service() } + + /// Test helper to compare the blockchain state of multiple (networked) + /// clients. + /// Potentially costly, as it creates in-memory copies of both blockchains in order + /// to compare them. If you have easier/softer checks that are sufficient, e.g. + /// by using .info(), you should probably use it instead of this. + pub fn blockchain_canon_equals(&self, other: &Self) -> bool { + if let (Some(mine), Some(others)) = (self.backend.clone(), other.backend.clone()) { + mine.as_in_memory().blockchain() + .canon_equals_to(others.as_in_memory().blockchain()) + } else { + false + } + } + + /// Count the current number of known blocks. Note that: + /// 1. this might be expensive as it creates an in-memory-copy of the chain + /// to count the blocks, thus if you have a different way of testing this + /// (e.g. `info.best_hash`) - use that. + /// 2. This is not always increasing nor accurate, as the + /// orphaned and proven-to-never-finalized blocks may be pruned at any time. + /// Therefore, this number can drop again. + pub fn blocks_count(&self) -> usize { + self.backend.as_ref().map( + |backend| backend.as_in_memory().blockchain().blocks_count() + ).unwrap_or(0) + } } pub struct EmptyTransactionPool; @@ -351,10 +400,12 @@ impl TransactionPool for EmptyTransactionPool { Vec::new() } - fn import(&self, _transaction: &Extrinsic) -> Option { - None + fn hash_of(&self, _transaction: &Extrinsic) -> Hash { + Hash::default() } + fn import(&self, _report_handle: ReportHandle, _who: PeerId, _rep_change: i32, _transaction: Extrinsic) {} + fn on_broadcasted(&self, _: HashMap>) {} } @@ -382,8 +433,11 @@ impl Clone for BlockImportAdapter { impl> BlockImport for BlockImportAdapter { type Error = T::Error; - fn check_block(&mut self, hash: Hash, parent_hash: Hash) -> Result { - self.0.lock().check_block(hash, parent_hash) + fn check_block( + &mut self, + block: BlockCheckParams, + ) -> Result { + self.0.lock().check_block(block) } fn import_block( @@ -423,7 +477,12 @@ pub trait TestNetFactory: Sized { /// These two need to be implemented! fn from_config(config: &ProtocolConfig) -> Self; - fn make_verifier(&self, client: PeersClient, config: &ProtocolConfig) -> Self::Verifier; + fn make_verifier( + &self, + client: PeersClient, + config: &ProtocolConfig, + peer_data: &Self::PeerData, + ) -> Self::Verifier; /// Get reference to peer. fn peer(&mut self, i: usize) -> &mut Peer; @@ -467,13 +526,27 @@ pub trait TestNetFactory: Sized { /// Add a full peer. fn add_full_peer(&mut self, config: &ProtocolConfig) { - let client = Arc::new(test_client::new()); - let verifier = self.make_verifier(PeersClient::Full(client.clone()), config); - let verifier = VerifierAdapter(Arc::new(Mutex::new(Box::new(verifier) as Box<_>))); - let (block_import, justification_import, finality_proof_import, finality_proof_request_builder, data) - = self.make_block_import(PeersClient::Full(client.clone())); + let test_client_builder = TestClientBuilder::with_default_backend(); + let backend = test_client_builder.backend(); + let (c, longest_chain) = test_client_builder.build_with_longest_chain(); + let client = Arc::new(c); + + let ( + block_import, + justification_import, + finality_proof_import, + finality_proof_request_builder, + data, + ) = self.make_block_import(PeersClient::Full(client.clone(), backend.clone())); let block_import = BlockImportAdapter(Arc::new(Mutex::new(block_import))); + let verifier = self.make_verifier( + PeersClient::Full(client.clone(), backend.clone()), + config, + &data, + ); + let verifier = VerifierAdapter(Arc::new(Mutex::new(Box::new(verifier) as Box<_>))); + let import_queue = Box::new(BasicQueue::new( verifier.clone(), Box::new(block_import.clone()), @@ -491,13 +564,14 @@ pub trait TestNetFactory: Sized { ..NetworkConfiguration::default() }, chain: client.clone(), - finality_proof_provider: self.make_finality_proof_provider(PeersClient::Full(client.clone())), + finality_proof_provider: self.make_finality_proof_provider(PeersClient::Full(client.clone(), backend.clone())), finality_proof_request_builder, on_demand: None, transaction_pool: Arc::new(EmptyTransactionPool), protocol_id: ProtocolId::from(&b"test-protocol-name"[..]), import_queue, specialization: self::SpecializationFactory::create(), + block_announce_validator: Box::new(DefaultBlockAnnounceValidator::new(client.clone())) }).unwrap(); self.mut_peers(|peers| { @@ -512,7 +586,9 @@ pub trait TestNetFactory: Sized { peers.push(Peer { data, - client: PeersClient::Full(client), + client: PeersClient::Full(client, backend.clone()), + select_chain: Some(longest_chain), + backend: Some(backend), imported_blocks_stream, finality_notification_stream, block_import: Box::new(block_import), @@ -527,13 +603,24 @@ pub trait TestNetFactory: Sized { let mut config = config.clone(); config.roles = Roles::LIGHT; - let client = Arc::new(test_client::new_light()); - let verifier = self.make_verifier(PeersClient::Light(client.clone()), &config); - let verifier = VerifierAdapter(Arc::new(Mutex::new(Box::new(verifier) as Box<_>))); - let (block_import, justification_import, finality_proof_import, finality_proof_request_builder, data) - = self.make_block_import(PeersClient::Light(client.clone())); + let (c, backend) = test_client::new_light(); + let client = Arc::new(c); + let ( + block_import, + justification_import, + finality_proof_import, + finality_proof_request_builder, + data, + ) = self.make_block_import(PeersClient::Light(client.clone(), backend.clone())); let block_import = BlockImportAdapter(Arc::new(Mutex::new(block_import))); + let verifier = self.make_verifier( + PeersClient::Light(client.clone(), backend.clone()), + &config, + &data, + ); + let verifier = VerifierAdapter(Arc::new(Mutex::new(Box::new(verifier) as Box<_>))); + let import_queue = Box::new(BasicQueue::new( verifier.clone(), Box::new(block_import.clone()), @@ -551,13 +638,14 @@ pub trait TestNetFactory: Sized { ..NetworkConfiguration::default() }, chain: client.clone(), - finality_proof_provider: self.make_finality_proof_provider(PeersClient::Light(client.clone())), + finality_proof_provider: self.make_finality_proof_provider(PeersClient::Light(client.clone(), backend.clone())), finality_proof_request_builder, on_demand: None, transaction_pool: Arc::new(EmptyTransactionPool), protocol_id: ProtocolId::from(&b"test-protocol-name"[..]), import_queue, specialization: self::SpecializationFactory::create(), + block_announce_validator: Box::new(DefaultBlockAnnounceValidator::new(client.clone())) }).unwrap(); self.mut_peers(|peers| { @@ -573,8 +661,10 @@ pub trait TestNetFactory: Sized { peers.push(Peer { data, verifier, + select_chain: None, + backend: None, block_import: Box::new(block_import), - client: PeersClient::Light(client), + client: PeersClient::Light(client, backend), imported_blocks_stream, finality_notification_stream, network, @@ -618,7 +708,7 @@ pub trait TestNetFactory: Sized { // We poll `imported_blocks_stream`. while let Ok(Async::Ready(Some(notification))) = peer.imported_blocks_stream.poll() { - peer.network.on_block_imported(notification.hash, notification.header); + peer.network.on_block_imported(notification.hash, notification.header, Vec::new(), true); } // We poll `finality_notification_stream`, but we only take the last event. @@ -650,7 +740,7 @@ impl TestNetFactory for TestNet { } } - fn make_verifier(&self, _client: PeersClient, _config: &ProtocolConfig) + fn make_verifier(&self, _client: PeersClient, _config: &ProtocolConfig, _peer_data: &()) -> Self::Verifier { PassThroughVerifier(false) @@ -696,8 +786,8 @@ impl TestNetFactory for JustificationTestNet { JustificationTestNet(TestNet::from_config(config)) } - fn make_verifier(&self, client: PeersClient, config: &ProtocolConfig) -> Self::Verifier { - self.0.make_verifier(client, config) + fn make_verifier(&self, client: PeersClient, config: &ProtocolConfig, peer_data: &()) -> Self::Verifier { + self.0.make_verifier(client, config, peer_data) } fn peer(&mut self, i: usize) -> &mut Peer { diff --git a/core/network/src/test/sync.rs b/core/network/src/test/sync.rs index f3a8f0c8ea4281cf1fdf054d892fc1441ab2a93d..b5b137a31ac85cef77adeac95301e2cf1ad4329c 100644 --- a/core/network/src/test/sync.rs +++ b/core/network/src/test/sync.rs @@ -14,7 +14,6 @@ // You should have received a copy of the GNU General Public License // along with Substrate. If not, see . -use client::{backend::Backend, blockchain::HeaderBackend}; use crate::config::Roles; use consensus::BlockOrigin; use futures03::TryFutureExt as _; @@ -36,8 +35,8 @@ fn test_ancestor_search_when_common_is(n: usize) { net.peer(2).push_blocks(100, false); net.block_until_sync(&mut runtime); - assert!(net.peer(0).client.as_in_memory_backend().blockchain() - .canon_equals_to(net.peer(1).client.as_in_memory_backend().blockchain())); + let peer1 = &net.peers()[1]; + assert!(net.peers()[0].blockchain_canon_equals(peer1)); } #[test] @@ -156,8 +155,8 @@ fn sync_from_two_peers_works() { net.peer(1).push_blocks(100, false); net.peer(2).push_blocks(100, false); net.block_until_sync(&mut runtime); - assert!(net.peer(0).client.as_in_memory_backend().blockchain() - .equals_to(net.peer(1).client.as_in_memory_backend().blockchain())); + let peer1 = &net.peers()[1]; + assert!(net.peers()[0].blockchain_canon_equals(peer1)); assert!(!net.peer(0).is_major_syncing()); } @@ -170,8 +169,8 @@ fn sync_from_two_peers_with_ancestry_search_works() { net.peer(1).push_blocks(100, false); net.peer(2).push_blocks(100, false); net.block_until_sync(&mut runtime); - assert!(net.peer(0).client.as_in_memory_backend().blockchain() - .canon_equals_to(net.peer(1).client.as_in_memory_backend().blockchain())); + let peer1 = &net.peers()[1]; + assert!(net.peers()[0].blockchain_canon_equals(peer1)); } #[test] @@ -185,8 +184,8 @@ fn ancestry_search_works_when_backoff_is_one() { net.peer(2).push_blocks(2, false); net.block_until_sync(&mut runtime); - assert!(net.peer(0).client.as_in_memory_backend().blockchain() - .canon_equals_to(net.peer(1).client.as_in_memory_backend().blockchain())); + let peer1 = &net.peers()[1]; + assert!(net.peers()[0].blockchain_canon_equals(peer1)); } #[test] @@ -200,8 +199,8 @@ fn ancestry_search_works_when_ancestor_is_genesis() { net.peer(2).push_blocks(100, false); net.block_until_sync(&mut runtime); - assert!(net.peer(0).client.as_in_memory_backend().blockchain() - .canon_equals_to(net.peer(1).client.as_in_memory_backend().blockchain())); + let peer1 = &net.peers()[1]; + assert!(net.peers()[0].blockchain_canon_equals(peer1)); } #[test] @@ -226,8 +225,8 @@ fn sync_long_chain_works() { let mut net = TestNet::new(2); net.peer(1).push_blocks(500, false); net.block_until_sync(&mut runtime); - assert!(net.peer(0).client.as_in_memory_backend().blockchain() - .equals_to(net.peer(1).client.as_in_memory_backend().blockchain())); + let peer1 = &net.peers()[1]; + assert!(net.peers()[0].blockchain_canon_equals(peer1)); } #[test] @@ -238,8 +237,8 @@ fn sync_no_common_longer_chain_fails() { net.peer(0).push_blocks(20, true); net.peer(1).push_blocks(20, false); net.block_until_sync(&mut runtime); - assert!(!net.peer(0).client.as_in_memory_backend().blockchain() - .canon_equals_to(net.peer(1).client.as_in_memory_backend().blockchain())); + let peer1 = &net.peers()[1]; + assert!(!net.peers()[0].blockchain_canon_equals(peer1)); } #[test] @@ -334,11 +333,11 @@ fn sync_after_fork_works() { net.peer(2).push_blocks(1, false); // peer 1 has the best chain - let peer1_chain = net.peer(1).client.as_in_memory_backend().blockchain().clone(); net.block_until_sync(&mut runtime); - assert!(net.peer(0).client.as_in_memory_backend().blockchain().canon_equals_to(&peer1_chain)); - assert!(net.peer(1).client.as_in_memory_backend().blockchain().canon_equals_to(&peer1_chain)); - assert!(net.peer(2).client.as_in_memory_backend().blockchain().canon_equals_to(&peer1_chain)); + let peer1 = &net.peers()[1]; + assert!(net.peers()[0].blockchain_canon_equals(peer1)); + (net.peers()[1].blockchain_canon_equals(peer1)); + (net.peers()[2].blockchain_canon_equals(peer1)); } #[test] @@ -354,8 +353,8 @@ fn syncs_all_forks() { net.block_until_sync(&mut runtime); // Check that all peers have all of the blocks. - assert_eq!(9, net.peer(0).client.as_in_memory_backend().blockchain().blocks_count()); - assert_eq!(9, net.peer(1).client.as_in_memory_backend().blockchain().blocks_count()); + assert_eq!(9, net.peer(0).blocks_count()); + assert_eq!(9, net.peer(1).blocks_count()); } #[test] @@ -368,11 +367,11 @@ fn own_blocks_are_announced() { net.block_until_sync(&mut runtime); - assert_eq!(net.peer(0).client.as_in_memory_backend().blockchain().info().best_number, 1); - assert_eq!(net.peer(1).client.as_in_memory_backend().blockchain().info().best_number, 1); - let peer0_chain = net.peer(0).client.as_in_memory_backend().blockchain().clone(); - assert!(net.peer(1).client.as_in_memory_backend().blockchain().canon_equals_to(&peer0_chain)); - assert!(net.peer(2).client.as_in_memory_backend().blockchain().canon_equals_to(&peer0_chain)); + assert_eq!(net.peer(0).client.info().chain.best_number, 1); + assert_eq!(net.peer(1).client.info().chain.best_number, 1); + let peer0 = &net.peers()[0]; + assert!(net.peers()[1].blockchain_canon_equals(peer0)); + (net.peers()[2].blockchain_canon_equals(peer0)); } #[test] @@ -445,7 +444,7 @@ fn can_sync_small_non_best_forks() { assert!(net.peer(0).client().header(&BlockId::Hash(small_hash)).unwrap().is_some()); assert!(!net.peer(1).client().header(&BlockId::Hash(small_hash)).unwrap().is_some()); - net.peer(0).announce_block(small_hash); + net.peer(0).announce_block(small_hash, Vec::new()); // after announcing, peer 1 downloads the block. @@ -500,7 +499,7 @@ fn light_peer_imports_header_from_announce() { let mut runtime = current_thread::Runtime::new().unwrap(); fn import_with_announce(net: &mut TestNet, runtime: &mut current_thread::Runtime, hash: H256) { - net.peer(0).announce_block(hash); + net.peer(0).announce_block(hash, Vec::new()); runtime.block_on(futures::future::poll_fn::<(), (), _>(|| { net.poll(); @@ -527,3 +526,58 @@ fn light_peer_imports_header_from_announce() { let known_stale_hash = net.peer(0).push_blocks_at(BlockId::Number(0), 1, true); import_with_announce(&mut net, &mut runtime, known_stale_hash); } + +#[test] +fn can_sync_explicit_forks() { + let _ = ::env_logger::try_init(); + let mut runtime = current_thread::Runtime::new().unwrap(); + let mut net = TestNet::new(2); + net.peer(0).push_blocks(30, false); + net.peer(1).push_blocks(30, false); + + // small fork + reorg on peer 1. + net.peer(0).push_blocks_at(BlockId::Number(30), 2, true); + let small_hash = net.peer(0).client().info().chain.best_hash; + let small_number = net.peer(0).client().info().chain.best_number; + net.peer(0).push_blocks_at(BlockId::Number(30), 10, false); + assert_eq!(net.peer(0).client().info().chain.best_number, 40); + + // peer 1 only ever had the long fork. + net.peer(1).push_blocks(10, false); + assert_eq!(net.peer(1).client().info().chain.best_number, 40); + + assert!(net.peer(0).client().header(&BlockId::Hash(small_hash)).unwrap().is_some()); + assert!(net.peer(1).client().header(&BlockId::Hash(small_hash)).unwrap().is_none()); + + // poll until the two nodes connect, otherwise announcing the block will not work + runtime.block_on(futures::future::poll_fn::<(), (), _>(|| -> Result<_, ()> { + net.poll(); + if net.peer(0).num_peers() == 0 || net.peer(1).num_peers() == 0 { + Ok(Async::NotReady) + } else { + Ok(Async::Ready(())) + } + })).unwrap(); + + // synchronization: 0 synced to longer chain and 1 didn't sync to small chain. + + assert_eq!(net.peer(0).client().info().chain.best_number, 40); + + assert!(net.peer(0).client().header(&BlockId::Hash(small_hash)).unwrap().is_some()); + assert!(!net.peer(1).client().header(&BlockId::Hash(small_hash)).unwrap().is_some()); + + // request explicit sync + let first_peer_id = net.peer(0).id(); + net.peer(1).set_sync_fork_request(vec![first_peer_id], small_hash, small_number); + + // peer 1 downloads the block. + runtime.block_on(futures::future::poll_fn::<(), (), _>(|| -> Result<_, ()> { + net.poll(); + + assert!(net.peer(0).client().header(&BlockId::Hash(small_hash)).unwrap().is_some()); + if net.peer(1).client().header(&BlockId::Hash(small_hash)).unwrap().is_none() { + return Ok(Async::NotReady) + } + Ok(Async::Ready(())) + })).unwrap(); +} diff --git a/core/offchain/Cargo.toml b/core/offchain/Cargo.toml index 4c8891eb6b14ce58947dc12283ceb1e716a74a1d..8f342ee60243bfcae9b292945344d0f6f5393625 100644 --- a/core/offchain/Cargo.toml +++ b/core/offchain/Cargo.toml @@ -7,22 +7,30 @@ authors = ["Parity Technologies "] edition = "2018" [dependencies] +bytes = "0.4.12" client = { package = "substrate-client", path = "../../core/client" } -futures-preview = "=0.3.0-alpha.17" -log = "0.4" +fnv = "1.0.6" +futures01 = { package = "futures", version = "0.1" } +futures-preview = "0.3.0-alpha.19" +futures-timer = "0.4.0" +hyper = "0.12.35" +hyper-tls = "0.3.2" +log = "0.4.8" offchain-primitives = { package = "substrate-offchain-primitives", path = "./primitives" } codec = { package = "parity-scale-codec", version = "1.0.0", features = ["derive"] } parking_lot = "0.9.0" primitives = { package = "substrate-primitives", path = "../../core/primitives" } +rand = "0.7.2" sr-primitives = { path = "../../core/sr-primitives" } transaction_pool = { package = "substrate-transaction-pool", path = "../../core/transaction-pool" } network = { package = "substrate-network", path = "../../core/network" } keystore = { package = "substrate-keystore", path = "../keystore" } [dev-dependencies] -env_logger = "0.6" +env_logger = "0.6.2" client-db = { package = "substrate-client-db", path = "../../core/client/db/", default-features = true } test-client = { package = "substrate-test-runtime-client", path = "../../core/test-runtime/client" } +tokio = "0.1.22" [features] default = [] diff --git a/core/offchain/primitives/src/lib.rs b/core/offchain/primitives/src/lib.rs index d51239483aa013aa9f19b2530c42d81aaafd4baf..dda08ae43f570afda5886e6bd6dd9518f0a5c511 100644 --- a/core/offchain/primitives/src/lib.rs +++ b/core/offchain/primitives/src/lib.rs @@ -26,6 +26,7 @@ decl_runtime_apis! { /// The offchain worker api. pub trait OffchainWorkerApi { /// Starts the off-chain task for given block number. + #[skip_initialize_block] fn offchain_worker(number: NumberFor); } } diff --git a/core/offchain/src/api.rs b/core/offchain/src/api.rs index 225e7c3f725a49dae8d761fba451da2018f4ed35..d17a892d975e10a5f4fff54018671ac6a321a332 100644 --- a/core/offchain/src/api.rs +++ b/core/offchain/src/api.rs @@ -17,13 +17,12 @@ use std::{ str::FromStr, sync::Arc, - convert::{TryFrom, TryInto}, - time::{SystemTime, Duration}, + convert::TryFrom, thread::sleep, }; use client::backend::OffchainStorage; -use futures::{StreamExt as _, Future, future, channel::mpsc}; +use futures::{StreamExt as _, Future, FutureExt as _, future, channel::mpsc}; use log::{info, debug, warn, error}; use network::{PeerId, Multiaddr, NetworkStateInfo}; use codec::{Encode, Decode}; @@ -34,6 +33,9 @@ use primitives::offchain::{ use sr_primitives::{generic::BlockId, traits::{self, Extrinsic}}; use transaction_pool::txpool::{Pool, ChainApi}; +mod http; +mod timestamp; + /// A message between the offchain extension and the processing thread. enum ExtMessage { SubmitExtrinsic(Vec), @@ -49,6 +51,8 @@ pub(crate) struct Api { _at: BlockId, /// Is this node a potential validator? is_validator: bool, + /// Everything HTTP-related is handled by a different struct. + http: http::HttpApi, } fn unavailable_yet(name: &str) -> R { @@ -89,33 +93,15 @@ where } fn timestamp(&mut self) -> Timestamp { - let now = SystemTime::now(); - let epoch_duration = now.duration_since(SystemTime::UNIX_EPOCH); - match epoch_duration { - Err(_) => { - // Current time is earlier than UNIX_EPOCH. - Timestamp::from_unix_millis(0) - }, - Ok(d) => { - let duration = d.as_millis(); - // Assuming overflow won't happen for a few hundred years. - Timestamp::from_unix_millis(duration.try_into() - .expect("epoch milliseconds won't overflow u64 for hundreds of years; qed")) - } - } + timestamp::now() } fn sleep_until(&mut self, deadline: Timestamp) { - // Get current timestamp. - let now = self.timestamp(); - // Calculate the diff with the deadline. - let diff = deadline.diff(&now); - // Call thread::sleep for the diff duration. - sleep(Duration::from_millis(diff.millis())); + sleep(timestamp::timestamp_from_now(deadline)); } fn random_seed(&mut self) -> [u8; 32] { - unavailable_yet("random_seed") + rand::random() } fn local_storage_set(&mut self, kind: StorageKind, key: &[u8], value: &[u8]) { @@ -149,58 +135,53 @@ where fn http_request_start( &mut self, - _method: &str, - _uri: &str, + method: &str, + uri: &str, _meta: &[u8] ) -> Result { - unavailable_yet::<()>("http_request_start"); - Err(()) + self.http.request_start(method, uri) } fn http_request_add_header( &mut self, - _request_id: HttpRequestId, - _name: &str, - _value: &str + request_id: HttpRequestId, + name: &str, + value: &str ) -> Result<(), ()> { - unavailable_yet::<()>("http_request_add_header"); - Err(()) + self.http.request_add_header(request_id, name, value) } fn http_request_write_body( &mut self, - _request_id: HttpRequestId, - _chunk: &[u8], - _deadline: Option + request_id: HttpRequestId, + chunk: &[u8], + deadline: Option ) -> Result<(), HttpError> { - unavailable_yet::<()>("http_request_write_body"); - Err(HttpError::IoError) + self.http.request_write_body(request_id, chunk, deadline) } fn http_response_wait( &mut self, ids: &[HttpRequestId], - _deadline: Option + deadline: Option ) -> Vec { - unavailable_yet::<()>("http_response_wait"); - ids.iter().map(|_| HttpRequestStatus::Unknown).collect() + self.http.response_wait(ids, deadline) } fn http_response_headers( &mut self, - _request_id: HttpRequestId + request_id: HttpRequestId ) -> Vec<(Vec, Vec)> { - unavailable_yet("http_response_headers") + self.http.response_headers(request_id) } fn http_response_read_body( &mut self, - _request_id: HttpRequestId, - _buffer: &mut [u8], - _deadline: Option + request_id: HttpRequestId, + buffer: &mut [u8], + deadline: Option ) -> Result { - unavailable_yet::<()>("http_response_read_body"); - Err(HttpError::IoError) + self.http.response_read_body(request_id, buffer, deadline) } } @@ -276,6 +257,8 @@ pub(crate) struct AsyncApi { receiver: Option>, transaction_pool: Arc>, at: BlockId, + /// Everything HTTP-related is handled by a different struct. + http: Option, } impl AsyncApi { @@ -289,18 +272,22 @@ impl AsyncApi { ) -> (Api, AsyncApi) { let (sender, rx) = mpsc::unbounded(); + let (http_api, http_worker) = http::http(); + let api = Api { sender, db, network_state, _at: at, is_validator, + http: http_api, }; let async_api = AsyncApi { receiver: Some(rx), transaction_pool, at, + http: Some(http_worker), }; (api, async_api) @@ -309,38 +296,41 @@ impl AsyncApi { /// Run a processing task for the API pub fn process(mut self) -> impl Future { let receiver = self.receiver.take().expect("Take invoked only once."); + let http = self.http.take().expect("Take invoked only once."); - receiver.for_each(move |msg| { + let extrinsics = receiver.for_each(move |msg| { match msg { ExtMessage::SubmitExtrinsic(ext) => self.submit_extrinsic(ext), } - future::ready(()) - }) + }); + + future::join(extrinsics, http) + .map(|((), ())| ()) } - fn submit_extrinsic(&mut self, ext: Vec) { + fn submit_extrinsic(&mut self, ext: Vec) -> impl Future { let xt = match ::Extrinsic::decode(&mut &*ext) { Ok(xt) => xt, Err(e) => { warn!("Unable to decode extrinsic: {:?}: {}", ext, e.what()); - return + return future::Either::Left(future::ready(())) }, }; info!("Submitting to the pool: {:?} (isSigned: {:?})", xt, xt.is_signed()); - match self.transaction_pool.submit_one(&self.at, xt.clone()) { - Ok(hash) => debug!("[{:?}] Offchain transaction added to the pool.", hash), - Err(e) => { - debug!("Couldn't submit transaction: {:?}", e); - }, - } + future::Either::Right(self.transaction_pool + .submit_one(&self.at, xt.clone()) + .map(|result| match result { + Ok(hash) => { debug!("[{:?}] Offchain transaction added to the pool.", hash); }, + Err(e) => { debug!("Couldn't submit transaction: {:?}", e); }, + })) } } #[cfg(test)] mod tests { use super::*; - use std::convert::TryFrom; + use std::{convert::{TryFrom, TryInto}, time::SystemTime}; use sr_primitives::traits::Zero; use client_db::offchain::LocalStorage; use network::PeerId; @@ -363,7 +353,7 @@ mod tests { let db = LocalStorage::new_test(); let client = Arc::new(test_client::new()); let pool = Arc::new( - Pool::new(Default::default(), transaction_pool::ChainApi::new(client.clone())) + Pool::new(Default::default(), transaction_pool::FullChainApi::new(client.clone())) ); let mock = Arc::new(MockNetworkStateInfo()); @@ -475,4 +465,13 @@ mod tests { // then assert_eq!(state, converted_back_state); } + + #[test] + fn should_get_random_seed() { + // given + let mut api = offchain_api().0; + let seed = api.random_seed(); + // then + assert_ne!(seed, [0; 32]); + } } diff --git a/core/offchain/src/api/http.rs b/core/offchain/src/api/http.rs new file mode 100644 index 0000000000000000000000000000000000000000..6744a42f959c7fddd40bcada579ca860003575ca --- /dev/null +++ b/core/offchain/src/api/http.rs @@ -0,0 +1,1004 @@ +// Copyright 2019 Parity Technologies (UK) Ltd. +// This file is part of Substrate. + +// Substrate 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. + +// Substrate 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 Substrate. If not, see . + +//! This module is composed of two structs: [`HttpApi`] and [`HttpWorker`]. Calling the [`http`] +//! function returns a pair of [`HttpApi`] and [`HttpWorker`] that share some state. +//! +//! The [`HttpApi`] is (indirectly) passed to the runtime when calling an offchain worker, while +//! the [`HttpWorker`] must be processed in the background. The [`HttpApi`] mimicks the API of the +//! HTTP-related methods available to offchain workers. +//! +//! The reason for this design is driven by the fact that HTTP requests should continue running +//! (i.e.: the socket should continue being processed) in the background even if the runtime isn't +//! actively calling any function. + +use crate::api::timestamp; +use bytes::Buf as _; +use fnv::FnvHashMap; +use futures::{prelude::*, channel::mpsc, compat::Compat01As03}; +use log::{warn, error}; +use primitives::offchain::{HttpRequestId, Timestamp, HttpRequestStatus, HttpError}; +use std::{fmt, io::Read as _, mem, pin::Pin, task::Context, task::Poll}; + +/// Creates a pair of [`HttpApi`] and [`HttpWorker`]. +pub fn http() -> (HttpApi, HttpWorker) { + let (to_worker, from_api) = mpsc::unbounded(); + let (to_api, from_worker) = mpsc::unbounded(); + + let api = HttpApi { + to_worker, + from_worker: from_worker.fuse(), + // We start with a random ID for the first HTTP request, to prevent mischievous people from + // writing runtime code with hardcoded IDs. + next_id: HttpRequestId(rand::random::() % 2000), + requests: FnvHashMap::default(), + }; + + let engine = HttpWorker { + to_api, + from_api, + // TODO: don't unwrap; we should fall back to the HttpConnector if we fail to create the + // Https one; there doesn't seem to be any built-in way to do this + http_client: HyperClient::new(), + requests: Vec::new(), + }; + + (api, engine) +} + +/// Provides HTTP capabilities. +/// +/// Since this struct is a helper for offchain workers, its API is mimicking the API provided +/// to offchain workers. +pub struct HttpApi { + /// Used to sends messages to the worker. + to_worker: mpsc::UnboundedSender, + /// Used to receive messages from the worker. + /// We use a `Fuse` in order to have an extra protection against panicking. + from_worker: stream::Fuse>, + /// Id to assign to the next HTTP request that is started. + next_id: HttpRequestId, + /// List of HTTP requests in preparation or in progress. + requests: FnvHashMap, +} + +/// One active request within `HttpApi`. +enum HttpApiRequest { + /// The request object is being constructed locally and not started yet. + NotDispatched(hyper::Request, hyper::body::Sender), + /// The request has been dispatched and we're in the process of sending out the body (if the + /// field is `Some`) or waiting for a response (if the field is `None`). + Dispatched(Option), + /// Received a response. + Response(HttpApiRequestRp), + /// A request has been dispatched but the worker notified us of an error. We report this + /// failure to the user as an `IoError` and remove the request from the list as soon as + /// possible. + Fail(hyper::Error), +} + +/// A request within `HttpApi` that has received a response. +struct HttpApiRequestRp { + /// We might still be writing the request's body when the response comes. + /// This field allows to continue writing that body. + sending_body: Option, + /// Status code of the response. + status_code: hyper::StatusCode, + /// Headers of the response. + headers: hyper::HeaderMap, + /// Body of the response, as a channel of `Chunk` objects. + /// While the code is designed to drop the `Receiver` once it ends, we wrap it within a + /// `Fuse` in order to be extra precautious about panics. + /// Elements extracted from the channel are first put into `current_read_chunk`. + /// If the channel produces an error, then that is translated into an `IoError` and the request + /// is removed from the list. + body: stream::Fuse>>, + /// Chunk that has been extracted from the channel and that is currently being read. + /// Reading data from the response should read from this field in priority. + current_read_chunk: Option>, +} + +impl HttpApi { + /// Mimicks the corresponding method in the offchain API. + pub fn request_start( + &mut self, + method: &str, + uri: &str + ) -> Result { + // Start by building the prototype of the request. + // We do this first so that we don't touch anything in `self` if building the prototype + // fails. + let (body_sender, body) = hyper::Body::channel(); + let mut request = hyper::Request::new(body); + *request.method_mut() = hyper::Method::from_bytes(method.as_bytes()).map_err(|_| ())?; + *request.uri_mut() = hyper::Uri::from_shared(From::from(uri)).map_err(|_| ())?; + + let new_id = self.next_id; + debug_assert!(!self.requests.contains_key(&new_id)); + match self.next_id.0.checked_add(1) { + Some(new_id) => self.next_id.0 = new_id, + None => { + error!("Overflow in offchain worker HTTP request ID assignment"); + return Err(()); + } + }; + self.requests.insert(new_id, HttpApiRequest::NotDispatched(request, body_sender)); + + Ok(new_id) + } + + /// Mimicks the corresponding method in the offchain API. + pub fn request_add_header( + &mut self, + request_id: HttpRequestId, + name: &str, + value: &str + ) -> Result<(), ()> { + let request = match self.requests.get_mut(&request_id) { + Some(&mut HttpApiRequest::NotDispatched(ref mut rq, _)) => rq, + _ => return Err(()) + }; + + let name = hyper::header::HeaderName::from_bytes(name.as_bytes()).map_err(|_| ())?; + let value = hyper::header::HeaderValue::from_str(value).map_err(|_| ())?; + // Note that we're always appending headers and never replacing old values. + // We assume here that the user knows what they're doing. + request.headers_mut().append(name, value); + Ok(()) + } + + /// Mimicks the corresponding method in the offchain API. + pub fn request_write_body( + &mut self, + request_id: HttpRequestId, + chunk: &[u8], + deadline: Option + ) -> Result<(), HttpError> { + // Extract the request from the list. + // Don't forget to add it back if necessary when returning. + let mut request = match self.requests.remove(&request_id) { + None => return Err(HttpError::Invalid), + Some(r) => r, + }; + + let mut deadline = timestamp::deadline_to_future(deadline); + // Closure that writes data to a sender, taking the deadline into account. Can return `Ok` + // (if the body has been written), or `DeadlineReached`, or `IoError`. + // If `IoError` is returned, don't forget to remove the request from the list. + let mut poll_sender = move |sender: &mut hyper::body::Sender| -> Result<(), HttpError> { + let mut when_ready = future::maybe_done(Compat01As03::new( + futures01::future::poll_fn(|| sender.poll_ready()) + )); + futures::executor::block_on(future::select(&mut when_ready, &mut deadline)); + match when_ready { + future::MaybeDone::Done(Ok(())) => {} + future::MaybeDone::Done(Err(_)) => return Err(HttpError::IoError), + future::MaybeDone::Future(_) | + future::MaybeDone::Gone => { + debug_assert!(if let future::MaybeDone::Done(_) = deadline { true } else { false }); + return Err(HttpError::DeadlineReached) + } + }; + + match sender.send_data(hyper::Chunk::from(chunk.to_owned())) { + Ok(()) => Ok(()), + Err(_chunk) => { + error!("HTTP sender refused data despite being ready"); + Err(HttpError::IoError) + }, + } + }; + + loop { + request = match request { + HttpApiRequest::NotDispatched(request, sender) => { + // If the request is not dispatched yet, dispatch it and loop again. + let _ = self.to_worker.unbounded_send(ApiToWorker::Dispatch { + id: request_id, + request + }); + HttpApiRequest::Dispatched(Some(sender)) + } + + HttpApiRequest::Dispatched(Some(mut sender)) => + if !chunk.is_empty() { + match poll_sender(&mut sender) { + Err(HttpError::IoError) => return Err(HttpError::IoError), + other => { + self.requests.insert( + request_id, + HttpApiRequest::Dispatched(Some(sender)) + ); + return other + } + } + } else { + // Writing an empty body is a hint that we should stop writing. Dropping + // the sender. + self.requests.insert(request_id, HttpApiRequest::Dispatched(None)); + return Ok(()) + } + + HttpApiRequest::Response(mut response @ HttpApiRequestRp { sending_body: Some(_), .. }) => + if !chunk.is_empty() { + match poll_sender(response.sending_body.as_mut() + .expect("Can only enter this match branch if Some; qed")) { + Err(HttpError::IoError) => return Err(HttpError::IoError), + other => { + self.requests.insert(request_id, HttpApiRequest::Response(response)); + return other + } + } + + } else { + // Writing an empty body is a hint that we should stop writing. Dropping + // the sender. + self.requests.insert(request_id, HttpApiRequest::Response(HttpApiRequestRp { + sending_body: None, + ..response + })); + return Ok(()) + } + + HttpApiRequest::Fail(_) => + // If the request has already failed, return without putting back the request + // in the list. + return Err(HttpError::IoError), + + v @ HttpApiRequest::Dispatched(None) | + v @ HttpApiRequest::Response(HttpApiRequestRp { sending_body: None, .. }) => { + // We have already finished sending this body. + self.requests.insert(request_id, v); + return Err(HttpError::Invalid) + } + } + } + } + + /// Mimicks the corresponding method in the offchain API. + pub fn response_wait( + &mut self, + ids: &[HttpRequestId], + deadline: Option + ) -> Vec { + // First of all, dispatch all the non-dispatched requests and drop all senders so that the + // user can't write anymore data. + for id in ids { + match self.requests.get_mut(id) { + Some(HttpApiRequest::NotDispatched(_, _)) => {} + Some(HttpApiRequest::Dispatched(sending_body)) | + Some(HttpApiRequest::Response(HttpApiRequestRp { sending_body, .. })) => { + let _ = sending_body.take(); + continue + } + _ => continue + }; + + let (request, _sender) = match self.requests.remove(id) { + Some(HttpApiRequest::NotDispatched(rq, s)) => (rq, s), + _ => unreachable!("we checked for NotDispatched above; qed") + }; + + let _ = self.to_worker.unbounded_send(ApiToWorker::Dispatch { + id: *id, + request + }); + + // We also destroy the sender in order to forbid writing more data. + self.requests.insert(*id, HttpApiRequest::Dispatched(None)); + } + + let mut deadline = timestamp::deadline_to_future(deadline); + + loop { + // Within that loop, first try to see if we have all the elements for a response. + // This includes the situation where the deadline is reached. + { + let mut output = Vec::with_capacity(ids.len()); + let mut must_wait_more = false; + for id in ids { + output.push(match self.requests.get_mut(id) { + None => HttpRequestStatus::Invalid, + Some(HttpApiRequest::NotDispatched(_, _)) => + unreachable!("we replaced all the NotDispatched with Dispatched earlier; qed"), + Some(HttpApiRequest::Dispatched(_)) => { + must_wait_more = true; + HttpRequestStatus::DeadlineReached + }, + Some(HttpApiRequest::Fail(_)) => HttpRequestStatus::IoError, + Some(HttpApiRequest::Response(HttpApiRequestRp { status_code, .. })) => + HttpRequestStatus::Finished(status_code.as_u16()), + }); + } + debug_assert_eq!(output.len(), ids.len()); + + // Are we ready to call `return`? + let is_done = if let future::MaybeDone::Done(_) = deadline { + true + } else if !must_wait_more { + true + } else { + false + }; + + if is_done { + // Requests in "fail" mode are purged before returning. + debug_assert_eq!(output.len(), ids.len()); + for n in (0..ids.len()).rev() { + if let HttpRequestStatus::IoError = output[n] { + self.requests.remove(&ids[n]); + } + } + return output + } + } + + // Grab next message from the worker. We call `continue` if deadline is reached so that + // we loop back and `return`. + let next_message = { + let mut next_msg = future::maybe_done(self.from_worker.next()); + futures::executor::block_on(future::select(&mut next_msg, &mut deadline)); + if let future::MaybeDone::Done(msg) = next_msg { + msg + } else { + debug_assert!(if let future::MaybeDone::Done(_) = deadline { true } else { false }); + continue + } + }; + + // Update internal state based on received message. + match next_message { + Some(WorkerToApi::Response { id, status_code, headers, body }) => + match self.requests.remove(&id) { + Some(HttpApiRequest::Dispatched(sending_body)) => { + self.requests.insert(id, HttpApiRequest::Response(HttpApiRequestRp { + sending_body, + status_code, + headers, + body: body.fuse(), + current_read_chunk: None, + })); + } + None => {} // can happen if we detected an IO error when sending the body + _ => error!("State mismatch between the API and worker"), + } + + Some(WorkerToApi::Fail { id, error }) => + match self.requests.remove(&id) { + Some(HttpApiRequest::Dispatched(_)) => { + self.requests.insert(id, HttpApiRequest::Fail(error)); + } + None => {} // can happen if we detected an IO error when sending the body + _ => error!("State mismatch between the API and worker"), + } + + None => { + error!("Worker has crashed"); + return ids.iter().map(|_| HttpRequestStatus::IoError).collect() + } + } + + } + } + + /// Mimicks the corresponding method in the offchain API. + pub fn response_headers( + &mut self, + request_id: HttpRequestId + ) -> Vec<(Vec, Vec)> { + // Do an implicit non-blocking wait on the request. + let _ = self.response_wait(&[request_id], Some(timestamp::now())); + + let headers = match self.requests.get(&request_id) { + Some(HttpApiRequest::Response(HttpApiRequestRp { headers, .. })) => headers, + _ => return Vec::new() + }; + + headers + .iter() + .map(|(name, value)| (name.as_str().as_bytes().to_owned(), value.as_bytes().to_owned())) + .collect() + } + + /// Mimicks the corresponding method in the offchain API. + pub fn response_read_body( + &mut self, + request_id: HttpRequestId, + buffer: &mut [u8], + deadline: Option + ) -> Result { + // Do an implicit wait on the request. + let _ = self.response_wait(&[request_id], deadline); + + // Remove the request from the list and handle situations where the request is invalid or + // in the wrong state. + let mut response = match self.requests.remove(&request_id) { + Some(HttpApiRequest::Response(r)) => r, + // Because we called `response_wait` above, we know that the deadline has been reached + // and we still haven't received a response. + Some(rq @ HttpApiRequest::Dispatched(_)) => { + self.requests.insert(request_id, rq); + return Err(HttpError::DeadlineReached) + }, + // The request has failed. + Some(HttpApiRequest::Fail { .. }) => + return Err(HttpError::IoError), + // Request hasn't been dispatched yet; reading the body is invalid. + Some(rq @ HttpApiRequest::NotDispatched(_, _)) => { + self.requests.insert(request_id, rq); + return Err(HttpError::Invalid) + } + None => return Err(HttpError::Invalid) + }; + + // Convert the deadline into a `Future` that resolves when the deadline is reached. + let mut deadline = timestamp::deadline_to_future(deadline); + + loop { + // First read from `current_read_chunk`. + if let Some(mut current_read_chunk) = response.current_read_chunk.take() { + match current_read_chunk.read(buffer) { + Ok(0) => {} + Ok(n) => { + self.requests.insert(request_id, HttpApiRequest::Response(HttpApiRequestRp { + current_read_chunk: Some(current_read_chunk), + .. response + })); + return Ok(n) + }, + Err(err) => { + // This code should never be reached unless there's a logic error somewhere. + error!("Failed to read from current read chunk: {:?}", err); + return Err(HttpError::IoError) + } + } + } + + // If we reach here, that means the `current_read_chunk` is empty and needs to be + // filled with a new chunk from `body`. We block on either the next body or the + // deadline. + let mut next_body = future::maybe_done(response.body.next()); + futures::executor::block_on(future::select(&mut next_body, &mut deadline)); + + if let future::MaybeDone::Done(next_body) = next_body { + match next_body { + Some(Ok(chunk)) => response.current_read_chunk = Some(chunk.reader()), + Some(Err(_)) => return Err(HttpError::IoError), + None => return Ok(0), // eof + } + } + + if let future::MaybeDone::Done(_) = deadline { + self.requests.insert(request_id, HttpApiRequest::Response(response)); + return Err(HttpError::DeadlineReached) + } + } + } +} + +impl fmt::Debug for HttpApi { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + f.debug_list() + .entries(self.requests.iter()) + .finish() + } +} + +impl fmt::Debug for HttpApiRequest { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + match self { + HttpApiRequest::NotDispatched(_, _) => + f.debug_tuple("HttpApiRequest::NotDispatched").finish(), + HttpApiRequest::Dispatched(_) => + f.debug_tuple("HttpApiRequest::Dispatched").finish(), + HttpApiRequest::Response(HttpApiRequestRp { status_code, headers, .. }) => + f.debug_tuple("HttpApiRequest::Response").field(status_code).field(headers).finish(), + HttpApiRequest::Fail(err) => + f.debug_tuple("HttpApiRequest::Fail").field(err).finish(), + } + } +} + +/// Message send from the API to the worker. +enum ApiToWorker { + /// Dispatches a new HTTP request. + Dispatch { + /// ID to send back when the response comes back. + id: HttpRequestId, + /// Request to start executing. + request: hyper::Request, + } +} + +/// Message send from the API to the worker. +enum WorkerToApi { + /// A request has succeeded. + Response { + /// The ID that was passed to the worker. + id: HttpRequestId, + /// Status code of the response. + status_code: hyper::StatusCode, + /// Headers of the response. + headers: hyper::HeaderMap, + /// Body of the response, as a channel of `Chunk` objects. + /// We send the body back through a channel instead of returning the hyper `Body` object + /// because we don't want the `HttpApi` to have to drive the reading. + /// Instead, reading an item from the channel will notify the worker task, which will push + /// the next item. + /// Can also be used to send an error, in case an error happend on the HTTP socket. After + /// an error is sent, the channel will close. + body: mpsc::Receiver>, + }, + /// A request has failed because of an error. The request is then no longer valid. + Fail { + /// The ID that was passed to the worker. + id: HttpRequestId, + /// Error that happened. + error: hyper::Error, + }, +} + +/// Wraps around a `hyper::Client` with either TLS enabled or disabled. +enum HyperClient { + /// Everything is ok and HTTPS is available. + Https(hyper::Client, hyper::Body>), + /// We failed to initialize HTTPS and therefore only allow HTTP. + Http(hyper::Client), +} + +impl HyperClient { + /// Creates new hyper client. + /// + /// By default we will try to initialize the `HttpsConnector`, + /// If that's not possible we'll fall back to `HttpConnector`. + pub fn new() -> Self { + match hyper_tls::HttpsConnector::new(1) { + Ok(tls) => HyperClient::Https(hyper::Client::builder().build(tls)), + Err(e) => { + warn!("Unable to initialize TLS client. Falling back to HTTP-only: {:?}", e); + HyperClient::Http(hyper::Client::new()) + }, + } + } +} + +/// Must be continuously polled for the [`HttpApi`] to properly work. +pub struct HttpWorker { + /// Used to sends messages to the `HttpApi`. + to_api: mpsc::UnboundedSender, + /// Used to receive messages from the `HttpApi`. + from_api: mpsc::UnboundedReceiver, + /// The engine that runs HTTP requests. + http_client: HyperClient, + /// HTTP requests that are being worked on by the engine. + requests: Vec<(HttpRequestId, HttpWorkerRequest)>, +} + +/// HTTP request being processed by the worker. +enum HttpWorkerRequest { + /// Request has been dispatched and is waiting for a response from the Internet. + Dispatched(Compat01As03), + /// Progressively reading the body of the response and sending it to the channel. + ReadBody { + /// Body to read `Chunk`s from. Only used if the channel is ready to accept data. + body: Compat01As03, + /// Channel to the [`HttpApi`] where we send the chunks to. + tx: mpsc::Sender>, + }, +} + +impl Future for HttpWorker { + type Output = (); + + fn poll(mut self: Pin<&mut Self>, cx: &mut Context) -> Poll { + // Reminder: this is continuously run in the background. + + // We use a `me` variable because the compiler isn't smart enough to allow borrowing + // multiple fields at once through a `Deref`. + let me = &mut *self; + + // We remove each element from `requests` one by one and add them back only if necessary. + for n in (0..me.requests.len()).rev() { + let (id, request) = me.requests.swap_remove(n); + match request { + HttpWorkerRequest::Dispatched(mut future) => { + // Check for an HTTP response from the Internet. + let mut response = match Future::poll(Pin::new(&mut future), cx) { + Poll::Pending => { + me.requests.push((id, HttpWorkerRequest::Dispatched(future))); + continue + }, + Poll::Ready(Ok(response)) => response, + Poll::Ready(Err(err)) => { + let _ = me.to_api.unbounded_send(WorkerToApi::Fail { + id, + error: err, + }); + continue; // don't insert the request back + } + }; + + // We received a response! Decompose it into its parts. + let status_code = response.status(); + let headers = mem::replace(response.headers_mut(), hyper::HeaderMap::new()); + let body = Compat01As03::new(response.into_body()); + + let (body_tx, body_rx) = mpsc::channel(3); + let _ = me.to_api.unbounded_send(WorkerToApi::Response { + id, + status_code, + headers, + body: body_rx, + }); + + me.requests.push((id, HttpWorkerRequest::ReadBody { body, tx: body_tx })); + cx.waker().wake_by_ref(); // reschedule in order to poll the new future + continue + } + + HttpWorkerRequest::ReadBody { mut body, mut tx } => { + // Before reading from the HTTP response, check that `tx` is ready to accept + // a new chunk. + match tx.poll_ready(cx) { + Poll::Ready(Ok(())) => {} + Poll::Ready(Err(_)) => continue, // don't insert the request back + Poll::Pending => { + me.requests.push((id, HttpWorkerRequest::ReadBody { body, tx })); + continue + } + } + + // `tx` is ready. Read a chunk from the socket and send it to the channel. + match Stream::poll_next(Pin::new(&mut body), cx) { + Poll::Ready(Some(Ok(chunk))) => { + let _ = tx.start_send(Ok(chunk)); + me.requests.push((id, HttpWorkerRequest::ReadBody { body, tx })); + cx.waker().wake_by_ref(); // reschedule in order to continue reading + } + Poll::Ready(Some(Err(err))) => { + let _ = tx.start_send(Err(err)); + // don't insert the request back + }, + Poll::Ready(None) => {} // EOF; don't insert the request back + Poll::Pending => { + me.requests.push((id, HttpWorkerRequest::ReadBody { body, tx })); + }, + } + } + } + } + + // Check for messages coming from the [`HttpApi`]. + match Stream::poll_next(Pin::new(&mut me.from_api), cx) { + Poll::Pending => {}, + Poll::Ready(None) => return Poll::Ready(()), // stops the worker + Poll::Ready(Some(ApiToWorker::Dispatch { id, request })) => { + let future = Compat01As03::new(match me.http_client { + HyperClient::Http(ref mut c) => c.request(request), + HyperClient::Https(ref mut c) => c.request(request), + }); + debug_assert!(me.requests.iter().all(|(i, _)| *i != id)); + me.requests.push((id, HttpWorkerRequest::Dispatched(future))); + cx.waker().wake_by_ref(); // reschedule the task to poll the request + } + } + + Poll::Pending + } +} + +impl fmt::Debug for HttpWorker { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + f.debug_list() + .entries(self.requests.iter()) + .finish() + } +} + +impl fmt::Debug for HttpWorkerRequest { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + match self { + HttpWorkerRequest::Dispatched(_) => + f.debug_tuple("HttpWorkerRequest::Dispatched").finish(), + HttpWorkerRequest::ReadBody { .. } => + f.debug_tuple("HttpWorkerRequest::Response").finish(), + } + } +} + +#[cfg(test)] +mod tests { + use crate::api::timestamp; + use super::http; + use futures::prelude::*; + use futures01::Future as _; + use primitives::offchain::{HttpError, HttpRequestId, HttpRequestStatus, Duration}; + + // Returns an `HttpApi` whose worker is ran in the background, and a `SocketAddr` to an HTTP + // server that runs in the background as well. + macro_rules! build_api_server { + () => {{ + let (api, worker) = http(); + // Note: we have to use tokio because hyper still uses old futures. + std::thread::spawn(move || { + tokio::run(futures::compat::Compat::new(worker.map(|()| Ok::<(), ()>(())))) + }); + let (addr_tx, addr_rx) = std::sync::mpsc::channel(); + std::thread::spawn(move || { + let server = hyper::Server::bind(&"127.0.0.1:0".parse().unwrap()) + .serve(|| { + hyper::service::service_fn_ok(move |_: hyper::Request| { + hyper::Response::new(hyper::Body::from("Hello World!")) + }) + }); + let _ = addr_tx.send(server.local_addr()); + hyper::rt::run(server.map_err(|e| panic!("{:?}", e))); + }); + (api, addr_rx.recv().unwrap()) + }}; + } + + #[test] + fn basic_localhost() { + let deadline = timestamp::now().add(Duration::from_millis(10_000)); + + // Performs an HTTP query to a background HTTP server. + + let (mut api, addr) = build_api_server!(); + + let id = api.request_start("POST", &format!("http://{}", addr)).unwrap(); + api.request_write_body(id, &[], Some(deadline)).unwrap(); + + match api.response_wait(&[id], Some(deadline))[0] { + HttpRequestStatus::Finished(200) => {}, + v => panic!("Connecting to localhost failed: {:?}", v) + } + + let headers = api.response_headers(id); + assert!(headers.iter().any(|(h, _)| h.eq_ignore_ascii_case(b"Date"))); + + let mut buf = vec![0; 2048]; + let n = api.response_read_body(id, &mut buf, Some(deadline)).unwrap(); + assert_eq!(&buf[..n], b"Hello World!"); + } + + #[test] + fn request_start_invalid_call() { + let (mut api, addr) = build_api_server!(); + + match api.request_start("\0", &format!("http://{}", addr)) { + Err(()) => {} + Ok(_) => panic!() + }; + + match api.request_start("GET", "http://\0localhost") { + Err(()) => {} + Ok(_) => panic!() + }; + } + + #[test] + fn request_add_header_invalid_call() { + let (mut api, addr) = build_api_server!(); + + match api.request_add_header(HttpRequestId(0xdead), "Foo", "bar") { + Err(()) => {} + Ok(_) => panic!() + }; + + let id = api.request_start("GET", &format!("http://{}", addr)).unwrap(); + match api.request_add_header(id, "\0", "bar") { + Err(()) => {} + Ok(_) => panic!() + }; + + let id = api.request_start("POST", &format!("http://{}", addr)).unwrap(); + match api.request_add_header(id, "Foo", "\0") { + Err(()) => {} + Ok(_) => panic!() + }; + + let id = api.request_start("POST", &format!("http://{}", addr)).unwrap(); + api.request_add_header(id, "Foo", "Bar").unwrap(); + api.request_write_body(id, &[1, 2, 3, 4], None).unwrap(); + match api.request_add_header(id, "Foo2", "Bar") { + Err(()) => {} + Ok(_) => panic!() + }; + + let id = api.request_start("GET", &format!("http://{}", addr)).unwrap(); + api.response_headers(id); + match api.request_add_header(id, "Foo2", "Bar") { + Err(()) => {} + Ok(_) => panic!() + }; + + let id = api.request_start("GET", &format!("http://{}", addr)).unwrap(); + api.response_read_body(id, &mut [], None).unwrap(); + match api.request_add_header(id, "Foo2", "Bar") { + Err(()) => {} + Ok(_) => panic!() + }; + } + + #[test] + fn request_write_body_invalid_call() { + let (mut api, addr) = build_api_server!(); + + match api.request_write_body(HttpRequestId(0xdead), &[1, 2, 3], None) { + Err(HttpError::Invalid) => {} + _ => panic!() + }; + + match api.request_write_body(HttpRequestId(0xdead), &[], None) { + Err(HttpError::Invalid) => {} + _ => panic!() + }; + + let id = api.request_start("POST", &format!("http://{}", addr)).unwrap(); + api.request_write_body(id, &[1, 2, 3, 4], None).unwrap(); + api.request_write_body(id, &[1, 2, 3, 4], None).unwrap(); + api.request_write_body(id, &[], None).unwrap(); + match api.request_write_body(id, &[], None) { + Err(HttpError::Invalid) => {} + _ => panic!() + }; + + let id = api.request_start("POST", &format!("http://{}", addr)).unwrap(); + api.request_write_body(id, &[1, 2, 3, 4], None).unwrap(); + api.request_write_body(id, &[1, 2, 3, 4], None).unwrap(); + api.request_write_body(id, &[], None).unwrap(); + match api.request_write_body(id, &[1, 2, 3, 4], None) { + Err(HttpError::Invalid) => {} + _ => panic!() + }; + + let id = api.request_start("POST", &format!("http://{}", addr)).unwrap(); + api.request_write_body(id, &[1, 2, 3, 4], None).unwrap(); + api.response_wait(&[id], None); + match api.request_write_body(id, &[], None) { + Err(HttpError::Invalid) => {} + _ => panic!() + }; + + let id = api.request_start("POST", &format!("http://{}", addr)).unwrap(); + api.request_write_body(id, &[1, 2, 3, 4], None).unwrap(); + api.response_wait(&[id], None); + match api.request_write_body(id, &[1, 2, 3, 4], None) { + Err(HttpError::Invalid) => {} + _ => panic!() + }; + + let id = api.request_start("POST", &format!("http://{}", addr)).unwrap(); + api.response_headers(id); + match api.request_write_body(id, &[1, 2, 3, 4], None) { + Err(HttpError::Invalid) => {} + _ => panic!() + }; + + let id = api.request_start("GET", &format!("http://{}", addr)).unwrap(); + api.response_headers(id); + match api.request_write_body(id, &[], None) { + Err(HttpError::Invalid) => {} + _ => panic!() + }; + + let id = api.request_start("POST", &format!("http://{}", addr)).unwrap(); + api.response_read_body(id, &mut [], None).unwrap(); + match api.request_write_body(id, &[1, 2, 3, 4], None) { + Err(HttpError::Invalid) => {} + _ => panic!() + }; + + let id = api.request_start("POST", &format!("http://{}", addr)).unwrap(); + api.response_read_body(id, &mut [], None).unwrap(); + match api.request_write_body(id, &[], None) { + Err(HttpError::Invalid) => {} + _ => panic!() + }; + } + + #[test] + fn response_headers_invalid_call() { + let (mut api, addr) = build_api_server!(); + assert!(api.response_headers(HttpRequestId(0xdead)).is_empty()); + + let id = api.request_start("POST", &format!("http://{}", addr)).unwrap(); + assert!(api.response_headers(id).is_empty()); + + let id = api.request_start("POST", &format!("http://{}", addr)).unwrap(); + api.request_write_body(id, &[], None).unwrap(); + while api.response_headers(id).is_empty() { + std::thread::sleep(std::time::Duration::from_millis(100)); + } + + let id = api.request_start("GET", &format!("http://{}", addr)).unwrap(); + api.response_wait(&[id], None); + assert!(!api.response_headers(id).is_empty()); + + let id = api.request_start("GET", &format!("http://{}", addr)).unwrap(); + let mut buf = [0; 128]; + while api.response_read_body(id, &mut buf, None).unwrap() != 0 {} + assert!(api.response_headers(id).is_empty()); + } + + #[test] + fn response_header_invalid_call() { + let (mut api, addr) = build_api_server!(); + + let id = api.request_start("POST", &format!("http://{}", addr)).unwrap(); + assert!(api.response_headers(id).is_empty()); + + let id = api.request_start("POST", &format!("http://{}", addr)).unwrap(); + api.request_add_header(id, "Foo", "Bar").unwrap(); + assert!(api.response_headers(id).is_empty()); + + let id = api.request_start("GET", &format!("http://{}", addr)).unwrap(); + api.request_add_header(id, "Foo", "Bar").unwrap(); + api.request_write_body(id, &[], None).unwrap(); + // Note: this test actually sends out the request, and is supposed to test a situation + // where we haven't received any response yet. This test can theoretically fail if the + // HTTP response comes back faster than the kernel schedules our thread, but that is highly + // unlikely. + assert!(api.response_headers(id).is_empty()); + } + + #[test] + fn response_read_body_invalid_call() { + let (mut api, addr) = build_api_server!(); + let mut buf = [0; 512]; + + match api.response_read_body(HttpRequestId(0xdead), &mut buf, None) { + Err(HttpError::Invalid) => {} + _ => panic!() + } + + let id = api.request_start("GET", &format!("http://{}", addr)).unwrap(); + while api.response_read_body(id, &mut buf, None).unwrap() != 0 {} + match api.response_read_body(id, &mut buf, None) { + Err(HttpError::Invalid) => {} + _ => panic!() + } + } + + #[test] + fn fuzzing() { + // Uses the API in random ways to try to trigger panicks. + // Doesn't test some paths, such as waiting for multiple requests. Also doesn't test what + // happens if the server force-closes our socket. + + let (mut api, addr) = build_api_server!(); + + for _ in 0..50 { + let id = api.request_start("POST", &format!("http://{}", addr)).unwrap(); + + for _ in 0..250 { + match rand::random::() % 6 { + 0 => { let _ = api.request_add_header(id, "Foo", "Bar"); } + 1 => { let _ = api.request_write_body(id, &[1, 2, 3, 4], None); } + 2 => { let _ = api.request_write_body(id, &[], None); } + 3 => { let _ = api.response_wait(&[id], None); } + 4 => { let _ = api.response_headers(id); } + 5 => { + let mut buf = [0; 512]; + let _ = api.response_read_body(id, &mut buf, None); + } + 6 ..= 255 => unreachable!() + } + } + } + } +} diff --git a/core/offchain/src/api/timestamp.rs b/core/offchain/src/api/timestamp.rs new file mode 100644 index 0000000000000000000000000000000000000000..445c7f3878474aef80646351871ea417b959ae67 --- /dev/null +++ b/core/offchain/src/api/timestamp.rs @@ -0,0 +1,62 @@ +// Copyright 2019 Parity Technologies (UK) Ltd. +// This file is part of Substrate. + +// Substrate 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. + +// Substrate 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 Substrate. If not, see . + +//! Helper methods dedicated to timestamps. + +use primitives::offchain::Timestamp; +use std::convert::TryInto; +use std::time::{SystemTime, Duration}; + +/// Returns the current time as a `Timestamp`. +pub fn now() -> Timestamp { + let now = SystemTime::now(); + let epoch_duration = now.duration_since(SystemTime::UNIX_EPOCH); + match epoch_duration { + Err(_) => { + // Current time is earlier than UNIX_EPOCH. + Timestamp::from_unix_millis(0) + }, + Ok(d) => { + let duration = d.as_millis(); + // Assuming overflow won't happen for a few hundred years. + Timestamp::from_unix_millis(duration.try_into() + .expect("epoch milliseconds won't overflow u64 for hundreds of years; qed")) + } + } +} + +/// Returns how a `Timestamp` compares to "now". +/// +/// In other words, returns `timestamp - now()`. +pub fn timestamp_from_now(timestamp: Timestamp) -> Duration { + Duration::from_millis(timestamp.diff(&now()).millis()) +} + +/// Converts the deadline into a `Future` that resolves when the deadline is reached. +/// +/// If `None`, returns a never-ending `Future`. +pub fn deadline_to_future( + deadline: Option, +) -> futures::future::MaybeDone { + use futures::future; + + future::maybe_done(match deadline { + Some(deadline) => future::Either::Left( + futures_timer::Delay::new(timestamp_from_now(deadline)) + ), + None => future::Either::Right(future::pending()) + }) +} diff --git a/core/offchain/src/lib.rs b/core/offchain/src/lib.rs index b38b202c62e084c008c0686489ff8aaf10770825..79c6df04ea1099d9700ee51922214278c60e753d 100644 --- a/core/offchain/src/lib.rs +++ b/core/offchain/src/lib.rs @@ -43,7 +43,7 @@ use client::runtime_api::ApiExt; use futures::future::Future; use log::{debug, warn}; use network::NetworkStateInfo; -use primitives::ExecutionContext; +use primitives::{offchain, ExecutionContext}; use sr_primitives::{generic::BlockId, traits::{self, ProvideRuntimeApi}}; use transaction_pool::txpool::{Pool, ChainApi}; @@ -122,7 +122,7 @@ impl OffchainWorkers< debug!("Running offchain workers at {:?}", at); let run = runtime.offchain_worker_with_context( &at, - ExecutionContext::OffchainWorker(api), + ExecutionContext::OffchainCall(Some((api, offchain::Capabilities::all()))), number, ); if let Err(e) = run { @@ -171,7 +171,7 @@ mod tests { // given let _ = env_logger::try_init(); let client = Arc::new(test_client::new()); - let pool = Arc::new(Pool::new(Default::default(), transaction_pool::ChainApi::new(client.clone()))); + let pool = Arc::new(Pool::new(Default::default(), transaction_pool::FullChainApi::new(client.clone()))); let db = client_db::offchain::LocalStorage::new_test(); let network_state = Arc::new(MockNetworkStateInfo()); diff --git a/core/offchain/src/testing.rs b/core/offchain/src/testing.rs index cdf2878c13e3fa19d67a372ceebf476db54f8af9..e1cc7f71a38114abfef620b7844ea3a3b90faf92 100644 --- a/core/offchain/src/testing.rs +++ b/core/offchain/src/testing.rs @@ -48,7 +48,7 @@ pub struct PendingRequest { /// Has the request been sent already. pub sent: bool, /// Response body - pub response: Vec, + pub response: Option>, /// Number of bytes already read from the response body. pub read: usize, /// Response headers @@ -67,6 +67,8 @@ pub struct State { pub persistent_storage: client::in_mem::OffchainStorage, /// Local storage pub local_storage: client::in_mem::OffchainStorage, + /// A vector of transactions submitted from the runtime. + pub transactions: Vec>, } impl State { @@ -87,7 +89,7 @@ impl State { *req, expected, ); - req.response = response.into(); + req.response = Some(response.into()); req.response_headers = response_headers.into_iter().collect(); } } @@ -95,7 +97,7 @@ impl State { fn fulfill_expected(&mut self, id: u16) { if let Some(mut req) = self.expected_requests.remove(&RequestId(id)) { - let response = std::mem::replace(&mut req.response, vec![]); + let response = req.response.take().expect("Response checked while added."); let headers = std::mem::replace(&mut req.response_headers, vec![]); self.fulfill_pending_request(id, req, response, headers); } @@ -108,6 +110,9 @@ impl State { /// Expected request has to be fulfilled before this struct is dropped, /// the `response` and `response_headers` fields will be used to return results to the callers. pub fn expect_request(&mut self, id: u16, expected: PendingRequest) { + if expected.response.is_none() { + panic!("Expected request needs to have a response."); + } self.expected_requests.insert(RequestId(id), expected); } } @@ -138,12 +143,17 @@ impl offchain::Externalities for TestOffchainExt { unimplemented!("not needed in tests so far") } - fn submit_transaction(&mut self, _ex: Vec) -> Result<(), ()> { - unimplemented!("not needed in tests so far") + fn submit_transaction(&mut self, ex: Vec) -> Result<(), ()> { + let mut state = self.0.write(); + state.transactions.push(ex); + Ok(()) } fn network_state(&self) -> Result { - unimplemented!("not needed in tests so far") + Ok(OpaqueNetworkState { + peer_id: Default::default(), + external_addresses: vec![], + }) } fn timestamp(&mut self) -> Timestamp { @@ -247,8 +257,9 @@ impl offchain::Externalities for TestOffchainExt { let state = self.0.read(); ids.iter().map(|id| match state.requests.get(id) { - Some(req) if req.response.is_empty() => RequestStatus::DeadlineReached, - None => RequestStatus::Unknown, + Some(req) if req.response.is_none() => + panic!("No `response` provided for request with id: {:?}", id), + None => RequestStatus::Invalid, _ => RequestStatus::Finished(200), }).collect() } @@ -274,13 +285,17 @@ impl offchain::Externalities for TestOffchainExt { ) -> Result { let mut state = self.0.write(); if let Some(req) = state.requests.get_mut(&request_id) { - if req.read >= req.response.len() { + let response = req.response + .as_mut() + .expect(&format!("No response provided for request: {:?}", request_id)); + + if req.read >= response.len() { // Remove the pending request as per spec. state.requests.remove(&request_id); Ok(0) } else { - let read = std::cmp::min(buffer.len(), req.response[req.read..].len()); - buffer[0..read].copy_from_slice(&req.response[req.read..read]); + let read = std::cmp::min(buffer.len(), response[req.read..].len()); + buffer[0..read].copy_from_slice(&response[req.read..read]); req.read += read; Ok(read) } diff --git a/core/panic-handler/Cargo.toml b/core/panic-handler/Cargo.toml index 054bd643ac3e6adee588e176ccf243c6e6c854f4..9724b9291926a8098a0124b247f6f8feb0c7ab3e 100644 --- a/core/panic-handler/Cargo.toml +++ b/core/panic-handler/Cargo.toml @@ -6,5 +6,5 @@ description = "Substrate panic handler." edition = "2018" [dependencies] -backtrace = "0.3" -log = "0.4" +backtrace = "0.3.38" +log = "0.4.8" diff --git a/core/panic-handler/src/lib.rs b/core/panic-handler/src/lib.rs index 287ff72a6aa1cd0bf649c37ddd9fa2a6487ee76d..1df05120c119d5f046b09f1143e017f1e29306f0 100644 --- a/core/panic-handler/src/lib.rs +++ b/core/panic-handler/src/lib.rs @@ -31,7 +31,18 @@ use std::cell::Cell; use std::thread; thread_local! { - static ABORT: Cell = Cell::new(true); + static ON_PANIC: Cell = Cell::new(OnPanic::Abort); +} + +/// Panic action. +#[derive(Debug, Clone, Copy, PartialEq)] +enum OnPanic { + /// Abort when panic occurs. + Abort, + /// Unwind when panic occurs. + Unwind, + /// Always unwind even if someone changes strategy to Abort afterwards. + NeverAbort, } /// Set the panic hook. @@ -40,8 +51,13 @@ thread_local! { /// /// The `bug_url` parameter is an invitation for users to visit that URL to submit a bug report /// in the case where a panic happens. -pub fn set(bug_url: &'static str) { - panic::set_hook(Box::new(move |c| panic_hook(c, bug_url))); +pub fn set(bug_url: &'static str, version: &str) { + panic::set_hook(Box::new({ + let version = version.to_string(); + move |c| { + panic_hook(c, bug_url, &version) + } + })); } macro_rules! ABOUT_PANIC { @@ -52,10 +68,13 @@ This is a bug. Please report it at: ")} /// Set aborting flag. Returns previous value of the flag. -fn set_abort(enabled: bool) -> bool { - ABORT.with(|flag| { - let prev = flag.get(); - flag.set(enabled); +fn set_abort(on_panic: OnPanic) -> OnPanic { + ON_PANIC.with(|val| { + let prev = val.get(); + match prev { + OnPanic::Abort | OnPanic::Unwind => val.set(on_panic), + OnPanic::NeverAbort => (), + } prev }) } @@ -69,7 +88,7 @@ fn set_abort(enabled: bool) -> bool { /// > the `AbortGuard` on the stack and let it destroy itself naturally. pub struct AbortGuard { /// Value that was in `ABORT` before we created this guard. - previous_val: bool, + previous_val: OnPanic, /// Marker so that `AbortGuard` doesn't implement `Send`. _not_send: PhantomData> } @@ -79,7 +98,7 @@ impl AbortGuard { /// unwind the stack (unless another guard is created afterwards). pub fn force_unwind() -> AbortGuard { AbortGuard { - previous_val: set_abort(false), + previous_val: set_abort(OnPanic::Unwind), _not_send: PhantomData } } @@ -88,7 +107,16 @@ impl AbortGuard { /// abort the process (unless another guard is created afterwards). pub fn force_abort() -> AbortGuard { AbortGuard { - previous_val: set_abort(true), + previous_val: set_abort(OnPanic::Abort), + _not_send: PhantomData + } + } + + /// Create a new guard. While the guard is alive, panics that happen in the current thread will + /// **never** abort the process (even if `AbortGuard::force_abort()` guard will be created afterwards). + pub fn never_abort() -> AbortGuard { + AbortGuard { + previous_val: set_abort(OnPanic::NeverAbort), _not_send: PhantomData } } @@ -101,7 +129,7 @@ impl Drop for AbortGuard { } /// Function being called when a panic happens. -fn panic_hook(info: &PanicInfo, report_url: &'static str) { +fn panic_hook(info: &PanicInfo, report_url: &'static str, version: &str) { let location = info.location(); let file = location.as_ref().map(|l| l.file()).unwrap_or(""); let line = location.as_ref().map(|l| l.line()).unwrap_or(0); @@ -124,6 +152,8 @@ fn panic_hook(info: &PanicInfo, report_url: &'static str) { let _ = writeln!(stderr, ""); let _ = writeln!(stderr, "===================="); let _ = writeln!(stderr, ""); + let _ = writeln!(stderr, "Version: {}", version); + let _ = writeln!(stderr, ""); let _ = writeln!(stderr, "{:?}", backtrace); let _ = writeln!(stderr, ""); let _ = writeln!( @@ -133,8 +163,8 @@ fn panic_hook(info: &PanicInfo, report_url: &'static str) { ); let _ = writeln!(stderr, ABOUT_PANIC!(), report_url); - ABORT.with(|flag| { - if flag.get() { + ON_PANIC.with(|val| { + if val.get() == OnPanic::Abort { ::std::process::exit(1); } }) @@ -146,8 +176,16 @@ mod tests { #[test] fn does_not_abort() { - set("test"); + set("test", "1.2.3"); let _guard = AbortGuard::force_unwind(); ::std::panic::catch_unwind(|| panic!()).ok(); } + + #[test] + fn does_not_abort_after_never_abort() { + set("test", "1.2.3"); + let _guard = AbortGuard::never_abort(); + let _guard = AbortGuard::force_abort(); + std::panic::catch_unwind(|| panic!()).ok(); + } } diff --git a/core/peerset/Cargo.toml b/core/peerset/Cargo.toml index 7bf0617a9ef5d7bd2e7e2b0e88c08381feaa4beb..b11e59c77050e2f5e63c347077facd05a5b8ef8d 100644 --- a/core/peerset/Cargo.toml +++ b/core/peerset/Cargo.toml @@ -8,12 +8,12 @@ authors = ["Parity Technologies "] edition = "2018" [dependencies] -futures-preview = "=0.3.0-alpha.17" -libp2p = { version = "0.11.0", default-features = false } -linked-hash-map = "0.5" -log = "0.4" +futures-preview = "0.3.0-alpha.19" +libp2p = { version = "0.12.0", default-features = false } +linked-hash-map = "0.5.2" +log = "0.4.8" lru-cache = "0.1.2" -serde_json = "1.0.24" +serde_json = "1.0.40" [dev-dependencies] -rand = "0.6" +rand = "0.7.2" diff --git a/core/peerset/src/lib.rs b/core/peerset/src/lib.rs index c7c7850f16087799a38fb455e349bf3642ad6f10..a243fd00bd2b77f845d61179d8a014788ab383f6 100644 --- a/core/peerset/src/lib.rs +++ b/core/peerset/src/lib.rs @@ -178,7 +178,7 @@ impl Peerset { }; let mut peerset = Peerset { - data: peersstate::PeersState::new(config.in_peers, config.out_peers), + data: peersstate::PeersState::new(config.in_peers, config.out_peers, config.reserved_only), tx, rx, reserved_only: config.reserved_only, @@ -224,9 +224,11 @@ impl Peerset { } fn on_set_reserved_only(&mut self, reserved_only: bool) { - // Disconnect non-reserved nodes. self.reserved_only = reserved_only; + self.data.set_priority_only(reserved_only); + if self.reserved_only { + // Disconnect non-reserved nodes. let reserved = self.data.get_priority_group(RESERVED_NODES).unwrap_or_default(); for peer_id in self.data.connected_peers().cloned().collect::>().into_iter() { let peer = self.data.peer(&peer_id).into_connected() diff --git a/core/peerset/src/peersstate.rs b/core/peerset/src/peersstate.rs index e02d6304046bc6f74b9a69e8a1cfbc2dc322f5ab..57dfc50d345b0814f92ab51b80dbc821c0db1059 100644 --- a/core/peerset/src/peersstate.rs +++ b/core/peerset/src/peersstate.rs @@ -50,6 +50,9 @@ pub struct PeersState { /// Priority groups. Each group is identified by a string ID and contains a set of peer IDs. priority_nodes: HashMap>, + + /// Only allow connections to/from peers in a priority group. + priority_only: bool, } /// State of a single node that we know about. @@ -96,7 +99,7 @@ impl ConnectionState { impl PeersState { /// Builds a new empty `PeersState`. - pub fn new(in_peers: u32, out_peers: u32) -> Self { + pub fn new(in_peers: u32, out_peers: u32, priority_only: bool) -> Self { PeersState { nodes: HashMap::new(), num_in: 0, @@ -104,6 +107,7 @@ impl PeersState { max_in: in_peers, max_out: out_peers, priority_nodes: HashMap::new(), + priority_only, } } @@ -220,9 +224,15 @@ impl PeersState { /// Sets the peer as connected with an outgoing connection. fn try_outgoing(&mut self, peer_id: &PeerId) -> bool { + let is_priority = self.is_priority(peer_id); + + // We are only accepting connections from priority nodes. + if !is_priority && self.priority_only { + return false; + } + // Note that it is possible for num_out to be strictly superior to the max, in case we were // connected to reserved node then marked them as not reserved. - let is_priority = self.is_priority(peer_id); if self.num_out >= self.max_out && !is_priority { return false; } @@ -245,6 +255,12 @@ impl PeersState { /// Note that reserved nodes don't count towards the number of slots. fn try_accept_incoming(&mut self, peer_id: &PeerId) -> bool { let is_priority = self.is_priority(peer_id); + + // We are only accepting connections from priority nodes. + if !is_priority && self.priority_only { + return false; + } + // Note that it is possible for num_in to be strictly superior to the max, in case we were // connected to reserved node then marked them as not reserved. if self.num_in >= self.max_in && !is_priority { @@ -315,6 +331,15 @@ impl PeersState { self.priority_nodes.get(group_id).cloned() } + /// Set whether to only allow connections to/from peers in a priority group. + /// Calling this method does not affect any existing connection, e.g. + /// enabling priority only will not disconnect from any non-priority peers + /// we are already connected to, only future incoming/outgoing connection + /// attempts will be affected. + pub fn set_priority_only(&mut self, priority: bool) { + self.priority_only = priority; + } + /// Check that node is any priority group. fn is_priority(&self, peer_id: &PeerId) -> bool { self.priority_nodes.iter().any(|(_, group)| group.contains(peer_id)) @@ -527,7 +552,7 @@ mod tests { #[test] fn full_slots_in() { - let mut peers_state = PeersState::new(1, 1); + let mut peers_state = PeersState::new(1, 1, false); let id1 = PeerId::random(); let id2 = PeerId::random(); @@ -542,7 +567,7 @@ mod tests { #[test] fn priority_node_doesnt_use_slot() { - let mut peers_state = PeersState::new(1, 1); + let mut peers_state = PeersState::new(1, 1, false); let id1 = PeerId::random(); let id2 = PeerId::random(); @@ -558,7 +583,7 @@ mod tests { #[test] fn disconnecting_frees_slot() { - let mut peers_state = PeersState::new(1, 1); + let mut peers_state = PeersState::new(1, 1, false); let id1 = PeerId::random(); let id2 = PeerId::random(); @@ -570,7 +595,7 @@ mod tests { #[test] fn priority_not_connected_peer() { - let mut peers_state = PeersState::new(25, 25); + let mut peers_state = PeersState::new(25, 25, false); let id1 = PeerId::random(); let id2 = PeerId::random(); @@ -589,7 +614,7 @@ mod tests { #[test] fn highest_not_connected_peer() { - let mut peers_state = PeersState::new(25, 25); + let mut peers_state = PeersState::new(25, 25, false); let id1 = PeerId::random(); let id2 = PeerId::random(); @@ -610,7 +635,7 @@ mod tests { #[test] fn disconnect_priority_doesnt_panic() { - let mut peers_state = PeersState::new(1, 1); + let mut peers_state = PeersState::new(1, 1, false); let id = PeerId::random(); peers_state.set_priority_group("test", vec![id.clone()].into_iter().collect()); let peer = peers_state.peer(&id).into_not_connected().unwrap().try_outgoing().unwrap(); @@ -619,7 +644,7 @@ mod tests { #[test] fn multiple_priority_groups_slot_count() { - let mut peers_state = PeersState::new(1, 1); + let mut peers_state = PeersState::new(1, 1, false); let id = PeerId::random(); if let Peer::Unknown(p) = peers_state.peer(&id) { @@ -636,4 +661,60 @@ mod tests { peers_state.set_priority_group("test2", vec![].into_iter().collect()); assert_eq!(peers_state.num_in, 1); } + + #[test] + fn priority_only_mode_ignores_drops_unknown_nodes() { + // test whether connection to/from given peer is allowed + let test_connection = |peers_state: &mut PeersState, id| { + if let Peer::Unknown(p) = peers_state.peer(id) { + p.discover(); + } + + let incoming = if let Peer::NotConnected(p) = peers_state.peer(id) { + p.try_accept_incoming().is_ok() + } else { + panic!() + }; + + if incoming { + peers_state.peer(id).into_connected().map(|p| p.disconnect()); + } + + let outgoing = if let Peer::NotConnected(p) = peers_state.peer(id) { + p.try_outgoing().is_ok() + } else { + panic!() + }; + + if outgoing { + peers_state.peer(id).into_connected().map(|p| p.disconnect()); + } + + incoming || outgoing + }; + + let mut peers_state = PeersState::new(1, 1, true); + let id = PeerId::random(); + + // this is an unknown peer and our peer state is set to only allow + // priority peers so any connection attempt should be denied. + assert!(!test_connection(&mut peers_state, &id)); + + // disabling priority only mode should allow the connection to go + // through. + peers_state.set_priority_only(false); + assert!(test_connection(&mut peers_state, &id)); + + // re-enabling it we should again deny connections from the peer. + peers_state.set_priority_only(true); + assert!(!test_connection(&mut peers_state, &id)); + + // but if we add the peer to a priority group it should be accepted. + peers_state.set_priority_group("TEST_GROUP", vec![id.clone()].into_iter().collect()); + assert!(test_connection(&mut peers_state, &id)); + + // and removing it will cause the connection to once again be denied. + peers_state.remove_from_priority_group("TEST_GROUP", &id); + assert!(!test_connection(&mut peers_state, &id)); + } } diff --git a/core/phragmen/Cargo.toml b/core/phragmen/Cargo.toml new file mode 100644 index 0000000000000000000000000000000000000000..e10be1d92d908129129043a4a68a8587564dc1fd --- /dev/null +++ b/core/phragmen/Cargo.toml @@ -0,0 +1,21 @@ +[package] +name = "substrate-phragmen" +version = "2.0.0" +authors = ["Parity Technologies "] +edition = "2018" + +[dependencies] +sr-primitives = { path = "../sr-primitives", default-features = false } +rstd = { package = "sr-std", path = "../sr-std", default-features = false } + +[dev-dependencies] +runtime-io ={ package = "sr-io", path = "../sr-io" } +support = { package = "srml-support", path = "../../srml/support" } +rand = "0.7.2" + +[features] +default = ["std"] +std = [ + "rstd/std", + "sr-primitives/std", +] diff --git a/core/phragmen/benches/phragmen.rs b/core/phragmen/benches/phragmen.rs new file mode 100644 index 0000000000000000000000000000000000000000..b73811b33fa55065e44e71a9a269e8db7d1b1088 --- /dev/null +++ b/core/phragmen/benches/phragmen.rs @@ -0,0 +1,212 @@ +// Copyright 2019 Parity Technologies +// +// 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. + +//! Benchmarks of the phragmen election algorithm. +//! Note that execution times will not be accurate in an absolute scale, since +//! - Everything is executed in the context of `TestExternalities` +//! - Everything is executed in native environment. +#![cfg(feature = "bench")] +#![feature(test)] + +extern crate test; +use test::Bencher; + +use rand::{self, Rng}; +extern crate substrate_phragmen as phragmen; +use phragmen::{Support, SupportMap, PhragmenStakedAssignment}; + +use std::collections::BTreeMap; +use sr_primitives::traits::{Convert, SaturatedConversion}; + +const VALIDATORS: u64 = 1000; +const NOMINATORS: u64 = 10_000; +const EDGES: u64 = 2; +const TO_ELECT: usize = 100; +const STAKE: Balance = 1000; + +type Balance = u128; +type AccountId = u64; + +pub struct TestCurrencyToVote; +impl Convert for TestCurrencyToVote { + fn convert(x: Balance) -> u64 { x.saturated_into() } +} +impl Convert for TestCurrencyToVote { + fn convert(x: u128) -> Balance { x.saturated_into() } +} + +fn do_phragmen( + b: &mut Bencher, + num_vals: u64, + num_noms: u64, + count: usize, + votes_per: u64, + eq_iters: usize, + _eq_tolerance: u128, +) { + assert!(num_vals > votes_per); + let rr = |a, b| rand::thread_rng().gen_range(a as usize, b as usize) as Balance; + + // prefix to distinguish the validator and nominator account ranges. + let np = 10_000; + + let mut candidates = Vec::with_capacity(num_vals as usize); + let mut slashable_balance_of: BTreeMap = BTreeMap::new(); + + (1 ..= num_vals) + .for_each(|acc| { + candidates.push(acc); + slashable_balance_of.insert(acc, STAKE + rr(10, 50)); + }); + + let mut voters = Vec::with_capacity(num_noms as usize); + (np ..= (np + num_noms)) + .for_each(|acc| { + let mut stashes_to_vote = candidates.clone(); + let votes = (0 .. votes_per) + .map(|_| { + stashes_to_vote.remove(rr(0, stashes_to_vote.len()) as usize) + }) + .collect::>(); + voters.push((acc, votes)); + slashable_balance_of.insert(acc, STAKE + rr(10, 50)); + }); + + let slashable_balance = |who: &AccountId| -> Balance { + *slashable_balance_of.get(who).unwrap() + }; + + b.iter(|| { + let r = phragmen::elect::( + count, + 1_usize, + candidates.clone(), + voters.clone(), + slashable_balance, + true, + ).unwrap(); + + // Do the benchmarking with equalize. + if eq_iters > 0 { + let elected_stashes = r.winners; + let assignments = r.assignments; + + let to_votes = |b: Balance| + >::convert(b) as u128; + + // Initialize the support of each candidate. + let mut supports = >::new(); + elected_stashes + .iter() + .map(|(e, _)| (e, to_votes(slashable_balance(e)))) + .for_each(|(e, s)| { + let item = Support { own: s, total: s, ..Default::default() }; + supports.insert(e.clone(), item); + }); + + // build support struct. + for (n, assignment) in assignments.iter() { + for (c, per_thing) in assignment.iter() { + let nominator_stake = to_votes(slashable_balance(n)); + let other_stake = *per_thing * nominator_stake; + if let Some(support) = supports.get_mut(c) { + support.total = support.total.saturating_add(other_stake); + support.others.push((n.clone(), other_stake)); + } + } + } + + let mut staked_assignments + : Vec<(AccountId, Vec>)> + = Vec::with_capacity(assignments.len()); + for (n, assignment) in assignments.iter() { + let mut staked_assignment + : Vec> + = Vec::with_capacity(assignment.len()); + for (c, per_thing) in assignment.iter() { + let nominator_stake = to_votes(slashable_balance(n)); + let other_stake = *per_thing * nominator_stake; + staked_assignment.push((c.clone(), other_stake)); + } + staked_assignments.push((n.clone(), staked_assignment)); + } + + let tolerance = 0_u128; + let iterations = 2_usize; + phragmen::equalize::<_, _, TestCurrencyToVote, _>( + staked_assignments, + &mut supports, + tolerance, + iterations, + slashable_balance, + ); + } + }) +} + +macro_rules! phragmen_benches { + ($($name:ident: $tup:expr,)*) => { + $( + #[bench] + fn $name(b: &mut Bencher) { + let (v, n, t, e, eq_iter, eq_tol) = $tup; + println!("----------------------"); + println!( + "++ Benchmark: {} Validators // {} Nominators // {} Edges-per-nominator // {} \ + total edges // electing {} // Equalize: {} iterations -- {} tolerance", + v, n, e, e * n, t, eq_iter, eq_tol, + ); + do_phragmen(b, v, n, t, e, eq_iter, eq_tol); + } + )* + } +} + +phragmen_benches! { + bench_1_1: (VALIDATORS, NOMINATORS, TO_ELECT, EDGES, 0, 0), + bench_1_2: (VALIDATORS*2, NOMINATORS, TO_ELECT, EDGES, 0, 0), + bench_1_3: (VALIDATORS*4, NOMINATORS, TO_ELECT, EDGES, 0, 0), + bench_1_4: (VALIDATORS*8, NOMINATORS, TO_ELECT, EDGES, 0, 0), + bench_1_1_eq: (VALIDATORS, NOMINATORS, TO_ELECT, EDGES, 2, 0), + bench_1_2_eq: (VALIDATORS*2, NOMINATORS, TO_ELECT, EDGES, 2, 0), + bench_1_3_eq: (VALIDATORS*4, NOMINATORS, TO_ELECT, EDGES, 2, 0), + bench_1_4_eq: (VALIDATORS*8, NOMINATORS, TO_ELECT, EDGES, 2, 0), + + bench_0_1: (VALIDATORS, NOMINATORS, TO_ELECT, EDGES, 0, 0), + bench_0_2: (VALIDATORS, NOMINATORS, TO_ELECT * 4, EDGES, 0, 0), + bench_0_3: (VALIDATORS, NOMINATORS, TO_ELECT * 8, EDGES, 0, 0), + bench_0_4: (VALIDATORS, NOMINATORS, TO_ELECT * 16, EDGES , 0, 0), + bench_0_1_eq: (VALIDATORS, NOMINATORS, TO_ELECT, EDGES, 2, 0), + bench_0_2_eq: (VALIDATORS, NOMINATORS, TO_ELECT * 4, EDGES, 2, 0), + bench_0_3_eq: (VALIDATORS, NOMINATORS, TO_ELECT * 8, EDGES, 2, 0), + bench_0_4_eq: (VALIDATORS, NOMINATORS, TO_ELECT * 16, EDGES , 2, 0), + + bench_2_1: (VALIDATORS, NOMINATORS, TO_ELECT, EDGES, 0, 0), + bench_2_2: (VALIDATORS, NOMINATORS*2, TO_ELECT, EDGES, 0, 0), + bench_2_3: (VALIDATORS, NOMINATORS*4, TO_ELECT, EDGES, 0, 0), + bench_2_4: (VALIDATORS, NOMINATORS*8, TO_ELECT, EDGES, 0, 0), + bench_2_1_eq: (VALIDATORS, NOMINATORS, TO_ELECT, EDGES, 2, 0), + bench_2_2_eq: (VALIDATORS, NOMINATORS*2, TO_ELECT, EDGES, 2, 0), + bench_2_3_eq: (VALIDATORS, NOMINATORS*4, TO_ELECT, EDGES, 2, 0), + bench_2_4_eq: (VALIDATORS, NOMINATORS*8, TO_ELECT, EDGES, 2, 0), + + bench_3_1: (VALIDATORS, NOMINATORS, TO_ELECT, EDGES, 0, 0 ), + bench_3_2: (VALIDATORS, NOMINATORS, TO_ELECT, EDGES*2, 0, 0), + bench_3_3: (VALIDATORS, NOMINATORS, TO_ELECT, EDGES*4, 0, 0), + bench_3_4: (VALIDATORS, NOMINATORS, TO_ELECT, EDGES*8, 0, 0), + bench_3_1_eq: (VALIDATORS, NOMINATORS, TO_ELECT, EDGES, 2, 0), + bench_3_2_eq: (VALIDATORS, NOMINATORS, TO_ELECT, EDGES*2, 2, 0), + bench_3_3_eq: (VALIDATORS, NOMINATORS, TO_ELECT, EDGES*4, 2, 0), + bench_3_4_eq: (VALIDATORS, NOMINATORS, TO_ELECT, EDGES*8, 2, 0), +} diff --git a/core/phragmen/src/lib.rs b/core/phragmen/src/lib.rs new file mode 100644 index 0000000000000000000000000000000000000000..5295d0f422506e570ee9bb02fb8dc742ddcd883b --- /dev/null +++ b/core/phragmen/src/lib.rs @@ -0,0 +1,512 @@ +// Copyright 2019 Parity Technologies (UK) Ltd. +// This file is part of Substrate. + +// Substrate 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. + +// Substrate 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 Substrate. If not, see . + +//! Rust implementation of the Phragmén election algorithm. This is used in several SRML modules to +//! optimally distribute the weight of a set of voters among an elected set of candidates. In the +//! context of staking this is mapped to validators and nominators. +//! +//! The algorithm has two phases: +//! - Sequential phragmen: performed in [`elect`] function which is first pass of the distribution +//! The results are not optimal but the execution time is less. +//! - Equalize post-processing: tries to further distribute the weight fairly among candidates. +//! Incurs more execution time. +//! +//! The main objective of the assignments done by phragmen is to maximize the minimum backed +//! candidate in the elected set. +//! +//! Reference implementation: https://github.com/w3f/consensus +//! Further details: +//! https://research.web3.foundation/en/latest/polkadot/NPoS/4.%20Sequential%20Phragm%C3%A9n%E2%80%99s%20method/ + +#![cfg_attr(not(feature = "std"), no_std)] + +use rstd::{prelude::*, collections::btree_map::BTreeMap}; +use sr_primitives::{helpers_128bit::multiply_by_rational_best_effort, Perbill, Rational128}; +use sr_primitives::traits::{Zero, Convert, Member, SimpleArithmetic, Saturating}; + +mod mock; +mod tests; + +/// A type in which performing operations on balances and stakes of candidates and voters are safe. +/// +/// This module's functions expect a `Convert` type to convert all balances to u64. Hence, u128 is +/// a safe type for arithmetic operations over them. +/// +/// Balance types converted to `ExtendedBalance` are referred to as `Votes`. +pub type ExtendedBalance = u128; + +/// The denominator used for loads. Since votes are collected as u64, the smallest ratio that we +/// might collect is `1/approval_stake` where approval stake is the sum of votes. Hence, some number +/// bigger than u64::max_value() is needed. For maximum accuracy we simply use u128; +const DEN: u128 = u128::max_value(); + +/// A candidate entity for phragmen election. +#[derive(Clone, Default)] +#[cfg_attr(feature = "std", derive(Debug))] +pub struct Candidate { + /// Identifier. + pub who: AccountId, + /// Intermediary value used to sort candidates. + pub score: Rational128, + /// Sum of the stake of this candidate based on received votes. + approval_stake: ExtendedBalance, + /// Flag for being elected. + elected: bool, +} + +/// A voter entity. +#[derive(Clone, Default)] +#[cfg_attr(feature = "std", derive(Debug))] +pub struct Voter { + /// Identifier. + who: AccountId, + /// List of candidates proposed by this voter. + edges: Vec>, + /// The stake of this voter. + budget: ExtendedBalance, + /// Incremented each time a candidate that this voter voted for has been elected. + load: Rational128, +} + +/// A candidate being backed by a voter. +#[derive(Clone, Default)] +#[cfg_attr(feature = "std", derive(Debug))] +pub struct Edge { + /// Identifier. + who: AccountId, + /// Load of this vote. + load: Rational128, + /// Index of the candidate stored in the 'candidates' vector. + candidate_index: usize, +} + +/// Means a particular `AccountId` was backed by `Perbill`th of a nominator's stake. +pub type PhragmenAssignment = (AccountId, Perbill); + +/// Means a particular `AccountId` was backed by `ExtendedBalance` of a nominator's stake. +pub type PhragmenStakedAssignment = (AccountId, ExtendedBalance); + +/// Final result of the phragmen election. +#[cfg_attr(feature = "std", derive(Debug))] +pub struct PhragmenResult { + /// Just winners zipped with their approval stake. Note that the approval stake is merely the + /// sub of their received stake and could be used for very basic sorting and approval voting. + pub winners: Vec<(AccountId, ExtendedBalance)>, + /// Individual assignments. for each tuple, the first elements is a voter and the second + /// is the list of candidates that it supports. + pub assignments: Vec<(AccountId, Vec>)> +} + +/// A structure to demonstrate the phragmen result from the perspective of the candidate, i.e. how +/// much support each candidate is receiving. +/// +/// This complements the [`PhragmenResult`] and is needed to run the equalize post-processing. +/// +/// This, at the current version, resembles the `Exposure` defined in the staking SRML module, yet +/// they do not necessarily have to be the same. +#[derive(Default)] +#[cfg_attr(feature = "std", derive(Debug))] +pub struct Support { + /// The amount of support as the effect of self-vote. + pub own: ExtendedBalance, + /// Total support. + pub total: ExtendedBalance, + /// Support from voters. + pub others: Vec>, +} + +/// A linkage from a candidate and its [`Support`]. +pub type SupportMap = BTreeMap>; + +/// Perform election based on Phragmén algorithm. +/// +/// Returns an `Option` the set of winners and their detailed support ratio from each voter if +/// enough candidates are provided. Returns `None` otherwise. +/// +/// * `candidate_count`: number of candidates to elect. +/// * `minimum_candidate_count`: minimum number of candidates to elect. If less candidates exist, +/// `None` is returned. +/// * `initial_candidates`: candidates list to be elected from. +/// * `initial_voters`: voters list. +/// * `stake_of`: something that can return the stake stake of a particular candidate or voter. +/// * `self_vote`. If true, then each candidate will automatically vote for themselves with the a +/// weight indicated by their stake. Note that when this is `true` candidates are filtered by +/// having at least some backed stake from themselves. +pub fn elect( + candidate_count: usize, + minimum_candidate_count: usize, + initial_candidates: Vec, + initial_voters: Vec<(AccountId, Vec)>, + stake_of: FS, + self_vote: bool, +) -> Option> where + AccountId: Default + Ord + Member, + Balance: Default + Copy + SimpleArithmetic, + for<'r> FS: Fn(&'r AccountId) -> Balance, + C: Convert + Convert, +{ + let to_votes = |b: Balance| >::convert(b) as ExtendedBalance; + + // return structures + let mut elected_candidates: Vec<(AccountId, ExtendedBalance)>; + let mut assigned: Vec<(AccountId, Vec>)>; + + // used to cache and access candidates index. + let mut c_idx_cache = BTreeMap::::new(); + + // voters list. + let num_voters = initial_candidates.len() + initial_voters.len(); + let mut voters: Vec> = Vec::with_capacity(num_voters); + + // collect candidates. self vote or filter might apply + let mut candidates = if self_vote { + // self vote. filter. + initial_candidates.into_iter().map(|who| { + let stake = stake_of(&who); + Candidate { who, approval_stake: to_votes(stake), ..Default::default() } + }) + .filter(|c| !c.approval_stake.is_zero()) + .enumerate() + .map(|(i, c)| { + voters.push(Voter { + who: c.who.clone(), + edges: vec![Edge { who: c.who.clone(), candidate_index: i, ..Default::default() }], + budget: c.approval_stake, + load: Rational128::zero(), + }); + c_idx_cache.insert(c.who.clone(), i); + c + }) + .collect::>>() + } else { + // no self vote. just collect. + initial_candidates.into_iter() + .enumerate() + .map(|(idx, who)| { + c_idx_cache.insert(who.clone(), idx); + Candidate { who, ..Default::default() } + }) + .collect::>>() + }; + + // early return if we don't have enough candidates + if candidates.len() < minimum_candidate_count { return None; } + + // collect voters. use `c_idx_cache` for fast access and aggregate `approval_stake` of + // candidates. + voters.extend(initial_voters.into_iter().map(|(who, votes)| { + let voter_stake = stake_of(&who); + let mut edges: Vec> = Vec::with_capacity(votes.len()); + for v in votes { + if let Some(idx) = c_idx_cache.get(&v) { + // This candidate is valid + already cached. + candidates[*idx].approval_stake = candidates[*idx].approval_stake + .saturating_add(to_votes(voter_stake)); + edges.push(Edge { who: v.clone(), candidate_index: *idx, ..Default::default() }); + } // else {} would be wrong votes. We don't really care about it. + } + Voter { + who, + edges: edges, + budget: to_votes(voter_stake), + load: Rational128::zero(), + } + })); + + + // we have already checked that we have more candidates than minimum_candidate_count. + // run phragmen. + let to_elect = candidate_count.min(candidates.len()); + elected_candidates = Vec::with_capacity(candidate_count); + assigned = Vec::with_capacity(candidate_count); + + // main election loop + for _round in 0..to_elect { + // loop 1: initialize score + for c in &mut candidates { + if !c.elected { + // 1 / approval_stake == (DEN / approval_stake) / DEN. If approval_stake is zero, + // then the ratio should be as large as possible, essentially `infinity`. + if c.approval_stake.is_zero() { + c.score = Rational128::from_unchecked(DEN, 0); + } else { + c.score = Rational128::from(DEN / c.approval_stake, DEN); + } + } + } + + // loop 2: increment score + for n in &voters { + for e in &n.edges { + let c = &mut candidates[e.candidate_index]; + if !c.elected && !c.approval_stake.is_zero() { + let temp_n = multiply_by_rational_best_effort( + n.load.n(), + n.budget, + c.approval_stake, + ); + let temp_d = n.load.d(); + let temp = Rational128::from(temp_n, temp_d); + c.score = c.score.lazy_saturating_add(temp); + } + } + } + + // loop 3: find the best + if let Some(winner) = candidates + .iter_mut() + .filter(|c| !c.elected) + .min_by_key(|c| c.score) + { + // loop 3: update voter and edge load + winner.elected = true; + for n in &mut voters { + for e in &mut n.edges { + if e.who == winner.who { + e.load = winner.score.lazy_saturating_sub(n.load); + n.load = winner.score; + } + } + } + + elected_candidates.push((winner.who.clone(), winner.approval_stake)); + } else { + break + } + } // end of all rounds + + // update backing stake of candidates and voters + for n in &mut voters { + let mut assignment = (n.who.clone(), vec![]); + for e in &mut n.edges { + if let Some(c) = elected_candidates.iter().cloned().find(|(c, _)| *c == e.who) { + if c.0 != n.who { + let per_bill_parts = + { + if n.load == e.load { + // Full support. No need to calculate. + Perbill::accuracy().into() + } else { + if e.load.d() == n.load.d() { + // return e.load / n.load. + let desired_scale: u128 = Perbill::accuracy().into(); + multiply_by_rational_best_effort( + desired_scale, + e.load.n(), + n.load.n(), + ) + } else { + // defensive only. Both edge and nominator loads are built from + // scores, hence MUST have the same denominator. + Zero::zero() + } + } + }; + // safer to .min() inside as well to argue as u32 is safe. + let per_thing = Perbill::from_parts( + per_bill_parts.min(Perbill::accuracy().into()) as u32 + ); + assignment.1.push((e.who.clone(), per_thing)); + } + } + } + + if assignment.1.len() > 0 { + // To ensure an assertion indicating: no stake from the nominator going to waste, + // we add a minimal post-processing to equally assign all of the leftover stake ratios. + let vote_count = assignment.1.len() as u32; + let len = assignment.1.len(); + let sum = assignment.1.iter() + .map(|a| a.1.deconstruct()) + .sum::(); + let accuracy = Perbill::accuracy(); + let diff = accuracy.checked_sub(sum).unwrap_or(0); + let diff_per_vote = (diff / vote_count).min(accuracy); + + if diff_per_vote > 0 { + for i in 0..len { + let current_ratio = assignment.1[i % len].1; + let next_ratio = current_ratio + .saturating_add(Perbill::from_parts(diff_per_vote)); + assignment.1[i % len].1 = next_ratio; + } + } + + // `remainder` is set to be less than maximum votes of a nominator (currently 16). + // safe to cast it to usize. + let remainder = diff - diff_per_vote * vote_count; + for i in 0..remainder as usize { + let current_ratio = assignment.1[i % len].1; + let next_ratio = current_ratio.saturating_add(Perbill::from_parts(1)); + assignment.1[i % len].1 = next_ratio; + } + assigned.push(assignment); + } + } + + Some(PhragmenResult { + winners: elected_candidates, + assignments: assigned, + }) +} + +/// Performs equalize post-processing to the output of the election algorithm. This happens in +/// rounds. The number of rounds and the maximum diff-per-round tolerance can be tuned through input +/// parameters. +/// +/// No value is returned from the function and the `supports` parameter is updated. +/// +/// * `assignments`: exactly the same is the output of phragmen. +/// * `supports`: mutable reference to s `SupportMap`. This parameter is updated. +/// * `tolerance`: maximum difference that can occur before an early quite happens. +/// * `iterations`: maximum number of iterations that will be processed. +/// * `stake_of`: something that can return the stake stake of a particular candidate or voter. +pub fn equalize( + mut assignments: Vec<(AccountId, Vec>)>, + supports: &mut SupportMap, + tolerance: ExtendedBalance, + iterations: usize, + stake_of: FS, +) where + C: Convert + Convert, + for<'r> FS: Fn(&'r AccountId) -> Balance, + AccountId: Ord + Clone, +{ + // prepare the data for equalise + for _i in 0..iterations { + let mut max_diff = 0; + + for (voter, assignment) in assignments.iter_mut() { + let voter_budget = stake_of(&voter); + + let diff = do_equalize::<_, _, C>( + voter, + voter_budget, + assignment, + supports, + tolerance, + ); + if diff > max_diff { max_diff = diff; } + } + + if max_diff < tolerance { + break; + } + } +} + +/// actually perform equalize. same interface is `equalize`. Just called in loops with a check for +/// maximum difference. +fn do_equalize( + voter: &AccountId, + budget_balance: Balance, + elected_edges: &mut Vec>, + support_map: &mut SupportMap, + tolerance: ExtendedBalance +) -> ExtendedBalance where + C: Convert + Convert, + AccountId: Ord + Clone, +{ + let to_votes = |b: Balance| + >::convert(b) as ExtendedBalance; + let budget = to_votes(budget_balance); + + // Nothing to do. This voter had nothing useful. + // Defensive only. Assignment list should always be populated. + if elected_edges.is_empty() { return 0; } + + let stake_used = elected_edges + .iter() + .fold(0 as ExtendedBalance, |s, e| s.saturating_add(e.1)); + + let backed_stakes_iter = elected_edges + .iter() + .filter_map(|e| support_map.get(&e.0)) + .map(|e| e.total); + + let backing_backed_stake = elected_edges + .iter() + .filter(|e| e.1 > 0) + .filter_map(|e| support_map.get(&e.0)) + .map(|e| e.total) + .collect::>(); + + let mut difference; + if backing_backed_stake.len() > 0 { + let max_stake = backing_backed_stake + .iter() + .max() + .expect("vector with positive length will have a max; qed"); + let min_stake = backed_stakes_iter + .min() + .expect("iterator with positive length will have a min; qed"); + + difference = max_stake.saturating_sub(min_stake); + difference = difference.saturating_add(budget.saturating_sub(stake_used)); + if difference < tolerance { + return difference; + } + } else { + difference = budget; + } + + // Undo updates to support + elected_edges.iter_mut().for_each(|e| { + if let Some(support) = support_map.get_mut(&e.0) { + support.total = support.total.saturating_sub(e.1); + support.others.retain(|i_support| i_support.0 != *voter); + } + e.1 = 0; + }); + + elected_edges.sort_unstable_by_key(|e| + if let Some(e) = support_map.get(&e.0) { e.total } else { Zero::zero() } + ); + + let mut cumulative_stake: ExtendedBalance = 0; + let mut last_index = elected_edges.len() - 1; + let mut idx = 0usize; + for e in &mut elected_edges[..] { + if let Some(support) = support_map.get_mut(&e.0) { + let stake = support.total; + let stake_mul = stake.saturating_mul(idx as ExtendedBalance); + let stake_sub = stake_mul.saturating_sub(cumulative_stake); + if stake_sub > budget { + last_index = idx.checked_sub(1).unwrap_or(0); + break; + } + cumulative_stake = cumulative_stake.saturating_add(stake); + } + idx += 1; + } + + let last_stake = elected_edges[last_index].1; + let split_ways = last_index + 1; + let excess = budget + .saturating_add(cumulative_stake) + .saturating_sub(last_stake.saturating_mul(split_ways as ExtendedBalance)); + elected_edges.iter_mut().take(split_ways).for_each(|e| { + if let Some(support) = support_map.get_mut(&e.0) { + e.1 = (excess / split_ways as ExtendedBalance) + .saturating_add(last_stake) + .saturating_sub(support.total); + support.total = support.total.saturating_add(e.1); + support.others.push((voter.clone(), e.1)); + } + }); + + difference +} diff --git a/core/phragmen/src/mock.rs b/core/phragmen/src/mock.rs new file mode 100644 index 0000000000000000000000000000000000000000..ee4e1eb4bbb326552f51faf7b7e17d4b39bb5bc7 --- /dev/null +++ b/core/phragmen/src/mock.rs @@ -0,0 +1,434 @@ +// Copyright 2019 Parity Technologies (UK) Ltd. +// This file is part of Substrate. + +// Substrate 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. + +// Substrate 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 Substrate. If not, see . + +//! Mock file for phragmen. + +#![cfg(test)] + +use crate::{elect, PhragmenResult, PhragmenAssignment}; +use sr_primitives::{ + assert_eq_error_rate, Perbill, + traits::{Convert, Member, SaturatedConversion} +}; +use rstd::collections::btree_map::BTreeMap; + +pub(crate) struct TestCurrencyToVote; +impl Convert for TestCurrencyToVote { + fn convert(x: Balance) -> u64 { x.saturated_into() } +} +impl Convert for TestCurrencyToVote { + fn convert(x: u128) -> Balance { x } +} + +#[derive(Default, Debug)] +pub(crate) struct _Candidate { + who: A, + score: f64, + approval_stake: f64, + elected: bool, +} + +#[derive(Default, Debug)] +pub(crate) struct _Voter { + who: A, + edges: Vec<_Edge>, + budget: f64, + load: f64, +} + +#[derive(Default, Debug)] +pub(crate) struct _Edge { + who: A, + load: f64, + candidate_index: usize, +} + +#[derive(Default, Debug, PartialEq)] +pub(crate) struct _Support { + pub own: f64, + pub total: f64, + pub others: Vec<_PhragmenAssignment>, +} + +pub(crate) type _PhragmenAssignment = (A, f64); +pub(crate) type _SupportMap = BTreeMap>; + +pub(crate) type Balance = u128; +pub(crate) type AccountId = u64; + +#[derive(Debug, Clone)] +pub(crate) struct _PhragmenResult { + pub winners: Vec<(A, Balance)>, + pub assignments: Vec<(A, Vec<_PhragmenAssignment>)> +} + +pub(crate) fn elect_float( + candidate_count: usize, + minimum_candidate_count: usize, + initial_candidates: Vec, + initial_voters: Vec<(A, Vec)>, + stake_of: FS, + self_vote: bool, +) -> Option<_PhragmenResult> where + A: Default + Ord + Member + Copy, + for<'r> FS: Fn(&'r A) -> Balance, +{ + let mut elected_candidates: Vec<(A, Balance)>; + let mut assigned: Vec<(A, Vec<_PhragmenAssignment>)>; + let mut c_idx_cache = BTreeMap::::new(); + let num_voters = initial_candidates.len() + initial_voters.len(); + let mut voters: Vec<_Voter> = Vec::with_capacity(num_voters); + + let mut candidates = if self_vote { + initial_candidates.into_iter().map(|who| { + let stake = stake_of(&who) as f64; + _Candidate { who, approval_stake: stake, ..Default::default() } + }) + .filter(|c| c.approval_stake != 0f64) + .enumerate() + .map(|(i, c)| { + let who = c.who; + voters.push(_Voter { + who: who.clone(), + edges: vec![ + _Edge { who: who.clone(), candidate_index: i, ..Default::default() } + ], + budget: c.approval_stake, + load: 0f64, + }); + c_idx_cache.insert(c.who.clone(), i); + c + }) + .collect::>>() + } else { + initial_candidates.into_iter() + .enumerate() + .map(|(idx, who)| { + c_idx_cache.insert(who.clone(), idx); + _Candidate { who, ..Default::default() } + }) + .collect::>>() + }; + + if candidates.len() < minimum_candidate_count { + return None; + } + + voters.extend(initial_voters.into_iter().map(|(who, votes)| { + let voter_stake = stake_of(&who) as f64; + let mut edges: Vec<_Edge> = Vec::with_capacity(votes.len()); + for v in votes { + if let Some(idx) = c_idx_cache.get(&v) { + candidates[*idx].approval_stake = candidates[*idx].approval_stake + voter_stake; + edges.push( + _Edge { who: v.clone(), candidate_index: *idx, ..Default::default() } + ); + } + } + _Voter { + who, + edges: edges, + budget: voter_stake, + load: 0f64, + } + })); + + let to_elect = candidate_count.min(candidates.len()); + elected_candidates = Vec::with_capacity(candidate_count); + assigned = Vec::with_capacity(candidate_count); + + for _round in 0..to_elect { + for c in &mut candidates { + if !c.elected { + c.score = 1.0 / c.approval_stake; + } + } + for n in &voters { + for e in &n.edges { + let c = &mut candidates[e.candidate_index]; + if !c.elected && !(c.approval_stake == 0f64) { + c.score += n.budget * n.load / c.approval_stake; + } + } + } + + if let Some(winner) = candidates + .iter_mut() + .filter(|c| !c.elected) + .min_by(|x, y| x.score.partial_cmp(&y.score).unwrap_or(rstd::cmp::Ordering::Equal)) + { + winner.elected = true; + for n in &mut voters { + for e in &mut n.edges { + if e.who == winner.who { + e.load = winner.score - n.load; + n.load = winner.score; + } + } + } + + elected_candidates.push((winner.who.clone(), winner.approval_stake as Balance)); + } else { + break + } + } + + for n in &mut voters { + let mut assignment = (n.who.clone(), vec![]); + for e in &mut n.edges { + if let Some(c) = elected_candidates.iter().cloned().map(|(c, _)| c).find(|c| *c == e.who) { + if c != n.who { + let ratio = e.load / n.load; + assignment.1.push((e.who.clone(), ratio)); + } + } + } + if assignment.1.len() > 0 { + assigned.push(assignment); + } + } + + Some(_PhragmenResult { + winners: elected_candidates, + assignments: assigned, + }) +} + +pub(crate) fn equalize_float( + mut assignments: Vec<(A, Vec<_PhragmenAssignment>)>, + supports: &mut _SupportMap, + tolerance: f64, + iterations: usize, + stake_of: FS, +) where + for<'r> FS: Fn(&'r A) -> Balance, + A: Ord + Clone + std::fmt::Debug, +{ + for _i in 0..iterations { + let mut max_diff = 0.0; + for (voter, assignment) in assignments.iter_mut() { + let voter_budget = stake_of(&voter); + let diff = do_equalize_float( + voter, + voter_budget, + assignment, + supports, + tolerance, + ); + if diff > max_diff { max_diff = diff; } + } + + if max_diff < tolerance { + break; + } + } +} + +pub(crate) fn do_equalize_float( + voter: &A, + budget_balance: Balance, + elected_edges: &mut Vec<_PhragmenAssignment>, + support_map: &mut _SupportMap, + tolerance: f64 +) -> f64 where + A: Ord + Clone, +{ + let budget = budget_balance as f64; + if elected_edges.is_empty() { return 0.0; } + + let stake_used = elected_edges + .iter() + .fold(0.0, |s, e| s + e.1); + + let backed_stakes_iter = elected_edges + .iter() + .filter_map(|e| support_map.get(&e.0)) + .map(|e| e.total); + + let backing_backed_stake = elected_edges + .iter() + .filter(|e| e.1 > 0.0) + .filter_map(|e| support_map.get(&e.0)) + .map(|e| e.total) + .collect::>(); + + let mut difference; + if backing_backed_stake.len() > 0 { + let max_stake = backing_backed_stake + .iter() + .max_by(|x, y| x.partial_cmp(&y).unwrap_or(rstd::cmp::Ordering::Equal)) + .expect("vector with positive length will have a max; qed"); + let min_stake = backed_stakes_iter + .min_by(|x, y| x.partial_cmp(&y).unwrap_or(rstd::cmp::Ordering::Equal)) + .expect("iterator with positive length will have a min; qed"); + + difference = max_stake - min_stake; + difference = difference + budget - stake_used; + if difference < tolerance { + return difference; + } + } else { + difference = budget; + } + + // Undo updates to support + elected_edges.iter_mut().for_each(|e| { + if let Some(support) = support_map.get_mut(&e.0) { + support.total = support.total - e.1; + support.others.retain(|i_support| i_support.0 != *voter); + } + e.1 = 0.0; + }); + + // todo: rewrite. + elected_edges.sort_unstable_by(|x, y| + if let Some(x) = support_map.get(&x.0) { + if let Some(y) = support_map.get(&y.0) { + x.total.partial_cmp(&y.total).unwrap_or(rstd::cmp::Ordering::Equal) + } else { + rstd::cmp::Ordering::Equal + } + } else { + rstd::cmp::Ordering::Equal + } + ); + + let mut cumulative_stake = 0.0; + let mut last_index = elected_edges.len() - 1; + elected_edges.iter_mut().enumerate().for_each(|(idx, e)| { + if let Some(support) = support_map.get_mut(&e.0) { + let stake = support.total; + let stake_mul = stake * (idx as f64); + let stake_sub = stake_mul - cumulative_stake; + if stake_sub > budget { + last_index = idx.checked_sub(1).unwrap_or(0); + return + } + cumulative_stake = cumulative_stake + stake; + } + }); + + let last_stake = elected_edges[last_index].1; + let split_ways = last_index + 1; + let excess = budget + cumulative_stake - last_stake * (split_ways as f64); + elected_edges.iter_mut().take(split_ways).for_each(|e| { + if let Some(support) = support_map.get_mut(&e.0) { + e.1 = excess / (split_ways as f64) + last_stake - support.total; + support.total = support.total + e.1; + support.others.push((voter.clone(), e.1)); + } + }); + + difference +} + + +pub(crate) fn create_stake_of(stakes: &[(AccountId, Balance)]) + -> Box Balance> +{ + let mut storage = BTreeMap::::new(); + stakes.iter().for_each(|s| { storage.insert(s.0, s.1); }); + let stake_of = move |who: &AccountId| -> Balance { storage.get(who).unwrap().to_owned() }; + Box::new(stake_of) +} + + +pub fn check_assignments(assignments: Vec<(AccountId, Vec>)>) { + for (_, a) in assignments { + let sum: u32 = a.iter().map(|(_, p)| p.deconstruct()).sum(); + assert_eq_error_rate!(sum, Perbill::accuracy(), 5); + } +} + +pub(crate) fn run_and_compare( + candidates: Vec, + voters: Vec<(AccountId, Vec)>, + stake_of: Box Balance>, + to_elect: usize, + min_to_elect: usize, + self_vote: bool, +) { + // run fixed point code. + let PhragmenResult { winners, assignments } = elect::<_, _, _, TestCurrencyToVote>( + to_elect, + min_to_elect, + candidates.clone(), + voters.clone(), + &stake_of, + self_vote, + ).unwrap(); + + // run float poc code. + let truth_value = elect_float( + to_elect, + min_to_elect, + candidates, + voters, + &stake_of, + self_vote, + ).unwrap(); + + assert_eq!(winners, truth_value.winners); + + for (nominator, assigned) in assignments.clone() { + if let Some(float_assignments) = truth_value.assignments.iter().find(|x| x.0 == nominator) { + for (candidate, per_thingy) in assigned { + if let Some(float_assignment) = float_assignments.1.iter().find(|x| x.0 == candidate ) { + assert_eq_error_rate!( + Perbill::from_fraction(float_assignment.1).deconstruct(), + per_thingy.deconstruct(), + 1, + ); + } else { + panic!("candidate mismatch. This should never happen.") + } + } + } else { + panic!("nominator mismatch. This should never happen.") + } + } + + check_assignments(assignments); +} + +pub(crate) fn build_support_map( + result: &mut _PhragmenResult, + stake_of: FS, +) -> _SupportMap + where for<'r> FS: Fn(&'r AccountId) -> Balance +{ + let mut supports = <_SupportMap>::new(); + result.winners + .iter() + .map(|(e, _)| (e, stake_of(e) as f64)) + .for_each(|(e, s)| { + let item = _Support { own: s, total: s, ..Default::default() }; + supports.insert(e.clone(), item); + }); + + for (n, assignment) in result.assignments.iter_mut() { + for (c, r) in assignment.iter_mut() { + let nominator_stake = stake_of(n) as f64; + let other_stake = nominator_stake * *r; + if let Some(support) = supports.get_mut(c) { + support.total = support.total + other_stake; + support.others.push((n.clone(), other_stake)); + } + *r = other_stake; + } + } + supports +} diff --git a/core/phragmen/src/tests.rs b/core/phragmen/src/tests.rs new file mode 100644 index 0000000000000000000000000000000000000000..d3c5b1168cc4ea9882f2ed9a6dd1b1bbcf4edd28 --- /dev/null +++ b/core/phragmen/src/tests.rs @@ -0,0 +1,351 @@ +// Copyright 2019 Parity Technologies (UK) Ltd. +// This file is part of Substrate. + +// Substrate 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. + +// Substrate 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 Substrate. If not, see . + +//! Tests for phragmen. + +#![cfg(test)] + +use crate::mock::*; +use crate::{elect, PhragmenResult}; +use support::assert_eq_uvec; +use sr_primitives::Perbill; + +#[test] +fn float_phragmen_poc_works() { + let candidates = vec![1, 2, 3]; + let voters = vec![ + (10, vec![1, 2]), + (20, vec![1, 3]), + (30, vec![2, 3]), + ]; + let stake_of = create_stake_of(&[(10, 10), (20, 20), (30, 30), (1, 0), (2, 0), (3, 0)]); + let mut phragmen_result = elect_float(2, 2, candidates, voters, &stake_of, false).unwrap(); + let winners = phragmen_result.clone().winners; + let assignments = phragmen_result.clone().assignments; + + assert_eq_uvec!(winners, vec![(2, 40), (3, 50)]); + assert_eq_uvec!( + assignments, + vec![ + (10, vec![(2, 1.0)]), + (20, vec![(3, 1.0)]), + (30, vec![(2, 0.5), (3, 0.5)]), + ] + ); + + let mut support_map = build_support_map(&mut phragmen_result, &stake_of); + + assert_eq!( + support_map.get(&2).unwrap(), + &_Support { own: 0.0, total: 25.0, others: vec![(10u64, 10.0), (30u64, 15.0)]} + ); + assert_eq!( + support_map.get(&3).unwrap(), + &_Support { own: 0.0, total: 35.0, others: vec![(20u64, 20.0), (30u64, 15.0)]} + ); + + equalize_float(phragmen_result.assignments, &mut support_map, 0.0, 2, stake_of); + + assert_eq!( + support_map.get(&2).unwrap(), + &_Support { own: 0.0, total: 30.0, others: vec![(10u64, 10.0), (30u64, 20.0)]} + ); + assert_eq!( + support_map.get(&3).unwrap(), + &_Support { own: 0.0, total: 30.0, others: vec![(20u64, 20.0), (30u64, 10.0)]} + ); +} + +#[test] +fn phragmen_poc_works() { + let candidates = vec![1, 2, 3]; + let voters = vec![ + (10, vec![1, 2]), + (20, vec![1, 3]), + (30, vec![2, 3]), + ]; + + let PhragmenResult { winners, assignments } = elect::<_, _, _, TestCurrencyToVote>( + 2, + 2, + candidates, + voters, + create_stake_of(&[(10, 10), (20, 20), (30, 30)]), + false, + ).unwrap(); + + assert_eq_uvec!(winners, vec![(2, 40), (3, 50)]); + assert_eq_uvec!( + assignments, + vec![ + (10, vec![(2, Perbill::from_percent(100))]), + (20, vec![(3, Perbill::from_percent(100))]), + (30, vec![(2, Perbill::from_percent(100/2)), (3, Perbill::from_percent(100/2))]), + ] + ); +} + +#[test] +fn phragmen_poc_2_works() { + let candidates = vec![10, 20, 30]; + let voters = vec![ + (2, vec![10, 20, 30]), + (4, vec![10, 20, 40]), + ]; + let stake_of = create_stake_of(&[ + (10, 1000), + (20, 1000), + (30, 1000), + (40, 1000), + (2, 500), + (4, 500), + ]); + + run_and_compare(candidates, voters, stake_of, 2, 2, true); +} + +#[test] +fn phragmen_poc_3_works() { + let candidates = vec![10, 20, 30]; + let voters = vec![ + (2, vec![10, 20, 30]), + (4, vec![10, 20, 40]), + ]; + let stake_of = create_stake_of(&[ + (10, 1000), + (20, 1000), + (30, 1000), + (2, 50), + (4, 1000), + ]); + + run_and_compare(candidates, voters, stake_of, 2, 2, true); +} + +#[test] +fn phragmen_accuracy_on_large_scale_only_validators() { + // because of this particular situation we had per_u128 and now rational128. In practice, a + // candidate can have the maximum amount of tokens, and also supported by the maximum. + let candidates = vec![1, 2, 3, 4, 5]; + let stake_of = create_stake_of(&[ + (1, (u64::max_value() - 1).into()), + (2, (u64::max_value() - 4).into()), + (3, (u64::max_value() - 5).into()), + (4, (u64::max_value() - 3).into()), + (5, (u64::max_value() - 2).into()), + ]); + + let PhragmenResult { winners, assignments } = elect::<_, _, _, TestCurrencyToVote>( + 2, + 2, + candidates, + vec![], + stake_of, + true, + ).unwrap(); + + assert_eq_uvec!(winners, vec![(1, 18446744073709551614u128), (5, 18446744073709551613u128)]); + assert_eq!(assignments.len(), 0); + check_assignments(assignments); +} + +#[test] +fn phragmen_accuracy_on_large_scale_validators_and_nominators() { + let candidates = vec![1, 2, 3, 4, 5]; + let voters = vec![ + (13, vec![1, 3, 5]), + (14, vec![2, 4]), + ]; + let stake_of = create_stake_of(&[ + (1, (u64::max_value() - 1).into()), + (2, (u64::max_value() - 4).into()), + (3, (u64::max_value() - 5).into()), + (4, (u64::max_value() - 3).into()), + (5, (u64::max_value() - 2).into()), + (13, (u64::max_value() - 10).into()), + (14, u64::max_value().into()), + ]); + + let PhragmenResult { winners, assignments } = elect::<_, _, _, TestCurrencyToVote>( + 2, + 2, + candidates, + voters, + stake_of, + true, + ).unwrap(); + + assert_eq_uvec!(winners, vec![(2, 36893488147419103226u128), (1, 36893488147419103219u128)]); + assert_eq!( + assignments, + vec![(13, vec![(1, Perbill::one())]), (14, vec![(2, Perbill::one())])] + ); + check_assignments(assignments); +} + +#[test] +fn phragmen_accuracy_on_small_scale_self_vote() { + let candidates = vec![40, 10, 20, 30]; + let voters = vec![]; + let stake_of = create_stake_of(&[ + (40, 0), + (10, 1), + (20, 2), + (30, 1), + ]); + + let PhragmenResult { winners, assignments: _ } = elect::<_, _, _, TestCurrencyToVote>( + 3, + 3, + candidates, + voters, + stake_of, + true, + ).unwrap(); + + assert_eq_uvec!(winners, vec![(20, 2), (10, 1), (30, 1)]); +} + +#[test] +fn phragmen_accuracy_on_small_scale_no_self_vote() { + let candidates = vec![40, 10, 20, 30]; + let voters = vec![ + (1, vec![10]), + (2, vec![20]), + (3, vec![30]), + (4, vec![40]), + ]; + let stake_of = create_stake_of(&[ + (40, 1000), // don't care + (10, 1000), // don't care + (20, 1000), // don't care + (30, 1000), // don't care + (4, 0), + (1, 1), + (2, 2), + (3, 1), + ]); + + let PhragmenResult { winners, assignments: _ } = elect::<_, _, _, TestCurrencyToVote>( + 3, + 3, + candidates, + voters, + stake_of, + false, + ).unwrap(); + + assert_eq_uvec!(winners, vec![(20, 2), (10, 1), (30, 1)]); +} + +#[test] +fn phragmen_large_scale_test() { + let candidates = vec![2, 4, 6, 8, 10, 12, 14, 16 ,18, 20, 22, 24]; + let voters = vec![ + (50, vec![2, 4, 6, 8, 10, 12, 14, 16 ,18, 20, 22, 24]), + ]; + let stake_of = create_stake_of(&[ + (2, 1), + (4, 100), + (6, 1000000), + (8, 100000000001000), + (10, 100000000002000), + (12, 100000000003000), + (14, 400000000000000), + (16, 400000000001000), + (18, 18000000000000000), + (20, 20000000000000000), + (22, 500000000000100000), + (24, 500000000000200000), + (50, 990000000000000000), + ]); + + let PhragmenResult { winners, assignments } = elect::<_, _, _, TestCurrencyToVote>( + 2, + 2, + candidates, + voters, + stake_of, + true, + ).unwrap(); + + assert_eq_uvec!(winners, vec![(24, 1490000000000200000u128), (22, 1490000000000100000u128)]); + check_assignments(assignments); +} + +#[test] +fn phragmen_large_scale_test_2() { + let nom_budget: u64 = 1_000_000_000_000_000_000; + let c_budget: u64 = 4_000_000; + + let candidates = vec![2, 4]; + let voters = vec![(50, vec![2, 4])]; + + let stake_of = create_stake_of(&[ + (2, c_budget.into()), + (4, c_budget.into()), + (50, nom_budget.into()), + ]); + + let PhragmenResult { winners, assignments } = elect::<_, _, _, TestCurrencyToVote>( + 2, + 2, + candidates, + voters, + stake_of, + true, + ).unwrap(); + + assert_eq_uvec!(winners, vec![(2, 1000000000004000000u128), (4, 1000000000004000000u128)]); + assert_eq!( + assignments, + vec![(50, vec![(2, Perbill::from_parts(500000001)), (4, Perbill::from_parts(499999999))])], + ); + check_assignments(assignments); +} + +#[test] +fn phragmen_linear_equalize() { + let candidates = vec![11, 21, 31, 41, 51, 61, 71]; + let voters = vec![ + (2, vec![11]), + (4, vec![11, 21]), + (6, vec![21, 31]), + (8, vec![31, 41]), + (110, vec![41, 51]), + (120, vec![51, 61]), + (130, vec![61, 71]), + ]; + let stake_of = create_stake_of(&[ + (11, 1000), + (21, 1000), + (31, 1000), + (41, 1000), + (51, 1000), + (61, 1000), + (71, 1000), + + (2, 2000), + (4, 1000), + (6, 1000), + (8, 1000), + (110, 1000), + (120, 1000), + (130, 1000), + ]); + + run_and_compare(candidates, voters, stake_of, 2, 2, true); +} diff --git a/core/primitives/Cargo.toml b/core/primitives/Cargo.toml index 085b7f52c1dff5c1f26b56098f3a692764f96781..461a8fe7e3d5a7777a34e9cd51208cce9a4449fb 100644 --- a/core/primitives/Cargo.toml +++ b/core/primitives/Cargo.toml @@ -7,36 +7,37 @@ edition = "2018" [dependencies] rstd = { package = "sr-std", path = "../sr-std", default-features = false } codec = { package = "parity-scale-codec", version = "1.0.0", default-features = false, features = ["derive"] } -rustc-hex = { version = "2.0", default-features = false } -serde = { version = "1.0", optional = true, features = ["derive"] } -twox-hash = { version = "1.2.0", optional = true } -byteorder = { version = "1.3.1", default-features = false } -primitive-types = { version = "0.5.0", default-features = false, features = ["codec"] } -impl-serde = { version = "0.1", optional = true } -wasmi = { version = "0.5.0", optional = true } -hash-db = { version = "0.15.0", default-features = false } -hash256-std-hasher = { version = "0.15.0", default-features = false } -ed25519-dalek = { version = "1.0.0-pre.1", optional = true } -base58 = { version = "0.1", optional = true } +rustc-hex = { version = "2.0.1", default-features = false } +serde = { version = "1.0.101", optional = true, features = ["derive"] } +twox-hash = { version = "1.5.0", optional = true } +byteorder = { version = "1.3.2", default-features = false } +primitive-types = { version = "0.5.1", default-features = false, features = ["codec"] } +impl-serde = { version = "0.2.1", optional = true } +log = { version = "0.4.8", optional = true } +wasmi = { version = "0.5.1", optional = true } +hash-db = { version = "0.15.2", default-features = false } +hash256-std-hasher = { version = "0.15.2", default-features = false } +ed25519-dalek = { version = "0.9.1", optional = true } +base58 = { version = "0.1.0", optional = true } blake2-rfc = { version = "0.2.18", optional = true } -schnorrkel = { version = "0.8.4", features = ["preaudit_deprecated"], optional = true } -rand = { version = "0.6", optional = true } -sha2 = { version = "0.8", optional = true } +schnorrkel = { version = "0.8.5", features = ["preaudit_deprecated"], optional = true } +rand = { version = "0.7.2", optional = true } +sha2 = { version = "0.8.0", optional = true } substrate-bip39 = { version = "0.3.1", optional = true } -tiny-bip39 = { version = "0.6.1", optional = true } -hex = { version = "0.3", optional = true } -regex = { version = "1.1", optional = true } -num-traits = { version = "0.2", default-features = false } -zeroize = { version = "0.9.2", default-features = false } -lazy_static = { version = "1.3", optional = true } +tiny-bip39 = { version = "0.6.2", optional = true } +hex = { version = "0.3.2", optional = true } +regex = { version = "1.3.1", optional = true } +num-traits = { version = "0.2.8", default-features = false } +zeroize = "0.10.1" +lazy_static = { version = "1.4.0", optional = true } parking_lot = { version = "0.9.0", optional = true } [dev-dependencies] substrate-serializer = { path = "../serializer" } -pretty_assertions = "0.6" -hex-literal = "0.2" -rand = "0.6" -criterion = "0.2" +pretty_assertions = "0.6.1" +hex-literal = "0.2.1" +rand = "0.7.2" +criterion = "0.2.11" [[bench]] name = "benches" @@ -48,6 +49,7 @@ bench = false [features] default = ["std"] std = [ + "log", "wasmi", "lazy_static", "parking_lot", @@ -77,5 +79,4 @@ std = [ "schnorrkel", "regex", "num-traits/std", - "zeroize/std" ] diff --git a/core/primitives/src/changes_trie.rs b/core/primitives/src/changes_trie.rs index fb7791f0a070bf67038bbc47cba00535d9f2ee7a..5e88485a039945c02660572b18a8c8277d53f298 100644 --- a/core/primitives/src/changes_trie.rs +++ b/core/primitives/src/changes_trie.rs @@ -39,19 +39,30 @@ pub struct ChangesTrieConfiguration { } impl ChangesTrieConfiguration { + /// Create new configuration given digest interval and levels. + pub fn new(digest_interval: u32, digest_levels: u32) -> Self { + Self { digest_interval, digest_levels } + } + /// Is digest build enabled? pub fn is_digest_build_enabled(&self) -> bool { self.digest_interval > 1 && self.digest_levels > 0 } /// Do we need to build digest at given block? - pub fn is_digest_build_required_at_block(&self, block: Number) -> bool + pub fn is_digest_build_required_at_block( + &self, + zero: Number, + block: Number, + ) -> bool where - Number: From + PartialEq + ::rstd::ops::Rem + Zero, + Number: From + PartialEq + + ::rstd::ops::Rem + ::rstd::ops::Sub + + ::rstd::cmp::PartialOrd + Zero, { - block != 0.into() + block > zero && self.is_digest_build_enabled() - && (block % self.digest_interval.into()).is_zero() + && ((block - zero) % self.digest_interval.into()).is_zero() } /// Returns max digest interval. One if digests are not created at all. @@ -71,6 +82,74 @@ impl ChangesTrieConfiguration { } } + /// Returns max level digest block number that has been created at block <= passed block number. + /// + /// Returns None if digests are not created at all. + pub fn prev_max_level_digest_block( + &self, + zero: Number, + block: Number, + ) -> Option + where + Number: Clone + From + PartialOrd + PartialEq + + ::rstd::ops::Add + ::rstd::ops::Sub + + ::rstd::ops::Div + ::rstd::ops::Mul + Zero, + { + if block <= zero { + return None; + } + + let (next_begin, next_end) = self.next_max_level_digest_range(zero.clone(), block.clone())?; + + // if 'next' digest includes our block, then it is a also a previous digest + if next_end == block { + return Some(block); + } + + // if previous digest ends at zero block, then there are no previous digest + let prev_end = next_begin - 1.into(); + if prev_end == zero { + None + } else { + Some(prev_end) + } + } + + /// Returns max level digest blocks range (inclusive) which includes passed block. + /// + /// Returns None if digests are not created at all. + /// It will return the first max-level digest if block is <= zero. + pub fn next_max_level_digest_range( + &self, + zero: Number, + mut block: Number, + ) -> Option<(Number, Number)> + where + Number: Clone + From + PartialOrd + PartialEq + + ::rstd::ops::Add + ::rstd::ops::Sub + + ::rstd::ops::Div + ::rstd::ops::Mul, + { + if !self.is_digest_build_enabled() { + return None; + } + + if block <= zero { + block = zero.clone() + 1.into(); + } + + let max_digest_interval: Number = self.max_digest_interval().into(); + let max_digests_since_zero = (block.clone() - zero.clone()) / max_digest_interval.clone(); + if max_digests_since_zero == 0.into() { + return Some((zero.clone() + 1.into(), zero + max_digest_interval)); + } + let last_max_digest_block = zero + max_digests_since_zero * max_digest_interval.clone(); + Some(if block == last_max_digest_block { + (block.clone() - max_digest_interval + 1.into(), block) + } else { + (last_max_digest_block.clone() + 1.into(), last_max_digest_block + max_digest_interval) + }) + } + /// Returns Some if digest must be built at given block number. /// The tuple is: /// ( @@ -78,20 +157,23 @@ impl ChangesTrieConfiguration { /// digest interval (in blocks) /// step between blocks we're interested in when digest is built /// ) - pub fn digest_level_at_block(&self, block: Number) -> Option<(u32, u32, u32)> + pub fn digest_level_at_block(&self, zero: Number, block: Number) -> Option<(u32, u32, u32)> where - Number: Clone + From + PartialEq + ::rstd::ops::Rem + Zero, + Number: Clone + From + PartialEq + + ::rstd::ops::Rem + ::rstd::ops::Sub + + ::rstd::cmp::PartialOrd + Zero, { - if !self.is_digest_build_required_at_block(block.clone()) { + if !self.is_digest_build_required_at_block(zero.clone(), block.clone()) { return None; } + let relative_block = block - zero; let mut digest_interval = self.digest_interval; let mut current_level = 1u32; let mut digest_step = 1u32; while current_level < self.digest_levels { let new_digest_interval = match digest_interval.checked_mul(self.digest_interval) { - Some(new_digest_interval) if (block.clone() % new_digest_interval.into()).is_zero() + Some(new_digest_interval) if (relative_block.clone() % new_digest_interval.into()).is_zero() => new_digest_interval, _ => break, }; @@ -131,31 +213,43 @@ mod tests { #[test] fn is_digest_build_required_at_block_works() { - assert!(!config(8, 4).is_digest_build_required_at_block(0u64)); - assert!(!config(8, 4).is_digest_build_required_at_block(1u64)); - assert!(!config(8, 4).is_digest_build_required_at_block(2u64)); - assert!(!config(8, 4).is_digest_build_required_at_block(4u64)); - assert!(config(8, 4).is_digest_build_required_at_block(8u64)); - assert!(!config(8, 4).is_digest_build_required_at_block(9u64)); - assert!(config(8, 4).is_digest_build_required_at_block(64u64)); - assert!(config(8, 4).is_digest_build_required_at_block(64u64)); - assert!(config(8, 4).is_digest_build_required_at_block(512u64)); - assert!(config(8, 4).is_digest_build_required_at_block(4096u64)); - assert!(!config(8, 4).is_digest_build_required_at_block(4103u64)); - assert!(config(8, 4).is_digest_build_required_at_block(4104u64)); - assert!(!config(8, 4).is_digest_build_required_at_block(4108u64)); + fn test_with_zero(zero: u64) { + assert!(!config(8, 4).is_digest_build_required_at_block(zero, zero + 0u64)); + assert!(!config(8, 4).is_digest_build_required_at_block(zero, zero + 1u64)); + assert!(!config(8, 4).is_digest_build_required_at_block(zero, zero + 2u64)); + assert!(!config(8, 4).is_digest_build_required_at_block(zero, zero + 4u64)); + assert!(config(8, 4).is_digest_build_required_at_block(zero, zero + 8u64)); + assert!(!config(8, 4).is_digest_build_required_at_block(zero, zero + 9u64)); + assert!(config(8, 4).is_digest_build_required_at_block(zero, zero + 64u64)); + assert!(config(8, 4).is_digest_build_required_at_block(zero, zero + 64u64)); + assert!(config(8, 4).is_digest_build_required_at_block(zero, zero + 512u64)); + assert!(config(8, 4).is_digest_build_required_at_block(zero, zero + 4096u64)); + assert!(!config(8, 4).is_digest_build_required_at_block(zero, zero + 4103u64)); + assert!(config(8, 4).is_digest_build_required_at_block(zero, zero + 4104u64)); + assert!(!config(8, 4).is_digest_build_required_at_block(zero, zero + 4108u64)); + } + + test_with_zero(0); + test_with_zero(8); + test_with_zero(17); } #[test] fn digest_level_at_block_works() { - assert_eq!(config(8, 4).digest_level_at_block(0u64), None); - assert_eq!(config(8, 4).digest_level_at_block(7u64), None); - assert_eq!(config(8, 4).digest_level_at_block(63u64), None); - assert_eq!(config(8, 4).digest_level_at_block(8u64), Some((1, 8, 1))); - assert_eq!(config(8, 4).digest_level_at_block(64u64), Some((2, 64, 8))); - assert_eq!(config(8, 4).digest_level_at_block(512u64), Some((3, 512, 64))); - assert_eq!(config(8, 4).digest_level_at_block(4096u64), Some((4, 4096, 512))); - assert_eq!(config(8, 4).digest_level_at_block(4112u64), Some((1, 8, 1))); + fn test_with_zero(zero: u64) { + assert_eq!(config(8, 4).digest_level_at_block(zero, zero + 0u64), None); + assert_eq!(config(8, 4).digest_level_at_block(zero, zero + 7u64), None); + assert_eq!(config(8, 4).digest_level_at_block(zero, zero + 63u64), None); + assert_eq!(config(8, 4).digest_level_at_block(zero, zero + 8u64), Some((1, 8, 1))); + assert_eq!(config(8, 4).digest_level_at_block(zero, zero + 64u64), Some((2, 64, 8))); + assert_eq!(config(8, 4).digest_level_at_block(zero, zero + 512u64), Some((3, 512, 64))); + assert_eq!(config(8, 4).digest_level_at_block(zero, zero + 4096u64), Some((4, 4096, 512))); + assert_eq!(config(8, 4).digest_level_at_block(zero, zero + 4112u64), Some((1, 8, 1))); + } + + test_with_zero(0); + test_with_zero(8); + test_with_zero(17); } #[test] @@ -165,4 +259,36 @@ mod tests { assert_eq!(config(8, 4).max_digest_interval(), 4096); assert_eq!(config(::std::u32::MAX, 1024).max_digest_interval(), ::std::u32::MAX); } + + #[test] + fn next_max_level_digest_range_works() { + assert_eq!(config(0, 0).next_max_level_digest_range(0u64, 16), None); + assert_eq!(config(1, 1).next_max_level_digest_range(0u64, 16), None); + assert_eq!(config(2, 1).next_max_level_digest_range(0u64, 16), Some((15, 16))); + assert_eq!(config(4, 1).next_max_level_digest_range(0u64, 16), Some((13, 16))); + assert_eq!(config(32, 1).next_max_level_digest_range(0u64, 16), Some((1, 32))); + assert_eq!(config(2, 3).next_max_level_digest_range(0u64, 10), Some((9, 16))); + assert_eq!(config(2, 3).next_max_level_digest_range(0u64, 8), Some((1, 8))); + assert_eq!(config(2, 1).next_max_level_digest_range(1u64, 1), Some((2, 3))); + assert_eq!(config(2, 2).next_max_level_digest_range(7u64, 9), Some((8, 11))); + + assert_eq!(config(2, 2).next_max_level_digest_range(7u64, 5), Some((8, 11))); + } + + #[test] + fn prev_max_level_digest_block_works() { + assert_eq!(config(0, 0).prev_max_level_digest_block(0u64, 16), None); + assert_eq!(config(1, 1).prev_max_level_digest_block(0u64, 16), None); + assert_eq!(config(2, 1).prev_max_level_digest_block(0u64, 16), Some(16)); + assert_eq!(config(4, 1).prev_max_level_digest_block(0u64, 16), Some(16)); + assert_eq!(config(4, 2).prev_max_level_digest_block(0u64, 16), Some(16)); + assert_eq!(config(4, 2).prev_max_level_digest_block(0u64, 17), Some(16)); + assert_eq!(config(4, 2).prev_max_level_digest_block(0u64, 33), Some(32)); + assert_eq!(config(32, 1).prev_max_level_digest_block(0u64, 16), None); + assert_eq!(config(2, 3).prev_max_level_digest_block(0u64, 10), Some(8)); + assert_eq!(config(2, 3).prev_max_level_digest_block(0u64, 8), Some(8)); + assert_eq!(config(2, 2).prev_max_level_digest_block(7u64, 8), None); + + assert_eq!(config(2, 2).prev_max_level_digest_block(7u64, 5), None); + } } diff --git a/core/primitives/src/child_storage_key.rs b/core/primitives/src/child_storage_key.rs new file mode 100644 index 0000000000000000000000000000000000000000..eba34c1ef9797a5f5e5f0e205682cfc17711bc05 --- /dev/null +++ b/core/primitives/src/child_storage_key.rs @@ -0,0 +1,68 @@ +// Copyright 2019 Parity Technologies (UK) Ltd. +// This file is part of Substrate. + +// Substrate 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. + +// Substrate 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 Substrate. If not, see . + +//! Provides a wrapper around a child storage key. + +use crate::storage::well_known_keys::is_child_trie_key_valid; +use rstd::{borrow::Cow, vec::Vec}; + +/// A wrapper around a child storage key. +/// +/// This wrapper ensures that the child storage key is correct and properly used. It is +/// impossible to create an instance of this struct without providing a correct `storage_key`. +pub struct ChildStorageKey<'a> { + storage_key: Cow<'a, [u8]>, +} + +impl<'a> ChildStorageKey<'a> { + fn new(storage_key: Cow<'a, [u8]>) -> Option { + if is_child_trie_key_valid(&storage_key) { + Some(ChildStorageKey { storage_key }) + } else { + None + } + } + + /// Create a new `ChildStorageKey` from a vector. + /// + /// `storage_key` need to start with `:child_storage:default:` + /// See `is_child_trie_key_valid` for more details. + pub fn from_vec(key: Vec) -> Option { + Self::new(Cow::Owned(key)) + } + + /// Create a new `ChildStorageKey` from a slice. + /// + /// `storage_key` need to start with `:child_storage:default:` + /// See `is_child_trie_key_valid` for more details. + pub fn from_slice(key: &'a [u8]) -> Option { + Self::new(Cow::Borrowed(key)) + } + + /// Get access to the byte representation of the storage key. + /// + /// This key is guaranteed to be correct. + pub fn as_ref(&self) -> &[u8] { + &*self.storage_key + } + + /// Destruct this instance into an owned vector that represents the storage key. + /// + /// This key is guaranteed to be correct. + pub fn into_owned(self) -> Vec { + self.storage_key.into_owned() + } +} diff --git a/core/primitives/src/crypto.rs b/core/primitives/src/crypto.rs index 0adf50e1602f3ca40e7b222c11c52125d614f38b..8a336783b79652cafc74163f5a9d46159c5e2a7e 100644 --- a/core/primitives/src/crypto.rs +++ b/core/primitives/src/crypto.rs @@ -261,6 +261,9 @@ pub trait Ss58Codec: Sized { Self::from_ss58check_with_version(s) .and_then(|(r, v)| match v { Ss58AddressFormat::SubstrateAccountDirect => Ok(r), + Ss58AddressFormat::PolkadotAccountDirect => Ok(r), + Ss58AddressFormat::KusamaAccountDirect => Ok(r), + Ss58AddressFormat::DothereumAccountDirect => Ok(r), v if v == *DEFAULT_VERSION.lock() => Ok(r), _ => Err(PublicError::UnknownVersion), }) @@ -273,6 +276,9 @@ pub trait Ss58Codec: Sized { Self::from_string_with_version(s) .and_then(|(r, v)| match v { Ss58AddressFormat::SubstrateAccountDirect => Ok(r), + Ss58AddressFormat::PolkadotAccountDirect => Ok(r), + Ss58AddressFormat::KusamaAccountDirect => Ok(r), + Ss58AddressFormat::DothereumAccountDirect => Ok(r), v if v == *DEFAULT_VERSION.lock() => Ok(r), _ => Err(PublicError::UnknownVersion), }) @@ -327,6 +333,8 @@ pub enum Ss58AddressFormat { PolkadotAccountDirect, /// Kusama Relay-chain, direct checksum, standard account (*25519). KusamaAccountDirect, + /// Dothereum Para-chain, direct checksum, standard account (*25519). + DothereumAccountDirect, /// Use a manually provided numeric value. Custom(u8), } @@ -338,6 +346,7 @@ impl From for u8 { Ss58AddressFormat::SubstrateAccountDirect => 42, Ss58AddressFormat::PolkadotAccountDirect => 0, Ss58AddressFormat::KusamaAccountDirect => 2, + Ss58AddressFormat::DothereumAccountDirect => 20, Ss58AddressFormat::Custom(n) => n, } } @@ -351,6 +360,7 @@ impl TryFrom for Ss58AddressFormat { 42 => Ok(Ss58AddressFormat::SubstrateAccountDirect), 0 => Ok(Ss58AddressFormat::PolkadotAccountDirect), 2 => Ok(Ss58AddressFormat::KusamaAccountDirect), + 20 => Ok(Ss58AddressFormat::DothereumAccountDirect), _ => Err(()), } } @@ -364,6 +374,7 @@ impl<'a> TryFrom<&'a str> for Ss58AddressFormat { "substrate" => Ok(Ss58AddressFormat::SubstrateAccountDirect), "polkadot" => Ok(Ss58AddressFormat::PolkadotAccountDirect), "kusama" => Ok(Ss58AddressFormat::KusamaAccountDirect), + "dothereum" => Ok(Ss58AddressFormat::DothereumAccountDirect), a => a.parse::().map(Ss58AddressFormat::Custom).map_err(|_| ()), } } @@ -376,6 +387,7 @@ impl From for String { Ss58AddressFormat::SubstrateAccountDirect => "substrate".into(), Ss58AddressFormat::PolkadotAccountDirect => "polkadot".into(), Ss58AddressFormat::KusamaAccountDirect => "kusama".into(), + Ss58AddressFormat::DothereumAccountDirect => "dothereum".into(), Ss58AddressFormat::Custom(x) => x.to_string(), } } @@ -387,7 +399,8 @@ impl From for String { /// /// Current known "versions" are: /// - 0 direct (payload) checksum for 32-byte *25519 Polkadot addresses. -/// - 2 direct (payload) checksum for 32-byte *25519 Polkadot Milestone 'K' addresses. +/// - 2 direct (payload) checksum for 32-byte *25519 Kusama addresses. +/// - 20 direct (payload) checksum for 32-byte *25519 Dothereum addresses. /// - 42 direct (payload) checksum for 32-byte *25519 addresses on any Substrate-based network. #[cfg(feature = "std")] pub fn set_default_ss58_version(version: Ss58AddressFormat) { @@ -574,9 +587,8 @@ pub trait Pair: CryptoType + Sized + Clone + Send + Sync + 'static { /// This is only for ephemeral keys really, since you won't have access to the secret key /// for storage. If you want a persistent key pair, use `generate_with_phrase` instead. fn generate() -> (Self, Self::Seed) { - let mut csprng: OsRng = OsRng::new().expect("OS random generator works; qed"); let mut seed = Self::Seed::default(); - csprng.fill_bytes(seed.as_mut()); + OsRng.fill_bytes(seed.as_mut()); (Self::from_seed(&seed), seed) } @@ -767,10 +779,6 @@ impl<'a> TryFrom<&'a str> for KeyTypeId { pub mod key_types { use super::KeyTypeId; - /// Key type for generic S/R 25519 key. - pub const SR25519: KeyTypeId = KeyTypeId(*b"sr25"); - /// Key type for generic Ed25519 key. - pub const ED25519: KeyTypeId = KeyTypeId(*b"ed25"); /// Key type for Babe module, build-in. pub const BABE: KeyTypeId = KeyTypeId(*b"babe"); /// Key type for Grandpa module, build-in. diff --git a/core/primitives/src/ed25519.rs b/core/primitives/src/ed25519.rs index 810e86767d8e365ce9026e91c932134285ed830a..c40499a3a182e84d33a9e21ee30411047232f0bf 100644 --- a/core/primitives/src/ed25519.rs +++ b/core/primitives/src/ed25519.rs @@ -397,7 +397,7 @@ impl TraitPair for Pair { fn from_seed_slice(seed_slice: &[u8]) -> Result { let secret = ed25519_dalek::SecretKey::from_bytes(seed_slice) .map_err(|_| SecretStringError::InvalidSeedLength)?; - let public = ed25519_dalek::PublicKey::from(&secret); + let public = ed25519_dalek::PublicKey::from(secret.expand::()); Ok(Pair(ed25519_dalek::Keypair { secret, public })) } @@ -434,7 +434,7 @@ impl TraitPair for Pair { /// Sign a message. fn sign(&self, message: &[u8]) -> Signature { - let r = self.0.sign(message).to_bytes(); + let r = self.0.sign::(message).to_bytes(); Signature::from_raw(r) } @@ -458,7 +458,7 @@ impl TraitPair for Pair { Err(_) => return false }; - match public_key.verify(message.as_ref(), &sig) { + match public_key.verify::(message.as_ref(), &sig) { Ok(_) => true, _ => false, } diff --git a/core/primitives/src/hexdisplay.rs b/core/primitives/src/hexdisplay.rs index cd2b6c18cb7fed04ecb08a2a6ac936c7853a1762..87be587a7d92d0a6a214974a3b591d685bd2cf9f 100644 --- a/core/primitives/src/hexdisplay.rs +++ b/core/primitives/src/hexdisplay.rs @@ -21,28 +21,37 @@ pub struct HexDisplay<'a>(&'a [u8]); impl<'a> HexDisplay<'a> { /// Create new instance that will display `d` as a hex string when displayed. - pub fn from(d: &'a dyn AsBytesRef) -> Self { HexDisplay(d.as_bytes_ref()) } + pub fn from(d: &'a R) -> Self { HexDisplay(d.as_bytes_ref()) } } impl<'a> ::core::fmt::Display for HexDisplay<'a> { - fn fmt(&self, fmtr: &mut ::core::fmt::Formatter) -> Result<(), ::core::fmt::Error> { + fn fmt(&self, f: &mut core::fmt::Formatter) -> Result<(), core::fmt::Error> { if self.0.len() < 1027 { for byte in self.0 { - fmtr.write_fmt(format_args!("{:02x}", byte))?; + f.write_fmt(format_args!("{:02x}", byte))?; } } else { for byte in &self.0[0..512] { - fmtr.write_fmt(format_args!("{:02x}", byte))?; + f.write_fmt(format_args!("{:02x}", byte))?; } - fmtr.write_str("...")?; + f.write_str("...")?; for byte in &self.0[self.0.len() - 512..] { - fmtr.write_fmt(format_args!("{:02x}", byte))?; + f.write_fmt(format_args!("{:02x}", byte))?; } } Ok(()) } } +impl<'a> core::fmt::Debug for HexDisplay<'a> { + fn fmt(&self, f: &mut core::fmt::Formatter) -> Result<(), core::fmt::Error> { + for byte in self.0 { + f.write_fmt(format_args!("{:02x}", byte))?; + } + Ok(()) + } +} + /// Simple trait to transform various types to `&[u8]` pub trait AsBytesRef { /// Transform `self` into `&[u8]`. diff --git a/core/primitives/src/lib.rs b/core/primitives/src/lib.rs index 21e7c878082ad85f4aade22a8711b2633f2f89df..310f0133ef2590a5e3410a1b0660a78be3b51107 100644 --- a/core/primitives/src/lib.rs +++ b/core/primitives/src/lib.rs @@ -54,6 +54,7 @@ pub mod crypto; pub mod u32_trait; +pub mod child_storage_key; pub mod ed25519; pub mod sr25519; pub mod hash; @@ -88,19 +89,23 @@ pub enum ExecutionContext { Syncing, /// Context used for block construction. BlockConstruction, - /// Offchain worker context. - OffchainWorker(Box), - /// Context used for other calls. - Other, + /// Context used for offchain calls. + /// + /// This allows passing offchain extension and customizing available capabilities. + OffchainCall(Option<(Box, offchain::Capabilities)>), } impl ExecutionContext { - /// Returns if the keystore should be enabled for the current context. - pub fn enable_keystore(&self) -> bool { + /// Returns the capabilities of particular context. + pub fn capabilities(&self) -> offchain::Capabilities { use ExecutionContext::*; + match self { - Importing | Syncing | BlockConstruction => false, - OffchainWorker(_) | Other => true, + Importing | Syncing | BlockConstruction => + offchain::Capabilities::none(), + // Enable keystore by default for offchain calls. CC @bkchr + OffchainCall(None) => [offchain::Capability::Keystore][..].into(), + OffchainCall(Some((_, capabilities))) => *capabilities, } } } @@ -154,7 +159,7 @@ pub enum NativeOrEncoded { #[cfg(feature = "std")] impl ::std::fmt::Debug for NativeOrEncoded { fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result { - self.as_encoded().as_ref().fmt(f) + hexdisplay::HexDisplay::from(&self.as_encoded().as_ref()).fmt(f) } } @@ -214,3 +219,8 @@ impl codec::Decode for NeverNativeValue { } } +/// Provide a simple 4 byte identifier for a type. +pub trait TypeId { + /// Simple 4 byte identifier. + const TYPE_ID: [u8; 4]; +} diff --git a/core/primitives/src/offchain.rs b/core/primitives/src/offchain.rs index 52dbf5fbee3566433f2664ea1ce790a641599fdb..6403a20dbd54676faa3c7d054f1a9cd8ec8c0db3 100644 --- a/core/primitives/src/offchain.rs +++ b/core/primitives/src/offchain.rs @@ -61,7 +61,7 @@ impl From for u32 { /// Opaque type for offchain http requests. #[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord)] -#[cfg_attr(feature = "std", derive(Debug))] +#[cfg_attr(feature = "std", derive(Debug, Hash))] pub struct HttpRequestId(pub u16); impl From for u32 { @@ -79,6 +79,8 @@ pub enum HttpError { DeadlineReached = 1, /// There was an IO Error while processing the request. IoError = 2, + /// The ID of the request is invalid in this context. + Invalid = 3, } impl TryFrom for HttpError { @@ -88,6 +90,7 @@ impl TryFrom for HttpError { match error { e if e == HttpError::DeadlineReached as u8 as u32 => Ok(HttpError::DeadlineReached), e if e == HttpError::IoError as u8 as u32 => Ok(HttpError::IoError), + e if e == HttpError::Invalid as u8 as u32 => Ok(HttpError::Invalid), _ => Err(()) } } @@ -105,18 +108,17 @@ impl From for u32 { pub enum HttpRequestStatus { /// Deadline was reached while we waited for this request to finish. /// - /// Note the deadline is controlled by the calling part, it not necessarily means - /// that the request has timed out. + /// Note the deadline is controlled by the calling part, it not necessarily + /// means that the request has timed out. DeadlineReached, - /// Request timed out. - /// - /// This means that the request couldn't be completed by the host environment - /// within a reasonable time (according to the host), has now been terminated - /// and is considered finished. - /// To retry the request you need to construct it again. - Timeout, - /// Request status of this ID is not known. - Unknown, + /// An error has occured during the request, for example a timeout or the + /// remote has closed our socket. + /// + /// The request is now considered destroyed. To retry the request you need + /// to construct it again. + IoError, + /// The passed ID is invalid in this context. + Invalid, /// The request has finished with given status code. Finished(u16), } @@ -124,9 +126,9 @@ pub enum HttpRequestStatus { impl From for u32 { fn from(status: HttpRequestStatus) -> Self { match status { - HttpRequestStatus::Unknown => 0, + HttpRequestStatus::Invalid => 0, HttpRequestStatus::DeadlineReached => 10, - HttpRequestStatus::Timeout => 20, + HttpRequestStatus::IoError => 20, HttpRequestStatus::Finished(code) => u32::from(code), } } @@ -137,9 +139,9 @@ impl TryFrom for HttpRequestStatus { fn try_from(status: u32) -> Result { match status { - 0 => Ok(HttpRequestStatus::Unknown), + 0 => Ok(HttpRequestStatus::Invalid), 10 => Ok(HttpRequestStatus::DeadlineReached), - 20 => Ok(HttpRequestStatus::Timeout), + 20 => Ok(HttpRequestStatus::IoError), 100..=999 => u16::try_from(status).map(HttpRequestStatus::Finished).map_err(|_| ()), _ => Err(()), } @@ -158,7 +160,7 @@ pub struct OpaqueNetworkState { } /// Simple blob to hold a `PeerId` without committing to its format. -#[derive(Clone, Eq, PartialEq, Encode, Decode)] +#[derive(Default, Clone, Eq, PartialEq, Encode, Decode)] #[cfg_attr(feature = "std", derive(Debug))] pub struct OpaquePeerId(pub Vec); @@ -230,6 +232,70 @@ impl Timestamp { } } +/// Execution context extra capabilities. +#[derive(Debug, PartialEq, Eq, Clone, Copy)] +#[repr(u8)] +pub enum Capability { + /// Access to transaction pool. + TransactionPool = 1, + /// External http calls. + Http = 2, + /// Keystore access. + Keystore = 4, + /// Randomness source. + Randomness = 8, + /// Access to opaque network state. + NetworkState = 16, + /// Access to offchain worker DB (read only). + OffchainWorkerDbRead = 32, + /// Access to offchain worker DB (writes). + OffchainWorkerDbWrite = 64, +} + +/// A set of capabilities +#[derive(Debug, PartialEq, Eq, Clone, Copy)] +pub struct Capabilities(u8); + +impl Capabilities { + /// Return an object representing an empty set of capabilities. + pub fn none() -> Self { + Self(0) + } + + /// Return an object representing all capabilities enabled. + pub fn all() -> Self { + Self(u8::max_value()) + } + + /// Return capabilities for rich offchain calls. + /// + /// Those calls should be allowed to sign and submit transactions + /// and access offchain workers database (but read only!). + pub fn rich_offchain_call() -> Self { + [ + Capability::TransactionPool, + Capability::Keystore, + Capability::OffchainWorkerDbRead, + ][..].into() + } + + /// Check if particular capability is enabled. + pub fn has(&self, capability: Capability) -> bool { + self.0 & capability as u8 != 0 + } + + /// Check if this capability object represents all capabilities. + pub fn has_all(&self) -> bool { + self == &Capabilities::all() + } +} + +impl<'a> From<&'a [Capability]> for Capabilities { + fn from(list: &'a [Capability]) -> Self { + Capabilities(list.iter().fold(0_u8, |a, b| a | *b as u8)) + } +} + /// An extended externalities for offchain workers. pub trait Externalities { /// Returns if the local node is a potential validator. @@ -291,6 +357,11 @@ pub trait Externalities { /// /// Meta is a future-reserved field containing additional, parity-scale-codec encoded parameters. /// Returns the id of newly started request. + /// + /// Returns an error if: + /// - No new request identifier could be allocated. + /// - The method or URI contain invalid characters. + /// fn http_request_start( &mut self, method: &str, @@ -299,6 +370,18 @@ pub trait Externalities { ) -> Result; /// Append header to the request. + /// + /// Calling this function multiple times with the same header name continues appending new + /// headers. In other words, headers are never replaced. + /// + /// Returns an error if: + /// - The request identifier is invalid. + /// - You have called `http_request_write_body` on that request. + /// - The name or value contain invalid characters. + /// + /// An error doesn't poison the request, and you can continue as if the call had never been + /// made. + /// fn http_request_add_header( &mut self, request_id: HttpRequestId, @@ -308,10 +391,19 @@ pub trait Externalities { /// Write a chunk of request body. /// - /// Writing an empty chunks finalises the request. + /// Calling this function with a non-empty slice may or may not start the + /// HTTP request. Calling this function with an empty chunks finalizes the + /// request and always starts it. It is no longer valid to write more data + /// afterwards. /// Passing `None` as deadline blocks forever. /// - /// Returns an error in case deadline is reached or the chunk couldn't be written. + /// Returns an error if: + /// - The request identifier is invalid. + /// - `http_response_wait` has already been called on this request. + /// - The deadline is reached. + /// - An I/O error has happened, for example the remote has closed our + /// request. The request is then considered invalid. + /// fn http_request_write_body( &mut self, request_id: HttpRequestId, @@ -325,6 +417,9 @@ pub trait Externalities { /// Note that if deadline is not provided the method will block indefinitely, /// otherwise unready responses will produce `DeadlineReached` status. /// + /// If a response returns an `IoError`, it is then considered destroyed. + /// Its id is then invalid. + /// /// Passing `None` as deadline blocks forever. fn http_response_wait( &mut self, @@ -335,6 +430,12 @@ pub trait Externalities { /// Read all response headers. /// /// Returns a vector of pairs `(HeaderKey, HeaderValue)`. + /// + /// Dispatches the request if it hasn't been done yet. It is no longer + /// valid to modify the headers or write data to the request. + /// + /// Returns an empty list if the identifier is unknown/invalid, hasn't + /// received a response, or has finished. fn http_response_headers( &mut self, request_id: HttpRequestId @@ -342,9 +443,23 @@ pub trait Externalities { /// Read a chunk of body response to given buffer. /// + /// Dispatches the request if it hasn't been done yet. It is no longer + /// valid to modify the headers or write data to the request. + /// /// Returns the number of bytes written or an error in case a deadline /// is reached or server closed the connection. /// Passing `None` as a deadline blocks forever. + /// + /// If `Ok(0)` or `Err(IoError)` is returned, the request is considered + /// destroyed. Doing another read or getting the response's headers, for + /// example, is then invalid. + /// + /// Returns an error if: + /// - The request identifier is invalid. + /// - The deadline is reached. + /// - An I/O error has happened, for example the remote has closed our + /// request. The request is then considered invalid. + /// fn http_response_read_body( &mut self, request_id: HttpRequestId, @@ -430,7 +545,230 @@ impl Externalities for Box { (&mut **self).http_response_read_body(request_id, buffer, deadline) } } +/// An `OffchainExternalities` implementation with limited capabilities. +pub struct LimitedExternalities { + capabilities: Capabilities, + externalities: T, +} + +impl LimitedExternalities { + /// Create new externalities limited to given `capabilities`. + pub fn new(capabilities: Capabilities, externalities: T) -> Self { + Self { + capabilities, + externalities, + } + } + + /// Check if given capability is allowed. + /// + /// Panics in case it is not. + fn check(&self, capability: Capability, name: &'static str) { + if !self.capabilities.has(capability) { + panic!("Accessing a forbidden API: {}. No: {:?} capability.", name, capability); + } + } +} + +impl Externalities for LimitedExternalities { + fn is_validator(&self) -> bool { + self.check(Capability::Keystore, "is_validator"); + self.externalities.is_validator() + } + + fn submit_transaction(&mut self, ex: Vec) -> Result<(), ()> { + self.check(Capability::TransactionPool, "submit_transaction"); + self.externalities.submit_transaction(ex) + } + + fn network_state(&self) -> Result { + self.check(Capability::NetworkState, "network_state"); + self.externalities.network_state() + } + + fn timestamp(&mut self) -> Timestamp { + self.check(Capability::Http, "timestamp"); + self.externalities.timestamp() + } + + fn sleep_until(&mut self, deadline: Timestamp) { + self.check(Capability::Http, "sleep_until"); + self.externalities.sleep_until(deadline) + } + + fn random_seed(&mut self) -> [u8; 32] { + self.check(Capability::Randomness, "random_seed"); + self.externalities.random_seed() + } + fn local_storage_set(&mut self, kind: StorageKind, key: &[u8], value: &[u8]) { + self.check(Capability::OffchainWorkerDbWrite, "local_storage_set"); + self.externalities.local_storage_set(kind, key, value) + } + + fn local_storage_compare_and_set( + &mut self, + kind: StorageKind, + key: &[u8], + old_value: Option<&[u8]>, + new_value: &[u8], + ) -> bool { + self.check(Capability::OffchainWorkerDbWrite, "local_storage_compare_and_set"); + self.externalities.local_storage_compare_and_set(kind, key, old_value, new_value) + } + + fn local_storage_get(&mut self, kind: StorageKind, key: &[u8]) -> Option> { + self.check(Capability::OffchainWorkerDbRead, "local_storage_get"); + self.externalities.local_storage_get(kind, key) + } + + fn http_request_start(&mut self, method: &str, uri: &str, meta: &[u8]) -> Result { + self.check(Capability::Http, "http_request_start"); + self.externalities.http_request_start(method, uri, meta) + } + + fn http_request_add_header(&mut self, request_id: HttpRequestId, name: &str, value: &str) -> Result<(), ()> { + self.check(Capability::Http, "http_request_add_header"); + self.externalities.http_request_add_header(request_id, name, value) + } + + fn http_request_write_body( + &mut self, + request_id: HttpRequestId, + chunk: &[u8], + deadline: Option + ) -> Result<(), HttpError> { + self.check(Capability::Http, "http_request_write_body"); + self.externalities.http_request_write_body(request_id, chunk, deadline) + } + + fn http_response_wait(&mut self, ids: &[HttpRequestId], deadline: Option) -> Vec { + self.check(Capability::Http, "http_response_wait"); + self.externalities.http_response_wait(ids, deadline) + } + + fn http_response_headers(&mut self, request_id: HttpRequestId) -> Vec<(Vec, Vec)> { + self.check(Capability::Http, "http_response_headers"); + self.externalities.http_response_headers(request_id) + } + + fn http_response_read_body( + &mut self, + request_id: HttpRequestId, + buffer: &mut [u8], + deadline: Option + ) -> Result { + self.check(Capability::Http, "http_response_read_body"); + self.externalities.http_response_read_body(request_id, buffer, deadline) + } +} + +/// An implementation of offchain extensions that should never be triggered. +pub enum NeverOffchainExt {} + +impl NeverOffchainExt { + /// Create new offchain extensions. + pub fn new<'a>() -> Option<&'a mut Self> { + None + } +} + +impl Externalities for NeverOffchainExt { + fn is_validator(&self) -> bool { + unreachable!() + } + + fn submit_transaction(&mut self, _extrinsic: Vec) -> Result<(), ()> { + unreachable!() + } + + fn network_state( + &self, + ) -> Result { + unreachable!() + } + + fn timestamp(&mut self) -> Timestamp { + unreachable!() + } + + fn sleep_until(&mut self, _deadline: Timestamp) { + unreachable!() + } + + fn random_seed(&mut self) -> [u8; 32] { + unreachable!() + } + + fn local_storage_set(&mut self, _kind: StorageKind, _key: &[u8], _value: &[u8]) { + unreachable!() + } + + fn local_storage_compare_and_set( + &mut self, + _kind: StorageKind, + _key: &[u8], + _old_value: Option<&[u8]>, + _new_value: &[u8], + ) -> bool { + unreachable!() + } + + fn local_storage_get(&mut self, _kind: StorageKind, _key: &[u8]) -> Option> { + unreachable!() + } + + fn http_request_start( + &mut self, + _method: &str, + _uri: &str, + _meta: &[u8] + ) -> Result { + unreachable!() + } + + fn http_request_add_header( + &mut self, + _request_id: HttpRequestId, + _name: &str, + _value: &str + ) -> Result<(), ()> { + unreachable!() + } + + fn http_request_write_body( + &mut self, + _request_id: HttpRequestId, + _chunk: &[u8], + _deadline: Option + ) -> Result<(), HttpError> { + unreachable!() + } + + fn http_response_wait( + &mut self, + _ids: &[HttpRequestId], + _deadline: Option + ) -> Vec { + unreachable!() + } + + fn http_response_headers( + &mut self, + _request_id: HttpRequestId + ) -> Vec<(Vec, Vec)> { + unreachable!() + } + + fn http_response_read_body( + &mut self, + _request_id: HttpRequestId, + _buffer: &mut [u8], + _deadline: Option + ) -> Result { + unreachable!() + } +} #[cfg(test)] mod tests { @@ -443,4 +781,18 @@ mod tests { assert_eq!(t.sub(Duration::from_millis(10)), Timestamp(0)); assert_eq!(t.diff(&Timestamp(3)), Duration(2)); } + + #[test] + fn capabilities() { + let none = Capabilities::none(); + let all = Capabilities::all(); + let some = Capabilities::from(&[Capability::Keystore, Capability::Randomness][..]); + + assert!(!none.has(Capability::Keystore)); + assert!(all.has(Capability::Keystore)); + assert!(some.has(Capability::Keystore)); + assert!(!none.has(Capability::TransactionPool)); + assert!(all.has(Capability::TransactionPool)); + assert!(!some.has(Capability::TransactionPool)); + } } diff --git a/core/primitives/src/storage.rs b/core/primitives/src/storage.rs index 8fdb7bdcc40c03618ea1eb3f02f7356676452c1e..14c49bfaa96096ef63355f930a678660bb4fe88d 100644 --- a/core/primitives/src/storage.rs +++ b/core/primitives/src/storage.rs @@ -75,4 +75,22 @@ pub mod well_known_keys { // Other code might depend on this, so be careful changing this. key.starts_with(CHILD_STORAGE_KEY_PREFIX) } + + /// Determine whether a child trie key is valid. + /// + /// For now, the only valid child trie keys are those starting with `:child_storage:default:`. + /// + /// `child_trie_root` and `child_delta_trie_root` can panic if invalid value is provided to them. + pub fn is_child_trie_key_valid(storage_key: &[u8]) -> bool { + let has_right_prefix = storage_key.starts_with(b":child_storage:default:"); + if has_right_prefix { + // This is an attempt to catch a change of `is_child_storage_key`, which + // just checks if the key has prefix `:child_storage:` at the moment of writing. + debug_assert!( + is_child_storage_key(&storage_key), + "`is_child_trie_key_valid` is a subset of `is_child_storage_key`", + ); + } + has_right_prefix + } } diff --git a/core/primitives/src/testing.rs b/core/primitives/src/testing.rs index 932c8b9cb1e75707b10beb5870d39486e3e2d722..ccfc36af7326111fc490f435454ae48327a628b8 100644 --- a/core/primitives/src/testing.rs +++ b/core/primitives/src/testing.rs @@ -17,7 +17,14 @@ //! Types that should only be used for testing! #[cfg(feature = "std")] -use crate::{ed25519, sr25519, crypto::{Public, Pair, KeyTypeId}}; +use crate::{ed25519, sr25519, crypto::{Public, Pair}}; +use crate::crypto::KeyTypeId; // No idea why this import had to move from + // the previous line, but now the compiler is happy + +/// Key type for generic Ed25519 key. +pub const ED25519: KeyTypeId = KeyTypeId(*b"ed25"); +/// Key type for generic Sr 25519 key. +pub const SR25519: KeyTypeId = KeyTypeId(*b"sr25"); /// A keystore implementation usable in tests. #[cfg(feature = "std")] @@ -126,18 +133,20 @@ impl crate::traits::BareCryptoStore for KeyStore { #[cfg(test)] mod tests { use super::*; - use crate::{sr25519, crypto::key_types, traits::BareCryptoStore}; + use crate::{sr25519, traits::BareCryptoStore}; + use crate::testing::{ED25519, SR25519}; + #[test] fn store_key_and_extract() { let store = KeyStore::new(); let public = store.write() - .ed25519_generate_new(key_types::ED25519, None) + .ed25519_generate_new(ED25519, None) .expect("Genrates key"); let store_key_pair = store.read() - .ed25519_key_pair(key_types::ED25519, &public) + .ed25519_key_pair(ED25519, &public) .expect("Key should exists in store"); assert_eq!(public, store_key_pair.public()); @@ -151,13 +160,13 @@ mod tests { let key_pair = sr25519::Pair::from_string(secret_uri, None).expect("Generates key pair"); store.write().insert_unknown( - key_types::SR25519, + SR25519, secret_uri, key_pair.public().as_ref(), ).expect("Inserts unknown key"); let store_key_pair = store.read().sr25519_key_pair( - key_types::SR25519, + SR25519, &key_pair.public(), ).expect("Gets key pair from keystore"); diff --git a/core/primitives/src/traits.rs b/core/primitives/src/traits.rs index 8e2f0c0213a13b26ed290b685ed014d3e99f32fd..b173d8512cfc4abc288c0cb7a71d0509421b34f7 100644 --- a/core/primitives/src/traits.rs +++ b/core/primitives/src/traits.rs @@ -17,7 +17,11 @@ //! Shareable Substrate traits. #[cfg(feature = "std")] -use crate::{crypto::KeyTypeId, ed25519, sr25519}; +use crate::{crypto::KeyTypeId, ed25519, sr25519, child_storage_key::ChildStorageKey}; +#[cfg(feature = "std")] +use std::{fmt::{Debug, Display}, panic::UnwindSafe}; +#[cfg(feature = "std")] +use hash_db::Hasher; /// Something that generates, stores and provides access to keys. #[cfg(feature = "std")] @@ -68,3 +72,134 @@ pub trait BareCryptoStore: Send + Sync { /// A pointer to the key store. #[cfg(feature = "std")] pub type BareCryptoStorePtr = std::sync::Arc>; + +/// Externalities: pinned to specific active address. +#[cfg(feature = "std")] +pub trait Externalities { + /// Read runtime storage. + fn storage(&self, key: &[u8]) -> Option>; + + /// Get storage value hash. This may be optimized for large values. + fn storage_hash(&self, key: &[u8]) -> Option { + self.storage(key).map(|v| H::hash(&v)) + } + + /// Get child storage value hash. This may be optimized for large values. + fn child_storage_hash(&self, storage_key: ChildStorageKey, key: &[u8]) -> Option { + self.child_storage(storage_key, key).map(|v| H::hash(&v)) + } + + /// Read original runtime storage, ignoring any overlayed changes. + fn original_storage(&self, key: &[u8]) -> Option>; + + /// Read original runtime child storage, ignoring any overlayed changes. + fn original_child_storage(&self, storage_key: ChildStorageKey, key: &[u8]) -> Option>; + + /// Get original storage value hash, ignoring any overlayed changes. + /// This may be optimized for large values. + fn original_storage_hash(&self, key: &[u8]) -> Option { + self.original_storage(key).map(|v| H::hash(&v)) + } + + /// Get original child storage value hash, ignoring any overlayed changes. + /// This may be optimized for large values. + fn original_child_storage_hash( + &self, + storage_key: ChildStorageKey, + key: &[u8], + ) -> Option { + self.original_child_storage(storage_key, key).map(|v| H::hash(&v)) + } + + /// Read child runtime storage. + fn child_storage(&self, storage_key: ChildStorageKey, key: &[u8]) -> Option>; + + /// Set storage entry `key` of current contract being called (effective immediately). + fn set_storage(&mut self, key: Vec, value: Vec) { + self.place_storage(key, Some(value)); + } + + /// Set child storage entry `key` of current contract being called (effective immediately). + fn set_child_storage(&mut self, storage_key: ChildStorageKey, key: Vec, value: Vec) { + self.place_child_storage(storage_key, key, Some(value)) + } + + /// Clear a storage entry (`key`) of current contract being called (effective immediately). + fn clear_storage(&mut self, key: &[u8]) { + self.place_storage(key.to_vec(), None); + } + + /// Clear a child storage entry (`key`) of current contract being called (effective immediately). + fn clear_child_storage(&mut self, storage_key: ChildStorageKey, key: &[u8]) { + self.place_child_storage(storage_key, key.to_vec(), None) + } + + /// Whether a storage entry exists. + fn exists_storage(&self, key: &[u8]) -> bool { + self.storage(key).is_some() + } + + /// Whether a child storage entry exists. + fn exists_child_storage(&self, storage_key: ChildStorageKey, key: &[u8]) -> bool { + self.child_storage(storage_key, key).is_some() + } + + /// Clear an entire child storage. + fn kill_child_storage(&mut self, storage_key: ChildStorageKey); + + /// Clear storage entries which keys are start with the given prefix. + fn clear_prefix(&mut self, prefix: &[u8]); + + /// Clear child storage entries which keys are start with the given prefix. + fn clear_child_prefix(&mut self, storage_key: ChildStorageKey, prefix: &[u8]); + + /// Set or clear a storage entry (`key`) of current contract being called (effective immediately). + fn place_storage(&mut self, key: Vec, value: Option>); + + /// Set or clear a child storage entry. Return whether the operation succeeds. + fn place_child_storage(&mut self, storage_key: ChildStorageKey, key: Vec, value: Option>); + + /// Get the identity of the chain. + fn chain_id(&self) -> u64; + + /// Get the trie root of the current storage map. This will also update all child storage keys + /// in the top-level storage map. + fn storage_root(&mut self) -> H::Out where H::Out: Ord; + + /// Get the trie root of a child storage map. This will also update the value of the child + /// storage keys in the top-level storage map. + /// If the storage root equals the default hash as defined by the trie, the key in the top-level + /// storage map will be removed. + fn child_storage_root(&mut self, storage_key: ChildStorageKey) -> Vec; + + /// Get the change trie root of the current storage overlay at a block with given parent. + fn storage_changes_root(&mut self, parent: H::Out) -> Result, ()> where H::Out: Ord; + + /// Returns offchain externalities extension if present. + fn offchain(&mut self) -> Option<&mut dyn crate::offchain::Externalities>; + + /// Returns the keystore. + fn keystore(&self) -> Option; +} + +/// Code execution engine. +#[cfg(feature = "std")] +pub trait CodeExecutor: Sized + Send + Sync { + /// Externalities error type. + type Error: Display + Debug + Send + 'static; + + /// Call a given method in the runtime. Returns a tuple of the result (either the output data + /// or an execution error) together with a `bool`, which is true if native execution was used. + fn call< + E: Externalities, + R: codec::Codec + PartialEq, + NC: FnOnce() -> Result + UnwindSafe, + >( + &self, + ext: &mut E, + method: &str, + data: &[u8], + use_native: bool, + native_call: Option, + ) -> (Result, Self::Error>, bool); +} diff --git a/core/rpc-servers/Cargo.toml b/core/rpc-servers/Cargo.toml index 64a494f65ffe74b870720c2b0feb02de6e0ff46d..27601d8cc148e6a82fa979de5e185059c0cce155 100644 --- a/core/rpc-servers/Cargo.toml +++ b/core/rpc-servers/Cargo.toml @@ -5,12 +5,13 @@ authors = ["Parity Technologies "] edition = "2018" [dependencies] -pubsub = { package = "jsonrpc-pubsub", version = "12.0.0" } -log = "0.4" -serde = "1.0" -substrate-rpc = { path = "../rpc" } +jsonrpc-core = "13.2.0" +pubsub = { package = "jsonrpc-pubsub", version = "13.2.0" } +log = "0.4.8" +serde = "1.0.101" +serde_json = "1.0" sr-primitives = { path = "../sr-primitives" } [target.'cfg(not(target_os = "unknown"))'.dependencies] -http = { package = "jsonrpc-http-server", version = "12.0.0" } -ws = { package = "jsonrpc-ws-server", version = "12.0.0" } +http = { package = "jsonrpc-http-server", version = "13.2.0" } +ws = { package = "jsonrpc-ws-server", version = "13.2.0" } diff --git a/core/rpc-servers/src/lib.rs b/core/rpc-servers/src/lib.rs index a33f726747149414ebc8e90dd59e0f04791e332c..a23b4a08997341efe64e49a5b67b4fb8c5fec436 100644 --- a/core/rpc-servers/src/lib.rs +++ b/core/rpc-servers/src/lib.rs @@ -18,11 +18,10 @@ #[warn(missing_docs)] -pub use substrate_rpc as apis; - use std::io; +use jsonrpc_core::IoHandlerExtension; use log::error; -use sr_primitives::{traits::{Block as BlockT, NumberFor}, generic::SignedBlock}; +use pubsub::PubSubMetadata; /// Maximal payload accepted by RPC servers. const MAX_PAYLOAD: usize = 15 * 1024 * 1024; @@ -30,30 +29,30 @@ const MAX_PAYLOAD: usize = 15 * 1024 * 1024; /// Default maximum number of connections for WS RPC servers. const WS_MAX_CONNECTIONS: usize = 100; -pub type Metadata = apis::metadata::Metadata; -pub type RpcHandler = pubsub::PubSubHandler; +/// The RPC IoHandler containing all requested APIs. +pub type RpcHandler = pubsub::PubSubHandler; pub use self::inner::*; /// Construct rpc `IoHandler` -pub fn rpc_handler( - state: S, - chain: C, - author: A, - system: Y, -) -> RpcHandler where - Block: BlockT + 'static, - ExHash: Send + Sync + 'static + sr_primitives::Serialize + sr_primitives::DeserializeOwned, - S: apis::state::StateApi, - C: apis::chain::ChainApi, Block::Hash, Block::Header, SignedBlock, Metadata=Metadata>, - A: apis::author::AuthorApi, - Y: apis::system::SystemApi>, -{ +pub fn rpc_handler( + extension: impl IoHandlerExtension +) -> RpcHandler { let mut io = pubsub::PubSubHandler::default(); - io.extend_with(state.to_delegate()); - io.extend_with(chain.to_delegate()); - io.extend_with(author.to_delegate()); - io.extend_with(system.to_delegate()); + extension.augment(&mut io); + + // add an endpoint to list all available methods. + let mut methods = io.iter().map(|x| x.0.clone()).collect::>(); + io.add_method("rpc_methods", { + methods.sort(); + let methods = serde_json::to_value(&methods) + .expect("Serialization of Vec is infallible; qed"); + + move |_| Ok(serde_json::json!({ + "version": 1, + "methods": methods.clone(), + })) + }); io } @@ -67,10 +66,10 @@ mod inner { /// Start HTTP server listening on given address. /// /// **Note**: Only available if `not(target_os = "unknown")`. - pub fn start_http( + pub fn start_http( addr: &std::net::SocketAddr, cors: Option<&Vec>, - io: RpcHandler, + io: RpcHandler, ) -> io::Result { http::ServerBuilder::new(io) .threads(4) @@ -89,13 +88,13 @@ mod inner { /// Start WS server listening on given address. /// /// **Note**: Only available if `not(target_os = "unknown")`. - pub fn start_ws( + pub fn start_ws>> ( addr: &std::net::SocketAddr, max_connections: Option, cors: Option<&Vec>, - io: RpcHandler, + io: RpcHandler, ) -> io::Result { - ws::ServerBuilder::with_meta_extractor(io, |context: &ws::RequestContext| Metadata::new(context.sender())) + ws::ServerBuilder::with_meta_extractor(io, |context: &ws::RequestContext| context.sender().into()) .max_payload(MAX_PAYLOAD) .max_connections(max_connections.unwrap_or(WS_MAX_CONNECTIONS)) .allowed_origins(map_cors(cors)) diff --git a/core/rpc/Cargo.toml b/core/rpc/Cargo.toml index 957fe5be0b32703b4f1cb84003631fbb7eef8b6e..e6f0db1c9cb0647b5e5104616b94405d225fb38d 100644 --- a/core/rpc/Cargo.toml +++ b/core/rpc/Cargo.toml @@ -5,33 +5,31 @@ authors = ["Parity Technologies "] edition = "2018" [dependencies] -derive_more = "0.14.0" -futures = "0.1" -futures03 = { package = "futures-preview", version = "=0.3.0-alpha.17", features = ["compat"] } -jsonrpc-core = "12.0.0" -jsonrpc-core-client = "12.0.0" -jsonrpc-pubsub = "12.0.0" -jsonrpc-derive = "12.0.0" -log = "0.4" -parking_lot = "0.9.0" -codec = { package = "parity-scale-codec", version = "1.0.0" } -serde = { version = "1.0", features = ["derive"] } -serde_json = "1.0" +api = { package = "substrate-rpc-api", path = "./api" } client = { package = "substrate-client", path = "../client" } -substrate-executor = { path = "../executor" } -network = { package = "substrate-network", path = "../network" } +codec = { package = "parity-scale-codec", version = "1.0.0" } +futures03 = { package = "futures-preview", version = "0.3.0-alpha.19", features = ["compat"] } +jsonrpc-pubsub = "13.1.0" +log = "0.4.8" primitives = { package = "substrate-primitives", path = "../primitives" } +rpc = { package = "jsonrpc-core", version = "13.0.0" } +runtime_version = { package = "sr-version", path = "../sr-version" } +serde_json = "1.0.40" session = { package = "substrate-session", path = "../session" } -state_machine = { package = "substrate-state-machine", path = "../state-machine" } -transaction_pool = { package = "substrate-transaction-pool", path = "../transaction-pool" } sr-primitives = { path = "../sr-primitives" } -runtime_version = { package = "sr-version", path = "../sr-version" } +rpc-primitives = { package = "substrate-rpc-primitives", path = "primitives" } +state_machine = { package = "substrate-state-machine", path = "../state-machine" } +substrate-executor = { path = "../executor" } substrate-keystore = { path = "../keystore" } +transaction_pool = { package = "substrate-transaction-pool", path = "../transaction-pool" } +hash-db = { version = "0.15.2", default-features = false } +parking_lot = { version = "0.9.0" } [dev-dependencies] -assert_matches = "1.1" -futures = "0.1.17" +assert_matches = "1.3.0" +futures = "0.1.29" +network = { package = "substrate-network", path = "../network" } +rustc-hex = "2.0.1" sr-io = { path = "../sr-io" } test-client = { package = "substrate-test-runtime-client", path = "../test-runtime/client" } -rustc-hex = "2.0" -tokio = "0.1.17" +tokio = "0.1.22" diff --git a/core/rpc/api/Cargo.toml b/core/rpc/api/Cargo.toml new file mode 100644 index 0000000000000000000000000000000000000000..b2614dbcede89c9101690cc0d41c4d061ce0b805 --- /dev/null +++ b/core/rpc/api/Cargo.toml @@ -0,0 +1,22 @@ +[package] +name = "substrate-rpc-api" +version = "2.0.0" +authors = ["Parity Technologies "] +edition = "2018" + +[dependencies] +codec = { package = "parity-scale-codec", version = "1.0.0" } +derive_more = "0.15.0" +futures03 = { package = "futures-preview", version = "0.3.0-alpha.19", features = ["compat"] } +jsonrpc-core = "13.2.0" +jsonrpc-core-client = "13.2.0" +jsonrpc-derive = "13.2.0" +jsonrpc-pubsub = "13.2.0" +log = "0.4.8" +parking_lot = "0.9.0" +primitives = { package = "substrate-primitives", path = "../../primitives" } +runtime_version = { package = "sr-version", path = "../../sr-version" } +serde = { version = "1.0.101", features = ["derive"] } +serde_json = "1.0.40" +txpool = { package = "substrate-transaction-graph", path = "../../transaction-pool/graph" } +rpc-primitives = { package = "substrate-rpc-primitives", path = "../../rpc/primitives" } diff --git a/core/rpc/src/author/error.rs b/core/rpc/api/src/author/error.rs similarity index 83% rename from core/rpc/src/author/error.rs rename to core/rpc/api/src/author/error.rs index 2fcc8c780dfdb59dac5b69d49a11b68852601ee5..8e4f8877682b37cc036c06b41a453ae6cb08960d 100644 --- a/core/rpc/src/author/error.rs +++ b/core/rpc/api/src/author/error.rs @@ -16,20 +16,23 @@ //! Authoring RPC module errors. -use client; -use transaction_pool::txpool; -use crate::rpc; use crate::errors; +use jsonrpc_core as rpc; /// Author RPC Result type. pub type Result = std::result::Result; +/// Author RPC future Result type. +pub type FutureResult = Box + Send>; + /// Author RPC errors. #[derive(Debug, derive_more::Display, derive_more::From)] pub enum Error { /// Client error. - Client(client::error::Error), + #[display(fmt="Client error: {}", _0)] + Client(Box), /// Transaction pool error, + #[display(fmt="Transaction pool error: {}", _0)] Pool(txpool::error::Error), /// Verification error #[display(fmt="Extrinsic verification error: {}", _0)] @@ -54,7 +57,7 @@ pub enum Error { impl std::error::Error for Error { fn source(&self) -> Option<&(dyn std::error::Error + 'static)> { match self { - Error::Client(ref err) => Some(err), + Error::Client(ref err) => Some(&**err), Error::Pool(ref err) => Some(err), Error::Verification(ref err) => Some(&**err), _ => None, @@ -83,6 +86,8 @@ const POOL_TOO_LOW_PRIORITY: i64 = POOL_INVALID_TX + 4; const POOL_CYCLE_DETECTED: i64 = POOL_INVALID_TX + 5; /// The transaction was not included to the pool because of the limits. const POOL_IMMEDIATELY_DROPPED: i64 = POOL_INVALID_TX + 6; +/// The key type crypto is not known. +const UNSUPPORTED_KEY_TYPE: i64 = POOL_INVALID_TX + 7; impl From for rpc::Error { fn from(e: Error) -> Self { @@ -99,15 +104,15 @@ impl From for rpc::Error { message: format!("Verification Error: {}", e).into(), data: Some(format!("{:?}", e).into()), }, - Error::Pool(PoolError::InvalidTransaction(code)) => rpc::Error { + Error::Pool(PoolError::InvalidTransaction(e)) => rpc::Error { code: rpc::ErrorCode::ServerError(POOL_INVALID_TX), message: "Invalid Transaction".into(), - data: Some(code.into()), + data: serde_json::to_value(e).ok(), }, - Error::Pool(PoolError::UnknownTransactionValidity(code)) => rpc::Error { + Error::Pool(PoolError::UnknownTransaction(e)) => rpc::Error { code: rpc::ErrorCode::ServerError(POOL_UNKNOWN_VALIDITY), message: "Unknown Transaction Validity".into(), - data: Some(code.into()), + data: serde_json::to_value(e).ok(), }, Error::Pool(PoolError::TemporarilyBanned) => rpc::Error { code: rpc::ErrorCode::ServerError(POOL_TEMPORARILY_BANNED), @@ -131,9 +136,17 @@ impl From for rpc::Error { }, Error::Pool(PoolError::ImmediatelyDropped) => rpc::Error { code: rpc::ErrorCode::ServerError(POOL_IMMEDIATELY_DROPPED), - message: "Immediately Dropped" .into(), + message: "Immediately Dropped".into(), data: Some("The transaction couldn't enter the pool because of the limit".into()), }, + Error::UnsupportedKeyType => rpc::Error { + code: rpc::ErrorCode::ServerError(UNSUPPORTED_KEY_TYPE), + message: "Unknown key type crypto" .into(), + data: Some( + "The crypto for the given key type is unknown, please add the public key to the \ + request to insert the key successfully.".into() + ), + }, e => errors::internal(e), } } diff --git a/core/rpc/src/author/hash.rs b/core/rpc/api/src/author/hash.rs similarity index 100% rename from core/rpc/src/author/hash.rs rename to core/rpc/api/src/author/hash.rs diff --git a/core/rpc/api/src/author/mod.rs b/core/rpc/api/src/author/mod.rs new file mode 100644 index 0000000000000000000000000000000000000000..4ea96cb3c6122be47da5dea671b78249ebb40b36 --- /dev/null +++ b/core/rpc/api/src/author/mod.rs @@ -0,0 +1,86 @@ +// Copyright 2017-2019 Parity Technologies (UK) Ltd. +// This file is part of Substrate. + +// Substrate 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. + +// Substrate 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 Substrate. If not, see . + +//! Substrate block-author/full-node API. + +pub mod error; +pub mod hash; + +use jsonrpc_derive::rpc; +use jsonrpc_pubsub::{typed::Subscriber, SubscriptionId}; +use primitives::{ + Bytes +}; +use self::error::{FutureResult, Result}; +use txpool::watcher::Status; + +pub use self::gen_client::Client as AuthorClient; + +/// Substrate authoring RPC API +#[rpc] +pub trait AuthorApi { + /// RPC metadata + type Metadata; + + /// Submit hex-encoded extrinsic for inclusion in block. + #[rpc(name = "author_submitExtrinsic")] + fn submit_extrinsic(&self, extrinsic: Bytes) -> FutureResult; + + /// Insert a key into the keystore. + #[rpc(name = "author_insertKey")] + fn insert_key(&self, + key_type: String, + suri: String, + public: Bytes, + ) -> Result<()>; + + /// Generate new session keys and returns the corresponding public keys. + #[rpc(name = "author_rotateKeys")] + fn rotate_keys(&self) -> Result; + + /// Returns all pending extrinsics, potentially grouped by sender. + #[rpc(name = "author_pendingExtrinsics")] + fn pending_extrinsics(&self) -> Result>; + + /// Remove given extrinsic from the pool and temporarily ban it to prevent reimporting. + #[rpc(name = "author_removeExtrinsic")] + fn remove_extrinsic(&self, + bytes_or_hash: Vec> + ) -> Result>; + + /// Submit an extrinsic to watch. + #[pubsub( + subscription = "author_extrinsicUpdate", + subscribe, + name = "author_submitAndWatchExtrinsic" + )] + fn watch_extrinsic(&self, + metadata: Self::Metadata, + subscriber: Subscriber>, + bytes: Bytes + ); + + /// Unsubscribe from extrinsic watching. + #[pubsub( + subscription = "author_extrinsicUpdate", + unsubscribe, + name = "author_unwatchExtrinsic" + )] + fn unwatch_extrinsic(&self, + metadata: Option, + id: SubscriptionId + ) -> Result; +} diff --git a/core/rpc/src/chain/error.rs b/core/rpc/api/src/chain/error.rs similarity index 84% rename from core/rpc/src/chain/error.rs rename to core/rpc/api/src/chain/error.rs index ad63af9add0510731df2083916551555b4df105a..eccb7f4f1b0f0892eca1d1a91ce4280f1df3a028 100644 --- a/core/rpc/src/chain/error.rs +++ b/core/rpc/api/src/chain/error.rs @@ -17,18 +17,21 @@ //! Error helpers for Chain RPC module. -use client; -use crate::rpc; use crate::errors; +use jsonrpc_core as rpc; /// Chain RPC Result type. pub type Result = std::result::Result; +/// State RPC future Result type. +pub type FutureResult = Box + Send>; + /// Chain RPC errors. #[derive(Debug, derive_more::Display, derive_more::From)] pub enum Error { /// Client error. - Client(client::error::Error), + #[display(fmt="Client error: {}", _0)] + Client(Box), /// Other error type. Other(String), } @@ -36,7 +39,7 @@ pub enum Error { impl std::error::Error for Error { fn source(&self) -> Option<&(dyn std::error::Error + 'static)> { match self { - Error::Client(ref err) => Some(err), + Error::Client(ref err) => Some(&**err), _ => None, } } diff --git a/core/rpc/api/src/chain/mod.rs b/core/rpc/api/src/chain/mod.rs new file mode 100644 index 0000000000000000000000000000000000000000..73f4388236cc8bec6e58c61173f864be1ceaa944 --- /dev/null +++ b/core/rpc/api/src/chain/mod.rs @@ -0,0 +1,89 @@ +// Copyright 2017-2019 Parity Technologies (UK) Ltd. +// This file is part of Substrate. + +// Substrate 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. + +// Substrate 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 Substrate. If not, see . + +//! Substrate blockchain API. + +pub mod error; + +use jsonrpc_core::Result as RpcResult; +use jsonrpc_core::futures::Future; +use jsonrpc_derive::rpc; +use jsonrpc_pubsub::{typed::Subscriber, SubscriptionId}; +use rpc_primitives::number; +use self::error::{FutureResult, Result}; + +pub use self::gen_client::Client as ChainClient; + +/// Substrate blockchain API +#[rpc] +pub trait ChainApi { + /// RPC metadata + type Metadata; + + /// Get header of a relay chain block. + #[rpc(name = "chain_getHeader")] + fn header(&self, hash: Option) -> FutureResult>; + + /// Get header and body of a relay chain block. + #[rpc(name = "chain_getBlock")] + fn block(&self, hash: Option) -> FutureResult>; + + /// Get hash of the n-th block in the canon chain. + /// + /// By default returns latest block hash. + #[rpc(name = "chain_getBlockHash", alias("chain_getHead"))] + fn block_hash(&self, hash: Option>) -> Result>; + + /// Get hash of the last finalized block in the canon chain. + #[rpc(name = "chain_getFinalizedHead", alias("chain_getFinalisedHead"))] + fn finalized_head(&self) -> Result; + + /// New head subscription + #[pubsub( + subscription = "chain_newHead", + subscribe, + name = "chain_subscribeNewHeads", + alias("subscribe_newHead", "chain_subscribeNewHead") + )] + fn subscribe_new_heads(&self, metadata: Self::Metadata, subscriber: Subscriber
); + + /// Unsubscribe from new head subscription. + #[pubsub( + subscription = "chain_newHead", + unsubscribe, + name = "chain_unsubscribeNewHeads", + alias("unsubscribe_newHead", "chain_unsubscribeNewHead") + )] + fn unsubscribe_new_heads(&self, metadata: Option, id: SubscriptionId) -> RpcResult; + + /// New head subscription + #[pubsub( + subscription = "chain_finalizedHead", + subscribe, + name = "chain_subscribeFinalizedHeads", + alias("chain_subscribeFinalisedHeads") + )] + fn subscribe_finalized_heads(&self, metadata: Self::Metadata, subscriber: Subscriber
); + + /// Unsubscribe from new head subscription. + #[pubsub( + subscription = "chain_finalizedHead", + unsubscribe, + name = "chain_unsubscribeFinalizedHeads", + alias("chain_unsubscribeFinalisedHeads") + )] + fn unsubscribe_finalized_heads(&self, metadata: Option, id: SubscriptionId) -> RpcResult; +} diff --git a/core/rpc/src/errors.rs b/core/rpc/api/src/errors.rs similarity index 86% rename from core/rpc/src/errors.rs rename to core/rpc/api/src/errors.rs index da910de76215ae18339f942a40394b5cdbae7404..984a1cd712762c57957977ade8427604bf27f0ed 100644 --- a/core/rpc/src/errors.rs +++ b/core/rpc/api/src/errors.rs @@ -14,13 +14,12 @@ // You should have received a copy of the GNU General Public License // along with Substrate. If not, see . -use crate::rpc; use log::warn; -pub fn internal(e: E) -> rpc::Error { +pub fn internal(e: E) -> jsonrpc_core::Error { warn!("Unknown error: {:?}", e); - rpc::Error { - code: rpc::ErrorCode::InternalError, + jsonrpc_core::Error { + code: jsonrpc_core::ErrorCode::InternalError, message: "Unknown error occured".into(), data: Some(format!("{:?}", e).into()), } diff --git a/core/rpc/api/src/helpers.rs b/core/rpc/api/src/helpers.rs new file mode 100644 index 0000000000000000000000000000000000000000..d500a50a869b49dac52745643c8240f0d2145c55 --- /dev/null +++ b/core/rpc/api/src/helpers.rs @@ -0,0 +1,31 @@ +// Copyright 2018-2019 Parity Technologies (UK) Ltd. +// This file is part of Substrate. + +// Substrate 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. + +// Substrate 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 Substrate. If not, see . + +use jsonrpc_core::futures::prelude::*; +use futures03::{channel::oneshot, compat::Compat}; + +/// Wraps around `oneshot::Receiver` and adjusts the error type to produce an internal error if the +/// sender gets dropped. +pub struct Receiver(pub Compat>); + +impl Future for Receiver { + type Item = T; + type Error = jsonrpc_core::Error; + + fn poll(&mut self) -> Poll { + self.0.poll().map_err(|_| jsonrpc_core::Error::internal_error()) + } +} diff --git a/core/rpc/api/src/lib.rs b/core/rpc/api/src/lib.rs new file mode 100644 index 0000000000000000000000000000000000000000..12db07633dcc42c3dd3b0e3bbdae279efe712c7f --- /dev/null +++ b/core/rpc/api/src/lib.rs @@ -0,0 +1,34 @@ +// Copyright 2019 Parity Technologies (UK) Ltd. +// This file is part of Substrate. + +// Substrate 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. + +// Substrate 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 Substrate. If not, see . + +//! Substrate RPC interfaces. +//! +//! A collection of RPC methods and subscriptions supported by all substrate clients. + +#![warn(missing_docs)] + +mod errors; +mod helpers; +mod subscriptions; + +pub use jsonrpc_core::IoHandlerExtension as RpcExtension; +pub use subscriptions::{Subscriptions, TaskExecutor}; +pub use helpers::Receiver; + +pub mod author; +pub mod chain; +pub mod state; +pub mod system; diff --git a/core/rpc/src/state/error.rs b/core/rpc/api/src/state/error.rs similarity index 86% rename from core/rpc/src/state/error.rs rename to core/rpc/api/src/state/error.rs index 4b9d30b36b2043ef130492db91eb74004d12aba5..553a06e896f3d465c8d2d36872709a0d2f532c8a 100644 --- a/core/rpc/src/state/error.rs +++ b/core/rpc/api/src/state/error.rs @@ -16,18 +16,21 @@ //! State RPC errors. -use client; -use crate::rpc; use crate::errors; +use jsonrpc_core as rpc; /// State RPC Result type. pub type Result = std::result::Result; +/// State RPC future Result type. +pub type FutureResult = Box + Send>; + /// State RPC errors. #[derive(Debug, derive_more::Display, derive_more::From)] pub enum Error { /// Client error. - Client(client::error::Error), + #[display(fmt="Client error: {}", _0)] + Client(Box), /// Provided block range couldn't be resolved to a list of blocks. #[display(fmt = "Cannot resolve a block range ['{:?}' ... '{:?}]. {}", from, to, details)] InvalidBlockRange { @@ -43,7 +46,7 @@ pub enum Error { impl std::error::Error for Error { fn source(&self) -> Option<&(dyn std::error::Error + 'static)> { match self { - Error::Client(ref err) => Some(err), + Error::Client(ref err) => Some(&**err), _ => None, } } diff --git a/core/rpc/api/src/state/mod.rs b/core/rpc/api/src/state/mod.rs new file mode 100644 index 0000000000000000000000000000000000000000..0d06092ca1659b988584536cf5af56ae24ab09ee --- /dev/null +++ b/core/rpc/api/src/state/mod.rs @@ -0,0 +1,143 @@ +// Copyright 2017-2019 Parity Technologies (UK) Ltd. +// This file is part of Substrate. + +// Substrate 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. + +// Substrate 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 Substrate. If not, see . + +//! Substrate state API. + +pub mod error; + +use jsonrpc_core::Result as RpcResult; +use jsonrpc_core::futures::Future; +use jsonrpc_derive::rpc; +use jsonrpc_pubsub::{typed::Subscriber, SubscriptionId}; +use primitives::Bytes; +use primitives::storage::{StorageKey, StorageData, StorageChangeSet}; +use runtime_version::RuntimeVersion; +use self::error::FutureResult; + +pub use self::gen_client::Client as StateClient; + +/// Substrate state API +#[rpc] +pub trait StateApi { + /// RPC Metadata + type Metadata; + + /// Call a contract at a block's state. + #[rpc(name = "state_call", alias("state_callAt"))] + fn call(&self, name: String, bytes: Bytes, hash: Option) -> FutureResult; + + /// Returns the keys with prefix, leave empty to get all the keys + #[rpc(name = "state_getKeys")] + fn storage_keys(&self, prefix: StorageKey, hash: Option) -> FutureResult>; + + /// Returns a storage entry at a specific block's state. + #[rpc(name = "state_getStorage", alias("state_getStorageAt"))] + fn storage(&self, key: StorageKey, hash: Option) -> FutureResult>; + + /// Returns the hash of a storage entry at a block's state. + #[rpc(name = "state_getStorageHash", alias("state_getStorageHashAt"))] + fn storage_hash(&self, key: StorageKey, hash: Option) -> FutureResult>; + + /// Returns the size of a storage entry at a block's state. + #[rpc(name = "state_getStorageSize", alias("state_getStorageSizeAt"))] + fn storage_size(&self, key: StorageKey, hash: Option) -> FutureResult>; + + /// Returns the keys with prefix from a child storage, leave empty to get all the keys + #[rpc(name = "state_getChildKeys")] + fn child_storage_keys( + &self, + child_storage_key: StorageKey, + prefix: StorageKey, + hash: Option + ) -> FutureResult>; + + /// Returns a child storage entry at a specific block's state. + #[rpc(name = "state_getChildStorage")] + fn child_storage( + &self, + child_storage_key: StorageKey, + key: StorageKey, + hash: Option + ) -> FutureResult>; + + /// Returns the hash of a child storage entry at a block's state. + #[rpc(name = "state_getChildStorageHash")] + fn child_storage_hash( + &self, + child_storage_key: StorageKey, + key: StorageKey, + hash: Option + ) -> FutureResult>; + + /// Returns the size of a child storage entry at a block's state. + #[rpc(name = "state_getChildStorageSize")] + fn child_storage_size( + &self, + child_storage_key: StorageKey, + key: StorageKey, + hash: Option + ) -> FutureResult>; + + /// Returns the runtime metadata as an opaque blob. + #[rpc(name = "state_getMetadata")] + fn metadata(&self, hash: Option) -> FutureResult; + + /// Get the runtime version. + #[rpc(name = "state_getRuntimeVersion", alias("chain_getRuntimeVersion"))] + fn runtime_version(&self, hash: Option) -> FutureResult; + + /// Query historical storage entries (by key) starting from a block given as the second parameter. + /// + /// NOTE This first returned result contains the initial state of storage for all keys. + /// Subsequent values in the vector represent changes to the previous state (diffs). + #[rpc(name = "state_queryStorage")] + fn query_storage( + &self, + keys: Vec, + block: Hash, + hash: Option + ) -> FutureResult>>; + + /// New runtime version subscription + #[pubsub( + subscription = "state_runtimeVersion", + subscribe, + name = "state_subscribeRuntimeVersion", + alias("chain_subscribeRuntimeVersion") + )] + fn subscribe_runtime_version(&self, metadata: Self::Metadata, subscriber: Subscriber); + + /// Unsubscribe from runtime version subscription + #[pubsub( + subscription = "state_runtimeVersion", + unsubscribe, + name = "state_unsubscribeRuntimeVersion", + alias("chain_unsubscribeRuntimeVersion") + )] + fn unsubscribe_runtime_version(&self, metadata: Option, id: SubscriptionId) -> RpcResult; + + /// New storage subscription + #[pubsub(subscription = "state_storage", subscribe, name = "state_subscribeStorage")] + fn subscribe_storage( + &self, metadata: Self::Metadata, subscriber: Subscriber>, keys: Option> + ); + + /// Unsubscribe from storage subscription + #[pubsub(subscription = "state_storage", unsubscribe, name = "state_unsubscribeStorage")] + fn unsubscribe_storage( + &self, metadata: Option, id: SubscriptionId + ) -> RpcResult; +} diff --git a/core/rpc/src/subscriptions.rs b/core/rpc/api/src/subscriptions.rs similarity index 83% rename from core/rpc/src/subscriptions.rs rename to core/rpc/api/src/subscriptions.rs index 77e1d958f683fed3f639f8093d048bd946984677..a1e486138fd7c30a2cd1dd44e57f9a4792b43c94 100644 --- a/core/rpc/src/subscriptions.rs +++ b/core/rpc/api/src/subscriptions.rs @@ -20,11 +20,14 @@ use std::sync::{Arc, atomic::{self, AtomicUsize}}; use log::{error, warn}; use jsonrpc_pubsub::{SubscriptionId, typed::{Sink, Subscriber}}; use parking_lot::Mutex; -use crate::rpc::futures::sync::oneshot; -use crate::rpc::futures::{Future, future}; +use jsonrpc_core::futures::sync::oneshot; +use jsonrpc_core::futures::{Future, future}; type Id = u64; +/// Alias for a an implementation of `futures::future::Executor`. +pub type TaskExecutor = Arc + Send>> + Send + Sync>; + /// Generate unique ids for subscriptions. #[derive(Clone, Debug)] pub struct IdProvider { @@ -53,12 +56,12 @@ impl IdProvider { pub struct Subscriptions { next_id: IdProvider, active_subscriptions: Arc>>>, - executor: Arc + Send>> + Send + Sync>, + executor: TaskExecutor, } impl Subscriptions { /// Creates new `Subscriptions` object. - pub fn new(executor: Arc + Send>> + Send + Sync>) -> Self { + pub fn new(executor: TaskExecutor) -> Self { Subscriptions { next_id: Default::default(), active_subscriptions: Default::default(), @@ -69,15 +72,16 @@ impl Subscriptions { /// Creates new subscription for given subscriber. /// /// Second parameter is a function that converts Subscriber sink into a future. - /// This future will be driven to completion bu underlying event loop + /// This future will be driven to completion by the underlying event loop /// or will be cancelled in case #cancel is invoked. - pub fn add(&self, subscriber: Subscriber, into_future: G) where + pub fn add(&self, subscriber: Subscriber, into_future: G) -> SubscriptionId where G: FnOnce(Sink) -> R, R: future::IntoFuture, F: future::Future + Send + 'static, { let id = self.next_id.next_id(); - if let Ok(sink) = subscriber.assign_id(id.into()) { + let subscription_id: SubscriptionId = id.into(); + if let Ok(sink) = subscriber.assign_id(subscription_id.clone()) { let (tx, rx) = oneshot::channel(); let future = into_future(sink) .into_future() @@ -89,6 +93,8 @@ impl Subscriptions { error!("Failed to spawn RPC subscription task"); } } + + subscription_id } /// Cancel subscription. diff --git a/core/rpc/src/system/error.rs b/core/rpc/api/src/system/error.rs similarity index 98% rename from core/rpc/src/system/error.rs rename to core/rpc/api/src/system/error.rs index bdd4cbe667e59a084d3b83f41b62e88f1518d5cd..32b694e3ac0088611bcd85edaae1e732cda650b9 100644 --- a/core/rpc/src/system/error.rs +++ b/core/rpc/api/src/system/error.rs @@ -16,8 +16,8 @@ //! System RPC module errors. -use crate::rpc; use crate::system::helpers::Health; +use jsonrpc_core as rpc; /// System RPC Result type. pub type Result = std::result::Result; diff --git a/core/rpc/src/system/helpers.rs b/core/rpc/api/src/system/helpers.rs similarity index 100% rename from core/rpc/src/system/helpers.rs rename to core/rpc/api/src/system/helpers.rs diff --git a/core/rpc/api/src/system/mod.rs b/core/rpc/api/src/system/mod.rs new file mode 100644 index 0000000000000000000000000000000000000000..b5eacc5d618233d30166bf0463fed9829705bd31 --- /dev/null +++ b/core/rpc/api/src/system/mod.rs @@ -0,0 +1,67 @@ +// Copyright 2017-2019 Parity Technologies (UK) Ltd. +// This file is part of Substrate. + +// Substrate 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. + +// Substrate 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 Substrate. If not, see . + +//! Substrate system API. + +pub mod error; +pub mod helpers; + +use crate::helpers::Receiver; +use jsonrpc_derive::rpc; + +use self::error::Result; + +pub use self::helpers::{Properties, SystemInfo, Health, PeerInfo}; +pub use self::gen_client::Client as SystemClient; + +/// Substrate system RPC API +#[rpc] +pub trait SystemApi { + /// Get the node's implementation name. Plain old string. + #[rpc(name = "system_name")] + fn system_name(&self) -> Result; + + /// Get the node implementation's version. Should be a semver string. + #[rpc(name = "system_version")] + fn system_version(&self) -> Result; + + /// Get the chain's type. Given as a string identifier. + #[rpc(name = "system_chain")] + fn system_chain(&self) -> Result; + + /// Get a custom set of properties as a JSON object, defined in the chain spec. + #[rpc(name = "system_properties")] + fn system_properties(&self) -> Result; + + /// Return health status of the node. + /// + /// Node is considered healthy if it is: + /// - connected to some peers (unless running in dev mode) + /// - not performing a major sync + #[rpc(name = "system_health", returns = "Health")] + fn system_health(&self) -> Receiver; + + /// Returns currently connected peers + #[rpc(name = "system_peers", returns = "Vec>")] + fn system_peers(&self) -> Receiver>>; + + /// Returns current state of the network. + /// + /// **Warning**: This API is not stable. + // TODO: make this stable and move structs https://github.com/paritytech/substrate/issues/1890 + #[rpc(name = "system_networkState", returns = "jsonrpc_core::Value")] + fn system_network_state(&self) -> Receiver; +} diff --git a/core/rpc/primitives/Cargo.toml b/core/rpc/primitives/Cargo.toml new file mode 100644 index 0000000000000000000000000000000000000000..4044428112780949b6c1d469406b89b87d575c34 --- /dev/null +++ b/core/rpc/primitives/Cargo.toml @@ -0,0 +1,9 @@ +[package] +name = "substrate-rpc-primitives" +version = "2.0.0" +authors = ["Parity Technologies "] +edition = "2018" + +[dependencies] +serde = { version = "1.0.101", features = ["derive"] } +primitives = { package = "substrate-primitives", path = "../../primitives" } diff --git a/core/rpc/primitives/src/lib.rs b/core/rpc/primitives/src/lib.rs new file mode 100644 index 0000000000000000000000000000000000000000..667b1b1b4b4f9619b2a3823a9dca0cac92f73c61 --- /dev/null +++ b/core/rpc/primitives/src/lib.rs @@ -0,0 +1,21 @@ +// Copyright 2019 Parity Technologies (UK) Ltd. +// This file is part of Substrate. + +// Substrate 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. + +// Substrate 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 Substrate. If not, see . + +//! Substrate RPC primitives and utilities. + +#![warn(missing_docs)] + +pub mod number; diff --git a/core/rpc/src/chain/number.rs b/core/rpc/primitives/src/number.rs similarity index 98% rename from core/rpc/src/chain/number.rs rename to core/rpc/primitives/src/number.rs index df796d5e6d9911c2f952dc344cd69b23eef0a3b9..0637e3decf39645b3561a61d7d8881451ce142a3 100644 --- a/core/rpc/src/chain/number.rs +++ b/core/rpc/primitives/src/number.rs @@ -61,14 +61,12 @@ impl + From + Debug + PartialOrd> NumberOrHex } } -#[cfg(test)] impl From for NumberOrHex { fn from(n: u64) -> Self { NumberOrHex::Number(n) } } -#[cfg(test)] impl From for NumberOrHex { fn from(n: U256) -> Self { NumberOrHex::Hex(n) diff --git a/core/rpc/src/author/mod.rs b/core/rpc/src/author/mod.rs index d797e87da57760dfff6bc5ba18b70f7a362c2cb8..9a978f22f717a1f2ae20457c009d46630a072d66 100644 --- a/core/rpc/src/author/mod.rs +++ b/core/rpc/src/author/mod.rs @@ -16,27 +16,25 @@ //! Substrate block-author/full-node API. -pub mod error; -pub mod hash; - #[cfg(test)] mod tests; use std::{sync::Arc, convert::TryInto}; +use futures03::future::{FutureExt, TryFutureExt}; +use log::warn; use client::{self, Client}; -use crate::rpc::futures::{Sink, Stream, Future}; -use crate::subscriptions::Subscriptions; -use jsonrpc_derive::rpc; +use rpc::futures::{ + Sink, Future, + stream::Stream as _, + future::result, +}; +use futures03::{StreamExt as _, compat::Compat}; +use api::Subscriptions; use jsonrpc_pubsub::{typed::Subscriber, SubscriptionId}; -use log::warn; use codec::{Encode, Decode}; -use primitives::{ - Bytes, Blake2Hasher, H256, ed25519, sr25519, crypto::{Pair, Public, key_types}, - traits::BareCryptoStorePtr, -}; +use primitives::{Bytes, Blake2Hasher, H256, traits::BareCryptoStorePtr}; use sr_primitives::{generic, traits::{self, ProvideRuntimeApi}}; -use self::error::{Error, Result}; use transaction_pool::{ txpool::{ ChainApi as PoolChainApi, @@ -49,63 +47,9 @@ use transaction_pool::{ }; use session::SessionKeys; -pub use self::gen_client::Client as AuthorClient; - -/// Substrate authoring RPC API -#[rpc] -pub trait AuthorApi { - /// RPC metadata - type Metadata; - - /// Submit hex-encoded extrinsic for inclusion in block. - #[rpc(name = "author_submitExtrinsic")] - fn submit_extrinsic(&self, extrinsic: Bytes) -> Result; - - /// Insert a key into the keystore. - #[rpc(name = "author_insertKey")] - fn insert_key(&self, - key_type: String, - suri: String, - maybe_public: Option - ) -> Result; - - /// Generate new session keys and returns the corresponding public keys. - #[rpc(name = "author_rotateKeys")] - fn rotate_keys(&self) -> Result; - - /// Returns all pending extrinsics, potentially grouped by sender. - #[rpc(name = "author_pendingExtrinsics")] - fn pending_extrinsics(&self) -> Result>; - - /// Remove given extrinsic from the pool and temporarily ban it to prevent reimporting. - #[rpc(name = "author_removeExtrinsic")] - fn remove_extrinsic(&self, - bytes_or_hash: Vec> - ) -> Result>; - - /// Submit an extrinsic to watch. - #[pubsub( - subscription = "author_extrinsicUpdate", - subscribe, - name = "author_submitAndWatchExtrinsic" - )] - fn watch_extrinsic(&self, - metadata: Self::Metadata, - subscriber: Subscriber>, - bytes: Bytes - ); - - /// Unsubscribe from extrinsic watching. - #[pubsub( - subscription = "author_extrinsicUpdate", - unsubscribe, - name = "author_unwatchExtrinsic" - )] - fn unwatch_extrinsic(&self, - metadata: Option, - id: SubscriptionId - ) -> Result; -} +/// Re-export the API for backward compatibility. +pub use api::author::*; +use self::error::{Error, FutureResult, Result}; /// Authoring API pub struct Author where P: PoolChainApi + Sync + Send + 'static { @@ -152,29 +96,13 @@ impl AuthorApi, BlockHash

> for Author whe &self, key_type: String, suri: String, - maybe_public: Option, - ) -> Result { + public: Bytes, + ) -> Result<()> { let key_type = key_type.as_str().try_into().map_err(|_| Error::BadKeyType)?; let mut keystore = self.keystore.write(); - let maybe_password = keystore.password(); - let public = match maybe_public { - Some(public) => public.0, - None => { - let maybe_public = match key_type { - key_types::BABE | key_types::IM_ONLINE | key_types::SR25519 => - sr25519::Pair::from_string(&suri, maybe_password) - .map(|pair| pair.public().to_raw_vec()), - key_types::GRANDPA | key_types::ED25519 => - ed25519::Pair::from_string(&suri, maybe_password) - .map(|pair| pair.public().to_raw_vec()), - _ => Err(Error::UnsupportedKeyType)?, - }; - maybe_public.map_err(|_| Error::BadSeedPhrase)? - } - }; keystore.insert_unknown(key_type, &suri, &public[..]) .map_err(|_| Error::KeyStoreUnavailable)?; - Ok(public.into()) + Ok(()) } fn rotate_keys(&self) -> Result { @@ -182,18 +110,22 @@ impl AuthorApi, BlockHash

> for Author whe self.client.runtime_api().generate_session_keys( &generic::BlockId::Hash(best_block_hash), None, - ).map(Into::into).map_err(Into::into) + ).map(Into::into).map_err(|e| Error::Client(Box::new(e))) } - fn submit_extrinsic(&self, ext: Bytes) -> Result> { - let xt = Decode::decode(&mut &ext[..])?; + fn submit_extrinsic(&self, ext: Bytes) -> FutureResult> { + let xt = match Decode::decode(&mut &ext[..]) { + Ok(xt) => xt, + Err(err) => return Box::new(result(Err(err.into()))), + }; let best_block_hash = self.client.info().chain.best_hash; - self.pool + Box::new(self.pool .submit_one(&generic::BlockId::hash(best_block_hash), xt) + .compat() .map_err(|e| e.into_pool_error() .map(Into::into) - .unwrap_or_else(|e| error::Error::Verification(Box::new(e)).into()) - ) + .unwrap_or_else(|e| error::Error::Verification(Box::new(e)).into())) + ) } fn pending_extrinsics(&self) -> Result> { @@ -228,17 +160,20 @@ impl AuthorApi, BlockHash

> for Author whe ) { let submit = || -> Result<_> { let best_block_hash = self.client.info().chain.best_hash; - let dxt = <

::Block as traits::Block>::Extrinsic::decode(&mut &xt[..])?; - self.pool + let dxt = <

::Block as traits::Block>::Extrinsic::decode(&mut &xt[..]) + .map_err(error::Error::from)?; + Ok(self.pool .submit_and_watch(&generic::BlockId::hash(best_block_hash), dxt) + .boxed() + .compat() .map_err(|e| e.into_pool_error() - .map(Into::into) + .map(error::Error::from) .unwrap_or_else(|e| error::Error::Verification(Box::new(e)).into()) - ) + )) }; - let watcher = match submit() { - Ok(watcher) => watcher, + let future_watcher = match submit() { + Ok(future_watcher) => future_watcher, Err(err) => { // reject the subscriber (ignore errors - we don't care if subscriber is no longer there). let _ = subscriber.reject(err.into()); @@ -246,12 +181,23 @@ impl AuthorApi, BlockHash

> for Author whe }, }; + // make 'future' watcher be a future with output = stream of watcher events + let future_watcher = future_watcher + .map_err(|err| { warn!("Failed to submit extrinsic: {}", err); }) + .map(|watcher| Compat::new(watcher.into_stream().map(|v| Ok::<_, ()>(Ok(v))))); + + // convert a 'future' watcher into the stream with single element = stream of watcher events + let watcher_stream = future_watcher.into_stream(); + + // and now flatten the 'watcher_stream' so that we'll have the stream with watcher events + let watcher_stream = watcher_stream.flatten(); + self.subscriptions.add(subscriber, move |sink| { sink .sink_map_err(|e| warn!("Error sending notifications: {:?}", e)) - .send_all(watcher.into_stream().map(Ok)) + .send_all(watcher_stream) .map(|_| ()) - }) + }); } fn unwatch_extrinsic(&self, _metadata: Option, id: SubscriptionId) -> Result { diff --git a/core/rpc/src/author/tests.rs b/core/rpc/src/author/tests.rs index 0fdff9989b1cab11b74cfa18f73598842ac6b93e..57d3929d928f70e60f1a86060d10e7282e3f8141 100644 --- a/core/rpc/src/author/tests.rs +++ b/core/rpc/src/author/tests.rs @@ -21,11 +21,11 @@ use assert_matches::assert_matches; use codec::Encode; use transaction_pool::{ txpool::Pool, - ChainApi, + FullChainApi, }; use primitives::{ - H256, blake2_256, hexdisplay::HexDisplay, traits::BareCryptoStore, testing::KeyStore, - ed25519, crypto::key_types, + H256, blake2_256, hexdisplay::HexDisplay, traits::BareCryptoStore, + testing::{ED25519, SR25519, KeyStore}, ed25519, crypto::Pair }; use test_client::{ self, AccountKeyring, runtime::{Extrinsic, Transfer, SessionKeys}, DefaultTestClientBuilderExt, @@ -50,7 +50,7 @@ fn submit_transaction_should_not_cause_error() { let keystore = KeyStore::new(); let p = Author { client: client.clone(), - pool: Arc::new(Pool::new(Default::default(), ChainApi::new(client))), + pool: Arc::new(Pool::new(Default::default(), FullChainApi::new(client))), subscriptions: Subscriptions::new(Arc::new(runtime.executor())), keystore: keystore.clone(), }; @@ -58,11 +58,11 @@ fn submit_transaction_should_not_cause_error() { let h: H256 = blake2_256(&xt).into(); assert_matches!( - AuthorApi::submit_extrinsic(&p, xt.clone().into()), + AuthorApi::submit_extrinsic(&p, xt.clone().into()).wait(), Ok(h2) if h == h2 ); assert!( - AuthorApi::submit_extrinsic(&p, xt.into()).is_err() + AuthorApi::submit_extrinsic(&p, xt.into()).wait().is_err() ); } @@ -73,7 +73,7 @@ fn submit_rich_transaction_should_not_cause_error() { let keystore = KeyStore::new(); let p = Author { client: client.clone(), - pool: Arc::new(Pool::new(Default::default(), ChainApi::new(client.clone()))), + pool: Arc::new(Pool::new(Default::default(), FullChainApi::new(client.clone()))), subscriptions: Subscriptions::new(Arc::new(runtime.executor())), keystore: keystore.clone(), }; @@ -81,11 +81,11 @@ fn submit_rich_transaction_should_not_cause_error() { let h: H256 = blake2_256(&xt).into(); assert_matches!( - AuthorApi::submit_extrinsic(&p, xt.clone().into()), + AuthorApi::submit_extrinsic(&p, xt.clone().into()).wait(), Ok(h2) if h == h2 ); assert!( - AuthorApi::submit_extrinsic(&p, xt.into()).is_err() + AuthorApi::submit_extrinsic(&p, xt.into()).wait().is_err() ); } @@ -94,7 +94,7 @@ fn should_watch_extrinsic() { //given let mut runtime = runtime::Runtime::new().unwrap(); let client = Arc::new(test_client::new()); - let pool = Arc::new(Pool::new(Default::default(), ChainApi::new(client.clone()))); + let pool = Arc::new(Pool::new(Default::default(), FullChainApi::new(client.clone()))); let keystore = KeyStore::new(); let p = Author { client, @@ -119,7 +119,7 @@ fn should_watch_extrinsic() { }; tx.into_signed_tx() }; - AuthorApi::submit_extrinsic(&p, replacement.encode().into()).unwrap(); + AuthorApi::submit_extrinsic(&p, replacement.encode().into()).wait().unwrap(); let (res, data) = runtime.block_on(data.into_future()).unwrap(); assert_eq!( res, @@ -136,7 +136,7 @@ fn should_watch_extrinsic() { fn should_return_pending_extrinsics() { let runtime = runtime::Runtime::new().unwrap(); let client = Arc::new(test_client::new()); - let pool = Arc::new(Pool::new(Default::default(), ChainApi::new(client.clone()))); + let pool = Arc::new(Pool::new(Default::default(), FullChainApi::new(client.clone()))); let keystore = KeyStore::new(); let p = Author { client, @@ -145,7 +145,7 @@ fn should_return_pending_extrinsics() { keystore: keystore.clone(), }; let ex = uxt(AccountKeyring::Alice, 0); - AuthorApi::submit_extrinsic(&p, ex.encode().into()).unwrap(); + AuthorApi::submit_extrinsic(&p, ex.encode().into()).wait().unwrap(); assert_matches!( p.pending_extrinsics(), Ok(ref expected) if *expected == vec![Bytes(ex.encode())] @@ -156,7 +156,7 @@ fn should_return_pending_extrinsics() { fn should_remove_extrinsics() { let runtime = runtime::Runtime::new().unwrap(); let client = Arc::new(test_client::new()); - let pool = Arc::new(Pool::new(Default::default(), ChainApi::new(client.clone()))); + let pool = Arc::new(Pool::new(Default::default(), FullChainApi::new(client.clone()))); let keystore = KeyStore::new(); let p = Author { client, @@ -165,11 +165,11 @@ fn should_remove_extrinsics() { keystore: keystore.clone(), }; let ex1 = uxt(AccountKeyring::Alice, 0); - p.submit_extrinsic(ex1.encode().into()).unwrap(); + p.submit_extrinsic(ex1.encode().into()).wait().unwrap(); let ex2 = uxt(AccountKeyring::Alice, 1); - p.submit_extrinsic(ex2.encode().into()).unwrap(); + p.submit_extrinsic(ex2.encode().into()).wait().unwrap(); let ex3 = uxt(AccountKeyring::Bob, 0); - let hash3 = p.submit_extrinsic(ex3.encode().into()).unwrap(); + let hash3 = p.submit_extrinsic(ex3.encode().into()).wait().unwrap(); assert_eq!(pool.status().ready, 3); // now remove all 3 @@ -189,7 +189,7 @@ fn should_insert_key() { let keystore = KeyStore::new(); let p = Author { client: client.clone(), - pool: Arc::new(Pool::new(Default::default(), ChainApi::new(client))), + pool: Arc::new(Pool::new(Default::default(), FullChainApi::new(client))), subscriptions: Subscriptions::new(Arc::new(runtime.executor())), keystore: keystore.clone(), }; @@ -197,13 +197,13 @@ fn should_insert_key() { let suri = "//Alice"; let key_pair = ed25519::Pair::from_string(suri, None).expect("Generates keypair"); p.insert_key( - String::from_utf8(key_types::ED25519.0.to_vec()).expect("Keytype is a valid string"), + String::from_utf8(ED25519.0.to_vec()).expect("Keytype is a valid string"), suri.to_string(), - Some(key_pair.public().0.to_vec().into()), + key_pair.public().0.to_vec().into(), ).expect("Insert key"); let store_key_pair = keystore.read() - .ed25519_key_pair(key_types::ED25519, &key_pair.public()).expect("Key exists in store"); + .ed25519_key_pair(ED25519, &key_pair.public()).expect("Key exists in store"); assert_eq!(key_pair.public(), store_key_pair.public()); } @@ -215,7 +215,7 @@ fn should_rotate_keys() { let client = Arc::new(test_client::TestClientBuilder::new().set_keystore(keystore.clone()).build()); let p = Author { client: client.clone(), - pool: Arc::new(Pool::new(Default::default(), ChainApi::new(client))), + pool: Arc::new(Pool::new(Default::default(), FullChainApi::new(client))), subscriptions: Subscriptions::new(Arc::new(runtime.executor())), keystore: keystore.clone(), }; @@ -226,15 +226,15 @@ fn should_rotate_keys() { .expect("SessionKeys decode successfully"); let ed25519_key_pair = keystore.read().ed25519_key_pair( - key_types::ED25519, + ED25519, &session_keys.ed25519.clone().into(), ).expect("ed25519 key exists in store"); let sr25519_key_pair = keystore.read().sr25519_key_pair( - key_types::SR25519, + SR25519, &session_keys.sr25519.clone().into(), ).expect("sr25519 key exists in store"); assert_eq!(session_keys.ed25519, ed25519_key_pair.public().into()); assert_eq!(session_keys.sr25519, sr25519_key_pair.public().into()); -} \ No newline at end of file +} diff --git a/core/rpc/src/chain/chain_full.rs b/core/rpc/src/chain/chain_full.rs new file mode 100644 index 0000000000000000000000000000000000000000..ad359a9300cdd63b4e513d3e428e3fecb799aebf --- /dev/null +++ b/core/rpc/src/chain/chain_full.rs @@ -0,0 +1,79 @@ +// Copyright 2019 Parity Technologies (UK) Ltd. +// This file is part of Substrate. + +// Substrate 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. + +// Substrate 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 Substrate. If not, see . + +//! Blockchain API backend for full nodes. + +use std::sync::Arc; +use rpc::futures::future::result; + +use api::Subscriptions; +use client::{backend::Backend, CallExecutor, Client}; +use primitives::{H256, Blake2Hasher}; +use sr_primitives::{ + generic::{BlockId, SignedBlock}, + traits::{Block as BlockT}, +}; + +use super::{ChainBackend, client_err, error::FutureResult}; + +/// Blockchain API backend for full nodes. Reads all the data from local database. +pub struct FullChain { + /// Substrate client. + client: Arc>, + /// Current subscriptions. + subscriptions: Subscriptions, +} + +impl FullChain { + /// Create new Chain API RPC handler. + pub fn new(client: Arc>, subscriptions: Subscriptions) -> Self { + Self { + client, + subscriptions, + } + } +} + +impl ChainBackend for FullChain where + Block: BlockT + 'static, + B: Backend + Send + Sync + 'static, + E: CallExecutor + Send + Sync + 'static, + RA: Send + Sync + 'static, +{ + fn client(&self) -> &Arc> { + &self.client + } + + fn subscriptions(&self) -> &Subscriptions { + &self.subscriptions + } + + fn header(&self, hash: Option) -> FutureResult> { + Box::new(result(self.client + .header(&BlockId::Hash(self.unwrap_or_best(hash))) + .map_err(client_err) + )) + } + + fn block(&self, hash: Option) + -> FutureResult>> + { + Box::new(result(self.client + .block(&BlockId::Hash(self.unwrap_or_best(hash))) + .map_err(client_err) + )) + } +} diff --git a/core/rpc/src/chain/chain_light.rs b/core/rpc/src/chain/chain_light.rs new file mode 100644 index 0000000000000000000000000000000000000000..d969d6ca9370218df642fc2a1caa984c0e5ef09e --- /dev/null +++ b/core/rpc/src/chain/chain_light.rs @@ -0,0 +1,123 @@ +// Copyright 2019 Parity Technologies (UK) Ltd. +// This file is part of Substrate. + +// Substrate 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. + +// Substrate 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 Substrate. If not, see . + +//! Blockchain API backend for light nodes. + +use std::sync::Arc; +use futures03::{future::ready, FutureExt, TryFutureExt}; +use rpc::futures::future::{result, Future, Either}; + +use api::Subscriptions; +use client::{ + self, Client, + light::{ + fetcher::{Fetcher, RemoteBodyRequest}, + blockchain::RemoteBlockchain, + }, +}; +use primitives::{H256, Blake2Hasher}; +use sr_primitives::{ + generic::{BlockId, SignedBlock}, + traits::{Block as BlockT}, +}; + +use super::{ChainBackend, client_err, error::FutureResult}; + +/// Blockchain API backend for light nodes. Reads all the data from local +/// database, if available, or fetches it from remote node otherwise. +pub struct LightChain { + /// Substrate client. + client: Arc>, + /// Current subscriptions. + subscriptions: Subscriptions, + /// Remote blockchain reference + remote_blockchain: Arc>, + /// Remote fetcher reference. + fetcher: Arc, +} + +impl> LightChain { + /// Create new Chain API RPC handler. + pub fn new( + client: Arc>, + subscriptions: Subscriptions, + remote_blockchain: Arc>, + fetcher: Arc, + ) -> Self { + Self { + client, + subscriptions, + remote_blockchain, + fetcher, + } + } +} + +impl ChainBackend for LightChain where + Block: BlockT + 'static, + B: client::backend::Backend + Send + Sync + 'static, + E: client::CallExecutor + Send + Sync + 'static, + RA: Send + Sync + 'static, + F: Fetcher + Send + Sync + 'static, +{ + fn client(&self) -> &Arc> { + &self.client + } + + fn subscriptions(&self) -> &Subscriptions { + &self.subscriptions + } + + fn header(&self, hash: Option) -> FutureResult> { + let hash = self.unwrap_or_best(hash); + + let fetcher = self.fetcher.clone(); + let maybe_header = client::light::blockchain::future_header( + &*self.remote_blockchain, + &*fetcher, + BlockId::Hash(hash), + ); + + Box::new(maybe_header.then(move |result| + ready(result.map_err(client_err)), + ).boxed().compat()) + } + + fn block(&self, hash: Option) + -> FutureResult>> + { + let fetcher = self.fetcher.clone(); + let block = self.header(hash) + .and_then(move |header| match header { + Some(header) => Either::A(fetcher + .remote_body(RemoteBodyRequest { + header: header.clone(), + retry_count: Default::default(), + }) + .boxed() + .compat() + .map(move |body| Some(SignedBlock { + block: Block::new(header, body), + justification: None, + })) + .map_err(client_err) + ), + None => Either::B(result(Ok(None))), + }); + + Box::new(block) + } +} diff --git a/core/rpc/src/chain/mod.rs b/core/rpc/src/chain/mod.rs index 9b8192e660e9be207c19c0b639ddccec88f5130a..61ecf967113832f456fc88231f2851618261352c 100644 --- a/core/rpc/src/chain/mod.rs +++ b/core/rpc/src/chain/mod.rs @@ -16,156 +16,182 @@ //! Substrate blockchain API. -pub mod error; -pub mod number; +mod chain_full; +mod chain_light; #[cfg(test)] mod tests; use std::sync::Arc; use futures03::{future, StreamExt as _, TryStreamExt as _}; - -use client::{self, Client, BlockchainEvents}; -use crate::rpc::Result as RpcResult; -use crate::rpc::futures::{stream, Future, Sink, Stream}; -use crate::subscriptions::Subscriptions; -use jsonrpc_derive::rpc; -use jsonrpc_pubsub::{typed::Subscriber, SubscriptionId}; use log::warn; +use rpc::{ + Result as RpcResult, + futures::{stream, Future, Sink, Stream}, +}; + +use api::Subscriptions; +use client::{ + self, Client, BlockchainEvents, + light::{fetcher::Fetcher, blockchain::RemoteBlockchain}, +}; +use jsonrpc_pubsub::{typed::Subscriber, SubscriptionId}; use primitives::{H256, Blake2Hasher}; -use sr_primitives::generic::{BlockId, SignedBlock}; -use sr_primitives::traits::{Block as BlockT, Header, NumberFor}; -use self::error::Result; +use rpc_primitives::number; +use sr_primitives::{ + generic::{BlockId, SignedBlock}, + traits::{Block as BlockT, Header, NumberFor}, +}; + +use self::error::{Result, Error, FutureResult}; + +pub use api::chain::*; + +/// Blockchain backend API +trait ChainBackend: Send + Sync + 'static + where + Block: BlockT + 'static, + B: client::backend::Backend + Send + Sync + 'static, + E: client::CallExecutor + Send + Sync + 'static, +{ + /// Get client reference. + fn client(&self) -> &Arc>; -pub use self::gen_client::Client as ChainClient; + /// Get subscriptions reference. + fn subscriptions(&self) -> &Subscriptions; -/// Substrate blockchain API -#[rpc] -pub trait ChainApi { - /// RPC metadata - type Metadata; + /// Tries to unwrap passed block hash, or uses best block hash otherwise. + fn unwrap_or_best(&self, hash: Option) -> Block::Hash { + match hash.into() { + None => self.client().info().chain.best_hash, + Some(hash) => hash, + } + } /// Get header of a relay chain block. - #[rpc(name = "chain_getHeader")] - fn header(&self, hash: Option) -> Result>; + fn header(&self, hash: Option) -> FutureResult>; /// Get header and body of a relay chain block. - #[rpc(name = "chain_getBlock")] - fn block(&self, hash: Option) -> Result>; + fn block(&self, hash: Option) -> FutureResult>>; /// Get hash of the n-th block in the canon chain. /// /// By default returns latest block hash. - #[rpc(name = "chain_getBlockHash", alias("chain_getHead"))] - fn block_hash(&self, hash: Option>) -> Result>; + fn block_hash( + &self, + number: Option>>, + ) -> Result> { + Ok(match number { + None => Some(self.client().info().chain.best_hash), + Some(num_or_hex) => self.client() + .header(&BlockId::number(num_or_hex.to_number()?)) + .map_err(client_err)? + .map(|h| h.hash()), + }) + } /// Get hash of the last finalized block in the canon chain. - #[rpc(name = "chain_getFinalizedHead", alias("chain_getFinalisedHead"))] - fn finalized_head(&self) -> Result; + fn finalized_head(&self) -> Result { + Ok(self.client().info().chain.finalized_hash) + } /// New head subscription - #[pubsub( - subscription = "chain_newHead", - subscribe, - name = "chain_subscribeNewHead", - alias("subscribe_newHead") - )] - fn subscribe_new_head(&self, metadata: Self::Metadata, subscriber: Subscriber

); + fn subscribe_new_heads( + &self, + _metadata: crate::metadata::Metadata, + subscriber: Subscriber, + ) { + subscribe_headers( + self.client(), + self.subscriptions(), + subscriber, + || self.client().info().chain.best_hash, + || self.client().import_notification_stream() + .filter(|notification| future::ready(notification.is_new_best)) + .map(|notification| Ok::<_, ()>(notification.header)) + .compat(), + ) + } /// Unsubscribe from new head subscription. - #[pubsub( - subscription = "chain_newHead", - unsubscribe, - name = "chain_unsubscribeNewHead", - alias("unsubscribe_newHead") - )] - fn unsubscribe_new_head(&self, metadata: Option, id: SubscriptionId) -> RpcResult; + fn unsubscribe_new_heads( + &self, + _metadata: Option, + id: SubscriptionId, + ) -> RpcResult { + Ok(self.subscriptions().cancel(id)) + } /// New head subscription - #[pubsub( - subscription = "chain_finalizedHead", - subscribe, - name = "chain_subscribeFinalizedHeads", - alias("chain_subscribeFinalisedHeads") - )] - fn subscribe_finalized_heads(&self, metadata: Self::Metadata, subscriber: Subscriber
); + fn subscribe_finalized_heads( + &self, + _metadata: crate::metadata::Metadata, + subscriber: Subscriber, + ) { + subscribe_headers( + self.client(), + self.subscriptions(), + subscriber, + || self.client().info().chain.finalized_hash, + || self.client().finality_notification_stream() + .map(|notification| Ok::<_, ()>(notification.header)) + .compat(), + ) + } /// Unsubscribe from new head subscription. - #[pubsub( - subscription = "chain_finalizedHead", - unsubscribe, - name = "chain_unsubscribeFinalizedHeads", - alias("chain_unsubscribeFinalisedHeads") - )] - fn unsubscribe_finalized_heads(&self, metadata: Option, id: SubscriptionId) -> RpcResult; + fn unsubscribe_finalized_heads( + &self, + _metadata: Option, + id: SubscriptionId, + ) -> RpcResult { + Ok(self.subscriptions().cancel(id)) + } } -/// Chain API with subscriptions support. -pub struct Chain { - /// Substrate client. +/// Create new state API that works on full node. +pub fn new_full( client: Arc>, - /// Current subscriptions. subscriptions: Subscriptions, +) -> Chain + where + Block: BlockT + 'static, + B: client::backend::Backend + Send + Sync + 'static, + E: client::CallExecutor + Send + Sync + 'static + Clone, + RA: Send + Sync + 'static, +{ + Chain { + backend: Box::new(self::chain_full::FullChain::new(client, subscriptions)), + } } -impl Chain { - /// Create new Chain API RPC handler. - pub fn new(client: Arc>, subscriptions: Subscriptions) -> Self { - Self { +/// Create new state API that works on light node. +pub fn new_light>( + client: Arc>, + subscriptions: Subscriptions, + remote_blockchain: Arc>, + fetcher: Arc, +) -> Chain + where + Block: BlockT + 'static, + B: client::backend::Backend + Send + Sync + 'static, + E: client::CallExecutor + Send + Sync + 'static + Clone, + RA: Send + Sync + 'static, + F: Send + Sync + 'static, +{ + Chain { + backend: Box::new(self::chain_light::LightChain::new( client, subscriptions, - } + remote_blockchain, + fetcher, + )), } } -impl Chain where - Block: BlockT + 'static, - B: client::backend::Backend + Send + Sync + 'static, - E: client::CallExecutor + Send + Sync + 'static, - RA: Send + Sync + 'static -{ - fn unwrap_or_best(&self, hash: Option) -> Result { - Ok(match hash.into() { - None => self.client.info().chain.best_hash, - Some(hash) => hash, - }) - } - - fn subscribe_headers( - &self, - subscriber: Subscriber, - best_block_hash: G, - stream: F, - ) where - F: FnOnce() -> S, - G: FnOnce() -> Result>, - ERR: ::std::fmt::Debug, - S: Stream + Send + 'static, - { - self.subscriptions.add(subscriber, |sink| { - // send current head right at the start. - let header = best_block_hash() - .and_then(|hash| self.header(hash.into())) - .and_then(|header| { - header.ok_or_else(|| "Best header missing.".to_owned().into()) - }) - .map_err(Into::into); - - // send further subscriptions - let stream = stream() - .map(|res| Ok(res)) - .map_err(|e| warn!("Block notification stream error: {:?}", e)); - - sink - .sink_map_err(|e| warn!("Error sending notifications: {:?}", e)) - .send_all( - stream::iter_result(vec![Ok(header)]) - .chain(stream) - ) - // we ignore the resulting Stream (if the first stream is over we are unsubscribed) - .map(|_| ()) - }); - } +/// Chain API with subscriptions support. +pub struct Chain { + backend: Box>, } impl ChainApi, Block::Hash, Block::Header, SignedBlock> for Chain where @@ -176,55 +202,81 @@ impl ChainApi, Block::Hash, Block::Header, Sig { type Metadata = crate::metadata::Metadata; - fn header(&self, hash: Option) -> Result> { - let hash = self.unwrap_or_best(hash)?; - Ok(self.client.header(&BlockId::Hash(hash))?) + fn header(&self, hash: Option) -> FutureResult> { + self.backend.header(hash) } - fn block(&self, hash: Option) - -> Result>> + fn block(&self, hash: Option) -> FutureResult>> { - let hash = self.unwrap_or_best(hash)?; - Ok(self.client.block(&BlockId::Hash(hash))?) + self.backend.block(hash) } fn block_hash(&self, number: Option>>) -> Result> { - Ok(match number { - None => Some(self.client.info().chain.best_hash), - Some(num_or_hex) => self.client.header(&BlockId::number(num_or_hex.to_number()?))?.map(|h| h.hash()), - }) + self.backend.block_hash(number) } fn finalized_head(&self) -> Result { - Ok(self.client.info().chain.finalized_hash) + self.backend.finalized_head() } - fn subscribe_new_head(&self, _metadata: Self::Metadata, subscriber: Subscriber) { - self.subscribe_headers( - subscriber, - || self.block_hash(None.into()), - || self.client.import_notification_stream() - .filter(|notification| future::ready(notification.is_new_best)) - .map(|notification| Ok::<_, ()>(notification.header)) - .compat(), - ) + fn subscribe_new_heads(&self, metadata: Self::Metadata, subscriber: Subscriber) { + self.backend.subscribe_new_heads(metadata, subscriber) } - fn unsubscribe_new_head(&self, _metadata: Option, id: SubscriptionId) -> RpcResult { - Ok(self.subscriptions.cancel(id)) + fn unsubscribe_new_heads(&self, metadata: Option, id: SubscriptionId) -> RpcResult { + self.backend.unsubscribe_new_heads(metadata, id) } - fn subscribe_finalized_heads(&self, _meta: Self::Metadata, subscriber: Subscriber) { - self.subscribe_headers( - subscriber, - || Ok(Some(self.client.info().chain.finalized_hash)), - || self.client.finality_notification_stream() - .map(|notification| Ok::<_, ()>(notification.header)) - .compat(), - ) + fn subscribe_finalized_heads(&self, metadata: Self::Metadata, subscriber: Subscriber) { + self.backend.subscribe_finalized_heads(metadata, subscriber) } - fn unsubscribe_finalized_heads(&self, _metadata: Option, id: SubscriptionId) -> RpcResult { - Ok(self.subscriptions.cancel(id)) + fn unsubscribe_finalized_heads(&self, metadata: Option, id: SubscriptionId) -> RpcResult { + self.backend.unsubscribe_finalized_heads(metadata, id) } } + +/// Subscribe to new headers. +fn subscribe_headers( + client: &Arc>, + subscriptions: &Subscriptions, + subscriber: Subscriber, + best_block_hash: G, + stream: F, +) where + Block: BlockT + 'static, + B: client::backend::Backend + Send + Sync + 'static, + E: client::CallExecutor + Send + Sync + 'static, + F: FnOnce() -> S, + G: FnOnce() -> Block::Hash, + ERR: ::std::fmt::Debug, + S: Stream + Send + 'static, +{ + subscriptions.add(subscriber, |sink| { + // send current head right at the start. + let header = client.header(&BlockId::Hash(best_block_hash())) + .map_err(client_err) + .and_then(|header| { + header.ok_or_else(|| "Best header missing.".to_owned().into()) + }) + .map_err(Into::into); + + // send further subscriptions + let stream = stream() + .map(|res| Ok(res)) + .map_err(|e| warn!("Block notification stream error: {:?}", e)); + + sink + .sink_map_err(|e| warn!("Error sending notifications: {:?}", e)) + .send_all( + stream::iter_result(vec![Ok(header)]) + .chain(stream) + ) + // we ignore the resulting Stream (if the first stream is over we are unsubscribed) + .map(|_| ()) + }); +} + +fn client_err(err: client::error::Error) -> Error { + Error::Client(Box::new(err)) +} diff --git a/core/rpc/src/chain/tests.rs b/core/rpc/src/chain/tests.rs index e6fa4d94e5b0dfa96bfebc615eeb9aede6e40082..8b46befee65208b61da8ca10e350436d83ee8eec 100644 --- a/core/rpc/src/chain/tests.rs +++ b/core/rpc/src/chain/tests.rs @@ -27,13 +27,11 @@ fn should_return_header() { let core = ::tokio::runtime::Runtime::new().unwrap(); let remote = core.executor(); - let client = Chain { - client: Arc::new(test_client::new()), - subscriptions: Subscriptions::new(Arc::new(remote)), - }; + let client = Arc::new(test_client::new()); + let api = new_full(client.clone(), Subscriptions::new(Arc::new(remote))); assert_matches!( - client.header(Some(client.client.genesis_hash()).into()), + api.header(Some(client.genesis_hash()).into()).wait(), Ok(Some(ref x)) if x == &Header { parent_hash: H256::from_low_u64_be(0), number: 0, @@ -44,7 +42,7 @@ fn should_return_header() { ); assert_matches!( - client.header(None.into()), + api.header(None.into()).wait(), Ok(Some(ref x)) if x == &Header { parent_hash: H256::from_low_u64_be(0), number: 0, @@ -55,7 +53,7 @@ fn should_return_header() { ); assert_matches!( - client.header(Some(H256::from_low_u64_be(5)).into()), + api.header(Some(H256::from_low_u64_be(5)).into()).wait(), Ok(None) ); } @@ -65,26 +63,24 @@ fn should_return_a_block() { let core = ::tokio::runtime::Runtime::new().unwrap(); let remote = core.executor(); - let api = Chain { - client: Arc::new(test_client::new()), - subscriptions: Subscriptions::new(Arc::new(remote)), - }; + let client = Arc::new(test_client::new()); + let api = new_full(client.clone(), Subscriptions::new(Arc::new(remote))); - let block = api.client.new_block(Default::default()).unwrap().bake().unwrap(); + let block = client.new_block(Default::default()).unwrap().bake().unwrap(); let block_hash = block.hash(); - api.client.import(BlockOrigin::Own, block).unwrap(); + client.import(BlockOrigin::Own, block).unwrap(); // Genesis block is not justified assert_matches!( - api.block(Some(api.client.genesis_hash()).into()), + api.block(Some(client.genesis_hash()).into()).wait(), Ok(Some(SignedBlock { justification: None, .. })) ); assert_matches!( - api.block(Some(block_hash).into()), + api.block(Some(block_hash).into()).wait(), Ok(Some(ref x)) if x.block == Block { header: Header { - parent_hash: api.client.genesis_hash(), + parent_hash: client.genesis_hash(), number: 1, state_root: x.block.header.state_root.clone(), extrinsics_root: "03170a2e7597b7b7e3d84c05391d139a62b157e78786d8c082f29dcf4c111314".parse().unwrap(), @@ -95,10 +91,10 @@ fn should_return_a_block() { ); assert_matches!( - api.block(None.into()), + api.block(None.into()).wait(), Ok(Some(ref x)) if x.block == Block { header: Header { - parent_hash: api.client.genesis_hash(), + parent_hash: client.genesis_hash(), number: 1, state_root: x.block.header.state_root.clone(), extrinsics_root: "03170a2e7597b7b7e3d84c05391d139a62b157e78786d8c082f29dcf4c111314".parse().unwrap(), @@ -109,7 +105,7 @@ fn should_return_a_block() { ); assert_matches!( - api.block(Some(H256::from_low_u64_be(5)).into()), + api.block(Some(H256::from_low_u64_be(5)).into()).wait(), Ok(None) ); } @@ -119,40 +115,38 @@ fn should_return_block_hash() { let core = ::tokio::runtime::Runtime::new().unwrap(); let remote = core.executor(); - let client = Chain { - client: Arc::new(test_client::new()), - subscriptions: Subscriptions::new(Arc::new(remote)), - }; + let client = Arc::new(test_client::new()); + let api = new_full(client.clone(), Subscriptions::new(Arc::new(remote))); assert_matches!( - client.block_hash(None.into()), - Ok(Some(ref x)) if x == &client.client.genesis_hash() + api.block_hash(None.into()), + Ok(Some(ref x)) if x == &client.genesis_hash() ); assert_matches!( - client.block_hash(Some(0u64.into()).into()), - Ok(Some(ref x)) if x == &client.client.genesis_hash() + api.block_hash(Some(0u64.into()).into()), + Ok(Some(ref x)) if x == &client.genesis_hash() ); assert_matches!( - client.block_hash(Some(1u64.into()).into()), + api.block_hash(Some(1u64.into()).into()), Ok(None) ); - let block = client.client.new_block(Default::default()).unwrap().bake().unwrap(); - client.client.import(BlockOrigin::Own, block.clone()).unwrap(); + let block = client.new_block(Default::default()).unwrap().bake().unwrap(); + client.import(BlockOrigin::Own, block.clone()).unwrap(); assert_matches!( - client.block_hash(Some(0u64.into()).into()), - Ok(Some(ref x)) if x == &client.client.genesis_hash() + api.block_hash(Some(0u64.into()).into()), + Ok(Some(ref x)) if x == &client.genesis_hash() ); assert_matches!( - client.block_hash(Some(1u64.into()).into()), + api.block_hash(Some(1u64.into()).into()), Ok(Some(ref x)) if x == &block.hash() ); assert_matches!( - client.block_hash(Some(::primitives::U256::from(1u64).into()).into()), + api.block_hash(Some(::primitives::U256::from(1u64).into()).into()), Ok(Some(ref x)) if x == &block.hash() ); } @@ -163,30 +157,28 @@ fn should_return_finalized_hash() { let core = ::tokio::runtime::Runtime::new().unwrap(); let remote = core.executor(); - let client = Chain { - client: Arc::new(test_client::new()), - subscriptions: Subscriptions::new(Arc::new(remote)), - }; + let client = Arc::new(test_client::new()); + let api = new_full(client.clone(), Subscriptions::new(Arc::new(remote))); assert_matches!( - client.finalized_head(), - Ok(ref x) if x == &client.client.genesis_hash() + api.finalized_head(), + Ok(ref x) if x == &client.genesis_hash() ); // import new block - let builder = client.client.new_block(Default::default()).unwrap(); - client.client.import(BlockOrigin::Own, builder.bake().unwrap()).unwrap(); + let builder = client.new_block(Default::default()).unwrap(); + client.import(BlockOrigin::Own, builder.bake().unwrap()).unwrap(); // no finalization yet assert_matches!( - client.finalized_head(), - Ok(ref x) if x == &client.client.genesis_hash() + api.finalized_head(), + Ok(ref x) if x == &client.genesis_hash() ); // finalize - client.client.finalize_block(BlockId::number(1), None, true).unwrap(); + client.finalize_block(BlockId::number(1), None).unwrap(); assert_matches!( - client.finalized_head(), - Ok(ref x) if x == &client.client.block_hash(1).unwrap().unwrap() + api.finalized_head(), + Ok(ref x) if x == &client.block_hash(1).unwrap().unwrap() ); } @@ -197,18 +189,16 @@ fn should_notify_about_latest_block() { let (subscriber, id, transport) = Subscriber::new_test("test"); { - let api = Chain { - client: Arc::new(test_client::new()), - subscriptions: Subscriptions::new(Arc::new(remote)), - }; + let client = Arc::new(test_client::new()); + let api = new_full(client.clone(), Subscriptions::new(Arc::new(remote))); - api.subscribe_new_head(Default::default(), subscriber); + api.subscribe_new_heads(Default::default(), subscriber); // assert id assigned assert_eq!(core.block_on(id), Ok(Ok(SubscriptionId::Number(1)))); - let builder = api.client.new_block(Default::default()).unwrap(); - api.client.import(BlockOrigin::Own, builder.bake().unwrap()).unwrap(); + let builder = client.new_block(Default::default()).unwrap(); + client.import(BlockOrigin::Own, builder.bake().unwrap()).unwrap(); } // assert initial head sent. @@ -228,19 +218,17 @@ fn should_notify_about_finalized_block() { let (subscriber, id, transport) = Subscriber::new_test("test"); { - let api = Chain { - client: Arc::new(test_client::new()), - subscriptions: Subscriptions::new(Arc::new(remote)), - }; + let client = Arc::new(test_client::new()); + let api = new_full(client.clone(), Subscriptions::new(Arc::new(remote))); api.subscribe_finalized_heads(Default::default(), subscriber); // assert id assigned assert_eq!(core.block_on(id), Ok(Ok(SubscriptionId::Number(1)))); - let builder = api.client.new_block(Default::default()).unwrap(); - api.client.import(BlockOrigin::Own, builder.bake().unwrap()).unwrap(); - api.client.finalize_block(BlockId::number(1), None, true).unwrap(); + let builder = client.new_block(Default::default()).unwrap(); + client.import(BlockOrigin::Own, builder.bake().unwrap()).unwrap(); + client.finalize_block(BlockId::number(1), None).unwrap(); } // assert initial head sent. diff --git a/core/rpc/src/helpers.rs b/core/rpc/src/helpers.rs index 2c69ead76caae134688da85c6a86e1551a3c7622..e579c743acdad202caedfd39e760559129c6109f 100644 --- a/core/rpc/src/helpers.rs +++ b/core/rpc/src/helpers.rs @@ -14,22 +14,6 @@ // You should have received a copy of the GNU General Public License // along with Substrate. If not, see . -use futures::prelude::*; -use futures03::{channel::oneshot, compat::Compat}; - -/// Wraps around `oneshot::Receiver` and adjusts the error type to produce an internal error if the -/// sender gets dropped. -pub struct Receiver(pub Compat>); - -impl Future for Receiver { - type Item = T; - type Error = jsonrpc_core::Error; - - fn poll(&mut self) -> Poll { - self.0.poll().map_err(|_| jsonrpc_core::Error::internal_error()) - } -} - /// Unwraps the trailing parameter or falls back with the closure result. pub fn unwrap_or_else(or_else: F, optional: Option) -> Result where F: FnOnce() -> Result, diff --git a/core/rpc/src/lib.rs b/core/rpc/src/lib.rs index 6488ea5f49c54120f5a77dbd1c23e8e16004b3d9..9ce9f82fdad2c3413247017378529d0313d3073e 100644 --- a/core/rpc/src/lib.rs +++ b/core/rpc/src/lib.rs @@ -14,20 +14,20 @@ // You should have received a copy of the GNU General Public License // along with Substrate. If not, see . -//! Substrate RPC interfaces. +//! Substrate RPC implementation. +//! +//! A core implementation of Substrate RPC interfaces. #![warn(missing_docs)] -mod errors; mod helpers; -mod subscriptions; +mod metadata; -pub use subscriptions::Subscriptions; +pub use api::Subscriptions; +pub use self::metadata::Metadata; +pub use rpc::IoHandlerExtension as RpcExtension; pub mod author; pub mod chain; -pub mod metadata; pub mod state; pub mod system; - -use jsonrpc_core as rpc; diff --git a/core/rpc/src/metadata.rs b/core/rpc/src/metadata.rs index e6af4ef94bc1adf6fee90eb520630da09ed18942..73bf583765b206ef3f1ecdcea51b5c977b26cd02 100644 --- a/core/rpc/src/metadata.rs +++ b/core/rpc/src/metadata.rs @@ -18,7 +18,7 @@ use std::sync::Arc; use jsonrpc_pubsub::{Session, PubSubMetadata}; -use crate::rpc::futures::sync::mpsc; +use rpc::futures::sync::mpsc; /// RPC Metadata. /// @@ -30,7 +30,7 @@ pub struct Metadata { session: Option>, } -impl crate::rpc::Metadata for Metadata {} +impl rpc::Metadata for Metadata {} impl PubSubMetadata for Metadata { fn session(&self) -> Option> { self.session.clone() @@ -52,3 +52,9 @@ impl Metadata { (rx, Self::new(tx)) } } + +impl From> for Metadata { + fn from(sender: mpsc::Sender) -> Self { + Self::new(sender) + } +} diff --git a/core/rpc/src/state/mod.rs b/core/rpc/src/state/mod.rs index 0044ad77b8000a4f14e7b1fa45807c0c8096560c..b922601b0a5b213999e49bc2cc76c64e7714b93d 100644 --- a/core/rpc/src/state/mod.rs +++ b/core/rpc/src/state/mod.rs @@ -16,374 +16,245 @@ //! Substrate state API. -pub mod error; +mod state_full; +mod state_light; #[cfg(test)] mod tests; -use std::{ - collections::{BTreeMap, HashMap}, - ops::Range, - sync::Arc, +use std::sync::Arc; +use jsonrpc_pubsub::{typed::Subscriber, SubscriptionId}; +use rpc::{ + Result as RpcResult, + futures::Future, }; -use futures03::{future, StreamExt as _, TryStreamExt as _}; -use client::{self, Client, CallExecutor, BlockchainEvents, runtime_api::Metadata}; -use crate::rpc::Result as RpcResult; -use crate::rpc::futures::{stream, Future, Sink, Stream}; -use crate::subscriptions::Subscriptions; -use jsonrpc_derive::rpc; -use jsonrpc_pubsub::{typed::Subscriber, SubscriptionId}; -use log::{warn, trace}; -use primitives::hexdisplay::HexDisplay; -use primitives::storage::{self, StorageKey, StorageData, StorageChangeSet}; -use primitives::{H256, Blake2Hasher, Bytes}; -use sr_primitives::generic::BlockId; -use sr_primitives::traits::{ - Block as BlockT, Header, ProvideRuntimeApi, NumberFor, - SaturatedConversion +use api::Subscriptions; +use client::{ + Client, CallExecutor, + runtime_api::Metadata, + light::{blockchain::RemoteBlockchain, fetcher::Fetcher}, +}; +use primitives::{ + Blake2Hasher, Bytes, H256, + storage::{StorageKey, StorageData, StorageChangeSet}, }; use runtime_version::RuntimeVersion; -use self::error::Result; -use state_machine::{self, ExecutionStrategy}; +use sr_primitives::{ + traits::{Block as BlockT, ProvideRuntimeApi}, +}; -pub use self::gen_client::Client as StateClient; +use self::error::{Error, FutureResult}; -/// Substrate state API -#[rpc] -pub trait StateApi { - /// RPC Metadata - type Metadata; +pub use api::state::*; - /// Call a contract at a block's state. - #[rpc(name = "state_call", alias("state_callAt"))] - fn call(&self, name: String, bytes: Bytes, hash: Option) -> Result; +/// State backend API. +pub trait StateBackend: Send + Sync + 'static + where + Block: BlockT + 'static, + B: client::backend::Backend + Send + Sync + 'static, + E: client::CallExecutor + Send + Sync + 'static, + RA: Send + Sync + 'static, +{ + /// Call runtime method at given block. + fn call( + &self, + block: Option, + method: String, + call_data: Bytes, + ) -> FutureResult; - /// Returns the keys with prefix, leave empty to get all the keys - #[rpc(name = "state_getKeys")] - fn storage_keys(&self, prefix: StorageKey, hash: Option) -> Result>; + /// Returns the keys with prefix, leave empty to get all the keys. + fn storage_keys( + &self, + block: Option, + prefix: StorageKey, + ) -> FutureResult>; /// Returns a storage entry at a specific block's state. - #[rpc(name = "state_getStorage", alias("state_getStorageAt"))] - fn storage(&self, key: StorageKey, hash: Option) -> Result>; + fn storage( + &self, + block: Option, + key: StorageKey, + ) -> FutureResult>; /// Returns the hash of a storage entry at a block's state. - #[rpc(name = "state_getStorageHash", alias("state_getStorageHashAt"))] - fn storage_hash(&self, key: StorageKey, hash: Option) -> Result>; + fn storage_hash( + &self, + block: Option, + key: StorageKey, + ) -> FutureResult>; /// Returns the size of a storage entry at a block's state. - #[rpc(name = "state_getStorageSize", alias("state_getStorageSizeAt"))] - fn storage_size(&self, key: StorageKey, hash: Option) -> Result>; + fn storage_size( + &self, + block: Option, + key: StorageKey, + ) -> FutureResult> { + Box::new(self.storage(block, key) + .map(|x| x.map(|x| x.0.len() as u64))) + } /// Returns the keys with prefix from a child storage, leave empty to get all the keys - #[rpc(name = "state_getChildKeys")] fn child_storage_keys( &self, + block: Option, child_storage_key: StorageKey, prefix: StorageKey, - hash: Option - ) -> Result>; + ) -> FutureResult>; /// Returns a child storage entry at a specific block's state. - #[rpc(name = "state_getChildStorage")] fn child_storage( &self, + block: Option, child_storage_key: StorageKey, key: StorageKey, - hash: Option - ) -> Result>; + ) -> FutureResult>; /// Returns the hash of a child storage entry at a block's state. - #[rpc(name = "state_getChildStorageHash")] fn child_storage_hash( &self, + block: Option, child_storage_key: StorageKey, key: StorageKey, - hash: Option - ) -> Result>; + ) -> FutureResult>; /// Returns the size of a child storage entry at a block's state. - #[rpc(name = "state_getChildStorageSize")] fn child_storage_size( &self, + block: Option, child_storage_key: StorageKey, key: StorageKey, - hash: Option - ) -> Result>; + ) -> FutureResult> { + Box::new(self.child_storage(block, child_storage_key, key) + .map(|x| x.map(|x| x.0.len() as u64))) + } /// Returns the runtime metadata as an opaque blob. - #[rpc(name = "state_getMetadata")] - fn metadata(&self, hash: Option) -> Result; + fn metadata(&self, block: Option) -> FutureResult; /// Get the runtime version. - #[rpc(name = "state_getRuntimeVersion", alias("chain_getRuntimeVersion"))] - fn runtime_version(&self, hash: Option) -> Result; + fn runtime_version(&self, block: Option) -> FutureResult; /// Query historical storage entries (by key) starting from a block given as the second parameter. /// /// NOTE This first returned result contains the initial state of storage for all keys. /// Subsequent values in the vector represent changes to the previous state (diffs). - #[rpc(name = "state_queryStorage")] fn query_storage( &self, + from: Block::Hash, + to: Option, keys: Vec, - block: Hash, - hash: Option - ) -> Result>>; + ) -> FutureResult>>; /// New runtime version subscription - #[pubsub( - subscription = "state_runtimeVersion", - subscribe, - name = "state_subscribeRuntimeVersion", - alias("chain_subscribeRuntimeVersion") - )] - fn subscribe_runtime_version(&self, metadata: Self::Metadata, subscriber: Subscriber); + fn subscribe_runtime_version( + &self, + _meta: crate::metadata::Metadata, + subscriber: Subscriber, + ); /// Unsubscribe from runtime version subscription - #[pubsub( - subscription = "state_runtimeVersion", - unsubscribe, - name = "state_unsubscribeRuntimeVersion", - alias("chain_unsubscribeRuntimeVersion") - )] - fn unsubscribe_runtime_version(&self, metadata: Option, id: SubscriptionId) -> RpcResult; + fn unsubscribe_runtime_version( + &self, + _meta: Option, + id: SubscriptionId, + ) -> RpcResult; /// New storage subscription - #[pubsub(subscription = "state_storage", subscribe, name = "state_subscribeStorage")] fn subscribe_storage( - &self, metadata: Self::Metadata, subscriber: Subscriber>, keys: Option> + &self, + _meta: crate::metadata::Metadata, + subscriber: Subscriber>, + keys: Option>, ); /// Unsubscribe from storage subscription - #[pubsub(subscription = "state_storage", unsubscribe, name = "state_unsubscribeStorage")] fn unsubscribe_storage( - &self, metadata: Option, id: SubscriptionId + &self, + _meta: Option, + id: SubscriptionId, ) -> RpcResult; } -/// State API with subscriptions support. -pub struct State { - /// Substrate client. +/// Create new state API that works on full node. +pub fn new_full( client: Arc>, - /// Current subscriptions. subscriptions: Subscriptions, +) -> State + where + Block: BlockT + 'static, + B: client::backend::Backend + Send + Sync + 'static, + E: CallExecutor + Send + Sync + 'static + Clone, + RA: Send + Sync + 'static, + Client: ProvideRuntimeApi, + as ProvideRuntimeApi>::Api: Metadata, +{ + State { + backend: Box::new(self::state_full::FullState::new(client, subscriptions)), + } } -/// Ranges to query in state_queryStorage. -struct QueryStorageRange { - /// Hashes of all the blocks in the range. - pub hashes: Vec, - /// Number of the first block in the range. - pub first_number: NumberFor, - /// Blocks subrange ([begin; end) indices within `hashes`) where we should read keys at - /// each state to get changes. - pub unfiltered_range: Range, - /// Blocks subrange ([begin; end) indices within `hashes`) where we could pre-filter - /// blocks-with-changes by using changes tries. - pub filtered_range: Option>, -} - -impl State where - Block: BlockT, - B: client::backend::Backend, - E: CallExecutor, +/// Create new state API that works on light node. +pub fn new_light>( + client: Arc>, + subscriptions: Subscriptions, + remote_blockchain: Arc>, + fetcher: Arc, +) -> State + where + Block: BlockT + 'static, + B: client::backend::Backend + Send + Sync + 'static, + E: CallExecutor + Send + Sync + 'static + Clone, + RA: Send + Sync + 'static, + F: Send + Sync + 'static, { - /// Create new State API RPC handler. - pub fn new(client: Arc>, subscriptions: Subscriptions) -> Self { - Self { + State { + backend: Box::new(self::state_light::LightState::new( client, subscriptions, - } - } - - /// Splits the `query_storage` block range into 'filtered' and 'unfiltered' subranges. - /// Blocks that contain changes within filtered subrange could be filtered using changes tries. - /// Blocks that contain changes within unfiltered subrange must be filtered manually. - fn split_query_storage_range( - &self, - from: Block::Hash, - to: Option - ) -> Result> { - let to = self.unwrap_or_best(to)?; - let from_hdr = self.client.header(&BlockId::hash(from))?; - let to_hdr = self.client.header(&BlockId::hash(to))?; - match (from_hdr, to_hdr) { - (Some(ref from), Some(ref to)) if from.number() <= to.number() => { - // check if we can get from `to` to `from` by going through parent_hashes. - let from_number = *from.number(); - let blocks = { - let mut blocks = vec![to.hash()]; - let mut last = to.clone(); - while *last.number() > from_number { - if let Some(hdr) = self.client.header(&BlockId::hash(*last.parent_hash()))? { - blocks.push(hdr.hash()); - last = hdr; - } else { - return Err(invalid_block_range( - Some(from), - Some(to), - format!("Parent of {} ({}) not found", last.number(), last.hash()), - )) - } - } - if last.hash() != from.hash() { - return Err(invalid_block_range( - Some(from), - Some(to), - format!("Expected to reach `from`, got {} ({})", last.number(), last.hash()), - )) - } - blocks.reverse(); - blocks - }; - // check if we can filter blocks-with-changes from some (sub)range using changes tries - let changes_trie_range = self.client.max_key_changes_range(from_number, BlockId::Hash(to.hash()))?; - let filtered_range_begin = changes_trie_range.map(|(begin, _)| (begin - from_number).saturated_into::()); - let (unfiltered_range, filtered_range) = split_range(blocks.len(), filtered_range_begin); - Ok(QueryStorageRange { - hashes: blocks, - first_number: from_number, - unfiltered_range, - filtered_range, - }) - }, - (from, to) => Err( - invalid_block_range(from.as_ref(), to.as_ref(), "Invalid range or unknown block".into()) - ), - } - } - - /// Iterates through range.unfiltered_range and check each block for changes of keys' values. - fn query_storage_unfiltered( - &self, - range: &QueryStorageRange, - keys: &[StorageKey], - last_values: &mut HashMap>, - changes: &mut Vec>, - ) -> Result<()> { - for block in range.unfiltered_range.start..range.unfiltered_range.end { - let block_hash = range.hashes[block].clone(); - let mut block_changes = StorageChangeSet { block: block_hash.clone(), changes: Vec::new() }; - let id = BlockId::hash(block_hash); - for key in keys { - let (has_changed, data) = { - let curr_data = self.client.storage(&id, key)?; - match last_values.get(key) { - Some(prev_data) => (curr_data != *prev_data, curr_data), - None => (true, curr_data), - } - }; - if has_changed { - block_changes.changes.push((key.clone(), data.clone())); - } - last_values.insert(key.clone(), data); - } - if !block_changes.changes.is_empty() { - changes.push(block_changes); - } - } - Ok(()) - } - - /// Iterates through all blocks that are changing keys within range.filtered_range and collects these changes. - fn query_storage_filtered( - &self, - range: &QueryStorageRange, - keys: &[StorageKey], - last_values: &HashMap>, - changes: &mut Vec>, - ) -> Result<()> { - let (begin, end) = match range.filtered_range { - Some(ref filtered_range) => ( - range.first_number + filtered_range.start.saturated_into(), - BlockId::Hash(range.hashes[filtered_range.end - 1].clone()) - ), - None => return Ok(()), - }; - let mut changes_map: BTreeMap, StorageChangeSet> = BTreeMap::new(); - for key in keys { - let mut last_block = None; - let mut last_value = last_values.get(key).cloned().unwrap_or_default(); - for (block, _) in self.client.key_changes(begin, end, key)?.into_iter().rev() { - if last_block == Some(block) { - continue; - } - - let block_hash = range.hashes[(block - range.first_number).saturated_into::()].clone(); - let id = BlockId::Hash(block_hash); - let value_at_block = self.client.storage(&id, key)?; - if last_value == value_at_block { - continue; - } - - changes_map.entry(block) - .or_insert_with(|| StorageChangeSet { block: block_hash, changes: Vec::new() }) - .changes.push((key.clone(), value_at_block.clone())); - last_block = Some(block); - last_value = value_at_block; - } - } - if let Some(additional_capacity) = changes_map.len().checked_sub(changes.len()) { - changes.reserve(additional_capacity); - } - changes.extend(changes_map.into_iter().map(|(_, cs)| cs)); - Ok(()) + remote_blockchain, + fetcher, + )), } } -impl State where - Block: BlockT, - B: client::backend::Backend, - E: CallExecutor, -{ - fn unwrap_or_best(&self, hash: Option) -> Result { - crate::helpers::unwrap_or_else(|| Ok(self.client.info().chain.best_hash), hash) - } +/// State API with subscriptions support. +pub struct State { + backend: Box>, } -impl StateApi for State where - Block: BlockT + 'static, - B: client::backend::Backend + Send + Sync + 'static, - E: CallExecutor + Send + Sync + 'static + Clone, - RA: Send + Sync + 'static, - Client: ProvideRuntimeApi, - as ProvideRuntimeApi>::Api: Metadata +impl StateApi for State + where + Block: BlockT + 'static, + B: client::backend::Backend + Send + Sync + 'static, + E: CallExecutor + Send + Sync + 'static + Clone, + RA: Send + Sync + 'static, { type Metadata = crate::metadata::Metadata; - fn call(&self, method: String, data: Bytes, block: Option) -> Result { - let block = self.unwrap_or_best(block)?; - trace!(target: "rpc", "Calling runtime at {:?} for method {} ({})", block, method, HexDisplay::from(&data.0)); - let return_data = self.client - .executor() - .call( - &BlockId::Hash(block), - &method, &data.0, ExecutionStrategy::NativeElseWasm, state_machine::NeverOffchainExt::new(), - )?; - Ok(Bytes(return_data)) + fn call(&self, method: String, data: Bytes, block: Option) -> FutureResult { + self.backend.call(block, method, data) } - fn storage_keys(&self, key_prefix: StorageKey, block: Option) -> Result> { - let block = self.unwrap_or_best(block)?; - trace!(target: "rpc", "Querying storage keys at {:?}", block); - Ok(self.client.storage_keys(&BlockId::Hash(block), &key_prefix)?) + fn storage_keys( + &self, + key_prefix: StorageKey, + block: Option, + ) -> FutureResult> { + self.backend.storage_keys(block, key_prefix) } - fn storage(&self, key: StorageKey, block: Option) -> Result> { - let block = self.unwrap_or_best(block)?; - trace!(target: "rpc", "Querying storage at {:?} for key {}", block, HexDisplay::from(&key.0)); - Ok(self.client.storage(&BlockId::Hash(block), &key)?) + fn storage(&self, key: StorageKey, block: Option) -> FutureResult> { + self.backend.storage(block, key) } - fn storage_hash(&self, key: StorageKey, block: Option) -> Result> { - let block = self.unwrap_or_best(block)?; - trace!(target: "rpc", "Querying storage hash at {:?} for key {}", block, HexDisplay::from(&key.0)); - Ok(self.client.storage_hash(&BlockId::Hash(block), &key)?) + fn storage_hash(&self, key: StorageKey, block: Option) -> FutureResult> { + self.backend.storage_hash(block, key) } - fn storage_size(&self, key: StorageKey, block: Option) -> Result> { - Ok(self.storage(key, block)?.map(|x| x.0.len() as u64)) + fn storage_size(&self, key: StorageKey, block: Option) -> FutureResult> { + self.backend.storage_size(block, key) } fn child_storage( @@ -391,10 +262,8 @@ impl StateApi for State where child_storage_key: StorageKey, key: StorageKey, block: Option - ) -> Result> { - let block = self.unwrap_or_best(block)?; - trace!(target: "rpc", "Querying child storage at {:?} for key {}", block, HexDisplay::from(&key.0)); - Ok(self.client.child_storage(&BlockId::Hash(block), &child_storage_key, &key)?) + ) -> FutureResult> { + self.backend.child_storage(block, child_storage_key, key) } fn child_storage_keys( @@ -402,10 +271,8 @@ impl StateApi for State where child_storage_key: StorageKey, key_prefix: StorageKey, block: Option - ) -> Result> { - let block = self.unwrap_or_best(block)?; - trace!(target: "rpc", "Querying child storage keys at {:?}", block); - Ok(self.client.child_storage_keys(&BlockId::Hash(block), &child_storage_key, &key_prefix)?) + ) -> FutureResult> { + self.backend.child_storage_keys(block, child_storage_key, key_prefix) } fn child_storage_hash( @@ -413,14 +280,8 @@ impl StateApi for State where child_storage_key: StorageKey, key: StorageKey, block: Option - ) -> Result> { - let block = self.unwrap_or_best(block)?; - trace!( - target: "rpc", "Querying child storage hash at {:?} for key {}", - block, - HexDisplay::from(&key.0), - ); - Ok(self.client.child_storage_hash(&BlockId::Hash(block), &child_storage_key, &key)?) + ) -> FutureResult> { + self.backend.child_storage_hash(block, child_storage_key, key) } fn child_storage_size( @@ -428,13 +289,12 @@ impl StateApi for State where child_storage_key: StorageKey, key: StorageKey, block: Option - ) -> Result> { - Ok(self.child_storage(child_storage_key, key, block)?.map(|x| x.0.len() as u64)) + ) -> FutureResult> { + self.backend.child_storage_size(block, child_storage_key, key) } - fn metadata(&self, block: Option) -> Result { - let block = self.unwrap_or_best(block)?; - self.client.runtime_api().metadata(&BlockId::Hash(block)).map(Into::into).map_err(Into::into) + fn metadata(&self, block: Option) -> FutureResult { + self.backend.metadata(block) } fn query_storage( @@ -442,156 +302,40 @@ impl StateApi for State where keys: Vec, from: Block::Hash, to: Option - ) -> Result>> { - let range = self.split_query_storage_range(from, to)?; - let mut changes = Vec::new(); - let mut last_values = HashMap::new(); - self.query_storage_unfiltered(&range, &keys, &mut last_values, &mut changes)?; - self.query_storage_filtered(&range, &keys, &last_values, &mut changes)?; - Ok(changes) + ) -> FutureResult>> { + self.backend.query_storage(from, to, keys) } fn subscribe_storage( &self, - _meta: Self::Metadata, + meta: Self::Metadata, subscriber: Subscriber>, keys: Option> ) { - let keys = Into::>>::into(keys); - let stream = match self.client.storage_changes_notification_stream( - keys.as_ref().map(|x| &**x), - None - ) { - Ok(stream) => stream, - Err(err) => { - let _ = subscriber.reject(error::Error::from(err).into()); - return; - }, - }; - - // initial values - let initial = stream::iter_result(keys - .map(|keys| { - let block = self.client.info().chain.best_hash; - let changes = keys - .into_iter() - .map(|key| self.storage(key.clone(), Some(block.clone()).into()) - .map(|val| (key.clone(), val)) - .unwrap_or_else(|_| (key, None)) - ) - .collect(); - vec![Ok(Ok(StorageChangeSet { block, changes }))] - }).unwrap_or_default()); - - self.subscriptions.add(subscriber, |sink| { - let stream = stream - .map(|(block, changes)| Ok::<_, ()>(Ok(StorageChangeSet { - block, - changes: changes.iter() - .filter_map(|(o_sk, k, v)| if o_sk.is_none() { - Some((k.clone(),v.cloned())) - } else { None }).collect(), - }))) - .compat(); - - sink - .sink_map_err(|e| warn!("Error sending notifications: {:?}", e)) - .send_all(initial.chain(stream)) - // we ignore the resulting Stream (if the first stream is over we are unsubscribed) - .map(|_| ()) - }) + self.backend.subscribe_storage(meta, subscriber, keys); } - fn unsubscribe_storage(&self, _meta: Option, id: SubscriptionId) -> RpcResult { - Ok(self.subscriptions.cancel(id)) + fn unsubscribe_storage(&self, meta: Option, id: SubscriptionId) -> RpcResult { + self.backend.unsubscribe_storage(meta, id) } - fn runtime_version(&self, at: Option) -> Result { - let at = self.unwrap_or_best(at)?; - Ok(self.client.runtime_version_at(&BlockId::Hash(at))?) + fn runtime_version(&self, at: Option) -> FutureResult { + self.backend.runtime_version(at) } - fn subscribe_runtime_version(&self, _meta: Self::Metadata, subscriber: Subscriber) { - let stream = match self.client.storage_changes_notification_stream( - Some(&[StorageKey(storage::well_known_keys::CODE.to_vec())]), - None, - ) { - Ok(stream) => stream, - Err(err) => { - let _ = subscriber.reject(error::Error::from(err).into()); - return; - } - }; - - self.subscriptions.add(subscriber, |sink| { - let version = self.runtime_version(None.into()) - .map_err(Into::into); - - let client = self.client.clone(); - let mut previous_version = version.clone(); - - let stream = stream - .filter_map(move |_| { - let info = client.info(); - let version = client - .runtime_version_at(&BlockId::hash(info.chain.best_hash)) - .map_err(error::Error::from) - .map_err(Into::into); - if previous_version != version { - previous_version = version.clone(); - future::ready(Some(Ok::<_, ()>(version))) - } else { - future::ready(None) - } - }) - .compat(); - - sink - .sink_map_err(|e| warn!("Error sending notifications: {:?}", e)) - .send_all( - stream::iter_result(vec![Ok(version)]) - .chain(stream) - ) - // we ignore the resulting Stream (if the first stream is over we are unsubscribed) - .map(|_| ()) - }); + fn subscribe_runtime_version(&self, meta: Self::Metadata, subscriber: Subscriber) { + self.backend.subscribe_runtime_version(meta, subscriber); } - fn unsubscribe_runtime_version(&self, _meta: Option, id: SubscriptionId) -> RpcResult { - Ok(self.subscriptions.cancel(id)) + fn unsubscribe_runtime_version( + &self, + meta: Option, + id: SubscriptionId, + ) -> RpcResult { + self.backend.unsubscribe_runtime_version(meta, id) } } -/// Splits passed range into two subranges where: -/// - first range has at least one element in it; -/// - second range (optionally) starts at given `middle` element. -pub(crate) fn split_range(size: usize, middle: Option) -> (Range, Option>) { - // check if we can filter blocks-with-changes from some (sub)range using changes tries - let range2_begin = match middle { - // some of required changes tries are pruned => use available tries - Some(middle) if middle != 0 => Some(middle), - // all required changes tries are available, but we still want values at first block - // => do 'unfiltered' read for the first block and 'filtered' for the rest - Some(_) if size > 1 => Some(1), - // range contains single element => do not use changes tries - Some(_) => None, - // changes tries are not available => do 'unfiltered' read for the whole range - None => None, - }; - let range1 = 0..range2_begin.unwrap_or(size); - let range2 = range2_begin.map(|begin| begin..size); - (range1, range2) -} - -fn invalid_block_range(from: Option<&H>, to: Option<&H>, reason: String) -> error::Error { - let to_string = |x: Option<&H>| match x { - None => "unknown hash".into(), - Some(h) => format!("{} ({})", h.number(), h.hash()), - }; - - error::Error::InvalidBlockRange { - from: to_string(from), - to: to_string(to), - details: reason, - } +fn client_err(err: client::error::Error) -> Error { + Error::Client(Box::new(err)) } diff --git a/core/rpc/src/state/state_full.rs b/core/rpc/src/state/state_full.rs new file mode 100644 index 0000000000000000000000000000000000000000..6f0472163f29dfac47ce5868ddebf5b3b671835b --- /dev/null +++ b/core/rpc/src/state/state_full.rs @@ -0,0 +1,507 @@ +// Copyright 2019 Parity Technologies (UK) Ltd. +// This file is part of Substrate. + +// Substrate 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. + +// Substrate 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 Substrate. If not, see . + +//! State API backend for full nodes. + +use std::collections::{BTreeMap, HashMap}; +use std::sync::Arc; +use std::ops::Range; +use futures03::{future, StreamExt as _, TryStreamExt as _}; +use log::warn; +use jsonrpc_pubsub::{typed::Subscriber, SubscriptionId}; +use rpc::{ + Result as RpcResult, + futures::{stream, Future, Sink, Stream, future::result}, +}; + +use api::Subscriptions; +use client::{ + Client, CallExecutor, BlockchainEvents, runtime_api::Metadata, + backend::Backend, error::Result as ClientResult, +}; +use primitives::{ + H256, Blake2Hasher, Bytes, offchain::NeverOffchainExt, + storage::{well_known_keys, StorageKey, StorageData, StorageChangeSet}, +}; +use runtime_version::RuntimeVersion; +use state_machine::ExecutionStrategy; +use sr_primitives::{ + generic::BlockId, + traits::{Block as BlockT, Header, NumberFor, ProvideRuntimeApi, SaturatedConversion}, +}; + +use super::{StateBackend, error::{FutureResult, Error, Result}, client_err}; + +/// Ranges to query in state_queryStorage. +struct QueryStorageRange { + /// Hashes of all the blocks in the range. + pub hashes: Vec, + /// Number of the first block in the range. + pub first_number: NumberFor, + /// Blocks subrange ([begin; end) indices within `hashes`) where we should read keys at + /// each state to get changes. + pub unfiltered_range: Range, + /// Blocks subrange ([begin; end) indices within `hashes`) where we could pre-filter + /// blocks-with-changes by using changes tries. + pub filtered_range: Option>, +} + +/// State API backend for full nodes. +pub struct FullState { + client: Arc>, + subscriptions: Subscriptions, +} + +impl FullState + where + Block: BlockT + 'static, + B: Backend + Send + Sync + 'static, + E: CallExecutor + Send + Sync + 'static + Clone, +{ + /// Create new state API backend for full nodes. + pub fn new(client: Arc>, subscriptions: Subscriptions) -> Self { + Self { client, subscriptions } + } + + /// Returns given block hash or best block hash if None is passed. + fn block_or_best(&self, hash: Option) -> ClientResult { + crate::helpers::unwrap_or_else(|| Ok(self.client.info().chain.best_hash), hash) + } + + /// Splits the `query_storage` block range into 'filtered' and 'unfiltered' subranges. + /// Blocks that contain changes within filtered subrange could be filtered using changes tries. + /// Blocks that contain changes within unfiltered subrange must be filtered manually. + fn split_query_storage_range( + &self, + from: Block::Hash, + to: Option + ) -> Result> { + let to = self.block_or_best(to).map_err(client_err)?; + let from_hdr = self.client.header(&BlockId::hash(from)).map_err(client_err)?; + let to_hdr = self.client.header(&BlockId::hash(to)).map_err(client_err)?; + match (from_hdr, to_hdr) { + (Some(ref from), Some(ref to)) if from.number() <= to.number() => { + // check if we can get from `to` to `from` by going through parent_hashes. + let from_number = *from.number(); + let blocks = { + let mut blocks = vec![to.hash()]; + let mut last = to.clone(); + while *last.number() > from_number { + let hdr = self.client + .header(&BlockId::hash(*last.parent_hash())) + .map_err(client_err)?; + if let Some(hdr) = hdr { + blocks.push(hdr.hash()); + last = hdr; + } else { + return Err(invalid_block_range( + Some(from), + Some(to), + format!("Parent of {} ({}) not found", last.number(), last.hash()), + )) + } + } + if last.hash() != from.hash() { + return Err(invalid_block_range( + Some(from), + Some(to), + format!("Expected to reach `from`, got {} ({})", last.number(), last.hash()), + )) + } + blocks.reverse(); + blocks + }; + // check if we can filter blocks-with-changes from some (sub)range using changes tries + let changes_trie_range = self.client + .max_key_changes_range(from_number, BlockId::Hash(to.hash())) + .map_err(client_err)?; + let filtered_range_begin = changes_trie_range + .map(|(begin, _)| (begin - from_number).saturated_into::()); + let (unfiltered_range, filtered_range) = split_range(blocks.len(), filtered_range_begin); + Ok(QueryStorageRange { + hashes: blocks, + first_number: from_number, + unfiltered_range, + filtered_range, + }) + }, + (from, to) => Err( + invalid_block_range(from.as_ref(), to.as_ref(), "Invalid range or unknown block".into()) + ), + } + } + + /// Iterates through range.unfiltered_range and check each block for changes of keys' values. + fn query_storage_unfiltered( + &self, + range: &QueryStorageRange, + keys: &[StorageKey], + last_values: &mut HashMap>, + changes: &mut Vec>, + ) -> Result<()> { + for block in range.unfiltered_range.start..range.unfiltered_range.end { + let block_hash = range.hashes[block].clone(); + let mut block_changes = StorageChangeSet { block: block_hash.clone(), changes: Vec::new() }; + let id = BlockId::hash(block_hash); + for key in keys { + let (has_changed, data) = { + let curr_data = self.client.storage(&id, key).map_err(client_err)?; + match last_values.get(key) { + Some(prev_data) => (curr_data != *prev_data, curr_data), + None => (true, curr_data), + } + }; + if has_changed { + block_changes.changes.push((key.clone(), data.clone())); + } + last_values.insert(key.clone(), data); + } + if !block_changes.changes.is_empty() { + changes.push(block_changes); + } + } + Ok(()) + } + + /// Iterates through all blocks that are changing keys within range.filtered_range and collects these changes. + fn query_storage_filtered( + &self, + range: &QueryStorageRange, + keys: &[StorageKey], + last_values: &HashMap>, + changes: &mut Vec>, + ) -> Result<()> { + let (begin, end) = match range.filtered_range { + Some(ref filtered_range) => ( + range.first_number + filtered_range.start.saturated_into(), + BlockId::Hash(range.hashes[filtered_range.end - 1].clone()) + ), + None => return Ok(()), + }; + let mut changes_map: BTreeMap, StorageChangeSet> = BTreeMap::new(); + for key in keys { + let mut last_block = None; + let mut last_value = last_values.get(key).cloned().unwrap_or_default(); + let key_changes = self.client.key_changes(begin, end, None, key).map_err(client_err)?; + for (block, _) in key_changes.into_iter().rev() { + if last_block == Some(block) { + continue; + } + + let block_hash = range.hashes[(block - range.first_number).saturated_into::()].clone(); + let id = BlockId::Hash(block_hash); + let value_at_block = self.client.storage(&id, key).map_err(client_err)?; + if last_value == value_at_block { + continue; + } + + changes_map.entry(block) + .or_insert_with(|| StorageChangeSet { block: block_hash, changes: Vec::new() }) + .changes.push((key.clone(), value_at_block.clone())); + last_block = Some(block); + last_value = value_at_block; + } + } + if let Some(additional_capacity) = changes_map.len().checked_sub(changes.len()) { + changes.reserve(additional_capacity); + } + changes.extend(changes_map.into_iter().map(|(_, cs)| cs)); + Ok(()) + } +} + +impl StateBackend for FullState + where + Block: BlockT + 'static, + B: Backend + Send + Sync + 'static, + E: CallExecutor + Send + Sync + 'static + Clone, + RA: Send + Sync + 'static, + Client: ProvideRuntimeApi, + as ProvideRuntimeApi>::Api: Metadata, +{ + fn call( + &self, + block: Option, + method: String, + call_data: Bytes, + ) -> FutureResult { + Box::new(result( + self.block_or_best(block) + .and_then(|block| self.client.executor() + .call( + &BlockId::Hash(block), + &method, + &*call_data, + ExecutionStrategy::NativeElseWasm, + NeverOffchainExt::new(), + ) + .map(Into::into)) + .map_err(client_err))) + } + + fn storage_keys( + &self, + block: Option, + prefix: StorageKey, + ) -> FutureResult> { + Box::new(result( + self.block_or_best(block) + .and_then(|block| self.client.storage_keys(&BlockId::Hash(block), &prefix)) + .map_err(client_err))) + } + + fn storage( + &self, + block: Option, + key: StorageKey, + ) -> FutureResult> { + Box::new(result( + self.block_or_best(block) + .and_then(|block| self.client.storage(&BlockId::Hash(block), &key)) + .map_err(client_err))) + } + + fn storage_hash( + &self, + block: Option, + key: StorageKey, + ) -> FutureResult> { + Box::new(result( + self.block_or_best(block) + .and_then(|block| self.client.storage_hash(&BlockId::Hash(block), &key)) + .map_err(client_err))) + } + + fn child_storage_keys( + &self, + block: Option, + child_storage_key: StorageKey, + prefix: StorageKey, + ) -> FutureResult> { + Box::new(result( + self.block_or_best(block) + .and_then(|block| self.client.child_storage_keys(&BlockId::Hash(block), &child_storage_key, &prefix)) + .map_err(client_err))) + } + + fn child_storage( + &self, + block: Option, + child_storage_key: StorageKey, + key: StorageKey, + ) -> FutureResult> { + Box::new(result( + self.block_or_best(block) + .and_then(|block| self.client.child_storage(&BlockId::Hash(block), &child_storage_key, &key)) + .map_err(client_err))) + } + + fn child_storage_hash( + &self, + block: Option, + child_storage_key: StorageKey, + key: StorageKey, + ) -> FutureResult> { + Box::new(result( + self.block_or_best(block) + .and_then(|block| self.client.child_storage_hash(&BlockId::Hash(block), &child_storage_key, &key)) + .map_err(client_err))) + } + + fn metadata(&self, block: Option) -> FutureResult { + Box::new(result( + self.block_or_best(block) + .and_then(|block| self.client.runtime_api().metadata(&BlockId::Hash(block)).map(Into::into)) + .map_err(client_err))) + } + + fn runtime_version(&self, block: Option) -> FutureResult { + Box::new(result( + self.block_or_best(block) + .and_then(|block| self.client.runtime_version_at(&BlockId::Hash(block))) + .map_err(client_err))) + } + + fn query_storage( + &self, + from: Block::Hash, + to: Option, + keys: Vec, + ) -> FutureResult>> { + let call_fn = move || { + let range = self.split_query_storage_range(from, to)?; + let mut changes = Vec::new(); + let mut last_values = HashMap::new(); + self.query_storage_unfiltered(&range, &keys, &mut last_values, &mut changes)?; + self.query_storage_filtered(&range, &keys, &last_values, &mut changes)?; + Ok(changes) + }; + Box::new(result(call_fn())) + } + + fn subscribe_runtime_version( + &self, + _meta: crate::metadata::Metadata, + subscriber: Subscriber, + ) { + let stream = match self.client.storage_changes_notification_stream( + Some(&[StorageKey(well_known_keys::CODE.to_vec())]), + None, + ) { + Ok(stream) => stream, + Err(err) => { + let _ = subscriber.reject(Error::from(client_err(err)).into()); + return; + } + }; + + self.subscriptions.add(subscriber, |sink| { + let version = self.runtime_version(None.into()) + .map_err(Into::into) + .wait(); + + let client = self.client.clone(); + let mut previous_version = version.clone(); + + let stream = stream + .filter_map(move |_| { + let info = client.info(); + let version = client + .runtime_version_at(&BlockId::hash(info.chain.best_hash)) + .map_err(client_err) + .map_err(Into::into); + if previous_version != version { + previous_version = version.clone(); + future::ready(Some(Ok::<_, ()>(version))) + } else { + future::ready(None) + } + }) + .compat(); + + sink + .sink_map_err(|e| warn!("Error sending notifications: {:?}", e)) + .send_all( + stream::iter_result(vec![Ok(version)]) + .chain(stream) + ) + // we ignore the resulting Stream (if the first stream is over we are unsubscribed) + .map(|_| ()) + }); + } + + fn unsubscribe_runtime_version( + &self, + _meta: Option, + id: SubscriptionId, + ) -> RpcResult { + Ok(self.subscriptions.cancel(id)) + } + + fn subscribe_storage( + &self, + _meta: crate::metadata::Metadata, + subscriber: Subscriber>, + keys: Option>, + ) { + let keys = Into::>>::into(keys); + let stream = match self.client.storage_changes_notification_stream( + keys.as_ref().map(|x| &**x), + None + ) { + Ok(stream) => stream, + Err(err) => { + let _ = subscriber.reject(client_err(err).into()); + return; + }, + }; + + // initial values + let initial = stream::iter_result(keys + .map(|keys| { + let block = self.client.info().chain.best_hash; + let changes = keys + .into_iter() + .map(|key| self.storage(Some(block.clone()).into(), key.clone()) + .map(|val| (key.clone(), val)) + .wait() + .unwrap_or_else(|_| (key, None)) + ) + .collect(); + vec![Ok(Ok(StorageChangeSet { block, changes }))] + }).unwrap_or_default()); + + self.subscriptions.add(subscriber, |sink| { + let stream = stream + .map(|(block, changes)| Ok::<_, ()>(Ok(StorageChangeSet { + block, + changes: changes.iter() + .filter_map(|(o_sk, k, v)| if o_sk.is_none() { + Some((k.clone(),v.cloned())) + } else { None }).collect(), + }))) + .compat(); + + sink + .sink_map_err(|e| warn!("Error sending notifications: {:?}", e)) + .send_all(initial.chain(stream)) + // we ignore the resulting Stream (if the first stream is over we are unsubscribed) + .map(|_| ()) + }); + } + + fn unsubscribe_storage( + &self, + _meta: Option, + id: SubscriptionId, + ) -> RpcResult { + Ok(self.subscriptions.cancel(id)) + } +} + +/// Splits passed range into two subranges where: +/// - first range has at least one element in it; +/// - second range (optionally) starts at given `middle` element. +pub(crate) fn split_range(size: usize, middle: Option) -> (Range, Option>) { + // check if we can filter blocks-with-changes from some (sub)range using changes tries + let range2_begin = match middle { + // some of required changes tries are pruned => use available tries + Some(middle) if middle != 0 => Some(middle), + // all required changes tries are available, but we still want values at first block + // => do 'unfiltered' read for the first block and 'filtered' for the rest + Some(_) if size > 1 => Some(1), + // range contains single element => do not use changes tries + Some(_) => None, + // changes tries are not available => do 'unfiltered' read for the whole range + None => None, + }; + let range1 = 0..range2_begin.unwrap_or(size); + let range2 = range2_begin.map(|begin| begin..size); + (range1, range2) +} + +fn invalid_block_range(from: Option<&H>, to: Option<&H>, reason: String) -> Error { + let to_string = |x: Option<&H>| match x { + None => "unknown hash".into(), + Some(h) => format!("{} ({})", h.number(), h.hash()), + }; + + Error::InvalidBlockRange { + from: to_string(from), + to: to_string(to), + details: reason, + } +} diff --git a/core/rpc/src/state/state_light.rs b/core/rpc/src/state/state_light.rs new file mode 100644 index 0000000000000000000000000000000000000000..3d0c7979e39953a10c102dc729522ade010eb1c1 --- /dev/null +++ b/core/rpc/src/state/state_light.rs @@ -0,0 +1,784 @@ +// Copyright 2019 Parity Technologies (UK) Ltd. +// This file is part of Substrate. + +// Substrate 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. + +// Substrate 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 Substrate. If not, see . + +//! State API backend for light nodes. + +use std::{ + sync::Arc, + collections::{HashSet, HashMap, hash_map::Entry}, +}; +use codec::Decode; +use futures03::{ + future::{ready, Either}, + channel::oneshot::{channel, Sender}, + FutureExt, TryFutureExt, + StreamExt as _, TryStreamExt as _, +}; +use hash_db::Hasher; +use jsonrpc_pubsub::{typed::Subscriber, SubscriptionId}; +use log::warn; +use parking_lot::Mutex; +use rpc::{ + Result as RpcResult, + futures::Sink, + futures::future::{result, Future}, + futures::stream::Stream, +}; + +use api::Subscriptions; +use client::{ + BlockchainEvents, Client, CallExecutor, backend::Backend, + error::Error as ClientError, + light::{ + blockchain::{future_header, RemoteBlockchain}, + fetcher::{Fetcher, RemoteCallRequest, RemoteReadRequest, RemoteReadChildRequest}, + }, +}; +use primitives::{ + H256, Blake2Hasher, Bytes, OpaqueMetadata, + storage::{StorageKey, StorageData, StorageChangeSet}, +}; +use runtime_version::RuntimeVersion; +use sr_primitives::{ + generic::BlockId, + traits::Block as BlockT, +}; + +use super::{StateBackend, error::{FutureResult, Error}, client_err}; + +/// Storage data map of storage keys => (optional) storage value. +type StorageMap = HashMap>; + +/// State API backend for light nodes. +pub struct LightState, B, E, RA> { + client: Arc>, + subscriptions: Subscriptions, + version_subscriptions: SimpleSubscriptions, + storage_subscriptions: Arc>>, + remote_blockchain: Arc>, + fetcher: Arc, +} + +/// Shared requests container. +trait SharedRequests: Clone + Send + Sync { + /// Tries to listen for already issued request, or issues request. + /// + /// Returns true if requests has been issued. + fn listen_request( + &self, + block: Hash, + sender: Sender>, + ) -> bool; + + /// Returns (and forgets) all listeners for given request. + fn on_response_received(&self, block: Hash) -> Vec>>; +} + +/// Storage subscriptions data. +struct StorageSubscriptions { + /// Active storage requests. + active_requests: HashMap>>>, + /// Map of subscription => keys that this subscription watch for. + keys_by_subscription: HashMap>, + /// Map of key => set of subscriptions that watch this key. + subscriptions_by_key: HashMap>, +} + +impl SharedRequests for Arc>> { + fn listen_request( + &self, + block: Block::Hash, + sender: Sender>, + ) -> bool { + let mut subscriptions = self.lock(); + let active_requests_at = subscriptions.active_requests.entry(block).or_default(); + active_requests_at.push(sender); + active_requests_at.len() == 1 + } + + fn on_response_received(&self, block: Block::Hash) -> Vec>> { + self.lock().active_requests.remove(&block).unwrap_or_default() + } +} + +/// Simple, maybe shared, subscription data that shares per block requests. +type SimpleSubscriptions = Arc>>>>>; + +impl SharedRequests for SimpleSubscriptions where + Hash: Send + Eq + std::hash::Hash, + V: Send, +{ + fn listen_request( + &self, + block: Hash, + sender: Sender>, + ) -> bool { + let mut subscriptions = self.lock(); + let active_requests_at = subscriptions.entry(block).or_default(); + active_requests_at.push(sender); + active_requests_at.len() == 1 + } + + fn on_response_received(&self, block: Hash) -> Vec>> { + self.lock().remove(&block).unwrap_or_default() + } +} + +impl + 'static, B, E, RA> LightState + where + Block: BlockT, + B: Backend + Send + Sync + 'static, + E: CallExecutor + Send + Sync + 'static + Clone, + RA: Send + Sync + 'static, +{ + /// Create new state API backend for light nodes. + pub fn new( + client: Arc>, + subscriptions: Subscriptions, + remote_blockchain: Arc>, + fetcher: Arc, + ) -> Self { + Self { + client, + subscriptions, + version_subscriptions: Arc::new(Mutex::new(HashMap::new())), + storage_subscriptions: Arc::new(Mutex::new(StorageSubscriptions { + active_requests: HashMap::new(), + keys_by_subscription: HashMap::new(), + subscriptions_by_key: HashMap::new(), + })), + remote_blockchain, + fetcher, + } + } + + /// Returns given block hash or best block hash if None is passed. + fn block_or_best(&self, hash: Option) -> Block::Hash { + hash.unwrap_or_else(|| self.client.info().chain.best_hash) + } +} + +impl StateBackend for LightState + where + Block: BlockT, + B: Backend + Send + Sync + 'static, + E: CallExecutor + Send + Sync + 'static + Clone, + RA: Send + Sync + 'static, + F: Fetcher + 'static +{ + fn call( + &self, + block: Option, + method: String, + call_data: Bytes, + ) -> FutureResult { + Box::new(call( + &*self.remote_blockchain, + self.fetcher.clone(), + self.block_or_best(block), + method, + call_data, + ).boxed().compat()) + } + + fn storage_keys( + &self, + _block: Option, + _prefix: StorageKey, + ) -> FutureResult> { + Box::new(result(Err(client_err(ClientError::NotAvailableOnLightClient)))) + } + + fn storage( + &self, + block: Option, + key: StorageKey, + ) -> FutureResult> { + Box::new(storage( + &*self.remote_blockchain, + self.fetcher.clone(), + self.block_or_best(block), + vec![key.0.clone()], + ).boxed().compat().map(move |mut values| values + .remove(&key) + .expect("successful request has entries for all requested keys; qed") + )) + } + + fn storage_hash( + &self, + block: Option, + key: StorageKey, + ) -> FutureResult> { + Box::new(self + .storage(block, key) + .and_then(|maybe_storage| + result(Ok(maybe_storage.map(|storage| Blake2Hasher::hash(&storage.0)))) + ) + ) + } + + fn child_storage_keys( + &self, + _block: Option, + _child_storage_key: StorageKey, + _prefix: StorageKey, + ) -> FutureResult> { + Box::new(result(Err(client_err(ClientError::NotAvailableOnLightClient)))) + } + + fn child_storage( + &self, + block: Option, + child_storage_key: StorageKey, + key: StorageKey, + ) -> FutureResult> { + let block = self.block_or_best(block); + let fetcher = self.fetcher.clone(); + let child_storage = resolve_header(&*self.remote_blockchain, &*self.fetcher, block) + .then(move |result| match result { + Ok(header) => Either::Left(fetcher.remote_read_child(RemoteReadChildRequest { + block, + header, + storage_key: child_storage_key.0, + keys: vec![key.0.clone()], + retry_count: Default::default(), + }).then(move |result| ready(result + .map(|mut data| data + .remove(&key.0) + .expect("successful result has entry for all keys; qed") + .map(StorageData) + ) + .map_err(client_err) + ))), + Err(error) => Either::Right(ready(Err(error))), + }); + + Box::new(child_storage.boxed().compat()) + } + + fn child_storage_hash( + &self, + block: Option, + child_storage_key: StorageKey, + key: StorageKey, + ) -> FutureResult> { + Box::new(self + .child_storage(block, child_storage_key, key) + .and_then(|maybe_storage| + result(Ok(maybe_storage.map(|storage| Blake2Hasher::hash(&storage.0)))) + ) + ) + } + + fn metadata(&self, block: Option) -> FutureResult { + let metadata = self.call(block, "Metadata_metadata".into(), Bytes(Vec::new())) + .and_then(|metadata| OpaqueMetadata::decode(&mut &metadata.0[..]) + .map(Into::into) + .map_err(|decode_err| client_err(ClientError::CallResultDecode( + "Unable to decode metadata", + decode_err, + )))); + + Box::new(metadata) + } + + fn runtime_version(&self, block: Option) -> FutureResult { + Box::new(runtime_version( + &*self.remote_blockchain, + self.fetcher.clone(), + self.block_or_best(block), + ).boxed().compat()) + } + + fn query_storage( + &self, + _from: Block::Hash, + _to: Option, + _keys: Vec, + ) -> FutureResult>> { + Box::new(result(Err(client_err(ClientError::NotAvailableOnLightClient)))) + } + + fn subscribe_storage( + &self, + _meta: crate::metadata::Metadata, + subscriber: Subscriber>, + keys: Option> + ) { + let keys = match keys { + Some(keys) => keys, + None => { + warn!("Cannot subscribe to all keys on light client. Subscription rejected."); + return; + } + }; + + let keys = keys.iter().cloned().collect::>(); + let keys_to_check = keys.iter().map(|k| k.0.clone()).collect::>(); + let subscription_id = self.subscriptions.add(subscriber, move |sink| { + let fetcher = self.fetcher.clone(); + let remote_blockchain = self.remote_blockchain.clone(); + let storage_subscriptions = self.storage_subscriptions.clone(); + let initial_block = self.block_or_best(None); + let initial_keys = keys_to_check.iter().cloned().collect::>(); + + let changes_stream = subscription_stream::( + storage_subscriptions.clone(), + self.client + .import_notification_stream() + .map(|notification| Ok::<_, ()>(notification.hash)) + .compat(), + display_error(storage( + &*remote_blockchain, + fetcher.clone(), + initial_block, + initial_keys, + ).map(move |r| r.map(|r| (initial_block, r)))), + move |block| { + // there'll be single request per block for all active subscriptions + // with all subscribed keys + let keys = storage_subscriptions + .lock() + .subscriptions_by_key + .keys() + .map(|k| k.0.clone()) + .collect(); + + storage( + &*remote_blockchain, + fetcher.clone(), + block, + keys, + ) + }, + move |block, old_value, new_value| { + // let's only select keys which are valid for this subscription + let new_value = new_value + .iter() + .filter(|(k, _)| keys_to_check.contains(&k.0)) + .map(|(k, v)| (k.clone(), v.clone())) + .collect::>(); + let value_differs = old_value + .as_ref() + .map(|old_value| **old_value != new_value) + .unwrap_or(true); + match value_differs { + true => Some(StorageChangeSet { + block, + changes: new_value + .iter() + .map(|(k, v)| (k.clone(), v.clone())) + .collect(), + }), + false => None, + } + } + ); + + sink + .sink_map_err(|e| warn!("Error sending notifications: {:?}", e)) + .send_all(changes_stream.map(|changes| Ok(changes))) + // we ignore the resulting Stream (if the first stream is over we are unsubscribed) + .map(|_| ()) + }); + + // remember keys associated with this subscription + let mut storage_subscriptions = self.storage_subscriptions.lock(); + storage_subscriptions.keys_by_subscription.insert(subscription_id.clone(), keys.clone()); + for key in keys { + storage_subscriptions + .subscriptions_by_key + .entry(key) + .or_default() + .insert(subscription_id.clone()); + } + } + + fn unsubscribe_storage( + &self, + _meta: Option, + id: SubscriptionId, + ) -> RpcResult { + if !self.subscriptions.cancel(id.clone()) { + return Ok(false); + } + + // forget subscription keys + let mut storage_subscriptions = self.storage_subscriptions.lock(); + let keys = storage_subscriptions.keys_by_subscription.remove(&id); + for key in keys.into_iter().flat_map(|keys| keys.into_iter()) { + match storage_subscriptions.subscriptions_by_key.entry(key) { + Entry::Vacant(_) => unreachable!("every key from keys_by_subscription has\ + corresponding entry in subscriptions_by_key; qed"), + Entry::Occupied(mut entry) => { + entry.get_mut().remove(&id); + if entry.get().is_empty() { + entry.remove(); + } + } + } + } + + Ok(true) + } + + fn subscribe_runtime_version( + &self, + _meta: crate::metadata::Metadata, + subscriber: Subscriber, + ) { + self.subscriptions.add(subscriber, move |sink| { + let fetcher = self.fetcher.clone(); + let remote_blockchain = self.remote_blockchain.clone(); + let version_subscriptions = self.version_subscriptions.clone(); + let initial_block = self.block_or_best(None); + + let versions_stream = subscription_stream::( + version_subscriptions, + self.client + .import_notification_stream() + .map(|notification| Ok::<_, ()>(notification.hash)) + .compat(), + display_error(runtime_version( + &*remote_blockchain, + fetcher.clone(), + initial_block, + ).map(move |r| r.map(|r| (initial_block, r)))), + move |block| runtime_version( + &*remote_blockchain, + fetcher.clone(), + block, + ), + |_, old_version, new_version| { + let version_differs = old_version + .as_ref() + .map(|old_version| *old_version != new_version) + .unwrap_or(true); + match version_differs { + true => Some(new_version.clone()), + false => None, + } + } + ); + + sink + .sink_map_err(|e| warn!("Error sending notifications: {:?}", e)) + .send_all(versions_stream.map(|version| Ok(version))) + // we ignore the resulting Stream (if the first stream is over we are unsubscribed) + .map(|_| ()) + }); + } + + fn unsubscribe_runtime_version( + &self, + _meta: Option, + id: SubscriptionId, + ) -> RpcResult { + Ok(self.subscriptions.cancel(id)) + } +} + +/// Resolve header by hash. +fn resolve_header>( + remote_blockchain: &dyn RemoteBlockchain, + fetcher: &F, + block: Block::Hash, +) -> impl std::future::Future> { + let maybe_header = future_header( + remote_blockchain, + fetcher, + BlockId::Hash(block), + ); + + maybe_header.then(move |result| + ready(result.and_then(|maybe_header| + maybe_header.ok_or(ClientError::UnknownBlock(format!("{}", block))) + ).map_err(client_err)), + ) +} + +/// Call runtime method at given block +fn call>( + remote_blockchain: &dyn RemoteBlockchain, + fetcher: Arc, + block: Block::Hash, + method: String, + call_data: Bytes, +) -> impl std::future::Future> { + resolve_header(remote_blockchain, &*fetcher, block) + .then(move |result| match result { + Ok(header) => Either::Left(fetcher.remote_call(RemoteCallRequest { + block, + header, + method, + call_data: call_data.0, + retry_count: Default::default(), + }).then(|result| ready(result.map(Bytes).map_err(client_err)))), + Err(error) => Either::Right(ready(Err(error))), + }) +} + +/// Get runtime version at given block. +fn runtime_version>( + remote_blockchain: &dyn RemoteBlockchain, + fetcher: Arc, + block: Block::Hash, +) -> impl std::future::Future> { + call( + remote_blockchain, + fetcher, + block, + "Core_version".into(), + Bytes(Vec::new()), + ) + .then(|version| ready(version.and_then(|version| + Decode::decode(&mut &version.0[..]).map_err(|_| client_err(ClientError::VersionInvalid)) + ))) +} + +/// Get storage value at given key at given block. +fn storage>( + remote_blockchain: &dyn RemoteBlockchain, + fetcher: Arc, + block: Block::Hash, + keys: Vec>, +) -> impl std::future::Future>, Error>> { + resolve_header(remote_blockchain, &*fetcher, block) + .then(move |result| match result { + Ok(header) => Either::Left(fetcher.remote_read(RemoteReadRequest { + block, + header, + keys, + retry_count: Default::default(), + }).then(|result| ready(result + .map(|result| result + .into_iter() + .map(|(key, value)| (StorageKey(key), value.map(StorageData))) + .collect() + ).map_err(client_err) + ))), + Err(error) => Either::Right(ready(Err(error))), + }) +} + +/// Returns subscription stream that issues request on every imported block and +/// if value has changed from previous block, emits (stream) item. +fn subscription_stream< + Block, + Requests, + FutureBlocksStream, + V, N, + InitialRequestFuture, + IssueRequest, IssueRequestFuture, + CompareValues, +>( + shared_requests: Requests, + future_blocks_stream: FutureBlocksStream, + initial_request: InitialRequestFuture, + issue_request: IssueRequest, + compare_values: CompareValues, +) -> impl Stream where + Block: BlockT, + Requests: 'static + SharedRequests, + FutureBlocksStream: Stream, + V: Send + 'static + Clone, + InitialRequestFuture: std::future::Future> + Send + 'static, + IssueRequest: 'static + Fn(Block::Hash) -> IssueRequestFuture, + IssueRequestFuture: std::future::Future> + Send + 'static, + CompareValues: Fn(Block::Hash, Option<&V>, &V) -> Option, +{ + // we need to send initial value first, then we'll only be sending if value has changed + let previous_value = Arc::new(Mutex::new(None)); + + // prepare 'stream' of initial values + let initial_value_stream = ignore_error(initial_request) + .boxed() + .compat() + .into_stream(); + + // prepare stream of future values + // + // we do not want to stop stream if single request fails + // (the warning should have been already issued by the request issuer) + let future_values_stream = future_blocks_stream + .and_then(move |block| ignore_error(maybe_share_remote_request::( + shared_requests.clone(), + block, + &issue_request, + ).map(move |r| r.map(|v| (block, v)))).boxed().compat()); + + // now let's return changed values for selected blocks + initial_value_stream + .chain(future_values_stream) + .filter_map(move |block_and_new_value| block_and_new_value.and_then(|(block, new_value)| { + let mut previous_value = previous_value.lock(); + compare_values(block, previous_value.as_ref(), &new_value) + .map(|notification_value| { + *previous_value = Some(new_value); + notification_value + }) + })) + .map_err(|_| ()) +} + +/// Request some data from remote node, probably reusing response from already +/// (in-progress) existing request. +fn maybe_share_remote_request( + shared_requests: Requests, + block: Block::Hash, + issue_request: &IssueRequest, +) -> impl std::future::Future> where + V: Clone, + Requests: SharedRequests, + IssueRequest: Fn(Block::Hash) -> IssueRequestFuture, + IssueRequestFuture: std::future::Future>, +{ + let (sender, receiver) = channel(); + let need_issue_request = shared_requests.listen_request(block, sender); + + // if that isn't the first request - just listen for existing request' response + if !need_issue_request { + return Either::Right(receiver.then(|r| ready(r.unwrap_or(Err(()))))); + } + + // that is the first request - issue remote request + notify all listeners on + // completion + Either::Left( + display_error(issue_request(block)) + .then(move |remote_result| { + let listeners = shared_requests.on_response_received(block); + // skip first element, because this future is the first element + for receiver in listeners.into_iter().skip(1) { + if let Err(_) = receiver.send(remote_result.clone()) { + // we don't care if receiver has been dropped already + } + } + + ready(remote_result) + }) + ) +} + +/// Convert successful future result into Ok(result) and error into Err(()), +/// displaying warning. +fn display_error(future: F) -> impl std::future::Future> where + F: std::future::Future> +{ + future.then(|result| ready(match result { + Ok(result) => Ok(result), + Err(err) => { + warn!("Remote request for subscription data has failed with: {:?}", err); + Err(()) + }, + })) +} + +/// Convert successful future result into Ok(Some(result)) and error into Ok(None), +/// displaying warning. +fn ignore_error(future: F) -> impl std::future::Future, ()>> where + F: std::future::Future> +{ + future.then(|result| ready(match result { + Ok(result) => Ok(Some(result)), + Err(()) => Ok(None), + })) +} + +#[cfg(test)] +mod tests { + use rpc::futures::stream::futures_ordered; + use test_client::runtime::Block; + use super::*; + + #[test] + fn subscription_stream_works() { + let stream = subscription_stream::( + SimpleSubscriptions::default(), + futures_ordered(vec![result(Ok(H256::from([2; 32]))), result(Ok(H256::from([3; 32])))]), + ready(Ok((H256::from([1; 32]), 100))), + |block| match block[0] { + 2 => ready(Ok(100)), + 3 => ready(Ok(200)), + _ => unreachable!("should not issue additional requests"), + }, + |_, old_value, new_value| match old_value == Some(new_value) { + true => None, + false => Some(new_value.clone()), + } + ); + + assert_eq!( + stream.collect().wait(), + Ok(vec![100, 200]) + ); + } + + #[test] + fn subscription_stream_ignores_failed_requests() { + let stream = subscription_stream::( + SimpleSubscriptions::default(), + futures_ordered(vec![result(Ok(H256::from([2; 32]))), result(Ok(H256::from([3; 32])))]), + ready(Ok((H256::from([1; 32]), 100))), + |block| match block[0] { + 2 => ready(Err(client_err(ClientError::NotAvailableOnLightClient))), + 3 => ready(Ok(200)), + _ => unreachable!("should not issue additional requests"), + }, + |_, old_value, new_value| match old_value == Some(new_value) { + true => None, + false => Some(new_value.clone()), + } + ); + + assert_eq!( + stream.collect().wait(), + Ok(vec![100, 200]) + ); + } + + #[test] + fn maybe_share_remote_request_shares_request() { + type UnreachableFuture = futures03::future::Ready>; + + let shared_requests = SimpleSubscriptions::default(); + + // let's 'issue' requests for B1 + shared_requests.lock().insert( + H256::from([1; 32]), + vec![channel().0], + ); + + // make sure that no additional requests are issued when we're asking for B1 + let _ = maybe_share_remote_request::( + shared_requests.clone(), + H256::from([1; 32]), + &|_| unreachable!("no duplicate requests issued"), + ); + + // make sure that additional requests is issued when we're asking for B2 + let request_issued = Arc::new(Mutex::new(false)); + let _ = maybe_share_remote_request::( + shared_requests.clone(), + H256::from([2; 32]), + &|_| { + *request_issued.lock() = true; + ready(Ok(Default::default())) + }, + ); + assert!(*request_issued.lock()); + } +} diff --git a/core/rpc/src/state/tests.rs b/core/rpc/src/state/tests.rs index 6b4ddc9b920bc9b0dbf9eb0c219e9c4cb3a4aef7..ba1aac4cc3eb4810a388587dd9217c5853196e41 100644 --- a/core/rpc/src/state/tests.rs +++ b/core/rpc/src/state/tests.rs @@ -15,9 +15,12 @@ // along with Substrate. If not, see . use super::*; +use super::state_full::split_range; use self::error::Error; +use std::sync::Arc; use assert_matches::assert_matches; +use futures::stream::Stream; use primitives::storage::well_known_keys; use sr_io::blake2_256; use test_client::{ @@ -25,29 +28,46 @@ use test_client::{ consensus::BlockOrigin, runtime, }; -use substrate_executor::NativeExecutionDispatch; #[test] fn should_return_storage() { - let core = tokio::runtime::Runtime::new().unwrap(); - let client = Arc::new(test_client::new()); + const KEY: &[u8] = b":mock"; + const VALUE: &[u8] = b"hello world"; + const STORAGE_KEY: &[u8] = b":child_storage:default:child"; + const CHILD_VALUE: &[u8] = b"hello world !"; + + let mut core = tokio::runtime::Runtime::new().unwrap(); + let client = TestClientBuilder::new() + .add_extra_storage(KEY.to_vec(), VALUE.to_vec()) + .add_extra_child_storage(STORAGE_KEY.to_vec(), KEY.to_vec(), CHILD_VALUE.to_vec()) + .build(); let genesis_hash = client.genesis_hash(); - let client = State::new(client, Subscriptions::new(Arc::new(core.executor()))); - let key = StorageKey(b":code".to_vec()); + let client = new_full(Arc::new(client), Subscriptions::new(Arc::new(core.executor()))); + let key = StorageKey(KEY.to_vec()); + let storage_key = StorageKey(STORAGE_KEY.to_vec()); assert_eq!( - client.storage(key.clone(), Some(genesis_hash).into()) + client.storage(key.clone(), Some(genesis_hash).into()).wait() .map(|x| x.map(|x| x.0.len())).unwrap().unwrap() as usize, - LocalExecutor::native_equivalent().len(), + VALUE.len(), ); assert_matches!( - client.storage_hash(key.clone(), Some(genesis_hash).into()).map(|x| x.is_some()), + client.storage_hash(key.clone(), Some(genesis_hash).into()).wait() + .map(|x| x.is_some()), Ok(true) ); assert_eq!( - client.storage_size(key.clone(), None).unwrap().unwrap() as usize, - LocalExecutor::native_equivalent().len(), + client.storage_size(key.clone(), None).wait().unwrap().unwrap() as usize, + VALUE.len(), + ); + assert_eq!( + core.block_on( + client.child_storage(storage_key, key, Some(genesis_hash).into()) + .map(|x| x.map(|x| x.0.len())) + ).unwrap().unwrap() as usize, + CHILD_VALUE.len(), ); + } #[test] @@ -57,22 +77,22 @@ fn should_return_child_storage() { .add_child_storage("test", "key", vec![42_u8]) .build()); let genesis_hash = client.genesis_hash(); - let client = State::new(client, Subscriptions::new(Arc::new(core.executor()))); + let client = new_full(client, Subscriptions::new(Arc::new(core.executor()))); let child_key = StorageKey(well_known_keys::CHILD_STORAGE_KEY_PREFIX.iter().chain(b"test").cloned().collect()); let key = StorageKey(b"key".to_vec()); assert_matches!( - client.child_storage(child_key.clone(), key.clone(), Some(genesis_hash).into()), + client.child_storage(child_key.clone(), key.clone(), Some(genesis_hash).into()).wait(), Ok(Some(StorageData(ref d))) if d[0] == 42 && d.len() == 1 ); assert_matches!( client.child_storage_hash(child_key.clone(), key.clone(), Some(genesis_hash).into()) - .map(|x| x.is_some()), + .wait().map(|x| x.is_some()), Ok(true) ); assert_matches!( - client.child_storage_size(child_key.clone(), key.clone(), None), + client.child_storage_size(child_key.clone(), key.clone(), None).wait(), Ok(Some(1)) ); } @@ -82,11 +102,11 @@ fn should_call_contract() { let core = tokio::runtime::Runtime::new().unwrap(); let client = Arc::new(test_client::new()); let genesis_hash = client.genesis_hash(); - let client = State::new(client, Subscriptions::new(Arc::new(core.executor()))); + let client = new_full(client, Subscriptions::new(Arc::new(core.executor()))); assert_matches!( - client.call("balanceOf".into(), Bytes(vec![1,2,3]), Some(genesis_hash).into()), - Err(Error::Client(client::error::Error::Execution(_))) + client.call("balanceOf".into(), Bytes(vec![1,2,3]), Some(genesis_hash).into()).wait(), + Err(Error::Client(_)) ) } @@ -97,21 +117,22 @@ fn should_notify_about_storage_changes() { let (subscriber, id, transport) = Subscriber::new_test("test"); { - let api = State::new(Arc::new(test_client::new()), Subscriptions::new(Arc::new(remote))); + let client = Arc::new(test_client::new()); + let api = new_full(client.clone(), Subscriptions::new(Arc::new(remote))); api.subscribe_storage(Default::default(), subscriber, None.into()); // assert id assigned assert_eq!(core.block_on(id), Ok(Ok(SubscriptionId::Number(1)))); - let mut builder = api.client.new_block(Default::default()).unwrap(); + let mut builder = client.new_block(Default::default()).unwrap(); builder.push_transfer(runtime::Transfer { from: AccountKeyring::Alice.into(), to: AccountKeyring::Ferdie.into(), amount: 42, nonce: 0, }).unwrap(); - api.client.import(BlockOrigin::Own, builder.bake().unwrap()).unwrap(); + client.import(BlockOrigin::Own, builder.bake().unwrap()).unwrap(); } // assert notification sent to transport @@ -128,7 +149,8 @@ fn should_send_initial_storage_changes_and_notifications() { let (subscriber, id, transport) = Subscriber::new_test("test"); { - let api = State::new(Arc::new(test_client::new()), Subscriptions::new(Arc::new(remote))); + let client = Arc::new(test_client::new()); + let api = new_full(client.clone(), Subscriptions::new(Arc::new(remote))); let alice_balance_key = blake2_256(&runtime::system::balance_of_key(AccountKeyring::Alice.into())); @@ -139,14 +161,14 @@ fn should_send_initial_storage_changes_and_notifications() { // assert id assigned assert_eq!(core.block_on(id), Ok(Ok(SubscriptionId::Number(1)))); - let mut builder = api.client.new_block(Default::default()).unwrap(); + let mut builder = client.new_block(Default::default()).unwrap(); builder.push_transfer(runtime::Transfer { from: AccountKeyring::Alice.into(), to: AccountKeyring::Ferdie.into(), amount: 42, nonce: 0, }).unwrap(); - api.client.import(BlockOrigin::Own, builder.bake().unwrap()).unwrap(); + client.import(BlockOrigin::Own, builder.bake().unwrap()).unwrap(); } // assert initial values sent to transport @@ -163,7 +185,7 @@ fn should_send_initial_storage_changes_and_notifications() { fn should_query_storage() { fn run_tests(client: Arc) { let core = tokio::runtime::Runtime::new().unwrap(); - let api = State::new(client.clone(), Subscriptions::new(Arc::new(core.executor()))); + let api = new_full(client.clone(), Subscriptions::new(Arc::new(core.executor()))); let add_block = |nonce| { let mut builder = client.new_block(Default::default()).unwrap(); @@ -215,7 +237,7 @@ fn should_query_storage() { Some(block1_hash).into(), ); - assert_eq!(result.unwrap(), expected); + assert_eq!(result.wait().unwrap(), expected); // Query all changes let result = api.query_storage( @@ -232,7 +254,7 @@ fn should_query_storage() { (StorageKey(vec![5]), Some(StorageData(vec![1]))), ], }); - assert_eq!(result.unwrap(), expected); + assert_eq!(result.wait().unwrap(), expected); } run_tests(Arc::new(test_client::new())); @@ -254,7 +276,7 @@ fn should_return_runtime_version() { let core = tokio::runtime::Runtime::new().unwrap(); let client = Arc::new(test_client::new()); - let api = State::new(client.clone(), Subscriptions::new(Arc::new(core.executor()))); + let api = new_full(client.clone(), Subscriptions::new(Arc::new(core.executor()))); let result = "{\"specName\":\"test\",\"implName\":\"parity-test\",\"authoringVersion\":1,\ \"specVersion\":1,\"implVersion\":1,\"apis\":[[\"0xdf6acb689907609b\",2],\ @@ -262,10 +284,12 @@ fn should_return_runtime_version() { [\"0xc6e9a76309f39b09\",1],[\"0xdd718d5cc53262d4\",1],[\"0xcbca25e39f142387\",1],\ [\"0xf78b278be53f454c\",1],[\"0xab3c0572291feb8b\",1]]}"; - assert_eq!( - serde_json::to_string(&api.runtime_version(None.into()).unwrap()).unwrap(), - result, - ); + let runtime_version = api.runtime_version(None.into()).wait().unwrap(); + let serialized = serde_json::to_string(&runtime_version).unwrap(); + assert_eq!(serialized, result); + + let deserialized: RuntimeVersion = serde_json::from_str(result).unwrap(); + assert_eq!(deserialized, runtime_version); } #[test] @@ -275,7 +299,7 @@ fn should_notify_on_runtime_version_initially() { { let client = Arc::new(test_client::new()); - let api = State::new(client.clone(), Subscriptions::new(Arc::new(core.executor()))); + let api = new_full(client.clone(), Subscriptions::new(Arc::new(core.executor()))); api.subscribe_runtime_version(Default::default(), subscriber); diff --git a/core/rpc/src/system/mod.rs b/core/rpc/src/system/mod.rs index 59ed73b588a5da6d41897b8e1efa156986054044..8eeff6758b0b1f036bc1c3f4d00c4bbbfdd9ed3e 100644 --- a/core/rpc/src/system/mod.rs +++ b/core/rpc/src/system/mod.rs @@ -16,62 +16,18 @@ //! Substrate system API. -pub mod error; -pub mod helpers; - #[cfg(test)] mod tests; -use crate::helpers::Receiver; use futures03::{channel::{mpsc, oneshot}, compat::Compat}; -use jsonrpc_derive::rpc; -use network; +use api::Receiver; use sr_primitives::traits::{self, Header as HeaderT}; - use self::error::Result; -pub use self::helpers::{Properties, SystemInfo, Health, PeerInfo}; +pub use api::system::*; +pub use self::helpers::{Properties, SystemInfo, Health, PeerInfo}; pub use self::gen_client::Client as SystemClient; -/// Substrate system RPC API -#[rpc] -pub trait SystemApi { - /// Get the node's implementation name. Plain old string. - #[rpc(name = "system_name")] - fn system_name(&self) -> Result; - - /// Get the node implementation's version. Should be a semver string. - #[rpc(name = "system_version")] - fn system_version(&self) -> Result; - - /// Get the chain's type. Given as a string identifier. - #[rpc(name = "system_chain")] - fn system_chain(&self) -> Result; - - /// Get a custom set of properties as a JSON object, defined in the chain spec. - #[rpc(name = "system_properties")] - fn system_properties(&self) -> Result; - - /// Return health status of the node. - /// - /// Node is considered healthy if it is: - /// - connected to some peers (unless running in dev mode) - /// - not performing a major sync - #[rpc(name = "system_health", returns = "Health")] - fn system_health(&self) -> Receiver; - - /// Returns currently connected peers - #[rpc(name = "system_peers", returns = "Vec>")] - fn system_peers(&self) -> Receiver>>; - - /// Returns current state of the network. - /// - /// **Warning**: This API is not stable. - // TODO: make this stable and move structs https://github.com/paritytech/substrate/issues/1890 - #[rpc(name = "system_networkState", returns = "network::NetworkState")] - fn system_network_state(&self) -> Receiver; -} - /// System API implementation pub struct System { info: SystemInfo, @@ -85,7 +41,7 @@ pub enum Request { /// Must return information about the peers we are connected to. Peers(oneshot::Sender::Number>>>), /// Must return the state of the network. - NetworkState(oneshot::Sender), + NetworkState(oneshot::Sender), } impl System { @@ -133,7 +89,7 @@ impl SystemApi::Number> for Sy Receiver(Compat::new(rx)) } - fn system_network_state(&self) -> Receiver { + fn system_network_state(&self) -> Receiver { let (tx, rx) = oneshot::channel(); let _ = self.send_back.unbounded_send(Request::NetworkState(tx)); Receiver(Compat::new(rx)) diff --git a/core/rpc/src/system/tests.rs b/core/rpc/src/system/tests.rs index 70e8b4b95b67608451d33cd35217b448852660f4..5b271af9ac23a747fd3a84ae6b45fbd8ea444cab 100644 --- a/core/rpc/src/system/tests.rs +++ b/core/rpc/src/system/tests.rs @@ -69,7 +69,7 @@ fn api>>(sync: T) -> System { let _ = sender.send(peers); } Request::NetworkState(sender) => { - let _ = sender.send(network::NetworkState { + let _ = sender.send(serde_json::to_value(&network::NetworkState { peer_id: String::new(), listened_addresses: Default::default(), external_addresses: Default::default(), @@ -78,7 +78,7 @@ fn api>>(sync: T) -> System { average_download_per_sec: 0, average_upload_per_sec: 0, peerset: serde_json::Value::Null, - }); + }).unwrap()); } }; @@ -206,8 +206,9 @@ fn system_peers() { #[test] fn system_network_state() { + let res = wait_receiver(api(None).system_network_state()); assert_eq!( - wait_receiver(api(None).system_network_state()), + serde_json::from_value::(res).unwrap(), network::NetworkState { peer_id: String::new(), listened_addresses: Default::default(), diff --git a/core/serializer/Cargo.toml b/core/serializer/Cargo.toml index ae320e4277bb5d54a492efc324b04d7796d70298..b6dfa3f470c7fb51efa88f5e0920fa308b4b35ce 100644 --- a/core/serializer/Cargo.toml +++ b/core/serializer/Cargo.toml @@ -5,5 +5,5 @@ authors = ["Parity Technologies "] edition = "2018" [dependencies] -serde = "1.0" -serde_json = "1.0" +serde = "1.0.101" +serde_json = "1.0.40" diff --git a/core/service/Cargo.toml b/core/service/Cargo.toml index bd04cd670e5b2ad2c6a7f28eda42c9c4f78185a4..5d8abee11696b9b61a19c60d2af6e7ed146245c5 100644 --- a/core/service/Cargo.toml +++ b/core/service/Cargo.toml @@ -5,20 +5,20 @@ authors = ["Parity Technologies "] edition = "2018" [dependencies] -derive_more = "0.14.0" -futures = "0.1.17" -futures03 = { package = "futures-preview", version = "=0.3.0-alpha.17", features = ["compat"] } +derive_more = "0.15.0" +futures = "0.1.29" +futures03 = { package = "futures-preview", version = "0.3.0-alpha.19", features = ["compat"] } parking_lot = "0.9.0" -lazy_static = "1.0" -log = "0.4" -slog = {version = "^2", features = ["nested-values"]} -tokio-executor = "0.1.7" -tokio-timer = "0.2" -exit-future = "0.1" -serde = { version = "1.0", features = ["derive"] } -serde_json = "1.0" -sysinfo = "0.9.0" -target_info = "0.1" +lazy_static = "1.4.0" +log = "0.4.8" +slog = { version = "2.5.2", features = ["nested-values"] } +tokio-executor = "0.1.8" +tokio-timer = "0.2.11" +exit-future = "0.1.4" +serde = "1.0.101" +serde_json = "1.0.40" +sysinfo = "0.9.5" +target_info = "0.1.0" keystore = { package = "substrate-keystore", path = "../../core/keystore" } sr-io = { path = "../../core/sr-io" } sr-primitives = { path = "../../core/sr-primitives" } @@ -27,15 +27,19 @@ session = { package = "substrate-session", path = "../session" } app-crypto = { package = "substrate-application-crypto", path = "../application-crypto" } consensus_common = { package = "substrate-consensus-common", path = "../../core/consensus/common" } network = { package = "substrate-network", path = "../../core/network" } +chain-spec = { package = "substrate-chain-spec", path = "../chain-spec" } client = { package = "substrate-client", path = "../../core/client" } client_db = { package = "substrate-client-db", path = "../../core/client/db", features = ["kvdb-rocksdb"] } codec = { package = "parity-scale-codec", version = "1.0.0" } substrate-executor = { path = "../../core/executor" } +substrate-authority-discovery = { path = "../../core/authority-discovery"} transaction_pool = { package = "substrate-transaction-pool", path = "../../core/transaction-pool" } -rpc = { package = "substrate-rpc-servers", path = "../../core/rpc-servers" } +rpc-servers = { package = "substrate-rpc-servers", path = "../../core/rpc-servers" } +rpc = { package = "substrate-rpc", path = "../../core/rpc" } tel = { package = "substrate-telemetry", path = "../../core/telemetry" } offchain = { package = "substrate-offchain", path = "../../core/offchain" } parity-multiaddr = { package = "parity-multiaddr", version = "0.5.0" } +authority-discovery-primitives = { package = "substrate-authority-discovery-primitives", path = "../authority-discovery/primitives", default-features = false } [dev-dependencies] substrate-test-runtime-client = { path = "../test-runtime/client" } diff --git a/core/service/src/builder.rs b/core/service/src/builder.rs new file mode 100644 index 0000000000000000000000000000000000000000..f0860de1c1cfa0e2139e27010afa76b1141855a5 --- /dev/null +++ b/core/service/src/builder.rs @@ -0,0 +1,1118 @@ +// Copyright 2017-2019 Parity Technologies (UK) Ltd. +// This file is part of Substrate. + +// Substrate 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. + +// Substrate 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 Substrate. If not, see . + +use crate::{NewService, NetworkStatus, NetworkState, error::{self, Error}, DEFAULT_PROTOCOL_ID}; +use crate::{SpawnTaskHandle, start_rpc_servers, build_network_future, TransactionPoolAdapter}; +use crate::TaskExecutor; +use crate::config::Configuration; +use client::{ + BlockchainEvents, Client, runtime_api, + backend::RemoteBackend, light::blockchain::RemoteBlockchain, +}; +use chain_spec::{RuntimeGenesis, Extension}; +use codec::{Decode, Encode, IoReader}; +use consensus_common::import_queue::ImportQueue; +use futures::{prelude::*, sync::mpsc}; +use futures03::{ + compat::Compat, + future::ready, + FutureExt as _, TryFutureExt as _, + StreamExt as _, TryStreamExt as _, +}; +use keystore::{Store as Keystore, KeyStorePtr}; +use log::{info, warn}; +use network::{FinalityProofProvider, OnDemand, NetworkService, NetworkStateInfo, DhtEvent}; +use network::{config::BoxFinalityProofRequestBuilder, specialization::NetworkSpecialization}; +use parking_lot::{Mutex, RwLock}; +use primitives::{Blake2Hasher, H256, Hasher}; +use rpc::{self, system::SystemInfo}; +use sr_primitives::generic::BlockId; +use sr_primitives::traits::{ + Block as BlockT, Extrinsic, ProvideRuntimeApi, NumberFor, One, Zero, Header, SaturatedConversion +}; +use substrate_executor::{NativeExecutor, NativeExecutionDispatch}; +use std::{io::{Read, Write, Seek}, marker::PhantomData, sync::Arc, sync::atomic::AtomicBool}; +use sysinfo::{get_current_pid, ProcessExt, System, SystemExt}; +use tel::{telemetry, SUBSTRATE_INFO}; +use transaction_pool::txpool::{self, ChainApi, Pool as TransactionPool}; + +/// Aggregator for the components required to build a service. +/// +/// # Usage +/// +/// Call [`ServiceBuilder::new_full`] or [`ServiceBuilder::new_light`], then call the various +/// `with_` methods to add the required components that you built yourself: +/// +/// - [`with_select_chain`](ServiceBuilder::with_select_chain) +/// - [`with_import_queue`](ServiceBuilder::with_import_queue) +/// - [`with_network_protocol`](ServiceBuilder::with_network_protocol) +/// - [`with_finality_proof_provider`](ServiceBuilder::with_finality_proof_provider) +/// - [`with_transaction_pool`](ServiceBuilder::with_transaction_pool) +/// +/// After this is done, call [`build`](ServiceBuilder::build) to construct the service. +/// +/// The order in which the `with_*` methods are called doesn't matter, as the correct binding of +/// generics is done when you call `build`. +/// +pub struct ServiceBuilder +{ + config: Configuration, + client: Arc, + backend: Arc, + keystore: Arc>, + fetcher: Option, + select_chain: Option, + import_queue: TImpQu, + finality_proof_request_builder: Option, + finality_proof_provider: Option, + network_protocol: TNetP, + transaction_pool: Arc, + rpc_extensions: TRpc, + rpc_builder: TRpcB, + dht_event_tx: Option>, + marker: PhantomData<(TBl, TRtApi)>, +} + +/// Full client type. +type TFullClient = Client< + TFullBackend, + TFullCallExecutor, + TBl, + TRtApi, +>; + +/// Full client backend type. +type TFullBackend = client_db::Backend; + +/// Full client call executor type. +type TFullCallExecutor = client::LocalCallExecutor< + client_db::Backend, + NativeExecutor, +>; + +/// Light client type. +type TLightClient = Client< + TLightBackend, + TLightCallExecutor, + TBl, + TRtApi, +>; + +/// Light client backend type. +type TLightBackend = client::light::backend::Backend< + client_db::light::LightStorage, + Blake2Hasher, +>; + +/// Light call executor type. +type TLightCallExecutor = client::light::call_executor::GenesisCallExecutor< + client::light::backend::Backend< + client_db::light::LightStorage, + Blake2Hasher + >, + client::LocalCallExecutor< + client::light::backend::Backend< + client_db::light::LightStorage, + Blake2Hasher + >, + NativeExecutor + >, +>; + +impl ServiceBuilder<(), (), TCfg, TGen, TCSExt, (), (), (), (), (), (), (), (), (), (), ()> +where TGen: RuntimeGenesis, TCSExt: Extension { + /// Start the service builder with a configuration. + pub fn new_full, TRtApi, TExecDisp: NativeExecutionDispatch>( + config: Configuration + ) -> Result, + Arc>, + (), + (), + BoxFinalityProofRequestBuilder, + (), + (), + (), + (), + FullRpcBuilder, + TFullBackend, + >, Error> { + let keystore = Keystore::open(config.keystore_path.clone(), config.keystore_password.clone())?; + + let db_settings = client_db::DatabaseSettings { + cache_size: None, + state_cache_size: config.state_cache_size, + state_cache_child_ratio: + config.state_cache_child_ratio.map(|v| (v, 100)), + path: config.database_path.clone(), + pruning: config.pruning.clone(), + }; + + let executor = NativeExecutor::::new(config.default_heap_pages); + + let fork_blocks = config.chain_spec + .extensions() + .get::>() + .cloned() + .unwrap_or_default(); + + let (client, backend) = client_db::new_client( + db_settings, + executor, + &config.chain_spec, + fork_blocks, + config.execution_strategies.clone(), + Some(keystore.clone()), + )?; + + let client = Arc::new(client); + + let rpc_builder = FullRpcBuilder { client: client.clone() }; + + Ok(ServiceBuilder { + config, + client, + backend, + keystore, + fetcher: None, + select_chain: None, + import_queue: (), + finality_proof_request_builder: None, + finality_proof_provider: None, + network_protocol: (), + transaction_pool: Arc::new(()), + rpc_extensions: Default::default(), + rpc_builder, + dht_event_tx: None, + marker: PhantomData, + }) + } + + /// Start the service builder with a configuration. + pub fn new_light, TRtApi, TExecDisp: NativeExecutionDispatch + 'static>( + config: Configuration + ) -> Result, + Arc>, + (), + (), + BoxFinalityProofRequestBuilder, + (), + (), + (), + (), + LightRpcBuilder, + TLightBackend, + >, Error> { + let keystore = Keystore::open(config.keystore_path.clone(), config.keystore_password.clone())?; + + let db_settings = client_db::DatabaseSettings { + cache_size: config.database_cache_size.map(|u| u as usize), + state_cache_size: config.state_cache_size, + state_cache_child_ratio: + config.state_cache_child_ratio.map(|v| (v, 100)), + path: config.database_path.clone(), + pruning: config.pruning.clone(), + }; + + let executor = NativeExecutor::::new(config.default_heap_pages); + + let db_storage = client_db::light::LightStorage::new(db_settings)?; + let light_blockchain = client::light::new_light_blockchain(db_storage); + let fetch_checker = Arc::new(client::light::new_fetch_checker(light_blockchain.clone(), executor.clone())); + let fetcher = Arc::new(network::OnDemand::new(fetch_checker)); + let backend = client::light::new_light_backend(light_blockchain); + let remote_blockchain = backend.remote_blockchain(); + let client = Arc::new(client::light::new_light( + backend.clone(), + &config.chain_spec, + executor, + )?); + let rpc_builder = LightRpcBuilder { + client: client.clone(), + remote_blockchain, + fetcher: fetcher.clone(), + }; + + Ok(ServiceBuilder { + config, + client, + backend, + keystore, + fetcher: Some(fetcher), + select_chain: None, + import_queue: (), + finality_proof_request_builder: None, + finality_proof_provider: None, + network_protocol: (), + transaction_pool: Arc::new(()), + rpc_extensions: Default::default(), + rpc_builder, + dht_event_tx: None, + marker: PhantomData, + }) + } +} + +impl + ServiceBuilder { + + /// Returns a reference to the client that was stored in this builder. + pub fn client(&self) -> &Arc { + &self.client + } + + /// Returns a reference to the backend that was used in this builder. + pub fn backend(&self) -> &Arc { + &self.backend + } + + /// Returns a reference to the select-chain that was stored in this builder. + pub fn select_chain(&self) -> Option<&TSc> { + self.select_chain.as_ref() + } + + /// Defines which head-of-chain strategy to use. + pub fn with_opt_select_chain( + self, + select_chain_builder: impl FnOnce( + &Configuration, &Arc + ) -> Result, Error> + ) -> Result, Error> { + let select_chain = select_chain_builder(&self.config, &self.backend)?; + + Ok(ServiceBuilder { + config: self.config, + client: self.client, + backend: self.backend, + keystore: self.keystore, + fetcher: self.fetcher, + select_chain, + import_queue: self.import_queue, + finality_proof_request_builder: self.finality_proof_request_builder, + finality_proof_provider: self.finality_proof_provider, + network_protocol: self.network_protocol, + transaction_pool: self.transaction_pool, + rpc_extensions: self.rpc_extensions, + rpc_builder: self.rpc_builder, + dht_event_tx: self.dht_event_tx, + marker: self.marker, + }) + } + + /// Defines which head-of-chain strategy to use. + pub fn with_select_chain( + self, + builder: impl FnOnce(&Configuration, &Arc) -> Result + ) -> Result, Error> { + self.with_opt_select_chain(|cfg, b| builder(cfg, b).map(Option::Some)) + } + + /// Defines which import queue to use. + pub fn with_import_queue( + self, + builder: impl FnOnce(&Configuration, Arc, Option, Arc) + -> Result + ) -> Result, Error> + where TSc: Clone { + let import_queue = builder( + &self.config, + self.client.clone(), + self.select_chain.clone(), + self.transaction_pool.clone() + )?; + + Ok(ServiceBuilder { + config: self.config, + client: self.client, + backend: self.backend, + keystore: self.keystore, + fetcher: self.fetcher, + select_chain: self.select_chain, + import_queue, + finality_proof_request_builder: self.finality_proof_request_builder, + finality_proof_provider: self.finality_proof_provider, + network_protocol: self.network_protocol, + transaction_pool: self.transaction_pool, + rpc_extensions: self.rpc_extensions, + rpc_builder: self.rpc_builder, + dht_event_tx: self.dht_event_tx, + marker: self.marker, + }) + } + + /// Defines which network specialization protocol to use. + pub fn with_network_protocol( + self, + network_protocol_builder: impl FnOnce(&Configuration) -> Result + ) -> Result, Error> { + let network_protocol = network_protocol_builder(&self.config)?; + + Ok(ServiceBuilder { + config: self.config, + client: self.client, + backend: self.backend, + keystore: self.keystore, + fetcher: self.fetcher, + select_chain: self.select_chain, + import_queue: self.import_queue, + finality_proof_request_builder: self.finality_proof_request_builder, + finality_proof_provider: self.finality_proof_provider, + network_protocol, + transaction_pool: self.transaction_pool, + rpc_extensions: self.rpc_extensions, + rpc_builder: self.rpc_builder, + dht_event_tx: self.dht_event_tx, + marker: self.marker, + }) + } + + /// Defines which strategy to use for providing finality proofs. + pub fn with_opt_finality_proof_provider( + self, + builder: impl FnOnce(Arc, Arc) -> Result>>, Error> + ) -> Result>, + TNetP, + TExPool, + TRpc, + TRpcB, + Backend, + >, Error> { + let finality_proof_provider = builder(self.client.clone(), self.backend.clone())?; + + Ok(ServiceBuilder { + config: self.config, + client: self.client, + backend: self.backend, + keystore: self.keystore, + fetcher: self.fetcher, + select_chain: self.select_chain, + import_queue: self.import_queue, + finality_proof_request_builder: self.finality_proof_request_builder, + finality_proof_provider, + network_protocol: self.network_protocol, + transaction_pool: self.transaction_pool, + rpc_extensions: self.rpc_extensions, + rpc_builder: self.rpc_builder, + dht_event_tx: self.dht_event_tx, + marker: self.marker, + }) + } + + /// Defines which strategy to use for providing finality proofs. + pub fn with_finality_proof_provider( + self, + build: impl FnOnce(Arc, Arc) -> Result>, Error> + ) -> Result>, + TNetP, + TExPool, + TRpc, + TRpcB, + Backend, + >, Error> { + self.with_opt_finality_proof_provider(|client, backend| build(client, backend).map(Option::Some)) + } + + /// Defines which import queue to use. + pub fn with_import_queue_and_opt_fprb( + self, + builder: impl FnOnce( + &Configuration, + Arc, + Arc, + Option, + Option, + Arc, + ) -> Result<(UImpQu, Option), Error> + ) -> Result, Error> + where TSc: Clone, TFchr: Clone { + let (import_queue, fprb) = builder( + &self.config, + self.client.clone(), + self.backend.clone(), + self.fetcher.clone(), + self.select_chain.clone(), + self.transaction_pool.clone() + )?; + + Ok(ServiceBuilder { + config: self.config, + client: self.client, + backend: self.backend, + keystore: self.keystore, + fetcher: self.fetcher, + select_chain: self.select_chain, + import_queue, + finality_proof_request_builder: fprb, + finality_proof_provider: self.finality_proof_provider, + network_protocol: self.network_protocol, + transaction_pool: self.transaction_pool, + rpc_extensions: self.rpc_extensions, + rpc_builder: self.rpc_builder, + dht_event_tx: self.dht_event_tx, + marker: self.marker, + }) + } + + /// Defines which import queue to use. + pub fn with_import_queue_and_fprb( + self, + builder: impl FnOnce( + &Configuration, + Arc, + Arc, + Option, + Option, + Arc, + ) -> Result<(UImpQu, UFprb), Error> + ) -> Result, Error> + where TSc: Clone, TFchr: Clone { + self.with_import_queue_and_opt_fprb(|cfg, cl, b, f, sc, tx| + builder(cfg, cl, b, f, sc, tx) + .map(|(q, f)| (q, Some(f))) + ) + } + + /// Defines which transaction pool to use. + pub fn with_transaction_pool( + self, + transaction_pool_builder: impl FnOnce(transaction_pool::txpool::Options, Arc) -> Result + ) -> Result, Error> { + let transaction_pool = transaction_pool_builder(self.config.transaction_pool.clone(), self.client.clone())?; + + Ok(ServiceBuilder { + config: self.config, + client: self.client, + backend: self.backend, + keystore: self.keystore, + fetcher: self.fetcher, + select_chain: self.select_chain, + import_queue: self.import_queue, + finality_proof_request_builder: self.finality_proof_request_builder, + finality_proof_provider: self.finality_proof_provider, + network_protocol: self.network_protocol, + transaction_pool: Arc::new(transaction_pool), + rpc_extensions: self.rpc_extensions, + rpc_builder: self.rpc_builder, + dht_event_tx: self.dht_event_tx, + marker: self.marker, + }) + } + + /// Defines the RPC extensions to use. + pub fn with_rpc_extensions( + self, + rpc_ext_builder: impl FnOnce(Arc, Arc) -> URpc + ) -> Result, Error> { + let rpc_extensions = rpc_ext_builder(self.client.clone(), self.transaction_pool.clone()); + + Ok(ServiceBuilder { + config: self.config, + client: self.client, + backend: self.backend, + keystore: self.keystore, + fetcher: self.fetcher, + select_chain: self.select_chain, + import_queue: self.import_queue, + finality_proof_request_builder: self.finality_proof_request_builder, + finality_proof_provider: self.finality_proof_provider, + network_protocol: self.network_protocol, + transaction_pool: self.transaction_pool, + rpc_extensions, + rpc_builder: self.rpc_builder, + dht_event_tx: self.dht_event_tx, + marker: self.marker, + }) + } + + /// Adds a dht event sender to builder to be used by the network to send dht events to the authority discovery + /// module. + pub fn with_dht_event_tx( + self, + dht_event_tx: mpsc::Sender, + ) -> Result, Error> { + Ok(ServiceBuilder { + config: self.config, + client: self.client, + backend: self.backend, + keystore: self.keystore, + fetcher: self.fetcher, + select_chain: self.select_chain, + import_queue: self.import_queue, + finality_proof_request_builder: self.finality_proof_request_builder, + finality_proof_provider: self.finality_proof_provider, + network_protocol: self.network_protocol, + transaction_pool: self.transaction_pool, + rpc_extensions: self.rpc_extensions, + rpc_builder: self.rpc_builder, + dht_event_tx: Some(dht_event_tx), + marker: self.marker, + }) + } +} + +/// RPC handlers builder. +pub trait RpcBuilder { + /// Build chain RPC handler. + fn build_chain(&self, subscriptions: rpc::Subscriptions) -> rpc::chain::Chain; + /// Build state RPC handler. + fn build_state(&self, subscriptions: rpc::Subscriptions) -> rpc::state::State; +} + +/// RPC handlers builder for full nodes. +pub struct FullRpcBuilder { + client: Arc>, +} + +impl RpcBuilder, TFullCallExecutor, TRtApi> + for + FullRpcBuilder + where + TBl: BlockT, + TRtApi: 'static + Send + Sync, + TExecDisp: 'static + NativeExecutionDispatch, + TFullClient: ProvideRuntimeApi, + as ProvideRuntimeApi>::Api: runtime_api::Metadata, +{ + fn build_chain( + &self, + subscriptions: rpc::Subscriptions, + ) -> rpc::chain::Chain, TFullCallExecutor, TBl, TRtApi> { + rpc::chain::new_full(self.client.clone(), subscriptions) + } + + fn build_state( + &self, + subscriptions: rpc::Subscriptions, + ) -> rpc::state::State, TFullCallExecutor, TBl, TRtApi> { + rpc::state::new_full(self.client.clone(), subscriptions) + } +} + +/// RPC handlers builder for light nodes. +pub struct LightRpcBuilder, TRtApi, TExecDisp> { + client: Arc>, + remote_blockchain: Arc>, + fetcher: Arc>, +} + +impl RpcBuilder, TLightCallExecutor, TRtApi> + for + LightRpcBuilder + where + TBl: BlockT, + TRtApi: 'static + Send + Sync, + TExecDisp: 'static + NativeExecutionDispatch, +{ + fn build_chain( + &self, + subscriptions: rpc::Subscriptions, + ) -> rpc::chain::Chain, TLightCallExecutor, TBl, TRtApi> { + rpc::chain::new_light( + self.client.clone(), + subscriptions, + self.remote_blockchain.clone(), + self.fetcher.clone(), + ) + } + + fn build_state( + &self, + subscriptions: rpc::Subscriptions, + ) -> rpc::state::State, TLightCallExecutor, TBl, TRtApi> { + rpc::state::new_light( + self.client.clone(), + subscriptions, + self.remote_blockchain.clone(), + self.fetcher.clone(), + ) + } +} + +/// Implemented on `ServiceBuilder`. Allows importing blocks once you have given all the required +/// components to the builder. +pub trait ServiceBuilderImport { + /// Starts the process of importing blocks. + fn import_blocks( + self, + exit: impl Future + Send + 'static, + input: impl Read + Seek, + ) -> Result + Send>, Error>; +} + +/// Implemented on `ServiceBuilder`. Allows exporting blocks once you have given all the required +/// components to the builder. +pub trait ServiceBuilderExport { + /// Type of block of the builder. + type Block: BlockT; + + /// Performs the blocks export. + fn export_blocks( + &self, + exit: impl Future + Send + 'static, + output: impl Write, + from: NumberFor, + to: Option>, + json: bool + ) -> Result<(), Error>; +} + +/// Implemented on `ServiceBuilder`. Allows reverting the chain once you have given all the +/// required components to the builder. +pub trait ServiceBuilderRevert { + /// Type of block of the builder. + type Block: BlockT; + + /// Performs a revert of `blocks` bocks. + fn revert_chain( + &self, + blocks: NumberFor + ) -> Result<(), Error>; +} + +impl< + TBl, TRtApi, TCfg, TGen, TCSExt, TBackend, + TExec, TFchr, TSc, TImpQu, TFprb, TFpp, TNetP, + TExPool, TRpc, TRpcB, Backend +> ServiceBuilderImport for ServiceBuilder< + TBl, TRtApi, TCfg, TGen, TCSExt, Client, + TFchr, TSc, TImpQu, TFprb, TFpp, TNetP, TExPool, TRpc, TRpcB, Backend +> where + TBl: BlockT::Out>, + TBackend: 'static + client::backend::Backend + Send, + TExec: 'static + client::CallExecutor + Send + Sync + Clone, + TImpQu: 'static + ImportQueue, + TRtApi: 'static + Send + Sync, +{ + fn import_blocks( + self, + exit: impl Future + Send + 'static, + input: impl Read + Seek, + ) -> Result + Send>, Error> { + let client = self.client; + let mut queue = self.import_queue; + import_blocks!(TBl, client, queue, exit, input) + .map(|f| Box::new(f) as Box<_>) + } +} + +impl + ServiceBuilderExport for ServiceBuilder, + TFchr, TSc, TImpQu, TFprb, TFpp, TNetP, TExPool, TRpc, TRpcB, TBackend> +where + TBl: BlockT::Out>, + TBackend: 'static + client::backend::Backend + Send, + TExec: 'static + client::CallExecutor + Send + Sync + Clone +{ + type Block = TBl; + + fn export_blocks( + &self, + exit: impl Future + Send + 'static, + mut output: impl Write, + from: NumberFor, + to: Option>, + json: bool + ) -> Result<(), Error> { + let client = &self.client; + export_blocks!(client, exit, output, from, to, json) + } +} + +impl + ServiceBuilderRevert for ServiceBuilder, + TFchr, TSc, TImpQu, TFprb, TFpp, TNetP, TExPool, TRpc, TRpcB, TBackend> +where + TBl: BlockT::Out>, + TBackend: 'static + client::backend::Backend + Send, + TExec: 'static + client::CallExecutor + Send + Sync + Clone +{ + type Block = TBl; + + fn revert_chain( + &self, + blocks: NumberFor + ) -> Result<(), Error> { + let client = &self.client; + revert_chain!(client, blocks) + } +} + +impl +ServiceBuilder< + TBl, + TRtApi, + TCfg, + TGen, + TCSExt, + Client, + Arc>, + TSc, + TImpQu, + BoxFinalityProofRequestBuilder, + Arc>, + TNetP, + TransactionPool, + TRpc, + TRpcB, + TBackend, +> where + Client: ProvideRuntimeApi, + as ProvideRuntimeApi>::Api: + runtime_api::Metadata + + offchain::OffchainWorkerApi + + runtime_api::TaggedTransactionQueue + + session::SessionKeys, + TBl: BlockT::Out>, + TRtApi: 'static + Send + Sync, + TCfg: Default, + TGen: RuntimeGenesis, + TCSExt: Extension, + TBackend: 'static + client::backend::Backend + Send, + TExec: 'static + client::CallExecutor + Send + Sync + Clone, + TSc: Clone, + TImpQu: 'static + ImportQueue, + TNetP: NetworkSpecialization, + TExPoolApi: 'static + ChainApi::Hash>, + TRpc: rpc::RpcExtension + Clone, + TRpcB: RpcBuilder, +{ + /// Builds the service. + pub fn build(self) -> Result, + TSc, + NetworkStatus, + NetworkService::Hash>, + TransactionPool, + offchain::OffchainWorkers< + Client, + TBackend::OffchainStorage, + TBl + >, + >, Error> { + let ServiceBuilder { + marker: _, + mut config, + client, + fetcher, + backend, + keystore, + select_chain, + import_queue, + finality_proof_request_builder, + finality_proof_provider, + network_protocol, + transaction_pool, + rpc_extensions, + dht_event_tx, + rpc_builder, + } = self; + + session::generate_initial_session_keys( + client.clone(), + config.dev_key_seed.clone().map(|s| vec![s]).unwrap_or_default() + )?; + + new_impl!( + TBl, + config, + move |_| -> Result<_, Error> { + Ok(( + client, + fetcher, + backend, + keystore, + select_chain, + import_queue, + finality_proof_request_builder, + finality_proof_provider, + network_protocol, + transaction_pool, + rpc_extensions, + dht_event_tx, + )) + }, + |h, c, tx, r| maintain_transaction_pool(h, c, tx, r), + |n, o, p, ns, v| offchain_workers(n, o, p, ns, v), + |c, ssb, si, te, tp, ext, ks| start_rpc(&rpc_builder, c, ssb, si, te, tp, ext, ks), + ) + } +} + +pub(crate) fn start_rpc( + rpc_builder: &RpcB, + client: Arc>, + system_send_back: futures03::channel::mpsc::UnboundedSender>, + rpc_system_info: SystemInfo, + task_executor: TaskExecutor, + transaction_pool: Arc>, + rpc_extensions: impl rpc::RpcExtension, + keystore: KeyStorePtr, +) -> rpc_servers::RpcHandler +where + Block: BlockT::Out>, + Backend: client::backend::Backend + 'static, + Client: ProvideRuntimeApi, + as ProvideRuntimeApi>::Api: + runtime_api::Metadata + session::SessionKeys, + Api: Send + Sync + 'static, + Executor: client::CallExecutor + Send + Sync + Clone + 'static, + PoolApi: txpool::ChainApi + 'static, + RpcB: RpcBuilder, +{ + use rpc::{chain, state, author, system}; + let subscriptions = rpc::Subscriptions::new(task_executor); + let chain = rpc_builder.build_chain(subscriptions.clone()); + let state = rpc_builder.build_state(subscriptions.clone()); + let author = rpc::author::Author::new( + client, + transaction_pool, + subscriptions, + keystore, + ); + let system = system::System::new(rpc_system_info, system_send_back); + + rpc_servers::rpc_handler(( + state::StateApi::to_delegate(state), + chain::ChainApi::to_delegate(chain), + author::AuthorApi::to_delegate(author), + system::SystemApi::to_delegate(system), + rpc_extensions, + )) +} + +pub(crate) fn maintain_transaction_pool( + id: &BlockId, + client: &Arc>, + transaction_pool: &TransactionPool, + retracted: &[Block::Hash], +) -> error::Result + Send>> where + Block: BlockT::Out>, + Backend: 'static + client::backend::Backend, + Client: ProvideRuntimeApi, + as ProvideRuntimeApi>::Api: runtime_api::TaggedTransactionQueue, + Executor: 'static + client::CallExecutor, + PoolApi: 'static + txpool::ChainApi, + Api: 'static, +{ + // Put transactions from retracted blocks back into the pool. + let client_copy = client.clone(); + let retracted_transactions = retracted.to_vec().into_iter() + .filter_map(move |hash| client_copy.block(&BlockId::hash(hash)).ok().unwrap_or(None)) + .flat_map(|block| block.block.deconstruct().1.into_iter()) + .filter(|tx| tx.is_signed().unwrap_or(false)); + let resubmit_future = transaction_pool + .submit_at(id, retracted_transactions, true) + .then(|resubmit_result| ready(match resubmit_result { + Ok(_) => Ok(()), + Err(e) => { + warn!("Error re-submitting transactions: {:?}", e); + Ok(()) + } + })) + .compat(); + + // Avoid calling into runtime if there is nothing to prune from the pool anyway. + if transaction_pool.status().is_empty() { + return Ok(Box::new(resubmit_future)) + } + + let block = client.block(id)?; + Ok(match block { + Some(block) => { + let parent_id = BlockId::hash(*block.block.header().parent_hash()); + let prune_future = transaction_pool + .prune(id, &parent_id, block.block.extrinsics()) + .boxed() + .compat() + .map_err(|e| { format!("{:?}", e); }); + + Box::new(resubmit_future.and_then(|_| prune_future)) + }, + None => Box::new(resubmit_future), + }) +} + +pub(crate) fn offchain_workers( + number: &NumberFor, + offchain: &offchain::OffchainWorkers< + Client, + >::OffchainStorage, + Block + >, + pool: &Arc>, + network_state: &Arc, + is_validator: bool, +) -> error::Result + Send>> +where + Block: BlockT::Out>, + Backend: client::backend::Backend + 'static, + Api: 'static, + >::OffchainStorage: 'static, + Client: ProvideRuntimeApi + Send + Sync, + as ProvideRuntimeApi>::Api: offchain::OffchainWorkerApi, + Executor: client::CallExecutor + 'static, + PoolApi: txpool::ChainApi + 'static, +{ + let future = offchain.on_block_imported(number, pool, network_state.clone(), is_validator) + .map(|()| Ok(())); + Ok(Box::new(Compat::new(future))) +} + +#[cfg(test)] +mod tests { + use super::*; + use futures03::executor::block_on; + use consensus_common::{BlockOrigin, SelectChain}; + use substrate_test_runtime_client::{prelude::*, runtime::Transfer}; + + #[test] + fn should_remove_transactions_from_the_pool() { + let (client, longest_chain) = TestClientBuilder::new().build_with_longest_chain(); + let client = Arc::new(client); + let pool = TransactionPool::new(Default::default(), ::transaction_pool::FullChainApi::new(client.clone())); + let transaction = Transfer { + amount: 5, + nonce: 0, + from: AccountKeyring::Alice.into(), + to: Default::default(), + }.into_signed_tx(); + let best = longest_chain.best_chain().unwrap(); + + // store the transaction in the pool + block_on(pool.submit_one(&BlockId::hash(best.hash()), transaction.clone())).unwrap(); + + // import the block + let mut builder = client.new_block(Default::default()).unwrap(); + builder.push(transaction.clone()).unwrap(); + let block = builder.bake().unwrap(); + let id = BlockId::hash(block.header().hash()); + client.import(BlockOrigin::Own, block).unwrap(); + + // fire notification - this should clean up the queue + assert_eq!(pool.status().ready, 1); + maintain_transaction_pool( + &id, + &client, + &pool, + &[] + ).unwrap().wait().unwrap(); + + // then + assert_eq!(pool.status().ready, 0); + assert_eq!(pool.status().future, 0); + } + + #[test] + fn should_add_reverted_transactions_to_the_pool() { + let (client, longest_chain) = TestClientBuilder::new().build_with_longest_chain(); + let client = Arc::new(client); + let pool = TransactionPool::new(Default::default(), ::transaction_pool::FullChainApi::new(client.clone())); + let transaction = Transfer { + amount: 5, + nonce: 0, + from: AccountKeyring::Alice.into(), + to: Default::default(), + }.into_signed_tx(); + let best = longest_chain.best_chain().unwrap(); + + // store the transaction in the pool + block_on(pool.submit_one(&BlockId::hash(best.hash()), transaction.clone())).unwrap(); + + // import the block + let mut builder = client.new_block(Default::default()).unwrap(); + builder.push(transaction.clone()).unwrap(); + let block = builder.bake().unwrap(); + let block1_hash = block.header().hash(); + let id = BlockId::hash(block1_hash.clone()); + client.import(BlockOrigin::Own, block).unwrap(); + + // fire notification - this should clean up the queue + assert_eq!(pool.status().ready, 1); + maintain_transaction_pool( + &id, + &client, + &pool, + &[] + ).unwrap().wait().unwrap(); + + // then + assert_eq!(pool.status().ready, 0); + assert_eq!(pool.status().future, 0); + + // import second block + let builder = client.new_block_at(&BlockId::hash(best.hash()), Default::default()).unwrap(); + let block = builder.bake().unwrap(); + let id = BlockId::hash(block.header().hash()); + client.import(BlockOrigin::Own, block).unwrap(); + + // fire notification - this should add the transaction back to the pool. + maintain_transaction_pool( + &id, + &client, + &pool, + &[block1_hash] + ).unwrap().wait().unwrap(); + + // then + assert_eq!(pool.status().ready, 1); + assert_eq!(pool.status().future, 0); + } +} diff --git a/core/service/src/chain_ops.rs b/core/service/src/chain_ops.rs index c801b81186f18cda9495bd6466f13788263b0e10..0858534482f4b25f4915e07f05f00f2478daf25f 100644 --- a/core/service/src/chain_ops.rs +++ b/core/service/src/chain_ops.rs @@ -16,44 +16,20 @@ //! Chain utilities. -use std::{self, io::{Read, Write, Seek}}; -use futures::prelude::*; -use futures03::TryFutureExt as _; -use log::{info, warn}; - -use sr_primitives::generic::{SignedBlock, BlockId}; -use sr_primitives::traits::{SaturatedConversion, Zero, One, Block, Header, NumberFor}; -use consensus_common::import_queue::{ImportQueue, IncomingBlock, Link, BlockImportError, BlockImportResult}; -use network::message; - -use consensus_common::BlockOrigin; -use crate::components::{self, Components, ServiceFactory, FactoryFullConfiguration, FactoryBlockNumber, RuntimeGenesis}; -use crate::new_client; -use codec::{Decode, Encode, IoReader}; use crate::error; -use crate::chain_spec::ChainSpec; +use chain_spec::{ChainSpec, RuntimeGenesis, Extension}; -/// Export a range of blocks to a binary stream. -pub fn export_blocks( - config: FactoryFullConfiguration, - exit: E, - mut output: W, - from: FactoryBlockNumber, - to: Option>, - json: bool -) -> error::Result<()> - where - F: ServiceFactory, - E: Future + Send + 'static, - W: Write, -{ - let client = new_client::(&config)?; - let mut block = from; +/// Defines the logic for an operation exporting blocks within a range. +#[macro_export] +/// Export blocks +macro_rules! export_blocks { +($client:ident, $exit:ident, $output:ident, $from:ident, $to:ident, $json:ident) => {{ + let mut block = $from; - let last = match to { + let last = match $to { Some(v) if v.is_zero() => One::one(), Some(v) => v, - None => client.info().chain.best_number, + None => $client.info().chain.best_number, }; if last < block { @@ -61,29 +37,29 @@ pub fn export_blocks( } let (exit_send, exit_recv) = std::sync::mpsc::channel(); - ::std::thread::spawn(move || { - let _ = exit.wait(); + std::thread::spawn(move || { + let _ = $exit.wait(); let _ = exit_send.send(()); }); info!("Exporting blocks from #{} to #{}", block, last); - if !json { + if !$json { let last_: u64 = last.saturated_into::(); let block_: u64 = block.saturated_into::(); let len: u64 = last_ - block_ + 1; - output.write(&len.encode())?; + $output.write(&len.encode())?; } loop { if exit_recv.try_recv().is_ok() { break; } - match client.block(&BlockId::number(block))? { + match $client.block(&BlockId::number(block))? { Some(block) => { - if json { - serde_json::to_writer(&mut output, &block) + if $json { + serde_json::to_writer(&mut $output, &block) .map_err(|e| format!("Error writing JSON: {}", e))?; } else { - output.write(&block.encode())?; + $output.write(&block.encode())?; } }, None => break, @@ -97,66 +73,61 @@ pub fn export_blocks( block += One::one(); } Ok(()) +}} } -struct WaitLink { - imported_blocks: u64, - has_error: bool, -} +/// Defines the logic for an operation importing blocks from some known import. +#[macro_export] +/// Import blocks +macro_rules! import_blocks { +($block:ty, $client:ident, $queue:ident, $exit:ident, $input:ident) => {{ + use consensus_common::import_queue::{IncomingBlock, Link, BlockImportError, BlockImportResult}; + use consensus_common::BlockOrigin; + use network::message; + use sr_primitives::generic::SignedBlock; + use sr_primitives::traits::Block; + use futures03::TryFutureExt as _; + + struct WaitLink { + imported_blocks: u64, + has_error: bool, + } -impl WaitLink { - fn new() -> WaitLink { - WaitLink { - imported_blocks: 0, - has_error: false, + impl WaitLink { + fn new() -> WaitLink { + WaitLink { + imported_blocks: 0, + has_error: false, + } } } -} -impl Link for WaitLink { - fn blocks_processed( - &mut self, - imported: usize, - _count: usize, - results: Vec<(Result>, BlockImportError>, B::Hash)> - ) { - self.imported_blocks += imported as u64; - - for result in results { - if let (Err(err), hash) = result { - warn!("There was an error importing block with hash {:?}: {:?}", hash, err); - self.has_error = true; - break; + impl Link for WaitLink { + fn blocks_processed( + &mut self, + imported: usize, + _count: usize, + results: Vec<(Result>, BlockImportError>, B::Hash)> + ) { + self.imported_blocks += imported as u64; + + for result in results { + if let (Err(err), hash) = result { + warn!("There was an error importing block with hash {:?}: {:?}", hash, err); + self.has_error = true; + break; + } } } } -} - -/// Returns a future that import blocks from a binary stream. -pub fn import_blocks( - mut config: FactoryFullConfiguration, - exit: E, - input: R -) -> error::Result> - where F: ServiceFactory, E: Future + Send + 'static, R: Read + Seek, -{ - let client = new_client::(&config)?; - // FIXME #1134 this shouldn't need a mutable config. - let select_chain = components::FullComponents::::build_select_chain(&mut config, client.clone())?; - let (mut queue, _) = components::FullComponents::::build_import_queue( - &mut config, - client.clone(), - select_chain, - None, - )?; let (exit_send, exit_recv) = std::sync::mpsc::channel(); - ::std::thread::spawn(move || { - let _ = exit.wait(); + std::thread::spawn(move || { + let _ = $exit.wait(); let _ = exit_send.send(()); }); - let mut io_reader_input = IoReader(input); + let mut io_reader_input = IoReader($input); let count: u64 = Decode::decode(&mut io_reader_input) .map_err(|e| format!("Error reading file: {}", e))?; info!("Importing {} blocks", count); @@ -165,11 +136,11 @@ pub fn import_blocks( if exit_recv.try_recv().is_ok() { break; } - match SignedBlock::::decode(&mut io_reader_input) { + match SignedBlock::<$block>::decode(&mut io_reader_input) { Ok(signed) => { let (header, extrinsics) = signed.block.deconstruct(); let hash = header.hash(); - let block = message::BlockData:: { + let block = message::BlockData::<$block> { hash, justification: signed.justification, header: Some(header), @@ -178,8 +149,8 @@ pub fn import_blocks( message_queue: None }; // import queue handles verification and importing it into the client - queue.import_blocks(BlockOrigin::File, vec![ - IncomingBlock:: { + $queue.import_blocks(BlockOrigin::File, vec![ + IncomingBlock::<$block> { hash: block.hash, header: block.header, body: block.body, @@ -208,7 +179,7 @@ pub fn import_blocks( let blocks_before = link.imported_blocks; let _ = futures03::future::poll_fn(|cx| { - queue.poll_actions(cx, &mut link); + $queue.poll_actions(cx, &mut link); std::task::Poll::Pending::> }).compat().poll(); if link.has_error { @@ -226,24 +197,21 @@ pub fn import_blocks( ); } if link.imported_blocks >= count { - info!("Imported {} blocks. Best: #{}", block_count, client.info().chain.best_number); + info!("Imported {} blocks. Best: #{}", block_count, $client.info().chain.best_number); Ok(Async::Ready(())) } else { Ok(Async::NotReady) } })) +}} } -/// Revert the chain. -pub fn revert_chain( - config: FactoryFullConfiguration, - blocks: FactoryBlockNumber -) -> error::Result<()> - where F: ServiceFactory, -{ - let client = new_client::(&config)?; - let reverted = client.revert(blocks)?; - let info = client.info().chain; +/// Revert the chain some number of blocks. +#[macro_export] +macro_rules! revert_chain { +($client:ident, $blocks:ident) => {{ + let reverted = $client.revert($blocks)?; + let info = $client.info().chain; if reverted.is_zero() { info!("There aren't any non-finalized blocks to revert."); @@ -251,11 +219,13 @@ pub fn revert_chain( info!("Reverted {} blocks. Best: #{} ({})", reverted, info.best_number, info.best_hash); } Ok(()) +}} } /// Build a chain spec json -pub fn build_spec(spec: ChainSpec, raw: bool) -> error::Result - where G: RuntimeGenesis, +pub fn build_spec(spec: ChainSpec, raw: bool) -> error::Result where + G: RuntimeGenesis, + E: Extension, { Ok(spec.to_json(raw)?) } diff --git a/core/service/src/components.rs b/core/service/src/components.rs deleted file mode 100644 index b88abd4a98b03e6811edb8103af73abdc4c90423..0000000000000000000000000000000000000000 --- a/core/service/src/components.rs +++ /dev/null @@ -1,761 +0,0 @@ -// Copyright 2017-2019 Parity Technologies (UK) Ltd. -// This file is part of Substrate. - -// Substrate 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. - -// Substrate 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 Substrate. If not, see . - -//! Substrate service components. - -use std::{sync::Arc, ops::Deref, ops::DerefMut}; -use serde::{Serialize, de::DeserializeOwned}; -use crate::chain_spec::ChainSpec; -use keystore::KeyStorePtr; -use client_db; -use client::{self, Client, runtime_api}; -use crate::{error, Service}; -use consensus_common::{import_queue::ImportQueue, SelectChain}; -use network::{ - self, OnDemand, FinalityProofProvider, NetworkStateInfo, config::BoxFinalityProofRequestBuilder -}; -use substrate_executor::{NativeExecutor, NativeExecutionDispatch}; -use transaction_pool::txpool::{self, Options as TransactionPoolOptions, Pool as TransactionPool}; -use sr_primitives::{ - BuildStorage, traits::{Block as BlockT, Header as HeaderT, ProvideRuntimeApi}, generic::BlockId -}; -use crate::config::Configuration; -use primitives::{Blake2Hasher, H256, traits::BareCryptoStorePtr}; -use rpc::{self, apis::system::SystemInfo}; -use futures::{prelude::*, future::Executor}; -use futures03::{FutureExt as _, channel::mpsc, compat::Compat}; - -// Type aliases. -// These exist mainly to avoid typing `::Foo` all over the code. - -/// Network service type for `Components`. -pub type NetworkService = network::NetworkService< - ComponentBlock, - <::Factory as ServiceFactory>::NetworkProtocol, - ComponentExHash ->; - -/// Code executor type for a factory. -pub type CodeExecutor = NativeExecutor<::RuntimeDispatch>; - -/// Full client backend type for a factory. -pub type FullBackend = client_db::Backend<::Block>; - -/// Full client executor type for a factory. -pub type FullExecutor = client::LocalCallExecutor< - client_db::Backend<::Block>, - CodeExecutor, ->; - -/// Light client backend type for a factory. -pub type LightBackend = client::light::backend::Backend< - client_db::light::LightStorage<::Block>, - network::OnDemand<::Block>, - Blake2Hasher, ->; - -/// Light client executor type for a factory. -pub type LightExecutor = client::light::call_executor::RemoteOrLocalCallExecutor< - ::Block, - client::light::backend::Backend< - client_db::light::LightStorage<::Block>, - network::OnDemand<::Block>, - Blake2Hasher - >, - client::light::call_executor::RemoteCallExecutor< - client::light::blockchain::Blockchain< - client_db::light::LightStorage<::Block>, - network::OnDemand<::Block> - >, - network::OnDemand<::Block>, - >, - client::LocalCallExecutor< - client::light::backend::Backend< - client_db::light::LightStorage<::Block>, - network::OnDemand<::Block>, - Blake2Hasher - >, - CodeExecutor - > ->; - -/// Full client type for a factory. -pub type FullClient = Client, FullExecutor, ::Block, ::RuntimeApi>; - -/// Light client type for a factory. -pub type LightClient = Client, LightExecutor, ::Block, ::RuntimeApi>; - -/// `ChainSpec` specialization for a factory. -pub type FactoryChainSpec = ChainSpec<::Genesis>; - -/// `Genesis` specialization for a factory. -pub type FactoryGenesis = ::Genesis; - -/// `Block` type for a factory. -pub type FactoryBlock = ::Block; - -/// `Extrinsic` type for a factory. -pub type FactoryExtrinsic = <::Block as BlockT>::Extrinsic; - -/// `Number` type for a factory. -pub type FactoryBlockNumber = < as BlockT>::Header as HeaderT>::Number; - -/// Full `Configuration` type for a factory. -pub type FactoryFullConfiguration = Configuration<::Configuration, FactoryGenesis>; - -/// Client type for `Components`. -pub type ComponentClient = Client< - ::Backend, - ::Executor, - FactoryBlock<::Factory>, - ::RuntimeApi, ->; - -/// A offchain workers storage backend type. -pub type ComponentOffchainStorage = < - ::Backend as client::backend::Backend, Blake2Hasher> ->::OffchainStorage; - -/// Block type for `Components` -pub type ComponentBlock = <::Factory as ServiceFactory>::Block; - -/// Extrinsic hash type for `Components` -pub type ComponentExHash = <::TransactionPoolApi as txpool::ChainApi>::Hash; - -/// Extrinsic type. -pub type ComponentExtrinsic = as BlockT>::Extrinsic; - -/// Extrinsic pool API type for `Components`. -pub type PoolApi = ::TransactionPoolApi; - -/// A set of traits for the runtime genesis config. -pub trait RuntimeGenesis: Serialize + DeserializeOwned + BuildStorage {} -impl RuntimeGenesis for T {} - -/// Something that can create and store initial session keys from given seeds. -pub trait InitialSessionKeys { - /// Generate the initial session keys for the given seeds and store them in - /// an internal keystore. - fn generate_initial_session_keys( - client: Arc>, - seeds: Vec, - ) -> error::Result<()>; -} - -impl InitialSessionKeys for C where - ComponentClient: ProvideRuntimeApi, - as ProvideRuntimeApi>::Api: session::SessionKeys>, -{ - fn generate_initial_session_keys( - client: Arc>, - seeds: Vec, - ) -> error::Result<()> { - session::generate_initial_session_keys(client, seeds).map_err(Into::into) - } -} - -/// Something that can start the RPC service. -pub trait StartRPC { - fn start_rpc( - client: Arc>, - system_send_back: mpsc::UnboundedSender>>, - system_info: SystemInfo, - task_executor: TaskExecutor, - transaction_pool: Arc>, - keystore: KeyStorePtr, - ) -> rpc::RpcHandler; -} - -impl StartRPC for C where - ComponentClient: ProvideRuntimeApi, - as ProvideRuntimeApi>::Api: - runtime_api::Metadata> + session::SessionKeys>, -{ - fn start_rpc( - client: Arc>, - system_send_back: mpsc::UnboundedSender>>, - rpc_system_info: SystemInfo, - task_executor: TaskExecutor, - transaction_pool: Arc>, - keystore: KeyStorePtr, - ) -> rpc::RpcHandler { - let subscriptions = rpc::apis::Subscriptions::new(task_executor.clone()); - let chain = rpc::apis::chain::Chain::new(client.clone(), subscriptions.clone()); - let state = rpc::apis::state::State::new(client.clone(), subscriptions.clone()); - let author = rpc::apis::author::Author::new( - client, - transaction_pool, - subscriptions, - keystore, - ); - let system = rpc::apis::system::System::new(rpc_system_info, system_send_back); - rpc::rpc_handler::, ComponentExHash, _, _, _, _>( - state, - chain, - author, - system, - ) - } -} - -/// Something that can maintain transaction pool on every imported block. -pub trait MaintainTransactionPool { - fn maintain_transaction_pool( - id: &BlockId>, - client: &ComponentClient, - transaction_pool: &TransactionPool, - ) -> error::Result<()>; -} - -fn maintain_transaction_pool( - id: &BlockId, - client: &Client, - transaction_pool: &TransactionPool, -) -> error::Result<()> where - Block: BlockT::Out>, - Backend: client::backend::Backend, - Client: ProvideRuntimeApi, - as ProvideRuntimeApi>::Api: runtime_api::TaggedTransactionQueue, - Executor: client::CallExecutor, - PoolApi: txpool::ChainApi, -{ - // Avoid calling into runtime if there is nothing to prune from the pool anyway. - if transaction_pool.status().is_empty() { - return Ok(()) - } - - if let Some(block) = client.block(id)? { - let parent_id = BlockId::hash(*block.block.header().parent_hash()); - let extrinsics = block.block.extrinsics(); - transaction_pool.prune(id, &parent_id, extrinsics).map_err(|e| format!("{:?}", e))?; - } - - Ok(()) -} - -impl MaintainTransactionPool for C where - ComponentClient: ProvideRuntimeApi, - as ProvideRuntimeApi>::Api: runtime_api::TaggedTransactionQueue>, -{ - fn maintain_transaction_pool( - id: &BlockId>, - client: &ComponentClient, - transaction_pool: &TransactionPool, - ) -> error::Result<()> { - maintain_transaction_pool(id, client, transaction_pool) - } -} - -pub trait OffchainWorker { - fn offchain_workers( - number: &FactoryBlockNumber, - offchain: &offchain::OffchainWorkers< - ComponentClient, - ComponentOffchainStorage, - ComponentBlock - >, - pool: &Arc>, - network_state: &Arc, - is_validator: bool, - ) -> error::Result + Send>>; -} - -impl OffchainWorker for C where - ComponentClient: ProvideRuntimeApi, - as ProvideRuntimeApi>::Api: offchain::OffchainWorkerApi>, -{ - fn offchain_workers( - number: &FactoryBlockNumber, - offchain: &offchain::OffchainWorkers< - ComponentClient, - ComponentOffchainStorage, - ComponentBlock - >, - pool: &Arc>, - network_state: &Arc, - is_validator: bool, - ) -> error::Result + Send>> { - let future = offchain.on_block_imported(number, pool, network_state.clone(), is_validator) - .map(|()| Ok(())); - Ok(Box::new(Compat::new(future))) - } -} - -/// The super trait that combines all required traits a `Service` needs to implement. -pub trait ServiceTrait: - Deref> - + Send - + 'static - + StartRPC - + MaintainTransactionPool - + OffchainWorker - + InitialSessionKeys -{} -impl ServiceTrait for T where - T: Deref> - + Send - + 'static - + StartRPC - + MaintainTransactionPool - + OffchainWorker - + InitialSessionKeys -{} - -/// Alias for a an implementation of `futures::future::Executor`. -pub type TaskExecutor = Arc + Send>> + Send + Sync>; - -/// A collection of types and methods to build a service on top of the substrate service. -pub trait ServiceFactory: 'static + Sized { - /// Block type. - type Block: BlockT; - /// The type that implements the runtime API. - type RuntimeApi: Send + Sync; - /// Network protocol extensions. - type NetworkProtocol: network::specialization::NetworkSpecialization; - /// Chain runtime. - type RuntimeDispatch: NativeExecutionDispatch + Send + Sync + 'static; - /// Extrinsic pool backend type for the full client. - type FullTransactionPoolApi: txpool::ChainApi::Hash, Block = Self::Block> + Send + 'static; - /// Extrinsic pool backend type for the light client. - type LightTransactionPoolApi: txpool::ChainApi::Hash, Block = Self::Block> + 'static; - /// Genesis configuration for the runtime. - type Genesis: RuntimeGenesis; - /// Other configuration for service members. - type Configuration: Default; - /// Extended full service type. - type FullService: ServiceTrait>; - /// Extended light service type. - type LightService: ServiceTrait>; - /// ImportQueue for full client - type FullImportQueue: ImportQueue + 'static; - /// ImportQueue for light clients - type LightImportQueue: ImportQueue + 'static; - /// The Fork Choice Strategy for the chain - type SelectChain: SelectChain + 'static; - - //TODO: replace these with a constructor trait. that TransactionPool implements. (#1242) - /// Extrinsic pool constructor for the full client. - fn build_full_transaction_pool(config: TransactionPoolOptions, client: Arc>) - -> Result, error::Error>; - /// Extrinsic pool constructor for the light client. - fn build_light_transaction_pool(config: TransactionPoolOptions, client: Arc>) - -> Result, error::Error>; - - /// Build network protocol. - fn build_network_protocol(config: &FactoryFullConfiguration) - -> Result; - - /// Build finality proof provider for serving network requests on full node. - fn build_finality_proof_provider( - client: Arc> - ) -> Result>>, error::Error>; - - /// Build the Fork Choice algorithm for full client - fn build_select_chain( - config: &mut FactoryFullConfiguration, - client: Arc>, - ) -> Result; - - /// Build full service. - fn new_full(config: FactoryFullConfiguration) - -> Result; - /// Build light service. - fn new_light(config: FactoryFullConfiguration) - -> Result; - - /// ImportQueue for a full client - fn build_full_import_queue( - config: &mut FactoryFullConfiguration, - _client: Arc>, - _select_chain: Self::SelectChain, - _transaction_pool: Option>>, - ) -> Result { - if let Some(name) = config.chain_spec.consensus_engine() { - match name { - _ => Err(format!("Chain Specification defines unknown consensus engine '{}'", name).into()) - } - - } else { - Err("Chain Specification doesn't contain any consensus_engine name".into()) - } - } - - /// ImportQueue for a light client - fn build_light_import_queue( - config: &mut FactoryFullConfiguration, - _client: Arc> - ) -> Result<(Self::LightImportQueue, BoxFinalityProofRequestBuilder), error::Error> { - if let Some(name) = config.chain_spec.consensus_engine() { - match name { - _ => Err(format!("Chain Specification defines unknown consensus engine '{}'", name).into()) - } - - } else { - Err("Chain Specification doesn't contain any consensus_engine name".into()) - } - } -} - -/// A collection of types and function to generalize over full / light client type. -pub trait Components: Sized + 'static { - /// Associated service factory. - type Factory: ServiceFactory; - /// Client backend. - type Backend: 'static + client::backend::Backend, Blake2Hasher>; - /// Client executor. - type Executor: 'static + client::CallExecutor, Blake2Hasher> + Send + Sync + Clone; - /// The type that implements the runtime API. - type RuntimeApi: Send + Sync; - /// A type that can start all runtime-dependent services. - type RuntimeServices: ServiceTrait; - // TODO: Traitify transaction pool and allow people to implement their own. (#1242) - /// Extrinsic pool type. - type TransactionPoolApi: 'static + txpool::ChainApi< - Hash = as BlockT>::Hash, - Block = FactoryBlock - >; - /// Our Import Queue - type ImportQueue: ImportQueue> + 'static; - /// The Fork Choice Strategy for the chain - type SelectChain: SelectChain>; - - /// Create client. - fn build_client( - config: &FactoryFullConfiguration, - executor: CodeExecutor, - keystore: Option, - ) -> Result< - ( - Arc>, - Option>>> - ), - error::Error - >; - - /// Create extrinsic pool. - fn build_transaction_pool(config: TransactionPoolOptions, client: Arc>) - -> Result, error::Error>; - - /// Build the queue that imports blocks from the network, and optionally a way for the network - /// to build requests for proofs of finality. - fn build_import_queue( - config: &mut FactoryFullConfiguration, - client: Arc>, - select_chain: Option, - _transaction_pool: Option>>, - ) -> Result<(Self::ImportQueue, Option>>), error::Error>; - - /// Finality proof provider for serving network requests. - fn build_finality_proof_provider( - client: Arc> - ) -> Result::Block>>>, error::Error>; - - /// Build fork choice selector - fn build_select_chain( - config: &mut FactoryFullConfiguration, - client: Arc> - ) -> Result, error::Error>; -} - -/// A struct that implement `Components` for the full client. -pub struct FullComponents { - service: Service>, -} - -impl FullComponents { - /// Create new `FullComponents` - pub fn new( - config: FactoryFullConfiguration - ) -> Result { - Ok( - Self { - service: Service::new(config)?, - } - ) - } -} - -impl Deref for FullComponents { - type Target = Service; - - fn deref(&self) -> &Self::Target { - &self.service - } -} - -impl DerefMut for FullComponents { - fn deref_mut(&mut self) -> &mut Service { - &mut self.service - } -} - -impl Future for FullComponents { - type Item = (); - type Error = super::Error; - - fn poll(&mut self) -> Poll { - self.service.poll() - } -} - -impl Executor + Send>> -for FullComponents { - fn execute( - &self, - future: Box + Send> - ) -> Result<(), futures::future::ExecuteError + Send>>> { - self.service.execute(future) - } -} - -impl Components for FullComponents { - type Factory = Factory; - type Executor = FullExecutor; - type Backend = FullBackend; - type TransactionPoolApi = ::FullTransactionPoolApi; - type ImportQueue = Factory::FullImportQueue; - type RuntimeApi = Factory::RuntimeApi; - type RuntimeServices = Factory::FullService; - type SelectChain = Factory::SelectChain; - - fn build_client( - config: &FactoryFullConfiguration, - executor: CodeExecutor, - keystore: Option, - ) -> Result< - (Arc>, Option>>>), - error::Error, - > - { - let db_settings = client_db::DatabaseSettings { - cache_size: config.database_cache_size.map(|u| u as usize), - state_cache_size: config.state_cache_size, - state_cache_child_ratio: - config.state_cache_child_ratio.map(|v| (v, 100)), - path: config.database_path.clone(), - pruning: config.pruning.clone(), - }; - - Ok(( - Arc::new( - client_db::new_client( - db_settings, - executor, - &config.chain_spec, - config.execution_strategies.clone(), - keystore, - )? - ), - None, - )) - } - - fn build_transaction_pool( - config: TransactionPoolOptions, - client: Arc> - ) -> Result, error::Error> { - Factory::build_full_transaction_pool(config, client) - } - - fn build_import_queue( - config: &mut FactoryFullConfiguration, - client: Arc>, - select_chain: Option, - transaction_pool: Option>>, - ) -> Result<(Self::ImportQueue, Option>>), error::Error> { - let select_chain = select_chain - .ok_or(error::Error::SelectChainRequired)?; - Factory::build_full_import_queue(config, client, select_chain, transaction_pool) - .map(|queue| (queue, None)) - } - - fn build_select_chain( - config: &mut FactoryFullConfiguration, - client: Arc> - ) -> Result, error::Error> { - Self::Factory::build_select_chain(config, client).map(Some) - } - - fn build_finality_proof_provider( - client: Arc> - ) -> Result::Block>>>, error::Error> { - Factory::build_finality_proof_provider(client) - } -} - -/// A struct that implement `Components` for the light client. -pub struct LightComponents { - service: Service>, -} - -impl LightComponents { - /// Create new `LightComponents` - pub fn new( - config: FactoryFullConfiguration, - ) -> Result { - Ok( - Self { - service: Service::new(config)?, - } - ) - } -} - -impl Deref for LightComponents { - type Target = Service; - - fn deref(&self) -> &Self::Target { - &self.service - } -} - -impl DerefMut for LightComponents { - fn deref_mut(&mut self) -> &mut Self::Target { - &mut self.service - } -} - -impl Future for LightComponents { - type Item = (); - type Error = super::Error; - - fn poll(&mut self) -> Poll { - self.service.poll() - } -} - -impl Executor + Send>> -for LightComponents { - fn execute( - &self, - future: Box + Send> - ) -> Result<(), futures::future::ExecuteError + Send>>> { - self.service.execute(future) - } -} - -impl Components for LightComponents { - type Factory = Factory; - type Executor = LightExecutor; - type Backend = LightBackend; - type TransactionPoolApi = ::LightTransactionPoolApi; - type ImportQueue = ::LightImportQueue; - type RuntimeApi = Factory::RuntimeApi; - type RuntimeServices = Factory::LightService; - type SelectChain = Factory::SelectChain; - - fn build_client( - config: &FactoryFullConfiguration, - executor: CodeExecutor, - _: Option, - ) - -> Result< - ( - Arc>, - Option>>> - ), error::Error> - { - let db_settings = client_db::DatabaseSettings { - cache_size: None, - state_cache_size: config.state_cache_size, - state_cache_child_ratio: - config.state_cache_child_ratio.map(|v| (v, 100)), - path: config.database_path.clone(), - pruning: config.pruning.clone(), - }; - - let db_storage = client_db::light::LightStorage::new(db_settings)?; - let light_blockchain = client::light::new_light_blockchain(db_storage); - let fetch_checker = Arc::new( - client::light::new_fetch_checker(light_blockchain.clone(), executor.clone()) - ); - let fetcher = Arc::new(network::OnDemand::new(fetch_checker)); - let client_backend = client::light::new_light_backend(light_blockchain, fetcher.clone()); - let client = client::light::new_light(client_backend, fetcher.clone(), &config.chain_spec, executor)?; - Ok((Arc::new(client), Some(fetcher))) - } - - fn build_transaction_pool(config: TransactionPoolOptions, client: Arc>) - -> Result, error::Error> - { - Factory::build_light_transaction_pool(config, client) - } - - fn build_import_queue( - config: &mut FactoryFullConfiguration, - client: Arc>, - _select_chain: Option, - _transaction_pool: Option>>, - ) -> Result<(Self::ImportQueue, Option>>), error::Error> { - Factory::build_light_import_queue(config, client) - .map(|(queue, builder)| (queue, Some(builder))) - } - - fn build_finality_proof_provider( - _client: Arc> - ) -> Result::Block>>>, error::Error> { - Ok(None) - } - fn build_select_chain( - _config: &mut FactoryFullConfiguration, - _client: Arc> - ) -> Result, error::Error> { - Ok(None) - } -} - -#[cfg(test)] -mod tests { - use super::*; - use consensus_common::BlockOrigin; - use substrate_test_runtime_client::{prelude::*, runtime::Transfer}; - - #[test] - fn should_remove_transactions_from_the_pool() { - let (client, longest_chain) = TestClientBuilder::new().build_with_longest_chain(); - let client = Arc::new(client); - let pool = TransactionPool::new(Default::default(), ::transaction_pool::ChainApi::new(client.clone())); - let transaction = Transfer { - amount: 5, - nonce: 0, - from: AccountKeyring::Alice.into(), - to: Default::default(), - }.into_signed_tx(); - let best = longest_chain.best_chain().unwrap(); - - // store the transaction in the pool - pool.submit_one(&BlockId::hash(best.hash()), transaction.clone()).unwrap(); - - // import the block - let mut builder = client.new_block(Default::default()).unwrap(); - builder.push(transaction.clone()).unwrap(); - let block = builder.bake().unwrap(); - let id = BlockId::hash(block.header().hash()); - client.import(BlockOrigin::Own, block).unwrap(); - - // fire notification - this should clean up the queue - assert_eq!(pool.status().ready, 1); - maintain_transaction_pool( - &id, - &client, - &pool, - ).unwrap(); - - // then - assert_eq!(pool.status().ready, 0); - assert_eq!(pool.status().future, 0); - } -} diff --git a/core/service/src/config.rs b/core/service/src/config.rs index 97eba357e3fead57a6fab1911bcffe192fb23094..c4690e53f7995ea01b256f9d97e12e3dd5f4a952 100644 --- a/core/service/src/config.rs +++ b/core/service/src/config.rs @@ -22,16 +22,14 @@ pub use network::config::{ExtTransport, NetworkConfiguration, Roles}; use std::{path::PathBuf, net::SocketAddr}; use transaction_pool; -use crate::chain_spec::ChainSpec; +use chain_spec::{ChainSpec, RuntimeGenesis, Extension, NoExtension}; use primitives::crypto::Protected; -use sr_primitives::BuildStorage; -use serde::{Serialize, de::DeserializeOwned}; use target_info::Target; use tel::TelemetryEndpoints; /// Service configuration. #[derive(Clone)] -pub struct Configuration { +pub struct Configuration { /// Implementation name pub impl_name: &'static str, /// Implementation version @@ -57,7 +55,7 @@ pub struct Configuration { /// Pruning settings. pub pruning: PruningMode, /// Chain configuration. - pub chain_spec: ChainSpec, + pub chain_spec: ChainSpec, /// Custom configuration. pub custom: C, /// Node name. @@ -95,9 +93,13 @@ pub struct Configuration { pub dev_key_seed: Option, } -impl Configuration { +impl Configuration where + C: Default, + G: RuntimeGenesis, + E: Extension, +{ /// Create default config for given chain spec. - pub fn default_with_spec(chain_spec: ChainSpec) -> Self { + pub fn default_with_spec(chain_spec: ChainSpec) -> Self { let mut configuration = Configuration { impl_name: "parity-substrate", impl_version: "0.0.0", diff --git a/core/service/src/lib.rs b/core/service/src/lib.rs index dc34a488535e59987f42a13255bb2ab5149276f4..fccf04d8a13452e2b22e71ededd5cbcdff628c87 100644 --- a/core/service/src/lib.rs +++ b/core/service/src/lib.rs @@ -19,13 +19,13 @@ #![warn(missing_docs)] -mod components; -mod chain_spec; pub mod config; +#[macro_use] pub mod chain_ops; pub mod error; use std::io; +use std::marker::PhantomData; use std::net::SocketAddr; use std::collections::HashMap; use std::sync::atomic::{AtomicBool, Ordering}; @@ -33,37 +33,32 @@ use std::time::{Duration, Instant}; use futures::sync::mpsc; use parking_lot::Mutex; -use client::{BlockchainEvents, backend::Backend, runtime_api::BlockT}; +use client::{runtime_api::BlockT, Client}; use exit_future::Signal; use futures::prelude::*; -use futures03::stream::{StreamExt as _, TryStreamExt as _}; -use keystore::Store as Keystore; -use network::{NetworkState, NetworkStateInfo}; -use log::{log, info, warn, debug, error, Level}; +use futures03::{ + future::{ready, FutureExt as _, TryFutureExt as _}, + stream::{StreamExt as _, TryStreamExt as _}, +}; +use network::{ + NetworkService, NetworkState, specialization::NetworkSpecialization, + Event, DhtEvent, PeerId, ReportHandle, +}; +use log::{log, warn, debug, error, Level}; use codec::{Encode, Decode}; +use primitives::{Blake2Hasher, H256}; use sr_primitives::generic::BlockId; -use sr_primitives::traits::{Header, NumberFor, SaturatedConversion}; -use substrate_executor::NativeExecutor; -use sysinfo::{get_current_pid, ProcessExt, System, SystemExt}; -use tel::{telemetry, SUBSTRATE_INFO}; +use sr_primitives::traits::NumberFor; pub use self::error::Error; +pub use self::builder::{ServiceBuilder, ServiceBuilderExport, ServiceBuilderImport, ServiceBuilderRevert}; pub use config::{Configuration, Roles, PruningMode}; -pub use chain_spec::{ChainSpec, Properties}; +pub use chain_spec::{ChainSpec, Properties, RuntimeGenesis, Extension as ChainSpecExtension}; pub use transaction_pool::txpool::{ self, Pool as TransactionPool, Options as TransactionPoolOptions, ChainApi, IntoPoolError }; pub use client::FinalityNotifications; - -pub use components::{ - ServiceFactory, FullBackend, FullExecutor, LightBackend, - LightExecutor, Components, PoolApi, ComponentClient, ComponentOffchainStorage, - ComponentBlock, FullClient, LightClient, FullComponents, LightComponents, - CodeExecutor, NetworkService, FactoryChainSpec, FactoryBlock, - FactoryFullConfiguration, RuntimeGenesis, FactoryGenesis, - ComponentExHash, ComponentExtrinsic, FactoryExtrinsic, InitialSessionKeys, -}; -use components::{StartRPC, MaintainTransactionPool, OffchainWorker}; +pub use rpc::Metadata as RpcMetadata; #[doc(hidden)] pub use std::{ops::Deref, result::Result, sync::Arc}; #[doc(hidden)] @@ -74,15 +69,15 @@ pub use futures::future::Executor; const DEFAULT_PROTOCOL_ID: &str = "sup"; /// Substrate service. -pub struct Service { - client: Arc>, - select_chain: Option, - network: Arc>, +pub struct NewService { + client: Arc, + select_chain: Option, + network: Arc, /// Sinks to propagate network status updates. network_status_sinks: Arc>, NetworkState + TNetStatus, NetworkState )>>>>, - transaction_pool: Arc>, + transaction_pool: Arc, /// A future that resolves when the service has exited, this is useful to /// make sure any internally spawned futures stop when the service does. exit: exit_future::Exit, @@ -99,44 +94,31 @@ pub struct Service { /// If spawning a background task is not possible, we instead push the task into this `Vec`. /// The elements must then be polled manually. to_poll: Vec + Send>>, - /// Configuration of this Service - config: FactoryFullConfiguration, - rpc_handlers: rpc::RpcHandler, + rpc_handlers: rpc_servers::RpcHandler, _rpc: Box, _telemetry: Option, _telemetry_on_connect_sinks: Arc>>>, - _offchain_workers: Option, - ComponentOffchainStorage, - ComponentBlock> - >>, + _offchain_workers: Option>, keystore: keystore::KeyStorePtr, + marker: PhantomData, } -/// Creates bare client without any networking. -pub fn new_client( - config: &FactoryFullConfiguration, -) -> Result>>, error::Error> { - let executor = NativeExecutor::new(config.default_heap_pages); - - components::FullComponents::::build_client( - config, - executor, - None, - ).map(|r| r.0) -} +/// Alias for a an implementation of `futures::future::Executor`. +pub type TaskExecutor = Arc + Send>> + Send + Sync>; /// An handle for spawning tasks in the service. #[derive(Clone)] pub struct SpawnTaskHandle { sender: mpsc::UnboundedSender + Send>>, + on_exit: exit_future::Exit, } impl Executor + Send>> for SpawnTaskHandle { fn execute( &self, - future: Box + Send> + future: Box + Send>, ) -> Result<(), futures::future::ExecuteError + Send>>> { + let future = Box::new(future.select(self.on_exit.clone()).then(|_| Ok(()))); if let Err(err) = self.sender.unbounded_send(future) { let kind = futures::future::ExecuteErrorKind::Shutdown; Err(futures::future::ExecuteError::new(kind, err.into_inner())) @@ -146,59 +128,40 @@ impl Executor + Send>> for SpawnTaskHandle } } -/// Stream of events for connection established to a telemetry server. -pub type TelemetryOnConnectNotifications = mpsc::UnboundedReceiver<()>; - -/// Used to hook on telemetry connection established events. -pub struct TelemetryOnConnect { - /// Event stream. - pub telemetry_connection_sinks: TelemetryOnConnectNotifications, -} - -impl Service { - /// Creates a new service. - pub fn new( - mut config: FactoryFullConfiguration, - ) -> Result { +macro_rules! new_impl { + ( + $block:ty, + $config:ident, + $build_components:expr, + $maintain_transaction_pool:expr, + $offchain_workers:expr, + $start_rpc:expr, + ) => {{ let (signal, exit) = exit_future::signal(); // List of asynchronous tasks to spawn. We collect them, then spawn them all at once. let (to_spawn_tx, to_spawn_rx) = mpsc::unbounded:: + Send>>(); - // Create client - let executor = NativeExecutor::new(config.default_heap_pages); - - let keystore = Keystore::open(config.keystore_path.clone(), config.keystore_password.clone())?; - - let (client, on_demand) = Components::build_client(&config, executor, Some(keystore.clone()))?; - let select_chain = Components::build_select_chain(&mut config, client.clone())?; - - let transaction_pool = Arc::new( - Components::build_transaction_pool(config.transaction_pool.clone(), client.clone())? - ); - let transaction_pool_adapter = Arc::new(TransactionPoolAdapter { - imports_external_transactions: !config.roles.is_light(), - pool: transaction_pool.clone(), - client: client.clone(), - }); - - let (import_queue, finality_proof_request_builder) = Components::build_import_queue( - &mut config, - client.clone(), - select_chain.clone(), - Some(transaction_pool.clone()), - )?; + // Create all the components. + let ( + client, + on_demand, + backend, + keystore, + select_chain, + import_queue, + finality_proof_request_builder, + finality_proof_provider, + network_protocol, + transaction_pool, + rpc_extensions, + dht_event_tx, + ) = $build_components(&$config)?; let import_queue = Box::new(import_queue); - let finality_proof_provider = Components::build_finality_proof_provider(client.clone())?; let chain_info = client.info().chain; - Components::RuntimeServices::generate_initial_session_keys( - client.clone(), - config.dev_key_seed.clone().map(|s| vec![s]).unwrap_or_default(), - )?; - - let version = config.full_version(); + let version = $config.full_version(); info!("Highest known block at #{}", chain_info.best_number); telemetry!( SUBSTRATE_INFO; @@ -207,10 +170,15 @@ impl Service { "best" => ?chain_info.best_hash ); - let network_protocol = ::build_network_protocol(&config)?; + let transaction_pool_adapter = Arc::new(TransactionPoolAdapter { + imports_external_transactions: !$config.roles.is_light(), + pool: transaction_pool.clone(), + client: client.clone(), + executor: Arc::new(SpawnTaskHandle { sender: to_spawn_tx.clone(), on_exit: exit.clone() }), + }); let protocol_id = { - let protocol_id_full = match config.chain_spec.protocol_id() { + let protocol_id_full = match $config.chain_spec.protocol_id() { Some(pid) => pid, None => { warn!("Using default protocol ID {:?} because none is configured in the \ @@ -222,9 +190,12 @@ impl Service { network::config::ProtocolId::from(protocol_id_full) }; + let block_announce_validator = + Box::new(consensus_common::block_validation::DefaultBlockAnnounceValidator::new(client.clone())); + let network_params = network::config::Params { - roles: config.roles, - network_config: config.network.clone(), + roles: $config.roles, + network_config: $config.network.clone(), chain: client.clone(), finality_proof_provider, finality_proof_request_builder, @@ -233,6 +204,7 @@ impl Service { import_queue, protocol_id, specialization: network_protocol, + block_announce_validator, }; let has_bootnodes = !network_params.network_config.boot_nodes.is_empty(); @@ -240,9 +212,8 @@ impl Service { let network = network_mut.service().clone(); let network_status_sinks = Arc::new(Mutex::new(Vec::new())); - #[allow(deprecated)] - let offchain_storage = client.backend().offchain_storage(); - let offchain_workers = match (config.offchain_worker, offchain_storage) { + let offchain_storage = backend.offchain_storage(); + let offchain_workers = match ($config.offchain_worker, offchain_storage) { (true, Some(db)) => { Some(Arc::new(offchain::OffchainWorkers::new(client.clone(), db))) }, @@ -260,23 +231,27 @@ impl Service { let offchain = offchain_workers.as_ref().map(Arc::downgrade); let to_spawn_tx_ = to_spawn_tx.clone(); let network_state_info: Arc = network.clone(); - let is_validator = config.roles.is_authority(); + let is_validator = $config.roles.is_authority(); let events = client.import_notification_stream() .map(|v| Ok::<_, ()>(v)).compat() .for_each(move |notification| { let number = *notification.header.number(); + let txpool = txpool.upgrade(); - if let (Some(txpool), Some(client)) = (txpool.upgrade(), wclient.upgrade()) { - Components::RuntimeServices::maintain_transaction_pool( + if let (Some(txpool), Some(client)) = (txpool.as_ref(), wclient.upgrade()) { + let future = $maintain_transaction_pool( &BlockId::hash(notification.hash), - &*client, + &client, &*txpool, + ¬ification.retracted, ).map_err(|e| warn!("Pool error processing new block: {:?}", e))?; + let _ = to_spawn_tx_.unbounded_send(future); } - if let (Some(txpool), Some(offchain)) = (txpool.upgrade(), offchain.as_ref().and_then(|o| o.upgrade())) { - let future = Components::RuntimeServices::offchain_workers( + let offchain = offchain.as_ref().and_then(|o| o.upgrade()); + if let (Some(txpool), Some(offchain)) = (txpool, offchain) { + let future = $offchain_workers( &number, &offchain, &txpool, @@ -298,6 +273,7 @@ impl Service { let network = Arc::downgrade(&network); let transaction_pool_ = transaction_pool.clone(); let events = transaction_pool.import_notification_stream() + .map(|v| Ok::<_, ()>(v)).compat() .for_each(move |_| { if let Some(network) = network.upgrade() { network.trigger_repropagate(); @@ -320,7 +296,7 @@ impl Service { let client_ = client.clone(); let mut sys = System::new(); let self_pid = get_current_pid().ok(); - let (netstat_tx, netstat_rx) = mpsc::unbounded::<(NetworkStatus>, NetworkState)>(); + let (netstat_tx, netstat_rx) = mpsc::unbounded::<(NetworkStatus<_>, NetworkState)>(); network_status_sinks.lock().push(netstat_tx); let tel_task = netstat_rx.for_each(move |(net_status, network_state)| { let info = client_.info(); @@ -332,9 +308,7 @@ impl Service { let bandwidth_download = net_status.average_download_per_sec; let bandwidth_upload = net_status.average_upload_per_sec; - #[allow(deprecated)] - let backend = (*client_).backend(); - let used_state_cache_size = match backend.used_state_cache_size(){ + let used_state_cache_size = match info.used_state_cache_size { Some(size) => size, None => 0, }; @@ -372,30 +346,34 @@ impl Service { // RPC let (system_rpc_tx, system_rpc_rx) = futures03::channel::mpsc::unbounded(); let gen_handler = || { - let system_info = rpc::apis::system::SystemInfo { - chain_name: config.chain_spec.name().into(), - impl_name: config.impl_name.into(), - impl_version: config.impl_version.into(), - properties: config.chain_spec.properties(), + let system_info = rpc::system::SystemInfo { + chain_name: $config.chain_spec.name().into(), + impl_name: $config.impl_name.into(), + impl_version: $config.impl_version.into(), + properties: $config.chain_spec.properties().clone(), }; - Components::RuntimeServices::start_rpc( + $start_rpc( client.clone(), + //light_components.clone(), system_rpc_tx.clone(), system_info.clone(), - Arc::new(SpawnTaskHandle { sender: to_spawn_tx.clone() }), + Arc::new(SpawnTaskHandle { sender: to_spawn_tx.clone(), on_exit: exit.clone() }), transaction_pool.clone(), + rpc_extensions.clone(), keystore.clone(), ) }; let rpc_handlers = gen_handler(); - let rpc = start_rpc_servers(&config, gen_handler)?; + let rpc = start_rpc_servers(&$config, gen_handler)?; + let _ = to_spawn_tx.unbounded_send(Box::new(build_network_future( network_mut, client.clone(), network_status_sinks.clone(), system_rpc_rx, - has_bootnodes + has_bootnodes, + dht_event_tx, ) .map_err(|_| ()) .select(exit.clone()) @@ -404,17 +382,17 @@ impl Service { let telemetry_connection_sinks: Arc>>> = Default::default(); // Telemetry - let telemetry = config.telemetry_endpoints.clone().map(|endpoints| { - let is_authority = config.roles.is_authority(); + let telemetry = $config.telemetry_endpoints.clone().map(|endpoints| { + let is_authority = $config.roles.is_authority(); let network_id = network.local_peer_id().to_base58(); - let name = config.name.clone(); - let impl_name = config.impl_name.to_owned(); + let name = $config.name.clone(); + let impl_name = $config.impl_name.to_owned(); let version = version.clone(); - let chain_name = config.chain_spec.name().to_owned(); + let chain_name = $config.chain_spec.name().to_owned(); let telemetry_connection_sinks_ = telemetry_connection_sinks.clone(); let telemetry = tel::init_telemetry(tel::TelemetryConfig { endpoints, - wasm_external_transport: config.telemetry_external_transport.take(), + wasm_external_transport: $config.telemetry_external_transport.take(), }); let future = telemetry.clone() .map(|ev| Ok::<_, ()>(ev)) @@ -444,7 +422,7 @@ impl Service { telemetry }); - Ok(Service { + Ok(NewService { client, network, network_status_sinks, @@ -456,121 +434,179 @@ impl Service { to_spawn_tx, to_spawn_rx, to_poll: Vec::new(), - config, rpc_handlers, _rpc: rpc, _telemetry: telemetry, _offchain_workers: offchain_workers, _telemetry_on_connect_sinks: telemetry_connection_sinks.clone(), keystore, + marker: PhantomData::<$block>, }) - } + }} +} - /// Returns a reference to the config passed at initialization. - pub fn config(&self) -> &FactoryFullConfiguration { - &self.config - } +mod builder; + +/// Abstraction over a Substrate service. +pub trait AbstractService: 'static + Future + + Executor + Send>> + Send { + /// Type of block of this chain. + type Block: BlockT; + /// Backend storage for the client. + type Backend: 'static + client::backend::Backend; + /// How to execute calls towards the runtime. + type CallExecutor: 'static + client::CallExecutor + Send + Sync + Clone; + /// API that the runtime provides. + type RuntimeApi: Send + Sync; + /// Chain selection algorithm. + type SelectChain: consensus_common::SelectChain; + /// API of the transaction pool. + type TransactionPoolApi: ChainApi; + /// Network specialization. + type NetworkSpecialization: NetworkSpecialization; + + /// Get event stream for telemetry connection established events. + fn telemetry_on_connect_stream(&self) -> mpsc::UnboundedReceiver<()>; + + /// return a shared instance of Telemetry (if enabled) + fn telemetry(&self) -> Option; + + /// Spawns a task in the background that runs the future passed as parameter. + fn spawn_task(&self, task: impl Future + Send + 'static); + + /// Spawns a task in the background that runs the future passed as + /// parameter. The given task is considered essential, i.e. if it errors we + /// trigger a service exit. + fn spawn_essential_task(&self, task: impl Future + Send + 'static); - /// Returns a reference to the config passed at initialization. + /// Returns a handle for spawning tasks. + fn spawn_task_handle(&self) -> SpawnTaskHandle; + + /// Returns the keystore that stores keys. + fn keystore(&self) -> keystore::KeyStorePtr; + + /// Starts an RPC query. /// - /// > **Note**: This method is currently necessary because we extract some elements from the - /// > configuration at the end of the service initialization. It is intended to be - /// > removed. - pub fn config_mut(&mut self) -> &mut FactoryFullConfiguration { - &mut self.config - } + /// The query is passed as a string and must be a JSON text similar to what an HTTP client + /// would for example send. + /// + /// Returns a `Future` that contains the optional response. + /// + /// If the request subscribes you to events, the `Sender` in the `RpcSession` object is used to + /// send back spontaneous events. + fn rpc_query(&self, mem: &RpcSession, request: &str) -> Box, Error = ()> + Send>; - /// Get event stream for telemetry connection established events. - pub fn telemetry_on_connect_stream(&self) -> TelemetryOnConnectNotifications { + /// Get shared client instance. + fn client(&self) -> Arc>; + + /// Get clone of select chain. + fn select_chain(&self) -> Option; + + /// Get shared network instance. + fn network(&self) -> Arc>; + + /// Returns a receiver that periodically receives a status of the network. + fn network_status(&self) -> mpsc::UnboundedReceiver<(NetworkStatus, NetworkState)>; + + /// Get shared transaction pool instance. + fn transaction_pool(&self) -> Arc>; + + /// Get a handle to a future that will resolve on exit. + fn on_exit(&self) -> ::exit_future::Exit; +} + +impl AbstractService for + NewService, TSc, NetworkStatus, + NetworkService, TransactionPool, TOc> +where + TBl: BlockT, + TBackend: 'static + client::backend::Backend, + TExec: 'static + client::CallExecutor + Send + Sync + Clone, + TRtApi: 'static + Send + Sync, + TSc: consensus_common::SelectChain + 'static + Clone + Send, + TExPoolApi: 'static + ChainApi, + TOc: 'static + Send + Sync, + TNetSpec: NetworkSpecialization, +{ + type Block = TBl; + type Backend = TBackend; + type CallExecutor = TExec; + type RuntimeApi = TRtApi; + type SelectChain = TSc; + type TransactionPoolApi = TExPoolApi; + type NetworkSpecialization = TNetSpec; + + fn telemetry_on_connect_stream(&self) -> mpsc::UnboundedReceiver<()> { let (sink, stream) = mpsc::unbounded(); self._telemetry_on_connect_sinks.lock().push(sink); stream } - /// Return a shared instance of Telemetry (if enabled) - pub fn telemetry(&self) -> Option { + fn telemetry(&self) -> Option { self._telemetry.as_ref().map(|t| t.clone()) } - /// Returns the keystore instance. - pub fn keystore(&self) -> keystore::KeyStorePtr { + fn keystore(&self) -> keystore::KeyStorePtr { self.keystore.clone() } - /// Spawns a task in the background that runs the future passed as parameter. - pub fn spawn_task(&self, task: impl Future + Send + 'static) { + fn spawn_task(&self, task: impl Future + Send + 'static) { + let task = task.select(self.on_exit()).then(|_| Ok(())); let _ = self.to_spawn_tx.unbounded_send(Box::new(task)); } - /// Spawns a task in the background that runs the future passed as - /// parameter. The given task is considered essential, i.e. if it errors we - /// trigger a service exit. - pub fn spawn_essential_task(&self, task: impl Future + Send + 'static) { + fn spawn_essential_task(&self, task: impl Future + Send + 'static) { let essential_failed = self.essential_failed.clone(); - let essential_task = Box::new(task.map_err(move |_| { + let essential_task = task.map_err(move |_| { error!("Essential task failed. Shutting down service."); essential_failed.store(true, Ordering::Relaxed); - })); + }); + let task = essential_task.select(self.on_exit()).then(|_| Ok(())); - let _ = self.to_spawn_tx.unbounded_send(essential_task); + let _ = self.to_spawn_tx.unbounded_send(Box::new(task)); } - /// Returns a handle for spawning tasks. - pub fn spawn_task_handle(&self) -> SpawnTaskHandle { + fn spawn_task_handle(&self) -> SpawnTaskHandle { SpawnTaskHandle { sender: self.to_spawn_tx.clone(), + on_exit: self.on_exit(), } } - /// Starts an RPC query. - /// - /// The query is passed as a string and must be a JSON text similar to what an HTTP client - /// would for example send. - /// - /// Returns a `Future` that contains the optional response. - /// - /// If the request subscribes you to events, the `Sender` in the `RpcSession` object is used to - /// send back spontaneous events. - pub fn rpc_query(&self, mem: &RpcSession, request: &str) - -> impl Future, Error = ()> - { - self.rpc_handlers.handle_request(request, mem.metadata.clone()) + fn rpc_query(&self, mem: &RpcSession, request: &str) -> Box, Error = ()> + Send> { + Box::new(self.rpc_handlers.handle_request(request, mem.metadata.clone())) } - /// Get shared client instance. - pub fn client(&self) -> Arc> { + fn client(&self) -> Arc> { self.client.clone() } - /// Get clone of select chain. - pub fn select_chain(&self) -> Option<::SelectChain> { + fn select_chain(&self) -> Option { self.select_chain.clone() } - /// Get shared network instance. - pub fn network(&self) -> Arc> { + fn network(&self) -> Arc> { self.network.clone() } - /// Returns a receiver that periodically receives a status of the network. - pub fn network_status(&self) -> mpsc::UnboundedReceiver<(NetworkStatus>, NetworkState)> { + fn network_status(&self) -> mpsc::UnboundedReceiver<(NetworkStatus, NetworkState)> { let (sink, stream) = mpsc::unbounded(); self.network_status_sinks.lock().push(sink); stream } - /// Get shared transaction pool instance. - pub fn transaction_pool(&self) -> Arc> { + fn transaction_pool(&self) -> Arc> { self.transaction_pool.clone() } - /// Get a handle to a future that will resolve on exit. - pub fn on_exit(&self) -> ::exit_future::Exit { + fn on_exit(&self) -> exit_future::Exit { self.exit.clone() } } -impl Future for Service where Components: components::Components { +impl Future for + NewService +{ type Item = (); type Error = Error; @@ -593,7 +629,7 @@ impl Future for Service where Components: components::Co // Polling all the `to_poll` futures. while let Some(pos) = self.to_poll.iter_mut().position(|t| t.poll().map(|t| t.is_ready()).unwrap_or(true)) { - self.to_poll.remove(pos); + let _ = self.to_poll.remove(pos); } // The service future never ends. @@ -601,8 +637,8 @@ impl Future for Service where Components: components::Co } } -impl Executor + Send>> - for Service where Components: components::Components +impl Executor + Send>> for + NewService { fn execute( &self, @@ -629,8 +665,9 @@ fn build_network_future< mut network: network::NetworkWorker, client: Arc, status_sinks: Arc, NetworkState)>>>>, - rpc_rx: futures03::channel::mpsc::UnboundedReceiver>, + rpc_rx: futures03::channel::mpsc::UnboundedReceiver>, should_have_peers: bool, + dht_event_tx: Option>, ) -> impl Future { // Compatibility shim while we're transitionning to stable Futures. // See https://github.com/paritytech/substrate/issues/3099 @@ -650,7 +687,7 @@ fn build_network_future< // We poll `imported_blocks_stream`. while let Ok(Async::Ready(Some(notification))) = imported_blocks_stream.poll() { - network.on_block_imported(notification.hash, notification.header); + network.on_block_imported(notification.hash, notification.header, Vec::new(), notification.is_new_best); } // We poll `finality_notification_stream`, but we only take the last event. @@ -665,16 +702,16 @@ fn build_network_future< // Poll the RPC requests and answer them. while let Ok(Async::Ready(Some(request))) = rpc_rx.poll() { match request { - rpc::apis::system::Request::Health(sender) => { - let _ = sender.send(rpc::apis::system::Health { + rpc::system::Request::Health(sender) => { + let _ = sender.send(rpc::system::Health { peers: network.peers_debug_info().len(), is_syncing: network.service().is_major_syncing(), should_have_peers, }); }, - rpc::apis::system::Request::Peers(sender) => { + rpc::system::Request::Peers(sender) => { let _ = sender.send(network.peers_debug_info().into_iter().map(|(peer_id, p)| - rpc::apis::system::PeerInfo { + rpc::system::PeerInfo { peer_id: peer_id.to_base58(), roles: format!("{:?}", p.roles), protocol_version: p.protocol_version, @@ -683,8 +720,10 @@ fn build_network_future< } ).collect()); } - rpc::apis::system::Request::NetworkState(sender) => { - let _ = sender.send(network.network_state()); + rpc::system::Request::NetworkState(sender) => { + if let Some(network_state) = serde_json::to_value(&network.network_state()).ok() { + let _ = sender.send(network_state); + } } }; } @@ -706,11 +745,21 @@ fn build_network_future< } // Main network polling. - match network.poll() { - Ok(Async::NotReady) => {} - Err(err) => warn!(target: "service", "Error in network: {:?}", err), - Ok(Async::Ready(())) => warn!(target: "service", "Network service finished"), - } + while let Ok(Async::Ready(Some(Event::Dht(event)))) = network.poll().map_err(|err| { + warn!(target: "service", "Error in network: {:?}", err); + }) { + // Given that core/authority-discovery is the only upper stack consumer of Dht events at the moment, all Dht + // events are being passed on to the authority-discovery module. In the future there might be multiple + // consumers of these events. In that case this would need to be refactored to properly dispatch the events, + // e.g. via a subscriber model. + if let Some(Err(e)) = dht_event_tx.as_ref().map(|c| c.clone().try_send(event)) { + if e.is_full() { + warn!(target: "service", "Dht event channel to authority discovery is full, dropping event."); + } else if e.is_disconnected() { + warn!(target: "service", "Dht event channel to authority discovery is disconnected, dropping event."); + } + } + }; // Now some diagnostic for performances. let polling_dur = before_polling.elapsed(); @@ -744,7 +793,9 @@ pub struct NetworkStatus { pub average_upload_per_sec: u64, } -impl Drop for Service where Components: components::Components { +impl Drop for + NewService +{ fn drop(&mut self) { debug!(target: "service", "Substrate service shutdown"); if let Some(signal) = self.signal.take() { @@ -755,8 +806,8 @@ impl Drop for Service where Components: components::Comp /// Starts RPC servers that run in their own thread, and returns an opaque object that keeps them alive. #[cfg(not(target_os = "unknown"))] -fn start_rpc_servers rpc::RpcHandler>( - config: &Configuration, +fn start_rpc_servers rpc_servers::RpcHandler>( + config: &Configuration, mut gen_handler: H ) -> Result, error::Error> { fn maybe_start_server(address: Option, mut start: F) -> Result, io::Error> @@ -780,11 +831,11 @@ fn start_rpc_servers rpc::RpcHandler>( Ok(Box::new(( maybe_start_server( config.rpc_http, - |address| rpc::start_http(address, config.rpc_cors.as_ref(), gen_handler()), + |address| rpc_servers::start_http(address, config.rpc_cors.as_ref(), gen_handler()), )?, maybe_start_server( config.rpc_ws, - |address| rpc::start_ws( + |address| rpc_servers::start_ws( address, config.rpc_ws_max_connections, config.rpc_cors.as_ref(), @@ -796,8 +847,8 @@ fn start_rpc_servers rpc::RpcHandler>( /// Starts RPC servers that run in their own thread, and returns an opaque object that keeps them alive. #[cfg(target_os = "unknown")] -fn start_rpc_servers rpc::RpcHandler>( - _: &Configuration, +fn start_rpc_servers components::RpcHandler>( + _: &Configuration, _: H ) -> Result, error::Error> { Ok(Box::new(())) @@ -818,7 +869,7 @@ impl RpcSession { /// The `RpcSession` must be kept alive in order to receive messages on the sender. pub fn new(sender: mpsc::Sender) -> RpcSession { RpcSession { - metadata: rpc::Metadata::new(sender), + metadata: sender.into(), } } } @@ -828,6 +879,7 @@ pub struct TransactionPoolAdapter { imports_external_transactions: bool, pool: Arc

, client: Arc, + executor: TaskExecutor, } /// Get transactions for propagation. @@ -838,7 +890,7 @@ fn transactions_to_propagate(pool: &TransactionPool) where PoolApi: ChainApi, B: BlockT, - H: std::hash::Hash + Eq + sr_primitives::traits::Member + serde::Serialize, + H: std::hash::Hash + Eq + sr_primitives::traits::Member + sr_primitives::traits::MaybeSerialize, E: txpool::error::IntoPoolError + From, { pool.ready() @@ -855,47 +907,49 @@ impl network::TransactionPool for TransactionPoolAdapter> where C: network::ClientHandle + Send + Sync, - PoolApi: ChainApi, + PoolApi: 'static + ChainApi, B: BlockT, - H: std::hash::Hash + Eq + sr_primitives::traits::Member + serde::Serialize, + H: std::hash::Hash + Eq + sr_primitives::traits::Member + sr_primitives::traits::MaybeSerialize, E: txpool::error::IntoPoolError + From, { fn transactions(&self) -> Vec<(H, ::Extrinsic)> { transactions_to_propagate(&self.pool) } - fn import(&self, transaction: &::Extrinsic) -> Option { + fn hash_of(&self, transaction: &B::Extrinsic) -> H { + self.pool.hash_of(transaction) + } + + fn import(&self, report_handle: ReportHandle, who: PeerId, reputation_change: i32, transaction: B::Extrinsic) { if !self.imports_external_transactions { debug!("Transaction rejected"); - return None; + return; } let encoded = transaction.encode(); match Decode::decode(&mut &encoded[..]) { Ok(uxt) => { let best_block_id = BlockId::hash(self.client.info().chain.best_hash); - match self.pool.submit_one(&best_block_id, uxt) { - Ok(hash) => Some(hash), - Err(e) => match e.into_pool_error() { - Ok(txpool::error::Error::AlreadyImported(hash)) => { - hash.downcast::().ok() - .map(|x| x.as_ref().clone()) - }, - Ok(e) => { - debug!("Error adding transaction to the pool: {:?}", e); - None - }, - Err(e) => { - debug!("Error converting pool error: {:?}", e); - None - }, - } + let import_future = self.pool.submit_one(&best_block_id, uxt); + let import_future = import_future + .then(move |import_result| { + match import_result { + Ok(_) => report_handle.report_peer(who, reputation_change), + Err(e) => match e.into_pool_error() { + Ok(txpool::error::Error::AlreadyImported(_)) => (), + Ok(e) => debug!("Error adding transaction to the pool: {:?}", e), + Err(e) => debug!("Error converting pool error: {:?}", e), + } + } + ready(Ok(())) + }) + .compat(); + + if let Err(e) = self.executor.execute(Box::new(import_future)) { + warn!("Error scheduling extrinsic import: {:?}", e); } } - Err(e) => { - debug!("Error decoding transaction {}", e); - None - } + Err(e) => debug!("Error decoding transaction {}", e), } } @@ -904,210 +958,10 @@ where } } -/// Constructs a service factory with the given name that implements the `ServiceFactory` trait. -/// The required parameters are required to be given in the exact order. Some parameters are followed -/// by `{}` blocks. These blocks are required and used to initialize the given parameter. -/// In these block it is required to write a closure that takes the same number of arguments, -/// the corresponding function in the `ServiceFactory` trait provides. -/// -/// # Example -/// -/// ``` -/// # use substrate_service::{ -/// # construct_service_factory, Service, FullBackend, FullExecutor, LightBackend, LightExecutor, -/// # FullComponents, LightComponents, FactoryFullConfiguration, FullClient -/// # }; -/// # use transaction_pool::{self, txpool::{Pool as TransactionPool}}; -/// # use network::{config::DummyFinalityProofRequestBuilder, construct_simple_protocol}; -/// # use client::{self, LongestChain}; -/// # use consensus_common::import_queue::{BasicQueue, Verifier}; -/// # use consensus_common::{BlockOrigin, BlockImportParams, well_known_cache_keys::Id as CacheKeyId}; -/// # use node_runtime::{GenesisConfig, RuntimeApi}; -/// # use std::sync::Arc; -/// # use node_primitives::Block; -/// # use babe_primitives::AuthorityPair as BabePair; -/// # use grandpa_primitives::AuthorityPair as GrandpaPair; -/// # use sr_primitives::Justification; -/// # use sr_primitives::traits::Block as BlockT; -/// # use grandpa; -/// # construct_simple_protocol! { -/// # pub struct NodeProtocol where Block = Block { } -/// # } -/// # struct MyVerifier; -/// # impl Verifier for MyVerifier { -/// # fn verify( -/// # &mut self, -/// # origin: BlockOrigin, -/// # header: B::Header, -/// # justification: Option, -/// # body: Option>, -/// # ) -> Result<(BlockImportParams, Option)>>), String> { -/// # unimplemented!(); -/// # } -/// # } -/// type FullChainApi = transaction_pool::ChainApi< -/// client::Client, FullExecutor, Block, RuntimeApi>, Block>; -/// type LightChainApi = transaction_pool::ChainApi< -/// client::Client, LightExecutor, Block, RuntimeApi>, Block>; -/// -/// construct_service_factory! { -/// struct Factory { -/// // Declare the block type -/// Block = Block, -/// RuntimeApi = RuntimeApi, -/// // Declare the network protocol and give an initializer. -/// NetworkProtocol = NodeProtocol { |config| Ok(NodeProtocol::new()) }, -/// RuntimeDispatch = node_executor::Executor, -/// FullTransactionPoolApi = FullChainApi -/// { |config, client| Ok(TransactionPool::new(config, transaction_pool::ChainApi::new(client))) }, -/// LightTransactionPoolApi = LightChainApi -/// { |config, client| Ok(TransactionPool::new(config, transaction_pool::ChainApi::new(client))) }, -/// Genesis = GenesisConfig, -/// Configuration = (), -/// FullService = FullComponents -/// { |config| >::new(config) }, -/// // Setup as Consensus Authority (if the role and key are given) -/// AuthoritySetup = { -/// |service: Self::FullService| { -/// Ok(service) -/// }}, -/// LightService = LightComponents -/// { |config| >::new(config) }, -/// FullImportQueue = BasicQueue -/// { |_, client, _, _| Ok(BasicQueue::new(MyVerifier, Box::new(client), None, None)) }, -/// LightImportQueue = BasicQueue -/// { |_, client| { -/// let fprb = Box::new(DummyFinalityProofRequestBuilder::default()) as Box<_>; -/// Ok((BasicQueue::new(MyVerifier, Box::new(client), None, None), fprb)) -/// }}, -/// SelectChain = LongestChain, Self::Block> -/// { |config: &FactoryFullConfiguration, client: Arc>| { -/// #[allow(deprecated)] -/// Ok(LongestChain::new(client.backend().clone())) -/// }}, -/// FinalityProofProvider = { |client: Arc>| { -/// Ok(Some(Arc::new(grandpa::FinalityProofProvider::new(client.clone(), client)) as _)) -/// }}, -/// } -/// } -/// ``` -#[macro_export] -macro_rules! construct_service_factory { - ( - $(#[$attr:meta])* - struct $name:ident { - Block = $block:ty, - RuntimeApi = $runtime_api:ty, - NetworkProtocol = $protocol:ty { $( $protocol_init:tt )* }, - RuntimeDispatch = $dispatch:ty, - FullTransactionPoolApi = $full_transaction:ty { $( $full_transaction_init:tt )* }, - LightTransactionPoolApi = $light_transaction:ty { $( $light_transaction_init:tt )* }, - Genesis = $genesis:ty, - Configuration = $config:ty, - FullService = $full_service:ty { $( $full_service_init:tt )* }, - AuthoritySetup = { $( $authority_setup:tt )* }, - LightService = $light_service:ty { $( $light_service_init:tt )* }, - FullImportQueue = $full_import_queue:ty - { $( $full_import_queue_init:tt )* }, - LightImportQueue = $light_import_queue:ty - { $( $light_import_queue_init:tt )* }, - SelectChain = $select_chain:ty - { $( $select_chain_init:tt )* }, - FinalityProofProvider = { $( $finality_proof_provider_init:tt )* }, - } - ) => { - $( #[$attr] )* - pub struct $name {} - - #[allow(unused_variables)] - impl $crate::ServiceFactory for $name { - type Block = $block; - type RuntimeApi = $runtime_api; - type NetworkProtocol = $protocol; - type RuntimeDispatch = $dispatch; - type FullTransactionPoolApi = $full_transaction; - type LightTransactionPoolApi = $light_transaction; - type Genesis = $genesis; - type Configuration = $config; - type FullService = $full_service; - type LightService = $light_service; - type FullImportQueue = $full_import_queue; - type LightImportQueue = $light_import_queue; - type SelectChain = $select_chain; - - fn build_full_transaction_pool( - config: $crate::TransactionPoolOptions, - client: $crate::Arc<$crate::FullClient> - ) -> $crate::Result<$crate::TransactionPool, $crate::Error> - { - ( $( $full_transaction_init )* ) (config, client) - } - - fn build_light_transaction_pool( - config: $crate::TransactionPoolOptions, - client: $crate::Arc<$crate::LightClient> - ) -> $crate::Result<$crate::TransactionPool, $crate::Error> - { - ( $( $light_transaction_init )* ) (config, client) - } - - fn build_network_protocol(config: &$crate::FactoryFullConfiguration) - -> $crate::Result - { - ( $( $protocol_init )* ) (config) - } - - fn build_select_chain( - config: &mut $crate::FactoryFullConfiguration, - client: Arc<$crate::FullClient> - ) -> $crate::Result { - ( $( $select_chain_init )* ) (config, client) - } - - fn build_full_import_queue( - config: &mut $crate::FactoryFullConfiguration, - client: $crate::Arc<$crate::FullClient>, - select_chain: Self::SelectChain, - transaction_pool: Option>>, - ) -> $crate::Result { - ( $( $full_import_queue_init )* ) (config, client, select_chain, transaction_pool) - } - - fn build_light_import_queue( - config: &mut FactoryFullConfiguration, - client: Arc<$crate::LightClient>, - ) -> Result<(Self::LightImportQueue, $crate::BoxFinalityProofRequestBuilder<$block>), $crate::Error> { - ( $( $light_import_queue_init )* ) (config, client) - } - - fn build_finality_proof_provider( - client: Arc<$crate::FullClient> - ) -> Result>>, $crate::Error> { - ( $( $finality_proof_provider_init )* ) (client) - } - - fn new_light( - config: $crate::FactoryFullConfiguration - ) -> $crate::Result - { - ( $( $light_service_init )* ) (config) - } - - fn new_full( - config: $crate::FactoryFullConfiguration - ) -> Result - { - ( $( $full_service_init )* ) (config).and_then(|service| { - ($( $authority_setup )*)(service) - }) - } - } - } -} - #[cfg(test)] mod tests { use super::*; + use futures03::executor::block_on; use consensus_common::SelectChain; use sr_primitives::traits::BlindCheckable; use substrate_test_runtime_client::{prelude::*, runtime::{Extrinsic, Transfer}}; @@ -1119,7 +973,7 @@ mod tests { let client = Arc::new(client); let pool = Arc::new(TransactionPool::new( Default::default(), - transaction_pool::ChainApi::new(client.clone()) + transaction_pool::FullChainApi::new(client.clone()) )); let best = longest_chain.best_chain().unwrap(); let transaction = Transfer { @@ -1128,8 +982,8 @@ mod tests { from: AccountKeyring::Alice.into(), to: Default::default(), }.into_signed_tx(); - pool.submit_one(&BlockId::hash(best.hash()), transaction.clone()).unwrap(); - pool.submit_one(&BlockId::hash(best.hash()), Extrinsic::IncludeData(vec![1])).unwrap(); + block_on(pool.submit_one(&BlockId::hash(best.hash()), transaction.clone())).unwrap(); + block_on(pool.submit_one(&BlockId::hash(best.hash()), Extrinsic::IncludeData(vec![1]))).unwrap(); assert_eq!(pool.status().ready, 2); // when diff --git a/core/service/test/Cargo.toml b/core/service/test/Cargo.toml index aa3dddfc1851e77580fad547ee561d404c0c65d1..b4651da7a75e8f6c1e93c54e19465ca445e962aa 100644 --- a/core/service/test/Cargo.toml +++ b/core/service/test/Cargo.toml @@ -5,12 +5,13 @@ authors = ["Parity Technologies "] edition = "2018" [dependencies] -tempdir = "0.3" -tokio = "0.1.7" -futures = "0.1" -log = "0.4" -env_logger = "0.6" -fdlimit = "0.1" +tempdir = "0.3.7" +tokio = "0.1.22" +futures = "0.1.29" +log = "0.4.8" +env_logger = "0.6.2" +fdlimit = "0.1.1" +futures03 = { package = "futures-preview", version = "=0.3.0-alpha.19", features = ["compat"] } service = { package = "substrate-service", path = "../../../core/service" } network = { package = "substrate-network", path = "../../../core/network" } consensus = { package = "substrate-consensus-common", path = "../../../core/consensus/common" } diff --git a/core/service/test/src/lib.rs b/core/service/test/src/lib.rs index 1b3c43dae74bbfd446e64f5470b9c4b271d06064..2d064f965bb27a627e9776b97707b2b217112f88 100644 --- a/core/service/test/src/lib.rs +++ b/core/service/test/src/lib.rs @@ -20,39 +20,36 @@ use std::iter; use std::sync::{Arc, Mutex, MutexGuard}; use std::net::Ipv4Addr; use std::time::Duration; -use std::collections::HashMap; use log::info; use futures::{Future, Stream, Poll}; use tempdir::TempDir; use tokio::{runtime::Runtime, prelude::FutureExt}; use tokio::timer::Interval; use service::{ - ServiceFactory, + AbstractService, + ChainSpec, Configuration, - FactoryFullConfiguration, - FactoryChainSpec, Roles, - FactoryExtrinsic, + Error, }; use network::{multiaddr, Multiaddr}; use network::config::{NetworkConfiguration, TransportConfig, NodeKeyConfig, Secret, NonReservedPeerMode}; -use sr_primitives::generic::BlockId; -use consensus::{BlockImportParams, BlockImport}; +use sr_primitives::{generic::BlockId, traits::Block as BlockT}; /// Maximum duration of single wait call. const MAX_WAIT_TIME: Duration = Duration::from_secs(60 * 3); -struct TestNet { +struct TestNet { runtime: Runtime, - authority_nodes: Vec<(usize, SyncService, Multiaddr)>, - full_nodes: Vec<(usize, SyncService, Multiaddr)>, - light_nodes: Vec<(usize, SyncService, Multiaddr)>, - chain_spec: FactoryChainSpec, + authority_nodes: Vec<(usize, SyncService, U, Multiaddr)>, + full_nodes: Vec<(usize, SyncService, U, Multiaddr)>, + light_nodes: Vec<(usize, SyncService, Multiaddr)>, + chain_spec: ChainSpec, base_port: u16, nodes: usize, } -/// Wraps around an `Arc>` and implements `Future`. +/// Wraps around an `Arc` and implements `Future`. pub struct SyncService(Arc>); impl SyncService { @@ -82,22 +79,24 @@ impl> Future for SyncService { } } -impl TestNet { +impl TestNet +where F: Send + 'static, L: Send +'static, U: Clone + Send + 'static +{ pub fn run_until_all_full( &mut self, full_predicate: FP, light_predicate: LP, ) where - FP: Send + Fn(usize, &SyncService) -> bool + 'static, - LP: Send + Fn(usize, &SyncService) -> bool + 'static, + FP: Send + Fn(usize, &SyncService) -> bool + 'static, + LP: Send + Fn(usize, &SyncService) -> bool + 'static, { let full_nodes = self.full_nodes.clone(); let light_nodes = self.light_nodes.clone(); let interval = Interval::new_interval(Duration::from_millis(100)) .map_err(|_| ()) .for_each(move |_| { - let full_ready = full_nodes.iter().all(|&(ref id, ref service, _)| + let full_ready = full_nodes.iter().all(|&(ref id, ref service, _, _)| full_predicate(*id, service) ); @@ -125,14 +124,14 @@ impl TestNet { } } -fn node_config ( +fn node_config ( index: usize, - spec: &FactoryChainSpec, + spec: &ChainSpec, role: Roles, key_seed: Option, base_port: u16, root: &TempDir, -) -> FactoryFullConfiguration +) -> Configuration<(), G, E> { let root = root.path().join(format!("node-{}", index)); @@ -194,18 +193,22 @@ fn node_config ( } } -impl TestNet where - F::FullService: Future, - F::LightService: Future, +impl TestNet where + F: AbstractService, + L: AbstractService, + E: Clone, { fn new( temp: &TempDir, - spec: FactoryChainSpec, - full: usize, - light: usize, - authorities: Vec, + spec: ChainSpec, + full: impl Iterator) -> Result<(F, U), Error>>, + light: impl Iterator) -> Result>, + authorities: impl Iterator) -> Result<(F, U), Error> + )>, base_port: u16 - ) -> TestNet { + ) -> TestNet { let _ = env_logger::try_init(); fdlimit::raise_fd_limit(); let runtime = Runtime::new().expect("Error creating tokio runtime"); @@ -222,85 +225,113 @@ impl TestNet where net } - fn insert_nodes(&mut self, temp: &TempDir, full: usize, light: usize, authorities: Vec) { - let mut nodes = self.nodes; - let base_port = self.base_port; - let spec = &self.chain_spec; + fn insert_nodes( + &mut self, + temp: &TempDir, + full: impl Iterator) -> Result<(F, U), Error>>, + light: impl Iterator) -> Result>, + authorities: impl Iterator) -> Result<(F, U), Error>)> + ) { let executor = self.runtime.executor(); - self.authority_nodes.extend(authorities.iter().enumerate().map(|(index, key)| { - let node_config = node_config::( - index, - &spec, + + for (key, authority) in authorities { + let node_config = node_config( + self.nodes, + &self.chain_spec, Roles::AUTHORITY, - Some(key.clone()), - base_port, + Some(key), + self.base_port, &temp, ); let addr = node_config.network.listen_addresses.iter().next().unwrap().clone(); - let service = SyncService::from(F::new_full(node_config).expect("Error creating test node service")); + let (service, user_data) = authority(node_config).expect("Error creating test node service"); + let service = SyncService::from(service); executor.spawn(service.clone().map_err(|_| ())); let addr = addr.with(multiaddr::Protocol::P2p(service.get().network().local_peer_id().into())); - ((index + nodes), service, addr) - })); - nodes += authorities.len(); + self.authority_nodes.push((self.nodes, service, user_data, addr)); + self.nodes += 1; + } - self.full_nodes.extend((nodes..nodes + full).map(|index| { - let node_config = node_config::(index, &spec, Roles::FULL, None, base_port, &temp); + for full in full { + let node_config = node_config(self.nodes, &self.chain_spec, Roles::FULL, None, self.base_port, &temp); let addr = node_config.network.listen_addresses.iter().next().unwrap().clone(); - let service = SyncService::from(F::new_full(node_config).expect("Error creating test node service")); + let (service, user_data) = full(node_config).expect("Error creating test node service"); + let service = SyncService::from(service); executor.spawn(service.clone().map_err(|_| ())); let addr = addr.with(multiaddr::Protocol::P2p(service.get().network().local_peer_id().into())); - (index, service, addr) - })); - nodes += full; + self.full_nodes.push((self.nodes, service, user_data, addr)); + self.nodes += 1; + } - self.light_nodes.extend((nodes..nodes + light).map(|index| { - let node_config = node_config::(index, &spec, Roles::LIGHT, None, base_port, &temp); + for light in light { + let node_config = node_config(self.nodes, &self.chain_spec, Roles::LIGHT, None, self.base_port, &temp); let addr = node_config.network.listen_addresses.iter().next().unwrap().clone(); - let service = SyncService::from(F::new_light(node_config).expect("Error creating test node service")); + let service = SyncService::from(light(node_config).expect("Error creating test node service")); executor.spawn(service.clone().map_err(|_| ())); let addr = addr.with(multiaddr::Protocol::P2p(service.get().network().local_peer_id().into())); - (index, service, addr) - })); - nodes += light; - - self.nodes = nodes; + self.light_nodes.push((self.nodes, service, addr)); + self.nodes += 1; + } } } -pub fn connectivity(spec: FactoryChainSpec) where - F::FullService: Future, - F::LightService: Future, +pub fn connectivity( + spec: ChainSpec, + full_builder: Fb, + light_builder: Lb, + light_node_interconnectivity: bool, // should normally be false, unless the light nodes + // aren't actually light. +) where + E: Clone, + Fb: Fn(Configuration<(), G, E>) -> Result, + F: AbstractService, + Lb: Fn(Configuration<(), G, E>) -> Result, + L: AbstractService, { const NUM_FULL_NODES: usize = 5; const NUM_LIGHT_NODES: usize = 5; + + let expected_full_connections = NUM_FULL_NODES - 1 + NUM_LIGHT_NODES; + let expected_light_connections = if light_node_interconnectivity { + expected_full_connections + } else { + NUM_FULL_NODES + }; + { let temp = TempDir::new("substrate-connectivity-test").expect("Error creating test dir"); let runtime = { - let mut network = TestNet::::new( + let mut network = TestNet::new( &temp, spec.clone(), - NUM_FULL_NODES, - NUM_LIGHT_NODES, - vec![], + (0..NUM_FULL_NODES).map(|_| { |cfg| full_builder(cfg).map(|s| (s, ())) }), + (0..NUM_LIGHT_NODES).map(|_| { |cfg| light_builder(cfg) }), + // Note: this iterator is empty but we can't just use `iter::empty()`, otherwise + // the type of the closure cannot be inferred. + (0..0).map(|_| (String::new(), { |cfg| full_builder(cfg).map(|s| (s, ())) })), 30400, ); info!("Checking star topology"); - let first_address = network.full_nodes[0].2.clone(); - for (_, service, _) in network.full_nodes.iter().skip(1) { - service.get().network().add_reserved_peer(first_address.to_string()).expect("Error adding reserved peer"); + let first_address = network.full_nodes[0].3.clone(); + for (_, service, _, _) in network.full_nodes.iter().skip(1) { + service.get().network().add_reserved_peer(first_address.to_string()) + .expect("Error adding reserved peer"); } for (_, service, _) in network.light_nodes.iter() { - service.get().network().add_reserved_peer(first_address.to_string()).expect("Error adding reserved peer"); + service.get().network().add_reserved_peer(first_address.to_string()) + .expect("Error adding reserved peer"); } + network.run_until_all_full( - |_index, service| service.get().network().num_connected() == NUM_FULL_NODES - 1 - + NUM_LIGHT_NODES, - |_index, service| service.get().network().num_connected() == NUM_FULL_NODES, + move |_index, service| service.get().network().num_connected() + == expected_full_connections, + move |_index, service| service.get().network().num_connected() + == expected_light_connections, ); + network.runtime }; @@ -311,76 +342,92 @@ pub fn connectivity(spec: FactoryChainSpec) where { let temp = TempDir::new("substrate-connectivity-test").expect("Error creating test dir"); { - let mut network = TestNet::::new( + let mut network = TestNet::new( &temp, spec, - NUM_FULL_NODES, - NUM_LIGHT_NODES, - vec![], + (0..NUM_FULL_NODES).map(|_| { |cfg| full_builder(cfg).map(|s| (s, ())) }), + (0..NUM_LIGHT_NODES).map(|_| { |cfg| light_builder(cfg) }), + // Note: this iterator is empty but we can't just use `iter::empty()`, otherwise + // the type of the closure cannot be inferred. + (0..0).map(|_| (String::new(), { |cfg| full_builder(cfg).map(|s| (s, ())) })), 30400, ); info!("Checking linked topology"); - let mut address = network.full_nodes[0].2.clone(); + let mut address = network.full_nodes[0].3.clone(); let max_nodes = std::cmp::max(NUM_FULL_NODES, NUM_LIGHT_NODES); for i in 0..max_nodes { if i != 0 { - if let Some((_, service, node_id)) = network.full_nodes.get(i) { - service.get().network().add_reserved_peer(address.to_string()).expect("Error adding reserved peer"); + if let Some((_, service, _, node_id)) = network.full_nodes.get(i) { + service.get().network().add_reserved_peer(address.to_string()) + .expect("Error adding reserved peer"); address = node_id.clone(); } } if let Some((_, service, node_id)) = network.light_nodes.get(i) { - service.get().network().add_reserved_peer(address.to_string()).expect("Error adding reserved peer"); + service.get().network().add_reserved_peer(address.to_string()) + .expect("Error adding reserved peer"); address = node_id.clone(); } } + network.run_until_all_full( - |_index, service| service.get().network().num_connected() == NUM_FULL_NODES - 1 - + NUM_LIGHT_NODES, - |_index, service| service.get().network().num_connected() == NUM_FULL_NODES, + move |_index, service| service.get().network().num_connected() + == expected_full_connections, + move |_index, service| service.get().network().num_connected() + == expected_light_connections, ); } temp.close().expect("Error removing temp dir"); } } -pub fn sync(spec: FactoryChainSpec, mut block_factory: B, mut extrinsic_factory: E) where - F: ServiceFactory, - F::FullService: Future, - F::LightService: Future, - B: FnMut(&SyncService) -> BlockImportParams, - E: FnMut(&SyncService) -> FactoryExtrinsic, +pub fn sync( + spec: ChainSpec, + full_builder: Fb, + light_builder: Lb, + mut make_block_and_import: B, + mut extrinsic_factory: ExF +) where + Fb: Fn(Configuration<(), G, E>) -> Result<(F, U), Error>, + F: AbstractService, + Lb: Fn(Configuration<(), G, E>) -> Result, + L: AbstractService, + B: FnMut(&F, &mut U), + ExF: FnMut(&F, &U) -> ::Extrinsic, + U: Clone + Send + 'static, + E: Clone, { const NUM_FULL_NODES: usize = 10; // FIXME: BABE light client support is currently not working. - const NUM_LIGHT_NODES: usize = 0; + const NUM_LIGHT_NODES: usize = 10; const NUM_BLOCKS: usize = 512; let temp = TempDir::new("substrate-sync-test").expect("Error creating test dir"); - let mut network = TestNet::::new( + let mut network = TestNet::new( &temp, spec.clone(), - NUM_FULL_NODES, - NUM_LIGHT_NODES, - vec![], + (0..NUM_FULL_NODES).map(|_| { |cfg| full_builder(cfg) }), + (0..NUM_LIGHT_NODES).map(|_| { |cfg| light_builder(cfg) }), + // Note: this iterator is empty but we can't just use `iter::empty()`, otherwise + // the type of the closure cannot be inferred. + (0..0).map(|_| (String::new(), { |cfg| full_builder(cfg) })), 30500, ); info!("Checking block sync"); let first_address = { - let first_service = &network.full_nodes[0].1; - let mut client = first_service.get().client(); + let &mut (_, ref first_service, ref mut first_user_data, _) = &mut network.full_nodes[0]; for i in 0 .. NUM_BLOCKS { if i % 128 == 0 { - info!("Generating #{}", i); + info!("Generating #{}", i + 1); } - let import_data = block_factory(&first_service); - client.import_block(import_data, HashMap::new()).expect("Error importing test block"); + + make_block_and_import(&first_service.get(), first_user_data); } - network.full_nodes[0].2.clone() + network.full_nodes[0].3.clone() }; info!("Running sync"); - for (_, service, _) in network.full_nodes.iter().skip(1) { + for (_, service, _, _) in network.full_nodes.iter().skip(1) { service.get().network().add_reserved_peer(first_address.to_string()).expect("Error adding reserved peer"); } for (_, service, _) in network.light_nodes.iter() { @@ -395,42 +442,50 @@ pub fn sync(spec: FactoryChainSpec, mut block_factory: B, mut extrin info!("Checking extrinsic propagation"); let first_service = network.full_nodes[0].1.clone(); + let first_user_data = &network.full_nodes[0].2; let best_block = BlockId::number(first_service.get().client().info().chain.best_number); - let extrinsic = extrinsic_factory(&first_service); - first_service.get().transaction_pool().submit_one(&best_block, extrinsic).unwrap(); + let extrinsic = extrinsic_factory(&first_service.get(), first_user_data); + futures03::executor::block_on(first_service.get().transaction_pool().submit_one(&best_block, extrinsic)).unwrap(); network.run_until_all_full( |_index, service| service.get().transaction_pool().ready().count() == 1, |_index, _service| true, ); } -pub fn consensus(spec: FactoryChainSpec, authorities: Vec) where - F: ServiceFactory, - F::FullService: Future, - F::LightService: Future, +pub fn consensus( + spec: ChainSpec, + full_builder: Fb, + light_builder: Lb, + authorities: impl IntoIterator +) where + Fb: Fn(Configuration<(), G, E>) -> Result, + F: AbstractService, + Lb: Fn(Configuration<(), G, E>) -> Result, + L: AbstractService, + E: Clone, { const NUM_FULL_NODES: usize = 10; - const NUM_LIGHT_NODES: usize = 0; + const NUM_LIGHT_NODES: usize = 10; const NUM_BLOCKS: usize = 10; // 10 * 2 sec block production time = ~20 seconds let temp = TempDir::new("substrate-conensus-test").expect("Error creating test dir"); - let mut network = TestNet::::new( + let mut network = TestNet::new( &temp, spec.clone(), - NUM_FULL_NODES / 2, - NUM_LIGHT_NODES / 2, - authorities, + (0..NUM_FULL_NODES / 2).map(|_| { |cfg| full_builder(cfg).map(|s| (s, ())) }), + (0..NUM_LIGHT_NODES / 2).map(|_| { |cfg| light_builder(cfg) }), + authorities.into_iter().map(|key| (key, { |cfg| full_builder(cfg).map(|s| (s, ())) })), 30600, ); info!("Checking consensus"); - let first_address = network.authority_nodes[0].2.clone(); - for (_, service, _) in network.full_nodes.iter() { + let first_address = network.authority_nodes[0].3.clone(); + for (_, service, _, _) in network.full_nodes.iter() { service.get().network().add_reserved_peer(first_address.to_string()).expect("Error adding reserved peer"); } for (_, service, _) in network.light_nodes.iter() { service.get().network().add_reserved_peer(first_address.to_string()).expect("Error adding reserved peer"); } - for (_, service, _) in network.authority_nodes.iter().skip(1) { + for (_, service, _, _) in network.authority_nodes.iter().skip(1) { service.get().network().add_reserved_peer(first_address.to_string()).expect("Error adding reserved peer"); } network.run_until_all_full( @@ -441,8 +496,15 @@ pub fn consensus(spec: FactoryChainSpec, authorities: Vec) where ); info!("Adding more peers"); - network.insert_nodes(&temp, NUM_FULL_NODES / 2, NUM_LIGHT_NODES / 2, vec![]); - for (_, service, _) in network.full_nodes.iter() { + network.insert_nodes( + &temp, + (0..NUM_FULL_NODES / 2).map(|_| { |cfg| full_builder(cfg).map(|s| (s, ())) }), + (0..NUM_LIGHT_NODES / 2).map(|_| { |cfg| light_builder(cfg) }), + // Note: this iterator is empty but we can't just use `iter::empty()`, otherwise + // the type of the closure cannot be inferred. + (0..0).map(|_| (String::new(), { |cfg| full_builder(cfg).map(|s| (s, ())) })), + ); + for (_, service, _, _) in network.full_nodes.iter() { service.get().network().add_reserved_peer(first_address.to_string()).expect("Error adding reserved peer"); } for (_, service, _) in network.light_nodes.iter() { diff --git a/core/sr-api-macros/Cargo.toml b/core/sr-api-macros/Cargo.toml index 3301b2fdc7ab3d6f505f477ce86d5401a736be5b..6f02e3040986f2842401db5cb7aa6d1d0093928d 100644 --- a/core/sr-api-macros/Cargo.toml +++ b/core/sr-api-macros/Cargo.toml @@ -9,10 +9,10 @@ proc-macro = true [dependencies] quote = "0.6.12" -syn = { version = "^0.15.30", features = [ "full", "fold", "extra-traits", "visit" ] } -proc-macro2 = "0.4" -blake2-rfc = "0.2" -proc-macro-crate = "0.1.3" +syn = { version = "0.15.44", features = [ "full", "fold", "extra-traits", "visit" ] } +proc-macro2 = "0.4.27" +blake2-rfc = "0.2.18" +proc-macro-crate = "0.1.4" [dev-dependencies] client = { package = "substrate-client", path = "../client" } @@ -21,10 +21,11 @@ state_machine = { package = "substrate-state-machine", path = "../state-machine" sr-primitives = { path = "../sr-primitives" } sr-version = { path = "../sr-version" } primitives = { package = "substrate-primitives", path = "../primitives" } -criterion = "0.2" +criterion = "0.2.11" consensus_common = { package = "substrate-consensus-common", path = "../consensus/common" } codec = { package = "parity-scale-codec", version = "1.0.0" } -trybuild = "1.0" +trybuild = "1.0.14" +rustversion = "0.1.4" [[bench]] name = "bench" diff --git a/core/sr-api-macros/src/decl_runtime_apis.rs b/core/sr-api-macros/src/decl_runtime_apis.rs index 27f102740b83b650aa6affb84d17d50ee8f6b0ec..12639bd1c1f17c22b807f7455113511ae80b996c 100644 --- a/core/sr-api-macros/src/decl_runtime_apis.rs +++ b/core/sr-api-macros/src/decl_runtime_apis.rs @@ -188,11 +188,11 @@ fn generate_native_call_generators(decl: &ItemTrait) -> Result { fn convert_between_block_types ( input: &I, error_desc: &'static str, - ) -> ::std::result::Result + ) -> std::result::Result { ::decode( - &mut &#crate_::runtime_api::Encode::encode(input)[..] - ).map_err(|_| error_desc) + &mut &#crate_::runtime_api::Encode::encode(input)[..], + ).map_err(|e| format!("{} {}", error_desc, e.what())) } )); @@ -203,13 +203,13 @@ fn generate_native_call_generators(decl: &ItemTrait) -> Result { let fn_name = generate_native_call_generator_fn_name(&fn_.ident); let output = return_type_replace_block_with_node_block(fn_.decl.output.clone()); let output_ty = return_type_extract_type(&output); - let output = quote!( ::std::result::Result<#output_ty, &'static str> ); + let output = quote!( std::result::Result<#output_ty, String> ); // Every type that is using the `Block` generic parameter, we need to encode/decode, // to make it compatible between the runtime/node. let conversions = params.iter().filter(|v| type_is_using_block(&v.1)).map(|(n, t, _)| { let name_str = format!( - "Could not convert parameter `{}` between node and runtime!", quote!(#n) + "Could not convert parameter `{}` between node and runtime:", quote!(#n) ); quote!( let #n: #t = convert_between_block_types(&#n, #name_str)?; @@ -398,7 +398,7 @@ fn generate_call_api_at_calls(decl: &ItemTrait) -> Result { #[cfg(any(feature = "std", test))] pub fn #fn_name< R: #crate_::runtime_api::Encode + #crate_::runtime_api::Decode + PartialEq, - NC: FnOnce() -> ::std::result::Result + ::std::panic::UnwindSafe, + NC: FnOnce() -> std::result::Result + std::panic::UnwindSafe, Block: #crate_::runtime_api::BlockT, T: #crate_::runtime_api::CallRuntimeAt, C: #crate_::runtime_api::Core, @@ -552,9 +552,9 @@ impl<'a> ToClientSideDecl<'a> { fn fold_trait_item_method(&mut self, method: TraitItemMethod) -> (TraitItemMethod, Option, TraitItemMethod) { let crate_ = self.crate_; - let context_other = quote!( #crate_::runtime_api::ExecutionContext::Other ); + let context = quote!( #crate_::runtime_api::ExecutionContext::OffchainCall(None) ); let fn_impl = self.create_method_runtime_api_impl(method.clone()); - let fn_decl = self.create_method_decl(method.clone(), context_other); + let fn_decl = self.create_method_decl(method.clone(), context); let fn_decl_ctx = self.create_method_decl_with_context(method); (fn_decl, fn_impl, fn_decl_ctx) diff --git a/core/sr-api-macros/src/impl_runtime_apis.rs b/core/sr-api-macros/src/impl_runtime_apis.rs index 973fa0558a85cd1eaf29fe450b27142c9c28fd26..fb154aa1123580a1e35597b1b40f1961b6ebb522 100644 --- a/core/sr-api-macros/src/impl_runtime_apis.rs +++ b/core/sr-api-macros/src/impl_runtime_apis.rs @@ -282,7 +282,7 @@ fn generate_runtime_api_base_structures(impls: &[ItemImpl]) -> Result> #crate_::runtime_api::ApiExt<#block> for RuntimeApiImpl { - fn map_api_result ::std::result::Result, R, E>( + fn map_api_result std::result::Result, R, E>( &self, map_call: F ) -> ::std::result::Result where Self: Sized { diff --git a/core/sr-api-macros/tests/runtime_calls.rs b/core/sr-api-macros/tests/runtime_calls.rs index 6b79e52ee21d01e46c71c8dabe8e53f722ce4353..f33a9e257a53a3a0905d824fb7c3e2450fafe22f 100644 --- a/core/sr-api-macros/tests/runtime_calls.rs +++ b/core/sr-api-macros/tests/runtime_calls.rs @@ -50,7 +50,10 @@ fn calling_wasm_runtime_function() { } #[test] -#[should_panic(expected = "Could not convert parameter `param` between node and runtime!")] +#[should_panic( + expected = + "Could not convert parameter `param` between node and runtime: DecodeFails always fails" +)] fn calling_native_runtime_function_with_non_decodable_parameter() { let client = TestClientBuilder::new().set_execution_strategy(ExecutionStrategy::NativeWhenPossible).build(); let runtime_api = client.runtime_api(); diff --git a/core/sr-api-macros/tests/trybuild.rs b/core/sr-api-macros/tests/trybuild.rs index 302dd7c0878e3dfb6c9b364c2004ee6f8fed2e80..9baea83196e9bf728e1aea8229f109f0d978ac41 100644 --- a/core/sr-api-macros/tests/trybuild.rs +++ b/core/sr-api-macros/tests/trybuild.rs @@ -1,5 +1,6 @@ use std::env; +#[rustversion::attr(not(stable), ignore)] #[test] fn ui() { // As trybuild is using `cargo check`, we don't need the real WASM binaries. diff --git a/core/sr-api-macros/tests/ui/declaring_old_block.stderr b/core/sr-api-macros/tests/ui/declaring_old_block.stderr index 181aa2a3ca7834eebc40cbb0b6b6f83a7380dcbc..999a50cc9697759f3e94a3e84a2f202399fc937b 100644 --- a/core/sr-api-macros/tests/ui/declaring_old_block.stderr +++ b/core/sr-api-macros/tests/ui/declaring_old_block.stderr @@ -16,4 +16,4 @@ warning: unused import: `sr_primitives::traits::Block as BlockT` 1 | use sr_primitives::traits::Block as BlockT; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | - = note: #[warn(unused_imports)] on by default + = note: `#[warn(unused_imports)]` on by default diff --git a/core/sr-api-macros/tests/ui/declaring_own_block_with_different_name.stderr b/core/sr-api-macros/tests/ui/declaring_own_block_with_different_name.stderr index a591d0448c50d7c03bc48b46fe071ea4c6b13ccd..ec033f2e09d23fe63309796c3b75e4b049015c16 100644 --- a/core/sr-api-macros/tests/ui/declaring_own_block_with_different_name.stderr +++ b/core/sr-api-macros/tests/ui/declaring_own_block_with_different_name.stderr @@ -10,4 +10,4 @@ warning: unused import: `sr_primitives::traits::Block as BlockT` 1 | use sr_primitives::traits::Block as BlockT; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | - = note: #[warn(unused_imports)] on by default + = note: `#[warn(unused_imports)]` on by default diff --git a/core/sr-io/Cargo.toml b/core/sr-io/Cargo.toml index 0e6fba5bd73d2c960244c30e9da5e07b5c50dc9e..65b080b86df82faad299eccfbacdc16e16b0cfb7 100644 --- a/core/sr-io/Cargo.toml +++ b/core/sr-io/Cargo.toml @@ -6,22 +6,19 @@ build = "build.rs" edition = "2018" [build-dependencies] -rustc_version = "0.2" +rustc_version = "0.2.3" [dependencies] rstd = { package = "sr-std", path = "../sr-std", default-features = false } primitives = { package = "substrate-primitives", path = "../primitives", default-features = false } codec = { package = "parity-scale-codec", version = "1.0.0", default-features = false } -hash-db = { version = "0.15.0", default-features = false } -libsecp256k1 = { version = "0.2.1", optional = true } -tiny-keccak = { version = "1.4.2", optional = true } -environmental = { version = "1.0.1", optional = true } +hash-db = { version = "0.15.2", default-features = false } +libsecp256k1 = { version = "0.3.0", optional = true } +tiny-keccak = { version = "1.5.0", optional = true } +environmental = { version = "1.0.2", optional = true } substrate-state-machine = { path = "../state-machine", optional = true } trie = { package = "substrate-trie", path = "../trie", optional = true } -[dev-dependencies] -substrate-offchain = { path = "../offchain" } - [features] default = ["std"] std = [ @@ -33,10 +30,14 @@ std = [ "environmental", "substrate-state-machine", "libsecp256k1", - "tiny-keccak" + "tiny-keccak", ] nightly = [] strict = [] -wasm-nice-panic-message = [] + +# These two features are used for `no_std` builds for the environments which already provides +# `#[panic_handler]` and `#[alloc_error_handler]`. +# +# For the regular wasm runtime builds those are not used. no_panic_handler = [] no_oom = [] diff --git a/core/sr-io/src/lib.rs b/core/sr-io/src/lib.rs index 91b27efba03045cd24054998ac8cd07832c66462..4b00a842311f5829e1471031d9e2048419a7ea11 100644 --- a/core/sr-io/src/lib.rs +++ b/core/sr-io/src/lib.rs @@ -26,15 +26,10 @@ #![cfg_attr(feature = "std", doc = "Substrate runtime standard library as compiled when linked with Rust's standard library.")] #![cfg_attr(not(feature = "std"), doc = "Substrate's runtime standard library as compiled without Rust's standard library.")] -use hash_db::Hasher; use rstd::vec::Vec; -#[doc(hidden)] -pub use codec; - -pub use primitives::Blake2Hasher; use primitives::{ - crypto::KeyTypeId, ed25519, sr25519, + crypto::KeyTypeId, ed25519, sr25519, H256, offchain::{ Timestamp, HttpRequestId, HttpRequestStatus, HttpError, StorageKind, OpaqueNetworkState, }, @@ -50,14 +45,6 @@ pub enum EcdsaVerifyError { BadSignature, } -pub mod offchain; - -/// Trait for things which can be printed. -pub trait Printable { - /// Print the object. - fn print(self); -} - /// Converts a public trait definition into a private trait and set of public functions /// that assume the trait is implemented for `()` for ease of calling. macro_rules! export_api { @@ -67,7 +54,6 @@ macro_rules! export_api { $( $( #[$attr:meta] )* fn $name:ident - $(< $( $g_name:ident $( : $g_ty:path )? ),+ >)? ( $( $arg:ident : $arg_ty:ty ),* $(,)? ) $( -> $ret:ty )? $( where $( $w_name:path : $w_ty:path ),+ )?; @@ -78,18 +64,18 @@ macro_rules! export_api { pub(crate) trait $trait_name { $( $( #[$attr] )* - fn $name $(< $( $g_name $( : $g_ty )? ),+ >)? ( $($arg : $arg_ty ),* ) $( -> $ret )? + fn $name ( $($arg : $arg_ty ),* ) $( -> $ret )? $( where $( $w_name : $w_ty ),+ )?; )* } $( $( #[$attr] )* - pub fn $name $(< $( $g_name $( : $g_ty )? ),+ >)? ( $($arg : $arg_ty ),* ) $( -> $ret )? + pub fn $name ( $($arg : $arg_ty ),* ) $( -> $ret )? $( where $( $w_name : $w_ty ),+ )? { #[allow(deprecated)] - <()>:: $name $(::< $( $g_name ),+ > )? ( $( $arg ),* ) + <()>:: $name ( $( $arg ),* ) } )* } @@ -154,26 +140,10 @@ export_api! { fn storage_changes_root(parent_hash: [u8; 32]) -> Option<[u8; 32]>; /// A trie root formed from the iterated items. - fn trie_root(input: I) -> H::Out - where - I: IntoIterator, - A: AsRef<[u8]>, - A: Ord, - B: AsRef<[u8]>, - H: Hasher, - H: self::imp::HasherBounds, - H::Out: Ord - ; + fn blake2_256_trie_root(input: Vec<(Vec, Vec)>) -> H256; /// A trie root formed from the enumerated items. - fn ordered_trie_root(input: I) -> H::Out - where - I: IntoIterator, - A: AsRef<[u8]>, - H: Hasher, - H: self::imp::HasherBounds, - H::Out: Ord - ; + fn blake2_256_ordered_trie_root(input: Vec>) -> H256; } } @@ -182,12 +152,12 @@ export_api! { /// The current relay chain identifier. fn chain_id() -> u64; - /// Print a printable value. - fn print(value: T) - where - T: Printable, - T: Sized - ; + /// Print a number. + fn print_num(val: u64); + /// Print any valid `utf8` buffer. + fn print_utf8(utf8: &[u8]); + /// Print any `u8` slice as hex. + fn print_hex(data: &[u8]); } } @@ -203,10 +173,10 @@ export_api! { /// key type in the keystore. /// /// Returns the raw signature. - fn ed25519_sign>( + fn ed25519_sign( id: KeyTypeId, pubkey: &ed25519::Public, - msg: &M, + msg: &[u8], ) -> Option; /// Verify an ed25519 signature. /// @@ -223,10 +193,10 @@ export_api! { /// key type in the keystore. /// /// Returns the raw signature. - fn sr25519_sign>( + fn sr25519_sign( id: KeyTypeId, pubkey: &sr25519::Public, - msg: &M, + msg: &[u8], ) -> Option; /// Verify an sr25519 signature. /// @@ -269,10 +239,11 @@ export_api! { /// Even if this function returns `true`, it does not mean that any keys are configured /// and that the validator is registered in the chain. fn is_validator() -> bool; + /// Submit transaction to the pool. /// /// The transaction will end up in the pool. - fn submit_transaction(data: &T) -> Result<(), ()>; + fn submit_transaction(data: Vec) -> Result<(), ()>; /// Returns information about the local node's network state. fn network_state() -> Result; @@ -308,7 +279,7 @@ export_api! { kind: StorageKind, key: &[u8], old_value: Option<&[u8]>, - new_value: &[u8] + new_value: &[u8], ) -> bool; /// Gets a value from the local storage. @@ -325,14 +296,14 @@ export_api! { fn http_request_start( method: &str, uri: &str, - meta: &[u8] + meta: &[u8], ) -> Result; /// Append header to the request. fn http_request_add_header( request_id: HttpRequestId, name: &str, - value: &str + value: &str, ) -> Result<(), ()>; /// Write a chunk of request body. @@ -344,7 +315,7 @@ export_api! { fn http_request_write_body( request_id: HttpRequestId, chunk: &[u8], - deadline: Option + deadline: Option, ) -> Result<(), HttpError>; /// Block and wait for the responses for given requests. @@ -356,16 +327,14 @@ export_api! { /// Passing `None` as deadline blocks forever. fn http_response_wait( ids: &[HttpRequestId], - deadline: Option + deadline: Option, ) -> Vec; /// Read all response headers. /// /// Returns a vector of pairs `(HeaderKey, HeaderValue)`. /// NOTE response headers have to be read before response body. - fn http_response_headers( - request_id: HttpRequestId - ) -> Vec<(Vec, Vec)>; + fn http_response_headers(request_id: HttpRequestId) -> Vec<(Vec, Vec)>; /// Read a chunk of body response to given buffer. /// @@ -378,7 +347,7 @@ export_api! { fn http_response_read_body( request_id: HttpRequestId, buffer: &mut [u8], - deadline: Option + deadline: Option, ) -> Result; } } diff --git a/core/sr-io/with_std.rs b/core/sr-io/with_std.rs index 167011608fd34c78d73254e8001ab7d7a89cbc84..919f4a913acc90d079cdfd2dd775bbf560f03a4c 100644 --- a/core/sr-io/with_std.rs +++ b/core/sr-io/with_std.rs @@ -15,16 +15,15 @@ // along with Substrate. If not, see . use primitives::{ - blake2_128, blake2_256, twox_128, twox_256, twox_64, ed25519, Blake2Hasher, sr25519, Pair, + blake2_128, blake2_256, twox_128, twox_256, twox_64, ed25519, Blake2Hasher, sr25519, Pair, H256, + traits::Externalities, child_storage_key::ChildStorageKey, hexdisplay::HexDisplay, offchain, + Hasher, }; // Switch to this after PoC-3 // pub use primitives::BlakeHasher; -pub use substrate_state_machine::{ - Externalities, BasicExternalities, TestExternalities, ChildStorageKey, -}; +pub use substrate_state_machine::{BasicExternalities, TestExternalities}; use environmental::environmental; -use primitives::{offchain, hexdisplay::HexDisplay, H256}; use trie::{TrieConfiguration, trie_types::Layout}; use std::{collections::HashMap, convert::TryFrom}; @@ -40,7 +39,7 @@ impl HasherBounds for T {} /// /// Panicking here is aligned with what the `without_std` environment would do /// in the case of an invalid child storage key. -fn child_storage_key_or_panic(storage_key: &[u8]) -> ChildStorageKey { +fn child_storage_key_or_panic(storage_key: &[u8]) -> ChildStorageKey { match ChildStorageKey::from_slice(storage_key) { Some(storage_key) => storage_key, None => panic!("child storage key is invalid"), @@ -55,9 +54,9 @@ impl StorageApi for () { fn read_storage(key: &[u8], value_out: &mut [u8], value_offset: usize) -> Option { ext::with(|ext| ext.storage(key).map(|value| { - let value = &value[value_offset..]; - let written = std::cmp::min(value.len(), value_out.len()); - value_out[..written].copy_from_slice(&value[..written]); + let data = &value[value_offset.min(value.len())..]; + let written = std::cmp::min(data.len(), value_out.len()); + value_out[..written].copy_from_slice(&data[..written]); value.len() })).expect("read_storage cannot be called outside of an Externalities-provided environment.") } @@ -86,9 +85,9 @@ impl StorageApi for () { let storage_key = child_storage_key_or_panic(storage_key); ext.child_storage(storage_key, key) .map(|value| { - let value = &value[value_offset..]; - let written = std::cmp::min(value.len(), value_out.len()); - value_out[..written].copy_from_slice(&value[..written]); + let data = &value[value_offset.min(value.len())..]; + let written = std::cmp::min(data.len(), value_out.len()); + value_out[..written].copy_from_slice(&data[..written]); value.len() }) }) @@ -167,25 +166,12 @@ impl StorageApi for () { ).unwrap_or(Ok(None)).expect("Invalid parent hash passed to storage_changes_root") } - fn trie_root(input: I) -> H::Out - where - I: IntoIterator, - A: AsRef<[u8]> + Ord, - B: AsRef<[u8]>, - H: Hasher, - H::Out: Ord, - { - Layout::::trie_root(input) + fn blake2_256_trie_root(input: Vec<(Vec, Vec)>) -> H256 { + Layout::::trie_root(input) } - fn ordered_trie_root(input: I) -> H::Out - where - I: IntoIterator, - A: AsRef<[u8]>, - H: Hasher, - H::Out: Ord, - { - Layout::::ordered_trie_root(input) + fn blake2_256_ordered_trie_root(input: Vec>) -> H256 { + Layout::::ordered_trie_root(input) } } @@ -196,8 +182,18 @@ impl OtherApi for () { ).unwrap_or(0) } - fn print(value: T) { - value.print() + fn print_num(val: u64) { + println!("{}", val); + } + + fn print_utf8(utf8: &[u8]) { + if let Ok(data) = std::str::from_utf8(utf8) { + println!("{}", data) + } + } + + fn print_hex(data: &[u8]) { + println!("{}", HexDisplay::from(&data)); } } @@ -206,7 +202,7 @@ impl CryptoApi for () { ext::with(|ext| { ext.keystore() .expect("No `keystore` associated for the current context!") - .write() + .read() .ed25519_public_keys(id) }).expect("`ed25519_public_keys` cannot be called outside of an Externalities-provided environment.") } @@ -221,10 +217,10 @@ impl CryptoApi for () { }).expect("`ed25519_generate` cannot be called outside of an Externalities-provided environment.") } - fn ed25519_sign>( + fn ed25519_sign( id: KeyTypeId, pubkey: &ed25519::Public, - msg: &M, + msg: &[u8], ) -> Option { let pub_key = ed25519::Public::try_from(pubkey.as_ref()).ok()?; @@ -233,7 +229,7 @@ impl CryptoApi for () { .expect("No `keystore` associated for the current context!") .read() .ed25519_key_pair(id, &pub_key) - .map(|k| k.sign(msg.as_ref()).into()) + .map(|k| k.sign(msg)) }).expect("`ed25519_sign` cannot be called outside of an Externalities-provided environment.") } @@ -245,7 +241,7 @@ impl CryptoApi for () { ext::with(|ext| { ext.keystore() .expect("No `keystore` associated for the current context!") - .write() + .read() .sr25519_public_keys(id) }).expect("`sr25519_public_keys` cannot be called outside of an Externalities-provided environment.") } @@ -260,10 +256,10 @@ impl CryptoApi for () { }).expect("`sr25519_generate` cannot be called outside of an Externalities-provided environment.") } - fn sr25519_sign>( + fn sr25519_sign( id: KeyTypeId, pubkey: &sr25519::Public, - msg: &M, + msg: &[u8], ) -> Option { let pub_key = sr25519::Public::try_from(pubkey.as_ref()).ok()?; @@ -272,7 +268,7 @@ impl CryptoApi for () { .expect("No `keystore` associated for the current context!") .read() .sr25519_key_pair(id, &pub_key) - .map(|k| k.sign(msg.as_ref()).into()) + .map(|k| k.sign(msg)) }).expect("`sr25519_sign` cannot be called outside of an Externalities-provided environment.") } @@ -334,9 +330,9 @@ impl OffchainApi for () { }, "is_validator can be called only in the offchain worker context") } - fn submit_transaction(data: &T) -> Result<(), ()> { + fn submit_transaction(data: Vec) -> Result<(), ()> { with_offchain(|ext| { - ext.submit_transaction(codec::Encode::encode(data)) + ext.submit_transaction(data) }, "submit_transaction can be called only in the offchain worker context") } @@ -390,7 +386,7 @@ impl OffchainApi for () { fn http_request_start( method: &str, uri: &str, - meta: &[u8] + meta: &[u8], ) -> Result { with_offchain(|ext| { ext.http_request_start(method, uri, meta) @@ -400,7 +396,7 @@ impl OffchainApi for () { fn http_request_add_header( request_id: offchain::HttpRequestId, name: &str, - value: &str + value: &str, ) -> Result<(), ()> { with_offchain(|ext| { ext.http_request_add_header(request_id, name, value) @@ -410,7 +406,7 @@ impl OffchainApi for () { fn http_request_write_body( request_id: offchain::HttpRequestId, chunk: &[u8], - deadline: Option + deadline: Option, ) -> Result<(), offchain::HttpError> { with_offchain(|ext| { ext.http_request_write_body(request_id, chunk, deadline) @@ -419,7 +415,7 @@ impl OffchainApi for () { fn http_response_wait( ids: &[offchain::HttpRequestId], - deadline: Option + deadline: Option, ) -> Vec { with_offchain(|ext| { ext.http_response_wait(ids, deadline) @@ -427,7 +423,7 @@ impl OffchainApi for () { } fn http_response_headers( - request_id: offchain::HttpRequestId + request_id: offchain::HttpRequestId, ) -> Vec<(Vec, Vec)> { with_offchain(|ext| { ext.http_response_headers(request_id) @@ -437,7 +433,7 @@ impl OffchainApi for () { fn http_response_read_body( request_id: offchain::HttpRequestId, buffer: &mut [u8], - deadline: Option + deadline: Option, ) -> Result { with_offchain(|ext| { ext.http_response_read_body(request_id, buffer, deadline) @@ -478,24 +474,6 @@ pub fn with_storage R>( r } -impl<'a> Printable for &'a [u8] { - fn print(self) { - println!("Runtime: {}", HexDisplay::from(&self)); - } -} - -impl<'a> Printable for &'a str { - fn print(self) { - println!("Runtime: {}", self); - } -} - -impl Printable for u64 { - fn print(self) { - println!("Runtime: {}", self); - } -} - #[cfg(test)] mod std_tests { use super::*; diff --git a/core/sr-io/without_std.rs b/core/sr-io/without_std.rs index 954eccc9cfafd6ccb7f46f2e0c454c4277f56c1f..90ec5a9ee4501ccb3fa5c1e77a0b566ca858b4cc 100644 --- a/core/sr-io/without_std.rs +++ b/core/sr-io/without_std.rs @@ -20,7 +20,7 @@ pub use rstd::{mem, slice}; use core::{intrinsics, panic::PanicInfo}; use rstd::{vec::Vec, cell::Cell, convert::TryInto}; -use primitives::{offchain, Blake2Hasher}; +use primitives::offchain; use codec::Decode; #[cfg(not(feature = "no_panic_handler"))] @@ -28,26 +28,15 @@ use codec::Decode; #[no_mangle] pub fn panic(info: &PanicInfo) -> ! { unsafe { - #[cfg(feature = "wasm-nice-panic-message")] - { - let message = rstd::alloc::format!("{}", info); - extern_functions_host_impl::ext_print_utf8(message.as_ptr() as *const u8, message.len() as u32); - } - #[cfg(not(feature = "wasm-nice-panic-message"))] - { - if let Some(loc) = info.location() { - extern_functions_host_impl::ext_print_utf8(loc.file().as_ptr() as *const u8, loc.file().len() as u32); - extern_functions_host_impl::ext_print_num(loc.line() as u64); - extern_functions_host_impl::ext_print_num(loc.column() as u64); - } - } + let message = rstd::alloc::format!("{}", info); + extern_functions_host_impl::ext_print_utf8(message.as_ptr() as *const u8, message.len() as u32); intrinsics::abort() } } #[cfg(not(feature = "no_oom"))] #[alloc_error_handler] -pub extern fn oom(_: ::core::alloc::Layout) -> ! { +pub extern fn oom(_: core::alloc::Layout) -> ! { static OOM_MSG: &str = "Runtime memory exhausted. Aborting"; unsafe { @@ -126,44 +115,6 @@ pub mod ext { } } - /// Ensures we use the right crypto when calling into native - pub trait ExternTrieCrypto: Hasher { - /// A trie root formed from the enumerated items. - fn ordered_trie_root< - A: AsRef<[u8]>, - I: IntoIterator - >(values: I) -> Self::Out; - } - - /// Additional bounds for Hasher trait for without_std. - pub trait HasherBounds: ExternTrieCrypto {} - impl HasherBounds for T {} - - // Ensures we use a Blake2_256-flavored Hasher when calling into native - impl ExternTrieCrypto for Blake2Hasher { - fn ordered_trie_root< - A: AsRef<[u8]>, - I: IntoIterator - >(items: I) -> Self::Out { - let mut values = Vec::new(); - let mut lengths = Vec::new(); - for v in items.into_iter() { - values.extend_from_slice(v.as_ref()); - lengths.push((v.as_ref().len() as u32).to_le()); - } - let mut result: [u8; 32] = Default::default(); - unsafe { - ext_blake2_256_enumerated_trie_root.get()( - values.as_ptr(), - lengths.as_ptr(), - lengths.len() as u32, - result.as_mut_ptr() - ); - } - result.into() - } - } - /// Declare extern functions macro_rules! extern_functions { ( @@ -228,7 +179,7 @@ pub mod ext { storage_key_data: *const u8, storage_key_len: u32, prefix_data: *const u8, - prefix_len: u32 + prefix_len: u32, ); /// Gets the value of the given key from storage. /// @@ -255,7 +206,7 @@ pub mod ext { key_len: u32, value_data: *mut u8, value_len: u32, - value_offset: u32 + value_offset: u32, ) -> u32; /// Gets the trie root of the storage. fn ext_storage_root(result: *mut u8); @@ -266,7 +217,10 @@ pub mod ext { /// - `1` if the change trie root was found. /// - `0` if the change trie root was not found. fn ext_storage_changes_root( - parent_hash_data: *const u8, parent_hash_len: u32, result: *mut u8) -> u32; + parent_hash_data: *const u8, + parent_hash_len: u32, + result: *mut u8, + ) -> u32; /// A child storage function. /// @@ -279,7 +233,7 @@ pub mod ext { key_data: *const u8, key_len: u32, value_data: *const u8, - value_len: u32 + value_len: u32, ); /// A child storage function. /// @@ -290,7 +244,7 @@ pub mod ext { storage_key_data: *const u8, storage_key_len: u32, key_data: *const u8, - key_len: u32 + key_len: u32, ); /// A child storage function. /// @@ -301,7 +255,7 @@ pub mod ext { storage_key_data: *const u8, storage_key_len: u32, key_data: *const u8, - key_len: u32 + key_len: u32, ) -> u32; /// A child storage function. /// @@ -319,7 +273,7 @@ pub mod ext { storage_key_len: u32, key_data: *const u8, key_len: u32, - written_out: *mut u32 + written_out: *mut u32, ) -> *mut u8; /// A child storage function. /// @@ -333,7 +287,7 @@ pub mod ext { key_len: u32, value_data: *mut u8, value_len: u32, - value_offset: u32 + value_offset: u32, ) -> u32; /// Commits all changes and calculates the child-storage root. /// @@ -498,7 +452,7 @@ pub mod ext { old_value: *const u8, old_value_len: u32, new_value: *const u8, - new_value_len: u32 + new_value_len: u32, ) -> u32; /// Read a value from local storage. @@ -526,7 +480,7 @@ pub mod ext { url: *const u8, url_len: u32, meta: *const u8, - meta_len: u32 + meta_len: u32, ) -> u32; /// Add a header to the request. @@ -540,7 +494,7 @@ pub mod ext { name: *const u8, name_len: u32, value: *const u8, - value_len: u32 + value_len: u32, ) -> u32; /// Write a chunk of request body. @@ -556,7 +510,7 @@ pub mod ext { request_id: u32, chunk: *const u8, chunk_len: u32, - deadline: u64 + deadline: u64, ) -> u32; /// Block and wait for the responses for given requests. @@ -570,7 +524,7 @@ pub mod ext { ids: *const u32, ids_len: u32, statuses: *mut u32, - deadline: u64 + deadline: u64, ); /// Read all response headers. @@ -583,7 +537,7 @@ pub mod ext { /// - In case invalid `id` is passed it returns a pointer to parity-encoded empty vector. fn ext_http_response_headers( id: u32, - written_out: *mut u32 + written_out: *mut u32, ) -> *mut u8; /// Read a chunk of body response to given buffer. @@ -605,7 +559,7 @@ pub mod ext { id: u32, buffer: *mut u8, buffer_len: u32, - deadline: u64 + deadline: u64, ) -> u32; } } @@ -777,21 +731,28 @@ impl StorageApi for () { } } - fn trie_root< - H: Hasher + ExternTrieCrypto, - I: IntoIterator, - A: AsRef<[u8]> + Ord, - B: AsRef<[u8]>, - >(_input: I) -> H::Out { + + fn blake2_256_trie_root(_input: Vec<(Vec, Vec)>) -> H256 { unimplemented!() } - fn ordered_trie_root< - H: Hasher + ExternTrieCrypto, - I: IntoIterator, - A: AsRef<[u8]> - >(values: I) -> H::Out { - H::ordered_trie_root(values) + fn blake2_256_ordered_trie_root(input: Vec>) -> H256 { + let mut values = Vec::with_capacity(input.len()); + let mut lengths = Vec::with_capacity(input.len()); + for v in input { + values.extend_from_slice(&v); + lengths.push((v.len() as u32).to_le()); + } + let mut result: [u8; 32] = Default::default(); + unsafe { + ext_blake2_256_enumerated_trie_root.get()( + values.as_ptr(), + lengths.as_ptr(), + lengths.len() as u32, + result.as_mut_ptr(), + ); + } + result.into() } } @@ -802,10 +763,23 @@ impl OtherApi for () { } } - fn print(value: T) { - value.print() + fn print_num(val: u64) { + unsafe { + ext_print_num.get()(val); + } } + fn print_utf8(utf8: &[u8]) { + unsafe { + ext_print_utf8.get()(utf8.as_ptr(), utf8.len() as u32); + } + } + + fn print_hex(data: &[u8]) { + unsafe { + ext_print_hex.get()(data.as_ptr(), data.len() as u32); + } + } } impl HashingApi for () { @@ -876,18 +850,18 @@ impl CryptoApi for () { ed25519::Public(res) } - fn ed25519_sign>( + fn ed25519_sign( id: KeyTypeId, pubkey: &ed25519::Public, - msg: &M, + msg: &[u8], ) -> Option { let mut res = [0u8; 64]; let success = unsafe { ext_ed25519_sign.get()( id.0.as_ptr(), pubkey.0.as_ptr(), - msg.as_ref().as_ptr(), - msg.as_ref().len() as u32, + msg.as_ptr(), + msg.len() as u32, res.as_mut_ptr(), ) == 0 }; @@ -927,18 +901,18 @@ impl CryptoApi for () { sr25519::Public(res) } - fn sr25519_sign>( + fn sr25519_sign( id: KeyTypeId, pubkey: &sr25519::Public, - msg: &M, + msg: &[u8], ) -> Option { let mut res = [0u8; 64]; let success = unsafe { ext_sr25519_sign.get()( id.0.as_ptr(), pubkey.0.as_ptr(), - msg.as_ref().as_ptr(), - msg.as_ref().len() as u32, + msg.as_ptr(), + msg.len() as u32, res.as_mut_ptr(), ) == 0 }; @@ -980,10 +954,9 @@ impl OffchainApi for () { unsafe { ext_is_validator.get()() == 1 } } - fn submit_transaction(data: &T) -> Result<(), ()> { - let encoded_data = codec::Encode::encode(data); + fn submit_transaction(data: Vec) -> Result<(), ()> { let ret = unsafe { - ext_submit_transaction.get()(encoded_data.as_ptr(), encoded_data.len() as u32) + ext_submit_transaction.get()(data.as_ptr(), data.len() as u32) }; if ret == 0 { @@ -1163,7 +1136,7 @@ impl OffchainApi for () { statuses .into_iter() - .map(|status| status.try_into().unwrap_or(offchain::HttpRequestStatus::Unknown)) + .map(|status| status.try_into().unwrap_or(offchain::HttpRequestStatus::Invalid)) .collect() } @@ -1218,25 +1191,3 @@ unsafe fn from_raw_parts(ptr: *mut u8, len: u32) -> Option> { } impl Api for () {} - -impl<'a> Printable for &'a [u8] { - fn print(self) { - unsafe { - ext_print_hex.get()(self.as_ptr(), self.len() as u32); - } - } -} - -impl<'a> Printable for &'a str { - fn print(self) { - unsafe { - ext_print_utf8.get()(self.as_ptr() as *const u8, self.len() as u32); - } - } -} - -impl Printable for u64 { - fn print(self) { - unsafe { ext_print_num.get()(self); } - } -} diff --git a/core/sr-primitives/Cargo.toml b/core/sr-primitives/Cargo.toml index d3510e6baa8340a5ed89d09534de7cfa43b61746..fc8b744d370f4cbc562aaf5fc33e0de2f9ded535 100644 --- a/core/sr-primitives/Cargo.toml +++ b/core/sr-primitives/Cargo.toml @@ -5,21 +5,24 @@ authors = ["Parity Technologies "] edition = "2018" [dependencies] -num-traits = { version = "0.2", default-features = false } -integer-sqrt = { version = "0.1.2" } -serde = { version = "1.0", optional = true, features = ["derive"] } +num-traits = { version = "0.2.8", default-features = false } +integer-sqrt = "0.1.2" +serde = { version = "1.0.101", optional = true, features = ["derive"] } codec = { package = "parity-scale-codec", version = "1.0.0", default-features = false, features = ["derive"] } primitives = { package = "substrate-primitives", path = "../primitives", default-features = false } app-crypto = { package = "substrate-application-crypto", path = "../application-crypto", default-features = false } rstd = { package = "sr-std", path = "../sr-std", default-features = false } runtime_io = { package = "sr-io", path = "../sr-io", default-features = false } -log = { version = "0.4", optional = true } -paste = { version = "0.1"} -rand = { version = "0.7.0", optional = true } +log = { version = "0.4.8", optional = true } +paste = "0.1.6" +rand = { version = "0.7.2", optional = true } +impl-trait-for-tuples = "0.1.2" [dev-dependencies] -serde_json = "1.0" -primitive-types = "0.5.0" +serde_json = "1.0.40" +primitive-types = "0.5.1" +rand = "0.7.2" +substrate-offchain = { path = "../offchain" } [features] default = ["std"] diff --git a/core/sr-primitives/src/curve.rs b/core/sr-primitives/src/curve.rs new file mode 100644 index 0000000000000000000000000000000000000000..dc6316bd470c73d176d0b73c21fe87bd6110a23a --- /dev/null +++ b/core/sr-primitives/src/curve.rs @@ -0,0 +1,164 @@ +// Copyright 2019 Parity Technologies (UK) Ltd. +// This file is part of Substrate. + +// Substrate 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. + +// Substrate 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 Substrate. If not, see . + +//! Provides some utilities to define a piecewise linear function. + +use crate::{Perbill, traits::{SimpleArithmetic, SaturatedConversion}}; +use core::ops::Sub; + +/// Piecewise Linear function in [0, 1] -> [0, 1]. +#[cfg_attr(feature = "std", derive(Debug))] +#[derive(PartialEq, Eq)] +pub struct PiecewiseLinear<'a> { + /// Array of points. Must be in order from the lowest abscissas to the highest. + pub points: &'a [(Perbill, Perbill)] +} + +fn abs_sub + Clone>(a: N, b: N) -> N where { + a.clone().max(b.clone()) - a.min(b) +} + +impl<'a> PiecewiseLinear<'a> { + /// Compute `f(n/d)*d` with `n <= d`. This is useful to avoid loss of precision. + pub fn calculate_for_fraction_times_denominator(&self, n: N, d: N) -> N where + N: SimpleArithmetic + Clone + { + let n = n.min(d.clone()); + + if self.points.len() == 0 { + return N::zero() + } + + let next_point_index = self.points.iter() + .position(|p| n < p.0 * d.clone()); + + let (prev, next) = if let Some(next_point_index) = next_point_index { + if let Some(previous_point_index) = next_point_index.checked_sub(1) { + (self.points[previous_point_index], self.points[next_point_index]) + } else { + // There is no previous points, take first point ordinate + return self.points.first().map(|p| p.1).unwrap_or_else(Perbill::zero) * d + } + } else { + // There is no next points, take last point ordinate + return self.points.last().map(|p| p.1).unwrap_or_else(Perbill::zero) * d + }; + + let delta_y = multiply_by_rational_saturating( + abs_sub(n.clone(), prev.0 * d.clone()), + abs_sub(next.1.deconstruct(), prev.1.deconstruct()), + // Must not saturate as prev abscissa > next abscissa + next.0.deconstruct().saturating_sub(prev.0.deconstruct()), + ); + + // If both substration are same sign then result is positive + if (n > prev.0 * d.clone()) == (next.1.deconstruct() > prev.1.deconstruct()) { + (prev.1 * d).saturating_add(delta_y) + // Otherwise result is negative + } else { + (prev.1 * d).saturating_sub(delta_y) + } + } +} + +// Compute value * p / q. +// This is guaranteed not to overflow on whatever values nor lose precision. +// `q` must be superior to zero. +fn multiply_by_rational_saturating(value: N, p: u32, q: u32) -> N + where N: SimpleArithmetic + Clone +{ + let q = q.max(1); + + // Mul can saturate if p > q + let result_divisor_part = (value.clone() / q.into()).saturating_mul(p.into()); + + let result_remainder_part = { + let rem = value % q.into(); + + // Fits into u32 because q is u32 and remainder < q + let rem_u32 = rem.saturated_into::(); + + // Multiplication fits into u64 as both term are u32 + let rem_part = rem_u32 as u64 * p as u64 / q as u64; + + // Can saturate if p > q + rem_part.saturated_into::() + }; + + // Can saturate if p > q + result_divisor_part.saturating_add(result_remainder_part) +} + +#[test] +fn test_multiply_by_rational_saturating() { + use std::convert::TryInto; + + let div = 100u32; + for value in 0..=div { + for p in 0..=div { + for q in 1..=div { + let value: u64 = (value as u128 * u64::max_value() as u128 / div as u128) + .try_into().unwrap(); + let p = (p as u64 * u32::max_value() as u64 / div as u64) + .try_into().unwrap(); + let q = (q as u64 * u32::max_value() as u64 / div as u64) + .try_into().unwrap(); + + assert_eq!( + multiply_by_rational_saturating(value, p, q), + (value as u128 * p as u128 / q as u128) + .try_into().unwrap_or(u64::max_value()) + ); + } + } + } +} + +#[test] +fn test_calculate_for_fraction_times_denominator() { + use std::convert::TryInto; + + let curve = PiecewiseLinear { + points: &[ + (Perbill::from_parts(0_000_000_000), Perbill::from_parts(0_500_000_000)), + (Perbill::from_parts(0_500_000_000), Perbill::from_parts(1_000_000_000)), + (Perbill::from_parts(1_000_000_000), Perbill::from_parts(0_000_000_000)), + ] + }; + + pub fn formal_calculate_for_fraction_times_denominator(n: u64, d: u64) -> u64 { + if n <= Perbill::from_parts(0_500_000_000) * d.clone() { + n + d / 2 + } else { + (d as u128 * 2 - n as u128 * 2).try_into().unwrap() + } + } + + let div = 100u32; + for d in 0..=div { + for n in 0..=d { + let d: u64 = (d as u128 * u64::max_value() as u128 / div as u128) + .try_into().unwrap(); + let n: u64 = (n as u128 * u64::max_value() as u128 / div as u128) + .try_into().unwrap(); + + let res = curve.calculate_for_fraction_times_denominator(n, d); + let expected = formal_calculate_for_fraction_times_denominator(n, d); + + assert!(abs_sub(res, expected) <= 1); + } + } +} diff --git a/core/sr-primitives/src/generic/checked_extrinsic.rs b/core/sr-primitives/src/generic/checked_extrinsic.rs index 08d7b10386721764ca2bad5cf627961b723a6b6a..e8d41325c432427c52e3c08333321167749ceb00 100644 --- a/core/sr-primitives/src/generic/checked_extrinsic.rs +++ b/core/sr-primitives/src/generic/checked_extrinsic.rs @@ -17,10 +17,8 @@ //! Generic implementation of an extrinsic that has passed the verification //! stage. -use rstd::result::Result; use crate::traits::{ - self, Member, MaybeDisplay, SignedExtension, DispatchError, Dispatchable, DispatchResult, - ValidateUnsigned + self, Member, MaybeDisplay, SignedExtension, Dispatchable, ValidateUnsigned, }; use crate::weights::{GetDispatchInfo, DispatchInfo}; use crate::transaction_validity::TransactionValidity; @@ -55,28 +53,24 @@ where self.signed.as_ref().map(|x| &x.0) } - fn validate>(&self, + fn validate>( + &self, info: DispatchInfo, len: usize, ) -> TransactionValidity { if let Some((ref id, ref extra)) = self.signed { - Extra::validate(extra, id, &self.function, info, len).into() + Extra::validate(extra, id, &self.function, info, len) } else { - match Extra::validate_unsigned(&self.function, info, len) { - Ok(extra) => match U::validate_unsigned(&self.function) { - TransactionValidity::Valid(v) => - TransactionValidity::Valid(v.combine_with(extra)), - x => x, - }, - x => x.into(), - } + let valid = Extra::validate_unsigned(&self.function, info, len)?; + Ok(valid.combine_with(U::validate_unsigned(&self.function)?)) } } - fn dispatch(self, + fn apply( + self, info: DispatchInfo, len: usize, - ) -> Result { + ) -> crate::ApplyResult { let (maybe_who, pre) = if let Some((id, extra)) = self.signed { let pre = Extra::pre_dispatch(extra, &id, &self.function, info, len)?; (Some(id), pre) @@ -86,7 +80,7 @@ where }; let res = self.function.dispatch(Origin::from(maybe_who)); Extra::post_dispatch(pre, info, len); - Ok(res) + Ok(res.map_err(Into::into)) } } diff --git a/core/sr-primitives/src/generic/mod.rs b/core/sr-primitives/src/generic/mod.rs index 1511753d2c5241981e7910c618fa76d18cea5062..0138a15aee21a2e7259a54cfaefc02ce4b519145 100644 --- a/core/sr-primitives/src/generic/mod.rs +++ b/core/sr-primitives/src/generic/mod.rs @@ -27,7 +27,7 @@ mod digest; #[cfg(test)] mod tests; -pub use self::unchecked_extrinsic::UncheckedExtrinsic; +pub use self::unchecked_extrinsic::{UncheckedExtrinsic, SignedPayload}; pub use self::era::{Era, Phase}; pub use self::checked_extrinsic::CheckedExtrinsic; pub use self::header::Header; diff --git a/core/sr-primitives/src/generic/unchecked_extrinsic.rs b/core/sr-primitives/src/generic/unchecked_extrinsic.rs index cb9330cfaaff0dad15939ebd9cc42575f7cb70e6..c5ee76e21c0114cbb63c409c7a33e3f68a1df97e 100644 --- a/core/sr-primitives/src/generic/unchecked_extrinsic.rs +++ b/core/sr-primitives/src/generic/unchecked_extrinsic.rs @@ -21,9 +21,11 @@ use std::fmt; use rstd::prelude::*; use runtime_io::blake2_256; -use crate::codec::{Decode, Encode, Input, Error}; -use crate::traits::{self, Member, MaybeDisplay, SignedExtension, Checkable, Extrinsic}; -use super::CheckedExtrinsic; +use codec::{Decode, Encode, EncodeLike, Input, Error}; +use crate::{ + traits::{self, Member, MaybeDisplay, SignedExtension, Checkable, Extrinsic}, + generic::CheckedExtrinsic, transaction_validity::{TransactionValidityError, InvalidTransaction}, +}; const TRANSACTION_VERSION: u8 = 3; @@ -72,12 +74,22 @@ impl Extrinsic { type Call = Call; + type SignaturePayload = ( + Address, + Signature, + Extra, + ); + fn is_signed(&self) -> Option { Some(self.signature.is_some()) } - fn new_unsigned(function: Call) -> Option { - Some(UncheckedExtrinsic::new_unsigned(function)) + fn new(function: Call, signed_data: Option) -> Option { + Some(if let Some((address, signature, extra)) = signed_data { + UncheckedExtrinsic::new_signed(function, address, signature, extra) + } else { + UncheckedExtrinsic::new_unsigned(function) + }) } } @@ -91,28 +103,25 @@ where Signature: Member + traits::Verify, Extra: SignedExtension, AccountId: Member + MaybeDisplay, - Lookup: traits::Lookup + Lookup: traits::Lookup, { type Checked = CheckedExtrinsic; - fn check(self, lookup: &Lookup) -> Result { + fn check(self, lookup: &Lookup) -> Result { Ok(match self.signature { Some((signed, signature, extra)) => { - let additional_signed = extra.additional_signed()?; - let raw_payload = (self.function, extra, additional_signed); let signed = lookup.lookup(signed)?; + let raw_payload = SignedPayload::new(self.function, extra)?; if !raw_payload.using_encoded(|payload| { - if payload.len() > 256 { - signature.verify(&blake2_256(payload)[..], &signed) - } else { - signature.verify(payload, &signed) - } + signature.verify(payload, &signed) }) { - return Err(crate::BAD_SIGNATURE) + return Err(InvalidTransaction::BadProof.into()) } + + let (function, extra, _) = raw_payload.deconstruct(); CheckedExtrinsic { - signed: Some((signed, raw_payload.1)), - function: raw_payload.0, + signed: Some((signed, extra)), + function, } } None => CheckedExtrinsic { @@ -123,6 +132,65 @@ where } } +/// A payload that has been signed for an unchecked extrinsics. +/// +/// Note that the payload that we sign to produce unchecked extrinsic signature +/// is going to be different than the `SignaturePayload` - so the thing the extrinsic +/// actually contains. +pub struct SignedPayload(( + Call, + Extra, + Extra::AdditionalSigned, +)); + +impl SignedPayload where + Call: Encode, + Extra: SignedExtension, +{ + /// Create new `SignedPayload`. + /// + /// This function may fail if `additional_signed` of `Extra` is not available. + pub fn new(call: Call, extra: Extra) -> Result { + let additional_signed = extra.additional_signed()?; + let raw_payload = (call, extra, additional_signed); + Ok(Self(raw_payload)) + } + + /// Create new `SignedPayload` from raw components. + pub fn from_raw(call: Call, extra: Extra, additional_signed: Extra::AdditionalSigned) -> Self { + Self((call, extra, additional_signed)) + } + + /// Deconstruct the payload into it's components. + pub fn deconstruct(self) -> (Call, Extra, Extra::AdditionalSigned) { + self.0 + } +} + +impl Encode for SignedPayload where + Call: Encode, + Extra: SignedExtension, +{ + /// Get an encoded version of this payload. + /// + /// Payloads longer than 256 bytes are going to be `blake2_256`-hashed. + fn using_encoded R>(&self, f: F) -> R { + self.0.using_encoded(|payload| { + if payload.len() > 256 { + f(&blake2_256(payload)[..]) + } else { + f(payload) + } + }) + } +} + +impl EncodeLike for SignedPayload +where + Call: Encode, + Extra: SignedExtension, +{} + impl Decode for UncheckedExtrinsic where @@ -178,6 +246,15 @@ where } } +impl EncodeLike + for UncheckedExtrinsic +where + Address: Encode, + Signature: Encode, + Call: Encode, + Extra: SignedExtension, +{} + #[cfg(feature = "std")] impl serde::Serialize for UncheckedExtrinsic @@ -196,7 +273,12 @@ where Extra: SignedExtension, { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - write!(f, "UncheckedExtrinsic({:?}, {:?})", self.signature.as_ref().map(|x| (&x.0, &x.2)), self.function) + write!( + f, + "UncheckedExtrinsic({:?}, {:?})", + self.signature.as_ref().map(|x| (&x.0, &x.2)), + self.function, + ) } } @@ -205,15 +287,10 @@ mod tests { use super::*; use runtime_io::blake2_256; use crate::codec::{Encode, Decode}; - use crate::traits::{SignedExtension, Lookup}; + use crate::traits::{SignedExtension, IdentityLookup}; use serde::{Serialize, Deserialize}; - struct TestContext; - impl Lookup for TestContext { - type Source = u64; - type Target = u64; - fn lookup(&self, s: u64) -> Result { Ok(s) } - } + type TestContext = IdentityLookup; #[derive(Eq, PartialEq, Clone, Debug, Serialize, Deserialize, Encode, Decode)] struct TestSig(u64, Vec); @@ -238,7 +315,7 @@ mod tests { type AdditionalSigned = (); type Pre = (); - fn additional_signed(&self) -> rstd::result::Result<(), &'static str> { Ok(()) } + fn additional_signed(&self) -> rstd::result::Result<(), TransactionValidityError> { Ok(()) } } type Ex = UncheckedExtrinsic; @@ -280,7 +357,7 @@ mod tests { fn unsigned_check_should_work() { let ux = Ex::new_unsigned(vec![0u8; 0]); assert!(!ux.is_signed().unwrap_or(false)); - assert!(>::check(ux, &TestContext).is_ok()); + assert!(>::check(ux, &Default::default()).is_ok()); } #[test] @@ -289,10 +366,13 @@ mod tests { vec![0u8; 0], TEST_ACCOUNT, TestSig(TEST_ACCOUNT, vec![0u8; 0]), - TestExtra + TestExtra, ); assert!(ux.is_signed().unwrap_or(false)); - assert_eq!(>::check(ux, &TestContext), Err(crate::BAD_SIGNATURE)); + assert_eq!( + >::check(ux, &Default::default()), + Err(InvalidTransaction::BadProof.into()), + ); } #[test] @@ -301,12 +381,12 @@ mod tests { vec![0u8; 0], TEST_ACCOUNT, TestSig(TEST_ACCOUNT, (vec![0u8; 0], TestExtra).encode()), - TestExtra + TestExtra, ); assert!(ux.is_signed().unwrap_or(false)); assert_eq!( - >::check(ux, &TestContext), - Ok(CEx { signed: Some((TEST_ACCOUNT, TestExtra)), function: vec![0u8; 0] }) + >::check(ux, &Default::default()), + Ok(CEx { signed: Some((TEST_ACCOUNT, TestExtra)), function: vec![0u8; 0] }), ); } diff --git a/core/sr-primitives/src/lib.rs b/core/sr-primitives/src/lib.rs index 636a97ce9200b917a874118b94e4f7b619a162c6..bdcbfb0b4606d8538c1555f95c545f368df4be90 100644 --- a/core/sr-primitives/src/lib.rs +++ b/core/sr-primitives/src/lib.rs @@ -17,7 +17,6 @@ //! Runtime Modules shared primitive types. #![warn(missing_docs)] - #![cfg_attr(not(feature = "std"), no_std)] #[doc(hidden)] @@ -37,41 +36,44 @@ pub use app_crypto; #[cfg(feature = "std")] pub use runtime_io::{StorageOverlay, ChildrenStorageOverlay}; -use rstd::{prelude::*, ops, convert::{TryInto, TryFrom}}; +use rstd::prelude::*; +use rstd::convert::TryFrom; use primitives::{crypto, ed25519, sr25519, hash::{H256, H512}}; -use codec::{Encode, Decode, CompactAs}; +use codec::{Encode, Decode}; #[cfg(feature = "std")] pub mod testing; -pub mod weights; -pub mod traits; -use traits::{SaturatedConversion, UniqueSaturatedInto, Saturating, Bounded, CheckedSub, CheckedAdd}; - +pub mod curve; pub mod generic; +pub mod offchain; +pub mod sr_arithmetic; +pub mod traits; pub mod transaction_validity; +pub mod weights; /// Re-export these since they're only "kind of" generic. pub use generic::{DigestItem, Digest}; /// Re-export this since it's part of the API of this crate. -pub use primitives::crypto::{key_types, KeyTypeId, CryptoType}; -pub use app_crypto::AppKey; - -/// A message indicating an invalid signature in extrinsic. -pub const BAD_SIGNATURE: &str = "bad signature in extrinsic"; - -/// Full block error message. -/// -/// This allows modules to indicate that given transaction is potentially valid -/// in the future, but can't be executed in the current state. -/// Note this error should be returned early in the execution to prevent DoS, -/// cause the fees are not being paid if this error is returned. +pub use primitives::{TypeId, crypto::{key_types, KeyTypeId, CryptoType}}; +pub use app_crypto::RuntimeAppPublic; + +/// Re-export arithmetic stuff. +pub use sr_arithmetic::{ + Perquintill, Perbill, Permill, Percent, + Rational128, Fixed64 +}; +/// Re-export 128 bit helpers from sr_arithmetic +pub use sr_arithmetic::helpers_128bit; + +/// An abstraction over justification for a block's validity under a consensus algorithm. /// -/// Example: block gas limit is reached (the transaction can be retried in the next block though). -pub const BLOCK_FULL: &str = "block size limit is reached"; - -/// Justification type. +/// Essentially a finality proof. The exact formulation will vary between consensus +/// algorithms. In the case where there are multiple valid proofs, inclusion within +/// the block itself would allow swapping justifications to change the block's hash +/// (and thus fork the chain). Sending a `Justification` alongside a block instead +/// bypasses this problem. pub type Justification = Vec; use traits::{Verify, Lazy}; @@ -80,7 +82,7 @@ use traits::{Verify, Lazy}; #[derive(Clone, Copy, Eq, PartialEq, Encode, Decode)] pub struct ModuleId(pub [u8; 8]); -impl traits::TypeId for ModuleId { +impl TypeId for ModuleId { const TYPE_ID: [u8; 4] = *b"modl"; } @@ -158,348 +160,6 @@ impl BuildStorage for (StorageOverlay, ChildrenStorageOverlay) { /// Consensus engine unique ID. pub type ConsensusEngineId = [u8; 4]; -/// Permill is parts-per-million (i.e. after multiplying by this, divide by 1000000). -#[cfg_attr(feature = "std", derive(Serialize, Deserialize, Debug, Ord, PartialOrd))] -#[derive(Encode, Decode, CompactAs, Default, Copy, Clone, PartialEq, Eq)] -pub struct Permill(u32); - -impl Permill { - /// Nothing. - pub fn zero() -> Self { Self(0) } - - /// `true` if this is nothing. - pub fn is_zero(&self) -> bool { self.0 == 0 } - - /// Everything. - pub fn one() -> Self { Self(1_000_000) } - - /// create a new raw instance. This can be called at compile time. - pub const fn from_const_parts(parts: u32) -> Self { - Self([parts, 1_000_000][(parts > 1_000_000) as usize]) - } - - /// From an explicitly defined number of parts per maximum of the type. - pub fn from_parts(parts: u32) -> Self { Self::from_const_parts(parts) } - - /// Converts from a percent. Equal to `x / 100`. - pub const fn from_percent(x: u32) -> Self { Self([x, 100][(x > 100) as usize] * 10_000) } - - /// Converts a fraction into `Permill`. - #[cfg(feature = "std")] - pub fn from_fraction(x: f64) -> Self { Self((x * 1_000_000.0) as u32) } - - /// Approximate the fraction `p/q` into a per million fraction - pub fn from_rational_approximation(p: N, q: N) -> Self - where N: traits::SimpleArithmetic + Clone - { - let p = p.min(q.clone()); - let factor = (q.clone() / 1_000_000u32.into()).max(1u32.into()); - - // Conversion can't overflow as p < q so ( p / (q/million)) < million - let p_reduce: u32 = (p / factor.clone()).try_into().unwrap_or_else(|_| panic!()); - let q_reduce: u32 = (q / factor.clone()).try_into().unwrap_or_else(|_| panic!()); - let part = p_reduce as u64 * 1_000_000u64 / q_reduce as u64; - - Permill(part as u32) - } -} - -impl ops::Mul for Permill -where - N: Clone + From + UniqueSaturatedInto + ops::Rem - + ops::Div + ops::Mul + ops::Add, -{ - type Output = N; - fn mul(self, b: N) -> Self::Output { - let million: N = 1_000_000.into(); - let part: N = self.0.into(); - - let rem_multiplied_divided = { - let rem = b.clone().rem(million.clone()); - - // `rem` is inferior to one million, thus it fits into u32 - let rem_u32 = rem.saturated_into::(); - - // `self` and `rem` are inferior to one million, thus the product is less than 10^12 - // and fits into u64 - let rem_multiplied_u64 = rem_u32 as u64 * self.0 as u64; - - // `rem_multiplied_u64` is less than 10^12 therefore divided by a million it fits into - // u32 - let rem_multiplied_divided_u32 = (rem_multiplied_u64 / 1_000_000) as u32; - - // `rem_multiplied_divided` is inferior to b, thus it can be converted back to N type - rem_multiplied_divided_u32.into() - }; - - (b / million) * part + rem_multiplied_divided - } -} - -#[cfg(feature = "std")] -impl From for Permill { - fn from(x: f64) -> Permill { - Permill::from_fraction(x) - } -} - -#[cfg(feature = "std")] -impl From for Permill { - fn from(x: f32) -> Permill { - Permill::from_fraction(x as f64) - } -} - -/// Perbill is parts-per-billion. It stores a value between 0 and 1 in fixed point and -/// provides a means to multiply some other value by that. -#[cfg_attr(feature = "std", derive(Serialize, Deserialize, Debug))] -#[derive(Encode, Decode, CompactAs, Default, Copy, Clone, PartialEq, Eq, Ord, PartialOrd)] -pub struct Perbill(u32); - -impl Perbill { - /// Nothing. - pub fn zero() -> Self { Self(0) } - - /// `true` if this is nothing. - pub fn is_zero(&self) -> bool { self.0 == 0 } - - /// Everything. - pub fn one() -> Self { Self(1_000_000_000) } - - /// create a new raw instance. This can be called at compile time. - pub const fn from_const_parts(parts: u32) -> Self { - Self([parts, 1_000_000_000][(parts > 1_000_000_000) as usize]) - } - - /// From an explicitly defined number of parts per maximum of the type. - pub fn from_parts(parts: u32) -> Self { Self::from_const_parts(parts) } - - /// Converts from a percent. Equal to `x / 100`. - pub const fn from_percent(x: u32) -> Self { Self([x, 100][(x > 100) as usize] * 10_000_000) } - - /// Construct new instance where `x` is in millionths. Value equivalent to `x / 1,000,000`. - pub fn from_millionths(x: u32) -> Self { Self(x.min(1_000_000) * 1000) } - - #[cfg(feature = "std")] - /// Construct new instance whose value is equal to `x` (between 0 and 1). - pub fn from_fraction(x: f64) -> Self { Self((x.max(0.0).min(1.0) * 1_000_000_000.0) as u32) } - - /// Approximate the fraction `p/q` into a per billion fraction - pub fn from_rational_approximation(p: N, q: N) -> Self - where N: traits::SimpleArithmetic + Clone - { - let p = p.min(q.clone()); - let factor = (q.clone() / 1_000_000_000u32.into()).max(1u32.into()); - - // Conversion can't overflow as p < q so ( p / (q/billion)) < billion - let p_reduce: u32 = (p / factor.clone()).try_into().unwrap_or_else(|_| panic!()); - let q_reduce: u32 = (q / factor.clone()).try_into().unwrap_or_else(|_| panic!()); - let part = p_reduce as u64 * 1_000_000_000u64 / q_reduce as u64; - - Perbill(part as u32) - } -} - -impl ops::Mul for Perbill -where - N: Clone + From + UniqueSaturatedInto + ops::Rem - + ops::Div + ops::Mul + ops::Add, -{ - type Output = N; - fn mul(self, b: N) -> Self::Output { - let billion: N = 1_000_000_000.into(); - let part: N = self.0.into(); - - let rem_multiplied_divided = { - let rem = b.clone().rem(billion.clone()); - - // `rem` is inferior to one billion, thus it fits into u32 - let rem_u32 = rem.saturated_into::(); - - // `self` and `rem` are inferior to one billion, thus the product is less than 10^18 - // and fits into u64 - let rem_multiplied_u64 = rem_u32 as u64 * self.0 as u64; - - // `rem_multiplied_u64` is less than 10^18 therefore divided by a billion it fits into - // u32 - let rem_multiplied_divided_u32 = (rem_multiplied_u64 / 1_000_000_000) as u32; - - // `rem_multiplied_divided` is inferior to b, thus it can be converted back to N type - rem_multiplied_divided_u32.into() - }; - - (b / billion) * part + rem_multiplied_divided - } -} - -#[cfg(feature = "std")] -impl From for Perbill { - fn from(x: f64) -> Perbill { - Perbill::from_fraction(x) - } -} - -#[cfg(feature = "std")] -impl From for Perbill { - fn from(x: f32) -> Perbill { - Perbill::from_fraction(x as f64) - } -} - -/// A fixed point number by the scale of 1 billion. -/// -/// cannot hold a value larger than +-`9223372036854775807 / 1_000_000_000` (~9 billion). -#[cfg_attr(feature = "std", derive(Debug))] -#[derive(Encode, Decode, Default, Copy, Clone, PartialEq, Eq, PartialOrd, Ord)] -pub struct Fixed64(i64); - -/// The maximum value of the `Fixed64` type -const DIV: i64 = 1_000_000_000; - -impl Fixed64 { - /// creates self from a natural number. - /// - /// Note that this might be lossy. - pub fn from_natural(int: i64) -> Self { - Self(int.saturating_mul(DIV)) - } - - /// Return the accuracy of the type. Given that this function returns the value `X`, it means - /// that an instance composed of `X` parts (`Fixed64::from_parts(X)`) is equal to `1`. - pub fn accuracy() -> i64 { - DIV - } - - /// creates self from a rational number. Equal to `n/d`. - /// - /// Note that this might be lossy. - pub fn from_rational(n: i64, d: u64) -> Self { - Self((n as i128 * DIV as i128 / (d as i128).max(1)).try_into().unwrap_or(Bounded::max_value())) - } - - /// Performs a saturated multiply and accumulate. - /// - /// Returns a saturated `n + (self * n)`. - /// TODO: generalize this to any weight type. #3189 - pub fn saturated_multiply_accumulate(&self, int: u32) -> u32 { - let parts = self.0; - let positive = parts > 0; - - // natural parts might overflow. - let natural_parts = self.clone().saturated_into::(); - // fractional parts can always fit into u32. - let perbill_parts = (parts.abs() % DIV) as u32; - - let n = int.saturating_mul(natural_parts); - let p = Perbill::from_parts(perbill_parts) * int; - // everything that needs to be either added or subtracted from the original weight. - let excess = n.saturating_add(p); - - if positive { - int.saturating_add(excess) - } else { - int.saturating_sub(excess) - } - } - - /// Raw constructor. Equal to `parts / 1_000_000_000`. - pub fn from_parts(parts: i64) -> Self { - Self(parts) - } -} - -impl UniqueSaturatedInto for Fixed64 { - /// Note that the maximum value of Fixed64 might be more than what can fit in u32. This is hence, - /// expected to be lossy. - fn unique_saturated_into(self) -> u32 { - (self.0.abs() / DIV).try_into().unwrap_or(Bounded::max_value()) - } -} - -impl Saturating for Fixed64 { - fn saturating_add(self, rhs: Self) -> Self { - Self(self.0.saturating_add(rhs.0)) - } - fn saturating_mul(self, rhs: Self) -> Self { - Self(self.0.saturating_mul(rhs.0) / DIV) - } - fn saturating_sub(self, rhs: Self) -> Self { - Self(self.0.saturating_sub(rhs.0)) - } -} - -/// Note that this is a standard, _potentially-panicking_, implementation. Use `Saturating` trait -/// for safe addition. -impl ops::Add for Fixed64 { - type Output = Self; - - fn add(self, rhs: Self) -> Self::Output { - Self(self.0 + rhs.0) - } -} - -/// Note that this is a standard, _potentially-panicking_, implementation. Use `Saturating` trait -/// for safe subtraction. -impl ops::Sub for Fixed64 { - type Output = Self; - - fn sub(self, rhs: Self) -> Self::Output { - Self(self.0 - rhs.0) - } -} - -impl CheckedSub for Fixed64 { - fn checked_sub(&self, rhs: &Self) -> Option { - if let Some(v) = self.0.checked_sub(rhs.0) { - Some(Self(v)) - } else { - None - } - } -} - -impl CheckedAdd for Fixed64 { - fn checked_add(&self, rhs: &Self) -> Option { - if let Some(v) = self.0.checked_add(rhs.0) { - Some(Self(v)) - } else { - None - } - } -} - -/// PerU128 is parts-per-u128-max-value. It stores a value between 0 and 1 in fixed point. -#[cfg_attr(feature = "std", derive(Serialize, Deserialize, Debug))] -#[derive(Encode, Decode, CompactAs, Default, Copy, Clone, PartialEq, Eq)] -pub struct PerU128(u128); - -const U128: u128 = u128::max_value(); - -impl PerU128 { - /// Nothing. - pub fn zero() -> Self { Self(0) } - - /// `true` if this is nothing. - pub fn is_zero(&self) -> bool { self.0 == 0 } - - /// Everything. - pub fn one() -> Self { Self(U128) } - - /// From an explicitly defined number of parts per maximum of the type. - pub fn from_parts(x: u128) -> Self { Self(x) } - - /// Construct new instance where `x` is denominator and the nominator is 1. - pub fn from_xth(x: u128) -> Self { Self(U128/x.max(1)) } -} - -impl ::rstd::ops::Deref for PerU128 { - type Target = u128; - - fn deref(&self) -> &u128 { - &self.0 - } -} - /// Signature verify that can work with any known signature types.. #[derive(Eq, PartialEq, Clone, Encode, Decode)] #[cfg_attr(feature = "std", derive(Debug))] @@ -624,53 +284,111 @@ impl From for AnySignature { } } -#[derive(Eq, PartialEq, Clone, Copy, Decode)] +#[derive(Eq, PartialEq, Clone, Copy, Decode, Encode)] #[cfg_attr(feature = "std", derive(Debug, Serialize))] -#[repr(u8)] -/// Outcome of a valid extrinsic application. Capable of being sliced. -pub enum ApplyOutcome { - /// Successful application (extrinsic reported no issue). - Success = 0, - /// Failed application (extrinsic was probably a no-op other than fees). - Fail = 1, +/// Reason why an extrinsic couldn't be applied (i.e. invalid extrinsic). +pub enum ApplyError { + /// General error to do with the permissions of the sender. + NoPermission, + + /// General error to do with the state of the system in general. + BadState, + + /// Any error to do with the transaction validity. + Validity(transaction_validity::TransactionValidityError), } -impl codec::Encode for ApplyOutcome { - fn using_encoded R>(&self, f: F) -> R { - f(&[*self as u8]) +impl ApplyError { + /// Returns if the reason for the error was block resource exhaustion. + pub fn exhausted_resources(&self) -> bool { + match self { + Self::Validity(e) => e.exhausted_resources(), + _ => false, + } } } -impl codec::EncodeLike for ApplyOutcome {} - -#[derive(Eq, PartialEq, Clone, Copy, Decode)] -#[cfg_attr(feature = "std", derive(Debug, Serialize))] -#[repr(u8)] -/// Reason why an extrinsic couldn't be applied (i.e. invalid extrinsic). -pub enum ApplyError { - /// Bad signature. - BadSignature = 0, - /// Nonce too low. - Stale = 1, - /// Nonce too high. - Future = 2, - /// Sending account had too low a balance. - CantPay = 3, - /// Block is full, no more extrinsics can be applied. - FullBlock = 255, +impl From for &'static str { + fn from(err: ApplyError) -> &'static str { + match err { + ApplyError::NoPermission => "Transaction does not have required permissions", + ApplyError::BadState => "System state currently prevents this transaction", + ApplyError::Validity(v) => v.into(), + } + } } -impl codec::Encode for ApplyError { - fn using_encoded R>(&self, f: F) -> R { - f(&[*self as u8]) +impl From for ApplyError { + fn from(err: transaction_validity::TransactionValidityError) -> Self { + ApplyError::Validity(err) } } -impl codec::EncodeLike for ApplyError {} +/// The outcome of applying a transaction. +pub type ApplyOutcome = Result<(), DispatchError>; + +impl From for ApplyOutcome { + fn from(err: DispatchError) -> Self { + Err(err) + } +} /// Result from attempt to apply an extrinsic. pub type ApplyResult = Result; +#[derive(Eq, PartialEq, Clone, Copy, Encode, Decode)] +#[cfg_attr(feature = "std", derive(Debug, Serialize))] +/// Reason why a dispatch call failed +pub struct DispatchError { + /// Module index, matching the metadata module index + pub module: Option, + /// Module specific error value + pub error: u8, + /// Optional error message. + #[codec(skip)] + pub message: Option<&'static str>, +} + +impl DispatchError { + /// Create a new instance of `DispatchError`. + pub fn new(module: Option, error: u8, message: Option<&'static str>) -> Self { + Self { + module, + error, + message, + } + } +} + +impl traits::Printable for DispatchError { + fn print(&self) { + "DispatchError".print(); + if let Some(module) = self.module { + module.print(); + } + self.error.print(); + if let Some(msg) = self.message { + msg.print(); + } + } +} + +impl traits::ModuleDispatchError for &'static str { + fn as_u8(&self) -> u8 { + 0 + } + + fn as_str(&self) -> &'static str { + self + } +} + +impl From<&'static str> for DispatchError { + fn from(err: &'static str) -> DispatchError { + DispatchError::new(None, 0, Some(err)) + } +} + /// Verify a signature on an encoded value in a lazy manner. This can be /// an optimization if the signature scheme has an "unsigned" escape hash. pub fn verify_encoded_lazy(sig: &V, item: &T, signer: &V::Signer) -> bool { @@ -805,6 +523,37 @@ macro_rules! impl_outer_config { } } +/// Checks that `$x` is equal to `$y` with an error rate of `$error`. +/// +/// # Example +/// +/// ```rust +/// # fn main() { +/// sr_primitives::assert_eq_error_rate!(10, 10, 0); +/// sr_primitives::assert_eq_error_rate!(10, 11, 1); +/// sr_primitives::assert_eq_error_rate!(12, 10, 2); +/// # } +/// ``` +/// +/// ```rust,should_panic +/// # fn main() { +/// sr_primitives::assert_eq_error_rate!(12, 10, 1); +/// # } +/// ``` +#[macro_export] +#[cfg(feature = "std")] +macro_rules! assert_eq_error_rate { + ($x:expr, $y:expr, $error:expr $(,)?) => { + assert!( + ($x) >= (($y) - ($error)) && ($x) <= (($y) + ($error)), + "{:?} != {:?} (with error rate {:?})", + $x, + $y, + $error, + ); + }; +} + /// Simple blob to hold an extrinsic without committing to its format and ensure it is serialized /// correctly. #[derive(PartialEq, Eq, Clone, Default, Encode, Decode)] @@ -835,50 +584,18 @@ impl<'a> ::serde::Deserialize<'a> for OpaqueExtrinsic { impl traits::Extrinsic for OpaqueExtrinsic { type Call = (); + type SignaturePayload = (); +} - fn is_signed(&self) -> Option { - None - } - - fn new_unsigned(_call: Self::Call) -> Option { None } +/// Print something that implements `Printable` from the runtime. +pub fn print(print: impl traits::Printable) { + print.print(); } #[cfg(test)] mod tests { - use crate::codec::{Encode, Decode}; - use super::{Perbill, Permill}; - - macro_rules! per_thing_upper_test { - ($num_type:tt, $per:tt) => { - // multiplication from all sort of from_percent - assert_eq!($per::from_percent(100) * $num_type::max_value(), $num_type::max_value()); - assert_eq!( - $per::from_percent(99) * $num_type::max_value(), - ((Into::::into($num_type::max_value()) * 99u32) / 100u32).as_u128() as $num_type - ); - assert_eq!($per::from_percent(50) * $num_type::max_value(), $num_type::max_value() / 2); - assert_eq!($per::from_percent(1) * $num_type::max_value(), $num_type::max_value() / 100); - assert_eq!($per::from_percent(0) * $num_type::max_value(), 0); - - // multiplication with bounds - assert_eq!($per::one() * $num_type::max_value(), $num_type::max_value()); - assert_eq!($per::zero() * $num_type::max_value(), 0); - - // from_rational_approximation - assert_eq!( - $per::from_rational_approximation(u128::max_value() - 1, u128::max_value()), - $per::one(), - ); - assert_eq!( - $per::from_rational_approximation(u128::max_value()/3, u128::max_value()), - $per::from_parts($per::one().0/3), - ); - assert_eq!( - $per::from_rational_approximation(1, u128::max_value()), - $per::zero(), - ); - } - } + use crate::DispatchError; + use codec::{Encode, Decode}; #[test] fn opaque_extrinsic_serialization() { @@ -887,76 +604,22 @@ mod tests { } #[test] - fn compact_permill_perbill_encoding() { - let tests = [(0u32, 1usize), (63, 1), (64, 2), (16383, 2), (16384, 4), (1073741823, 4), (1073741824, 5), (u32::max_value(), 5)]; - for &(n, l) in &tests { - let compact: crate::codec::Compact = Permill(n).into(); - let encoded = compact.encode(); - assert_eq!(encoded.len(), l); - let decoded = >::decode(&mut & encoded[..]).unwrap(); - let permill: Permill = decoded.into(); - assert_eq!(permill, Permill(n)); - - let compact: crate::codec::Compact = Perbill(n).into(); - let encoded = compact.encode(); - assert_eq!(encoded.len(), l); - let decoded = >::decode(&mut & encoded[..]).unwrap(); - let perbill: Perbill = decoded.into(); - assert_eq!(perbill, Perbill(n)); - } - } - - #[derive(Encode, Decode, PartialEq, Eq, Debug)] - struct WithCompact { - data: T, - } - - #[test] - fn test_has_compact_permill() { - let data = WithCompact { data: Permill(1) }; - let encoded = data.encode(); - assert_eq!(data, WithCompact::::decode(&mut &encoded[..]).unwrap()); - } - - #[test] - fn test_has_compact_perbill() { - let data = WithCompact { data: Perbill(1) }; - let encoded = data.encode(); - assert_eq!(data, WithCompact::::decode(&mut &encoded[..]).unwrap()); - } - - #[test] - fn per_things_should_work() { - use super::{Perbill, Permill}; - use primitive_types::U256; - - per_thing_upper_test!(u32, Perbill); - per_thing_upper_test!(u64, Perbill); - per_thing_upper_test!(u128, Perbill); - - per_thing_upper_test!(u32, Permill); - per_thing_upper_test!(u64, Permill); - per_thing_upper_test!(u128, Permill); - - } - - #[test] - fn per_things_operate_in_output_type() { - assert_eq!(Perbill::one() * 255_u64, 255); - } - - #[test] - fn per_things_one_minus_one_part() { - use primitive_types::U256; - - assert_eq!( - Perbill::from_parts(999_999_999) * std::u128::MAX, - ((Into::::into(std::u128::MAX) * 999_999_999u32) / 1_000_000_000u32).as_u128() - ); - + fn dispatch_error_encoding() { + let error = DispatchError { + module: Some(1), + error: 2, + message: Some("error message"), + }; + let encoded = error.encode(); + let decoded = DispatchError::decode(&mut &encoded[..]).unwrap(); + assert_eq!(encoded, vec![1, 1, 2]); assert_eq!( - Permill::from_parts(999_999) * std::u128::MAX, - ((Into::::into(std::u128::MAX) * 999_999u32) / 1_000_000u32).as_u128() + decoded, + DispatchError { + module: Some(1), + error: 2, + message: None, + }, ); } } diff --git a/core/sr-io/src/offchain/http.rs b/core/sr-primitives/src/offchain/http.rs similarity index 88% rename from core/sr-io/src/offchain/http.rs rename to core/sr-primitives/src/offchain/http.rs index 6685dd023f469e607b59cfcf7509b629c58bde94..6df18da83ec5a09204fa491443b858ee2ad0b907 100644 --- a/core/sr-io/src/offchain/http.rs +++ b/core/sr-primitives/src/offchain/http.rs @@ -14,7 +14,38 @@ // You should have received a copy of the GNU General Public License // along with Substrate. If not, see . -//! A non-std set of HTTP types. +//! A high-level helpers for making HTTP requests from Offchain Workers. +//! +//! `sr-io` crate exposes a low level methods to make and control HTTP requests +//! available only for Offchain Workers. Those might be hard to use +//! and usually that level of control is not really necessary. +//! This module aims to provide high-level wrappers for those APIs +//! to simplify making HTTP requests. +//! +//! +//! Example: +//! ```rust,no_run +//! use sr_primitives::offchain::http::Request; +//! +//! // initiate a GET request to localhost:1234 +//! let request: Request = Request::get("http://localhost:1234"); +//! let pending = request +//! .add_header("X-Auth", "hunter2") +//! .send() +//! .unwrap(); +//! +//! // wait for the response indefinitely +//! let mut response = pending.wait().unwrap(); +//! +//! // then check the headers +//! let mut headers = response.headers().into_iter(); +//! assert_eq!(headers.current(), None); +//! +//! // and collect the body +//! let body = response.body(); +//! assert_eq!(body.clone().collect::>(), b"1234".to_vec()); +//! assert_eq!(body.error(), &None); +//! ``` use rstd::str; use rstd::prelude::Vec; @@ -192,11 +223,11 @@ impl<'a, I: AsRef<[u8]>, T: IntoIterator> Request<'a, T> { let meta = &[]; // start an http request. - let id = crate::http_request_start(self.method.as_ref(), self.url, meta).map_err(|_| HttpError::IoError)?; + let id = runtime_io::http_request_start(self.method.as_ref(), self.url, meta).map_err(|_| HttpError::IoError)?; // add custom headers for header in &self.headers { - crate::http_request_add_header( + runtime_io::http_request_add_header( id, header.name(), header.value(), @@ -205,11 +236,11 @@ impl<'a, I: AsRef<[u8]>, T: IntoIterator> Request<'a, T> { // write body for chunk in self.body { - crate::http_request_write_body(id, chunk.as_ref(), self.deadline)?; + runtime_io::http_request_write_body(id, chunk.as_ref(), self.deadline)?; } // finalise the request - crate::http_request_write_body(id, &[], self.deadline)?; + runtime_io::http_request_write_body(id, &[], self.deadline)?; Ok(PendingRequest { id, @@ -224,7 +255,7 @@ pub enum Error { /// Deadline has been reached. DeadlineReached, /// Request had timed out. - Timeout, + IoError, /// Unknown error has been ecountered. Unknown, } @@ -276,15 +307,15 @@ impl PendingRequest { deadline: impl Into> ) -> Vec> { let ids = requests.iter().map(|r| r.id).collect::>(); - let statuses = crate::http_response_wait(&ids, deadline.into()); + let statuses = runtime_io::http_response_wait(&ids, deadline.into()); statuses .into_iter() .zip(requests.into_iter()) .map(|(status, req)| match status { RequestStatus::DeadlineReached => Err(req), - RequestStatus::Timeout => Ok(Err(Error::Timeout)), - RequestStatus::Unknown => Ok(Err(Error::Unknown)), + RequestStatus::IoError => Ok(Err(Error::IoError)), + RequestStatus::Invalid => Ok(Err(Error::Unknown)), RequestStatus::Finished(code) => Ok(Ok(Response::new(req.id, code))), }) .collect() @@ -314,7 +345,7 @@ impl Response { /// Retrieve the headers for this response. pub fn headers(&mut self) -> &Headers { if self.headers.is_none() { - self.headers = Some(Headers { raw: crate::http_response_headers(self.id) }); + self.headers = Some(Headers { raw: runtime_io::http_response_headers(self.id) }); } self.headers.as_ref().expect("Headers were just set; qed") } @@ -393,7 +424,7 @@ impl Iterator for ResponseBody { } if self.filled_up_to.is_none() { - let result = crate::http_response_read_body(self.id, &mut self.buffer, self.deadline); + let result = runtime_io::http_response_read_body(self.id, &mut self.buffer, self.deadline); match result { Err(e) => { self.error = Some(e); @@ -481,7 +512,7 @@ impl<'a> HeadersIterator<'a> { #[cfg(test)] mod tests { use super::*; - use crate::{TestExternalities, with_externalities}; + use runtime_io::{TestExternalities, with_externalities}; use substrate_offchain::testing; #[test] diff --git a/core/sr-io/src/offchain/mod.rs b/core/sr-primitives/src/offchain/mod.rs similarity index 100% rename from core/sr-io/src/offchain/mod.rs rename to core/sr-primitives/src/offchain/mod.rs diff --git a/core/sr-primitives/src/sr_arithmetic.rs b/core/sr-primitives/src/sr_arithmetic.rs new file mode 100644 index 0000000000000000000000000000000000000000..20a7f51c1f1b5fb5f5dd1b18ad5a5bc0e31bd6c3 --- /dev/null +++ b/core/sr-primitives/src/sr_arithmetic.rs @@ -0,0 +1,1373 @@ +// Copyright 2019 Parity Technologies (UK) Ltd. +// This file is part of Substrate. + +// Substrate 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. + +// Substrate 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 Substrate. If not, see . + +//! Minimal fixed point arithmetic primitives and types for runtime. + +#[cfg(feature = "std")] +use crate::serde::{Serialize, Deserialize}; + +use rstd::{ + ops, prelude::*, + convert::{TryInto, TryFrom}, + cmp::Ordering, +}; +use codec::{Encode, Decode}; +use crate::traits::{ + SaturatedConversion, CheckedSub, CheckedAdd, Bounded, UniqueSaturatedInto, Saturating, Zero, +}; + +macro_rules! implement_per_thing { + ($name:ident, $test_mod:ident, [$($test_units:tt),+], $max:tt, $type:ty, $upper_type:ty, $title:expr $(,)?) => { + /// A fixed point representation of a number between in the range [0, 1]. + /// + #[doc = $title] + #[cfg_attr(feature = "std", derive(Serialize, Deserialize, Debug, Ord, PartialOrd))] + #[derive(Encode, Decode, Default, Copy, Clone, PartialEq, Eq)] + pub struct $name($type); + + impl $name { + /// Nothing. + pub fn zero() -> Self { Self(0) } + + /// `true` if this is nothing. + pub fn is_zero(&self) -> bool { self.0 == 0 } + + /// Everything. + pub fn one() -> Self { Self($max) } + + /// Consume self and deconstruct into a raw numeric type. + pub fn deconstruct(self) -> $type { self.0 } + + /// Return the scale at which this per-thing is working. + pub const fn accuracy() -> $type { $max } + + /// From an explicitly defined number of parts per maximum of the type. + /// + /// This can be called at compile time. + pub const fn from_parts(parts: $type) -> Self { + Self([parts, $max][(parts > $max) as usize]) + } + + /// Converts from a percent. Equal to `x / 100`. + /// + /// This can be created at compile time. + pub const fn from_percent(x: $type) -> Self { + Self([x, 100][(x > 100) as usize] * ($max / 100)) + } + + /// Return the product of multiplication of this value by itself. + pub fn square(self) -> Self { + // both can be safely casted and multiplied. + let p: $upper_type = self.0 as $upper_type * self.0 as $upper_type; + let q: $upper_type = $max as $upper_type * $max as $upper_type; + Self::from_rational_approximation(p, q) + } + + /// Converts a fraction into `Permill`. + #[cfg(feature = "std")] + pub fn from_fraction(x: f64) -> Self { Self((x * ($max as f64)) as $type) } + + /// Approximate the fraction `p/q` into a per-thing fraction. This will never overflow. + /// + /// The computation of this approximation is performed in the generic type `N`. Given + /// `M` as the data type that can hold the maximum value of this per-thing (e.g. u32 for + /// perbill), this can only work if `N == M` or `N: From + TryInto`. + pub fn from_rational_approximation(p: N, q: N) -> Self + where N: Clone + Ord + From<$type> + TryInto<$type> + ops::Div + { + // q cannot be zero. + let q = q.max((1 as $type).into()); + // p should not be bigger than q. + let p = p.min(q.clone()); + + let factor = (q.clone() / $max.into()).max((1 as $type).into()); + + // q cannot overflow: (q / (q/$max)) < 2 * $max. p < q hence p also cannot overflow. + // this implies that $type must be able to fit 2 * $max. + let q_reduce: $type = (q / factor.clone()) + .try_into() + .map_err(|_| "Failed to convert") + .expect( + "q / (q/$max) < (2 * $max). Macro prevents any type being created that \ + does not satisfy this; qed" + ); + let p_reduce: $type = (p / factor.clone()) + .try_into() + .map_err(|_| "Failed to convert") + .expect( + "q / (q/$max) < (2 * $max). Macro prevents any type being created that \ + does not satisfy this; qed" + ); + + // `p_reduced` and `q_reduced` are withing $type. Mul by another $max will always + // fit in $upper_type. This is guaranteed by the macro tests. + let part = + p_reduce as $upper_type + * ($max as $upper_type) + / q_reduce as $upper_type; + + $name(part as $type) + } + } + + impl Saturating for $name { + fn saturating_add(self, rhs: Self) -> Self { + // defensive-only: since `$max * 2 < $type::max_value()`, this can never overflow. + Self::from_parts(self.0.saturating_add(rhs.0)) + } + fn saturating_sub(self, rhs: Self) -> Self { + Self::from_parts(self.0.saturating_sub(rhs.0)) + } + fn saturating_mul(self, rhs: Self) -> Self { + let a = self.0 as $upper_type; + let b = rhs.0 as $upper_type; + let m = $max as $upper_type; + let parts = a * b / m; + // This will always fit into $type. + Self::from_parts(parts as $type) + } + } + + impl ops::Div for $name { + type Output = Self; + + fn div(self, rhs: Self) -> Self::Output { + let p = self.0; + let q = rhs.0; + Self::from_rational_approximation(p, q) + } + } + + /// Overflow-prune multiplication. + /// + /// tailored to be used with a balance type. + impl ops::Mul for $name + where + N: Clone + From<$type> + UniqueSaturatedInto<$type> + ops::Rem + + ops::Div + ops::Mul + ops::Add, + { + type Output = N; + fn mul(self, b: N) -> Self::Output { + let maximum: N = $max.into(); + let upper_max: $upper_type = $max.into(); + let part: N = self.0.into(); + + let rem_multiplied_divided = { + let rem = b.clone().rem(maximum.clone()); + + // `rem_sized` is inferior to $max, thus it fits into $type. This is assured by + // a test. + let rem_sized = rem.saturated_into::<$type>(); + + // `self` and `rem_sized` are inferior to $max, thus the product is less than + // $max^2 and fits into $upper_type. This is assured by a test. + let rem_multiplied_upper = rem_sized as $upper_type * self.0 as $upper_type; + + // `rem_multiplied_upper` is less than $max^2 therefore divided by $max it fits + // in $type. remember that $type always fits $max. + let mut rem_multiplied_divided_sized = + (rem_multiplied_upper / upper_max) as $type; + // fix a tiny rounding error + if rem_multiplied_upper % upper_max > upper_max / 2 { + rem_multiplied_divided_sized += 1; + } + + // `rem_multiplied_divided_sized` is inferior to b, thus it can be converted + // back to N type + rem_multiplied_divided_sized.into() + }; + + (b / maximum) * part + rem_multiplied_divided + } + } + + impl codec::CompactAs for $name { + type As = $type; + fn encode_as(&self) -> &$type { + &self.0 + } + fn decode_from(x: $type) -> Self { + Self(x) + } + } + + impl From> for $name { + fn from(x: codec::Compact<$name>) -> Self { + x.0 + } + } + + #[cfg(test)] + mod $test_mod { + use codec::{Encode, Decode}; + use super::{$name, Saturating}; + use crate::{assert_eq_error_rate, traits::Zero}; + + + #[test] + fn macro_expanded_correctly() { + // needed for the `from_percent` to work. + assert!($max >= 100); + assert!($max % 100 == 0); + + // needed for `from_rational_approximation` + assert!(2 * $max < <$type>::max_value()); + assert!(($max as $upper_type) < <$upper_type>::max_value()); + + // for something like percent they can be the same. + assert!((<$type>::max_value() as $upper_type) <= <$upper_type>::max_value()); + assert!(($max as $upper_type).checked_mul($max.into()).is_some()); + } + + #[derive(Encode, Decode, PartialEq, Eq, Debug)] + struct WithCompact { + data: T, + } + + #[test] + fn has_compact() { + let data = WithCompact { data: $name(1) }; + let encoded = data.encode(); + assert_eq!(data, WithCompact::<$name>::decode(&mut &encoded[..]).unwrap()); + } + + #[test] + fn compact_encoding() { + let tests = [ + // assume all per_things have the size u8 at least. + (0 as $type, 1usize), + (1 as $type, 1usize), + (63, 1), + (64, 2), + (65, 2), + (<$type>::max_value(), <$type>::max_value().encode().len() + 1) + ]; + for &(n, l) in &tests { + let compact: crate::codec::Compact<$name> = $name(n).into(); + let encoded = compact.encode(); + assert_eq!(encoded.len(), l); + let decoded = >::decode(&mut & encoded[..]) + .unwrap(); + let per_thingy: $name = decoded.into(); + assert_eq!(per_thingy, $name(n)); + } + } + + #[test] + fn per_thing_api_works() { + // some really basic stuff + assert_eq!($name::zero(), $name::from_parts(Zero::zero())); + assert_eq!($name::one(), $name::from_parts($max)); + assert_eq!($name::accuracy(), $max); + assert_eq!($name::from_percent(0), $name::from_parts(Zero::zero())); + assert_eq!($name::from_percent(10), $name::from_parts($max / 10)); + assert_eq!($name::from_percent(100), $name::from_parts($max)); + } + + macro_rules! per_thing_mul_test { + ($num_type:tt) => { + // multiplication from all sort of from_percent + assert_eq!( + $name::from_percent(100) * $num_type::max_value(), + $num_type::max_value() + ); + assert_eq_error_rate!( + $name::from_percent(99) * $num_type::max_value(), + ((Into::::into($num_type::max_value()) * 99u32) / 100u32).as_u128() as $num_type, + 1, + ); + assert_eq!( + $name::from_percent(50) * $num_type::max_value(), + $num_type::max_value() / 2, + ); + assert_eq_error_rate!( + $name::from_percent(1) * $num_type::max_value(), + $num_type::max_value() / 100, + 1, + ); + assert_eq!($name::from_percent(0) * $num_type::max_value(), 0); + + // // multiplication with bounds + assert_eq!($name::one() * $num_type::max_value(), $num_type::max_value()); + assert_eq!($name::zero() * $num_type::max_value(), 0); + } + } + + #[test] + fn per_thing_mul_works() { + use primitive_types::U256; + + // accuracy test + assert_eq!($name::from_rational_approximation(1 as $type, 3) * 30 as $type, 10); + + $(per_thing_mul_test!($test_units);)* + } + + #[test] + fn per_thing_mul_rounds_to_nearest_number() { + assert_eq!($name::from_percent(33) * 10u64, 3); + assert_eq!($name::from_percent(34) * 10u64, 3); + assert_eq!($name::from_percent(35) * 10u64, 3); + assert_eq!($name::from_percent(36) * 10u64, 4); + assert_eq!($name::from_percent(36) * 10u64, 4); + } + + #[test] + fn per_thing_multiplication_with_large_number() { + use primitive_types::U256; + let max_minus_one = $max - 1; + assert_eq_error_rate!( + $name::from_parts(max_minus_one) * std::u128::MAX, + ((Into::::into(std::u128::MAX) * max_minus_one) / $max).as_u128(), + 1, + ); + } + + macro_rules! per_thing_from_rationale_approx_test { + ($num_type:tt) => { + // within accuracy boundary + assert_eq!( + $name::from_rational_approximation(1 as $num_type, 0), + $name::one(), + ); + assert_eq!( + $name::from_rational_approximation(1 as $num_type, 1), + $name::one(), + ); + assert_eq_error_rate!( + $name::from_rational_approximation(1 as $num_type, 3).0, + $name::from_parts($max / 3).0, + 2 + ); + assert_eq!( + $name::from_rational_approximation(1 as $num_type, 10), + $name::from_percent(10), + ); + assert_eq!( + $name::from_rational_approximation(1 as $num_type, 4), + $name::from_percent(25), + ); + assert_eq!( + $name::from_rational_approximation(1 as $num_type, 4), + $name::from_rational_approximation(2 as $num_type, 8), + ); + // no accurate anymore but won't overflow. + assert_eq!( + $name::from_rational_approximation( + $num_type::max_value() - 1, + $num_type::max_value() + ), + $name::one(), + ); + assert_eq_error_rate!( + $name::from_rational_approximation( + $num_type::max_value() / 3, + $num_type::max_value() + ).0, + $name::from_parts($max / 3).0, + 2 + ); + assert_eq!( + $name::from_rational_approximation(1, $num_type::max_value()), + $name::zero(), + ); + }; + } + + #[test] + fn per_thing_from_rationale_approx_works() { + // This is just to make sure something like Percent which _might_ get built from a + // u8 does not overflow in the context of this test. + let max_value = $max as $upper_type; + // almost at the edge + assert_eq!( + $name::from_rational_approximation($max - 1, $max + 1), + $name::from_parts($max - 2), + ); + assert_eq!( + $name::from_rational_approximation(1, $max-1), + $name::from_parts(1), + ); + assert_eq!( + $name::from_rational_approximation(1, $max), + $name::from_parts(1), + ); + assert_eq!( + $name::from_rational_approximation(2, 2 * $max - 1), + $name::from_parts(1), + ); + assert_eq!( + $name::from_rational_approximation(1, $max+1), + $name::zero(), + ); + assert_eq!( + $name::from_rational_approximation(3 * max_value / 2, 3 * max_value), + $name::from_percent(50), + ); + $(per_thing_from_rationale_approx_test!($test_units);)* + } + + #[test] + fn per_things_mul_operates_in_output_type() { + // assert_eq!($name::from_percent(50) * 100u32, 50u32); + assert_eq!($name::from_percent(50) * 100u64, 50u64); + assert_eq!($name::from_percent(50) * 100u128, 50u128); + } + + #[test] + fn per_thing_saturating_op_works() { + assert_eq!( + $name::from_percent(50).saturating_add($name::from_percent(40)), + $name::from_percent(90) + ); + assert_eq!( + $name::from_percent(50).saturating_add($name::from_percent(50)), + $name::from_percent(100) + ); + assert_eq!( + $name::from_percent(60).saturating_add($name::from_percent(50)), + $name::from_percent(100) + ); + + assert_eq!( + $name::from_percent(60).saturating_sub($name::from_percent(50)), + $name::from_percent(10) + ); + assert_eq!( + $name::from_percent(60).saturating_sub($name::from_percent(60)), + $name::from_percent(0) + ); + assert_eq!( + $name::from_percent(60).saturating_sub($name::from_percent(70)), + $name::from_percent(0) + ); + + assert_eq!( + $name::from_percent(50).saturating_mul($name::from_percent(50)), + $name::from_percent(25) + ); + assert_eq!( + $name::from_percent(20).saturating_mul($name::from_percent(20)), + $name::from_percent(4) + ); + assert_eq!( + $name::from_percent(10).saturating_mul($name::from_percent(10)), + $name::from_percent(1) + ); + } + + #[test] + fn per_thing_square_works() { + assert_eq!($name::from_percent(100).square(), $name::from_percent(100)); + assert_eq!($name::from_percent(50).square(), $name::from_percent(25)); + assert_eq!($name::from_percent(10).square(), $name::from_percent(1)); + assert_eq!( + $name::from_percent(2).square(), + $name::from_parts((4 * ($max as $upper_type) / 100 / 100) as $type) + ); + } + + #[test] + fn per_things_div_works() { + // normal + assert_eq!($name::from_percent(10) / $name::from_percent(20), + $name::from_percent(50) + ); + assert_eq!($name::from_percent(10) / $name::from_percent(10), + $name::from_percent(100) + ); + assert_eq!($name::from_percent(10) / $name::from_percent(0), + $name::from_percent(100) + ); + + // will not overflow + assert_eq!($name::from_percent(10) / $name::from_percent(5), + $name::from_percent(100) + ); + assert_eq!($name::from_percent(100) / $name::from_percent(50), + $name::from_percent(100) + ); + } + } + }; +} + +implement_per_thing!( + Percent, + test_per_cent, + [u32, u64, u128], + 100u8, + u8, + u16, + "_Percent_", +); +implement_per_thing!( + Permill, + test_permill, + [u32, u64, u128], + 1_000_000u32, + u32, + u64, + "_Parts per Million_", +); +implement_per_thing!( + Perbill, + test_perbill, + [u32, u64, u128], + 1_000_000_000u32, + u32, + u64, + "_Parts per Billion_", +); +implement_per_thing!( + Perquintill, + test_perquintill, + [u64, u128], + 1_000_000_000_000_000_000u64, + u64, + u128, + "_Parts per Quintillion_", +); + +/// An unsigned fixed point number. Can hold any value in the range [-9_223_372_036, 9_223_372_036] +/// with fixed point accuracy of one billion. +#[cfg_attr(feature = "std", derive(Debug))] +#[derive(Encode, Decode, Default, Copy, Clone, PartialEq, Eq, PartialOrd, Ord)] +pub struct Fixed64(i64); + +/// The accuracy of the `Fixed64` type. +const DIV: i64 = 1_000_000_000; + +impl Fixed64 { + /// creates self from a natural number. + /// + /// Note that this might be lossy. + pub fn from_natural(int: i64) -> Self { + Self(int.saturating_mul(DIV)) + } + + /// Return the accuracy of the type. Given that this function returns the value `X`, it means + /// that an instance composed of `X` parts (`Fixed64::from_parts(X)`) is equal to `1`. + pub fn accuracy() -> i64 { + DIV + } + + /// Raw constructor. Equal to `parts / 1_000_000_000`. + pub fn from_parts(parts: i64) -> Self { + Self(parts) + } + + /// creates self from a rational number. Equal to `n/d`. + /// + /// Note that this might be lossy. + pub fn from_rational(n: i64, d: u64) -> Self { + Self( + ((n as i128).saturating_mul(DIV as i128) / (d as i128).max(1)) + .try_into() + .unwrap_or(Bounded::max_value()) + ) + } + + /// Performs a saturated multiply and accumulate by unsigned number. + /// + /// Returns a saturated `int + (self * int)`. + pub fn saturated_multiply_accumulate(&self, int: N) -> N + where + N: TryFrom + From + UniqueSaturatedInto + Bounded + Clone + Saturating + + ops::Rem + ops::Div + ops::Mul + + ops::Add, + { + let div = DIV as u64; + let positive = self.0 > 0; + // safe to convert as absolute value. + let parts = self.0.checked_abs().map(|v| v as u64).unwrap_or(i64::max_value() as u64 + 1); + + + // will always fit. + let natural_parts = parts / div; + // might saturate. + let natural_parts: N = natural_parts.saturated_into(); + // fractional parts can always fit into u32. + let perbill_parts = (parts % div) as u32; + + let n = int.clone().saturating_mul(natural_parts); + let p = Perbill::from_parts(perbill_parts) * int.clone(); + + // everything that needs to be either added or subtracted from the original weight. + let excess = n.saturating_add(p); + + if positive { + int.saturating_add(excess) + } else { + int.saturating_sub(excess) + } + } +} + +impl Saturating for Fixed64 { + fn saturating_add(self, rhs: Self) -> Self { + Self(self.0.saturating_add(rhs.0)) + } + fn saturating_mul(self, rhs: Self) -> Self { + Self(self.0.saturating_mul(rhs.0) / DIV) + } + fn saturating_sub(self, rhs: Self) -> Self { + Self(self.0.saturating_sub(rhs.0)) + } +} + +/// Note that this is a standard, _potentially-panicking_, implementation. Use `Saturating` trait +/// for safe addition. +impl ops::Add for Fixed64 { + type Output = Self; + + fn add(self, rhs: Self) -> Self::Output { + Self(self.0 + rhs.0) + } +} + +/// Note that this is a standard, _potentially-panicking_, implementation. Use `Saturating` trait +/// for safe subtraction. +impl ops::Sub for Fixed64 { + type Output = Self; + + fn sub(self, rhs: Self) -> Self::Output { + Self(self.0 - rhs.0) + } +} + +impl CheckedSub for Fixed64 { + fn checked_sub(&self, rhs: &Self) -> Option { + if let Some(v) = self.0.checked_sub(rhs.0) { + Some(Self(v)) + } else { + None + } + } +} + +impl CheckedAdd for Fixed64 { + fn checked_add(&self, rhs: &Self) -> Option { + if let Some(v) = self.0.checked_add(rhs.0) { + Some(Self(v)) + } else { + None + } + } +} + +/// Some helper functions to work with 128bit numbers. Note that the functionality provided here is +/// only sensible to use with 128bit numbers because for smaller sizes, you can always rely on +/// assumptions of a bigger type (u128) being available, or simply create a per-thing and use the +/// multiplication implementation provided there. +pub mod helpers_128bit { + use super::Perquintill; + use crate::traits::Zero; + use rstd::cmp::{min, max}; + + const ERROR: &'static str = "can not accurately multiply by rational in this type"; + + /// Helper gcd function used in Rational128 implementation. + pub fn gcd(a: u128, b: u128) -> u128 { + match ((a, b), (a & 1, b & 1)) { + ((x, y), _) if x == y => y, + ((0, x), _) | ((x, 0), _) => x, + ((x, y), (0, 1)) | ((y, x), (1, 0)) => gcd(x >> 1, y), + ((x, y), (0, 0)) => gcd(x >> 1, y >> 1) << 1, + ((x, y), (1, 1)) => { + let (x, y) = (min(x, y), max(x, y)); + gcd((y - x) >> 1, x) + }, + _ => unreachable!(), + } + } + + /// Safely and accurately compute `a * b / c`. The approach is: + /// - Simply try `a * b / c`. + /// - Else, swap the operations (divide first) if `a > c` (division is possible) and `b <= c` + /// (overflow cannot happen) + /// - At any point, given an overflow or accuracy loss, return an Error. + /// + /// Invariant: c must be greater than or equal to 1. + /// This might not return Ok even if `b < c`. + pub fn multiply_by_rational(a: u128, b: u128, c: u128) -> Result { + if a.is_zero() || b.is_zero() { return Ok(Zero::zero()); } + + // invariant: C cannot be zero. + let c = c.max(1); + + // a and b are interchangeable by definition in this function. It always helps to assume the + // bigger of which is being multiplied by a `0 < b/c < 1`. Hence, a should be the bigger and + // b the smaller one. + let t = a; + let a = a.max(b); + let b = t.min(b); + + if let Some(x) = a.checked_mul(b) { + // This is the safest way to go. Try it. + Ok(x / c) + } else if a > c { + // if it can be safely swapped and it is a fraction, then swap. + let q = a / c; + let r = a % c; + let r_additional = multiply_by_rational(r, b, c)?; + + let q_part = q.checked_mul(b) + .ok_or(ERROR)?; + let result = q_part.checked_add(r_additional) + .ok_or(ERROR)?; + Ok(result) + } else { + Err(ERROR) + } + } + + /// Performs [`multiply_by_rational`]. In case of failure, if `b < c` it tries to approximate + /// the ratio into a perquintillion and return a lossy result. Otherwise, a best effort approach + /// of shifting both b and c is performed until multiply_by_rational can work. + /// + /// This function can very well be lossy and as the name suggests, perform a best effort in the + /// scope of u128 numbers. In case `b > c` and overflow happens, `a` is returned. + /// + /// c must be greater than or equal to 1. + pub fn multiply_by_rational_best_effort(a: u128, b: u128, c: u128) -> u128 { + if a.is_zero() || b.is_zero() { return Zero::zero(); } + let c = c.max(1); + + // unwrap the loop once. This favours performance over readability. + multiply_by_rational(a, b, c).unwrap_or_else(|_| { + if b <= c { + let per_thing = Perquintill::from_rational_approximation(b, c); + per_thing * a + } else { + let mut shift = 1; + let mut shifted_b = b.checked_shr(shift).unwrap_or(0); + let mut shifted_c = c.checked_shr(shift).unwrap_or(0); + + loop { + if shifted_b.is_zero() || shifted_c.is_zero() { + break a + } + match multiply_by_rational(a, shifted_b, shifted_c) { + Ok(r) => break r, + Err(_) => { + shift = shift + 1; + // by the time we reach here, b >= 1 && c >= 1. Before panic, they have + // to be zero which is prevented to happen by the break. + shifted_b = b.checked_shr(shift) + .expect( + "b >= 1 && c >= 1; break prevents them from ever being zero; \ + panic can only happen after either is zero; qed" + ); + shifted_c = c.checked_shr(shift) + .expect( + "b >= 1 && c >= 1; break prevents them from ever being zero; \ + panic can only happen after either is zero; qed" + ); + } + } + } + } + }) + } +} + +/// A wrapper for any rational number with a 128 bit numerator and denominator. +#[derive(Clone, Copy, Default, Eq)] +#[cfg_attr(feature = "std", derive(Debug))] +pub struct Rational128(u128, u128); + +impl Rational128 { + /// Nothing. + pub fn zero() -> Self { + Self(0, 1) + } + + /// If it is zero or not + pub fn is_zero(&self) -> bool { + self.0.is_zero() + } + + /// Build from a raw `n/d`. + pub fn from(n: u128, d: u128) -> Self { + Self(n, d.max(1)) + } + + /// Build from a raw `n/d`. This could lead to / 0 if not properly handled. + pub fn from_unchecked(n: u128, d: u128) -> Self { + Self(n, d) + } + + /// Return the numerator. + pub fn n(&self) -> u128 { + self.0 + } + + /// Return the denominator. + pub fn d(&self) -> u128 { + self.1 + } + + /// Convert `self` to a similar rational number where denominator is the given `den`. + // + /// This only returns if the result is accurate. `Err` is returned if the result cannot be + /// accurately calculated. + pub fn to_den(self, den: u128) -> Result { + if den == self.1 { + Ok(self) + } else { + if den > self.1 { + let n = helpers_128bit::multiply_by_rational(self.0, den, self.1)?; + Ok(Self(n, den)) + } else { + let div = self.1 / den; + Ok(Self(self.0 / div.max(1), den)) + } + } + } + + /// Get the least common divisor of `self` and `other`. + /// + /// This only returns if the result is accurate. `Err` is returned if the result cannot be + /// accurately calculated. + pub fn lcm(&self, other: &Self) -> Result { + // this should be tested better: two large numbers that are almost the same. + if self.1 == other.1 { return Ok(self.1) } + let g = helpers_128bit::gcd(self.1, other.1); + helpers_128bit::multiply_by_rational(self.1 , other.1, g) + } + + /// A saturating add that assumes `self` and `other` have the same denominator. + pub fn lazy_saturating_add(self, other: Self) -> Self { + if other.is_zero() { + self + } else { + Self(self.0.saturating_add(other.0) ,self.1) + } + } + + /// A saturating subtraction that assumes `self` and `other` have the same denominator. + pub fn lazy_saturating_sub(self, other: Self) -> Self { + if other.is_zero() { + self + } else { + Self(self.0.saturating_sub(other.0) ,self.1) + } + } + + /// Addition. Simply tries to unify the denominators and add the numerators. + /// + /// Overflow might happen during any of the steps. Error is returned in such cases. + pub fn checked_add(self, other: Self) -> Result { + let lcm = self.lcm(&other)?; + let self_scaled = self.to_den(lcm)?; + let other_scaled = other.to_den(lcm)?; + let n = self_scaled.0.checked_add(other_scaled.0) + .ok_or("overflow while adding numerators")?; + Ok(Self(n, self_scaled.1)) + } + + /// Subtraction. Simply tries to unify the denominators and subtract the numerators. + /// + /// Overflow might happen during any of the steps. None is returned in such cases. + pub fn checked_sub(self, other: Self) -> Result { + let lcm = self.lcm(&other)?; + let self_scaled = self.to_den(lcm)?; + let other_scaled = other.to_den(lcm)?; + + let n = self_scaled.0.checked_sub(other_scaled.0) + .ok_or("overflow while subtracting numerators")?; + Ok(Self(n, self_scaled.1)) + } +} + +impl PartialOrd for Rational128 { + fn partial_cmp(&self, other: &Self) -> Option { + Some(self.cmp(other)) + } +} + +/// Note that this implementation can very well be lossy. TODO #3670 +impl Ord for Rational128 { + fn cmp(&self, other: &Self) -> Ordering { + // handle some edge cases. + if self.1 == other.1 { + self.0.cmp(&other.0) + } else if self.1.is_zero() { + Ordering::Greater + } else if other.1.is_zero() { + Ordering::Less + } else { + // general lossy case + let saturated_lcm = helpers_128bit::multiply_by_rational_best_effort( + self.1, + other.1, + helpers_128bit::gcd(self.1, other.1) + ); + let self_scaled = self.to_den(saturated_lcm) + .unwrap_or(Self(Bounded::max_value(), self.1)); + let other_scaled = other.to_den(saturated_lcm) + .unwrap_or(Self(Bounded::max_value(), other.1)); + self_scaled.n().cmp(&other_scaled.n()) + } + } +} + +/// Note that this implementation can very well be lossy. TODO #3670 +impl PartialEq for Rational128 { + fn eq(&self, other: &Self) -> bool { + // handle some edge cases. + if self.1 == other.1 { + self.0.eq(&other.0) + } else { + // general lossy case + let saturated_lcm = helpers_128bit::multiply_by_rational_best_effort( + self.1, + other.1, + helpers_128bit::gcd(self.1, other.1) + ); + let self_scaled = self.to_den(saturated_lcm) + .unwrap_or(Self(Bounded::max_value(), self.1)); + let other_scaled = other.to_den(saturated_lcm) + .unwrap_or(Self(Bounded::max_value(), other.1)); + self_scaled.n().eq(&other_scaled.n()) + } + } +} + + +#[cfg(test)] +mod test_rational128 { + use super::*; + use super::helpers_128bit::*; + use crate::assert_eq_error_rate; + use rand::Rng; + + const MAX128: u128 = u128::max_value(); + const MAX64: u128 = u64::max_value() as u128; + const MAX64_2: u128 = 2 * u64::max_value() as u128; + + fn r(p: u128, q: u128) -> Rational128 { + Rational128(p, q) + } + + fn mul_div(a: u128, b: u128, c: u128) -> u128 { + use primitive_types::U256; + if a.is_zero() { return Zero::zero(); } + let c = c.max(1); + + // e for extended + let ae: U256 = a.into(); + let be: U256 = b.into(); + let ce: U256 = c.into(); + + let r = ae * be / ce; + if r > u128::max_value().into() { + a + } else { + r.as_u128() + } + } + + #[test] + fn truth_value_function_works() { + assert_eq!( + mul_div(2u128.pow(100), 8, 4), + 2u128.pow(101) + ); + assert_eq!( + mul_div(2u128.pow(100), 4, 8), + 2u128.pow(99) + ); + + // and it returns a if result cannot fit + assert_eq!(mul_div(MAX128 - 10, 2, 1), MAX128 - 10); + } + + #[test] + fn to_denom_works() { + // simple up and down + assert_eq!(r(1, 5).to_den(10), Ok(r(2, 10))); + assert_eq!(r(4, 10).to_den(5), Ok(r(2, 5))); + + // up and down with large numbers + assert_eq!(r(MAX128 - 10, MAX128).to_den(10), Ok(r(9, 10))); + assert_eq!(r(MAX128 / 2, MAX128).to_den(10), Ok(r(5, 10))); + + // large to perbill. This is very well needed for phragmen. + assert_eq!( + r(MAX128 / 2, MAX128).to_den(1000_000_000), + Ok(r(500_000_000, 1000_000_000)) + ); + + // large to large + assert_eq!(r(MAX128 / 2, MAX128).to_den(MAX128/2), Ok(r(MAX128/4, MAX128/2))); + } + + #[test] + fn gdc_works() { + assert_eq!(gcd(10, 5), 5); + assert_eq!(gcd(7, 22), 1); + } + + #[test] + fn lcm_works() { + // simple stuff + assert_eq!(r(3, 10).lcm(&r(4, 15)).unwrap(), 30); + assert_eq!(r(5, 30).lcm(&r(1, 7)).unwrap(), 210); + assert_eq!(r(5, 30).lcm(&r(1, 10)).unwrap(), 30); + + // large numbers + assert_eq!( + r(1_000_000_000, MAX128).lcm(&r(7_000_000_000, MAX128-1)), + Err("can not accurately multiply by rational in this type"), + ); + assert_eq!( + r(1_000_000_000, MAX64).lcm(&r(7_000_000_000, MAX64-1)), + Ok(340282366920938463408034375210639556610), + ); + assert!(340282366920938463408034375210639556610 < MAX128); + assert!(340282366920938463408034375210639556610 == MAX64 * (MAX64 - 1)); + } + + #[test] + fn add_works() { + // works + assert_eq!(r(3, 10).checked_add(r(1, 10)).unwrap(), r(2, 5)); + assert_eq!(r(3, 10).checked_add(r(3, 7)).unwrap(), r(51, 70)); + + // errors + assert_eq!( + r(1, MAX128).checked_add(r(1, MAX128-1)), + Err("can not accurately multiply by rational in this type"), + ); + assert_eq!( + r(7, MAX128).checked_add(r(MAX128, MAX128)), + Err("overflow while adding numerators"), + ); + assert_eq!( + r(MAX128, MAX128).checked_add(r(MAX128, MAX128)), + Err("overflow while adding numerators"), + ); + } + + #[test] + fn sub_works() { + // works + assert_eq!(r(3, 10).checked_sub(r(1, 10)).unwrap(), r(1, 5)); + assert_eq!(r(6, 10).checked_sub(r(3, 7)).unwrap(), r(12, 70)); + + // errors + assert_eq!( + r(2, MAX128).checked_sub(r(1, MAX128-1)), + Err("can not accurately multiply by rational in this type"), + ); + assert_eq!( + r(7, MAX128).checked_sub(r(MAX128, MAX128)), + Err("overflow while subtracting numerators"), + ); + assert_eq!( + r(1, 10).checked_sub(r(2,10)), + Err("overflow while subtracting numerators"), + ); + } + + #[test] + fn ordering_and_eq_works() { + assert!(r(1, 2) > r(1, 3)); + assert!(r(1, 2) > r(2, 6)); + + assert!(r(1, 2) < r(6, 6)); + assert!(r(2, 1) > r(2, 6)); + + assert!(r(5, 10) == r(1, 2)); + assert!(r(1, 2) == r(1, 2)); + + assert!(r(1, 1490000000000200000) > r(1, 1490000000000200001)); + } + + #[test] + fn multiply_by_rational_works() { + assert_eq!(multiply_by_rational(7, 2, 3).unwrap(), 7 * 2 / 3); + assert_eq!(multiply_by_rational(7, 20, 30).unwrap(), 7 * 2 / 3); + assert_eq!(multiply_by_rational(20, 7, 30).unwrap(), 7 * 2 / 3); + + // computed with swap + assert_eq!( + // MAX128 % 3 == 0 + multiply_by_rational(MAX128, 2, 3).unwrap(), + MAX128 / 3 * 2, + ); + assert_eq!( + // MAX128 % 7 == 3 + multiply_by_rational(MAX128, 5, 7).unwrap(), + (MAX128 / 7 * 5) + (3 * 5 / 7), + ); + assert_eq!( + // MAX128 % 7 == 3 + multiply_by_rational(MAX128, 11 , 13).unwrap(), + (MAX128 / 13 * 11) + (8 * 11 / 13), + ); + assert_eq!( + // MAX128 % 1000 == 455 + multiply_by_rational(MAX128, 555, 1000).unwrap(), + (MAX128 / 1000 * 555) + (455 * 555 / 1000), + ); + + assert_eq!( + multiply_by_rational(2 * MAX64 - 1, MAX64, MAX64).unwrap(), + 2 * MAX64 - 1, + ); + assert_eq!( + multiply_by_rational(2 * MAX64 - 1, MAX64 - 1, MAX64).unwrap(), + 2 * MAX64 - 3, + ); + + + assert_eq!( + multiply_by_rational(MAX64 + 100, MAX64_2, MAX64_2 / 2).unwrap(), + (MAX64 + 100) * 2, + ); + assert_eq!( + multiply_by_rational(MAX64 + 100, MAX64_2 / 100, MAX64_2 / 200).unwrap(), + (MAX64 + 100) * 2, + ); + + // fails to compute. have to use the greedy, lossy version here + assert!(multiply_by_rational(2u128.pow(66) - 1, 2u128.pow(65) - 1, 2u128.pow(65)).is_err()); + assert!(multiply_by_rational(1_000_000_000, MAX128 / 8, MAX128 / 2).is_err()); + } + + #[test] + fn multiply_by_rational_a_b_are_interchangeable() { + assert_eq!( + multiply_by_rational(10, MAX128, MAX128 / 2), + Ok(20), + ); + assert_eq!( + multiply_by_rational(MAX128, 10, MAX128 / 2), + Ok(20), + ); + } + + #[test] + fn multiply_by_rational_best_effort_works() { + assert_eq_error_rate!( + multiply_by_rational_best_effort(MAX64 + 100, MAX64_2, MAX64_2 / 2), + (MAX64 + 100) * 2, + 10, + ); + assert_eq_error_rate!( + multiply_by_rational_best_effort(MAX64 + 100, MAX64_2 * 100, MAX64_2 * 100 / 2), + (MAX64 + 100) * 2, + 10, + ); + assert_eq_error_rate!( + multiply_by_rational_best_effort(2u128.pow(66) - 1, 2u128.pow(65) - 1, 2u128.pow(65)), + mul_div(2u128.pow(66) - 1, 2u128.pow(65) - 1, 2u128.pow(65)), + 10, + ); + assert_eq_error_rate!( + multiply_by_rational_best_effort(1_000_000_000, MAX128 / 8, MAX128 / 2), + 1_000_000_000 / 4, + 10, + ); + + assert_eq!( + multiply_by_rational_best_effort(MAX128, MAX128 - 1, MAX128), + MAX128, + ); + + assert_eq!( + multiply_by_rational_best_effort(MAX64, MAX128 / 2, MAX128), + MAX64 / 2, + ); + } + + fn do_fuzz_multiply_by_rational( + iters: usize, + bits: u32, + maximum_error: u128, + do_print: bool, + bounded: bool, + mul_fn: F, + ) where F: Fn(u128, u128, u128) -> u128 { + let mut rng = rand::thread_rng(); + let mut average_diff = 0.0; + let upper_bound = 2u128.pow(bits); + + for _ in 0..iters { + let a = rng.gen_range(0u128, upper_bound); + let c = rng.gen_range(0u128, upper_bound); + let b = rng.gen_range( + 0u128, + if bounded { c } else { upper_bound } + ); + + let a: u128 = a.into(); + let b: u128 = b.into(); + let c: u128 = c.into(); + + let truth = mul_div(a, b, c); + let result = mul_fn(a, b, c); + let diff = truth.max(result) - truth.min(result); + let loss_ratio = diff as f64 / truth as f64; + average_diff += loss_ratio; + + if do_print && diff > maximum_error { + println!("++ Computed with more loss than expected: {} * {} / {}", a, b, c); + println!("++ Expected {}", truth); + println!("+++++++ Got {}", result); + } + } + + // print report + println!( + "## Fuzzed with {} numbers. Average error was {}", + iters, + average_diff / (iters as f64), + ); + } + + #[test] + fn fuzz_multiply_by_rational_best_effort_32() { + let f = |a, b, c| multiply_by_rational_best_effort(a, b, c); + println!("\nInvariant: b < c"); + do_fuzz_multiply_by_rational(1_000_000, 32, 0, false, true, f); + println!("every possibility"); + do_fuzz_multiply_by_rational(1_000_000, 32, 0, false, false, f); + } + + #[test] + fn fuzz_multiply_by_rational_best_effort_64() { + let f = |a, b, c| multiply_by_rational_best_effort(a, b, c); + println!("\nInvariant: b < c"); + do_fuzz_multiply_by_rational(1_000_000, 64, 0, false, true, f); + println!("every possibility"); + do_fuzz_multiply_by_rational(1_000_000, 64, 0, false, false, f); + } + + #[test] + fn fuzz_multiply_by_rational_best_effort_96() { + let f = |a, b, c| multiply_by_rational_best_effort(a, b, c); + // println!("\nInvariant: b < c"); + // do_fuzz_multiply_by_rational(1_000_000, 96, 0, false, true, f); + println!("every possibility"); + // do_fuzz_multiply_by_rational(1_000_000, 96, 0, false, false, f); + do_fuzz_multiply_by_rational(10, 96, 0, true, false, f); + } + + #[test] + fn fuzz_multiply_by_rational_best_effort_128() { + let f = |a, b, c| multiply_by_rational_best_effort(a, b, c); + println!("\nInvariant: b < c"); + do_fuzz_multiply_by_rational(1_000_000, 127, 0, false, true, f); + println!("every possibility"); + do_fuzz_multiply_by_rational(1_000_000, 127, 0, false, false, f); + } + + #[test] + fn fuzz_multiply_by_rational_32() { + // if Err just return the truth value. We don't care about such cases. The point of this + // fuzzing is to make sure: if `multiply_by_rational` returns `Ok`, it must be 100% accurate + // returning `Err` is fine. + let f = |a, b, c| multiply_by_rational(a, b, c).unwrap_or(mul_div(a, b, c)); + println!("\nInvariant: b < c"); + do_fuzz_multiply_by_rational(1_000_000, 32, 0, false, true, f); + println!("every possibility"); + do_fuzz_multiply_by_rational(1_000_000, 32, 0, false, false, f); + } + + #[test] + fn fuzz_multiply_by_rational_64() { + let f = |a, b, c| multiply_by_rational(a, b, c).unwrap_or(mul_div(a, b, c)); + println!("\nInvariant: b < c"); + do_fuzz_multiply_by_rational(1_000_000, 64, 0, false, true, f); + println!("every possibility"); + do_fuzz_multiply_by_rational(1_000_000, 64, 0, false, false, f); + } + + #[test] + fn fuzz_multiply_by_rational_96() { + let f = |a, b, c| multiply_by_rational(a, b, c).unwrap_or(mul_div(a, b, c)); + println!("\nInvariant: b < c"); + do_fuzz_multiply_by_rational(1_000_000, 96, 0, false, true, f); + println!("every possibility"); + do_fuzz_multiply_by_rational(1_000_000, 96, 0, false, false, f); + } + + #[test] + fn fuzz_multiply_by_rational_128() { + let f = |a, b, c| multiply_by_rational(a, b, c).unwrap_or(mul_div(a, b, c)); + println!("\nInvariant: b < c"); + do_fuzz_multiply_by_rational(1_000_000, 127, 0, false, true, f); + println!("every possibility"); + do_fuzz_multiply_by_rational(1_000_000, 127, 0, false, false, f); + } +} + + +#[cfg(test)] +mod tests_fixed64 { + use super::*; + + fn max() -> Fixed64 { + Fixed64::from_parts(i64::max_value()) + } + + #[test] + fn fixed64_semantics() { + assert_eq!(Fixed64::from_rational(5, 2).0, 5 * 1_000_000_000 / 2); + assert_eq!(Fixed64::from_rational(5, 2), Fixed64::from_rational(10, 4)); + assert_eq!(Fixed64::from_rational(5, 0), Fixed64::from_rational(5, 1)); + + // biggest value that can be created. + assert_ne!(max(), Fixed64::from_natural(9_223_372_036)); + assert_eq!(max(), Fixed64::from_natural(9_223_372_037)); + } + + macro_rules! saturating_mul_acc_test { + ($num_type:tt) => { + assert_eq!( + Fixed64::from_rational(100, 1).saturated_multiply_accumulate(10 as $num_type), + 1010, + ); + assert_eq!( + Fixed64::from_rational(100, 2).saturated_multiply_accumulate(10 as $num_type), + 510, + ); + assert_eq!( + Fixed64::from_rational(100, 3).saturated_multiply_accumulate(0 as $num_type), + 0, + ); + assert_eq!( + Fixed64::from_rational(5, 1).saturated_multiply_accumulate($num_type::max_value()), + $num_type::max_value() + ); + assert_eq!( + max().saturated_multiply_accumulate($num_type::max_value()), + $num_type::max_value() + ); + } + } + + #[test] + fn fixed64_multiply_accumulate_works() { + saturating_mul_acc_test!(u32); + saturating_mul_acc_test!(u64); + saturating_mul_acc_test!(u128); + } +} diff --git a/core/sr-primitives/src/testing.rs b/core/sr-primitives/src/testing.rs index c91c8366c1123587a98e1f4a5a7542963489dd89..5391735576aa212e49bc14083e504e0d358a02ad 100644 --- a/core/sr-primitives/src/testing.rs +++ b/core/sr-primitives/src/testing.rs @@ -17,22 +17,34 @@ //! Testing utilities. use serde::{Serialize, Serializer, Deserialize, de::Error as DeError, Deserializer}; -use std::{fmt::Debug, ops::Deref, fmt}; +use std::{fmt::Debug, ops::Deref, fmt, cell::RefCell}; use crate::codec::{Codec, Encode, Decode}; use crate::traits::{ - self, Checkable, Applyable, BlakeTwo256, OpaqueKeys, DispatchError, DispatchResult, - ValidateUnsigned, SignedExtension, Dispatchable, + self, Checkable, Applyable, BlakeTwo256, OpaqueKeys, ValidateUnsigned, + SignedExtension, Dispatchable, }; -use crate::{generic, KeyTypeId}; +use crate::{generic, KeyTypeId, ApplyResult}; use crate::weights::{GetDispatchInfo, DispatchInfo}; -pub use primitives::H256; +pub use primitives::{H256, sr25519}; use primitives::{crypto::{CryptoType, Dummy, key_types, Public}, U256}; -use crate::transaction_validity::TransactionValidity; +use crate::transaction_validity::{TransactionValidity, TransactionValidityError}; /// Authority Id -#[derive(Default, PartialEq, Eq, Clone, Encode, Decode, Debug, Hash, Serialize, Deserialize)] +#[derive(Default, PartialEq, Eq, Clone, Encode, Decode, Debug, Hash, Serialize, Deserialize, PartialOrd, Ord)] pub struct UintAuthorityId(pub u64); +impl From for UintAuthorityId { + fn from(id: u64) -> Self { + UintAuthorityId(id) + } +} + +impl From for u64 { + fn from(id: UintAuthorityId) -> u64 { + id.0 + } +} + impl UintAuthorityId { /// Convert this authority id into a public key. pub fn to_public_key(&self) -> T { @@ -47,34 +59,44 @@ impl CryptoType for UintAuthorityId { impl AsRef<[u8]> for UintAuthorityId { fn as_ref(&self) -> &[u8] { + // Unsafe, i know, but it's test code and it's just there because it's really convenient to + // keep `UintAuthorityId` as a u64 under the hood. unsafe { std::slice::from_raw_parts(&self.0 as *const u64 as *const _, std::mem::size_of::()) } } } +thread_local! { + /// A list of all UintAuthorityId keys returned to the runtime. + static ALL_KEYS: RefCell> = RefCell::new(vec![]); +} + +impl UintAuthorityId { + /// Set the list of keys returned by the runtime call for all keys of that type. + pub fn set_all_keys>(keys: impl IntoIterator) { + ALL_KEYS.with(|l| *l.borrow_mut() = keys.into_iter().map(Into::into).collect()) + } +} + impl app_crypto::RuntimeAppPublic for UintAuthorityId { + const ID: KeyTypeId = key_types::DUMMY; + type Signature = u64; fn all() -> Vec { - unimplemented!("`all()` not available for `UintAuthorityId`.") + ALL_KEYS.with(|l| l.borrow().clone()) } - #[cfg(feature = "std")] fn generate_pair(_: Option<&str>) -> Self { use rand::RngCore; UintAuthorityId(rand::thread_rng().next_u64()) } - #[cfg(not(feature = "std"))] - fn generate_pair(_: Option<&str>) -> Self { - unimplemented!("`generate_pair` not implemented for `UIntAuthorityId` on `no_std`.") - } - fn sign>(&self, msg: &M) -> Option { let mut signature = [0u8; 8]; msg.as_ref().iter() - .chain(rstd::iter::repeat(&42u8)) + .chain(std::iter::repeat(&42u8)) .take(8) .enumerate() .for_each(|(i, v)| { signature[i] = *v; }); @@ -85,7 +107,7 @@ impl app_crypto::RuntimeAppPublic for UintAuthorityId { fn verify>(&self, msg: &M, signature: &Self::Signature) -> bool { let mut msg_signature = [0u8; 8]; msg.as_ref().iter() - .chain(rstd::iter::repeat(&42)) + .chain(std::iter::repeat(&42)) .take(8) .enumerate() .for_each(|(i, v)| { msg_signature[i] = *v; }); @@ -97,19 +119,16 @@ impl app_crypto::RuntimeAppPublic for UintAuthorityId { impl OpaqueKeys for UintAuthorityId { type KeyTypeIds = std::iter::Cloned>; - fn key_ids() -> Self::KeyTypeIds { [key_types::DUMMY].iter().cloned() } - // Unsafe, i know, but it's test code and it's just there because it's really convenient to - // keep `UintAuthorityId` as a u64 under the hood. + fn key_ids() -> Self::KeyTypeIds { + [key_types::DUMMY].iter().cloned() + } + fn get_raw(&self, _: KeyTypeId) -> &[u8] { - unsafe { - std::slice::from_raw_parts( - &self.0 as *const _ as *const u8, - std::mem::size_of::(), - ) - } + self.as_ref() } + fn get(&self, _: KeyTypeId) -> Option { - self.0.using_encoded(|mut x| T::decode(&mut x)).ok() + self.using_encoded(|mut x| T::decode(&mut x)).ok() } } @@ -187,6 +206,7 @@ pub struct ExtrinsicWrapper(Xt); impl traits::Extrinsic for ExtrinsicWrapper { type Call = (); + type SignaturePayload = (); fn is_signed(&self) -> Option { None @@ -270,24 +290,25 @@ impl Debug for TestXt { impl Checkable for TestXt { type Checked = Self; - fn check(self, _: &Context) -> Result { Ok(self) } + fn check(self, _: &Context) -> Result { Ok(self) } } impl traits::Extrinsic for TestXt { type Call = Call; + type SignaturePayload = (u64, Extra); fn is_signed(&self) -> Option { Some(self.0.is_some()) } - fn new_unsigned(_c: Call) -> Option { - None + fn new(c: Call, sig: Option) -> Option { + Some(TestXt(sig, c)) } } impl Applyable for TestXt where Call: 'static + Sized + Send + Sync + Clone + Eq + Codec + Debug + Dispatchable, Extra: SignedExtension, - Origin: From> + Origin: From>, { type AccountId = u64; type Call = Call; @@ -295,19 +316,21 @@ impl Applyable for TestXt where fn sender(&self) -> Option<&Self::AccountId> { self.0.as_ref().map(|x| &x.0) } /// Checks to see if this is a valid *transaction*. It returns information on it if so. - fn validate>(&self, + fn validate>( + &self, _info: DispatchInfo, _len: usize, ) -> TransactionValidity { - TransactionValidity::Valid(Default::default()) + Ok(Default::default()) } /// Executes all necessary logic needed prior to dispatch and deconstructs into function call, /// index and sender. - fn dispatch(self, + fn apply( + self, info: DispatchInfo, len: usize, - ) -> Result { + ) -> ApplyResult { let maybe_who = if let Some((who, extra)) = self.0 { Extra::pre_dispatch(extra, &who, &self.1, info, len)?; Some(who) @@ -315,7 +338,8 @@ impl Applyable for TestXt where Extra::pre_dispatch_unsigned(&self.1, info, len)?; None }; - Ok(self.1.dispatch(maybe_who.into())) + + Ok(self.1.dispatch(maybe_who.into()).map_err(Into::into)) } } diff --git a/core/sr-primitives/src/traits.rs b/core/sr-primitives/src/traits.rs index 5fc0cb5c5761bf916af38b5aba5743bc31b768b4..10c2e806584ba58f8b9a13686ce93b8bb9cf6e13 100644 --- a/core/sr-primitives/src/traits.rs +++ b/core/sr-primitives/src/traits.rs @@ -19,11 +19,15 @@ use rstd::prelude::*; use rstd::{self, result, marker::PhantomData, convert::{TryFrom, TryInto}}; use runtime_io; -#[cfg(feature = "std")] use std::fmt::{Debug, Display}; -#[cfg(feature = "std")] use serde::{Serialize, Deserialize, de::DeserializeOwned}; -use primitives::{self, Hasher, Blake2Hasher}; +#[cfg(feature = "std")] +use std::fmt::{Debug, Display}; +#[cfg(feature = "std")] +use serde::{Serialize, Deserialize, de::DeserializeOwned}; +use primitives::{self, Hasher, Blake2Hasher, TypeId}; use crate::codec::{Codec, Encode, Decode, HasCompact}; -use crate::transaction_validity::{ValidTransaction, TransactionValidity}; +use crate::transaction_validity::{ + ValidTransaction, TransactionValidity, TransactionValidityError, UnknownTransaction, +}; use crate::generic::{Digest, DigestItem}; use crate::weights::DispatchInfo; pub use integer_sqrt::IntegerSquareRoot; @@ -35,7 +39,8 @@ use rstd::ops::{ Add, Sub, Mul, Div, Rem, AddAssign, SubAssign, MulAssign, DivAssign, RemAssign, Shl, Shr }; -use crate::AppKey; +use app_crypto::AppKey; +use impl_trait_for_tuples::impl_for_tuples; /// A lazy value. pub trait Lazy { @@ -93,18 +98,44 @@ impl< } } +/// An error type that indicates that the origin is invalid. +#[derive(Encode, Decode)] +pub struct InvalidOrigin; + +impl From for &'static str { + fn from(_: InvalidOrigin) -> &'static str { + "Invalid origin" + } +} + /// Some sort of check on the origin is performed by this object. pub trait EnsureOrigin { /// A return type. type Success; /// Perform the origin check. - fn ensure_origin(o: OuterOrigin) -> result::Result { - Self::try_origin(o).map_err(|_| "Invalid origin") + fn ensure_origin(o: OuterOrigin) -> result::Result { + Self::try_origin(o).map_err(|_| InvalidOrigin) } /// Perform the origin check. fn try_origin(o: OuterOrigin) -> result::Result; } +/// An error that indicates that a lookup failed. +#[derive(Encode, Decode)] +pub struct LookupError; + +impl From for &'static str { + fn from(_: LookupError) -> &'static str { + "Can not lookup" + } +} + +impl From for TransactionValidityError { + fn from(_: LookupError) -> Self { + UnknownTransaction::CannotLookup.into() + } +} + /// Means of changing one type into another in a manner dependent on the source type. pub trait Lookup { /// Type to lookup from. @@ -112,7 +143,7 @@ pub trait Lookup { /// Type to lookup into. type Target; /// Attempt a lookup. - fn lookup(&self, s: Self::Source) -> result::Result; + fn lookup(&self, s: Self::Source) -> Result; } /// Means of changing one type into another in a manner dependent on the source type. @@ -124,7 +155,7 @@ pub trait StaticLookup { /// Type to lookup into. type Target; /// Attempt a lookup. - fn lookup(s: Self::Source) -> result::Result; + fn lookup(s: Self::Source) -> Result; /// Convert from Target back to Source. fn unlookup(t: Self::Target) -> Self::Source; } @@ -135,13 +166,14 @@ pub struct IdentityLookup(PhantomData); impl StaticLookup for IdentityLookup { type Source = T; type Target = T; - fn lookup(x: T) -> result::Result { Ok(x) } + fn lookup(x: T) -> Result { Ok(x) } fn unlookup(x: T) -> T { x } } + impl Lookup for IdentityLookup { type Source = T; type Target = T; - fn lookup(&self, x: T) -> result::Result { Ok(x) } + fn lookup(&self, x: T) -> Result { Ok(x) } } /// Extensible conversion trait. Generic over both source and destination types. @@ -375,22 +407,20 @@ impl { /// The block is being finalized. Implement to have something happen. fn on_finalize(_n: BlockNumber) {} } -impl OnFinalize for () {} - /// The block initialization trait. Implementing this lets you express what should happen /// for your module when the block is beginning (right before the first extrinsic is executed). +#[impl_for_tuples(30)] pub trait OnInitialize { /// The block is being initialized. Implement to have something happen. fn on_initialize(_n: BlockNumber) {} } -impl OnInitialize for () {} - /// Off-chain computation trait. /// /// Implementing this trait on a module allows you to perform long-running tasks @@ -399,6 +429,7 @@ impl OnInitialize for () {} /// /// NOTE: This function runs off-chain, so it can access the block state, /// but cannot preform any alterations. +#[impl_for_tuples(30)] pub trait OffchainWorker { /// This function is being called on every block. /// @@ -407,50 +438,10 @@ pub trait OffchainWorker { fn generate_extrinsics(_n: BlockNumber) {} } -impl OffchainWorker for () {} - -macro_rules! tuple_impl { - ($first:ident, $($rest:ident,)+) => { - tuple_impl!([$first] [$first] [$($rest)+]); - }; - ([$($direct:ident)+] [$($reverse:ident)+] []) => { - impl< - Number: Copy, - $($direct: OnFinalize),+ - > OnFinalize for ($($direct),+,) { - fn on_finalize(n: Number) { - $($reverse::on_finalize(n);)+ - } - } - impl< - Number: Copy, - $($direct: OnInitialize),+ - > OnInitialize for ($($direct),+,) { - fn on_initialize(n: Number) { - $($direct::on_initialize(n);)+ - } - } - impl< - Number: Copy, - $($direct: OffchainWorker),+ - > OffchainWorker for ($($direct),+,) { - fn generate_extrinsics(n: Number) { - $($direct::generate_extrinsics(n);)+ - } - } - }; - ([$($direct:ident)+] [$($reverse:ident)+] [$first:ident $($rest:ident)*]) => { - tuple_impl!([$($direct)+] [$($reverse)+] []); - tuple_impl!([$($direct)+ $first] [$first $($reverse)+] [$($rest)*]); - }; -} - -#[allow(non_snake_case)] -tuple_impl!(A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y, Z,); - /// Abstraction around hashing -pub trait Hash: 'static + MaybeSerializeDebug + Clone + Eq + PartialEq { // Stupid bug in the Rust compiler believes derived - // traits must be fulfilled by all type parameters. +// Stupid bug in the Rust compiler believes derived +// traits must be fulfilled by all type parameters. +pub trait Hash: 'static + MaybeSerializeDebug + Clone + Eq + PartialEq { /// The hash type produced. type Output: Member + MaybeSerializeDebug + rstd::hash::Hash + AsRef<[u8]> + AsMut<[u8]> + Copy + Default + Encode + Decode; @@ -466,18 +457,11 @@ pub trait Hash: 'static + MaybeSerializeDebug + Clone + Eq + PartialEq { // Stup Encode::using_encoded(s, Self::hash) } - /// Iterator-based version of `ordered_trie_root`. - fn ordered_trie_root< - I: IntoIterator, - A: AsRef<[u8]> - >(input: I) -> Self::Output; + /// The ordered Patricia tree root of the given `input`. + fn ordered_trie_root(input: Vec>) -> Self::Output; - /// The Patricia tree root of the given mapping as an iterator. - fn trie_root< - I: IntoIterator, - A: AsRef<[u8]> + Ord, - B: AsRef<[u8]> - >(input: I) -> Self::Output; + /// The Patricia tree root of the given mapping. + fn trie_root(input: Vec<(Vec, Vec)>) -> Self::Output; /// Acquire the global storage root. fn storage_root() -> Self::Output; @@ -497,22 +481,19 @@ impl Hash for BlakeTwo256 { fn hash(s: &[u8]) -> Self::Output { runtime_io::blake2_256(s).into() } - fn trie_root< - I: IntoIterator, - A: AsRef<[u8]> + Ord, - B: AsRef<[u8]> - >(input: I) -> Self::Output { - runtime_io::trie_root::(input).into() + + fn trie_root(input: Vec<(Vec, Vec)>) -> Self::Output { + runtime_io::blake2_256_trie_root(input) } - fn ordered_trie_root< - I: IntoIterator, - A: AsRef<[u8]> - >(input: I) -> Self::Output { - runtime_io::ordered_trie_root::(input).into() + + fn ordered_trie_root(input: Vec>) -> Self::Output { + runtime_io::blake2_256_ordered_trie_root(input) } + fn storage_root() -> Self::Output { runtime_io::storage_root().into() } + fn storage_changes_root(parent_hash: Self::Output) -> Option { runtime_io::storage_changes_root(parent_hash.into()).map(Into::into) } @@ -529,16 +510,20 @@ impl CheckEqual for primitives::H256 { fn check_equal(&self, other: &Self) { use primitives::hexdisplay::HexDisplay; if self != other { - println!("Hash: given={}, expected={}", HexDisplay::from(self.as_fixed_bytes()), HexDisplay::from(other.as_fixed_bytes())); + println!( + "Hash: given={}, expected={}", + HexDisplay::from(self.as_fixed_bytes()), + HexDisplay::from(other.as_fixed_bytes()), + ); } } #[cfg(not(feature = "std"))] fn check_equal(&self, other: &Self) { if self != other { - runtime_io::print("Hash not equal"); - runtime_io::print(self.as_bytes()); - runtime_io::print(other.as_bytes()); + "Hash not equal".print(); + self.as_bytes().print(); + other.as_bytes().print(); } } } @@ -554,84 +539,50 @@ impl CheckEqual for super::generic::DigestItem MaybeSerializeDebugButNotDeserialize for T {} - -/// A type that implements Serialize and Debug when in std environment. -#[cfg(not(feature = "std"))] -pub trait MaybeSerializeDebugButNotDeserialize {} -#[cfg(not(feature = "std"))] -impl MaybeSerializeDebugButNotDeserialize for T {} - -/// A type that implements Serialize when in std environment. -#[cfg(feature = "std")] -pub trait MaybeSerialize: Serialize {} -#[cfg(feature = "std")] -impl MaybeSerialize for T {} - -/// A type that implements Serialize when in std environment. -#[cfg(not(feature = "std"))] -pub trait MaybeSerialize {} -#[cfg(not(feature = "std"))] -impl MaybeSerialize for T {} - -/// A type that implements Serialize, DeserializeOwned and Debug when in std environment. -#[cfg(feature = "std")] -pub trait MaybeSerializeDebug: Serialize + DeserializeOwned + Debug {} -#[cfg(feature = "std")] -impl MaybeSerializeDebug for T {} - -/// A type that implements Serialize, DeserializeOwned and Debug when in std environment. -#[cfg(not(feature = "std"))] -pub trait MaybeSerializeDebug {} -#[cfg(not(feature = "std"))] -impl MaybeSerializeDebug for T {} +macro_rules! impl_maybe_marker { + ( $( $(#[$doc:meta])+ $trait_name:ident: $($trait_bound:path),+ );+ ) => { + $( + $(#[$doc])+ + #[cfg(feature = "std")] + pub trait $trait_name: $($trait_bound +)+ {} + #[cfg(feature = "std")] + impl $trait_name for T {} + + $(#[$doc])+ + #[cfg(not(feature = "std"))] + pub trait $trait_name {} + #[cfg(not(feature = "std"))] + impl $trait_name for T {} + )+ + } +} -/// A type that implements Debug when in std environment. -#[cfg(feature = "std")] -pub trait MaybeDebug: Debug {} -#[cfg(feature = "std")] -impl MaybeDebug for T {} +impl_maybe_marker!( + /// A type that implements Debug when in std environment. + MaybeDebug: Debug; -/// A type that implements Debug when in std environment. -#[cfg(not(feature = "std"))] -pub trait MaybeDebug {} -#[cfg(not(feature = "std"))] -impl MaybeDebug for T {} + /// A type that implements Display when in std environment. + MaybeDisplay: Display; -/// A type that implements Display when in std environment. -#[cfg(feature = "std")] -pub trait MaybeDisplay: Display {} -#[cfg(feature = "std")] -impl MaybeDisplay for T {} + /// A type that implements Hash when in std environment. + MaybeHash: ::rstd::hash::Hash; -/// A type that implements Display when in std environment. -#[cfg(not(feature = "std"))] -pub trait MaybeDisplay {} -#[cfg(not(feature = "std"))] -impl MaybeDisplay for T {} + /// A type that implements Serialize when in std environment. + MaybeSerialize: Serialize; -/// A type that implements Hash when in std environment. -#[cfg(feature = "std")] -pub trait MaybeHash: ::rstd::hash::Hash {} -#[cfg(feature = "std")] -impl MaybeHash for T {} + /// A type that implements Serialize, DeserializeOwned and Debug when in std environment. + MaybeSerializeDebug: Debug, DeserializeOwned, Serialize; -/// A type that implements Hash when in std environment. -#[cfg(not(feature = "std"))] -pub trait MaybeHash {} -#[cfg(not(feature = "std"))] -impl MaybeHash for T {} + /// A type that implements Serialize and Debug when in std environment. + MaybeSerializeDebugButNotDeserialize: Debug, Serialize +); /// A type that provides a randomness beacon. pub trait RandomnessBeacon { @@ -743,13 +694,24 @@ pub trait Extrinsic: Sized { /// The function call. type Call; + /// The payload we carry for signed extrinsics. + /// + /// Usually it will contain a `Signature` and + /// may include some additional data that are specific to signed + /// extrinsics. + type SignaturePayload; + /// Is this `Extrinsic` signed? /// If no information are available about signed/unsigned, `None` should be returned. fn is_signed(&self) -> Option { None } - /// New instance of an unsigned extrinsic aka "inherent". `None` if this is an opaque - /// extrinsic type. - fn new_unsigned(_call: Self::Call) -> Option { None } + /// Create new instance of the extrinsic. + /// + /// Extrinsics can be split into: + /// 1. Inherents (no signature; created by validators during block production) + /// 2. Unsigned Transactions (no signature; represent "system calls" or other special kinds of calls) + /// 3. Signed Transactions (with signature; a regular transactions with known origin) + fn new(_call: Self::Call, _signed_data: Option) -> Option { None } } /// Extract the hashing type for a block. @@ -770,7 +732,7 @@ pub trait Checkable: Sized { type Checked; /// Check self, given an instance of Context. - fn check(self, c: &Context) -> Result; + fn check(self, c: &Context) -> Result; } /// A "checkable" piece of information, used by the standard Substrate Executive in order to @@ -782,61 +744,21 @@ pub trait BlindCheckable: Sized { type Checked; /// Check self. - fn check(self) -> Result; + fn check(self) -> Result; } // Every `BlindCheckable` is also a `StaticCheckable` for arbitrary `Context`. impl Checkable for T { type Checked = ::Checked; - fn check(self, _c: &Context) -> Result { - BlindCheckable::check(self) - } -} - -/// An abstract error concerning an attempt to verify, check or dispatch the transaction. This -/// cannot be more concrete because it's designed to work reasonably well over a broad range of -/// possible transaction types. -#[cfg_attr(feature = "std", derive(Debug))] -pub enum DispatchError { - /// General error to do with the inability to pay some fees (e.g. account balance too low). - Payment, - - /// General error to do with the exhaustion of block resources. - Exhausted, - - /// General error to do with the permissions of the sender. - NoPermission, - - /// General error to do with the state of the system in general. - BadState, - /// General error to do with the transaction being outdated (e.g. nonce too low). - Stale, - - /// General error to do with the transaction not yet being valid (e.g. nonce too high). - Future, - - /// General error to do with the transaction's proofs (e.g. signature). - BadProof, -} - -impl From for i8 { - fn from(e: DispatchError) -> i8 { - match e { - DispatchError::Payment => -64, - DispatchError::Exhausted => -65, - DispatchError::NoPermission => -66, - DispatchError::BadState => -67, - DispatchError::Stale => -68, - DispatchError::Future => -69, - DispatchError::BadProof => -70, - } + fn check(self, _c: &Context) -> Result { + BlindCheckable::check(self) } } /// Result of a module function call; either nothing (functions are only called for "side effects") /// or an error message. -pub type DispatchResult = result::Result<(), &'static str>; +pub type DispatchResult = result::Result<(), Error>; /// A lazy call (module function and argument values) that can be executed via its `dispatch` /// method. @@ -847,15 +769,15 @@ pub trait Dispatchable { type Origin; /// ... type Trait; + /// The error type returned by this dispatchable. + type Error: Into; /// Actually dispatch this call and result the result of it. - fn dispatch(self, origin: Self::Origin) -> DispatchResult; + fn dispatch(self, origin: Self::Origin) -> DispatchResult; } /// Means by which a transaction may be extended. This type embodies both the data and the logic /// that should be additionally associated with the transaction. It should be plain old data. -pub trait SignedExtension: - Codec + MaybeDebug + Sync + Send + Clone + Eq + PartialEq -{ +pub trait SignedExtension: Codec + MaybeDebug + Sync + Send + Clone + Eq + PartialEq { /// The type which encodes the sender identity. type AccountId; @@ -871,133 +793,155 @@ pub trait SignedExtension: /// Construct any additional data that should be in the signed payload of the transaction. Can /// also perform any pre-signature-verification checks and return an error if needed. - fn additional_signed(&self) -> Result; + fn additional_signed(&self) -> Result; /// Validate a signed transaction for the transaction queue. + /// + /// This function can be called frequently by the transaction queue, + /// to obtain transaction validity against current state. + /// It should perform all checks that determine a valid transaction, + /// that can pay for it's execution and quickly eliminate ones + /// that are stale or incorrect. + /// + /// Make sure to perform the same checks in `pre_dispatch` function. fn validate( &self, _who: &Self::AccountId, _call: &Self::Call, _info: DispatchInfo, _len: usize, - ) -> Result { - Ok(Default::default()) + ) -> TransactionValidity { + Ok(ValidTransaction::default()) } /// Do any pre-flight stuff for a signed transaction. + /// + /// Note this function by default delegates to `validate`, so that + /// all checks performed for the transaction queue are also performed during + /// the dispatch phase (applying the extrinsic). + /// + /// If you ever override this function, you need to make sure to always + /// perform the same validation as in `validate`. fn pre_dispatch( self, who: &Self::AccountId, call: &Self::Call, info: DispatchInfo, len: usize, - ) -> Result { - self.validate(who, call, info, len).map(|_| Self::Pre::default()) + ) -> Result { + self.validate(who, call, info, len) + .map(|_| Self::Pre::default()) + .map_err(Into::into) } - /// Validate an unsigned transaction for the transaction queue. Normally the default - /// implementation is fine since `ValidateUnsigned` is a better way of recognising and - /// validating unsigned transactions. + /// Validate an unsigned transaction for the transaction queue. + /// + /// Normally the default implementation is fine since `ValidateUnsigned` + /// is a better way of recognising and validating unsigned transactions. + /// + /// This function can be called frequently by the transaction queue, + /// to obtain transaction validity against current state. + /// It should perform all checks that determine a valid unsigned transaction, + /// and quickly eliminate ones that are stale or incorrect. + /// + /// Make sure to perform the same checks in `pre_dispatch_unsigned` function. fn validate_unsigned( _call: &Self::Call, _info: DispatchInfo, _len: usize, - ) -> Result { Ok(Default::default()) } + ) -> TransactionValidity { + Ok(ValidTransaction::default()) + } /// Do any pre-flight stuff for a unsigned transaction. + /// + /// Note this function by default delegates to `validate_unsigned`, so that + /// all checks performed for the transaction queue are also performed during + /// the dispatch phase (applying the extrinsic). + /// + /// If you ever override this function, you need to make sure to always + /// perform the same validation as in `validate_unsigned`. fn pre_dispatch_unsigned( call: &Self::Call, info: DispatchInfo, len: usize, - ) -> Result { - Self::validate_unsigned(call, info, len).map(|_| Self::Pre::default()) + ) -> Result { + Self::validate_unsigned(call, info, len) + .map(|_| Self::Pre::default()) + .map_err(Into::into) } /// Do any post-flight stuff for a transaction. - fn post_dispatch( - _pre: Self::Pre, - _info: DispatchInfo, - _len: usize, - ) { } + fn post_dispatch(_pre: Self::Pre, _info: DispatchInfo, _len: usize) { } } -macro_rules! tuple_impl_indexed { - ($first:ident, $($rest:ident,)+ ; $first_index:tt, $($rest_index:tt,)+) => { - tuple_impl_indexed!([$first] [$($rest)+] ; [$first_index,] [$($rest_index,)+]); - }; - ([$($direct:ident)+] ; [$($index:tt,)+]) => { - impl< - AccountId, - Call, - $($direct: SignedExtension),+ - > SignedExtension for ($($direct),+,) { - type AccountId = AccountId; - type Call = Call; - type AdditionalSigned = ($($direct::AdditionalSigned,)+); - type Pre = ($($direct::Pre,)+); - fn additional_signed(&self) -> Result { - Ok(( $(self.$index.additional_signed()?,)+ )) - } - fn validate( - &self, - who: &Self::AccountId, - call: &Self::Call, - info: DispatchInfo, - len: usize, - ) -> Result { - let aggregator = vec![$(<$direct as SignedExtension>::validate(&self.$index, who, call, info, len)?),+]; - Ok(aggregator.into_iter().fold(ValidTransaction::default(), |acc, a| acc.combine_with(a))) - } - fn pre_dispatch( - self, - who: &Self::AccountId, - call: &Self::Call, - info: DispatchInfo, - len: usize, - ) -> Result { - Ok(($(self.$index.pre_dispatch(who, call, info, len)?,)+)) - } - fn validate_unsigned( - call: &Self::Call, - info: DispatchInfo, - len: usize, - ) -> Result { - let aggregator = vec![$($direct::validate_unsigned(call, info, len)?),+]; - Ok(aggregator.into_iter().fold(ValidTransaction::default(), |acc, a| acc.combine_with(a))) - } - fn pre_dispatch_unsigned( - call: &Self::Call, - info: DispatchInfo, - len: usize, - ) -> Result { - Ok(($($direct::pre_dispatch_unsigned(call, info, len)?,)+)) - } - fn post_dispatch( - pre: Self::Pre, - info: DispatchInfo, - len: usize, - ) { - $($direct::post_dispatch(pre.$index, info, len);)+ - } - } +/// An error that is returned by a dispatchable function of a module. +pub trait ModuleDispatchError { + /// Convert this error to an `u8`. + /// + /// The `u8` corresponds to the index of the variant in the error enum. + fn as_u8(&self) -> u8; - }; - ([$($direct:ident)+] [] ; [$($index:tt,)+] []) => { - tuple_impl_indexed!([$($direct)+] ; [$($index,)+]); - }; - ( - [$($direct:ident)+] [$first:ident $($rest:ident)*] - ; - [$($index:tt,)+] [$first_index:tt, $($rest_index:tt,)*] - ) => { - tuple_impl_indexed!([$($direct)+] ; [$($index,)+]); - tuple_impl_indexed!([$($direct)+ $first] [$($rest)*] ; [$($index,)+ $first_index,] [$($rest_index,)*]); - }; + /// Convert the error to a `&'static str`. + fn as_str(&self) -> &'static str; } -// TODO: merge this into `tuple_impl` once codec supports `trait Codec` for longer tuple lengths. #3152 -#[allow(non_snake_case)] -tuple_impl_indexed!(A, B, C, D, E, F, G, H, I, J, ; 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,); +#[impl_for_tuples(1, 12)] +impl SignedExtension for Tuple { + for_tuples!( where #( Tuple: SignedExtension )* ); + type AccountId = AccountId; + type Call = Call; + for_tuples!( type AdditionalSigned = ( #( Tuple::AdditionalSigned ),* ); ); + for_tuples!( type Pre = ( #( Tuple::Pre ),* ); ); + + fn additional_signed(&self) -> Result { + Ok(for_tuples!( ( #( Tuple.additional_signed()? ),* ) )) + } + + fn validate( + &self, + who: &Self::AccountId, + call: &Self::Call, + info: DispatchInfo, + len: usize, + ) -> TransactionValidity { + let valid = ValidTransaction::default(); + for_tuples!( #( let valid = valid.combine_with(Tuple.validate(who, call, info, len)?); )* ); + Ok(valid) + } + + fn pre_dispatch(self, who: &Self::AccountId, call: &Self::Call, info: DispatchInfo, len: usize) + -> Result + { + Ok(for_tuples!( ( #( Tuple.pre_dispatch(who, call, info, len)? ),* ) )) + } + + fn validate_unsigned( + call: &Self::Call, + info: DispatchInfo, + len: usize, + ) -> TransactionValidity { + let valid = ValidTransaction::default(); + for_tuples!( #( let valid = valid.combine_with(Tuple::validate_unsigned(call, info, len)?); )* ); + Ok(valid) + } + + fn pre_dispatch_unsigned( + call: &Self::Call, + info: DispatchInfo, + len: usize, + ) -> Result { + Ok(for_tuples!( ( #( Tuple::pre_dispatch_unsigned(call, info, len)? ),* ) )) + } + + fn post_dispatch( + pre: Self::Pre, + info: DispatchInfo, + len: usize, + ) { + for_tuples!( #( Tuple::post_dispatch(pre.Tuple, info, len); )* ) + } +} /// Only for bare bone testing when you don't care about signed extensions at all. #[cfg(feature = "std")] @@ -1006,7 +950,7 @@ impl SignedExtension for () { type AdditionalSigned = (); type Call = (); type Pre = (); - fn additional_signed(&self) -> rstd::result::Result<(), &'static str> { Ok(()) } + fn additional_signed(&self) -> rstd::result::Result<(), TransactionValidityError> { Ok(()) } } /// An "executable" piece of information, used by the standard Substrate Executive in order to @@ -1026,17 +970,19 @@ pub trait Applyable: Sized + Send + Sync { fn sender(&self) -> Option<&Self::AccountId>; /// Checks to see if this is a valid *transaction*. It returns information on it if so. - fn validate>(&self, + fn validate>( + &self, info: DispatchInfo, len: usize, ) -> TransactionValidity; /// Executes all necessary logic needed prior to dispatch and deconstructs into function call, /// index and sender. - fn dispatch(self, + fn apply( + self, info: DispatchInfo, len: usize, - ) -> Result; + ) -> crate::ApplyResult; } /// Auxiliary wrapper that holds an api instance and binds it to the given lifetime. @@ -1095,7 +1041,12 @@ pub trait RuntimeApiInfo { const VERSION: u32; } -/// Something that can validate unsigned extrinsics. +/// Something that can validate unsigned extrinsics for the transaction pool. +/// +/// Note that any checks done here are only used for determining the validity of +/// the transaction for the transaction pool. +/// During block execution phase one need to perform the same checks anyway, +/// since this function is not being called. pub trait ValidateUnsigned { /// The call to validate type Call; @@ -1172,12 +1123,6 @@ pub trait AccountIdConversion: Sized { fn try_from_sub_account(x: &AccountId) -> Option<(Self, S)>; } -/// Provide a simple 4 byte identifier for a type. -pub trait TypeId { - /// Simple 4 byte identifier. - const TYPE_ID: [u8; 4]; -} - /// Format is TYPE_ID ++ encode(parachain ID) ++ 00.... where 00... is indefinite trailing zeroes to /// fill AccountId. impl AccountIdConversion for Id { @@ -1201,76 +1146,6 @@ impl AccountIdConver } } -#[cfg(test)] -mod tests { - use super::AccountIdConversion; - use crate::codec::{Encode, Decode, Input}; - - #[derive(Encode, Decode, Default, PartialEq, Debug)] - struct U32Value(u32); - impl super::TypeId for U32Value { - const TYPE_ID: [u8; 4] = [0x0d, 0xf0, 0xfe, 0xca]; - } - // cafef00d - - #[derive(Encode, Decode, Default, PartialEq, Debug)] - struct U16Value(u16); - impl super::TypeId for U16Value { - const TYPE_ID: [u8; 4] = [0xfe, 0xca, 0x0d, 0xf0]; - } - // f00dcafe - - type AccountId = u64; - - #[test] - fn into_account_should_work() { - let r: AccountId = U32Value::into_account(&U32Value(0xdeadbeef)); - assert_eq!(r, 0x_deadbeef_cafef00d); - } - - #[test] - fn try_from_account_should_work() { - let r = U32Value::try_from_account(&0x_deadbeef_cafef00d_u64); - assert_eq!(r.unwrap(), U32Value(0xdeadbeef)); - } - - #[test] - fn into_account_with_fill_should_work() { - let r: AccountId = U16Value::into_account(&U16Value(0xc0da)); - assert_eq!(r, 0x_0000_c0da_f00dcafe); - } - - #[test] - fn try_from_account_with_fill_should_work() { - let r = U16Value::try_from_account(&0x0000_c0da_f00dcafe_u64); - assert_eq!(r.unwrap(), U16Value(0xc0da)); - } - - #[test] - fn bad_try_from_account_should_fail() { - let r = U16Value::try_from_account(&0x0000_c0de_baadcafe_u64); - assert!(r.is_none()); - let r = U16Value::try_from_account(&0x0100_c0da_f00dcafe_u64); - assert!(r.is_none()); - } - - #[test] - fn trailing_zero_should_work() { - let mut t = super::TrailingZeroInput(&[1, 2, 3]); - assert_eq!(t.remaining_len(), Ok(None)); - let mut buffer = [0u8; 2]; - assert_eq!(t.read(&mut buffer), Ok(())); - assert_eq!(t.remaining_len(), Ok(None)); - assert_eq!(buffer, [1, 2]); - assert_eq!(t.read(&mut buffer), Ok(())); - assert_eq!(t.remaining_len(), Ok(None)); - assert_eq!(buffer, [3, 0]); - assert_eq!(t.read(&mut buffer), Ok(())); - assert_eq!(t.remaining_len(), Ok(None)); - assert_eq!(buffer, [0, 0]); - } -} - /// Calls a given macro a number of times with a set of fixed params and an incrementing numeral. /// e.g. /// ```nocompile @@ -1299,13 +1174,14 @@ macro_rules! count { /// just the bytes of the key. /// /// ```rust -/// use sr_primitives::{impl_opaque_keys, key_types, KeyTypeId, app_crypto::{sr25519, ed25519}}; +/// use sr_primitives::{impl_opaque_keys, KeyTypeId, app_crypto::{sr25519, ed25519}}; +/// use primitives::testing::{SR25519, ED25519}; /// /// impl_opaque_keys! { /// pub struct Keys { -/// #[id(key_types::ED25519)] +/// #[id(ED25519)] /// pub ed25519: ed25519::AppPublic, -/// #[id(key_types::SR25519)] +/// #[id(SR25519)] /// pub sr25519: sr25519::AppPublic, /// } /// } @@ -1362,3 +1238,103 @@ macro_rules! impl_opaque_keys { } }; } + +/// Trait for things which can be printed from the runtime. +pub trait Printable { + /// Print the object. + fn print(&self); +} + +impl Printable for u8 { + fn print(&self) { + u64::from(*self).print() + } +} + +impl Printable for &[u8] { + fn print(&self) { + runtime_io::print_hex(self); + } +} + +impl Printable for &str { + fn print(&self) { + runtime_io::print_utf8(self.as_bytes()); + } +} + +impl Printable for u64 { + fn print(&self) { + runtime_io::print_num(*self); + } +} + +#[cfg(test)] +mod tests { + use super::AccountIdConversion; + use crate::codec::{Encode, Decode, Input}; + + #[derive(Encode, Decode, Default, PartialEq, Debug)] + struct U32Value(u32); + impl super::TypeId for U32Value { + const TYPE_ID: [u8; 4] = [0x0d, 0xf0, 0xfe, 0xca]; + } + // cafef00d + + #[derive(Encode, Decode, Default, PartialEq, Debug)] + struct U16Value(u16); + impl super::TypeId for U16Value { + const TYPE_ID: [u8; 4] = [0xfe, 0xca, 0x0d, 0xf0]; + } + // f00dcafe + + type AccountId = u64; + + #[test] + fn into_account_should_work() { + let r: AccountId = U32Value::into_account(&U32Value(0xdeadbeef)); + assert_eq!(r, 0x_deadbeef_cafef00d); + } + + #[test] + fn try_from_account_should_work() { + let r = U32Value::try_from_account(&0x_deadbeef_cafef00d_u64); + assert_eq!(r.unwrap(), U32Value(0xdeadbeef)); + } + + #[test] + fn into_account_with_fill_should_work() { + let r: AccountId = U16Value::into_account(&U16Value(0xc0da)); + assert_eq!(r, 0x_0000_c0da_f00dcafe); + } + + #[test] + fn try_from_account_with_fill_should_work() { + let r = U16Value::try_from_account(&0x0000_c0da_f00dcafe_u64); + assert_eq!(r.unwrap(), U16Value(0xc0da)); + } + + #[test] + fn bad_try_from_account_should_fail() { + let r = U16Value::try_from_account(&0x0000_c0de_baadcafe_u64); + assert!(r.is_none()); + let r = U16Value::try_from_account(&0x0100_c0da_f00dcafe_u64); + assert!(r.is_none()); + } + + #[test] + fn trailing_zero_should_work() { + let mut t = super::TrailingZeroInput(&[1, 2, 3]); + assert_eq!(t.remaining_len(), Ok(None)); + let mut buffer = [0u8; 2]; + assert_eq!(t.read(&mut buffer), Ok(())); + assert_eq!(t.remaining_len(), Ok(None)); + assert_eq!(buffer, [1, 2]); + assert_eq!(t.read(&mut buffer), Ok(())); + assert_eq!(t.remaining_len(), Ok(None)); + assert_eq!(buffer, [3, 0]); + assert_eq!(t.read(&mut buffer), Ok(())); + assert_eq!(t.remaining_len(), Ok(None)); + assert_eq!(buffer, [0, 0]); + } +} diff --git a/core/sr-primitives/src/transaction_validity.rs b/core/sr-primitives/src/transaction_validity.rs index 4d5d53baf199f103a877198b824dbe94a42634d4..eb6cf3bdbb00ec17e6449a4a642ac50814e0c884 100644 --- a/core/sr-primitives/src/transaction_validity.rs +++ b/core/sr-primitives/src/transaction_validity.rs @@ -17,8 +17,7 @@ //! Transaction validity interface. use rstd::prelude::*; -use crate::codec::{Encode, Decode, Error}; -use crate::traits::DispatchError; +use crate::codec::{Encode, Decode}; /// Priority for a transaction. Additive. Higher is better. pub type TransactionPriority = u64; @@ -30,29 +29,151 @@ pub type TransactionLongevity = u64; /// Tag for a transaction. No two transactions with the same tag should be placed on-chain. pub type TransactionTag = Vec; -/// Information on a transaction's validity and, if valid, on how it relates to other transactions. -#[derive(Clone, PartialEq, Eq, Encode)] -#[cfg_attr(feature = "std", derive(Debug))] -pub enum TransactionValidity { - /// Transaction is invalid. Details are described by the error code. - Invalid(i8), - /// Transaction is valid. - Valid(ValidTransaction), +/// An invalid transaction validity. +#[derive(Clone, PartialEq, Eq, Encode, Decode, Copy)] +#[cfg_attr(feature = "std", derive(Debug, serde::Serialize))] +pub enum InvalidTransaction { + /// The call of the transaction is not expected. + Call, + /// General error to do with the inability to pay some fees (e.g. account balance too low). + Payment, + /// General error to do with the transaction not yet being valid (e.g. nonce too high). + Future, + /// General error to do with the transaction being outdated (e.g. nonce too low). + Stale, + /// General error to do with the transaction's proofs (e.g. signature). + BadProof, + /// The transaction birth block is ancient. + AncientBirthBlock, + /// The transaction would exhaust the resources of current block. + /// + /// The transaction might be valid, but there are not enough resources left in the current block. + ExhaustsResources, + /// Any other custom invalid validity that is not covered by this enum. + Custom(u8), +} + +impl InvalidTransaction { + /// Returns if the reason for the invalidity was block resource exhaustion. + pub fn exhausted_resources(&self) -> bool { + match self { + Self::ExhaustsResources => true, + _ => false, + } + } +} + +impl From for &'static str { + fn from(invalid: InvalidTransaction) -> &'static str { + match invalid { + InvalidTransaction::Call => "Transaction call is not expected", + InvalidTransaction::Future => "Transaction will be valid in the future", + InvalidTransaction::Stale => "Transaction is outdated", + InvalidTransaction::BadProof => "Transaction has a bad signature", + InvalidTransaction::AncientBirthBlock => "Transaction has an ancient birth block", + InvalidTransaction::ExhaustsResources => + "Transaction would exhausts the block limits", + InvalidTransaction::Payment => + "Inability to pay some fees (e.g. account balance too low)", + InvalidTransaction::Custom(_) => "InvalidTransaction custom error", + } + } +} + +/// An unknown transaction validity. +#[derive(Clone, PartialEq, Eq, Encode, Decode, Copy)] +#[cfg_attr(feature = "std", derive(Debug, serde::Serialize))] +pub enum UnknownTransaction { + /// Could not lookup some information that is required to validate the transaction. + CannotLookup, + /// No validator found for the given unsigned transaction. + NoUnsignedValidator, + /// Any other custom unknown validity that is not covered by this enum. + Custom(u8), +} + +impl From for &'static str { + fn from(unknown: UnknownTransaction) -> &'static str { + match unknown { + UnknownTransaction::CannotLookup => + "Could not lookup information required to validate the transaction", + UnknownTransaction::NoUnsignedValidator => + "Could not find an unsigned validator for the unsigned transaction", + UnknownTransaction::Custom(_) => "UnknownTransaction custom error", + } + } +} + +/// Errors that can occur while checking the validity of a transaction. +#[derive(Clone, PartialEq, Eq, Encode, Decode, Copy)] +#[cfg_attr(feature = "std", derive(Debug, serde::Serialize))] +pub enum TransactionValidityError { + /// The transaction is invalid. + Invalid(InvalidTransaction), /// Transaction validity can't be determined. - Unknown(i8), + Unknown(UnknownTransaction), +} + +impl TransactionValidityError { + /// Returns `true` if the reason for the error was block resource exhaustion. + pub fn exhausted_resources(&self) -> bool { + match self { + Self::Invalid(e) => e.exhausted_resources(), + Self::Unknown(_) => false, + } + } } -impl From> for TransactionValidity { - fn from(r: Result) -> Self { - match r { - Ok(v) => TransactionValidity::Valid(v), - Err(e) => TransactionValidity::Invalid(e.into()), +impl From for &'static str { + fn from(err: TransactionValidityError) -> &'static str { + match err { + TransactionValidityError::Invalid(invalid) => invalid.into(), + TransactionValidityError::Unknown(unknown) => unknown.into(), } } } +impl From for TransactionValidityError { + fn from(err: InvalidTransaction) -> Self { + TransactionValidityError::Invalid(err) + } +} + +impl From for TransactionValidityError { + fn from(err: UnknownTransaction) -> Self { + TransactionValidityError::Unknown(err) + } +} + +impl From for crate::ApplyError { + fn from(invalid: InvalidTransaction) -> crate::ApplyError { + TransactionValidityError::from(invalid).into() + } +} + +impl From for crate::ApplyError { + fn from(unknown: UnknownTransaction) -> crate::ApplyError { + TransactionValidityError::from(unknown).into() + } +} + +/// Information on a transaction's validity and, if valid, on how it relates to other transactions. +pub type TransactionValidity = Result; + +impl Into for InvalidTransaction { + fn into(self) -> TransactionValidity { + Err(self.into()) + } +} + +impl Into for UnknownTransaction { + fn into(self) -> TransactionValidity { + Err(self.into()) + } +} + /// Information concerning a valid transaction. -#[derive(Clone, PartialEq, Eq, Encode)] +#[derive(Clone, PartialEq, Eq, Encode, Decode)] #[cfg_attr(feature = "std", derive(Debug))] pub struct ValidTransaction { /// Priority of the transaction. @@ -112,49 +233,13 @@ impl ValidTransaction { } } -impl Decode for TransactionValidity { - fn decode(value: &mut I) -> Result { - match value.read_byte()? { - 0 => Ok(TransactionValidity::Invalid(i8::decode(value)?)), - 1 => { - let priority = TransactionPriority::decode(value)?; - let requires = Vec::decode(value)?; - let provides = Vec::decode(value)?; - let longevity = TransactionLongevity::decode(value)?; - let propagate = bool::decode(value).unwrap_or(true); - - Ok(TransactionValidity::Valid(ValidTransaction { - priority, requires, provides, longevity, propagate, - })) - }, - 2 => Ok(TransactionValidity::Unknown(i8::decode(value)?)), - _ => Err("Invalid transaction validity variant".into()), - } - } -} - #[cfg(test)] mod tests { use super::*; - #[test] - fn should_decode_with_backward_compat() { - let old_encoding = vec![ - 1, 5, 0, 0, 0, 0, 0, 0, 0, 4, 16, 1, 2, 3, 4, 4, 12, 4, 5, 6, 42, 0, 0, 0, 0, 0, 0, 0 - ]; - - assert_eq!(TransactionValidity::decode(&mut &*old_encoding), Ok(TransactionValidity::Valid(ValidTransaction { - priority: 5, - requires: vec![vec![1, 2, 3, 4]], - provides: vec![vec![4, 5, 6]], - longevity: 42, - propagate: true, - }))); - } - #[test] fn should_encode_and_decode() { - let v = TransactionValidity::Valid(ValidTransaction { + let v: TransactionValidity = Ok(ValidTransaction { priority: 5, requires: vec![vec![1, 2, 3, 4]], provides: vec![vec![4, 5, 6]], @@ -165,7 +250,7 @@ mod tests { let encoded = v.encode(); assert_eq!( encoded, - vec![1, 5, 0, 0, 0, 0, 0, 0, 0, 4, 16, 1, 2, 3, 4, 4, 12, 4, 5, 6, 42, 0, 0, 0, 0, 0, 0, 0, 0] + vec![0, 5, 0, 0, 0, 0, 0, 0, 0, 4, 16, 1, 2, 3, 4, 4, 12, 4, 5, 6, 42, 0, 0, 0, 0, 0, 0, 0, 0] ); // decode back diff --git a/core/sr-primitives/src/weights.rs b/core/sr-primitives/src/weights.rs index 45ac59e0d5489c5ded68bd14c1344e8a9e7f19ff..28f1b2fe0cfc4ebcb54f842111b84559f31a02c7 100644 --- a/core/sr-primitives/src/weights.rs +++ b/core/sr-primitives/src/weights.rs @@ -188,7 +188,7 @@ impl WeightMultiplier { /// build self from raw parts per billion. #[cfg(feature = "std")] pub fn from_parts(parts: i64) -> Self { - Self(Fixed64(parts)) + Self(Fixed64::from_parts(parts)) } /// build self from a fixed64 value. diff --git a/core/sr-sandbox/Cargo.toml b/core/sr-sandbox/Cargo.toml index da80b2f213c7ef53074a2f34884ef9b4813946f6..87b4e742a04131aaaa6a0122685b528cab9b875b 100755 --- a/core/sr-sandbox/Cargo.toml +++ b/core/sr-sandbox/Cargo.toml @@ -6,17 +6,17 @@ build = "build.rs" edition = "2018" [build-dependencies] -rustc_version = "0.2" +rustc_version = "0.2.3" [dependencies] -wasmi = { version = "0.5.0", optional = true } +wasmi = { version = "0.5.1", optional = true } primitives = { package = "substrate-primitives", path = "../primitives", default-features = false } rstd = { package = "sr-std", path = "../sr-std", default-features = false } codec = { package = "parity-scale-codec", version = "1.0.0", default-features = false } [dev-dependencies] -wabt = "~0.7.4" -assert_matches = "1.1" +wabt = "0.9.2" +assert_matches = "1.3.0" [features] default = ["std"] diff --git a/core/sr-staking-primitives/Cargo.toml b/core/sr-staking-primitives/Cargo.toml new file mode 100644 index 0000000000000000000000000000000000000000..25e8f4ccf1529576e5d34111445d57b947f04f37 --- /dev/null +++ b/core/sr-staking-primitives/Cargo.toml @@ -0,0 +1,18 @@ +[package] +name = "sr-staking-primitives" +version = "2.0.0" +authors = ["Parity Technologies "] +edition = "2018" + +[dependencies] +codec = { package = "parity-scale-codec", version = "1.0.0", default-features = false, features = ["derive"] } +sr-primitives = { path = "../sr-primitives", default-features = false } +rstd = { package = "sr-std", path = "../sr-std", default-features = false } + +[features] +default = ["std"] +std = [ + "codec/std", + "sr-primitives/std", + "rstd/std", +] diff --git a/core/sr-staking-primitives/src/lib.rs b/core/sr-staking-primitives/src/lib.rs new file mode 100644 index 0000000000000000000000000000000000000000..182307cb4712fa1a17668f348b70bf89f4dbfda3 --- /dev/null +++ b/core/sr-staking-primitives/src/lib.rs @@ -0,0 +1,23 @@ + +// Copyright 2019 Parity Technologies (UK) Ltd. +// This file is part of Substrate. + +// Substrate 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. + +// Substrate 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. + +#![cfg_attr(not(feature = "std"), no_std)] + +//! A crate which contains primitives that are useful for implementation that uses staking +//! approaches in general. Definitions related to sessions, slashing, etc go here. + +pub mod offence; + +/// Simple index type with which we can count sessions. +pub type SessionIndex = u32; diff --git a/core/sr-staking-primitives/src/offence.rs b/core/sr-staking-primitives/src/offence.rs new file mode 100644 index 0000000000000000000000000000000000000000..c076103c18332841851be65a66faf5b444acaf63 --- /dev/null +++ b/core/sr-staking-primitives/src/offence.rs @@ -0,0 +1,142 @@ +// Copyright 2019 Parity Technologies (UK) Ltd. +// This file is part of Substrate. + +// Substrate 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. + +// Substrate 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 Substrate. If not, see . + +//! Common traits and types that are useful for describing offences for usage in environments +//! that use staking. + +use rstd::vec::Vec; + +use codec::{Encode, Decode}; +use sr_primitives::Perbill; + +use crate::SessionIndex; + +/// The kind of an offence, is a byte string representing some kind identifier +/// e.g. `b"im-online:offlin"`, `b"babe:equivocatio"` +// TODO [slashing]: Is there something better we can have here that is more natural but still +// flexible? as you see in examples, they get cut off with long names. +pub type Kind = [u8; 16]; + +/// Number of times the offence of this authority was already reported in the past. +/// +/// Note that we don't buffer offence reporting, so every time we see a new offence +/// of the same kind, we will report past authorities again. +/// This counter keeps track of how many times the authority was already reported in the past, +/// so that we can slash it accordingly. +pub type OffenceCount = u32; + +/// A trait implemented by an offence report. +/// +/// This trait assumes that the offence is legitimate and was validated already. +/// +/// Examples of offences include: a BABE equivocation or a GRANDPA unjustified vote. +pub trait Offence { + /// Identifier which is unique for this kind of an offence. + const ID: Kind; + + /// A type that represents a point in time on an abstract timescale. + /// + /// See `Offence::time_slot` for details. The only requirement is that such timescale could be + /// represented by a single `u128` value. + type TimeSlot: Clone + codec::Codec + Ord; + + /// The list of all offenders involved in this incident. + /// + /// The list has no duplicates, so it is rather a set. + fn offenders(&self) -> Vec; + + /// The session index that is used for querying the validator set for the `slash_fraction` + /// function. + /// + /// This is used for filtering historical sessions. + fn session_index(&self) -> SessionIndex; + + /// Return a validator set count at the time when the offence took place. + fn validator_set_count(&self) -> u32; + + /// A point in time when this offence happened. + /// + /// This is used for looking up offences that happened at the "same time". + /// + /// The timescale is abstract and doesn't have to be the same across different implementations + /// of this trait. The value doesn't represent absolute timescale though since it is interpreted + /// along with the `session_index`. Two offences are considered to happen at the same time iff + /// both `session_index` and `time_slot` are equal. + /// + /// As an example, for GRANDPA timescale could be a round number and for BABE it could be a slot + /// number. Note that for GRANDPA the round number is reset each epoch. + fn time_slot(&self) -> Self::TimeSlot; + + /// A slash fraction of the total exposure that should be slashed for this + /// particular offence kind for the given parameters that happened at a singular `TimeSlot`. + /// + /// `offenders_count` - the count of unique offending authorities. It is >0. + /// `validator_set_count` - the cardinality of the validator set at the time of offence. + fn slash_fraction( + offenders_count: u32, + validator_set_count: u32, + ) -> Perbill; +} + +/// A trait for decoupling offence reporters from the actual handling of offence reports. +pub trait ReportOffence> { + /// Report an `offence` and reward given `reporters`. + fn report_offence(reporters: Vec, offence: O); +} + +impl> ReportOffence for () { + fn report_offence(_reporters: Vec, _offence: O) {} +} + +/// A trait to take action on an offence. +/// +/// Used to decouple the module that handles offences and +/// the one that should punish for those offences. +pub trait OnOffenceHandler { + /// A handler for an offence of a particular kind. + /// + /// Note that this contains a list of all previous offenders + /// as well. The implementer should cater for a case, where + /// the same authorities were reported for the same offence + /// in the past (see `OffenceCount`). + /// + /// The vector of `slash_fraction` contains `Perbill`s + /// the authorities should be slashed and is computed + /// according to the `OffenceCount` already. This is of the same length as `offenders.` + /// Zero is a valid value for a fraction. + fn on_offence( + offenders: &[OffenceDetails], + slash_fraction: &[Perbill], + ); +} + +impl OnOffenceHandler for () { + fn on_offence( + _offenders: &[OffenceDetails], + _slash_fraction: &[Perbill], + ) {} +} + +/// A details about an offending authority for a particular kind of offence. +#[derive(Clone, PartialEq, Eq, Encode, Decode)] +#[cfg_attr(feature = "std", derive(Debug))] +pub struct OffenceDetails { + /// The offending authority id + pub offender: Offender, + /// A list of reporters of offences of this authority ID. Possibly empty where there are no + /// particular reporters. + pub reporters: Vec, +} diff --git a/core/sr-std/src/lib.rs b/core/sr-std/src/lib.rs index 24c137c285f41096e94b71a43eaa967fc7f16cc9..f369d3908ba83233ecebb645c278f1318c491e28 100644 --- a/core/sr-std/src/lib.rs +++ b/core/sr-std/src/lib.rs @@ -68,7 +68,7 @@ include!("../without_std.rs"); pub mod prelude { pub use crate::vec::Vec; pub use crate::boxed::Box; - pub use crate::cmp::{Eq, PartialEq}; + pub use crate::cmp::{Eq, PartialEq, Reverse}; pub use crate::clone::Clone; // Re-export `vec!` macro here, but not in `std` mode, since diff --git a/core/sr-std/without_std.rs b/core/sr-std/without_std.rs index 327e271049d586f7f35b6292ca52a5352634d703..ed9eea6c31b74531670188004cfaacf555c9706c 100755 --- a/core/sr-std/without_std.rs +++ b/core/sr-std/without_std.rs @@ -19,7 +19,7 @@ pub extern crate alloc; extern "C" { - fn ext_malloc(size: usize) -> *mut u8; + fn ext_malloc(size: u32) -> *mut u8; fn ext_free(ptr: *mut u8); } @@ -37,7 +37,7 @@ mod __impl { unsafe impl GlobalAlloc for WasmAllocator { unsafe fn alloc(&self, layout: Layout) -> *mut u8 { - super::ext_malloc(layout.size()) as *mut u8 + super::ext_malloc(layout.size() as u32) as *mut u8 } unsafe fn dealloc(&self, ptr: *mut u8, _layout: Layout) { @@ -49,7 +49,6 @@ mod __impl { pub use alloc::boxed; pub use alloc::rc; pub use alloc::vec; -pub use core::borrow; pub use core::cell; pub use core::clone; pub use core::cmp; @@ -76,3 +75,8 @@ pub mod collections { pub use alloc::collections::btree_set; pub use alloc::collections::vec_deque; } + +pub mod borrow { + pub use core::borrow::*; + pub use alloc::borrow::*; +} diff --git a/core/sr-version/Cargo.toml b/core/sr-version/Cargo.toml index a83d1f6415dd072ef6093b60e61675ce3ce06cd3..fcae97b4d2a7aa289b90366cc37defcb6e5d17b1 100644 --- a/core/sr-version/Cargo.toml +++ b/core/sr-version/Cargo.toml @@ -5,9 +5,9 @@ authors = ["Parity Technologies "] edition = "2018" [dependencies] -impl-serde = { version = "0.1", optional = true } -serde = { version = "1.0", optional = true, features = ["derive"] } -codec = { package = "parity-scale-codec", version = "1.0.0", default-features = false, features = ["derive"] } +impl-serde = { version = "0.2.1", optional = true } +serde = { version = "1.0.101", optional = true, features = ["derive"] } +codec = { package = "parity-scale-codec", version = "1.0.5", default-features = false, features = ["derive"] } rstd = { package = "sr-std", path = "../sr-std", default-features = false } sr-primitives = { path = "../sr-primitives", default-features = false } diff --git a/core/sr-version/src/lib.rs b/core/sr-version/src/lib.rs index cf96fe70e219faaed1e98ef5ae5a6e12445b768e..ca98f3c2210fedfd6f39c395d103eb828125b410 100644 --- a/core/sr-version/src/lib.rs +++ b/core/sr-version/src/lib.rs @@ -62,7 +62,7 @@ macro_rules! create_apis_vec { /// This triplet have different semantics and mis-interpretation could cause problems. /// In particular: bug fixes should result in an increment of `spec_version` and possibly `authoring_version`, /// absolutely not `impl_version` since they change the semantics of the runtime. -#[derive(Clone, PartialEq, Eq, Encode)] +#[derive(Clone, PartialEq, Eq, Encode, Default)] #[cfg_attr(feature = "std", derive(Debug, Serialize, Deserialize, Decode))] #[cfg_attr(feature = "std", serde(rename_all = "camelCase"))] pub struct RuntimeVersion { @@ -96,7 +96,13 @@ pub struct RuntimeVersion { pub impl_version: u32, /// List of supported API "features" along with their versions. - #[cfg_attr(feature = "std", serde(serialize_with = "apis_serialize::serialize"))] + #[cfg_attr( + feature = "std", + serde( + serialize_with = "apis_serialize::serialize", + deserialize_with = "apis_serialize::deserialize", + ) + )] pub apis: ApisVec, } @@ -163,7 +169,7 @@ impl NativeVersion { mod apis_serialize { use super::*; use impl_serde::serialize as bytes; - use serde::{Serializer, ser::SerializeTuple}; + use serde::{Serializer, de, ser::SerializeTuple}; #[derive(Serialize)] struct ApiId<'a>( @@ -182,9 +188,48 @@ mod apis_serialize { seq.end() } - pub fn serialize_bytesref(apis: &&super::ApiId, ser: S) -> Result where + pub fn serialize_bytesref(&apis: &&super::ApiId, ser: S) -> Result where S: Serializer, { - bytes::serialize(*apis, ser) + bytes::serialize(apis, ser) + } + + #[derive(Deserialize)] + struct ApiIdOwned( + #[serde(deserialize_with="deserialize_bytes")] + super::ApiId, + u32, + ); + + pub fn deserialize<'de, D>(deserializer: D) -> Result where + D: de::Deserializer<'de>, + { + struct Visitor; + impl<'de> de::Visitor<'de> for Visitor { + type Value = ApisVec; + + fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { + formatter.write_str("a sequence of api id and version tuples") + } + + fn visit_seq(self, mut visitor: V) -> Result where + V: de::SeqAccess<'de>, + { + let mut apis = Vec::new(); + while let Some(value) = visitor.next_element::()? { + apis.push((value.0, value.1)); + } + Ok(apis.into()) + } + } + deserializer.deserialize_seq(Visitor) + } + + pub fn deserialize_bytes<'de, D>(d: D) -> Result where + D: de::Deserializer<'de> + { + let mut arr = [0; 8]; + bytes::deserialize_check_len(d, bytes::ExpectedLen::Exact(&mut arr[..]))?; + Ok(arr) } } diff --git a/core/state-db/Cargo.toml b/core/state-db/Cargo.toml index 332751c927f5d1ca65398def6578fe4489c5f877..86298ae909101ae843963ed45825b33428effb5e 100644 --- a/core/state-db/Cargo.toml +++ b/core/state-db/Cargo.toml @@ -6,9 +6,9 @@ edition = "2018" [dependencies] parking_lot = "0.9.0" -log = "0.4" +log = "0.4.8" primitives = { package = "substrate-primitives", path = "../../core/primitives" } codec = { package = "parity-scale-codec", version = "1.0.0", features = ["derive"] } [dev-dependencies] -env_logger = "0.6" +env_logger = "0.6.2" diff --git a/core/state-machine/Cargo.toml b/core/state-machine/Cargo.toml index bf5b96e43675a70ed12ce00f53b314dfb0b8d71e..914fa04db821490984574fd2c360a616a2831650 100644 --- a/core/state-machine/Cargo.toml +++ b/core/state-machine/Cargo.toml @@ -6,19 +6,20 @@ description = "Substrate State Machine" edition = "2018" [dependencies] -log = "0.4" +log = "0.4.8" parking_lot = "0.9.0" -hash-db = "0.15.0" -trie-db = "0.15.0" -trie-root = "0.15.0" +hash-db = "0.15.2" +trie-db = "0.15.2" +trie-root = "0.15.2" trie = { package = "substrate-trie", path = "../trie" } primitives = { package = "substrate-primitives", path = "../primitives" } panic-handler = { package = "substrate-panic-handler", path = "../panic-handler" } codec = { package = "parity-scale-codec", version = "1.0.0" } -num-traits = "0.2" +num-traits = "0.2.8" +rand = "0.7.2" [dev-dependencies] -hex-literal = "0.2.0" +hex-literal = "0.2.1" [features] default = [] diff --git a/core/state-machine/src/backend.rs b/core/state-machine/src/backend.rs index 0feb6e84d039e2102ac278c46fec09c2153647ac..e2f398ef7ccaef0af7c1b69a287c1aa01682d3d7 100644 --- a/core/state-machine/src/backend.rs +++ b/core/state-machine/src/backend.rs @@ -16,22 +16,21 @@ //! State machine backends. These manage the code and storage of contracts. -use std::{error, fmt}; -use std::cmp::Ord; -use std::collections::HashMap; -use std::marker::PhantomData; +use std::{error, fmt, cmp::Ord, collections::HashMap, marker::PhantomData}; use log::warn; use hash_db::Hasher; use crate::trie_backend::TrieBackend; use crate::trie_backend_essence::TrieBackendStorage; -use trie::{TrieMut, MemoryDB, child_trie_root, default_child_trie_root, TrieConfiguration}; -use trie::trie_types::{TrieDBMut, Layout}; +use trie::{ + TrieMut, MemoryDB, child_trie_root, default_child_trie_root, TrieConfiguration, + trie_types::{TrieDBMut, Layout}, +}; /// A state backend is used to read state data and can have changes committed /// to it. /// /// The clone operation (if implemented) should be cheap. -pub trait Backend { +pub trait Backend: std::fmt::Debug { /// An error type when fetching data is not possible. type Error: super::Error; @@ -72,7 +71,14 @@ pub trait Backend { /// Retrieve all entries keys which start with the given prefix and /// call `f` for each of those keys. - fn for_keys_with_prefix(&self, prefix: &[u8], f: F); + fn for_keys_with_prefix(&self, prefix: &[u8], mut f: F) { + self.for_key_values_with_prefix(prefix, |k, _v| f(k)) + } + + /// Retrieve all entries keys and values of which start with the given prefix and + /// call `f` for each of those keys. + fn for_key_values_with_prefix(&self, prefix: &[u8], f: F); + /// Retrieve all child entries keys which start with the given prefix and /// call `f` for each of those keys. @@ -112,7 +118,9 @@ pub trait Backend { } /// Try convert into trie backend. - fn as_trie_backend(&mut self) -> Option<&TrieBackend>; + fn as_trie_backend(&mut self) -> Option<&TrieBackend> { + None + } /// Calculate the storage root, with given delta over what is already stored /// in the backend, and produce a "transaction" that can be used to commit. @@ -147,7 +155,56 @@ pub trait Backend { txs.consolidate(parent_txs); (root, txs) } +} + +impl<'a, T: Backend, H: Hasher> Backend for &'a T { + type Error = T::Error; + type Transaction = T::Transaction; + type TrieBackendStorage = T::TrieBackendStorage; + + fn storage(&self, key: &[u8]) -> Result>, Self::Error> { + (*self).storage(key) + } + + fn child_storage(&self, storage_key: &[u8], key: &[u8]) -> Result>, Self::Error> { + (*self).child_storage(storage_key, key) + } + + fn for_keys_in_child_storage(&self, storage_key: &[u8], f: F) { + (*self).for_keys_in_child_storage(storage_key, f) + } + fn for_keys_with_prefix(&self, prefix: &[u8], f: F) { + (*self).for_keys_with_prefix(prefix, f) + } + + fn for_child_keys_with_prefix(&self, storage_key: &[u8], prefix: &[u8], f: F) { + (*self).for_child_keys_with_prefix(storage_key, prefix, f) + } + + fn storage_root(&self, delta: I) -> (H::Out, Self::Transaction) + where + I: IntoIterator, Option>)>, + H::Out: Ord, + { + (*self).storage_root(delta) + } + + fn child_storage_root(&self, storage_key: &[u8], delta: I) -> (Vec, bool, Self::Transaction) + where + I: IntoIterator, Option>)>, + H::Out: Ord, + { + (*self).child_storage_root(storage_key, delta) + } + + fn pairs(&self) -> Vec<(Vec, Vec)> { + (*self).pairs() + } + + fn for_key_values_with_prefix(&self, prefix: &[u8], f: F) { + (*self).for_key_values_with_prefix(prefix, f); + } } /// Trait that allows consolidate two transactions together. @@ -197,6 +254,12 @@ pub struct InMemory { _hasher: PhantomData, } +impl std::fmt::Debug for InMemory { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + write!(f, "InMemory ({} values)", self.inner.len()) + } +} + impl Default for InMemory { fn default() -> Self { InMemory { @@ -291,8 +354,6 @@ impl From>, Vec, Option>)>> for InMem } } -impl super::Error for Void {} - impl InMemory { /// child storage key iterator pub fn child_storage_keys(&self) -> impl Iterator { @@ -321,6 +382,11 @@ impl Backend for InMemory { self.inner.get(&None).map(|map| map.keys().filter(|key| key.starts_with(prefix)).map(|k| &**k).for_each(f)); } + fn for_key_values_with_prefix(&self, prefix: &[u8], mut f: F) { + self.inner.get(&None).map(|map| map.iter().filter(|(key, _val)| key.starts_with(prefix)) + .for_each(|(k, v)| f(k, v))); + } + fn for_keys_in_child_storage(&self, storage_key: &[u8], mut f: F) { self.inner.get(&Some(storage_key.to_vec())).map(|map| map.keys().for_each(|k| f(&k))); } diff --git a/core/state-machine/src/basic.rs b/core/state-machine/src/basic.rs index 1d36a0ddad51d1afe6d87cee6594031dc6c53a1d..e45af45c9f80b058a409b76833db1d49b36b8272 100644 --- a/core/state-machine/src/basic.rs +++ b/core/state-machine/src/basic.rs @@ -22,9 +22,10 @@ use crate::backend::{Backend, InMemory}; use hash_db::Hasher; use trie::{TrieConfiguration, default_child_trie_root}; use trie::trie_types::Layout; -use primitives::offchain; -use primitives::storage::well_known_keys::is_child_storage_key; -use super::{ChildStorageKey, Externalities}; +use primitives::{ + storage::well_known_keys::is_child_storage_key, child_storage_key::ChildStorageKey, offchain, + traits::Externalities, +}; use log::warn; /// Simple HashMap-based Externalities impl. @@ -35,7 +36,6 @@ pub struct BasicExternalities { } impl BasicExternalities { - /// Create a new instance of `BasicExternalities` pub fn new( top: HashMap, Vec>, @@ -97,11 +97,11 @@ impl Externalities for BasicExternalities where H::Out: Ord { Externalities::::storage(self, key) } - fn child_storage(&self, storage_key: ChildStorageKey, key: &[u8]) -> Option> { + fn child_storage(&self, storage_key: ChildStorageKey, key: &[u8]) -> Option> { self.children.get(storage_key.as_ref()).and_then(|child| child.get(key)).cloned() } - fn original_child_storage(&self, storage_key: ChildStorageKey, key: &[u8]) -> Option> { + fn original_child_storage(&self, storage_key: ChildStorageKey, key: &[u8]) -> Option> { Externalities::::child_storage(self, storage_key, key) } @@ -119,9 +119,9 @@ impl Externalities for BasicExternalities where H::Out: Ord { fn place_child_storage( &mut self, - storage_key: ChildStorageKey, + storage_key: ChildStorageKey, key: Vec, - value: Option> + value: Option>, ) { let child_map = self.children.entry(storage_key.into_owned()).or_default(); if let Some(value) = value { @@ -131,7 +131,7 @@ impl Externalities for BasicExternalities where H::Out: Ord { } } - fn kill_child_storage(&mut self, storage_key: ChildStorageKey) { + fn kill_child_storage(&mut self, storage_key: ChildStorageKey) { self.children.remove(storage_key.as_ref()); } @@ -147,7 +147,7 @@ impl Externalities for BasicExternalities where H::Out: Ord { self.top.retain(|key, _| !key.starts_with(prefix)); } - fn clear_child_prefix(&mut self, storage_key: ChildStorageKey, prefix: &[u8]) { + fn clear_child_prefix(&mut self, storage_key: ChildStorageKey, prefix: &[u8]) { if let Some(child) = self.children.get_mut(storage_key.as_ref()) { child.retain(|key, _| !key.starts_with(prefix)); } @@ -163,9 +163,10 @@ impl Externalities for BasicExternalities where H::Out: Ord { // type of child trie support. let empty_hash = default_child_trie_root::>(&[]); for storage_key in keys { - let child_root = self.child_storage_root( - ChildStorageKey::::from_slice(storage_key.as_slice()) - .expect("Map only feed by valid keys; qed") + let child_root = Externalities::::child_storage_root( + self, + ChildStorageKey::from_slice(storage_key.as_slice()) + .expect("Map only feed by valid keys; qed"), ); if &empty_hash[..] == &child_root[..] { top.remove(&storage_key); @@ -173,10 +174,11 @@ impl Externalities for BasicExternalities where H::Out: Ord { top.insert(storage_key, child_root); } } + Layout::::trie_root(self.top.clone()) } - fn child_storage_root(&mut self, storage_key: ChildStorageKey) -> Vec { + fn child_storage_root(&mut self, storage_key: ChildStorageKey) -> Vec { if let Some(child) = self.children.get(storage_key.as_ref()) { let delta = child.clone().into_iter().map(|(k, v)| (k, Some(v))); diff --git a/core/state-machine/src/changes_trie/build.rs b/core/state-machine/src/changes_trie/build.rs index e1e3f6a808e34102fcd21e92deaa2b3c39e59f4d..10c38a41e26509173543a456a2ee233901604155 100644 --- a/core/state-machine/src/changes_trie/build.rs +++ b/core/state-machine/src/changes_trie/build.rs @@ -16,7 +16,7 @@ //! Structures and functions required to build changes trie for given block. -use std::collections::BTreeMap; +use std::collections::{BTreeMap, BTreeSet}; use std::collections::btree_map::Entry; use codec::Decode; use hash_db::Hasher; @@ -26,62 +26,138 @@ use crate::overlayed_changes::OverlayedChanges; use crate::trie_backend_essence::TrieBackendEssence; use crate::changes_trie::build_iterator::digest_build_iterator; use crate::changes_trie::input::{InputKey, InputPair, DigestIndex, ExtrinsicIndex}; -use crate::changes_trie::{AnchorBlockId, Configuration, Storage, BlockNumber}; +use crate::changes_trie::{AnchorBlockId, ConfigurationRange, Storage, BlockNumber}; +use crate::changes_trie::input::ChildIndex; /// Prepare input pairs for building a changes trie of given block. /// /// Returns Err if storage error has occurred OR if storage haven't returned /// required data. -pub fn prepare_input<'a, B, S, H, Number>( +pub(crate) fn prepare_input<'a, B, H, Number>( backend: &'a B, - storage: &'a S, - config: &'a Configuration, + storage: &'a dyn Storage, + config: ConfigurationRange<'a, Number>, changes: &'a OverlayedChanges, parent: &'a AnchorBlockId, -) -> Result> + 'a, String> +) -> Result<( + impl Iterator> + 'a, + Vec<(ChildIndex, impl Iterator> + 'a)>, + Vec, + ), String> where B: Backend, - S: Storage, H: Hasher + 'a, Number: BlockNumber, { let number = parent.number.clone() + One::one(); - let extrinsics_input = prepare_extrinsics_input( + let (extrinsics_input, children_extrinsics_input) = prepare_extrinsics_input( backend, &number, - changes)?; - let digest_input = prepare_digest_input::<_, H, Number>( + changes, + )?; + let (digest_input, mut children_digest_input, digest_input_blocks) = prepare_digest_input::( parent, config, number, - storage)?; - Ok(extrinsics_input.chain(digest_input)) -} + storage, + )?; + + let mut children_digest = Vec::with_capacity(children_extrinsics_input.len()); + for (child_index, ext_iter) in children_extrinsics_input.into_iter() { + let dig_iter = children_digest_input.remove(&child_index); + children_digest.push(( + child_index, + Some(ext_iter).into_iter().flatten() + .chain(dig_iter.into_iter().flatten()), + )); + } + for (child_index, dig_iter) in children_digest_input.into_iter() { + children_digest.push(( + child_index, + None.into_iter().flatten() + .chain(Some(dig_iter).into_iter().flatten()), + )); + } + Ok(( + extrinsics_input.chain(digest_input), + children_digest, + digest_input_blocks, + )) +} /// Prepare ExtrinsicIndex input pairs. fn prepare_extrinsics_input<'a, B, H, Number>( backend: &'a B, block: &Number, changes: &'a OverlayedChanges, +) -> Result<( + impl Iterator> + 'a, + BTreeMap, impl Iterator> + 'a>, + ), String> + where + B: Backend, + H: Hasher + 'a, + Number: BlockNumber, +{ + + let mut children_keys = BTreeSet::>::new(); + let mut children_result = BTreeMap::new(); + for (storage_key, _) in changes.prospective.children.iter() + .chain(changes.committed.children.iter()) { + children_keys.insert(storage_key.clone()); + } + for storage_key in children_keys { + let child_index = ChildIndex:: { + block: block.clone(), + storage_key: storage_key.clone(), + }; + + let iter = prepare_extrinsics_input_inner(backend, block, changes, Some(storage_key))?; + children_result.insert(child_index, iter); + } + + let top = prepare_extrinsics_input_inner(backend, block, changes, None)?; + + Ok((top, children_result)) +} + +fn prepare_extrinsics_input_inner<'a, B, H, Number>( + backend: &'a B, + block: &Number, + changes: &'a OverlayedChanges, + storage_key: Option>, ) -> Result> + 'a, String> where B: Backend, H: Hasher, Number: BlockNumber, { - changes.committed.top.iter() - .chain(changes.prospective.top.iter()) + let (committed, prospective) = if let Some(sk) = storage_key.as_ref() { + (changes.committed.children.get(sk), changes.prospective.children.get(sk)) + } else { + (Some(&changes.committed.top), Some(&changes.prospective.top)) + }; + committed.iter().flat_map(|c| c.iter()) + .chain(prospective.iter().flat_map(|c| c.iter())) .filter(|( _, v)| v.extrinsics.is_some()) .try_fold(BTreeMap::new(), |mut map: BTreeMap<&[u8], (ExtrinsicIndex, Vec)>, (k, v)| { match map.entry(k) { Entry::Vacant(entry) => { // ignore temporary values (values that have null value at the end of operation // AND are not in storage at the beginning of operation - if !changes.storage(k).map(|v| v.is_some()).unwrap_or_default() { - if !backend.exists_storage(k).map_err(|e| format!("{}", e))? { - return Ok(map); + if let Some(sk) = storage_key.as_ref() { + if !changes.child_storage(sk, k).map(|v| v.is_some()).unwrap_or_default() { + if !backend.exists_child_storage(sk, k).map_err(|e| format!("{}", e))? { + return Ok(map); + } } - } + } else { + if !changes.storage(k).map(|v| v.is_some()).unwrap_or_default() { + if !backend.exists_storage(k).map_err(|e| format!("{}", e))? { + return Ok(map); + } + } + }; let extrinsics = v.extrinsics.as_ref() .expect("filtered by filter() call above; qed") @@ -110,29 +186,43 @@ fn prepare_extrinsics_input<'a, B, H, Number>( .map(|pairs| pairs.into_iter().map(|(_, (k, v))| InputPair::ExtrinsicIndex(k, v))) } + /// Prepare DigestIndex input pairs. -fn prepare_digest_input<'a, S, H, Number>( +fn prepare_digest_input<'a, H, Number>( parent: &'a AnchorBlockId, - config: &Configuration, + config: ConfigurationRange, block: Number, - storage: &'a S -) -> Result> + 'a, String> + storage: &'a dyn Storage, +) -> Result<( + impl Iterator> + 'a, + BTreeMap, impl Iterator> + 'a>, + Vec, + ), String> where - S: Storage, H: Hasher, H::Out: 'a, Number: BlockNumber, { - digest_build_iterator(config, block.clone()) - .try_fold(BTreeMap::new(), move |mut map, digest_build_block| { + let build_skewed_digest = config.end.as_ref() == Some(&block); + let block_for_digest = if build_skewed_digest { + config.config.next_max_level_digest_range(config.zero.clone(), block.clone()) + .map(|(_, end)| end) + .unwrap_or_else(|| block.clone()) + } else { + block.clone() + }; + + let digest_input_blocks = digest_build_iterator(config, block_for_digest).collect::>(); + digest_input_blocks.clone().into_iter() + .try_fold( + (BTreeMap::new(), BTreeMap::new()), move |(mut map, mut child_map), digest_build_block| { + let extrinsic_prefix = ExtrinsicIndex::key_neutral_prefix(digest_build_block.clone()); + let digest_prefix = DigestIndex::key_neutral_prefix(digest_build_block.clone()); + let child_prefix = ChildIndex::key_neutral_prefix(digest_build_block.clone()); let trie_root = storage.root(parent, digest_build_block.clone())?; let trie_root = trie_root.ok_or_else(|| format!("No changes trie root for block {}", digest_build_block.clone()))?; - let trie_storage = TrieBackendEssence::<_, H>::new( - crate::changes_trie::TrieBackendStorageAdapter(storage), - trie_root, - ); - let mut insert_to_map = |key: Vec| { + let insert_to_map = |map: &mut BTreeMap<_,_>, key: Vec| { match map.entry(key.clone()) { Entry::Vacant(entry) => { entry.insert((DigestIndex { @@ -154,34 +244,106 @@ fn prepare_digest_input<'a, S, H, Number>( } }; - let extrinsic_prefix = ExtrinsicIndex::key_neutral_prefix(digest_build_block.clone()); - trie_storage.for_keys_with_prefix(&extrinsic_prefix, |key| - if let Ok(InputKey::ExtrinsicIndex::(trie_key)) = Decode::decode(&mut &key[..]) { - insert_to_map(trie_key.key); - }); + // try to get all updated keys from cache + let populated_from_cache = storage.with_cached_changed_keys( + &trie_root, + &mut |changed_keys| { + for (storage_key, changed_keys) in changed_keys { + let map = match storage_key { + Some(storage_key) => child_map + .entry(ChildIndex:: { + block: block.clone(), + storage_key: storage_key.clone(), + }) + .or_default(), + None => &mut map, + }; + for changed_key in changed_keys.iter().cloned() { + insert_to_map(map, changed_key); + } + } + } + ); + if populated_from_cache { + return Ok((map, child_map)); + } - let digest_prefix = DigestIndex::key_neutral_prefix(digest_build_block.clone()); - trie_storage.for_keys_with_prefix(&digest_prefix, |key| - if let Ok(InputKey::DigestIndex::(trie_key)) = Decode::decode(&mut &key[..]) { - insert_to_map(trie_key.key); - }); + let mut children_roots = BTreeMap::, _>::new(); + { + let trie_storage = TrieBackendEssence::<_, H>::new( + crate::changes_trie::TrieBackendStorageAdapter(storage), + trie_root, + ); - Ok(map) + trie_storage.for_key_values_with_prefix(&child_prefix, |key, value| + if let Ok(InputKey::ChildIndex::(trie_key)) = Decode::decode(&mut &key[..]) { + if let Ok(value) = >::decode(&mut &value[..]) { + let mut trie_root = ::Out::default(); + trie_root.as_mut().copy_from_slice(&value[..]); + children_roots.insert(trie_key.storage_key, trie_root); + } + }); + + trie_storage.for_keys_with_prefix(&extrinsic_prefix, |key| + if let Ok(InputKey::ExtrinsicIndex::(trie_key)) = Decode::decode(&mut &key[..]) { + insert_to_map(&mut map, trie_key.key); + }); + + trie_storage.for_keys_with_prefix(&digest_prefix, |key| + if let Ok(InputKey::DigestIndex::(trie_key)) = Decode::decode(&mut &key[..]) { + insert_to_map(&mut map, trie_key.key); + }); + } + + for (storage_key, trie_root) in children_roots.into_iter() { + let child_index = ChildIndex:: { + block: block.clone(), + storage_key, + }; + + let mut map = child_map.entry(child_index).or_default(); + let trie_storage = TrieBackendEssence::<_, H>::new( + crate::changes_trie::TrieBackendStorageAdapter(storage), + trie_root, + ); + trie_storage.for_keys_with_prefix(&extrinsic_prefix, |key| + if let Ok(InputKey::ExtrinsicIndex::(trie_key)) = Decode::decode(&mut &key[..]) { + insert_to_map(&mut map, trie_key.key); + }); + + trie_storage.for_keys_with_prefix(&digest_prefix, |key| + if let Ok(InputKey::DigestIndex::(trie_key)) = Decode::decode(&mut &key[..]) { + insert_to_map(&mut map, trie_key.key); + }); + } + Ok((map, child_map)) }) - .map(|pairs| pairs.into_iter().map(|(_, (k, v))| InputPair::DigestIndex(k, v))) + .map(|(pairs, child_pairs)| ( + pairs.into_iter().map(|(_, (k, v))| InputPair::DigestIndex(k, v)), + child_pairs.into_iter().map(|(sk, pairs)| + (sk, pairs.into_iter().map(|(_, (k, v))| InputPair::DigestIndex(k, v)))).collect(), + digest_input_blocks, + )) } #[cfg(test)] mod test { use codec::Encode; use primitives::Blake2Hasher; - use primitives::storage::well_known_keys::EXTRINSIC_INDEX; + use primitives::storage::well_known_keys::{EXTRINSIC_INDEX}; use crate::backend::InMemory; - use crate::changes_trie::storage::InMemoryStorage; - use crate::overlayed_changes::OverlayedValue; + use crate::changes_trie::{RootsStorage, Configuration, storage::InMemoryStorage}; + use crate::changes_trie::build_cache::{IncompleteCacheAction, IncompleteCachedBuildData}; + use crate::overlayed_changes::{OverlayedValue, OverlayedChangeSet}; use super::*; - fn prepare_for_build() -> (InMemory, InMemoryStorage, OverlayedChanges) { + fn prepare_for_build(zero: u64) -> ( + InMemory, + InMemoryStorage, + OverlayedChanges, + Configuration, + ) { + let config = Configuration { digest_interval: 4, digest_levels: 2 }; let backend: InMemory<_> = vec![ (vec![100], vec![255]), (vec![101], vec![255]), @@ -190,42 +352,59 @@ mod test { (vec![104], vec![255]), (vec![105], vec![255]), ].into_iter().collect::<::std::collections::HashMap<_, _>>().into(); + let child_trie_key1 = b"1".to_vec(); + let child_trie_key2 = b"2".to_vec(); let storage = InMemoryStorage::with_inputs(vec![ - (1, vec![ - InputPair::ExtrinsicIndex(ExtrinsicIndex { block: 1, key: vec![100] }, vec![1, 3]), - InputPair::ExtrinsicIndex(ExtrinsicIndex { block: 1, key: vec![101] }, vec![0, 2]), - InputPair::ExtrinsicIndex(ExtrinsicIndex { block: 1, key: vec![105] }, vec![0, 2, 4]), + (zero + 1, vec![ + InputPair::ExtrinsicIndex(ExtrinsicIndex { block: zero + 1, key: vec![100] }, vec![1, 3]), + InputPair::ExtrinsicIndex(ExtrinsicIndex { block: zero + 1, key: vec![101] }, vec![0, 2]), + InputPair::ExtrinsicIndex(ExtrinsicIndex { block: zero + 1, key: vec![105] }, vec![0, 2, 4]), ]), - (2, vec![ - InputPair::ExtrinsicIndex(ExtrinsicIndex { block: 2, key: vec![102] }, vec![0]), + (zero + 2, vec![ + InputPair::ExtrinsicIndex(ExtrinsicIndex { block: zero + 2, key: vec![102] }, vec![0]), ]), - (3, vec![ - InputPair::ExtrinsicIndex(ExtrinsicIndex { block: 3, key: vec![100] }, vec![0]), - InputPair::ExtrinsicIndex(ExtrinsicIndex { block: 3, key: vec![105] }, vec![1]), + (zero + 3, vec![ + InputPair::ExtrinsicIndex(ExtrinsicIndex { block: zero + 3, key: vec![100] }, vec![0]), + InputPair::ExtrinsicIndex(ExtrinsicIndex { block: zero + 3, key: vec![105] }, vec![1]), ]), - (4, vec![ - InputPair::ExtrinsicIndex(ExtrinsicIndex { block: 4, key: vec![100] }, vec![0, 2, 3]), - InputPair::ExtrinsicIndex(ExtrinsicIndex { block: 4, key: vec![101] }, vec![1]), - InputPair::ExtrinsicIndex(ExtrinsicIndex { block: 4, key: vec![103] }, vec![0, 1]), - - InputPair::DigestIndex(DigestIndex { block: 4, key: vec![100] }, vec![1, 3]), - InputPair::DigestIndex(DigestIndex { block: 4, key: vec![101] }, vec![1]), - InputPair::DigestIndex(DigestIndex { block: 4, key: vec![102] }, vec![2]), - InputPair::DigestIndex(DigestIndex { block: 4, key: vec![105] }, vec![1, 3]), + (zero + 4, vec![ + InputPair::ExtrinsicIndex(ExtrinsicIndex { block: zero + 4, key: vec![100] }, vec![0, 2, 3]), + InputPair::ExtrinsicIndex(ExtrinsicIndex { block: zero + 4, key: vec![101] }, vec![1]), + InputPair::ExtrinsicIndex(ExtrinsicIndex { block: zero + 4, key: vec![103] }, vec![0, 1]), + + InputPair::DigestIndex(DigestIndex { block: zero + 4, key: vec![100] }, vec![zero + 1, zero + 3]), + InputPair::DigestIndex(DigestIndex { block: zero + 4, key: vec![101] }, vec![zero + 1]), + InputPair::DigestIndex(DigestIndex { block: zero + 4, key: vec![102] }, vec![zero + 2]), + InputPair::DigestIndex(DigestIndex { block: zero + 4, key: vec![105] }, vec![zero + 1, zero + 3]), + ]), + (zero + 5, Vec::new()), + (zero + 6, vec![ + InputPair::ExtrinsicIndex(ExtrinsicIndex { block: zero + 6, key: vec![105] }, vec![2]), ]), - (5, Vec::new()), - (6, vec![ - InputPair::ExtrinsicIndex(ExtrinsicIndex { block: 6, key: vec![105] }, vec![2]), + (zero + 7, Vec::new()), + (zero + 8, vec![ + InputPair::DigestIndex(DigestIndex { block: zero + 8, key: vec![105] }, vec![zero + 6]), ]), - (7, Vec::new()), - (8, vec![ - InputPair::DigestIndex(DigestIndex { block: 8, key: vec![105] }, vec![6]), + (zero + 9, Vec::new()), (zero + 10, Vec::new()), (zero + 11, Vec::new()), (zero + 12, Vec::new()), + (zero + 13, Vec::new()), (zero + 14, Vec::new()), (zero + 15, Vec::new()), + ], vec![(child_trie_key1.clone(), vec![ + (zero + 1, vec![ + InputPair::ExtrinsicIndex(ExtrinsicIndex { block: zero + 1, key: vec![100] }, vec![1, 3]), + InputPair::ExtrinsicIndex(ExtrinsicIndex { block: zero + 1, key: vec![101] }, vec![0, 2]), + InputPair::ExtrinsicIndex(ExtrinsicIndex { block: zero + 1, key: vec![105] }, vec![0, 2, 4]), + ]), + (zero + 2, vec![ + InputPair::ExtrinsicIndex(ExtrinsicIndex { block: zero + 2, key: vec![102] }, vec![0]), + ]), + (zero + 4, vec![ + InputPair::ExtrinsicIndex(ExtrinsicIndex { block: zero + 2, key: vec![102] }, vec![0, 3]), + + InputPair::DigestIndex(DigestIndex { block: zero + 4, key: vec![102] }, vec![zero + 2]), + ]), ]), - (9, Vec::new()), (10, Vec::new()), (11, Vec::new()), (12, Vec::new()), (13, Vec::new()), - (14, Vec::new()), (15, Vec::new()), ]); let changes = OverlayedChanges { - prospective: vec![ + prospective: OverlayedChangeSet { top: vec![ (vec![100], OverlayedValue { value: Some(vec![200]), extrinsics: Some(vec![0, 2].into_iter().collect()) @@ -235,7 +414,22 @@ mod test { extrinsics: Some(vec![0, 1].into_iter().collect()) }), ].into_iter().collect(), - committed: vec![ + children: vec![ + (child_trie_key1.clone(), vec![ + (vec![100], OverlayedValue { + value: Some(vec![200]), + extrinsics: Some(vec![0, 2].into_iter().collect()) + }) + ].into_iter().collect()), + (child_trie_key2, vec![ + (vec![100], OverlayedValue { + value: Some(vec![200]), + extrinsics: Some(vec![0, 2].into_iter().collect()) + }) + ].into_iter().collect()), + ].into_iter().collect() + }, + committed: OverlayedChangeSet { top: vec![ (EXTRINSIC_INDEX.to_vec(), OverlayedValue { value: Some(3u32.encode()), extrinsics: None, @@ -249,108 +443,320 @@ mod test { extrinsics: Some(vec![1].into_iter().collect()) }), ].into_iter().collect(), - changes_trie_config: Some(Configuration { digest_interval: 4, digest_levels: 2 }), + children: vec![ + (child_trie_key1, vec![ + (vec![100], OverlayedValue { + value: Some(vec![202]), + extrinsics: Some(vec![3].into_iter().collect()) + }) + ].into_iter().collect()), + ].into_iter().collect(), + }, + changes_trie_config: Some(config.clone()), }; - (backend, storage, changes) + (backend, storage, changes, config) + } + + fn configuration_range<'a>(config: &'a Configuration, zero: u64) -> ConfigurationRange<'a, u64> { + ConfigurationRange { + config, + zero, + end: None, + } } #[test] fn build_changes_trie_nodes_on_non_digest_block() { - let (backend, storage, changes) = prepare_for_build(); - let config = changes.changes_trie_config.as_ref().unwrap(); - let parent = AnchorBlockId { hash: Default::default(), number: 4 }; - let changes_trie_nodes = prepare_input( - &backend, - &storage, - config, - &changes, - &parent, - ).unwrap(); - assert_eq!(changes_trie_nodes.collect::>>(), vec![ - InputPair::ExtrinsicIndex(ExtrinsicIndex { block: 5, key: vec![100] }, vec![0, 2, 3]), - InputPair::ExtrinsicIndex(ExtrinsicIndex { block: 5, key: vec![101] }, vec![1]), - InputPair::ExtrinsicIndex(ExtrinsicIndex { block: 5, key: vec![103] }, vec![0, 1]), - ]); + fn test_with_zero(zero: u64) { + let (backend, storage, changes, config) = prepare_for_build(zero); + let parent = AnchorBlockId { hash: Default::default(), number: zero + 4 }; + let changes_trie_nodes = prepare_input( + &backend, + &storage, + configuration_range(&config, zero), + &changes, + &parent, + ).unwrap(); + assert_eq!(changes_trie_nodes.0.collect::>>(), vec![ + InputPair::ExtrinsicIndex(ExtrinsicIndex { block: zero + 5, key: vec![100] }, vec![0, 2, 3]), + InputPair::ExtrinsicIndex(ExtrinsicIndex { block: zero + 5, key: vec![101] }, vec![1]), + InputPair::ExtrinsicIndex(ExtrinsicIndex { block: zero + 5, key: vec![103] }, vec![0, 1]), + ]); + assert_eq!(changes_trie_nodes.1.into_iter() + .map(|(k,v)| (k, v.collect::>())).collect::>(), vec![ + (ChildIndex { block: zero + 5u64, storage_key: b"1".to_vec() }, + vec![ + InputPair::ExtrinsicIndex(ExtrinsicIndex { block: zero + 5u64, key: vec![100] }, vec![0, 2, 3]), + ]), + (ChildIndex { block: zero + 5, storage_key: b"2".to_vec() }, + vec![ + InputPair::ExtrinsicIndex(ExtrinsicIndex { block: zero + 5, key: vec![100] }, vec![0, 2]), + ]), + ]); + + } + + test_with_zero(0); + test_with_zero(16); + test_with_zero(17); } #[test] fn build_changes_trie_nodes_on_digest_block_l1() { - let (backend, storage, changes) = prepare_for_build(); - let config = changes.changes_trie_config.as_ref().unwrap(); - let parent = AnchorBlockId { hash: Default::default(), number: 3 }; - let changes_trie_nodes = prepare_input( - &backend, - &storage, - config, - &changes, - &parent, - ).unwrap(); - assert_eq!(changes_trie_nodes.collect::>>(), vec![ - InputPair::ExtrinsicIndex(ExtrinsicIndex { block: 4, key: vec![100] }, vec![0, 2, 3]), - InputPair::ExtrinsicIndex(ExtrinsicIndex { block: 4, key: vec![101] }, vec![1]), - InputPair::ExtrinsicIndex(ExtrinsicIndex { block: 4, key: vec![103] }, vec![0, 1]), - - InputPair::DigestIndex(DigestIndex { block: 4, key: vec![100] }, vec![1, 3]), - InputPair::DigestIndex(DigestIndex { block: 4, key: vec![101] }, vec![1]), - InputPair::DigestIndex(DigestIndex { block: 4, key: vec![102] }, vec![2]), - InputPair::DigestIndex(DigestIndex { block: 4, key: vec![105] }, vec![1, 3]), - ]); + fn test_with_zero(zero: u64) { + let (backend, storage, changes, config) = prepare_for_build(zero); + let parent = AnchorBlockId { hash: Default::default(), number: zero + 3 }; + let changes_trie_nodes = prepare_input( + &backend, + &storage, + configuration_range(&config, zero), + &changes, + &parent, + ).unwrap(); + assert_eq!(changes_trie_nodes.0.collect::>>(), vec![ + InputPair::ExtrinsicIndex(ExtrinsicIndex { block: zero + 4, key: vec![100] }, vec![0, 2, 3]), + InputPair::ExtrinsicIndex(ExtrinsicIndex { block: zero + 4, key: vec![101] }, vec![1]), + InputPair::ExtrinsicIndex(ExtrinsicIndex { block: zero + 4, key: vec![103] }, vec![0, 1]), + + InputPair::DigestIndex(DigestIndex { block: zero + 4, key: vec![100] }, vec![zero + 1, zero + 3]), + InputPair::DigestIndex(DigestIndex { block: zero + 4, key: vec![101] }, vec![zero + 1]), + InputPair::DigestIndex(DigestIndex { block: zero + 4, key: vec![102] }, vec![zero + 2]), + InputPair::DigestIndex(DigestIndex { block: zero + 4, key: vec![105] }, vec![zero + 1, zero + 3]), + ]); + assert_eq!(changes_trie_nodes.1.into_iter() + .map(|(k,v)| (k, v.collect::>())).collect::>(), vec![ + (ChildIndex { block: zero + 4u64, storage_key: b"1".to_vec() }, + vec![ + InputPair::ExtrinsicIndex(ExtrinsicIndex { block: zero + 4u64, key: vec![100] }, vec![0, 2, 3]), + + InputPair::DigestIndex(DigestIndex { block: zero + 4, key: vec![100] }, vec![zero + 1]), + InputPair::DigestIndex(DigestIndex { block: zero + 4, key: vec![101] }, vec![zero + 1]), + InputPair::DigestIndex(DigestIndex { block: zero + 4, key: vec![102] }, vec![zero + 2]), + InputPair::DigestIndex(DigestIndex { block: zero + 4, key: vec![105] }, vec![zero + 1]), + ]), + (ChildIndex { block: zero + 4, storage_key: b"2".to_vec() }, + vec![ + InputPair::ExtrinsicIndex(ExtrinsicIndex { block: zero + 4, key: vec![100] }, vec![0, 2]), + ]), + ]); + + } + + test_with_zero(0); + test_with_zero(16); + test_with_zero(17); } #[test] fn build_changes_trie_nodes_on_digest_block_l2() { - let (backend, storage, changes) = prepare_for_build(); + fn test_with_zero(zero: u64) { + let (backend, storage, changes, config) = prepare_for_build(zero); + let parent = AnchorBlockId { hash: Default::default(), number: zero + 15 }; + let changes_trie_nodes = prepare_input( + &backend, + &storage, + configuration_range(&config, zero), + &changes, + &parent, + ).unwrap(); + assert_eq!(changes_trie_nodes.0.collect::>>(), vec![ + InputPair::ExtrinsicIndex(ExtrinsicIndex { block: zero + 16, key: vec![100] }, vec![0, 2, 3]), + InputPair::ExtrinsicIndex(ExtrinsicIndex { block: zero + 16, key: vec![101] }, vec![1]), + InputPair::ExtrinsicIndex(ExtrinsicIndex { block: zero + 16, key: vec![103] }, vec![0, 1]), + + InputPair::DigestIndex(DigestIndex { block: zero + 16, key: vec![100] }, vec![zero + 4]), + InputPair::DigestIndex(DigestIndex { block: zero + 16, key: vec![101] }, vec![zero + 4]), + InputPair::DigestIndex(DigestIndex { block: zero + 16, key: vec![102] }, vec![zero + 4]), + InputPair::DigestIndex(DigestIndex { block: zero + 16, key: vec![103] }, vec![zero + 4]), + InputPair::DigestIndex(DigestIndex { block: zero + 16, key: vec![105] }, vec![zero + 4, zero + 8]), + ]); + assert_eq!(changes_trie_nodes.1.into_iter() + .map(|(k,v)| (k, v.collect::>())).collect::>(), vec![ + (ChildIndex { block: zero + 16u64, storage_key: b"1".to_vec() }, + vec![ + InputPair::ExtrinsicIndex(ExtrinsicIndex { block: zero + 16u64, key: vec![100] }, vec![0, 2, 3]), + + InputPair::DigestIndex(DigestIndex { block: zero + 16, key: vec![102] }, vec![zero + 4]), + ]), + (ChildIndex { block: zero + 16, storage_key: b"2".to_vec() }, + vec![ + InputPair::ExtrinsicIndex(ExtrinsicIndex { block: zero + 16, key: vec![100] }, vec![0, 2]), + ]), + ]); + + } + + test_with_zero(0); + test_with_zero(16); + test_with_zero(17); + } + + #[test] + fn build_changes_trie_nodes_on_skewed_digest_block() { + fn test_with_zero(zero: u64) { + let (backend, storage, changes, config) = prepare_for_build(zero); + let parent = AnchorBlockId { hash: Default::default(), number: zero + 10 }; + + let mut configuration_range = configuration_range(&config, zero); + let changes_trie_nodes = prepare_input( + &backend, + &storage, + configuration_range.clone(), + &changes, + &parent, + ).unwrap(); + assert_eq!(changes_trie_nodes.0.collect::>>(), vec![ + InputPair::ExtrinsicIndex(ExtrinsicIndex { block: zero + 11, key: vec![100] }, vec![0, 2, 3]), + InputPair::ExtrinsicIndex(ExtrinsicIndex { block: zero + 11, key: vec![101] }, vec![1]), + InputPair::ExtrinsicIndex(ExtrinsicIndex { block: zero + 11, key: vec![103] }, vec![0, 1]), + ]); + + configuration_range.end = Some(zero + 11); + let changes_trie_nodes = prepare_input( + &backend, + &storage, + configuration_range, + &changes, + &parent, + ).unwrap(); + assert_eq!(changes_trie_nodes.0.collect::>>(), vec![ + InputPair::ExtrinsicIndex(ExtrinsicIndex { block: zero + 11, key: vec![100] }, vec![0, 2, 3]), + InputPair::ExtrinsicIndex(ExtrinsicIndex { block: zero + 11, key: vec![101] }, vec![1]), + InputPair::ExtrinsicIndex(ExtrinsicIndex { block: zero + 11, key: vec![103] }, vec![0, 1]), + + InputPair::DigestIndex(DigestIndex { block: zero + 11, key: vec![100] }, vec![zero + 4]), + InputPair::DigestIndex(DigestIndex { block: zero + 11, key: vec![101] }, vec![zero + 4]), + InputPair::DigestIndex(DigestIndex { block: zero + 11, key: vec![102] }, vec![zero + 4]), + InputPair::DigestIndex(DigestIndex { block: zero + 11, key: vec![103] }, vec![zero + 4]), + InputPair::DigestIndex(DigestIndex { block: zero + 11, key: vec![105] }, vec![zero + 4, zero + 8]), + ]); + } + + test_with_zero(0); + test_with_zero(16); + test_with_zero(17); + } + + #[test] + fn build_changes_trie_nodes_ignores_temporary_storage_values() { + fn test_with_zero(zero: u64) { + let (backend, storage, mut changes, config) = prepare_for_build(zero); + + // 110: missing from backend, set to None in overlay + changes.prospective.top.insert(vec![110], OverlayedValue { + value: None, + extrinsics: Some(vec![1].into_iter().collect()) + }); + + let parent = AnchorBlockId { hash: Default::default(), number: zero + 3 }; + let changes_trie_nodes = prepare_input( + &backend, + &storage, + configuration_range(&config, zero), + &changes, + &parent, + ).unwrap(); + assert_eq!(changes_trie_nodes.0.collect::>>(), vec![ + InputPair::ExtrinsicIndex(ExtrinsicIndex { block: zero + 4, key: vec![100] }, vec![0, 2, 3]), + InputPair::ExtrinsicIndex(ExtrinsicIndex { block: zero + 4, key: vec![101] }, vec![1]), + InputPair::ExtrinsicIndex(ExtrinsicIndex { block: zero + 4, key: vec![103] }, vec![0, 1]), + + InputPair::DigestIndex(DigestIndex { block: zero + 4, key: vec![100] }, vec![zero + 1, zero + 3]), + InputPair::DigestIndex(DigestIndex { block: zero + 4, key: vec![101] }, vec![zero + 1]), + InputPair::DigestIndex(DigestIndex { block: zero + 4, key: vec![102] }, vec![zero + 2]), + InputPair::DigestIndex(DigestIndex { block: zero + 4, key: vec![105] }, vec![zero + 1, zero + 3]), + ]); + assert_eq!(changes_trie_nodes.1.into_iter() + .map(|(k,v)| (k, v.collect::>())).collect::>(), vec![ + (ChildIndex { block: zero + 4u64, storage_key: b"1".to_vec() }, + vec![ + InputPair::ExtrinsicIndex(ExtrinsicIndex { block: zero + 4u64, key: vec![100] }, vec![0, 2, 3]), + + InputPair::DigestIndex(DigestIndex { block: zero + 4, key: vec![100] }, vec![zero + 1]), + InputPair::DigestIndex(DigestIndex { block: zero + 4, key: vec![101] }, vec![zero + 1]), + InputPair::DigestIndex(DigestIndex { block: zero + 4, key: vec![102] }, vec![zero + 2]), + InputPair::DigestIndex(DigestIndex { block: zero + 4, key: vec![105] }, vec![zero + 1]), + ]), + (ChildIndex { block: zero + 4, storage_key: b"2".to_vec() }, + vec![ + InputPair::ExtrinsicIndex(ExtrinsicIndex { block: zero + 4, key: vec![100] }, vec![0, 2]), + ]), + ]); + + } + + test_with_zero(0); + test_with_zero(16); + test_with_zero(17); + } + + #[test] + fn cache_is_used_when_changes_trie_is_built() { + let (backend, mut storage, changes, _) = prepare_for_build(0); let config = changes.changes_trie_config.as_ref().unwrap(); let parent = AnchorBlockId { hash: Default::default(), number: 15 }; - let changes_trie_nodes = prepare_input( + + // override some actual values from storage with values from the cache + // + // top-level storage: + // (keys 100, 101, 103, 105 are now missing from block#4 => they do not appear + // in l2 digest at block 16) + // + // "1" child storage: + // key 102 is now missing from block#4 => it doesn't appear in l2 digest at block 16 + // (keys 103, 104) are now added to block#4 => they appear in l2 digest at block 16 + // + // "2" child storage: + // (keys 105, 106) are now added to block#4 => they appear in l2 digest at block 16 + let trie_root4 = storage.root(&parent, 4).unwrap().unwrap(); + let cached_data4 = IncompleteCacheAction::CacheBuildData(IncompleteCachedBuildData::new()) + .set_digest_input_blocks(vec![1, 2, 3]) + .insert(None, vec![vec![100], vec![102]].into_iter().collect()) + .insert(Some(b"1".to_vec()), vec![vec![103], vec![104]].into_iter().collect()) + .insert(Some(b"2".to_vec()), vec![vec![105], vec![106]].into_iter().collect()) + .complete(4, &trie_root4); + storage.cache_mut().perform(cached_data4); + + let (root_changes_trie_nodes, child_changes_tries_nodes, _) = prepare_input( &backend, &storage, - config, + configuration_range(&config, 0), &changes, &parent, ).unwrap(); - assert_eq!(changes_trie_nodes.collect::>>(), vec![ + assert_eq!(root_changes_trie_nodes.collect::>>(), vec![ InputPair::ExtrinsicIndex(ExtrinsicIndex { block: 16, key: vec![100] }, vec![0, 2, 3]), InputPair::ExtrinsicIndex(ExtrinsicIndex { block: 16, key: vec![101] }, vec![1]), InputPair::ExtrinsicIndex(ExtrinsicIndex { block: 16, key: vec![103] }, vec![0, 1]), InputPair::DigestIndex(DigestIndex { block: 16, key: vec![100] }, vec![4]), - InputPair::DigestIndex(DigestIndex { block: 16, key: vec![101] }, vec![4]), InputPair::DigestIndex(DigestIndex { block: 16, key: vec![102] }, vec![4]), - InputPair::DigestIndex(DigestIndex { block: 16, key: vec![103] }, vec![4]), - InputPair::DigestIndex(DigestIndex { block: 16, key: vec![105] }, vec![4, 8]), + InputPair::DigestIndex(DigestIndex { block: 16, key: vec![105] }, vec![8]), ]); - } - #[test] - fn build_changes_trie_nodes_ignores_temporary_storage_values() { - let (backend, storage, mut changes) = prepare_for_build(); + let child_changes_tries_nodes = child_changes_tries_nodes + .into_iter() + .map(|(k, i)| (k, i.collect::>())) + .collect::>(); + assert_eq!( + child_changes_tries_nodes.get(&ChildIndex { block: 16u64, storage_key: b"1".to_vec() }).unwrap(), + &vec![ + InputPair::ExtrinsicIndex(ExtrinsicIndex { block: 16u64, key: vec![100] }, vec![0, 2, 3]), - // 110: missing from backend, set to None in overlay - changes.prospective.top.insert(vec![110], OverlayedValue { - value: None, - extrinsics: Some(vec![1].into_iter().collect()) - }); + InputPair::DigestIndex(DigestIndex { block: 16u64, key: vec![103] }, vec![4]), + InputPair::DigestIndex(DigestIndex { block: 16u64, key: vec![104] }, vec![4]), + ], + ); + assert_eq!( + child_changes_tries_nodes.get(&ChildIndex { block: 16u64, storage_key: b"2".to_vec() }).unwrap(), + &vec![ + InputPair::ExtrinsicIndex(ExtrinsicIndex { block: 16u64, key: vec![100] }, vec![0, 2]), + + InputPair::DigestIndex(DigestIndex { block: 16u64, key: vec![105] }, vec![4]), + InputPair::DigestIndex(DigestIndex { block: 16u64, key: vec![106] }, vec![4]), + ], + ); - let config = changes.changes_trie_config.as_ref().unwrap(); - let parent = AnchorBlockId { hash: Default::default(), number: 3 }; - let changes_trie_nodes = prepare_input( - &backend, - &storage, - config, - &changes, - &parent, - ).unwrap(); - assert_eq!(changes_trie_nodes.collect::>>(), vec![ - InputPair::ExtrinsicIndex(ExtrinsicIndex { block: 4, key: vec![100] }, vec![0, 2, 3]), - InputPair::ExtrinsicIndex(ExtrinsicIndex { block: 4, key: vec![101] }, vec![1]), - InputPair::ExtrinsicIndex(ExtrinsicIndex { block: 4, key: vec![103] }, vec![0, 1]), - - InputPair::DigestIndex(DigestIndex { block: 4, key: vec![100] }, vec![1, 3]), - InputPair::DigestIndex(DigestIndex { block: 4, key: vec![101] }, vec![1]), - InputPair::DigestIndex(DigestIndex { block: 4, key: vec![102] }, vec![2]), - InputPair::DigestIndex(DigestIndex { block: 4, key: vec![105] }, vec![1, 3]), - ]); } } diff --git a/core/state-machine/src/changes_trie/build_cache.rs b/core/state-machine/src/changes_trie/build_cache.rs new file mode 100644 index 0000000000000000000000000000000000000000..f5c7c28b6b8016dec445bc252c432795a9be91d5 --- /dev/null +++ b/core/state-machine/src/changes_trie/build_cache.rs @@ -0,0 +1,262 @@ +// Copyright 2019 Parity Technologies (UK) Ltd. +// This file is part of Substrate. + +// Substrate 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. + +// Substrate 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 Substrate. If not, see . + +//! Changes tries build cache. + +use std::collections::{HashMap, HashSet}; + +/// Changes trie build cache. +/// +/// Helps to avoid read of changes tries from the database when digest trie +/// is built. It holds changed keys for every block (indexed by changes trie +/// root) that could be referenced by future digest items. For digest entries +/// it also holds keys covered by this digest. Entries for top level digests +/// are never created, because they'll never be used to build other digests. +/// +/// Entries are pruned from the cache once digest block that is using this entry +/// is inserted (because digest block will includes all keys from this entry). +/// When there's a fork, entries are pruned when first changes trie is inserted. +pub struct BuildCache { + /// Map of block (implies changes true) number => changes trie root. + roots_by_number: HashMap, + /// Map of changes trie root => set of storage keys that are in this trie. + /// The `Option>` in inner `HashMap` stands for the child storage key. + /// If it is `None`, then the `HashSet` contains keys changed in top-level storage. + /// If it is `Some`, then the `HashSet` contains keys changed in child storage, identified by the key. + changed_keys: HashMap>, HashSet>>>, +} + +/// The action to perform when block-with-changes-trie is imported. +#[derive(Debug, PartialEq)] +pub enum CacheAction { + /// Cache data that has been collected when CT has been built. + CacheBuildData(CachedBuildData), + /// Clear cache from all existing entries. + Clear, +} + +/// The data that has been cached during changes trie building. +#[derive(Debug, PartialEq)] +pub struct CachedBuildData { + block: N, + trie_root: H, + digest_input_blocks: Vec, + changed_keys: HashMap>, HashSet>>, +} + +/// The action to perform when block-with-changes-trie is imported. +#[derive(Debug, PartialEq)] +pub(crate) enum IncompleteCacheAction { + /// Cache data that has been collected when CT has been built. + CacheBuildData(IncompleteCachedBuildData), + /// Clear cache from all existing entries. + Clear, +} + +/// The data (without changes trie root) that has been cached during changes trie building. +#[derive(Debug, PartialEq)] +pub(crate) struct IncompleteCachedBuildData { + digest_input_blocks: Vec, + changed_keys: HashMap>, HashSet>>, +} + +impl BuildCache + where + N: Eq + ::std::hash::Hash, + H: Eq + ::std::hash::Hash + Clone, +{ + /// Create new changes trie build cache. + pub fn new() -> Self { + BuildCache { + roots_by_number: HashMap::new(), + changed_keys: HashMap::new(), + } + } + + /// Get cached changed keys for changes trie with given root. + pub fn get(&self, root: &H) -> Option<&HashMap>, HashSet>>> { + self.changed_keys.get(&root) + } + + /// Execute given functor with cached entry for given block. + /// Returns true if the functor has been called and false otherwise. + pub fn with_changed_keys( + &self, + root: &H, + functor: &mut dyn FnMut(&HashMap>, HashSet>>), + ) -> bool { + match self.changed_keys.get(&root) { + Some(changed_keys) => { + functor(changed_keys); + true + }, + None => false, + } + } + + /// Insert data into cache. + pub fn perform(&mut self, action: CacheAction) { + match action { + CacheAction::CacheBuildData(data) => { + self.roots_by_number.insert(data.block, data.trie_root.clone()); + self.changed_keys.insert(data.trie_root, data.changed_keys); + + for digest_input_block in data.digest_input_blocks { + let digest_input_block_hash = self.roots_by_number.remove(&digest_input_block); + if let Some(digest_input_block_hash) = digest_input_block_hash { + self.changed_keys.remove(&digest_input_block_hash); + } + } + }, + CacheAction::Clear => { + self.roots_by_number.clear(); + self.changed_keys.clear(); + }, + } + } +} + +impl IncompleteCacheAction { + /// Returns true if we need to collect changed keys for this action. + pub fn collects_changed_keys(&self) -> bool { + match *self { + IncompleteCacheAction::CacheBuildData(_) => true, + IncompleteCacheAction::Clear => false, + } + } + + /// Complete cache action with computed changes trie root. + pub(crate) fn complete(self, block: N, trie_root: &H) -> CacheAction { + match self { + IncompleteCacheAction::CacheBuildData(build_data) => + CacheAction::CacheBuildData(build_data.complete(block, trie_root.clone())), + IncompleteCacheAction::Clear => CacheAction::Clear, + } + } + + /// Set numbers of blocks that are superseded by this new entry. + /// + /// If/when this build data is committed to the cache, entries for these blocks + /// will be removed from the cache. + pub(crate) fn set_digest_input_blocks(self, digest_input_blocks: Vec) -> Self { + match self { + IncompleteCacheAction::CacheBuildData(build_data) => + IncompleteCacheAction::CacheBuildData(build_data.set_digest_input_blocks(digest_input_blocks)), + IncompleteCacheAction::Clear => IncompleteCacheAction::Clear, + } + } + + /// Insert changed keys of given storage into cached data. + pub(crate) fn insert( + self, + storage_key: Option>, + changed_keys: HashSet>, + ) -> Self { + match self { + IncompleteCacheAction::CacheBuildData(build_data) => + IncompleteCacheAction::CacheBuildData(build_data.insert(storage_key, changed_keys)), + IncompleteCacheAction::Clear => IncompleteCacheAction::Clear, + } + } +} + +impl IncompleteCachedBuildData { + /// Create new cached data. + pub(crate) fn new() -> Self { + IncompleteCachedBuildData { + digest_input_blocks: Vec::new(), + changed_keys: HashMap::new(), + } + } + + fn complete(self, block: N, trie_root: H) -> CachedBuildData { + CachedBuildData { + block, + trie_root, + digest_input_blocks: self.digest_input_blocks, + changed_keys: self.changed_keys, + } + } + + fn set_digest_input_blocks(mut self, digest_input_blocks: Vec) -> Self { + self.digest_input_blocks = digest_input_blocks; + self + } + + fn insert( + mut self, + storage_key: Option>, + changed_keys: HashSet>, + ) -> Self { + self.changed_keys.insert(storage_key, changed_keys); + self + } +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn updated_keys_are_stored_when_non_top_level_digest_is_built() { + let mut data = IncompleteCachedBuildData::::new(); + data = data.insert(None, vec![vec![1]].into_iter().collect()); + assert_eq!(data.changed_keys.len(), 1); + + let mut cache = BuildCache::new(); + cache.perform(CacheAction::CacheBuildData(data.complete(1, 1))); + assert_eq!(cache.changed_keys.len(), 1); + assert_eq!( + cache.get(&1).unwrap().clone(), + vec![(None, vec![vec![1]].into_iter().collect())].into_iter().collect(), + ); + } + + #[test] + fn obsolete_entries_are_purged_when_new_ct_is_built() { + let mut cache = BuildCache::::new(); + cache.perform(CacheAction::CacheBuildData(IncompleteCachedBuildData::new() + .insert(None, vec![vec![1]].into_iter().collect()) + .complete(1, 1))); + cache.perform(CacheAction::CacheBuildData(IncompleteCachedBuildData::new() + .insert(None, vec![vec![2]].into_iter().collect()) + .complete(2, 2))); + cache.perform(CacheAction::CacheBuildData(IncompleteCachedBuildData::new() + .insert(None, vec![vec![3]].into_iter().collect()) + .complete(3, 3))); + + assert_eq!(cache.changed_keys.len(), 3); + + cache.perform(CacheAction::CacheBuildData(IncompleteCachedBuildData::new() + .set_digest_input_blocks(vec![1, 2, 3]) + .complete(4, 4))); + + assert_eq!(cache.changed_keys.len(), 1); + + cache.perform(CacheAction::CacheBuildData(IncompleteCachedBuildData::new() + .insert(None, vec![vec![8]].into_iter().collect()) + .complete(8, 8))); + cache.perform(CacheAction::CacheBuildData(IncompleteCachedBuildData::new() + .insert(None, vec![vec![12]].into_iter().collect()) + .complete(12, 12))); + + assert_eq!(cache.changed_keys.len(), 3); + + cache.perform(CacheAction::Clear); + + assert_eq!(cache.changed_keys.len(), 0); + } +} \ No newline at end of file diff --git a/core/state-machine/src/changes_trie/build_iterator.rs b/core/state-machine/src/changes_trie/build_iterator.rs index f4fff28765667685e1d35b7c06f2aa894c2100d7..36b6dd198316d769af467e3c0e93243680b22487 100644 --- a/core/state-machine/src/changes_trie/build_iterator.rs +++ b/core/state-machine/src/changes_trie/build_iterator.rs @@ -17,59 +17,73 @@ //! Structures and functions to return blocks whose changes are to be included //! in given block's changes trie. -use crate::changes_trie::{Configuration, BlockNumber}; +use num_traits::Zero; +use crate::changes_trie::{ConfigurationRange, BlockNumber}; /// Returns iterator of OTHER blocks that are required for inclusion into /// changes trie of given block. Blocks are guaranteed to be returned in /// ascending order. -pub fn digest_build_iterator( - config: &Configuration, +/// +/// Skewed digest is built IF block >= config.end. +pub fn digest_build_iterator<'a, Number: BlockNumber>( + config: ConfigurationRange<'a, Number>, block: Number, ) -> DigestBuildIterator { // prepare digest build parameters - let (_, _, digest_step) = match config.digest_level_at_block(block.clone()) { + let (_, _, digest_step) = match config.config.digest_level_at_block(config.zero, block.clone()) { Some((current_level, digest_interval, digest_step)) => (current_level, digest_interval, digest_step), None => return DigestBuildIterator::empty(), }; - DigestBuildIterator::new(block, config.digest_interval, digest_step) + DigestBuildIterator::new(block.clone(), config.end.unwrap_or(block), config.config.digest_interval, digest_step) } /// Changes trie build iterator that returns numbers of OTHER blocks that are /// required for inclusion into changes trie of given block. #[derive(Debug)] pub struct DigestBuildIterator { - /// Block we're building changes trie for. + /// Block we're building changes trie for. It could (logically) be a post-end block if we are creating + /// skewed digest. block: Number, - /// Interval for creation digest blocks. + /// Block that is a last block where current configuration is active. We have never yet created anything + /// after this block => digest that we're creating can't reference any blocks that are >= end. + end: Number, + /// Interval of L1 digest blocks. digest_interval: u32, - /// Max step of blocks range. + /// Max step that could be used when digest is created. max_step: u32, + + // Mutable data below: + /// Step of current blocks range. current_step: u32, /// Reverse step of current blocks range. current_step_reverse: u32, /// Current blocks range. current_range: Option>, + /// Last block that we have returned. + last_block: Option, } impl DigestBuildIterator { /// Create new digest build iterator. - pub fn new(block: Number, digest_interval: u32, max_step: u32) -> Self { + pub fn new(block: Number, end: Number, digest_interval: u32, max_step: u32) -> Self { DigestBuildIterator { block, + end, digest_interval, max_step, current_step: max_step, current_step_reverse: 0, current_range: None, + last_block: None, } } /// Create empty digest build iterator. pub fn empty() -> Self { - Self::new(0.into(), 0, 0) + Self::new(Zero::zero(), Zero::zero(), 0, 0) } } @@ -77,39 +91,44 @@ impl Iterator for DigestBuildIterator { type Item = Number; fn next(&mut self) -> Option { - if let Some(next) = self.current_range.as_mut().and_then(|iter| iter.next()) { - return Some(next); - } - - // we are safe to use non-checking mul/sub versions here because: - // DigestBuildIterator is created only by internal function that is checking - // that all multiplications/subtractions are safe within max_step limit - - let next_step_reverse = if self.current_step_reverse == 0 { - 1 - } else { - self.current_step_reverse * self.digest_interval - }; - if next_step_reverse > self.max_step { - return None; + // when we're building skewed digest, we might want to skip some blocks if + // they're not covered by current configuration + loop { + if let Some(next) = self.current_range.as_mut().and_then(|iter| iter.next()) { + if next < self.end { + self.last_block = Some(next.clone()); + return Some(next); + } + } + + // we are safe to use non-checking mul/sub versions here because: + // DigestBuildIterator is created only by internal function that is checking + // that all multiplications/subtractions are safe within max_step limit + + let next_step_reverse = if self.current_step_reverse == 0 { + 1 + } else { + self.current_step_reverse * self.digest_interval + }; + if next_step_reverse > self.max_step { + return None; + } + + self.current_step_reverse = next_step_reverse; + self.current_range = Some(BlocksRange::new( + match self.last_block.clone() { + Some(last_block) => last_block + self.current_step.into(), + None => self.block.clone() - (self.current_step * self.digest_interval - self.current_step).into(), + }, + self.block.clone(), + self.current_step.into(), + )); + + self.current_step = self.current_step / self.digest_interval; + if self.current_step == 0 { + self.current_step = 1; + } } - - self.current_step_reverse = next_step_reverse; - self.current_range = Some(BlocksRange::new( - self.block.clone() - (self.current_step * self.digest_interval - self.current_step).into(), - self.block.clone(), - self.current_step.into(), - )); - - self.current_step = self.current_step / self.digest_interval; - if self.current_step == 0 { - self.current_step = 1; - } - - Some(self.current_range.as_mut() - .expect("assigned one line above; qed") - .next() - .expect("X - I^(N+1) + I^N > X when X,I,N are > 1; qed")) } } @@ -147,102 +166,266 @@ impl Iterator for BlocksRange { #[cfg(test)] mod tests { + use crate::changes_trie::Configuration; use super::*; - fn digest_build_iterator(digest_interval: u32, digest_levels: u32, block: u64) -> DigestBuildIterator { - super::digest_build_iterator(&Configuration { digest_interval, digest_levels }, block) + fn digest_build_iterator( + digest_interval: u32, + digest_levels: u32, + zero: u64, + block: u64, + end: Option, + ) -> DigestBuildIterator { + super::digest_build_iterator( + ConfigurationRange { + config: &Configuration { + digest_interval, + digest_levels, + }, + zero, + end, + }, + block, + ) } - fn digest_build_iterator_basic(digest_interval: u32, digest_levels: u32, block: u64) -> (u64, u32, u32) { - let iter = digest_build_iterator(digest_interval, digest_levels, block); + fn digest_build_iterator_basic( + digest_interval: u32, + digest_levels: u32, + zero: u64, + block: u64, + ) -> (u64, u32, u32) { + let iter = digest_build_iterator(digest_interval, digest_levels, zero, block, None); (iter.block, iter.digest_interval, iter.max_step) } - fn digest_build_iterator_blocks(digest_interval: u32, digest_levels: u32, block: u64) -> Vec { - digest_build_iterator(digest_interval, digest_levels, block).collect() + fn digest_build_iterator_blocks( + digest_interval: u32, + digest_levels: u32, + zero: u64, + block: u64, + end: Option, + ) -> Vec { + digest_build_iterator(digest_interval, digest_levels, zero, block, end).collect() } #[test] fn suggest_digest_inclusion_returns_empty_iterator() { - let empty = (0, 0, 0); - assert_eq!(digest_build_iterator_basic(4, 16, 0), empty, "block is 0"); - assert_eq!(digest_build_iterator_basic(0, 16, 64), empty, "digest_interval is 0"); - assert_eq!(digest_build_iterator_basic(1, 16, 64), empty, "digest_interval is 1"); - assert_eq!(digest_build_iterator_basic(4, 0, 64), empty, "digest_levels is 0"); - assert_eq!(digest_build_iterator_basic(4, 16, 1), empty, "digest is not required for this block"); - assert_eq!(digest_build_iterator_basic(4, 16, 2), empty, "digest is not required for this block"); - assert_eq!(digest_build_iterator_basic(4, 16, 15), empty, "digest is not required for this block"); - assert_eq!(digest_build_iterator_basic(4, 16, 17), empty, "digest is not required for this block"); - assert_eq!(digest_build_iterator_basic( - ::std::u32::MAX / 2 + 1, - 16, - ::std::u64::MAX, - ), empty, "digest_interval * 2 is greater than u64::MAX"); + fn test_with_zero(zero: u64) { + let empty = (0, 0, 0); + assert_eq!(digest_build_iterator_basic(4, 16, zero, zero + 0), empty, "block is 0"); + assert_eq!(digest_build_iterator_basic(0, 16, zero, zero + 64), empty, "digest_interval is 0"); + assert_eq!(digest_build_iterator_basic(1, 16, zero, zero + 64), empty, "digest_interval is 1"); + assert_eq!(digest_build_iterator_basic(4, 0, zero, zero + 64), empty, "digest_levels is 0"); + assert_eq!( + digest_build_iterator_basic(4, 16, zero, zero + 1), + empty, + "digest is not required for this block", + ); + assert_eq!( + digest_build_iterator_basic(4, 16, zero, zero + 2), + empty, + "digest is not required for this block", + ); + assert_eq!( + digest_build_iterator_basic(4, 16, zero, zero + 15), + empty, + "digest is not required for this block", + ); + assert_eq!( + digest_build_iterator_basic(4, 16, zero, zero + 17), + empty, + "digest is not required for this block", + ); + assert_eq!(digest_build_iterator_basic( + ::std::u32::MAX / 2 + 1, + 16, + zero, + ::std::u64::MAX, + ), empty, "digest_interval * 2 is greater than u64::MAX"); + } + + test_with_zero(0); + test_with_zero(1); + test_with_zero(2); + test_with_zero(4); + test_with_zero(17); } #[test] fn suggest_digest_inclusion_returns_level1_iterator() { - assert_eq!(digest_build_iterator_basic(16, 1, 16), (16, 16, 1), "!(block % interval) && first digest level == block"); - assert_eq!(digest_build_iterator_basic(16, 1, 256), (256, 16, 1), "!(block % interval^2), but there's only 1 digest level"); - assert_eq!(digest_build_iterator_basic(16, 2, 32), (32, 16, 1), "second level digest is not required for this block"); - assert_eq!(digest_build_iterator_basic(16, 3, 4080), (4080, 16, 1), "second && third level digest are not required for this block"); + fn test_with_zero(zero: u64) { + assert_eq!( + digest_build_iterator_basic(16, 1, zero, zero + 16), + (zero + 16, 16, 1), + "!(block % interval) && first digest level == block", + ); + assert_eq!( + digest_build_iterator_basic(16, 1, zero, zero + 256), + (zero + 256, 16, 1), + "!(block % interval^2), but there's only 1 digest level", + ); + assert_eq!( + digest_build_iterator_basic(16, 2, zero, zero + 32), + (zero + 32, 16, 1), + "second level digest is not required for this block", + ); + assert_eq!( + digest_build_iterator_basic(16, 3, zero, zero + 4080), + (zero + 4080, 16, 1), + "second && third level digest are not required for this block", + ); + } + + test_with_zero(0); + test_with_zero(16); + test_with_zero(17); } #[test] fn suggest_digest_inclusion_returns_level2_iterator() { - assert_eq!(digest_build_iterator_basic(16, 2, 256), (256, 16, 16), "second level digest"); - assert_eq!(digest_build_iterator_basic(16, 2, 4096), (4096, 16, 16), "!(block % interval^3), but there's only 2 digest levels"); + fn test_with_zero(zero: u64) { + assert_eq!( + digest_build_iterator_basic(16, 2, zero, zero + 256), + (zero + 256, 16, 16), + "second level digest", + ); + assert_eq!( + digest_build_iterator_basic(16, 2, zero, zero + 4096), + (zero + 4096, 16, 16), + "!(block % interval^3), but there's only 2 digest levels", + ); + } + + test_with_zero(0); + test_with_zero(16); + test_with_zero(17); } #[test] fn suggest_digest_inclusion_returns_level3_iterator() { - assert_eq!(digest_build_iterator_basic(16, 3, 4096), (4096, 16, 256), "third level digest: beginning"); - assert_eq!(digest_build_iterator_basic(16, 3, 8192), (8192, 16, 256), "third level digest: next"); + fn test_with_zero(zero: u64) { + assert_eq!( + digest_build_iterator_basic(16, 3, zero, zero + 4096), + (zero + 4096, 16, 256), + "third level digest: beginning", + ); + assert_eq!( + digest_build_iterator_basic(16, 3, zero, zero + 8192), + (zero + 8192, 16, 256), + "third level digest: next", + ); + } + + test_with_zero(0); + test_with_zero(16); + test_with_zero(17); } #[test] fn digest_iterator_returns_level1_blocks() { - assert_eq!(digest_build_iterator_blocks(16, 1, 16), - vec![1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15]); - assert_eq!(digest_build_iterator_blocks(16, 1, 256), - vec![241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255]); - assert_eq!(digest_build_iterator_blocks(16, 2, 32), - vec![17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31]); - assert_eq!(digest_build_iterator_blocks(16, 3, 4080), - vec![4065, 4066, 4067, 4068, 4069, 4070, 4071, 4072, 4073, 4074, 4075, 4076, 4077, 4078, 4079]); + fn test_with_zero(zero: u64) { + assert_eq!(digest_build_iterator_blocks(16, 1, zero, zero + 16, None), + [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15] + .iter().map(|item| zero + item).collect::>()); + assert_eq!(digest_build_iterator_blocks(16, 1, zero, zero + 256, None), + [241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255] + .iter().map(|item| zero + item).collect::>()); + assert_eq!(digest_build_iterator_blocks(16, 2, zero, zero + 32, None), + [17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31] + .iter().map(|item| zero + item).collect::>()); + assert_eq!(digest_build_iterator_blocks(16, 3, zero, zero + 4080, None), + [4065, 4066, 4067, 4068, 4069, 4070, 4071, 4072, 4073, 4074, 4075, 4076, 4077, 4078, 4079] + .iter().map(|item| zero + item).collect::>()); + } + + test_with_zero(0); + test_with_zero(16); + test_with_zero(17); } #[test] fn digest_iterator_returns_level1_and_level2_blocks() { - assert_eq!(digest_build_iterator_blocks(16, 2, 256), - vec![ - // level2 points to previous 16-1 level1 digests: - 16, 32, 48, 64, 80, 96, 112, 128, 144, 160, 176, 192, 208, 224, 240, - // level2 is a level1 digest of 16-1 previous blocks: - 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, - ], - ); - assert_eq!(digest_build_iterator_blocks(16, 2, 4096), - vec![ - // level2 points to previous 16-1 level1 digests: - 3856, 3872, 3888, 3904, 3920, 3936, 3952, 3968, 3984, 4000, 4016, 4032, 4048, 4064, 4080, - // level2 is a level1 digest of 16-1 previous blocks: - 4081, 4082, 4083, 4084, 4085, 4086, 4087, 4088, 4089, 4090, 4091, 4092, 4093, 4094, 4095, - ], - ); + fn test_with_zero(zero: u64) { + assert_eq!(digest_build_iterator_blocks(16, 2, zero, zero + 256, None), + [ + // level2 points to previous 16-1 level1 digests: + 16, 32, 48, 64, 80, 96, 112, 128, 144, 160, 176, 192, 208, 224, 240, + // level2 is a level1 digest of 16-1 previous blocks: + 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, + ].iter().map(|item| zero + item).collect::>(), + ); + assert_eq!(digest_build_iterator_blocks(16, 2, zero, zero + 4096, None), + [ + // level2 points to previous 16-1 level1 digests: + 3856, 3872, 3888, 3904, 3920, 3936, 3952, 3968, 3984, 4000, 4016, 4032, 4048, 4064, 4080, + // level2 is a level1 digest of 16-1 previous blocks: + 4081, 4082, 4083, 4084, 4085, 4086, 4087, 4088, 4089, 4090, 4091, 4092, 4093, 4094, 4095, + ].iter().map(|item| zero + item).collect::>(), + ); + } + + test_with_zero(0); + test_with_zero(16); + test_with_zero(17); } #[test] fn digest_iterator_returns_level1_and_level2_and_level3_blocks() { - assert_eq!(digest_build_iterator_blocks(16, 3, 4096), - vec![ - // level3 points to previous 16-1 level2 digests: - 256, 512, 768, 1024, 1280, 1536, 1792, 2048, 2304, 2560, 2816, 3072, 3328, 3584, 3840, - // level3 points to previous 16-1 level1 digests: - 3856, 3872, 3888, 3904, 3920, 3936, 3952, 3968, 3984, 4000, 4016, 4032, 4048, 4064, 4080, - // level3 is a level1 digest of 16-1 previous blocks: - 4081, 4082, 4083, 4084, 4085, 4086, 4087, 4088, 4089, 4090, 4091, 4092, 4093, 4094, 4095, - ], - ); + fn test_with_zero(zero: u64) { + assert_eq!(digest_build_iterator_blocks(16, 3, zero, zero + 4096, None), + [ + // level3 points to previous 16-1 level2 digests: + 256, 512, 768, 1024, 1280, 1536, 1792, 2048, 2304, 2560, 2816, 3072, 3328, 3584, 3840, + // level3 points to previous 16-1 level1 digests: + 3856, 3872, 3888, 3904, 3920, 3936, 3952, 3968, 3984, 4000, 4016, 4032, 4048, 4064, 4080, + // level3 is a level1 digest of 16-1 previous blocks: + 4081, 4082, 4083, 4084, 4085, 4086, 4087, 4088, 4089, 4090, 4091, 4092, 4093, 4094, 4095, + ].iter().map(|item| zero + item).collect::>(), + ); + } + + test_with_zero(0); + test_with_zero(16); + test_with_zero(17); + } + + #[test] + fn digest_iterator_returns_skewed_digest_blocks() { + fn test_with_zero(zero: u64) { + assert_eq!(digest_build_iterator_blocks(16, 3, zero, zero + 4096, Some(zero + 1338)), + [ + // level3 MUST point to previous 16-1 level2 digests, BUT there are only 5: + 256, 512, 768, 1024, 1280, + // level3 MUST point to previous 16-1 level1 digests, BUT there are only 3: + 1296, 1312, 1328, + // level3 MUST be a level1 digest of 16-1 previous blocks, BUT there are only 9: + 1329, 1330, 1331, 1332, 1333, 1334, 1335, 1336, 1337, + ].iter().map(|item| zero + item).collect::>(), + ); + } + + test_with_zero(0); + test_with_zero(16); + test_with_zero(17); + } + + #[test] + fn digest_iterator_returns_skewed_digest_blocks_skipping_level() { + fn test_with_zero(zero: u64) { + assert_eq!(digest_build_iterator_blocks(16, 3, zero, zero + 4096, Some(zero + 1284)), + [ + // level3 MUST point to previous 16-1 level2 digests, BUT there are only 5: + 256, 512, 768, 1024, 1280, + // level3 MUST point to previous 16-1 level1 digests, BUT there are NO ANY L1-digests: + // level3 MUST be a level1 digest of 16-1 previous blocks, BUT there are only 3: + 1281, 1282, 1283, + ].iter().map(|item| zero + item).collect::>(), + ); + } + + test_with_zero(0); + test_with_zero(16); + test_with_zero(17); } } diff --git a/core/state-machine/src/changes_trie/changes_iterator.rs b/core/state-machine/src/changes_trie/changes_iterator.rs index f7342cc60ff32dfc31c8f9cc2832a911a3360f17..e8730a1bddedb7a631a8159a5fcf3b36809ff3a3 100644 --- a/core/state-machine/src/changes_trie/changes_iterator.rs +++ b/core/state-machine/src/changes_trie/changes_iterator.rs @@ -20,37 +20,47 @@ use std::cell::RefCell; use std::collections::VecDeque; use codec::{Decode, Encode}; -use hash_db::{HashDB, Hasher, EMPTY_PREFIX}; -use num_traits::One; -use trie::{Recorder, MemoryDB}; -use crate::changes_trie::{AnchorBlockId, Configuration, RootsStorage, Storage, BlockNumber}; +use hash_db::Hasher; +use num_traits::Zero; +use trie::Recorder; +use crate::changes_trie::{AnchorBlockId, ConfigurationRange, RootsStorage, Storage, BlockNumber}; use crate::changes_trie::input::{DigestIndex, ExtrinsicIndex, DigestIndexValue, ExtrinsicIndexValue}; use crate::changes_trie::storage::{TrieBackendAdapter, InMemoryStorage}; +use crate::changes_trie::input::ChildIndex; +use crate::changes_trie::surface_iterator::{surface_iterator, SurfaceIterator}; use crate::proving_backend::ProvingBackendEssence; use crate::trie_backend_essence::{TrieBackendEssence}; /// Return changes of given key at given blocks range. /// `max` is the number of best known block. /// Changes are returned in descending order (i.e. last block comes first). -pub fn key_changes<'a, S: Storage, H: Hasher, Number: BlockNumber>( - config: &'a Configuration, - storage: &'a S, +pub fn key_changes<'a, H: Hasher, Number: BlockNumber>( + config: ConfigurationRange<'a, Number>, + storage: &'a dyn Storage, begin: Number, end: &'a AnchorBlockId, max: Number, + storage_key: Option<&'a [u8]>, key: &'a [u8], -) -> Result, String> { +) -> Result, String> { // we can't query any roots before root let max = ::std::cmp::min(max.clone(), end.number.clone()); Ok(DrilldownIterator { essence: DrilldownIteratorEssence { + storage_key, key, - roots_storage: storage, + roots_storage: storage.as_roots_storage(), storage, begin: begin.clone(), end, - surface: surface_iterator(config, max, begin, end.number.clone())?, + config: config.clone(), + surface: surface_iterator( + config, + max, + begin, + end.number.clone(), + )?, extrinsics: Default::default(), blocks: Default::default(), @@ -60,14 +70,16 @@ pub fn key_changes<'a, S: Storage, H: Hasher, Number: BlockNumber>( }) } + /// Returns proof of changes of given key at given blocks range. /// `max` is the number of best known block. -pub fn key_changes_proof, H: Hasher, Number: BlockNumber>( - config: &Configuration, - storage: &S, +pub fn key_changes_proof<'a, H: Hasher, Number: BlockNumber>( + config: ConfigurationRange<'a, Number>, + storage: &dyn Storage, begin: Number, end: &AnchorBlockId, max: Number, + storage_key: Option<&[u8]>, key: &[u8], ) -> Result>, String> { // we can't query any roots before root @@ -75,12 +87,19 @@ pub fn key_changes_proof, H: Hasher, Number: BlockNumber>( let mut iter = ProvingDrilldownIterator { essence: DrilldownIteratorEssence { + storage_key, key, - roots_storage: storage.clone(), + roots_storage: storage.as_roots_storage(), storage, begin: begin.clone(), end, - surface: surface_iterator(config, max, begin, end.number.clone())?, + config: config.clone(), + surface: surface_iterator( + config, + max, + begin, + end.number.clone(), + )?, extrinsics: Default::default(), blocks: Default::default(), @@ -101,32 +120,57 @@ pub fn key_changes_proof, H: Hasher, Number: BlockNumber>( /// Check key changes proof and return changes of the key at given blocks range. /// `max` is the number of best known block. /// Changes are returned in descending order (i.e. last block comes first). -pub fn key_changes_proof_check, H: Hasher, Number: BlockNumber>( - config: &Configuration, - roots_storage: &S, +pub fn key_changes_proof_check<'a, H: Hasher, Number: BlockNumber>( + config: ConfigurationRange<'a, Number>, + roots_storage: &dyn RootsStorage, proof: Vec>, begin: Number, end: &AnchorBlockId, max: Number, + storage_key: Option<&[u8]>, + key: &[u8] +) -> Result, String> { + key_changes_proof_check_with_db( + config, + roots_storage, + &InMemoryStorage::with_proof(proof), + begin, + end, + max, + storage_key, + key, + ) +} + +/// Similar to the `key_changes_proof_check` function, but works with prepared proof storage. +pub fn key_changes_proof_check_with_db<'a, H: Hasher, Number: BlockNumber>( + config: ConfigurationRange<'a, Number>, + roots_storage: &dyn RootsStorage, + proof_db: &InMemoryStorage, + begin: Number, + end: &AnchorBlockId, + max: Number, + storage_key: Option<&[u8]>, key: &[u8] ) -> Result, String> { // we can't query any roots before root let max = ::std::cmp::min(max.clone(), end.number.clone()); - let mut proof_db = MemoryDB::::default(); - for item in proof { - proof_db.insert(EMPTY_PREFIX, &item); - } - - let proof_db = InMemoryStorage::with_db(proof_db); DrilldownIterator { essence: DrilldownIteratorEssence { + storage_key, key, roots_storage, - storage: &proof_db, + storage: proof_db, begin: begin.clone(), end, - surface: surface_iterator(config, max, begin, end.number.clone())?, + config: config.clone(), + surface: surface_iterator( + config, + max, + begin, + end.number.clone(), + )?, extrinsics: Default::default(), blocks: Default::default(), @@ -136,87 +180,38 @@ pub fn key_changes_proof_check, H: Hasher, Number: Bl }.collect() } -/// Surface iterator - only traverses top-level digests from given range and tries to find -/// all digest changes for the key. -pub struct SurfaceIterator<'a, Number: BlockNumber> { - config: &'a Configuration, - begin: Number, - max: Number, - current: Option, - current_begin: Number, - digest_step: u32, - digest_level: u32, -} - -impl<'a, Number: BlockNumber> Iterator for SurfaceIterator<'a, Number> { - type Item = Result<(Number, u32), String>; - - fn next(&mut self) -> Option { - let current = self.current.clone()?; - let digest_level = self.digest_level; - - if current < self.digest_step.into() { - self.current = None; - } - else { - let next = current.clone() - self.digest_step.into(); - if next.is_zero() || next < self.begin { - self.current = None; - } - else if next > self.current_begin { - self.current = Some(next); - } else { - let (current, current_begin, digest_step, digest_level) = match - lower_bound_max_digest(self.config, self.max.clone(), self.begin.clone(), next) { - Err(err) => return Some(Err(err)), - Ok(range) => range, - }; - - self.current = Some(current); - self.current_begin = current_begin; - self.digest_step = digest_step; - self.digest_level = digest_level; - } - } - - Some(Ok((current, digest_level))) - } -} - /// Drilldown iterator - receives 'digest points' from surface iterator and explores /// every point until extrinsic is found. -pub struct DrilldownIteratorEssence<'a, RS, S, H, Number> +pub struct DrilldownIteratorEssence<'a, H, Number> where - RS: 'a + RootsStorage, - S: 'a + Storage, H: Hasher, Number: BlockNumber, H::Out: 'a, { + storage_key: Option<&'a [u8]>, key: &'a [u8], - roots_storage: &'a RS, - storage: &'a S, + roots_storage: &'a dyn RootsStorage, + storage: &'a dyn Storage, begin: Number, end: &'a AnchorBlockId, + config: ConfigurationRange<'a, Number>, surface: SurfaceIterator<'a, Number>, extrinsics: VecDeque<(Number, u32)>, - blocks: VecDeque<(Number, u32)>, + blocks: VecDeque<(Number, Option)>, _hasher: ::std::marker::PhantomData, } -impl<'a, RS, S, H, Number> DrilldownIteratorEssence<'a, RS, S, H, Number> +impl<'a, H, Number> DrilldownIteratorEssence<'a, H, Number> where - RS: 'a + RootsStorage, - S: 'a + Storage, H: Hasher, Number: BlockNumber, H::Out: 'a, { pub fn next(&mut self, trie_reader: F) -> Option> where - F: FnMut(&S, H::Out, &[u8]) -> Result>, String>, + F: FnMut(&dyn Storage, H::Out, &[u8]) -> Result>, String>, { match self.do_next(trie_reader) { Ok(Some(res)) => Some(Ok(res)), @@ -227,7 +222,7 @@ impl<'a, RS, S, H, Number> DrilldownIteratorEssence<'a, RS, S, H, Number> fn do_next(&mut self, mut trie_reader: F) -> Result, String> where - F: FnMut(&S, H::Out, &[u8]) -> Result>, String>, + F: FnMut(&dyn Storage, H::Out, &[u8]) -> Result>, String>, { loop { if let Some((block, extrinsic)) = self.extrinsics.pop_front() { @@ -240,6 +235,25 @@ impl<'a, RS, S, H, Number> DrilldownIteratorEssence<'a, RS, S, H, Number> // AND trie roots for old blocks are known (both on full + light node) let trie_root = self.roots_storage.root(&self.end, block.clone())? .ok_or_else(|| format!("Changes trie root for block {} is not found", block.clone()))?; + let trie_root = if let Some(storage_key) = self.storage_key { + let child_key = ChildIndex { + block: block.clone(), + storage_key: storage_key.to_vec(), + }.encode(); + if let Some(trie_root) = trie_reader(self.storage, trie_root, &child_key)? + .and_then(|v| >::decode(&mut &v[..]).ok()) + .map(|v| { + let mut hash = H::Out::default(); + hash.as_mut().copy_from_slice(&v[..]); + hash + }) { + trie_root + } else { + continue; + } + } else { + trie_root + }; // only return extrinsics for blocks before self.max // most of blocks will be filtered out before pushing to `self.blocks` @@ -247,7 +261,7 @@ impl<'a, RS, S, H, Number> DrilldownIteratorEssence<'a, RS, S, H, Number> debug_assert!(block >= self.begin, "We shall not touch digests earlier than a range' begin"); if block <= self.end.number { let extrinsics_key = ExtrinsicIndex { block: block.clone(), key: self.key.to_vec() }.encode(); - let extrinsics = trie_reader(&self.storage, trie_root, &extrinsics_key); + let extrinsics = trie_reader(self.storage, trie_root, &extrinsics_key); if let Some(extrinsics) = extrinsics? { if let Ok(extrinsics) = ExtrinsicIndexValue::decode(&mut &extrinsics[..]) { self.extrinsics.extend(extrinsics.into_iter().rev().map(|e| (block.clone(), e))); @@ -256,17 +270,26 @@ impl<'a, RS, S, H, Number> DrilldownIteratorEssence<'a, RS, S, H, Number> } let blocks_key = DigestIndex { block: block.clone(), key: self.key.to_vec() }.encode(); - let blocks = trie_reader(&self.storage, trie_root, &blocks_key); + let blocks = trie_reader(self.storage, trie_root, &blocks_key); if let Some(blocks) = blocks? { if let Ok(blocks) = >::decode(&mut &blocks[..]) { // filter level0 blocks here because we tend to use digest blocks, // AND digest block changes could also include changes for out-of-range blocks let begin = self.begin.clone(); let end = self.end.number.clone(); + let config = self.config.clone(); self.blocks.extend(blocks.into_iter() .rev() - .filter(|b| level > 1 || (*b >= begin && *b <= end)) - .map(|b| (b, level - 1)) + .filter(|b| level.map(|level| level > 1).unwrap_or(true) || (*b >= begin && *b <= end)) + .map(|b| { + let prev_level = level + .map(|level| Some(level - 1)) + .unwrap_or_else(|| + Some(config.config.digest_level_at_block(config.zero.clone(), b.clone()) + .map(|(level, _, _)| level) + .unwrap_or_else(|| Zero::zero()))); + (b, prev_level) + }) ); } } @@ -284,19 +307,17 @@ impl<'a, RS, S, H, Number> DrilldownIteratorEssence<'a, RS, S, H, Number> } /// Exploring drilldown operator. -pub struct DrilldownIterator<'a, RS, S, H, Number> +pub struct DrilldownIterator<'a, H, Number> where Number: BlockNumber, H: Hasher, - S: 'a + Storage, - RS: 'a + RootsStorage, H::Out: 'a, { - essence: DrilldownIteratorEssence<'a, RS, S, H, Number>, + essence: DrilldownIteratorEssence<'a, H, Number>, } -impl<'a, RS: 'a + RootsStorage, S: Storage, H: Hasher, Number: BlockNumber> Iterator - for DrilldownIterator<'a, RS, S, H, Number> +impl<'a, H: Hasher, Number: BlockNumber> Iterator + for DrilldownIterator<'a, H, Number> { type Item = Result<(Number, u32), String>; @@ -307,24 +328,20 @@ impl<'a, RS: 'a + RootsStorage, S: Storage, H: Hasher, Num } /// Proving drilldown iterator. -struct ProvingDrilldownIterator<'a, RS, S, H, Number> +struct ProvingDrilldownIterator<'a, H, Number> where Number: BlockNumber, H: Hasher, - S: 'a + Storage, - RS: 'a + RootsStorage, H::Out: 'a, { - essence: DrilldownIteratorEssence<'a, RS, S, H, Number>, + essence: DrilldownIteratorEssence<'a, H, Number>, proof_recorder: RefCell>, } -impl<'a, RS, S, H, Number> ProvingDrilldownIterator<'a, RS, S, H, Number> +impl<'a, H, Number> ProvingDrilldownIterator<'a, H, Number> where Number: BlockNumber, H: Hasher, - S: 'a + Storage, - RS: 'a + RootsStorage, H::Out: 'a, { /// Consume the iterator, extracting the gathered proof in lexicographical order @@ -337,12 +354,10 @@ impl<'a, RS, S, H, Number> ProvingDrilldownIterator<'a, RS, S, H, Number> } } -impl<'a, RS, S, H, Number> Iterator for ProvingDrilldownIterator<'a, RS, S, H, Number> +impl<'a, H, Number> Iterator for ProvingDrilldownIterator<'a, H, Number> where Number: BlockNumber, H: Hasher, - S: 'a + Storage, - RS: 'a + RootsStorage, H::Out: 'a, { type Item = Result<(Number, u32), String>; @@ -358,90 +373,11 @@ impl<'a, RS, S, H, Number> Iterator for ProvingDrilldownIterator<'a, RS, S, H, N } } -/// Returns surface iterator for given range of blocks. -fn surface_iterator<'a, Number: BlockNumber>( - config: &'a Configuration, - max: Number, - begin: Number, - end: Number, -) -> Result, String> { - let (current, current_begin, digest_step, digest_level) = lower_bound_max_digest( - config, - max.clone(), - begin.clone(), - end, - )?; - Ok(SurfaceIterator { - config, - begin, - max, - current: Some(current), - current_begin, - digest_step, - digest_level, - }) -} - -/// Returns parameters of highest level digest block that includes the end of given range -/// and tends to include the whole range. -fn lower_bound_max_digest( - config: &Configuration, - max: Number, - begin: Number, - end: Number, -) -> Result<(Number, Number, u32, u32), String> { - if end > max || begin > end { - return Err("invalid changes range".into()); - } - - let mut digest_level = 0u32; - let mut digest_step = 1u32; - let mut digest_interval = 0u32; - let mut current = end.clone(); - let mut current_begin = begin.clone(); - if current_begin != current { - while digest_level != config.digest_levels { - let new_digest_level = digest_level + 1; - let new_digest_step = digest_step * config.digest_interval; - let new_digest_interval = config.digest_interval * { - if digest_interval == 0 { 1 } else { digest_interval } - }; - let new_digest_begin = ((current.clone() - One::one()) - / new_digest_interval.into()) * new_digest_interval.into(); - let new_digest_end = new_digest_begin.clone() + new_digest_interval.into(); - let new_current = new_digest_begin.clone() + new_digest_interval.into(); - - if new_digest_end > max { - if begin < new_digest_begin { - current_begin = new_digest_begin; - } - break; - } - - digest_level = new_digest_level; - digest_step = new_digest_step; - digest_interval = new_digest_interval; - current = new_current; - current_begin = new_digest_begin; - - if current_begin <= begin && new_digest_end >= end { - break; - } - } - } - - Ok(( - current, - current_begin, - digest_step, - digest_level, - )) -} - #[cfg(test)] mod tests { use std::iter::FromIterator; use primitives::Blake2Hasher; + use crate::changes_trie::Configuration; use crate::changes_trie::input::InputPair; use crate::changes_trie::storage::InMemoryStorage; use super::*; @@ -450,8 +386,10 @@ mod tests { let config = Configuration { digest_interval: 4, digest_levels: 2 }; let backend = InMemoryStorage::with_inputs(vec![ // digest: 1..4 => [(3, 0)] - (1, vec![]), - (2, vec![]), + (1, vec![ + ]), + (2, vec![ + ]), (3, vec![ InputPair::ExtrinsicIndex(ExtrinsicIndex { block: 3, key: vec![42] }, vec![0]), ]), @@ -480,37 +418,99 @@ mod tests { (16, vec![ InputPair::DigestIndex(DigestIndex { block: 16, key: vec![42] }, vec![4, 8]), ]), + ], vec![(b"1".to_vec(), vec![ + (1, vec![ + InputPair::ExtrinsicIndex(ExtrinsicIndex { block: 1, key: vec![42] }, vec![0]), + ]), + (2, vec![ + InputPair::ExtrinsicIndex(ExtrinsicIndex { block: 2, key: vec![42] }, vec![3]), + ]), + (16, vec![ + InputPair::ExtrinsicIndex(ExtrinsicIndex { block: 16, key: vec![42] }, vec![5]), + + InputPair::DigestIndex(DigestIndex { block: 16, key: vec![42] }, vec![2]), + ]), + ]), ]); (config, backend) } + fn configuration_range<'a>(config: &'a Configuration, zero: u64) -> ConfigurationRange<'a, u64> { + ConfigurationRange { + config, + zero, + end: None, + } + } + #[test] fn drilldown_iterator_works() { let (config, storage) = prepare_for_drilldown(); - let drilldown_result = key_changes::, Blake2Hasher, u64>( - &config, &storage, 0, &AnchorBlockId { hash: Default::default(), number: 16 }, 16, &[42]) - .and_then(Result::from_iter); + let drilldown_result = key_changes::( + configuration_range(&config, 0), + &storage, + 1, + &AnchorBlockId { hash: Default::default(), number: 16 }, + 16, + None, + &[42], + ).and_then(Result::from_iter); assert_eq!(drilldown_result, Ok(vec![(8, 2), (8, 1), (6, 3), (3, 0)])); - let drilldown_result = key_changes::, Blake2Hasher, u64>( - &config, &storage, 0, &AnchorBlockId { hash: Default::default(), number: 2 }, 4, &[42]) - .and_then(Result::from_iter); + let drilldown_result = key_changes::( + configuration_range(&config, 0), + &storage, + 1, + &AnchorBlockId { hash: Default::default(), number: 2 }, + 4, + None, + &[42], + ).and_then(Result::from_iter); assert_eq!(drilldown_result, Ok(vec![])); - let drilldown_result = key_changes::, Blake2Hasher, u64>( - &config, &storage, 0, &AnchorBlockId { hash: Default::default(), number: 3 }, 4, &[42]) - .and_then(Result::from_iter); + let drilldown_result = key_changes::( + configuration_range(&config, 0), + &storage, + 1, + &AnchorBlockId { hash: Default::default(), number: 3 }, + 4, + None, + &[42], + ).and_then(Result::from_iter); assert_eq!(drilldown_result, Ok(vec![(3, 0)])); - let drilldown_result = key_changes::, Blake2Hasher, u64>( - &config, &storage, 7, &AnchorBlockId { hash: Default::default(), number: 8 }, 8, &[42]) - .and_then(Result::from_iter); + let drilldown_result = key_changes::( + configuration_range(&config, 0), + &storage, + 1, + &AnchorBlockId { hash: Default::default(), number: 7 }, + 7, + None, + &[42], + ).and_then(Result::from_iter); + assert_eq!(drilldown_result, Ok(vec![(6, 3), (3, 0)])); + + let drilldown_result = key_changes::( + configuration_range(&config, 0), + &storage, + 7, + &AnchorBlockId { hash: Default::default(), number: 8 }, + 8, + None, + &[42], + ).and_then(Result::from_iter); assert_eq!(drilldown_result, Ok(vec![(8, 2), (8, 1)])); - let drilldown_result = key_changes::, Blake2Hasher, u64>( - &config, &storage, 5, &AnchorBlockId { hash: Default::default(), number: 7 }, 8, &[42]) - .and_then(Result::from_iter); + let drilldown_result = key_changes::( + configuration_range(&config, 0), + &storage, + 5, + &AnchorBlockId { hash: Default::default(), number: 7 }, + 8, + None, + &[42], + ).and_then(Result::from_iter); assert_eq!(drilldown_result, Ok(vec![(6, 3)])); } @@ -519,18 +519,48 @@ mod tests { let (config, storage) = prepare_for_drilldown(); storage.clear_storage(); - assert!(key_changes::, Blake2Hasher, u64>( - &config, &storage, 0, &AnchorBlockId { hash: Default::default(), number: 100 }, 1000, &[42]) - .and_then(|i| i.collect::, _>>()).is_err()); + assert!(key_changes::( + configuration_range(&config, 0), + &storage, + 1, + &AnchorBlockId { hash: Default::default(), number: 100 }, + 1000, + None, + &[42], + ).and_then(|i| i.collect::, _>>()).is_err()); + + assert!(key_changes::( + configuration_range(&config, 0), + &storage, + 1, + &AnchorBlockId { hash: Default::default(), number: 100 }, + 1000, + Some(&b"1"[..]), + &[42], + ).and_then(|i| i.collect::, _>>()).is_err()); } #[test] fn drilldown_iterator_fails_when_range_is_invalid() { let (config, storage) = prepare_for_drilldown(); - assert!(key_changes::, Blake2Hasher, u64>( - &config, &storage, 0, &AnchorBlockId { hash: Default::default(), number: 100 }, 50, &[42]).is_err()); - assert!(key_changes::, Blake2Hasher, u64>( - &config, &storage, 20, &AnchorBlockId { hash: Default::default(), number: 10 }, 100, &[42]).is_err()); + assert!(key_changes::( + configuration_range(&config, 0), + &storage, + 1, + &AnchorBlockId { hash: Default::default(), number: 100 }, + 50, + None, + &[42], + ).is_err()); + assert!(key_changes::( + configuration_range(&config, 0), + &storage, + 20, + &AnchorBlockId { hash: Default::default(), number: 10 }, + 100, + None, + &[42], + ).is_err()); } @@ -540,20 +570,66 @@ mod tests { // create drilldown iterator that records all trie nodes during drilldown let (remote_config, remote_storage) = prepare_for_drilldown(); - let remote_proof = key_changes_proof::, Blake2Hasher, u64>( - &remote_config, &remote_storage, - 0, &AnchorBlockId { hash: Default::default(), number: 16 }, 16, &[42]).unwrap(); + let remote_proof = key_changes_proof::( + configuration_range(&remote_config, 0), &remote_storage, 1, + &AnchorBlockId { hash: Default::default(), number: 16 }, 16, None, &[42]).unwrap(); + + let (remote_config, remote_storage) = prepare_for_drilldown(); + let remote_proof_child = key_changes_proof::( + configuration_range(&remote_config, 0), &remote_storage, 1, + &AnchorBlockId { hash: Default::default(), number: 16 }, 16, Some(&b"1"[..]), &[42]).unwrap(); // happens on local light node: // create drilldown iterator that works the same, but only depends on trie let (local_config, local_storage) = prepare_for_drilldown(); local_storage.clear_storage(); - let local_result = key_changes_proof_check::, Blake2Hasher, u64>( - &local_config, &local_storage, remote_proof, - 0, &AnchorBlockId { hash: Default::default(), number: 16 }, 16, &[42]); + let local_result = key_changes_proof_check::( + configuration_range(&local_config, 0), &local_storage, remote_proof, 1, + &AnchorBlockId { hash: Default::default(), number: 16 }, 16, None, &[42]); + + let (local_config, local_storage) = prepare_for_drilldown(); + local_storage.clear_storage(); + let local_result_child = key_changes_proof_check::( + configuration_range(&local_config, 0), &local_storage, remote_proof_child, 1, + &AnchorBlockId { hash: Default::default(), number: 16 }, 16, Some(&b"1"[..]), &[42]); // check that drilldown result is the same as if it was happening at the full node assert_eq!(local_result, Ok(vec![(8, 2), (8, 1), (6, 3), (3, 0)])); + assert_eq!(local_result_child, Ok(vec![(16, 5), (2, 3)])); + } + + #[test] + fn drilldown_iterator_works_with_skewed_digest() { + let config = Configuration { digest_interval: 4, digest_levels: 3 }; + let mut config_range = configuration_range(&config, 0); + config_range.end = Some(91); + + // when 4^3 deactivates at block 91: + // last L3 digest has been created at block#64 + // skewed digest covers: + // L2 digests at blocks: 80 + // L1 digests at blocks: 84, 88 + // regular blocks: 89, 90, 91 + let mut input = (1u64..92u64).map(|b| (b, vec![])).collect::>(); + // changed at block#63 and covered by L3 digest at block#64 + input[63 - 1].1.push(InputPair::ExtrinsicIndex(ExtrinsicIndex { block: 63, key: vec![42] }, vec![0])); + input[64 - 1].1.push(InputPair::DigestIndex(DigestIndex { block: 64, key: vec![42] }, vec![63])); + // changed at block#79 and covered by L2 digest at block#80 + skewed digest at block#91 + input[79 - 1].1.push(InputPair::ExtrinsicIndex(ExtrinsicIndex { block: 79, key: vec![42] }, vec![1])); + input[80 - 1].1.push(InputPair::DigestIndex(DigestIndex { block: 80, key: vec![42] }, vec![79])); + input[91 - 1].1.push(InputPair::DigestIndex(DigestIndex { block: 91, key: vec![42] }, vec![80])); + let storage = InMemoryStorage::with_inputs(input, vec![]); + + let drilldown_result = key_changes::( + config_range, + &storage, + 1, + &AnchorBlockId { hash: Default::default(), number: 91 }, + 100_000u64, + None, + &[42], + ).and_then(Result::from_iter); + assert_eq!(drilldown_result, Ok(vec![(79, 1), (63, 0)])); } } diff --git a/core/state-machine/src/changes_trie/input.rs b/core/state-machine/src/changes_trie/input.rs index 8da4f1a3862cb0cb813cf36287ce122cfa0c3d71..e0bcad18be114fe58ed55cfbf2cb0123ac612ec3 100644 --- a/core/state-machine/src/changes_trie/input.rs +++ b/core/state-machine/src/changes_trie/input.rs @@ -40,9 +40,22 @@ pub struct DigestIndex { pub key: Vec, } +/// Key of { childtrie key => Childchange trie } mapping. +#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord)] +pub struct ChildIndex { + /// Block at which this key has been inserted in the trie. + pub block: Number, + /// Storage key this node is responsible for. + pub storage_key: Vec, +} + /// Value of { changed key => block/digest block numbers } mapping. pub type DigestIndexValue = Vec; +/// Value of { changed key => block/digest block numbers } mapping. +/// That is the root of the child change trie. +pub type ChildIndexValue = Vec; + /// Single input pair of changes trie. #[derive(Clone, Debug, PartialEq, Eq)] pub enum InputPair { @@ -50,6 +63,8 @@ pub enum InputPair { ExtrinsicIndex(ExtrinsicIndex, ExtrinsicIndexValue), /// Element of { key => set of blocks/digest blocks where key has been changed } element mapping. DigestIndex(DigestIndex, DigestIndexValue), + /// Element of { childtrie key => Childchange trie } where key has been changed } element mapping. + ChildIndex(ChildIndex, ChildIndexValue), } /// Single input key of changes trie. @@ -59,6 +74,19 @@ pub enum InputKey { ExtrinsicIndex(ExtrinsicIndex), /// Key of { key => set of blocks/digest blocks where key has been changed } element mapping. DigestIndex(DigestIndex), + /// Key of { childtrie key => Childchange trie } where key has been changed } element mapping. + ChildIndex(ChildIndex), +} + +impl InputPair { + /// Extract storage key that this pair corresponds to. + pub fn key(&self) -> Option<&[u8]> { + match *self { + InputPair::ExtrinsicIndex(ref key, _) => Some(&key.key), + InputPair::DigestIndex(ref key, _) => Some(&key.key), + InputPair::ChildIndex(_, _) => None, + } + } } impl Into<(Vec, Vec)> for InputPair { @@ -66,6 +94,7 @@ impl Into<(Vec, Vec)> for InputPair { match self { InputPair::ExtrinsicIndex(key, value) => (key.encode(), value.encode()), InputPair::DigestIndex(key, value) => (key.encode(), value.encode()), + InputPair::ChildIndex(key, value) => (key.encode(), value.encode()), } } } @@ -75,6 +104,7 @@ impl Into> for InputPair { match self { InputPair::ExtrinsicIndex(key, _) => InputKey::ExtrinsicIndex(key), InputPair::DigestIndex(key, _) => InputKey::DigestIndex(key), + InputPair::ChildIndex(key, _) => InputKey::ChildIndex(key), } } } @@ -114,6 +144,22 @@ impl Encode for DigestIndex { } } +impl ChildIndex { + pub fn key_neutral_prefix(block: Number) -> Vec { + let mut prefix = vec![3]; + prefix.extend(block.encode()); + prefix + } +} + +impl Encode for ChildIndex { + fn encode_to(&self, dest: &mut W) { + dest.push_byte(3); + self.block.encode_to(dest); + self.storage_key.encode_to(dest); + } +} + impl codec::EncodeLike for DigestIndex {} impl Decode for InputKey { @@ -127,6 +173,10 @@ impl Decode for InputKey { block: Decode::decode(input)?, key: Decode::decode(input)?, })), + 3 => Ok(InputKey::ChildIndex(ChildIndex { + block: Decode::decode(input)?, + storage_key: Decode::decode(input)?, + })), _ => Err("Invalid input key variant".into()), } } diff --git a/core/state-machine/src/changes_trie/mod.rs b/core/state-machine/src/changes_trie/mod.rs index b29a515d74b4a3e2eb22afe6725e635e28ce1c0c..f771fddf6196415ce53e0176633bdbb5149e8ba9 100644 --- a/core/state-machine/src/changes_trie/mod.rs +++ b/core/state-machine/src/changes_trie/mod.rs @@ -32,26 +32,48 @@ //! the last N*digest_level-1 blocks (except for genesis block), mapping these keys //! to the set of lower-level digest blocks. //! +//! Changes trie configuration could change within a time. The range of blocks, where +//! configuration has been active, is given by two blocks: zero and end. Zero block is +//! the block where configuration has been set. But the first changes trie that uses +//! this configuration will be built at the block zero+1. If configuration deactivates +//! at some block, this will be the end block of the configuration. It is also the +//! zero block of the next configuration. +//! +//! If configuration has the end block, it also means that 'skewed digest' has/should +//! been built at that block. If this is the block where max-level digest should have +//! been created, than it is simply max-level digest of this configuration. Otherwise, +//! it is the digest that covers all blocks since last max-level digest block was +//! created. +//! //! Changes trie only contains the top level storage changes. Sub-level changes //! are propagated through its storage root on the top level storage. mod build; +mod build_cache; mod build_iterator; mod changes_iterator; mod input; mod prune; mod storage; +mod surface_iterator; +pub use self::build_cache::{BuildCache, CachedBuildData, CacheAction}; pub use self::storage::InMemoryStorage; -pub use self::changes_iterator::{key_changes, key_changes_proof, key_changes_proof_check}; +pub use self::changes_iterator::{ + key_changes, key_changes_proof, + key_changes_proof_check, key_changes_proof_check_with_db, +}; pub use self::prune::{prune, oldest_non_pruned_trie}; +use std::collections::{HashMap, HashSet}; +use std::convert::TryInto; use hash_db::{Hasher, Prefix}; use crate::backend::Backend; use num_traits::{One, Zero}; use codec::{Decode, Encode}; use primitives; use crate::changes_trie::build::prepare_input; +use crate::changes_trie::build_cache::{IncompleteCachedBuildData, IncompleteCacheAction}; use crate::overlayed_changes::OverlayedChanges; use trie::{MemoryDB, DBValue, TrieMut}; use trie::trie_types::TrieDBMut; @@ -64,8 +86,9 @@ pub trait BlockNumber: Send + Sync + 'static + ::std::fmt::Display + Clone + - From + One + Zero + + From + TryInto + One + Zero + PartialEq + Ord + + ::std::hash::Hash + ::std::ops::Add + ::std::ops::Sub + ::std::ops::Mul + ::std::ops::Div + ::std::ops::Rem + @@ -78,8 +101,9 @@ impl BlockNumber for T where T: Send + Sync + 'static + ::std::fmt::Display + Clone + - From + One + Zero + + From + TryInto + One + Zero + PartialEq + Ord + + ::std::hash::Hash + ::std::ops::Add + ::std::ops::Sub + ::std::ops::Mul + ::std::ops::Div + ::std::ops::Rem + @@ -108,6 +132,15 @@ pub trait RootsStorage: Send + Sync { /// Changes trie storage. Provides access to trie roots and trie nodes. pub trait Storage: RootsStorage { + /// Casts from self reference to RootsStorage reference. + fn as_roots_storage(&self) -> &dyn RootsStorage; + /// Execute given functor with cached entry for given trie root. + /// Returns true if the functor has been called (cache entry exists) and false otherwise. + fn with_cached_changed_keys( + &self, + root: &H::Out, + functor: &mut dyn FnMut(&HashMap>, HashSet>>), + ) -> bool; /// Get a trie node. fn get(&self, key: &H::Out, prefix: Prefix) -> Result, String>; } @@ -126,6 +159,17 @@ impl<'a, H: Hasher, N: BlockNumber> crate::TrieBackendStorage for TrieBackend /// Changes trie configuration. pub type Configuration = primitives::ChangesTrieConfiguration; +/// Blocks range where configuration has been constant. +#[derive(Clone)] +pub struct ConfigurationRange<'a, N> { + /// Active configuration. + pub config: &'a Configuration, + /// Zero block of this configuration. The configuration is active starting from the next block. + pub zero: N, + /// End block of this configuration. It is the last block where configuration has been active. + pub end: Option, +} + /// Compute the changes trie root and transaction for given block. /// Returns Err(()) if unknown `parent_hash` has been passed. /// Returns Ok(None) if there's no data to perform computation. @@ -135,7 +179,7 @@ pub fn build_changes_trie<'a, B: Backend, S: Storage, H: Hasher, N storage: Option<&'a S>, changes: &OverlayedChanges, parent_hash: H::Out, -) -> Result, H::Out)>, ()> +) -> Result, H::Out, CacheAction)>, ()> where H::Out: Ord + 'static, { @@ -144,21 +188,149 @@ pub fn build_changes_trie<'a, B: Backend, S: Storage, H: Hasher, N _ => return Ok(None), }; + // FIXME: remove this in https://github.com/paritytech/substrate/pull/3201 + let config = ConfigurationRange { + config, + zero: Zero::zero(), + end: None, + }; + // build_anchor error should not be considered fatal let parent = storage.build_anchor(parent_hash).map_err(|_| ())?; + let block = parent.number.clone() + One::one(); // storage errors are considered fatal (similar to situations when runtime fetches values from storage) - let input_pairs = prepare_input::(backend, storage, config, changes, &parent) - .expect("changes trie: storage access is not allowed to fail within runtime"); - let mut root = Default::default(); + let (input_pairs, child_input_pairs, digest_input_blocks) = prepare_input::( + backend, + storage, + config.clone(), + changes, + &parent, + ).expect("changes trie: storage access is not allowed to fail within runtime"); + + // prepare cached data + let mut cache_action = prepare_cached_build_data(config, block.clone()); + let needs_changed_keys = cache_action.collects_changed_keys(); + cache_action = cache_action.set_digest_input_blocks(digest_input_blocks); + let mut mdb = MemoryDB::default(); + let mut child_roots = Vec::with_capacity(child_input_pairs.len()); + for (child_index, input_pairs) in child_input_pairs { + let mut not_empty = false; + let mut root = Default::default(); + { + let mut trie = TrieDBMut::::new(&mut mdb, &mut root); + let mut storage_changed_keys = HashSet::new(); + for input_pair in input_pairs { + if needs_changed_keys { + if let Some(key) = input_pair.key() { + storage_changed_keys.insert(key.to_vec()); + } + } + + let (key, value) = input_pair.into(); + not_empty = true; + trie.insert(&key, &value) + .expect("changes trie: insertion to trie is not allowed to fail within runtime"); + } + + cache_action = cache_action.insert( + Some(child_index.storage_key.clone()), + storage_changed_keys, + ); + } + if not_empty { + child_roots.push(input::InputPair::ChildIndex(child_index, root.as_ref().to_vec())); + } + } + let mut root = Default::default(); { let mut trie = TrieDBMut::::new(&mut mdb, &mut root); - for (key, value) in input_pairs.map(Into::into) { + for (key, value) in child_roots.into_iter().map(Into::into) { trie.insert(&key, &value) .expect("changes trie: insertion to trie is not allowed to fail within runtime"); } + + let mut storage_changed_keys = HashSet::new(); + for input_pair in input_pairs { + if needs_changed_keys { + if let Some(key) = input_pair.key() { + storage_changed_keys.insert(key.to_vec()); + } + } + + let (key, value) = input_pair.into(); + trie.insert(&key, &value) + .expect("changes trie: insertion to trie is not allowed to fail within runtime"); + } + cache_action = cache_action.insert( + None, + storage_changed_keys, + ); + } + + let cache_action = cache_action.complete(block, &root); + Ok(Some((mdb, root, cache_action))) +} + +/// Prepare empty cached build data for given block. +fn prepare_cached_build_data( + config: ConfigurationRange, + block: Number, +) -> IncompleteCacheAction { + // when digests are not enabled in configuration, we do not need to cache anything + // because it'll never be used again for building other tries + // => let's clear the cache + if !config.config.is_digest_build_enabled() { + return IncompleteCacheAction::Clear; + } + + // when this is the last block where current configuration is active + // => let's clear the cache + if config.end.as_ref() == Some(&block) { + return IncompleteCacheAction::Clear; + } + + // we do not need to cache anything when top-level digest trie is created, because + // it'll never be used again for building other tries + // => let's clear the cache + match config.config.digest_level_at_block(config.zero.clone(), block) { + Some((digest_level, _, _)) if digest_level == config.config.digest_levels => IncompleteCacheAction::Clear, + _ => IncompleteCacheAction::CacheBuildData(IncompleteCachedBuildData::new()), } +} + +#[cfg(test)] +mod tests { + use super::*; - Ok(Some((mdb, root))) + #[test] + fn cache_is_cleared_when_digests_are_disabled() { + let config = Configuration { digest_interval: 0, digest_levels: 0 }; + let config_range = ConfigurationRange { zero: 0, end: None, config: &config }; + assert_eq!(prepare_cached_build_data(config_range, 8u32), IncompleteCacheAction::Clear); + } + + #[test] + fn build_data_is_cached_when_digests_are_enabled() { + let config = Configuration { digest_interval: 8, digest_levels: 2 }; + let config_range = ConfigurationRange { zero: 0, end: None, config: &config }; + assert!(prepare_cached_build_data(config_range.clone(), 4u32).collects_changed_keys()); + assert!(prepare_cached_build_data(config_range.clone(), 7u32).collects_changed_keys()); + assert!(prepare_cached_build_data(config_range, 8u32).collects_changed_keys()); + } + + #[test] + fn cache_is_cleared_when_digests_are_enabled_and_top_level_digest_is_built() { + let config = Configuration { digest_interval: 8, digest_levels: 2 }; + let config_range = ConfigurationRange { zero: 0, end: None, config: &config }; + assert_eq!(prepare_cached_build_data(config_range, 64u32), IncompleteCacheAction::Clear); + } + + #[test] + fn cache_is_cleared_when_end_block_of_configuration_is_built() { + let config = Configuration { digest_interval: 8, digest_levels: 2 }; + let config_range = ConfigurationRange { zero: 0, end: Some(4u32), config: &config }; + assert_eq!(prepare_cached_build_data(config_range.clone(), 4u32), IncompleteCacheAction::Clear); + } } diff --git a/core/state-machine/src/changes_trie/prune.rs b/core/state-machine/src/changes_trie/prune.rs index 08e7c02b8c73f1823c050a9293f74ca3d3318857..1dc7c3e6c07b23087a79963e266055ddbf741760 100644 --- a/core/state-machine/src/changes_trie/prune.rs +++ b/core/state-machine/src/changes_trie/prune.rs @@ -19,11 +19,13 @@ use hash_db::Hasher; use trie::Recorder; use log::warn; -use num_traits::One; +use num_traits::{One, Zero}; use crate::proving_backend::ProvingBackendEssence; use crate::trie_backend_essence::TrieBackendEssence; use crate::changes_trie::{AnchorBlockId, Configuration, Storage, BlockNumber}; use crate::changes_trie::storage::TrieBackendAdapter; +use crate::changes_trie::input::{ChildIndex, InputKey}; +use codec::Decode; /// Get number of oldest block for which changes trie is not pruned /// given changes trie configuration, pruning parameter and number of @@ -54,6 +56,7 @@ pub fn prune, H: Hasher, Number: BlockNumber, F: FnMut(H:: current_block: &AnchorBlockId, mut remove_trie_node: F, ) { + // select range for pruning let (first, last) = match pruning_range(config, min_blocks_to_keep, current_block.number.clone()) { Some((first, last)) => (first, last), @@ -81,23 +84,55 @@ pub fn prune, H: Hasher, Number: BlockNumber, F: FnMut(H:: continue; }, }; - - // enumerate all changes trie' keys, recording all nodes that have been 'touched' - // (effectively - all changes trie nodes) - let mut proof_recorder: Recorder = Default::default(); - { - let mut trie = ProvingBackendEssence::<_, H> { - backend: &TrieBackendEssence::new(TrieBackendAdapter::new(storage), root), - proof_recorder: &mut proof_recorder, - }; - trie.record_all_keys(); + let children_roots = { + let trie_storage = TrieBackendEssence::<_, H>::new( + crate::changes_trie::TrieBackendStorageAdapter(storage), + root, + ); + let child_prefix = ChildIndex::key_neutral_prefix(block.clone()); + let mut children_roots = Vec::new(); + trie_storage.for_key_values_with_prefix(&child_prefix, |key, value| { + if let Ok(InputKey::ChildIndex::(_trie_key)) = Decode::decode(&mut &key[..]) { + if let Ok(value) = >::decode(&mut &value[..]) { + let mut trie_root = ::Out::default(); + trie_root.as_mut().copy_from_slice(&value[..]); + children_roots.push(trie_root); + } + } + }); + + children_roots + }; + for root in children_roots.into_iter() { + prune_trie(storage, root, &mut remove_trie_node); } - // all nodes of this changes trie should be pruned - remove_trie_node(root); - for node in proof_recorder.drain().into_iter().map(|n| n.hash) { - remove_trie_node(node); - } + prune_trie(storage, root, &mut remove_trie_node); + } +} + +// Prune a trie. +fn prune_trie, H: Hasher, Number: BlockNumber, F: FnMut(H::Out)>( + storage: &S, + root: H::Out, + remove_trie_node: &mut F, +) { + + // enumerate all changes trie' keys, recording all nodes that have been 'touched' + // (effectively - all changes trie nodes) + let mut proof_recorder: Recorder = Default::default(); + { + let mut trie = ProvingBackendEssence::<_, H> { + backend: &TrieBackendEssence::new(TrieBackendAdapter::new(storage), root), + proof_recorder: &mut proof_recorder, + }; + trie.record_all_keys(); + } + + // all nodes of this changes trie should be pruned + remove_trie_node(root); + for node in proof_recorder.drain().into_iter().map(|n| n.hash) { + remove_trie_node(node); } } @@ -110,7 +145,7 @@ fn pruning_range( // compute number of changes tries we actually want to keep let (prune_interval, blocks_to_keep) = if config.is_digest_build_enabled() { // we only CAN prune at block where max-level-digest is created - let max_digest_interval = match config.digest_level_at_block(block.clone()) { + let max_digest_interval = match config.digest_level_at_block(Zero::zero(), block.clone()) { Some((digest_level, digest_interval, _)) if digest_level == config.digest_levels => digest_interval, _ => return None, @@ -169,6 +204,7 @@ mod tests { use primitives::Blake2Hasher; use crate::backend::insert_into_memory_db; use crate::changes_trie::storage::InMemoryStorage; + use codec::Encode; use super::*; fn config(interval: u32, levels: u32) -> Configuration { @@ -193,12 +229,19 @@ mod tests { #[test] fn prune_works() { fn prepare_storage() -> InMemoryStorage { + + let child_key = ChildIndex { block: 67u64, storage_key: b"1".to_vec() }.encode(); let mut mdb1 = MemoryDB::::default(); let root1 = insert_into_memory_db::(&mut mdb1, vec![(vec![10], vec![20])]).unwrap(); let mut mdb2 = MemoryDB::::default(); let root2 = insert_into_memory_db::(&mut mdb2, vec![(vec![11], vec![21]), (vec![12], vec![22])]).unwrap(); let mut mdb3 = MemoryDB::::default(); - let root3 = insert_into_memory_db::(&mut mdb3, vec![(vec![13], vec![23]), (vec![14], vec![24])]).unwrap(); + let ch_root3 = insert_into_memory_db::(&mut mdb3, vec![(vec![110], vec![120])]).unwrap(); + let root3 = insert_into_memory_db::(&mut mdb3, vec![ + (vec![13], vec![23]), + (vec![14], vec![24]), + (child_key, ch_root3.as_ref().encode()), + ]).unwrap(); let mut mdb4 = MemoryDB::::default(); let root4 = insert_into_memory_db::(&mut mdb4, vec![(vec![15], vec![25])]).unwrap(); let storage = InMemoryStorage::new(); diff --git a/core/state-machine/src/changes_trie/storage.rs b/core/state-machine/src/changes_trie/storage.rs index bb2256235a1a719bb6312b95b9248d9b3c96f5d4..a82477bdc393310089329b070af3d7c0d1603f02 100644 --- a/core/state-machine/src/changes_trie/storage.rs +++ b/core/state-machine/src/changes_trie/storage.rs @@ -16,29 +16,28 @@ //! Changes trie storage utilities. -use std::collections::BTreeMap; -use hash_db::{Hasher, Prefix}; +use std::collections::{BTreeMap, HashSet, HashMap}; +use hash_db::{Hasher, Prefix, EMPTY_PREFIX}; use trie::DBValue; use trie::MemoryDB; use parking_lot::RwLock; -use crate::changes_trie::{RootsStorage, Storage, AnchorBlockId, BlockNumber}; +use crate::changes_trie::{BuildCache, RootsStorage, Storage, AnchorBlockId, BlockNumber}; use crate::trie_backend_essence::TrieBackendStorage; -#[cfg(test)] -use std::collections::HashSet; #[cfg(test)] use crate::backend::insert_into_memory_db; #[cfg(test)] -use crate::changes_trie::input::InputPair; +use crate::changes_trie::input::{InputPair, ChildIndex}; /// In-memory implementation of changes trie storage. pub struct InMemoryStorage { data: RwLock>, + cache: BuildCache, } /// Adapter for using changes trie storage as a TrieBackendEssence' storage. -pub struct TrieBackendAdapter<'a, H: Hasher, Number: BlockNumber, S: 'a + Storage> { - storage: &'a S, +pub struct TrieBackendAdapter<'a, H: Hasher, Number: BlockNumber> { + storage: &'a dyn Storage, _hasher: ::std::marker::PhantomData<(H, Number)>, } @@ -48,21 +47,38 @@ struct InMemoryStorageData { } impl InMemoryStorage { - /// Create the storage from given in-memory database. + /// Creates storage from given in-memory database. pub fn with_db(mdb: MemoryDB) -> Self { Self { data: RwLock::new(InMemoryStorageData { roots: BTreeMap::new(), mdb, }), + cache: BuildCache::new(), } } - /// Create the storage with empty database. + /// Creates storage with empty database. pub fn new() -> Self { Self::with_db(Default::default()) } + /// Creates storage with given proof. + pub fn with_proof(proof: Vec>) -> Self { + use hash_db::HashDB; + + let mut proof_db = MemoryDB::::default(); + for item in proof { + proof_db.insert(EMPTY_PREFIX, &item); + } + Self::with_db(proof_db) + } + + /// Get mutable cache reference. + pub fn cache_mut(&mut self) -> &mut BuildCache { + &mut self.cache + } + /// Create the storage with given blocks. pub fn with_blocks(blocks: Vec<(Number, H::Out)>) -> Self { Self { @@ -70,14 +86,37 @@ impl InMemoryStorage { roots: blocks.into_iter().collect(), mdb: MemoryDB::default(), }), + cache: BuildCache::new(), } } #[cfg(test)] - pub fn with_inputs(inputs: Vec<(Number, Vec>)>) -> Self { + pub fn with_inputs( + mut top_inputs: Vec<(Number, Vec>)>, + children_inputs: Vec<(Vec, Vec<(Number, Vec>)>)>, + ) -> Self { let mut mdb = MemoryDB::default(); let mut roots = BTreeMap::new(); - for (block, pairs) in inputs { + for (storage_key, child_input) in children_inputs { + for (block, pairs) in child_input { + let root = insert_into_memory_db::(&mut mdb, pairs.into_iter().map(Into::into)); + + if let Some(root) = root { + let ix = if let Some(ix) = top_inputs.iter().position(|v| v.0 == block) { + ix + } else { + top_inputs.push((block.clone(), Default::default())); + top_inputs.len() - 1 + }; + top_inputs[ix].1.push(InputPair::ChildIndex( + ChildIndex { block: block.clone(), storage_key: storage_key.clone() }, + root.as_ref().to_vec(), + )); + } + } + } + + for (block, pairs) in top_inputs { let root = insert_into_memory_db::(&mut mdb, pairs.into_iter().map(Into::into)); if let Some(root) = root { roots.insert(block, root); @@ -89,6 +128,7 @@ impl InMemoryStorage { roots, mdb, }), + cache: BuildCache::new(), } } @@ -132,20 +172,31 @@ impl RootsStorage for InMemoryStorage } impl Storage for InMemoryStorage { + fn as_roots_storage(&self) -> &dyn RootsStorage { + self + } + + fn with_cached_changed_keys( + &self, + root: &H::Out, + functor: &mut dyn FnMut(&HashMap>, HashSet>>), + ) -> bool { + self.cache.with_changed_keys(root, functor) + } + fn get(&self, key: &H::Out, prefix: Prefix) -> Result, String> { MemoryDB::::get(&self.data.read().mdb, key, prefix) } } -impl<'a, H: Hasher, Number: BlockNumber, S: 'a + Storage> TrieBackendAdapter<'a, H, Number, S> { - pub fn new(storage: &'a S) -> Self { +impl<'a, H: Hasher, Number: BlockNumber> TrieBackendAdapter<'a, H, Number> { + pub fn new(storage: &'a dyn Storage) -> Self { Self { storage, _hasher: Default::default() } } } -impl<'a, H, Number, S> TrieBackendStorage for TrieBackendAdapter<'a, H, Number, S> +impl<'a, H, Number> TrieBackendStorage for TrieBackendAdapter<'a, H, Number> where - S: 'a + Storage, Number: BlockNumber, H: Hasher, { diff --git a/core/state-machine/src/changes_trie/surface_iterator.rs b/core/state-machine/src/changes_trie/surface_iterator.rs new file mode 100644 index 0000000000000000000000000000000000000000..f3583e2f57e6b7536217a341e32c394a60ff865f --- /dev/null +++ b/core/state-machine/src/changes_trie/surface_iterator.rs @@ -0,0 +1,285 @@ +// Copyright 2017-2019 Parity Technologies (UK) Ltd. +// This file is part of Substrate. + +// Substrate 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. + +// Substrate 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 Substrate. If not, see . + +//! The best way to understand how this iterator works is to imagine some 2D terrain that have some mountains +//! (digest changes tries) and valleys (changes tries for regular blocks). There are gems (blocks) beneath the +//! terrain. Given the request to find all gems in the range [X1; X2] this iterator will return **minimal set** +//! of points at the terrain (mountains and valleys) inside this range that have to be drilled down to +//! search for gems. + +use num_traits::One; +use crate::changes_trie::{ConfigurationRange, BlockNumber}; + +/// Returns surface iterator for given range of blocks. +/// +/// `max` is the number of best block, known to caller. We can't access any changes tries +/// that are built after this block, even though we may have them built already. +pub fn surface_iterator<'a, Number: BlockNumber>( + config: ConfigurationRange<'a, Number>, + max: Number, + begin: Number, + end: Number, +) -> Result, String> { + let (current, current_begin, digest_step, digest_level) = lower_bound_max_digest( + config.clone(), + max.clone(), + begin.clone(), + end, + )?; + Ok(SurfaceIterator { + config, + begin, + max, + current: Some(current), + current_begin, + digest_step, + digest_level, + }) +} + +/// Surface iterator - only traverses top-level digests from given range and tries to find +/// all valid digest changes. +/// +/// Iterator item is the tuple of (last block of the current point + digest level of the current point). +/// Digest level is Some(0) when it is regular block, is Some(non-zero) when it is digest block and None +/// if it is skewed digest block. +pub struct SurfaceIterator<'a, Number: BlockNumber> { + config: ConfigurationRange<'a, Number>, + begin: Number, + max: Number, + current: Option, + current_begin: Number, + digest_step: u32, + digest_level: Option, +} + +impl<'a, Number: BlockNumber> Iterator for SurfaceIterator<'a, Number> { + type Item = Result<(Number, Option), String>; + + fn next(&mut self) -> Option { + let current = self.current.clone()?; + let digest_level = self.digest_level; + + if current < self.digest_step.into() { + self.current = None; + } else { + let next = current.clone() - self.digest_step.into(); + if next.is_zero() || next < self.begin { + self.current = None; + } else if next > self.current_begin { + self.current = Some(next); + } else { + let max_digest_interval = lower_bound_max_digest( + self.config.clone(), + self.max.clone(), + self.begin.clone(), + next, + ); + let (current, current_begin, digest_step, digest_level) = match max_digest_interval { + Err(err) => return Some(Err(err)), + Ok(range) => range, + }; + + self.current = Some(current); + self.current_begin = current_begin; + self.digest_step = digest_step; + self.digest_level = digest_level; + } + } + + Some(Ok((current, digest_level))) + } +} + +/// Returns parameters of highest level digest block that includes the end of given range +/// and tends to include the whole range. +fn lower_bound_max_digest<'a, Number: BlockNumber>( + config: ConfigurationRange<'a, Number>, + max: Number, + begin: Number, + end: Number, +) -> Result<(Number, Number, u32, Option), String> { + if end > max || begin > end { + return Err(format!("invalid changes range: {}..{}/{}", begin, end, max)); + } + if begin <= config.zero || config.end.as_ref().map(|config_end| end > *config_end).unwrap_or(false) { + return Err(format!("changes trie range is not covered by configuration: {}..{}/{}..{}", + begin, end, config.zero, match config.end.as_ref() { + Some(config_end) => format!("{}", config_end), + None => "None".into(), + })); + } + + let mut digest_level = 0u32; + let mut digest_step = 1u32; + let mut digest_interval = 0u32; + let mut current = end.clone(); + let mut current_begin = begin.clone(); + if current_begin != current { + while digest_level != config.config.digest_levels { + // try to use next level digest + let new_digest_level = digest_level + 1; + let new_digest_step = digest_step * config.config.digest_interval; + let new_digest_interval = config.config.digest_interval * { + if digest_interval == 0 { 1 } else { digest_interval } + }; + let new_digest_begin = config.zero.clone() + ((current.clone() - One::one() - config.zero.clone()) + / new_digest_interval.into()) * new_digest_interval.into(); + let new_digest_end = new_digest_begin.clone() + new_digest_interval.into(); + let new_current = new_digest_begin.clone() + new_digest_interval.into(); + + // check if we met skewed digest + if let Some(skewed_digest_end) = config.end.as_ref() { + if new_digest_end > *skewed_digest_end { + let skewed_digest_start = config.config.prev_max_level_digest_block( + config.zero.clone(), + skewed_digest_end.clone(), + ); + if let Some(skewed_digest_start) = skewed_digest_start { + let skewed_digest_range = (skewed_digest_end.clone() - skewed_digest_start.clone()) + .try_into().ok() + .expect("skewed digest range is always <= max level digest range;\ + max level digest range always fits u32; qed"); + return Ok(( + skewed_digest_end.clone(), + skewed_digest_start, + skewed_digest_range, + None, + )); + } + } + } + + // we can't use next level digest if it touches any unknown (> max) blocks + if new_digest_end > max { + if begin < new_digest_begin { + current_begin = new_digest_begin; + } + break; + } + + // we can (and will) use this digest + digest_level = new_digest_level; + digest_step = new_digest_step; + digest_interval = new_digest_interval; + current = new_current; + current_begin = new_digest_begin; + + // if current digest covers the whole range => no need to use next level digest + if current_begin <= begin && new_digest_end >= end { + break; + } + } + } + + Ok(( + current, + current_begin, + digest_step, + Some(digest_level), + )) +} + +#[cfg(test)] +mod tests { + use crate::changes_trie::{Configuration}; + use super::*; + + fn configuration_range<'a>(config: &'a Configuration, zero: u64) -> ConfigurationRange<'a, u64> { + ConfigurationRange { + config, + zero, + end: None, + } + } + + #[test] + fn lower_bound_max_digest_works() { + let config = Configuration { digest_interval: 4, digest_levels: 2 }; + + // when config activates at 0 + assert_eq!( + lower_bound_max_digest(configuration_range(&config, 0u64), 100_000u64, 20u64, 180u64).unwrap(), + (192, 176, 16, Some(2)), + ); + + // when config activates at 30 + assert_eq!( + lower_bound_max_digest(configuration_range(&config, 30u64), 100_000u64, 50u64, 210u64).unwrap(), + (222, 206, 16, Some(2)), + ); + } + + #[test] + fn surface_iterator_works() { + let config = Configuration { digest_interval: 4, digest_levels: 2 }; + + // when config activates at 0 + assert_eq!( + surface_iterator( + configuration_range(&config, 0u64), + 100_000u64, + 40u64, + 180u64, + ).unwrap().collect::>(), + vec![ + Ok((192, Some(2))), Ok((176, Some(2))), Ok((160, Some(2))), Ok((144, Some(2))), + Ok((128, Some(2))), Ok((112, Some(2))), Ok((96, Some(2))), Ok((80, Some(2))), + Ok((64, Some(2))), Ok((48, Some(2))), + ], + ); + + // when config activates at 30 + assert_eq!( + surface_iterator( + configuration_range(&config, 30u64), + 100_000u64, + 40u64, + 180u64, + ).unwrap().collect::>(), + vec![ + Ok((190, Some(2))), Ok((174, Some(2))), Ok((158, Some(2))), Ok((142, Some(2))), Ok((126, Some(2))), + Ok((110, Some(2))), Ok((94, Some(2))), Ok((78, Some(2))), Ok((62, Some(2))), Ok((46, Some(2))), + ], + ); + + // when config activates at 0 AND max block is before next digest + assert_eq!( + surface_iterator(configuration_range(&config, 0u64), 183u64, 40u64, 183u64).unwrap().collect::>(), + vec![ + Ok((183, Some(0))), Ok((182, Some(0))), Ok((181, Some(0))), Ok((180, Some(1))), + Ok((176, Some(2))), Ok((160, Some(2))), Ok((144, Some(2))), Ok((128, Some(2))), Ok((112, Some(2))), + Ok((96, Some(2))), Ok((80, Some(2))), Ok((64, Some(2))), Ok((48, Some(2))), + ], + ); + } + + #[test] + fn surface_iterator_works_with_skewed_digest() { + let config = Configuration { digest_interval: 4, digest_levels: 2 }; + let mut config_range = configuration_range(&config, 0u64); + + // when config activates at 0 AND ends at 170 + config_range.end = Some(170); + assert_eq!( + surface_iterator(config_range, 100_000u64, 40u64, 170u64).unwrap().collect::>(), + vec![ + Ok((170, None)), Ok((160, Some(2))), Ok((144, Some(2))), Ok((128, Some(2))), Ok((112, Some(2))), + Ok((96, Some(2))), Ok((80, Some(2))), Ok((64, Some(2))), Ok((48, Some(2))), + ], + ); + } +} diff --git a/core/state-machine/src/error.rs b/core/state-machine/src/error.rs new file mode 100644 index 0000000000000000000000000000000000000000..6e6ce995858ea409dcbe3e309cb195e44eba4feb --- /dev/null +++ b/core/state-machine/src/error.rs @@ -0,0 +1,47 @@ +// Copyright 2019 Parity Technologies (UK) Ltd. +// This file is part of Substrate. + +// Substrate 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. + +// Substrate 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 Substrate. If not, see . + +/// State Machine Errors + +use std::fmt; + +/// State Machine Error bound. +/// +/// This should reflect Wasm error type bound for future compatibility. +pub trait Error: 'static + fmt::Debug + fmt::Display + Send {} + +impl Error for T {} + +/// Externalities Error. +/// +/// Externalities are not really allowed to have errors, since it's assumed that dependent code +/// would not be executed unless externalities were available. This is included for completeness, +/// and as a transition away from the pre-existing framework. +#[derive(Debug, Eq, PartialEq)] +pub enum ExecutionError { + /// Backend error. + Backend(String), + /// The entry `:code` doesn't exist in storage so there's no way we can execute anything. + CodeEntryDoesNotExist, + /// Backend is incompatible with execution proof generation process. + UnableToGenerateProof, + /// Invalid execution proof. + InvalidProof, +} + +impl fmt::Display for ExecutionError { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { write!(f, "Externalities Error") } +} diff --git a/core/state-machine/src/ext.rs b/core/state-machine/src/ext.rs index 896b07c6473ffe93fb49fbe37e1b6e0ce196c425..c4a2bd7f63b2166ba5973d2fc872679203e6ec1c 100644 --- a/core/state-machine/src/ext.rs +++ b/core/state-machine/src/ext.rs @@ -17,12 +17,19 @@ //! Concrete externalities implementation. use std::{error, fmt, cmp::Ord}; -use log::warn; -use crate::backend::Backend; -use crate::changes_trie::{Storage as ChangesTrieStorage, build_changes_trie}; -use crate::{Externalities, OverlayedChanges, ChildStorageKey}; +use log::{warn, trace}; +use crate::{ + backend::Backend, OverlayedChanges, + changes_trie::{ + Storage as ChangesTrieStorage, CacheAction as ChangesTrieCacheAction, build_changes_trie, + }, +}; use hash_db::Hasher; -use primitives::{offchain, storage::well_known_keys::is_child_storage_key, traits::BareCryptoStorePtr}; +use primitives::{ + offchain, storage::well_known_keys::is_child_storage_key, + traits::{BareCryptoStorePtr, Externalities}, child_storage_key::ChildStorageKey, + hexdisplay::HexDisplay, +}; use trie::{MemoryDB, default_child_trie_root}; use trie::trie_types::Layout; @@ -78,13 +85,15 @@ where /// This differs from `storage_transaction` behavior, because the moment when /// `storage_changes_root` is called matters + we need to remember additional /// data at this moment (block number). - changes_trie_transaction: Option<(MemoryDB, H::Out)>, + changes_trie_transaction: Option<(MemoryDB, H::Out, ChangesTrieCacheAction)>, /// Additional externalities for offchain workers. /// /// If None, some methods from the trait might not be supported. offchain_externalities: Option<&'a mut O>, /// The keystore that manages the keys of the node. keystore: Option, + /// Pseudo-unique id used for tracing. + pub id: u16, /// Dummy usage of N arg. _phantom: ::std::marker::PhantomData, } @@ -114,19 +123,20 @@ where changes_trie_transaction: None, offchain_externalities, keystore, + id: rand::random(), _phantom: Default::default(), } } /// Get the transaction necessary to update the backend. - pub fn transaction(mut self) -> ((B::Transaction, H::Out), Option>) { + pub fn transaction(mut self) -> ((B::Transaction, H::Out), Option>) { let _ = self.storage_root(); let (storage_transaction, changes_trie_transaction) = ( self.storage_transaction .expect("storage_transaction always set after calling storage root; qed"), self.changes_trie_transaction - .map(|(tx, _)| tx), + .map(|(tx, _, cache)| (tx, cache)), ); ( @@ -168,76 +178,146 @@ where } impl<'a, B, T, H, N, O> Externalities for Ext<'a, H, N, B, T, O> -where - H: Hasher, +where H: Hasher, B: 'a + Backend, T: 'a + ChangesTrieStorage, - O: 'a + offchain::Externalities, H::Out: Ord + 'static, N: crate::changes_trie::BlockNumber, + O: 'a + offchain::Externalities, { fn storage(&self, key: &[u8]) -> Option> { let _guard = panic_handler::AbortGuard::force_abort(); - self.overlay.storage(key).map(|x| x.map(|x| x.to_vec())).unwrap_or_else(|| - self.backend.storage(key).expect(EXT_NOT_ALLOWED_TO_FAIL)) + let result = self.overlay.storage(key).map(|x| x.map(|x| x.to_vec())).unwrap_or_else(|| + self.backend.storage(key).expect(EXT_NOT_ALLOWED_TO_FAIL)); + trace!(target: "state-trace", "{:04x}: Get {}={:?}", + self.id, + HexDisplay::from(&key), + result.as_ref().map(HexDisplay::from) + ); + result } fn storage_hash(&self, key: &[u8]) -> Option { let _guard = panic_handler::AbortGuard::force_abort(); - self.overlay.storage(key).map(|x| x.map(|x| H::hash(x))).unwrap_or_else(|| - self.backend.storage_hash(key).expect(EXT_NOT_ALLOWED_TO_FAIL)) + let result = self.overlay.storage(key).map(|x| x.map(|x| H::hash(x))).unwrap_or_else(|| + self.backend.storage_hash(key).expect(EXT_NOT_ALLOWED_TO_FAIL)); + trace!(target: "state-trace", "{:04x}: Hash {}={:?}", + self.id, + HexDisplay::from(&key), + result, + ); + result } fn original_storage(&self, key: &[u8]) -> Option> { let _guard = panic_handler::AbortGuard::force_abort(); - self.backend.storage(key).expect(EXT_NOT_ALLOWED_TO_FAIL) + let result = self.backend.storage(key).expect(EXT_NOT_ALLOWED_TO_FAIL); + trace!(target: "state-trace", "{:04x}: GetOriginal {}={:?}", + self.id, + HexDisplay::from(&key), + result.as_ref().map(HexDisplay::from) + ); + result } fn original_storage_hash(&self, key: &[u8]) -> Option { let _guard = panic_handler::AbortGuard::force_abort(); - self.backend.storage_hash(key).expect(EXT_NOT_ALLOWED_TO_FAIL) + let result = self.backend.storage_hash(key).expect(EXT_NOT_ALLOWED_TO_FAIL); + trace!(target: "state-trace", "{:04x}: GetOriginalHash {}={:?}", + self.id, + HexDisplay::from(&key), + result, + ); + result } - fn child_storage(&self, storage_key: ChildStorageKey, key: &[u8]) -> Option> { + fn child_storage(&self, storage_key: ChildStorageKey, key: &[u8]) -> Option> { let _guard = panic_handler::AbortGuard::force_abort(); - self.overlay.child_storage(storage_key.as_ref(), key).map(|x| x.map(|x| x.to_vec())).unwrap_or_else(|| - self.backend.child_storage(storage_key.as_ref(), key).expect(EXT_NOT_ALLOWED_TO_FAIL)) + let result = self.overlay.child_storage(storage_key.as_ref(), key).map(|x| x.map(|x| x.to_vec())).unwrap_or_else(|| + self.backend.child_storage(storage_key.as_ref(), key).expect(EXT_NOT_ALLOWED_TO_FAIL)); + trace!(target: "state-trace", "{:04x}: GetChild({}) {}={:?}", + self.id, + HexDisplay::from(&storage_key.as_ref()), + HexDisplay::from(&key), + result.as_ref().map(HexDisplay::from) + ); + result } - fn child_storage_hash(&self, storage_key: ChildStorageKey, key: &[u8]) -> Option { + fn child_storage_hash(&self, storage_key: ChildStorageKey, key: &[u8]) -> Option { let _guard = panic_handler::AbortGuard::force_abort(); - self.overlay.child_storage(storage_key.as_ref(), key).map(|x| x.map(|x| H::hash(x))).unwrap_or_else(|| - self.backend.storage_hash(key).expect(EXT_NOT_ALLOWED_TO_FAIL)) + let result = self.overlay.child_storage(storage_key.as_ref(), key).map(|x| x.map(|x| H::hash(x))).unwrap_or_else(|| + self.backend.storage_hash(key).expect(EXT_NOT_ALLOWED_TO_FAIL)); + trace!(target: "state-trace", "{:04x}: ChildHash({}) {}={:?}", + self.id, + HexDisplay::from(&storage_key.as_ref()), + HexDisplay::from(&key), + result, + ); + result } - fn original_child_storage(&self, storage_key: ChildStorageKey, key: &[u8]) -> Option> { + fn original_child_storage(&self, storage_key: ChildStorageKey, key: &[u8]) -> Option> { let _guard = panic_handler::AbortGuard::force_abort(); - self.backend.child_storage(storage_key.as_ref(), key).expect(EXT_NOT_ALLOWED_TO_FAIL) + let result = self.backend.child_storage(storage_key.as_ref(), key).expect(EXT_NOT_ALLOWED_TO_FAIL); + trace!(target: "state-trace", "{:04x}: ChildOriginal({}) {}={:?}", + self.id, + HexDisplay::from(&storage_key.as_ref()), + HexDisplay::from(&key), + result.as_ref().map(HexDisplay::from), + ); + result } - fn original_child_storage_hash(&self, storage_key: ChildStorageKey, key: &[u8]) -> Option { + fn original_child_storage_hash(&self, storage_key: ChildStorageKey, key: &[u8]) -> Option { let _guard = panic_handler::AbortGuard::force_abort(); - self.backend.child_storage_hash(storage_key.as_ref(), key).expect(EXT_NOT_ALLOWED_TO_FAIL) + let result = self.backend.child_storage_hash(storage_key.as_ref(), key).expect(EXT_NOT_ALLOWED_TO_FAIL); + trace!(target: "state-trace", "{}: ChildHashOriginal({}) {}={:?}", + self.id, + HexDisplay::from(&storage_key.as_ref()), + HexDisplay::from(&key), + result, + ); + result } fn exists_storage(&self, key: &[u8]) -> bool { let _guard = panic_handler::AbortGuard::force_abort(); - match self.overlay.storage(key) { + let result = match self.overlay.storage(key) { Some(x) => x.is_some(), _ => self.backend.exists_storage(key).expect(EXT_NOT_ALLOWED_TO_FAIL), - } + }; + trace!(target: "state-trace", "{:04x}: Exists {}={:?}", + self.id, + HexDisplay::from(&key), + result, + ); + result + } - fn exists_child_storage(&self, storage_key: ChildStorageKey, key: &[u8]) -> bool { + fn exists_child_storage(&self, storage_key: ChildStorageKey, key: &[u8]) -> bool { let _guard = panic_handler::AbortGuard::force_abort(); - match self.overlay.child_storage(storage_key.as_ref(), key) { + let result = match self.overlay.child_storage(storage_key.as_ref(), key) { Some(x) => x.is_some(), _ => self.backend.exists_child_storage(storage_key.as_ref(), key).expect(EXT_NOT_ALLOWED_TO_FAIL), - } + }; + trace!(target: "state-trace", "{:04x}: ChildExists({}) {}={:?}", + self.id, + HexDisplay::from(&storage_key.as_ref()), + HexDisplay::from(&key), + result, + ); + result } fn place_storage(&mut self, key: Vec, value: Option>) { + trace!(target: "state-trace", "{:04x}: Put {}={:?}", + self.id, + HexDisplay::from(&key), + value.as_ref().map(HexDisplay::from) + ); let _guard = panic_handler::AbortGuard::force_abort(); if is_child_storage_key(&key) { warn!(target: "trie", "Refuse to directly set child storage key"); @@ -248,14 +328,24 @@ where self.overlay.set_storage(key, value); } - fn place_child_storage(&mut self, storage_key: ChildStorageKey, key: Vec, value: Option>) { + fn place_child_storage(&mut self, storage_key: ChildStorageKey, key: Vec, value: Option>) { + trace!(target: "state-trace", "{:04x}: PutChild({}) {}={:?}", + self.id, + HexDisplay::from(&storage_key.as_ref()), + HexDisplay::from(&key), + value.as_ref().map(HexDisplay::from) + ); let _guard = panic_handler::AbortGuard::force_abort(); self.mark_dirty(); self.overlay.set_child_storage(storage_key.into_owned(), key, value); } - fn kill_child_storage(&mut self, storage_key: ChildStorageKey) { + fn kill_child_storage(&mut self, storage_key: ChildStorageKey) { + trace!(target: "state-trace", "{:04x}: KillChild({})", + self.id, + HexDisplay::from(&storage_key.as_ref()), + ); let _guard = panic_handler::AbortGuard::force_abort(); self.mark_dirty(); @@ -266,6 +356,10 @@ where } fn clear_prefix(&mut self, prefix: &[u8]) { + trace!(target: "state-trace", "{:04x}: ClearPrefix {}", + self.id, + HexDisplay::from(&prefix), + ); let _guard = panic_handler::AbortGuard::force_abort(); if is_child_storage_key(prefix) { warn!(target: "trie", "Refuse to directly clear prefix that is part of child storage key"); @@ -279,7 +373,12 @@ where }); } - fn clear_child_prefix(&mut self, storage_key: ChildStorageKey, prefix: &[u8]) { + fn clear_child_prefix(&mut self, storage_key: ChildStorageKey, prefix: &[u8]) { + trace!(target: "state-trace", "{:04x}: ClearChildPrefix({}) {}", + self.id, + HexDisplay::from(&storage_key.as_ref()), + HexDisplay::from(&prefix), + ); let _guard = panic_handler::AbortGuard::force_abort(); self.mark_dirty(); @@ -296,6 +395,10 @@ where fn storage_root(&mut self) -> H::Out { let _guard = panic_handler::AbortGuard::force_abort(); if let Some((_, ref root)) = self.storage_transaction { + trace!(target: "state-trace", "{:04x}: Root (cached) {}", + self.id, + HexDisplay::from(&root.as_ref()), + ); return root.clone(); } @@ -305,10 +408,10 @@ where let child_delta_iter = child_storage_keys.map(|storage_key| (storage_key.clone(), self.overlay.committed.children.get(storage_key) .into_iter() - .flat_map(|map| map.1.iter().map(|(k, v)| (k.clone(), v.clone()))) + .flat_map(|map| map.iter().map(|(k, v)| (k.clone(), v.value.clone()))) .chain(self.overlay.prospective.children.get(storage_key) .into_iter() - .flat_map(|map| map.1.iter().map(|(k, v)| (k.clone(), v.clone())))))); + .flat_map(|map| map.iter().map(|(k, v)| (k.clone(), v.value.clone())))))); // compute and memoize @@ -317,31 +420,46 @@ where let (root, transaction) = self.backend.full_storage_root(delta, child_delta_iter); self.storage_transaction = Some((transaction, root)); + trace!(target: "state-trace", "{:04x}: Root {}", + self.id, + HexDisplay::from(&root.as_ref()), + ); root } - fn child_storage_root(&mut self, storage_key: ChildStorageKey) -> Vec { + fn child_storage_root(&mut self, storage_key: ChildStorageKey) -> Vec { let _guard = panic_handler::AbortGuard::force_abort(); if self.storage_transaction.is_some() { - self + let root = self .storage(storage_key.as_ref()) .unwrap_or( default_child_trie_root::>(storage_key.as_ref()) - ) + ); + trace!(target: "state-trace", "{:04x}: ChildRoot({}) (cached) {}", + self.id, + HexDisplay::from(&storage_key.as_ref()), + HexDisplay::from(&root.as_ref()), + ); + root } else { let storage_key = storage_key.as_ref(); let delta = self.overlay.committed.children.get(storage_key) .into_iter() - .flat_map(|map| map.1.iter().map(|(k, v)| (k.clone(), v.clone()))) + .flat_map(|map| map.iter().map(|(k, v)| (k.clone(), v.value.clone()))) .chain(self.overlay.prospective.children.get(storage_key) .into_iter() - .flat_map(|map| map.1.clone().into_iter())); + .flat_map(|map| map.clone().into_iter().map(|(k, v)| (k.clone(), v.value.clone())))); let root = self.backend.child_storage_root(storage_key, delta).0; self.overlay.set_storage(storage_key.to_vec(), Some(root.to_vec())); + trace!(target: "state-trace", "{:04x}: ChildRoot({}) {}", + self.id, + HexDisplay::from(&storage_key.as_ref()), + HexDisplay::from(&root.as_ref()), + ); root } @@ -355,7 +473,13 @@ where self.overlay, parent_hash, )?; - Ok(self.changes_trie_transaction.as_ref().map(|(_, root)| root.clone())) + let result = Ok(self.changes_trie_transaction.as_ref().map(|(_, root, _)| root.clone())); + trace!(target: "state-trace", "{:04x}: ChangesRoot({}) {:?}", + self.id, + HexDisplay::from(&parent_hash.as_ref()), + result, + ); + result } fn offchain(&mut self) -> Option<&mut dyn offchain::Externalities> { @@ -365,6 +489,7 @@ where fn keystore(&self) -> Option { self.keystore.clone() } + } #[cfg(test)] diff --git a/core/state-machine/src/lib.rs b/core/state-machine/src/lib.rs index 8c2046e5917c60a356b6b3af4c1614016e65b908..5220b4b31db81982cbd92a7c8fee25c02d9eb8bc 100644 --- a/core/state-machine/src/lib.rs +++ b/core/state-machine/src/lib.rs @@ -18,18 +18,22 @@ #![warn(missing_docs)] -use std::{fmt, panic::UnwindSafe, result, marker::PhantomData}; -use std::borrow::Cow; -use log::warn; +use std::{ + fmt, result, collections::HashMap, + marker::PhantomData, panic::UnwindSafe, +}; +use log::{warn, trace}; use hash_db::Hasher; use codec::{Decode, Encode}; use primitives::{ - storage::well_known_keys, NativeOrEncoded, NeverNativeValue, offchain, - traits::BareCryptoStorePtr, + storage::well_known_keys, NativeOrEncoded, NeverNativeValue, offchain::{self, NeverOffchainExt}, + traits::{BareCryptoStorePtr, CodeExecutor}, + hexdisplay::HexDisplay, }; pub mod backend; mod changes_trie; +mod error; mod ext; mod testing; mod basic; @@ -50,9 +54,12 @@ pub use changes_trie::{ Storage as ChangesTrieStorage, RootsStorage as ChangesTrieRootsStorage, InMemoryStorage as InMemoryChangesTrieStorage, + BuildCache as ChangesTrieBuildCache, + CacheAction as ChangesTrieCacheAction, + ConfigurationRange as ChangesTrieConfigurationRange, key_changes, key_changes_proof, key_changes_proof_check, prune as prune_changes_tries, - oldest_non_pruned_trie as oldest_non_pruned_changes_trie + oldest_non_pruned_trie as oldest_non_pruned_changes_trie, }; pub use overlayed_changes::OverlayedChanges; pub use proving_backend::{ @@ -61,322 +68,17 @@ pub use proving_backend::{ }; pub use trie_backend_essence::{TrieBackendStorage, Storage}; pub use trie_backend::TrieBackend; - - -/// A wrapper around a child storage key. -/// -/// This wrapper ensures that the child storage key is correct and properly used. It is -/// impossible to create an instance of this struct without providing a correct `storage_key`. -pub struct ChildStorageKey<'a, H: Hasher> { - storage_key: Cow<'a, [u8]>, - _hasher: PhantomData, -} - -impl<'a, H: Hasher> ChildStorageKey<'a, H> { - fn new(storage_key: Cow<'a, [u8]>) -> Option { - if !trie::is_child_trie_key_valid::>(&storage_key) { - return None; - } - - Some(ChildStorageKey { - storage_key, - _hasher: PhantomData, - }) - } - - /// Create a new `ChildStorageKey` from a vector. - /// - /// `storage_key` has should start with `:child_storage:default:` - /// See `is_child_trie_key_valid` for more details. - pub fn from_vec(key: Vec) -> Option { - Self::new(Cow::Owned(key)) - } - - /// Create a new `ChildStorageKey` from a slice. - /// - /// `storage_key` has should start with `:child_storage:default:` - /// See `is_child_trie_key_valid` for more details. - pub fn from_slice(key: &'a [u8]) -> Option { - Self::new(Cow::Borrowed(key)) - } - - /// Get access to the byte representation of the storage key. - /// - /// This key is guaranteed to be correct. - pub fn as_ref(&self) -> &[u8] { - &*self.storage_key - } - - /// Destruct this instance into an owned vector that represents the storage key. - /// - /// This key is guaranteed to be correct. - pub fn into_owned(self) -> Vec { - self.storage_key.into_owned() - } -} - -/// State Machine Error bound. -/// -/// This should reflect WASM error type bound for future compatibility. -pub trait Error: 'static + fmt::Debug + fmt::Display + Send {} - -impl Error for ExecutionError {} - -/// Externalities Error. -/// -/// Externalities are not really allowed to have errors, since it's assumed that dependent code -/// would not be executed unless externalities were available. This is included for completeness, -/// and as a transition away from the pre-existing framework. -#[derive(Debug, Eq, PartialEq)] -pub enum ExecutionError { - /// Backend error. - Backend(String), - /// The entry `:code` doesn't exist in storage so there's no way we can execute anything. - CodeEntryDoesNotExist, - /// Backend is incompatible with execution proof generation process. - UnableToGenerateProof, - /// Invalid execution proof. - InvalidProof, -} - -impl fmt::Display for ExecutionError { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { write!(f, "Externalities Error") } -} +pub use error::{Error, ExecutionError}; type CallResult = Result, E>; -/// Externalities: pinned to specific active address. -pub trait Externalities { - /// Read runtime storage. - fn storage(&self, key: &[u8]) -> Option>; - - /// Get storage value hash. This may be optimized for large values. - fn storage_hash(&self, key: &[u8]) -> Option { - self.storage(key).map(|v| H::hash(&v)) - } - - /// Get child storage value hash. This may be optimized for large values. - fn child_storage_hash(&self, storage_key: ChildStorageKey, key: &[u8]) -> Option { - self.child_storage(storage_key, key).map(|v| H::hash(&v)) - } - - /// Read original runtime storage, ignoring any overlayed changes. - fn original_storage(&self, key: &[u8]) -> Option>; - - /// Read original runtime child storage, ignoring any overlayed changes. - fn original_child_storage(&self, storage_key: ChildStorageKey, key: &[u8]) -> Option>; - - /// Get original storage value hash, ignoring any overlayed changes. - /// This may be optimized for large values. - fn original_storage_hash(&self, key: &[u8]) -> Option { - self.original_storage(key).map(|v| H::hash(&v)) - } - - /// Get original child storage value hash, ignoring any overlayed changes. - /// This may be optimized for large values. - fn original_child_storage_hash( - &self, - storage_key: ChildStorageKey, - key: &[u8], - ) -> Option { - self.original_child_storage(storage_key, key).map(|v| H::hash(&v)) - } - - /// Read child runtime storage. - fn child_storage(&self, storage_key: ChildStorageKey, key: &[u8]) -> Option>; - - /// Set storage entry `key` of current contract being called (effective immediately). - fn set_storage(&mut self, key: Vec, value: Vec) { - self.place_storage(key, Some(value)); - } - - /// Set child storage entry `key` of current contract being called (effective immediately). - fn set_child_storage(&mut self, storage_key: ChildStorageKey, key: Vec, value: Vec) { - self.place_child_storage(storage_key, key, Some(value)) - } - - /// Clear a storage entry (`key`) of current contract being called (effective immediately). - fn clear_storage(&mut self, key: &[u8]) { - self.place_storage(key.to_vec(), None); - } - - /// Clear a child storage entry (`key`) of current contract being called (effective immediately). - fn clear_child_storage(&mut self, storage_key: ChildStorageKey, key: &[u8]) { - self.place_child_storage(storage_key, key.to_vec(), None) - } - - /// Whether a storage entry exists. - fn exists_storage(&self, key: &[u8]) -> bool { - self.storage(key).is_some() - } - - /// Whether a child storage entry exists. - fn exists_child_storage(&self, storage_key: ChildStorageKey, key: &[u8]) -> bool { - self.child_storage(storage_key, key).is_some() - } - - /// Clear an entire child storage. - fn kill_child_storage(&mut self, storage_key: ChildStorageKey); - - /// Clear storage entries which keys are start with the given prefix. - fn clear_prefix(&mut self, prefix: &[u8]); - - /// Clear child storage entries which keys are start with the given prefix. - fn clear_child_prefix(&mut self, storage_key: ChildStorageKey, prefix: &[u8]); - - /// Set or clear a storage entry (`key`) of current contract being called (effective immediately). - fn place_storage(&mut self, key: Vec, value: Option>); - - /// Set or clear a child storage entry. Return whether the operation succeeds. - fn place_child_storage(&mut self, storage_key: ChildStorageKey, key: Vec, value: Option>); +type DefaultHandler = fn(CallResult, CallResult) -> CallResult; - /// Get the identity of the chain. - fn chain_id(&self) -> u64; - - /// Get the trie root of the current storage map. This will also update all child storage keys in the top-level storage map. - fn storage_root(&mut self) -> H::Out where H::Out: Ord; - - /// Get the trie root of a child storage map. This will also update the value of the child - /// storage keys in the top-level storage map. - /// If the storage root equals the default hash as defined by the trie, the key in the top-level - /// storage map will be removed. - fn child_storage_root(&mut self, storage_key: ChildStorageKey) -> Vec; - - /// Get the change trie root of the current storage overlay at a block with given parent. - fn storage_changes_root(&mut self, parent: H::Out) -> Result, ()> where H::Out: Ord; - - /// Returns offchain externalities extension if present. - fn offchain(&mut self) -> Option<&mut dyn offchain::Externalities>; - - /// Returns the keystore. - fn keystore(&self) -> Option; -} - -/// An implementation of offchain extensions that should never be triggered. -pub enum NeverOffchainExt {} - -impl NeverOffchainExt { - /// Create new offchain extensions. - pub fn new<'a>() -> Option<&'a mut Self> { - None - } -} - -impl offchain::Externalities for NeverOffchainExt { - fn is_validator(&self) -> bool { - unreachable!() - } - - fn submit_transaction(&mut self, _extrinsic: Vec) -> Result<(), ()> { - unreachable!() - } - - fn network_state( - &self, - ) -> Result { - unreachable!() - } - - fn timestamp(&mut self) -> offchain::Timestamp { - unreachable!() - } - - fn sleep_until(&mut self, _deadline: offchain::Timestamp) { - unreachable!() - } - - fn random_seed(&mut self) -> [u8; 32] { - unreachable!() - } - - fn local_storage_set(&mut self, _kind: offchain::StorageKind, _key: &[u8], _value: &[u8]) { - unreachable!() - } - - fn local_storage_compare_and_set( - &mut self, - _kind: offchain::StorageKind, - _key: &[u8], - _old_value: Option<&[u8]>, - _new_value: &[u8], - ) -> bool { - unreachable!() - } - - fn local_storage_get(&mut self, _kind: offchain::StorageKind, _key: &[u8]) -> Option> { - unreachable!() - } - - fn http_request_start( - &mut self, - _method: &str, - _uri: &str, - _meta: &[u8] - ) -> Result { - unreachable!() - } - - fn http_request_add_header( - &mut self, - _request_id: offchain::HttpRequestId, - _name: &str, - _value: &str - ) -> Result<(), ()> { - unreachable!() - } - - fn http_request_write_body( - &mut self, - _request_id: offchain::HttpRequestId, - _chunk: &[u8], - _deadline: Option - ) -> Result<(), offchain::HttpError> { - unreachable!() - } - - fn http_response_wait( - &mut self, - _ids: &[offchain::HttpRequestId], - _deadline: Option - ) -> Vec { - unreachable!() - } - - fn http_response_headers( - &mut self, - _request_id: offchain::HttpRequestId - ) -> Vec<(Vec, Vec)> { - unreachable!() - } - - fn http_response_read_body( - &mut self, - _request_id: offchain::HttpRequestId, - _buffer: &mut [u8], - _deadline: Option - ) -> Result { - unreachable!() - } -} - -/// Code execution engine. -pub trait CodeExecutor: Sized + Send + Sync { - /// Externalities error type. - type Error: Error; - - /// Call a given method in the runtime. Returns a tuple of the result (either the output data - /// or an execution error) together with a `bool`, which is true if native execution was used. - fn call< - E: Externalities, R: Encode + Decode + PartialEq, NC: FnOnce() -> result::Result + UnwindSafe - >( - &self, - ext: &mut E, - method: &str, - data: &[u8], - use_native: bool, - native_call: Option, - ) -> (CallResult, bool); -} +/// Type of changes trie transaction. +pub type ChangesTrieTransaction = ( + MemoryDB, + ChangesTrieCacheAction<::Out, N>, +); /// Strategy for executing a call into the runtime. #[derive(Copy, Clone, Eq, PartialEq, Debug)] @@ -391,18 +93,26 @@ pub enum ExecutionStrategy { NativeElseWasm, } -type DefaultHandler = fn( - CallResult, - CallResult, -) -> CallResult; +/// Storage backend trust level. +#[derive(Debug, Clone)] +pub enum BackendTrustLevel { + /// Panics from trusted backends are considered justified, and never caught. + Trusted, + /// Panics from untrusted backend are caught and interpreted as runtime error. + /// Untrusted backend may be missing some parts of the trie, so panics are not considered + /// fatal. + Untrusted, +} /// Like `ExecutionStrategy` only it also stores a handler in case of consensus failure. #[derive(Clone)] pub enum ExecutionManager { /// Execute with the native equivalent if it is compatible with the given wasm module; otherwise fall back to the wasm. NativeWhenPossible, - /// Use the given wasm module. - AlwaysWasm, + /// Use the given wasm module. The backend on which code is executed code could be + /// trusted to provide all storage or not (i.e. the light client cannot be trusted to provide + /// for all storage queries since the storage entries it has come from an external node). + AlwaysWasm(BackendTrustLevel), /// Run with both the wasm and the native variant (if compatible). Call `F` in the case of any discrepency. Both(F), /// First native, then if that fails or is not possible, wasm. @@ -413,7 +123,7 @@ impl<'a, F> From<&'a ExecutionManager> for ExecutionStrategy { fn from(s: &'a ExecutionManager) -> Self { match *s { ExecutionManager::NativeWhenPossible => ExecutionStrategy::NativeWhenPossible, - ExecutionManager::AlwaysWasm => ExecutionStrategy::AlwaysWasm, + ExecutionManager::AlwaysWasm(_) => ExecutionStrategy::AlwaysWasm, ExecutionManager::NativeElseWasm => ExecutionStrategy::NativeElseWasm, ExecutionManager::Both(_) => ExecutionStrategy::Both, } @@ -422,9 +132,11 @@ impl<'a, F> From<&'a ExecutionManager> for ExecutionStrategy { impl ExecutionStrategy { /// Gets the corresponding manager for the execution strategy. - pub fn get_manager(self) -> ExecutionManager> { + pub fn get_manager( + self, + ) -> ExecutionManager> { match self { - ExecutionStrategy::AlwaysWasm => ExecutionManager::AlwaysWasm, + ExecutionStrategy::AlwaysWasm => ExecutionManager::AlwaysWasm(BackendTrustLevel::Trusted), ExecutionStrategy::NativeWhenPossible => ExecutionManager::NativeWhenPossible, ExecutionStrategy::NativeElseWasm => ExecutionManager::NativeElseWasm, ExecutionStrategy::Both => ExecutionManager::Both(|wasm_result, native_result| { @@ -439,49 +151,24 @@ impl ExecutionStrategy { } } - -/// Evaluate to ExecutionManager::NativeWhenPossible, without having to figure out the type. -pub fn native_when_possible() -> ExecutionManager> { - ExecutionManager::NativeWhenPossible -} - /// Evaluate to ExecutionManager::NativeElseWasm, without having to figure out the type. pub fn native_else_wasm() -> ExecutionManager> { ExecutionManager::NativeElseWasm } -/// Evaluate to ExecutionManager::NativeWhenPossible, without having to figure out the type. -pub fn always_wasm() -> ExecutionManager> { - ExecutionManager::AlwaysWasm +/// Evaluate to ExecutionManager::AlwaysWasm with trusted backend, without having to figure out the type. +fn always_wasm() -> ExecutionManager> { + ExecutionManager::AlwaysWasm(BackendTrustLevel::Trusted) } -/// Creates new substrate state machine. -pub fn new<'a, H, N, B, T, O, Exec>( - backend: &'a B, - changes_trie_storage: Option<&'a T>, - offchain_ext: Option<&'a mut O>, - overlay: &'a mut OverlayedChanges, - exec: &'a Exec, - method: &'a str, - call_data: &'a [u8], - keystore: Option, -) -> StateMachine<'a, H, N, B, T, O, Exec> { - StateMachine { - backend, - changes_trie_storage, - offchain_ext, - overlay, - exec, - method, - call_data, - keystore, - _hasher: PhantomData, - } +/// Evaluate ExecutionManager::AlwaysWasm with untrusted backend, without having to figure out the type. +fn always_untrusted_wasm() -> ExecutionManager> { + ExecutionManager::AlwaysWasm(BackendTrustLevel::Untrusted) } /// The substrate state machine. -pub struct StateMachine<'a, H, N, B, T, O, Exec> { - backend: &'a B, +pub struct StateMachine<'a, B, H, N, T, O, Exec> { + backend: B, changes_trie_storage: Option<&'a T>, offchain_ext: Option<&'a mut O>, overlay: &'a mut OverlayedChanges, @@ -492,7 +179,7 @@ pub struct StateMachine<'a, H, N, B, T, O, Exec> { _hasher: PhantomData<(H, N)>, } -impl<'a, H, N, B, T, O, Exec> StateMachine<'a, H, N, B, T, O, Exec> where +impl<'a, B, H, N, T, O, Exec> StateMachine<'a, B, H, N, T, O, Exec> where H: Hasher, Exec: CodeExecutor, B: Backend, @@ -501,6 +188,30 @@ impl<'a, H, N, B, T, O, Exec> StateMachine<'a, H, N, B, T, O, Exec> where H::Out: Ord + 'static, N: crate::changes_trie::BlockNumber, { + /// Creates new substrate state machine. + pub fn new( + backend: B, + changes_trie_storage: Option<&'a T>, + offchain_ext: Option<&'a mut O>, + overlay: &'a mut OverlayedChanges, + exec: &'a Exec, + method: &'a str, + call_data: &'a [u8], + keystore: Option, + ) -> Self { + Self { + backend, + changes_trie_storage, + offchain_ext, + overlay, + exec, + method, + call_data, + keystore, + _hasher: PhantomData, + } + } + /// Execute a call using the given state backend, overlayed changes, and call executor. /// Produces a state-backend-specific "transaction" which can be used to apply the changes /// to the backing store, such as the disk. @@ -512,7 +223,7 @@ impl<'a, H, N, B, T, O, Exec> StateMachine<'a, H, N, B, T, O, Exec> where pub fn execute( &mut self, strategy: ExecutionStrategy, - ) -> Result<(Vec, (B::Transaction, H::Out), Option>), Box> { + ) -> Result<(Vec, (B::Transaction, H::Out), Option>), Box> { // We are not giving a native call and thus we are sure that the result can never be a native // value. self.execute_using_consensus_failure_handler::<_, NeverNativeValue, fn() -> _>( @@ -536,18 +247,25 @@ impl<'a, H, N, B, T, O, Exec> StateMachine<'a, H, N, B, T, O, Exec> where CallResult, bool, Option<(B::Transaction, H::Out)>, - Option>, + Option>, ) where R: Decode + Encode + PartialEq, - NC: FnOnce() -> result::Result + UnwindSafe, + NC: FnOnce() -> result::Result + UnwindSafe, { let mut externalities = ext::Ext::new( self.overlay, - self.backend, + &self.backend, self.changes_trie_storage, self.offchain_ext.as_mut().map(|x| &mut **x), self.keystore.clone(), ); + let id = externalities.id; + trace!(target: "state-trace", "{:04x}: Call {} at {:?}. Input={:?}", + id, + self.method, + self.backend, + HexDisplay::from(&self.call_data), + ); let (result, was_native) = self.exec.call( &mut externalities, self.method, @@ -561,6 +279,11 @@ impl<'a, H, N, B, T, O, Exec> StateMachine<'a, H, N, B, T, O, Exec> where } else { (None, None) }; + trace!(target: "state-trace", "{:04x}: Return. Native={:?}, Result={:?}", + id, + was_native, + result, + ); (result, was_native, storage_delta, changes_delta) } @@ -570,19 +293,27 @@ impl<'a, H, N, B, T, O, Exec> StateMachine<'a, H, N, B, T, O, Exec> where mut native_call: Option, orig_prospective: OverlayedChangeSet, on_consensus_failure: Handler, - ) -> (CallResult, Option<(B::Transaction, H::Out)>, Option>) where + ) -> (CallResult, Option<(B::Transaction, H::Out)>, Option>) where R: Decode + Encode + PartialEq, - NC: FnOnce() -> result::Result + UnwindSafe, + NC: FnOnce() -> result::Result + UnwindSafe, Handler: FnOnce( CallResult, CallResult ) -> CallResult { - let (result, was_native, storage_delta, changes_delta) = self.execute_aux(compute_tx, true, native_call.take()); + let (result, was_native, storage_delta, changes_delta) = self.execute_aux( + compute_tx, + true, + native_call.take(), + ); if was_native { self.overlay.prospective = orig_prospective.clone(); - let (wasm_result, _, wasm_storage_delta, wasm_changes_delta) = self.execute_aux(compute_tx, false, native_call); + let (wasm_result, _, wasm_storage_delta, wasm_changes_delta) = self.execute_aux( + compute_tx, + false, + native_call, + ); if (result.is_ok() && wasm_result.is_ok() && result.as_ref().ok() == wasm_result.as_ref().ok()) @@ -601,17 +332,25 @@ impl<'a, H, N, B, T, O, Exec> StateMachine<'a, H, N, B, T, O, Exec> where compute_tx: bool, mut native_call: Option, orig_prospective: OverlayedChangeSet, - ) -> (CallResult, Option<(B::Transaction, H::Out)>, Option>) where + ) -> (CallResult, Option<(B::Transaction, H::Out)>, Option>) where R: Decode + Encode + PartialEq, - NC: FnOnce() -> result::Result + UnwindSafe, + NC: FnOnce() -> result::Result + UnwindSafe, { - let (result, was_native, storage_delta, changes_delta) = self.execute_aux(compute_tx, true, native_call.take()); + let (result, was_native, storage_delta, changes_delta) = self.execute_aux( + compute_tx, + true, + native_call.take(), + ); if !was_native || result.is_ok() { (result, storage_delta, changes_delta) } else { self.overlay.prospective = orig_prospective.clone(); - let (wasm_result, _, wasm_storage_delta, wasm_changes_delta) = self.execute_aux(compute_tx, false, native_call); + let (wasm_result, _, wasm_storage_delta, wasm_changes_delta) = self.execute_aux( + compute_tx, + false, + native_call, + ); (wasm_result, wasm_storage_delta, wasm_changes_delta) } } @@ -632,13 +371,13 @@ impl<'a, H, N, B, T, O, Exec> StateMachine<'a, H, N, B, T, O, Exec> where ) -> Result<( NativeOrEncoded, Option<(B::Transaction, H::Out)>, - Option> + Option>, ), Box> where R: Decode + Encode + PartialEq, - NC: FnOnce() -> result::Result + UnwindSafe, + NC: FnOnce() -> result::Result + UnwindSafe, Handler: FnOnce( CallResult, - CallResult + CallResult, ) -> CallResult { // read changes trie configuration. The reason why we're doing it here instead of the @@ -646,8 +385,7 @@ impl<'a, H, N, B, T, O, Exec> StateMachine<'a, H, N, B, T, O, Exec> where // proof-of-execution on light clients. And the proof is recorded by the backend which // is created after OverlayedChanges - let backend = self.backend.clone(); - let init_overlay = |overlay: &mut OverlayedChanges, final_check: bool| { + let init_overlay = |overlay: &mut OverlayedChanges, final_check: bool, backend: &B| { let changes_trie_config = try_read_overlay_value( overlay, backend, @@ -655,32 +393,45 @@ impl<'a, H, N, B, T, O, Exec> StateMachine<'a, H, N, B, T, O, Exec> where )?; set_changes_trie_config(overlay, changes_trie_config, final_check) }; - init_overlay(self.overlay, false)?; + init_overlay(self.overlay, false, &self.backend)?; let result = { let orig_prospective = self.overlay.prospective.clone(); let (result, storage_delta, changes_delta) = match manager { ExecutionManager::Both(on_consensus_failure) => { - self.execute_call_with_both_strategy(compute_tx, native_call.take(), orig_prospective, on_consensus_failure) + self.execute_call_with_both_strategy( + compute_tx, + native_call.take(), + orig_prospective, + on_consensus_failure, + ) }, ExecutionManager::NativeElseWasm => { - self.execute_call_with_native_else_wasm_strategy(compute_tx, native_call.take(), orig_prospective) + self.execute_call_with_native_else_wasm_strategy( + compute_tx, + native_call.take(), + orig_prospective, + ) }, - ExecutionManager::AlwaysWasm => { - let (result, _, storage_delta, changes_delta) = self.execute_aux(compute_tx, false, native_call); - (result, storage_delta, changes_delta) + ExecutionManager::AlwaysWasm(trust_level) => { + let _abort_guard = match trust_level { + BackendTrustLevel::Trusted => None, + BackendTrustLevel::Untrusted => Some(panic_handler::AbortGuard::never_abort()), + }; + let res = self.execute_aux(compute_tx, false, native_call); + (res.0, res.2, res.3) }, ExecutionManager::NativeWhenPossible => { - let (result, _was_native, storage_delta, changes_delta) = self.execute_aux(compute_tx, true, native_call); - (result, storage_delta, changes_delta) + let res = self.execute_aux(compute_tx, true, native_call); + (res.0, res.2, res.3) }, }; result.map(move |out| (out, storage_delta, changes_delta)) }; if result.is_ok() { - init_overlay(self.overlay, true)?; + init_overlay(self.overlay, true, &self.backend)?; } result.map_err(|e| Box::new(e) as _) @@ -731,23 +482,16 @@ where H::Out: Ord + 'static, { let proving_backend = proving_backend::ProvingBackend::new(trie_backend); - let mut sm = StateMachine { - backend: &proving_backend, - changes_trie_storage: None as Option<&changes_trie::InMemoryStorage>, - offchain_ext: NeverOffchainExt::new(), - overlay, - exec, - method, - call_data, - keystore, - _hasher: PhantomData, - }; + let mut sm = StateMachine::<_, H, _, InMemoryChangesTrieStorage, _, Exec>::new( + proving_backend, None, NeverOffchainExt::new(), overlay, exec, method, call_data, keystore, + ); + let (result, _, _) = sm.execute_using_consensus_failure_handler::<_, NeverNativeValue, fn() -> _>( - native_else_wasm(), + always_wasm(), false, None, )?; - let proof = proving_backend.extract_proof(); + let proof = sm.backend.extract_proof(); Ok((result.into_encoded(), proof)) } @@ -784,119 +528,144 @@ where Exec: CodeExecutor, H::Out: Ord + 'static, { - let mut sm = StateMachine { - backend: trie_backend, - changes_trie_storage: None as Option<&changes_trie::InMemoryStorage>, - offchain_ext: NeverOffchainExt::new(), - overlay, - exec, - method, - call_data, - keystore, - _hasher: PhantomData, - }; + let mut sm = StateMachine::<_, H, _, InMemoryChangesTrieStorage, _, Exec>::new( + trie_backend, None, NeverOffchainExt::new(), overlay, exec, method, call_data, keystore, + ); + sm.execute_using_consensus_failure_handler::<_, NeverNativeValue, fn() -> _>( - native_else_wasm(), + always_untrusted_wasm(), false, None, ).map(|(result, _, _)| result.into_encoded()) } /// Generate storage read proof. -pub fn prove_read( +pub fn prove_read( mut backend: B, - key: &[u8] -) -> Result<(Option>, Vec>), Box> + keys: I, +) -> Result>, Box> where B: Backend, H: Hasher, - H::Out: Ord + H::Out: Ord, + I: IntoIterator, + I::Item: AsRef<[u8]>, { let trie_backend = backend.as_trie_backend() .ok_or_else( - ||Box::new(ExecutionError::UnableToGenerateProof) as Box + || Box::new(ExecutionError::UnableToGenerateProof) as Box )?; - prove_read_on_trie_backend(trie_backend, key) + prove_read_on_trie_backend(trie_backend, keys) } /// Generate child storage read proof. -pub fn prove_child_read( +pub fn prove_child_read( mut backend: B, storage_key: &[u8], - key: &[u8], -) -> Result<(Option>, Vec>), Box> + keys: I, +) -> Result>, Box> where B: Backend, H: Hasher, - H::Out: Ord + H::Out: Ord, + I: IntoIterator, + I::Item: AsRef<[u8]>, { let trie_backend = backend.as_trie_backend() .ok_or_else(|| Box::new(ExecutionError::UnableToGenerateProof) as Box)?; - prove_child_read_on_trie_backend(trie_backend, storage_key, key) + prove_child_read_on_trie_backend(trie_backend, storage_key, keys) } - /// Generate storage read proof on pre-created trie backend. -pub fn prove_read_on_trie_backend( +pub fn prove_read_on_trie_backend( trie_backend: &TrieBackend, - key: &[u8] -) -> Result<(Option>, Vec>), Box> + keys: I, +) -> Result>, Box> where S: trie_backend_essence::TrieBackendStorage, H: Hasher, - H::Out: Ord + H::Out: Ord, + I: IntoIterator, + I::Item: AsRef<[u8]>, { let proving_backend = proving_backend::ProvingBackend::<_, H>::new(trie_backend); - let result = proving_backend.storage(key).map_err(|e| Box::new(e) as Box)?; - Ok((result, proving_backend.extract_proof())) + for key in keys.into_iter() { + proving_backend + .storage(key.as_ref()) + .map_err(|e| Box::new(e) as Box)?; + } + Ok(proving_backend.extract_proof()) } /// Generate storage read proof on pre-created trie backend. -pub fn prove_child_read_on_trie_backend( +pub fn prove_child_read_on_trie_backend( trie_backend: &TrieBackend, storage_key: &[u8], - key: &[u8] -) -> Result<(Option>, Vec>), Box> + keys: I, +) -> Result>, Box> where S: trie_backend_essence::TrieBackendStorage, H: Hasher, - H::Out: Ord + H::Out: Ord, + I: IntoIterator, + I::Item: AsRef<[u8]>, { let proving_backend = proving_backend::ProvingBackend::<_, H>::new(trie_backend); - let result = proving_backend.child_storage(storage_key, key).map_err(|e| Box::new(e) as Box)?; - Ok((result, proving_backend.extract_proof())) + for key in keys.into_iter() { + proving_backend + .child_storage(storage_key, key.as_ref()) + .map_err(|e| Box::new(e) as Box)?; + } + Ok(proving_backend.extract_proof()) } /// Check storage read proof, generated by `prove_read` call. -pub fn read_proof_check( +pub fn read_proof_check( root: H::Out, proof: Vec>, - key: &[u8], -) -> Result>, Box> + keys: I, +) -> Result, Option>>, Box> where H: Hasher, - H::Out: Ord + H::Out: Ord, + I: IntoIterator, + I::Item: AsRef<[u8]>, { let proving_backend = create_proof_check_backend::(root, proof)?; - read_proof_check_on_proving_backend(&proving_backend, key) + let mut result = HashMap::new(); + for key in keys.into_iter() { + let value = read_proof_check_on_proving_backend(&proving_backend, key.as_ref())?; + result.insert(key.as_ref().to_vec(), value); + } + Ok(result) } /// Check child storage read proof, generated by `prove_child_read` call. -pub fn read_child_proof_check( +pub fn read_child_proof_check( root: H::Out, proof: Vec>, storage_key: &[u8], - key: &[u8], -) -> Result>, Box> + keys: I, +) -> Result, Option>>, Box> where H: Hasher, - H::Out: Ord + H::Out: Ord, + I: IntoIterator, + I::Item: AsRef<[u8]>, { let proving_backend = create_proof_check_backend::(root, proof)?; - read_child_proof_check_on_proving_backend(&proving_backend, storage_key, key) + let mut result = HashMap::new(); + for key in keys.into_iter() { + let value = read_child_proof_check_on_proving_backend( + &proving_backend, + storage_key, + key.as_ref(), + )?; + result.insert(key.as_ref().to_vec(), value); + } + Ok(result) } - /// Check storage read proof on pre-created proving backend. pub fn read_proof_check_on_proving_backend( proving_backend: &TrieBackend, H>, @@ -904,7 +673,7 @@ pub fn read_proof_check_on_proving_backend( ) -> Result>, Box> where H: Hasher, - H::Out: Ord + H::Out: Ord, { proving_backend.storage(key).map_err(|e| Box::new(e) as Box) } @@ -917,14 +686,14 @@ pub fn read_child_proof_check_on_proving_backend( ) -> Result>, Box> where H: Hasher, - H::Out: Ord + H::Out: Ord, { proving_backend.child_storage(storage_key, key).map_err(|e| Box::new(e) as Box) } /// Sets overlayed changes' changes trie configuration. Returns error if configuration /// differs from previous OR config decode has failed. -pub(crate) fn set_changes_trie_config( +fn set_changes_trie_config( overlay: &mut OverlayedChanges, config: Option>, final_check: bool, @@ -948,12 +717,10 @@ pub(crate) fn set_changes_trie_config( } /// Reads storage value from overlay or from the backend. -fn try_read_overlay_value(overlay: &OverlayedChanges, backend: &B, key: &[u8]) - -> Result>, Box> -where - H: Hasher, - B: Backend, -{ +fn try_read_overlay_value( + overlay: &OverlayedChanges, + backend: &B, key: &[u8], +) -> Result>, Box> where H: Hasher, B: Backend { match overlay.storage(key).map(|x| x.map(|x| x.to_vec())) { Some(value) => Ok(value), None => backend @@ -974,7 +741,7 @@ mod tests { InMemoryStorage as InMemoryChangesTrieStorage, Configuration as ChangesTrieConfig, }; - use primitives::{Blake2Hasher, map}; + use primitives::{Blake2Hasher, map, traits::Externalities, child_storage_key::ChildStorageKey}; struct DummyCodeExecutor { change_changes_trie_config: bool, @@ -986,7 +753,7 @@ mod tests { impl CodeExecutor for DummyCodeExecutor { type Error = u8; - fn call, R: Encode + Decode + PartialEq, NC: FnOnce() -> result::Result>( + fn call, R: Encode + Decode + PartialEq, NC: FnOnce() -> result::Result>( &self, ext: &mut E, _method: &str, @@ -1026,15 +793,17 @@ mod tests { } } - impl Error for u8 {} - #[test] fn execute_works() { - assert_eq!(new( - &trie_backend::tests::test_trie(), - Some(&InMemoryChangesTrieStorage::::new()), + let backend = trie_backend::tests::test_trie(); + let mut overlayed_changes = Default::default(); + let changes_trie_storage = InMemoryChangesTrieStorage::::new(); + + let mut state_machine = StateMachine::new( + backend, + Some(&changes_trie_storage), NeverOffchainExt::new(), - &mut Default::default(), + &mut overlayed_changes, &DummyCodeExecutor { change_changes_trie_config: false, native_available: true, @@ -1044,19 +813,26 @@ mod tests { "test", &[], None, - ).execute( - ExecutionStrategy::NativeWhenPossible - ).unwrap().0, vec![66]); + ); + + assert_eq!( + state_machine.execute(ExecutionStrategy::NativeWhenPossible).unwrap().0, + vec![66], + ); } #[test] fn execute_works_with_native_else_wasm() { - assert_eq!(new( - &trie_backend::tests::test_trie(), - Some(&InMemoryChangesTrieStorage::::new()), + let backend = trie_backend::tests::test_trie(); + let mut overlayed_changes = Default::default(); + let changes_trie_storage = InMemoryChangesTrieStorage::::new(); + + let mut state_machine = StateMachine::new( + backend, + Some(&changes_trie_storage), NeverOffchainExt::new(), - &mut Default::default(), + &mut overlayed_changes, &DummyCodeExecutor { change_changes_trie_config: false, native_available: true, @@ -1066,19 +842,23 @@ mod tests { "test", &[], None, - ).execute( - ExecutionStrategy::NativeElseWasm - ).unwrap().0, vec![66]); + ); + + assert_eq!(state_machine.execute(ExecutionStrategy::NativeElseWasm).unwrap().0, vec![66]); } #[test] fn dual_execution_strategy_detects_consensus_failure() { let mut consensus_failed = false; - assert!(new( - &trie_backend::tests::test_trie(), - Some(&InMemoryChangesTrieStorage::::new()), + let backend = trie_backend::tests::test_trie(); + let mut overlayed_changes = Default::default(); + let changes_trie_storage = InMemoryChangesTrieStorage::::new(); + + let mut state_machine = StateMachine::new( + backend, + Some(&changes_trie_storage), NeverOffchainExt::new(), - &mut Default::default(), + &mut overlayed_changes, &DummyCodeExecutor { change_changes_trie_config: false, native_available: true, @@ -1088,14 +868,18 @@ mod tests { "test", &[], None, - ).execute_using_consensus_failure_handler::<_, NeverNativeValue, fn() -> _>( - ExecutionManager::Both(|we, _ne| { - consensus_failed = true; - we - }), - true, - None, - ).is_err()); + ); + + assert!( + state_machine.execute_using_consensus_failure_handler::<_, NeverNativeValue, fn() -> _>( + ExecutionManager::Both(|we, _ne| { + consensus_failed = true; + we + }), + true, + None, + ).is_err() + ); assert!(consensus_failed); } @@ -1228,20 +1012,23 @@ mod tests { // fetch read proof from 'remote' full node let remote_backend = trie_backend::tests::test_trie(); let remote_root = remote_backend.storage_root(::std::iter::empty()).0; - let remote_proof = prove_read(remote_backend, b"value2").unwrap().1; + let remote_proof = prove_read(remote_backend, &[b"value2"]).unwrap(); // check proof locally - let local_result1 = read_proof_check::( + let local_result1 = read_proof_check::( remote_root, remote_proof.clone(), - b"value2" + &[b"value2"], ).unwrap(); - let local_result2 = read_proof_check::( + let local_result2 = read_proof_check::( remote_root, remote_proof.clone(), - &[0xff] + &[&[0xff]], ).is_ok(); // check that results are correct - assert_eq!(local_result1, Some(vec![24])); + assert_eq!( + local_result1.into_iter().collect::>(), + vec![(b"value2".to_vec(), Some(vec![24]))], + ); assert_eq!(local_result2, false); // on child trie let remote_backend = trie_backend::tests::test_trie(); @@ -1249,66 +1036,77 @@ mod tests { let remote_proof = prove_child_read( remote_backend, b":child_storage:default:sub1", - b"value3" - ).unwrap().1; - let local_result1 = read_child_proof_check::( + &[b"value3"], + ).unwrap(); + let local_result1 = read_child_proof_check::( remote_root, remote_proof.clone(), - b":child_storage:default:sub1",b"value3" + b":child_storage:default:sub1", + &[b"value3"], ).unwrap(); - let local_result2 = read_child_proof_check::( + let local_result2 = read_child_proof_check::( remote_root, remote_proof.clone(), b":child_storage:default:sub1", - b"value2" + &[b"value2"], ).unwrap(); - assert_eq!(local_result1, Some(vec![142])); - assert_eq!(local_result2, None); + assert_eq!( + local_result1.into_iter().collect::>(), + vec![(b"value3".to_vec(), Some(vec![142]))], + ); + assert_eq!( + local_result2.into_iter().collect::>(), + vec![(b"value2".to_vec(), None)], + ); } #[test] fn cannot_change_changes_trie_config() { - assert!( - new( - &trie_backend::tests::test_trie(), - Some(&InMemoryChangesTrieStorage::::new()), - NeverOffchainExt::new(), - &mut Default::default(), - &DummyCodeExecutor { - change_changes_trie_config: true, - native_available: false, - native_succeeds: true, - fallback_succeeds: true, - }, - "test", - &[], - None, - ) - .execute(ExecutionStrategy::NativeWhenPossible) - .is_err() + let backend = trie_backend::tests::test_trie(); + let mut overlayed_changes = Default::default(); + let changes_trie_storage = InMemoryChangesTrieStorage::::new(); + + let mut state_machine = StateMachine::new( + backend, + Some(&changes_trie_storage), + NeverOffchainExt::new(), + &mut overlayed_changes, + &DummyCodeExecutor { + change_changes_trie_config: true, + native_available: false, + native_succeeds: true, + fallback_succeeds: true, + }, + "test", + &[], + None, ); + + assert!(state_machine.execute(ExecutionStrategy::NativeWhenPossible).is_err()); } #[test] fn cannot_change_changes_trie_config_with_native_else_wasm() { - assert!( - new( - &trie_backend::tests::test_trie(), - Some(&InMemoryChangesTrieStorage::::new()), - NeverOffchainExt::new(), - &mut Default::default(), - &DummyCodeExecutor { - change_changes_trie_config: true, - native_available: false, - native_succeeds: true, - fallback_succeeds: true, - }, - "test", - &[], - None, - ) - .execute(ExecutionStrategy::NativeElseWasm) - .is_err() + let backend = trie_backend::tests::test_trie(); + let mut overlayed_changes = Default::default(); + let changes_trie_storage = InMemoryChangesTrieStorage::::new(); + + let mut state_machine = StateMachine::new( + backend, + Some(&changes_trie_storage), + NeverOffchainExt::new(), + &mut overlayed_changes, + &DummyCodeExecutor { + change_changes_trie_config: true, + native_available: false, + native_succeeds: true, + fallback_succeeds: true, + }, + "test", + &[], + None, ); + + assert!(state_machine.execute(ExecutionStrategy::NativeElseWasm).is_err()); } } diff --git a/core/state-machine/src/overlayed_changes.rs b/core/state-machine/src/overlayed_changes.rs index 9efafab20f57cdff0fc351e14efa1e4cf62ee5aa..a4952ddf73790088feb9ccb3f854cbbc5f8995d3 100644 --- a/core/state-machine/src/overlayed_changes.rs +++ b/core/state-machine/src/overlayed_changes.rs @@ -16,7 +16,8 @@ //! The overlayed changes to state. -#[cfg(test)] use std::iter::FromIterator; +#[cfg(test)] +use std::iter::FromIterator; use std::collections::{HashMap, BTreeSet}; use codec::Decode; use crate::changes_trie::{NO_EXTRINSIC_INDEX, Configuration as ChangesTrieConfig}; @@ -55,7 +56,7 @@ pub struct OverlayedChangeSet { /// Top level storage changes. pub top: HashMap, OverlayedValue>, /// Child storage changes. - pub children: HashMap, (Option>, HashMap, Option>>)>, + pub children: HashMap, HashMap, OverlayedValue>>, } #[cfg(test)] @@ -117,14 +118,14 @@ impl OverlayedChanges { /// value has been set. pub fn child_storage(&self, storage_key: &[u8], key: &[u8]) -> Option> { if let Some(map) = self.prospective.children.get(storage_key) { - if let Some(val) = map.1.get(key) { - return Some(val.as_ref().map(AsRef::as_ref)); + if let Some(val) = map.get(key) { + return Some(val.value.as_ref().map(AsRef::as_ref)); } } if let Some(map) = self.committed.children.get(storage_key) { - if let Some(val) = map.1.get(key) { - return Some(val.as_ref().map(AsRef::as_ref)); + if let Some(val) = map.get(key) { + return Some(val.value.as_ref().map(AsRef::as_ref)); } } @@ -151,10 +152,11 @@ impl OverlayedChanges { pub(crate) fn set_child_storage(&mut self, storage_key: Vec, key: Vec, val: Option>) { let extrinsic_index = self.extrinsic_index(); let map_entry = self.prospective.children.entry(storage_key).or_default(); - map_entry.1.insert(key, val); + let entry = map_entry.entry(key).or_default(); + entry.value = val; if let Some(extrinsic) = extrinsic_index { - map_entry.0.get_or_insert_with(Default::default) + entry.extrinsics.get_or_insert_with(Default::default) .insert(extrinsic); } } @@ -169,16 +171,28 @@ impl OverlayedChanges { let extrinsic_index = self.extrinsic_index(); let map_entry = self.prospective.children.entry(storage_key.to_vec()).or_default(); - if let Some(extrinsic) = extrinsic_index { - map_entry.0.get_or_insert_with(Default::default) - .insert(extrinsic); - } + map_entry.values_mut().for_each(|e| { + if let Some(extrinsic) = extrinsic_index { + e.extrinsics.get_or_insert_with(Default::default) + .insert(extrinsic); + } - map_entry.1.values_mut().for_each(|e| *e = None); + e.value = None; + }); - if let Some((_, committed_map)) = self.committed.children.get(storage_key) { - for (key, _) in committed_map.iter() { - map_entry.1.insert(key.clone(), None); + if let Some(committed_map) = self.committed.children.get(storage_key) { + for (key, value) in committed_map.iter() { + if !map_entry.contains_key(key) { + map_entry.insert(key.clone(), OverlayedValue { + value: None, + extrinsics: extrinsic_index.map(|i| { + let mut e = value.extrinsics.clone() + .unwrap_or_else(|| BTreeSet::default()); + e.insert(i); + e + }), + }); + } } } } @@ -224,12 +238,12 @@ impl OverlayedChanges { let extrinsic_index = self.extrinsic_index(); let map_entry = self.prospective.children.entry(storage_key.to_vec()).or_default(); - for (key, entry) in map_entry.1.iter_mut() { + for (key, entry) in map_entry.iter_mut() { if key.starts_with(prefix) { - *entry = None; + entry.value = None; if let Some(extrinsic) = extrinsic_index { - map_entry.0.get_or_insert_with(Default::default) + entry.extrinsics.get_or_insert_with(Default::default) .insert(extrinsic); } } @@ -238,13 +252,13 @@ impl OverlayedChanges { if let Some(child_committed) = self.committed.children.get(storage_key) { // Then do the same with keys from commited changes. // NOTE that we are making changes in the prospective change set. - for key in child_committed.1.keys() { + for key in child_committed.keys() { if key.starts_with(prefix) { - let entry = map_entry.1.entry(key.clone()).or_default(); - *entry = None; + let entry = map_entry.entry(key.clone()).or_default(); + entry.value = None; if let Some(extrinsic) = extrinsic_index { - map_entry.0.get_or_insert_with(Default::default) + entry.extrinsics.get_or_insert_with(Default::default) .insert(extrinsic); } } @@ -271,13 +285,16 @@ impl OverlayedChanges { .extend(prospective_extrinsics); } } - for (storage_key, map) in self.prospective.children.drain() { - let entry = self.committed.children.entry(storage_key).or_default(); - entry.1.extend(map.1.iter().map(|(k, v)| (k.clone(), v.clone()))); - - if let Some(prospective_extrinsics) = map.0 { - entry.0.get_or_insert_with(Default::default) - .extend(prospective_extrinsics); + for (storage_key, mut map) in self.prospective.children.drain() { + let map_dest = self.committed.children.entry(storage_key).or_default(); + for (key, val) in map.drain() { + let entry = map_dest.entry(key).or_default(); + entry.value = val.value; + + if let Some(prospective_extrinsics) = val.extrinsics { + entry.extrinsics.get_or_insert_with(Default::default) + .extend(prospective_extrinsics); + } } } } @@ -293,7 +310,8 @@ impl OverlayedChanges { ){ assert!(self.prospective.is_empty()); (self.committed.top.into_iter().map(|(k, v)| (k, v.value)), - self.committed.children.into_iter().map(|(sk, v)| (sk, v.1.into_iter()))) + self.committed.children.into_iter() + .map(|(sk, v)| (sk, v.into_iter().map(|(k, v)| (k, v.value))))) } /// Inserts storage entry responsible for current extrinsic index. @@ -333,12 +351,12 @@ impl From>> for OverlayedValue { #[cfg(test)] mod tests { use hex_literal::hex; - use primitives::{Blake2Hasher, H256}; - use primitives::storage::well_known_keys::EXTRINSIC_INDEX; + use primitives::{ + Blake2Hasher, H256, traits::Externalities, storage::well_known_keys::EXTRINSIC_INDEX, + }; use crate::backend::InMemory; use crate::changes_trie::InMemoryStorage as InMemoryChangesTrieStorage; use crate::ext::Ext; - use crate::Externalities; use super::*; fn strip_extrinsic_index(map: &HashMap, OverlayedValue>) -> HashMap, OverlayedValue> { diff --git a/core/state-machine/src/proving_backend.rs b/core/state-machine/src/proving_backend.rs index 5e8f618c826466a0b798e9f3512f4e1c2982e767..3908f62eaae0a44928e25d8097e45b1bd6a88e57 100644 --- a/core/state-machine/src/proving_backend.rs +++ b/core/state-machine/src/proving_backend.rs @@ -128,9 +128,8 @@ impl<'a, S: 'a + TrieBackendStorage, H: 'a + Hasher> ProvingBackend<'a, S, H> } } - /// Consume the backend, extracting the gathered proof in lexicographical order - /// by value. - pub fn extract_proof(self) -> Vec> { + /// Consume the backend, extracting the gathered proof in lexicographical order by value. + pub fn extract_proof(&self) -> Vec> { self.proof_recorder .borrow_mut() .drain() @@ -140,6 +139,12 @@ impl<'a, S: 'a + TrieBackendStorage, H: 'a + Hasher> ProvingBackend<'a, S, H> } } +impl<'a, S: 'a + TrieBackendStorage, H: 'a + Hasher> std::fmt::Debug for ProvingBackend<'a, S, H> { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!(f, "ProvingBackend") + } +} + impl<'a, S, H> Backend for ProvingBackend<'a, S, H> where S: 'a + TrieBackendStorage, @@ -174,6 +179,10 @@ impl<'a, S, H> Backend for ProvingBackend<'a, S, H> self.backend.for_keys_with_prefix(prefix, f) } + fn for_key_values_with_prefix(&self, prefix: &[u8], f: F) { + self.backend.for_key_values_with_prefix(prefix, f) + } + fn for_child_keys_with_prefix(&self, storage_key: &[u8], prefix: &[u8], f: F) { self.backend.for_child_keys_with_prefix(storage_key, prefix, f) } @@ -203,10 +212,6 @@ impl<'a, S, H> Backend for ProvingBackend<'a, S, H> { self.backend.child_storage_root(storage_key, delta) } - - fn as_trie_backend(&mut self) -> Option<&TrieBackend> { - None - } } /// Create proof check backend. @@ -245,8 +250,7 @@ mod tests { use crate::backend::{InMemory}; use crate::trie_backend::tests::test_trie; use super::*; - use primitives::{Blake2Hasher}; - use crate::ChildStorageKey; + use primitives::{Blake2Hasher, child_storage_key::ChildStorageKey}; fn test_proving<'a>( trie_backend: &'a TrieBackend,Blake2Hasher>, @@ -311,12 +315,8 @@ mod tests { #[test] fn proof_recorded_and_checked_with_child() { - let subtrie1 = ChildStorageKey::::from_slice( - b":child_storage:default:sub1" - ).unwrap(); - let subtrie2 = ChildStorageKey::::from_slice( - b":child_storage:default:sub2" - ).unwrap(); + let subtrie1 = ChildStorageKey::from_slice(b":child_storage:default:sub1").unwrap(); + let subtrie2 = ChildStorageKey::from_slice(b":child_storage:default:sub2").unwrap(); let own1 = subtrie1.into_owned(); let own2 = subtrie2.into_owned(); let contents = (0..64).map(|i| (None, vec![i], Some(vec![i]))) diff --git a/core/state-machine/src/testing.rs b/core/state-machine/src/testing.rs index 5026abcb2f76515cfbfc79fb2b5ffbc428a0c0cb..160f7d2a47ccb8d9aae15a35756129e4e6069692 100644 --- a/core/state-machine/src/testing.rs +++ b/core/state-machine/src/testing.rs @@ -18,17 +18,18 @@ use std::collections::{HashMap}; use hash_db::Hasher; -use crate::backend::{InMemory, Backend}; -use primitives::storage::well_known_keys::is_child_storage_key; -use crate::changes_trie::{ - build_changes_trie, InMemoryStorage as ChangesTrieInMemoryStorage, - BlockNumber as ChangesTrieBlockNumber, +use crate::{ + backend::{InMemory, Backend}, OverlayedChanges, + changes_trie::{ + build_changes_trie, InMemoryStorage as ChangesTrieInMemoryStorage, + BlockNumber as ChangesTrieBlockNumber, + }, }; use primitives::{ - storage::well_known_keys::{CHANGES_TRIE_CONFIG, CODE, HEAP_PAGES}, traits::BareCryptoStorePtr, offchain + storage::well_known_keys::{CHANGES_TRIE_CONFIG, CODE, HEAP_PAGES, is_child_storage_key}, + traits::{BareCryptoStorePtr, Externalities}, offchain, child_storage_key::ChildStorageKey, }; use codec::Encode; -use super::{ChildStorageKey, Externalities, OverlayedChanges}; const EXT_NOT_ALLOWED_TO_FAIL: &str = "Externalities not allowed to fail within runtime"; @@ -89,6 +90,11 @@ impl TestExternalities { self.offchain = Some(Box::new(offchain)); } + /// Set keystore. + pub fn set_keystore(&mut self, keystore: BareCryptoStorePtr) { + self.keystore = Some(keystore); + } + /// Get mutable reference to changes trie storage. pub fn changes_trie_storage(&mut self) -> &mut ChangesTrieInMemoryStorage { &mut self.changes_trie_storage @@ -103,8 +109,8 @@ impl TestExternalities { let children = self.overlay.committed.children.clone().into_iter() .chain(self.overlay.prospective.children.clone().into_iter()) .flat_map(|(keyspace, map)| { - map.1.into_iter() - .map(|(k, v)| (Some(keyspace.clone()), k, v)) + map.into_iter() + .map(|(k, v)| (Some(keyspace.clone()), k, v.value)) .collect::>() }); @@ -136,11 +142,10 @@ impl From for TestExternalit } } -impl Externalities for TestExternalities - where - H: Hasher, - N: ChangesTrieBlockNumber, - H::Out: Ord + 'static +impl Externalities for TestExternalities where + H: Hasher, + N: ChangesTrieBlockNumber, + H::Out: Ord + 'static, { fn storage(&self, key: &[u8]) -> Option> { self.overlay.storage(key).map(|x| x.map(|x| x.to_vec())).unwrap_or_else(|| @@ -151,7 +156,7 @@ impl Externalities for TestExternalities self.backend.storage(key).expect(EXT_NOT_ALLOWED_TO_FAIL) } - fn child_storage(&self, storage_key: ChildStorageKey, key: &[u8]) -> Option> { + fn child_storage(&self, storage_key: ChildStorageKey, key: &[u8]) -> Option> { self.overlay .child_storage(storage_key.as_ref(), key) .map(|x| x.map(|x| x.to_vec())) @@ -161,7 +166,7 @@ impl Externalities for TestExternalities ) } - fn original_child_storage(&self, storage_key: ChildStorageKey, key: &[u8]) -> Option> { + fn original_child_storage(&self, storage_key: ChildStorageKey, key: &[u8]) -> Option> { self.backend .child_storage(storage_key.as_ref(), key) .map(|x| x.map(|x| x.to_vec())) @@ -178,14 +183,14 @@ impl Externalities for TestExternalities fn place_child_storage( &mut self, - storage_key: ChildStorageKey, + storage_key: ChildStorageKey, key: Vec, value: Option> ) { self.overlay.set_child_storage(storage_key.into_owned(), key, value); } - fn kill_child_storage(&mut self, storage_key: ChildStorageKey) { + fn kill_child_storage(&mut self, storage_key: ChildStorageKey) { let backend = &self.backend; let overlay = &mut self.overlay; @@ -209,7 +214,7 @@ impl Externalities for TestExternalities }); } - fn clear_child_prefix(&mut self, storage_key: ChildStorageKey, prefix: &[u8]) { + fn clear_child_prefix(&mut self, storage_key: ChildStorageKey, prefix: &[u8]) { self.overlay.clear_child_prefix(storage_key.as_ref(), prefix); @@ -231,10 +236,10 @@ impl Externalities for TestExternalities let child_delta_iter = child_storage_keys.map(|storage_key| (storage_key.clone(), self.overlay.committed.children.get(storage_key) .into_iter() - .flat_map(|map| map.1.iter().map(|(k, v)| (k.clone(), v.clone()))) + .flat_map(|map| map.iter().map(|(k, v)| (k.clone(), v.value.clone()))) .chain(self.overlay.prospective.children.get(storage_key) .into_iter() - .flat_map(|map| map.1.iter().map(|(k, v)| (k.clone(), v.clone())))))); + .flat_map(|map| map.iter().map(|(k, v)| (k.clone(), v.value.clone())))))); // compute and memoize @@ -244,16 +249,16 @@ impl Externalities for TestExternalities } - fn child_storage_root(&mut self, storage_key: ChildStorageKey) -> Vec { + fn child_storage_root(&mut self, storage_key: ChildStorageKey) -> Vec { let storage_key = storage_key.as_ref(); let (root, is_empty, _) = { let delta = self.overlay.committed.children.get(storage_key) .into_iter() - .flat_map(|map| map.1.iter().map(|(k, v)| (k.clone(), v.clone()))) + .flat_map(|map| map.clone().into_iter().map(|(k, v)| (k, v.value))) .chain(self.overlay.prospective.children.get(storage_key) .into_iter() - .flat_map(|map| map.1.clone().into_iter())); + .flat_map(|map| map.clone().into_iter().map(|(k, v)| (k, v.value)))); self.backend.child_storage_root(storage_key, delta) }; @@ -271,7 +276,7 @@ impl Externalities for TestExternalities Some(&self.changes_trie_storage), &self.overlay, parent, - )?.map(|(_, root)| root)) + )?.map(|(_, root, _)| root)) } fn offchain(&mut self) -> Option<&mut dyn offchain::Externalities> { diff --git a/core/state-machine/src/trie_backend.rs b/core/state-machine/src/trie_backend.rs index 53c293b7ad17f3de567fd5cbccc935cb4946fe8b..ce5773c0b7956ce0d979be1afa9b3da8a7edafdf 100644 --- a/core/state-machine/src/trie_backend.rs +++ b/core/state-machine/src/trie_backend.rs @@ -57,7 +57,11 @@ impl, H: Hasher> TrieBackend { } } -impl super::Error for String {} +impl, H: Hasher> std::fmt::Debug for TrieBackend { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!(f, "TrieBackend") + } +} impl, H: Hasher> Backend for TrieBackend where H::Out: Ord, @@ -78,6 +82,10 @@ impl, H: Hasher> Backend for TrieBackend where self.essence.for_keys_with_prefix(prefix, f) } + fn for_key_values_with_prefix(&self, prefix: &[u8], f: F) { + self.essence.for_key_values_with_prefix(prefix, f) + } + fn for_keys_in_child_storage(&self, storage_key: &[u8], f: F) { self.essence.for_keys_in_child_storage(storage_key, f) } diff --git a/core/state-machine/src/trie_backend_essence.rs b/core/state-machine/src/trie_backend_essence.rs index aeb265c2e2a5657c196e1aef54bb8573995d1d06..5a5431963448cb285489cf64150469d44f135b05 100644 --- a/core/state-machine/src/trie_backend_essence.rs +++ b/core/state-machine/src/trie_backend_essence.rs @@ -119,7 +119,7 @@ impl, H: Hasher> TrieBackendEssence { } /// Execute given closure for all keys starting with prefix. - pub fn for_child_keys_with_prefix(&self, storage_key: &[u8], prefix: &[u8], f: F) { + pub fn for_child_keys_with_prefix(&self, storage_key: &[u8], prefix: &[u8], mut f: F) { let root_vec = match self.storage(storage_key) { Ok(v) => v.unwrap_or(default_child_trie_root::>(storage_key)), Err(e) => { @@ -130,16 +130,21 @@ impl, H: Hasher> TrieBackendEssence { let mut root = H::Out::default(); root.as_mut().copy_from_slice(&root_vec); - self.keys_with_prefix_inner(&root, prefix, f) + self.keys_values_with_prefix_inner(&root, prefix, |k, _v| f(k)) } /// Execute given closure for all keys starting with prefix. - pub fn for_keys_with_prefix(&self, prefix: &[u8], f: F) { - self.keys_with_prefix_inner(&self.root, prefix, f) + pub fn for_keys_with_prefix(&self, prefix: &[u8], mut f: F) { + self.keys_values_with_prefix_inner(&self.root, prefix, |k, _v| f(k)) } - fn keys_with_prefix_inner(&self, root: &H::Out, prefix: &[u8], mut f: F) { + fn keys_values_with_prefix_inner( + &self, + root: &H::Out, + prefix: &[u8], + mut f: F, + ) { let mut read_overlay = S::Overlay::default(); let eph = Ephemeral { storage: &self.storage, @@ -153,13 +158,13 @@ impl, H: Hasher> TrieBackendEssence { iter.seek(prefix)?; for x in iter { - let (key, _) = x?; + let (key, value) = x?; if !key.starts_with(prefix) { break; } - f(&key); + f(&key, &value); } Ok(()) @@ -170,6 +175,11 @@ impl, H: Hasher> TrieBackendEssence { } } + /// Execute given closure for all key and values starting with prefix. + pub fn for_key_values_with_prefix(&self, prefix: &[u8], f: F) { + self.keys_values_with_prefix_inner(&self.root, prefix, f) + } + } pub(crate) struct Ephemeral<'a, S: 'a + TrieBackendStorage, H: 'a + Hasher> { diff --git a/core/telemetry/Cargo.toml b/core/telemetry/Cargo.toml index d4332eb9ec343ec4307414fdc5dfb1c619df0b6b..90150ad7490df539ab61b744748bba86fac57e4f 100644 --- a/core/telemetry/Cargo.toml +++ b/core/telemetry/Cargo.toml @@ -6,20 +6,20 @@ description = "Telemetry utils" edition = "2018" [dependencies] -bytes = "0.4" +bytes = "0.4.12" parking_lot = "0.9.0" futures01 = { package = "futures", version = "0.1" } -futures-preview = { version = "=0.3.0-alpha.17", features = ["compat"] } -futures-timer = "0.2.1" -libp2p = { version = "0.11.0", default-features = false, features = ["libp2p-websocket"] } -log = "0.4" -rand = "0.6" -serde = { version = "1.0.81", features = ["derive"] } -slog = { version = "^2", features = ["nested-values"] } +futures-preview = { version = "0.3.0-alpha.19", features = ["compat"] } +futures-timer = "0.4.0" +libp2p = { version = "0.12.0", default-features = false, features = ["libp2p-websocket"] } +log = "0.4.8" +rand = "0.7.2" +serde = { version = "1.0.101", features = ["derive"] } +slog = { version = "2.5.2", features = ["nested-values"] } # TODO: we're using slog-async just to be able to clone records; See https://github.com/slog-rs/slog/issues/221, # https://github.com/paritytech/substrate/issues/2823 and https://github.com/paritytech/substrate/issues/3260 slog-async = { git = "https://github.com/paritytech/slog-async", features = ["nested-values"] } -slog-json = { version = "^2", features = ["nested-values"] } -slog-scope = "^4" -tokio-io = "0.1" -void = "1.0" +slog-json = { version = "2.3.0", features = ["nested-values"] } +slog-scope = "4.1.2" +tokio-io = "0.1.12" +void = "1.0.2" diff --git a/core/telemetry/src/lib.rs b/core/telemetry/src/lib.rs index 71a86defb6d3ee634a5b7531a528dd6a9b260f3c..768fc2df84e6a6c0ae2bb7d4ebd341b3a546321c 100644 --- a/core/telemetry/src/lib.rs +++ b/core/telemetry/src/lib.rs @@ -92,7 +92,7 @@ pub struct TelemetryConfig { /// maximum verbosity level. /// /// The URL string can be either a URL or a multiaddress. -#[derive(Debug, Clone, Serialize, Deserialize)] +#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)] pub struct TelemetryEndpoints(Vec<(String, u8)>); impl TelemetryEndpoints { diff --git a/core/test-client/Cargo.toml b/core/test-client/Cargo.toml index 1af77ce2f0193045806a0f17c0ace529b7808399..de13b34d69753e3ecd2a6b74907ba892fe38f75f 100644 --- a/core/test-client/Cargo.toml +++ b/core/test-client/Cargo.toml @@ -9,8 +9,8 @@ client = { package = "substrate-client", path = "../client" } client-db = { package = "substrate-client-db", path = "../client/db", features = ["test-helpers"] } consensus = { package = "substrate-consensus-common", path = "../consensus/common" } executor = { package = "substrate-executor", path = "../executor" } -futures-preview = "=0.3.0-alpha.17" -hash-db = "0.15.0" +futures-preview = "0.3.0-alpha.19" +hash-db = "0.15.2" keyring = { package = "substrate-keyring", path = "../keyring" } codec = { package = "parity-scale-codec", version = "1.0.0" } primitives = { package = "substrate-primitives", path = "../primitives" } diff --git a/core/test-client/src/client_ext.rs b/core/test-client/src/client_ext.rs index b29a7db471e5e9bd4f21f70beb3a701660436930..7d3d7301c55d30dcff4374543ad223e5da6b17cf 100644 --- a/core/test-client/src/client_ext.rs +++ b/core/test-client/src/client_ext.rs @@ -16,7 +16,7 @@ //! Client extension for tests. -use client::{self, Client}; +use client::{self, Client, backend::Finalizer}; use consensus::{ BlockImportParams, BlockImport, BlockOrigin, Error as ConsensusError, ForkChoiceStrategy, @@ -126,7 +126,7 @@ impl ClientExt for Client id: BlockId, justification: Option, ) -> client::error::Result<()> { - self.finalize_block(id, justification, true) + Finalizer::finalize_block(self, id, justification, true) } fn genesis_hash(&self) -> ::Hash { diff --git a/core/test-client/src/lib.rs b/core/test-client/src/lib.rs index d0d4a54b0f4ae55b02caac7d399f386873805f7b..a2baf11be2e8483381b11affd3b4be404e395da4 100644 --- a/core/test-client/src/lib.rs +++ b/core/test-client/src/lib.rs @@ -36,24 +36,17 @@ pub use state_machine::ExecutionStrategy; use std::sync::Arc; use std::collections::HashMap; -use futures::future::Ready; use hash_db::Hasher; use primitives::storage::well_known_keys; -use sr_primitives::traits::{ - Block as BlockT, NumberFor -}; +use sr_primitives::traits::Block as BlockT; use client::LocalCallExecutor; /// Test client light database backend. pub type LightBackend = client::light::backend::Backend< client_db::light::LightStorage, - LightFetcher, Blake2Hasher, >; -/// Test client light fetcher. -pub struct LightFetcher; - /// A genesis storage initialisation trait. pub trait GenesisInit: Default { /// Construct genesis storage. @@ -67,7 +60,7 @@ impl GenesisInit for () { } /// A builder for creating a test client instance. -pub struct TestClientBuilder { +pub struct TestClientBuilder { execution_strategies: ExecutionStrategies, genesis_init: G, child_storage_extension: HashMap, Vec<(Vec, Vec)>>, @@ -76,9 +69,10 @@ pub struct TestClientBuilder { keystore: Option, } -impl Default for TestClientBuilder< +impl Default for TestClientBuilder< Executor, Backend, + G, > where Block: BlockT::Out>, { @@ -99,6 +93,11 @@ impl TestClientBuilder< let backend = Arc::new(Backend::new_test(std::u32::MAX, std::u64::MAX)); Self::with_backend(backend) } + + /// Give access to the underlying backend of these clients + pub fn backend(&self) -> Arc> { + self.backend.clone() + } } impl TestClientBuilder { @@ -188,6 +187,7 @@ impl TestClientBuilder self.backend.clone(), executor, storage, + Default::default(), self.execution_strategies, ).expect("Creates new client"); @@ -226,53 +226,3 @@ impl TestClientBuilder< self.build_with_executor(executor) } } - -impl client::light::fetcher::Fetcher for LightFetcher { - type RemoteHeaderResult = Ready>; - type RemoteReadResult = Ready>, client::error::Error>>; - type RemoteCallResult = Ready, client::error::Error>>; - type RemoteChangesResult = Ready, u32)>, client::error::Error>>; - type RemoteBodyResult = Ready, client::error::Error>>; - - fn remote_header( - &self, - _request: client::light::fetcher::RemoteHeaderRequest, - ) -> Self::RemoteHeaderResult { - unimplemented!("not (yet) used in tests") - } - - fn remote_read( - &self, - _request: client::light::fetcher::RemoteReadRequest, - ) -> Self::RemoteReadResult { - unimplemented!("not (yet) used in tests") - } - - fn remote_read_child( - &self, - _request: client::light::fetcher::RemoteReadChildRequest, - ) -> Self::RemoteReadResult { - unimplemented!("not (yet) used in tests") - } - - fn remote_call( - &self, - _request: client::light::fetcher::RemoteCallRequest, - ) -> Self::RemoteCallResult { - unimplemented!("not (yet) used in tests") - } - - fn remote_changes( - &self, - _request: client::light::fetcher::RemoteChangesRequest, - ) -> Self::RemoteChangesResult { - unimplemented!("not (yet) used in tests") - } - - fn remote_body( - &self, - _request: client::light::fetcher::RemoteBodyRequest, - ) -> Self::RemoteBodyResult { - unimplemented!("not (yet) used in tests") - } -} diff --git a/core/test-runtime/Cargo.toml b/core/test-runtime/Cargo.toml index 13186056ce2dcc31f2c0089013768cb2f6f9a813..313db0fd070f14f676b62395ba564bac04fe05f1 100644 --- a/core/test-runtime/Cargo.toml +++ b/core/test-runtime/Cargo.toml @@ -6,8 +6,8 @@ edition = "2018" build = "build.rs" [dependencies] -log = { version = "0.4", optional = true } -serde = { version = "1.0", optional = true, features = ["derive"] } +log = { version = "0.4.8", optional = true } +serde = { version = "1.0.101", optional = true, features = ["derive"] } codec = { package = "parity-scale-codec", version = "1.0.0", default-features = false, features = ["derive"] } keyring = { package = "substrate-keyring", path = "../keyring", optional = true } substrate-client = { path = "../client", default-features = false } @@ -23,11 +23,11 @@ session = { package = "substrate-session", path = "../session", default-features runtime_version = { package = "sr-version", path = "../sr-version", default-features = false } runtime_support = { package = "srml-support", path = "../../srml/support", default-features = false } substrate-trie = { path = "../trie", default-features = false } -trie-db = { version = "0.15.0", default-features = false } -memory-db = { version = "0.15.0", default-features = false } +trie-db = { version = "0.15.2", default-features = false } +memory-db = { version = "0.15.2", default-features = false } offchain-primitives = { package = "substrate-offchain-primitives", path = "../offchain/primitives", default-features = false} executive = { package = "srml-executive", path = "../../srml/executive", default-features = false } -cfg-if = "0.1.6" +cfg-if = "0.1.10" srml-babe = { path = "../../srml/babe", default-features = false } srml-timestamp = { path = "../../srml/timestamp", default-features = false } srml-system = { path = "../../srml/system", default-features = false } @@ -44,7 +44,6 @@ wasm-builder-runner = { package = "substrate-wasm-builder-runner", version = "1. default = [ "std", ] -no_std = [] std = [ "log", "serde", diff --git a/core/test-runtime/build.rs b/core/test-runtime/build.rs index e412123b94d88b77d775892bae428181b3c7a857..2e2d1fc93ec7ec2013ec25f79a498ce030295cff 100644 --- a/core/test-runtime/build.rs +++ b/core/test-runtime/build.rs @@ -21,7 +21,7 @@ fn main() { "wasm_binary.rs", WasmBuilderSource::CratesOrPath { path: "../utils/wasm-builder", - version: "1.0.4", + version: "1.0.7", }, // Note that we set the stack-size to 1MB explicitly even though it is set // to this value by default. This is because some of our tests (`restoration_of_globals`) diff --git a/core/test-runtime/client/src/lib.rs b/core/test-runtime/client/src/lib.rs index f1cbb6fd8c9216049b6ecea63df50b5f8f62d51a..722aa0b2b472601b6003bc3bf805ef1324acfecd 100644 --- a/core/test-runtime/client/src/lib.rs +++ b/core/test-runtime/client/src/lib.rs @@ -22,6 +22,8 @@ pub mod trait_tests; mod block_builder_ext; +use std::sync::Arc; +use std::collections::HashMap; pub use block_builder_ext::BlockBuilderExt; pub use generic_test_client::*; pub use runtime; @@ -51,8 +53,7 @@ mod local_executor { native_executor_instance!( pub LocalExecutor, runtime::api::dispatch, - runtime::native_version, - runtime::WASM_BINARY + runtime::native_version ); } @@ -72,21 +73,12 @@ pub type Executor = client::LocalCallExecutor< pub type LightBackend = generic_test_client::LightBackend; /// Test client light executor. -pub type LightExecutor = client::light::call_executor::RemoteOrLocalCallExecutor< - runtime::Block, +pub type LightExecutor = client::light::call_executor::GenesisCallExecutor< LightBackend, - client::light::call_executor::RemoteCallExecutor< - client::light::blockchain::Blockchain< - client_db::light::LightStorage, - LightFetcher - >, - LightFetcher - >, client::LocalCallExecutor< client::light::backend::Backend< client_db::light::LightStorage, - LightFetcher, - Blake2Hasher + Blake2Hasher, >, NativeExecutor > @@ -97,21 +89,45 @@ pub type LightExecutor = client::light::call_executor::RemoteOrLocalCallExecutor pub struct GenesisParameters { support_changes_trie: bool, heap_pages_override: Option, + extra_storage: HashMap, Vec>, + child_extra_storage: HashMap, HashMap, Vec>>, +} + +impl GenesisParameters { + fn genesis_config(&self) -> GenesisConfig { + GenesisConfig::new( + self.support_changes_trie, + vec![ + sr25519::Public::from(Sr25519Keyring::Alice).into(), + sr25519::Public::from(Sr25519Keyring::Bob).into(), + sr25519::Public::from(Sr25519Keyring::Charlie).into(), + ], + vec![ + AccountKeyring::Alice.into(), + AccountKeyring::Bob.into(), + AccountKeyring::Charlie.into(), + ], + 1000, + self.heap_pages_override, + self.extra_storage.clone(), + self.child_extra_storage.clone(), + ) + } } impl generic_test_client::GenesisInit for GenesisParameters { fn genesis_storage(&self) -> (StorageOverlay, ChildrenStorageOverlay) { use codec::Encode; - let mut storage = genesis_config(self.support_changes_trie, self.heap_pages_override).genesis_map(); + let mut storage = self.genesis_config().genesis_map(); let child_roots = storage.1.iter().map(|(sk, child_map)| { let state_root = <<::Header as HeaderT>::Hashing as HashT>::trie_root( - child_map.clone().into_iter() + child_map.clone().into_iter().collect() ); (sk.clone(), state_root.encode()) }); let state_root = <<::Header as HeaderT>::Hashing as HashT>::trie_root( - storage.0.clone().into_iter().chain(child_roots) + storage.0.clone().into_iter().chain(child_roots).collect() ); let block: runtime::Block = client::genesis::construct_genesis_block(state_root); storage.0.extend(additional_storage_with_genesis(&block)); @@ -157,6 +173,25 @@ pub trait TestClientBuilderExt: Sized { /// Override the default value for Wasm heap pages. fn set_heap_pages(self, heap_pages: u64) -> Self; + /// Add an extra value into the genesis storage. + /// + /// # Panics + /// + /// Panics if the key is empty. + fn add_extra_child_storage>, K: Into>, V: Into>>( + self, + storage_key: SK, + key: K, + value: V, + ) -> Self; + + /// Add an extra child value into the genesis storage. + /// + /// # Panics + /// + /// Panics if the key is empty. + fn add_extra_storage>, V: Into>>(self, key: K, value: V) -> Self; + /// Build the test client. fn build(self) -> Client { self.build_with_longest_chain().0 @@ -182,54 +217,61 @@ impl TestClientBuilderExt for TestClientBuilder< self } + fn add_extra_storage>, V: Into>>(mut self, key: K, value: V) -> Self { + let key = key.into(); + assert!(!key.is_empty()); + self.genesis_init_mut().extra_storage.insert(key, value.into()); + self + } + + fn add_extra_child_storage>, K: Into>, V: Into>>( + mut self, + storage_key: SK, + key: K, + value: V, + ) -> Self { + let storage_key = storage_key.into(); + let key = key.into(); + assert!(!storage_key.is_empty()); + assert!(!key.is_empty()); + self.genesis_init_mut().child_extra_storage + .entry(storage_key) + .or_insert_with(Default::default) + .insert(key, value.into()); + self + } + + fn build_with_longest_chain(self) -> (Client, client::LongestChain) { self.build_with_native_executor(None) } } -fn genesis_config(support_changes_trie: bool, heap_pages_override: Option) -> GenesisConfig { - GenesisConfig::new( - support_changes_trie, - vec![ - sr25519::Public::from(Sr25519Keyring::Alice).into(), - sr25519::Public::from(Sr25519Keyring::Bob).into(), - sr25519::Public::from(Sr25519Keyring::Charlie).into(), - ], vec![ - AccountKeyring::Alice.into(), - AccountKeyring::Bob.into(), - AccountKeyring::Charlie.into(), - ], - 1000, - heap_pages_override, - ) -} - /// Creates new client instance used for tests. pub fn new() -> Client { TestClientBuilder::new().build() } /// Creates new light client instance used for tests. -pub fn new_light() -> client::Client { - use std::sync::Arc; +pub fn new_light() -> ( + client::Client, + Arc, +) { let storage = client_db::light::LightStorage::new_test(); let blockchain = Arc::new(client::light::blockchain::Blockchain::new(storage)); let backend = Arc::new(LightBackend::new(blockchain.clone())); let executor = NativeExecutor::new(None); - let fetcher = Arc::new(LightFetcher); - let remote_call_executor = client::light::call_executor::RemoteCallExecutor::new( - blockchain.clone(), - fetcher, - ); let local_call_executor = client::LocalCallExecutor::new(backend.clone(), executor, None); let call_executor = LightExecutor::new( backend.clone(), - remote_call_executor, local_call_executor, ); - TestClientBuilder::with_backend(backend) - .build_with_executor(call_executor) - .0 + ( + TestClientBuilder::with_backend(backend.clone()) + .build_with_executor(call_executor) + .0, + backend, + ) } diff --git a/core/test-runtime/src/genesismap.rs b/core/test-runtime/src/genesismap.rs index 7686ed08bc02e6996296182d087c57ba8c9128fd..a3abf235ff1ca9132132046940d959d60ac95729 100644 --- a/core/test-runtime/src/genesismap.rs +++ b/core/test-runtime/src/genesismap.rs @@ -25,10 +25,13 @@ use sr_primitives::traits::{Block as BlockT, Hash as HashT, Header as HeaderT}; /// Configuration of a general Substrate test genesis block. pub struct GenesisConfig { - pub changes_trie_config: Option, - pub authorities: Vec, - pub balances: Vec<(AccountId, u64)>, - pub heap_pages_override: Option, + changes_trie_config: Option, + authorities: Vec, + balances: Vec<(AccountId, u64)>, + heap_pages_override: Option, + /// Additional storage key pairs that will be added to the genesis map. + extra_storage: HashMap, Vec>, + child_extra_storage: HashMap, HashMap, Vec>>, } impl GenesisConfig { @@ -38,6 +41,8 @@ impl GenesisConfig { endowed_accounts: Vec, balance: u64, heap_pages_override: Option, + extra_storage: HashMap, Vec>, + child_extra_storage: HashMap, HashMap, Vec>>, ) -> Self { GenesisConfig { changes_trie_config: match support_changes_trie { @@ -47,6 +52,8 @@ impl GenesisConfig { authorities: authorities.clone(), balances: endowed_accounts.into_iter().map(|a| (a, balance)).collect(), heap_pages_override, + extra_storage, + child_extra_storage, } } @@ -70,7 +77,10 @@ impl GenesisConfig { map.insert(well_known_keys::CHANGES_TRIE_CONFIG.to_vec(), changes_trie_config.encode()); } map.insert(twox_128(&b"sys:auth"[..])[..].to_vec(), self.authorities.encode()); - (map, Default::default()) + // Finally, add the extra storage entries. + map.extend(self.extra_storage.clone().into_iter()); + + (map, self.child_extra_storage.clone()) } } @@ -80,15 +90,14 @@ pub fn insert_genesis_block( HashMap, HashMap, Vec>>, ) ) -> primitives::hash::H256 { - let child_roots = storage.1.iter().map(|(sk, child_map)| { let state_root = <<::Header as HeaderT>::Hashing as HashT>::trie_root( - child_map.clone().into_iter() + child_map.clone().into_iter().collect(), ); (sk.clone(), state_root.encode()) }); let state_root = <<::Header as HeaderT>::Hashing as HashT>::trie_root( - storage.0.clone().into_iter().chain(child_roots) + storage.0.clone().into_iter().chain(child_roots).collect() ); let block: crate::Block = substrate_client::genesis::construct_genesis_block(state_root); let genesis_hash = block.header.hash(); diff --git a/core/test-runtime/src/lib.rs b/core/test-runtime/src/lib.rs index 54c922c2169f8ef0f94bba9278d8887f838d07e3..e75cb69149d8dcb493c8901755b81eb33af757e0 100644 --- a/core/test-runtime/src/lib.rs +++ b/core/test-runtime/src/lib.rs @@ -25,7 +25,14 @@ pub mod system; use rstd::{prelude::*, marker::PhantomData}; use codec::{Encode, Decode, Input, Error}; -use primitives::{Blake2Hasher, OpaqueMetadata}; +use primitives::{ + Blake2Hasher, + OpaqueMetadata, + testing::{ + ED25519, + SR25519, + } +}; use app_crypto::{ed25519, sr25519, RuntimeAppPublic}; pub use app_crypto; use trie_db::{TrieMut, Trie}; @@ -38,14 +45,16 @@ use substrate_client::{ }; use sr_primitives::{ ApplyResult, create_runtime_str, Perbill, impl_opaque_keys, - transaction_validity::{TransactionValidity, ValidTransaction}, + transaction_validity::{ + TransactionValidity, ValidTransaction, TransactionValidityError, InvalidTransaction, + }, traits::{ BlindCheckable, BlakeTwo256, Block as BlockT, Extrinsic as ExtrinsicT, GetNodeBlockType, GetRuntimeBlockType, Verify, IdentityLookup, }, }; use runtime_version::RuntimeVersion; -pub use primitives::{hash::H256, crypto::key_types}; +pub use primitives::{hash::H256}; #[cfg(any(feature = "std", test))] use runtime_version::NativeVersion; use runtime_support::{impl_outer_origin, parameter_types}; @@ -123,17 +132,17 @@ impl serde::Serialize for Extrinsic { impl BlindCheckable for Extrinsic { type Checked = Self; - fn check(self) -> Result { + fn check(self) -> Result { match self { Extrinsic::AuthoritiesChange(new_auth) => Ok(Extrinsic::AuthoritiesChange(new_auth)), Extrinsic::Transfer(transfer, signature) => { if sr_primitives::verify_encoded_lazy(&signature, &transfer, &transfer.from) { Ok(Extrinsic::Transfer(transfer, signature)) } else { - Err(sr_primitives::BAD_SIGNATURE) + Err(InvalidTransaction::BadProof.into()) } }, - Extrinsic::IncludeData(_) => Err(sr_primitives::BAD_SIGNATURE), + Extrinsic::IncludeData(_) => Err(InvalidTransaction::BadProof.into()), Extrinsic::StorageChange(key, value) => Ok(Extrinsic::StorageChange(key, value)), } } @@ -141,6 +150,7 @@ impl BlindCheckable for Extrinsic { impl ExtrinsicT for Extrinsic { type Call = Extrinsic; + type SignaturePayload = (); fn is_signed(&self) -> Option { if let Extrinsic::IncludeData(_) = *self { @@ -150,7 +160,7 @@ impl ExtrinsicT for Extrinsic { } } - fn new_unsigned(call: Self::Call) -> Option { + fn new(call: Self::Call, _signature_payload: Option) -> Option { Some(call) } } @@ -185,7 +195,7 @@ pub type Header = sr_primitives::generic::Header; /// Run whatever tests we have. pub fn run_tests(mut input: &[u8]) -> Vec { - use runtime_io::print; + use sr_primitives::print; print("run_tests..."); let block = Block::decode(&mut input).unwrap(); @@ -261,6 +271,7 @@ cfg_if! { fn benchmark_direct_call() -> u64; fn returns_mutable_static() -> u64; fn allocates_huge_stack_array(trap: bool) -> Vec; + fn vec_with_capacity(size: u32) -> Vec; /// Returns the initialized block number. fn get_block_number() -> u64; /// Takes and returns the initialized block number. @@ -276,6 +287,8 @@ cfg_if! { /// /// Returns the signature generated for the message `sr25519`. fn test_sr25519_crypto() -> (sr25519::AppSignature, sr25519::AppPublic); + /// Run various tests against storage. + fn test_storage(); } } } else { @@ -302,6 +315,7 @@ cfg_if! { fn benchmark_direct_call() -> u64; fn returns_mutable_static() -> u64; fn allocates_huge_stack_array(trap: bool) -> Vec; + fn vec_with_capacity(size: u32) -> Vec; /// Returns the initialized block number. fn get_block_number() -> u64; /// Takes and returns the initialized block number. @@ -317,6 +331,8 @@ cfg_if! { /// /// Returns the signature generated for the message `sr25519`. fn test_sr25519_crypto() -> (sr25519::AppSignature, sr25519::AppPublic); + /// Run various tests against storage. + fn test_storage(); } } } @@ -371,6 +387,7 @@ impl srml_system::Trait for Runtime { type MaximumBlockWeight = MaximumBlockWeight; type MaximumBlockLength = MaximumBlockLength; type AvailableBlockRatio = AvailableBlockRatio; + type Version = (); } impl srml_timestamp::Trait for Runtime { @@ -388,6 +405,10 @@ parameter_types! { impl srml_babe::Trait for Runtime { type EpochDuration = EpochDuration; type ExpectedBlockTime = ExpectedBlockTime; + // there is no actual runtime in this test-runtime, so testing crates + // are manually adding the digests. normally in this situation you'd use + // srml_babe::SameAuthoritiesForever. + type EpochChangeTrigger = srml_babe::ExternalTrigger; } /// Adds one to the given input and returns the final result. @@ -436,9 +457,9 @@ fn code_using_trie() -> u64 { impl_opaque_keys! { pub struct SessionKeys { - #[id(key_types::ED25519)] + #[id(ED25519)] pub ed25519: ed25519::AppPublic, - #[id(key_types::SR25519)] + #[id(SR25519)] pub sr25519: sr25519::AppPublic, } } @@ -474,7 +495,7 @@ cfg_if! { impl client_api::TaggedTransactionQueue for Runtime { fn validate_transaction(utx: ::Extrinsic) -> TransactionValidity { if let Extrinsic::IncludeData(data) = utx { - return TransactionValidity::Valid(ValidTransaction { + return Ok(ValidTransaction { priority: data.len() as u64, requires: vec![], provides: vec![data], @@ -561,6 +582,10 @@ cfg_if! { unimplemented!("is not expected to be invoked from non-wasm builds"); } + fn vec_with_capacity(_size: u32) -> Vec { + unimplemented!("is not expected to be invoked from non-wasm builds"); + } + fn get_block_number() -> u64 { system::get_block_number().expect("Block number is initialized") } @@ -580,6 +605,11 @@ cfg_if! { fn test_sr25519_crypto() -> (sr25519::AppSignature, sr25519::AppPublic) { test_sr25519_crypto() } + + fn test_storage() { + test_read_storage(); + test_read_child_storage(); + } } impl aura_primitives::AuraApi for Runtime { @@ -593,24 +623,15 @@ cfg_if! { } impl babe_primitives::BabeApi for Runtime { - fn startup_data() -> babe_primitives::BabeConfiguration { + fn configuration() -> babe_primitives::BabeConfiguration { babe_primitives::BabeConfiguration { - median_required_blocks: 0, - slot_duration: 3000, + slot_duration: 1000, + epoch_length: EpochDuration::get(), c: (3, 10), - } - } - - fn epoch() -> babe_primitives::Epoch { - let authorities = system::authorities(); - let authorities: Vec<_> = authorities.into_iter().map(|x|(x, 1)).collect(); - - babe_primitives::Epoch { - start_slot: >::epoch_start_slot(), - authorities, + genesis_authorities: system::authorities() + .into_iter().map(|x|(x, 1)).collect(), randomness: >::randomness(), - epoch_index: >::epoch_index(), - duration: EpochDuration::get(), + secondary_slots: true, } } } @@ -618,7 +639,7 @@ cfg_if! { impl offchain_primitives::OffchainWorkerApi for Runtime { fn offchain_worker(block: u64) { let ex = Extrinsic::IncludeData(block.encode()); - runtime_io::submit_transaction(&ex).unwrap(); + runtime_io::submit_transaction(ex.encode()).unwrap(); } } @@ -653,7 +674,7 @@ cfg_if! { impl client_api::TaggedTransactionQueue for Runtime { fn validate_transaction(utx: ::Extrinsic) -> TransactionValidity { if let Extrinsic::IncludeData(data) = utx { - return TransactionValidity::Valid(ValidTransaction{ + return Ok(ValidTransaction{ priority: data.len() as u64, requires: vec![], provides: vec![data], @@ -771,6 +792,10 @@ cfg_if! { data.to_vec() } + fn vec_with_capacity(size: u32) -> Vec { + Vec::with_capacity(size as usize) + } + fn get_block_number() -> u64 { system::get_block_number().expect("Block number is initialized") } @@ -790,6 +815,11 @@ cfg_if! { fn test_sr25519_crypto() -> (sr25519::AppSignature, sr25519::AppPublic) { test_sr25519_crypto() } + + fn test_storage() { + test_read_storage(); + test_read_child_storage(); + } } impl aura_primitives::AuraApi for Runtime { @@ -803,24 +833,15 @@ cfg_if! { } impl babe_primitives::BabeApi for Runtime { - fn startup_data() -> babe_primitives::BabeConfiguration { + fn configuration() -> babe_primitives::BabeConfiguration { babe_primitives::BabeConfiguration { - median_required_blocks: 0, slot_duration: 1000, + epoch_length: EpochDuration::get(), c: (3, 10), - } - } - - fn epoch() -> babe_primitives::Epoch { - let authorities = system::authorities(); - let authorities: Vec<_> = authorities.into_iter().map(|x|(x, 1)).collect(); - - babe_primitives::Epoch { - start_slot: >::epoch_start_slot(), - authorities, + genesis_authorities: system::authorities() + .into_iter().map(|x|(x, 1)).collect(), randomness: >::randomness(), - epoch_index: >::epoch_index(), - duration: EpochDuration::get(), + secondary_slots: true, } } } @@ -828,7 +849,7 @@ cfg_if! { impl offchain_primitives::OffchainWorkerApi for Runtime { fn offchain_worker(block: u64) { let ex = Extrinsic::IncludeData(block.encode()); - runtime_io::submit_transaction(&ex).unwrap() + runtime_io::submit_transaction(ex.encode()).unwrap() } } @@ -871,10 +892,51 @@ fn test_sr25519_crypto() -> (sr25519::AppSignature, sr25519::AppPublic) { (signature, public0) } +fn test_read_storage() { + const KEY: &[u8] = b":read_storage"; + runtime_io::set_storage(KEY, b"test"); + + let mut v = [0u8; 4]; + let r = runtime_io::read_storage( + KEY, + &mut v, + 0 + ); + assert_eq!(r, Some(4)); + assert_eq!(&v, b"test"); + + let mut v = [0u8; 4]; + let r = runtime_io::read_storage(KEY, &mut v, 8); + assert_eq!(r, Some(4)); + assert_eq!(&v, &[0, 0, 0, 0]); +} + +fn test_read_child_storage() { + const CHILD_KEY: &[u8] = b":child_storage:default:read_child_storage"; + const KEY: &[u8] = b":read_child_storage"; + runtime_io::set_child_storage(CHILD_KEY, KEY, b"test"); + + let mut v = [0u8; 4]; + let r = runtime_io::read_child_storage( + CHILD_KEY, + KEY, + &mut v, + 0 + ); + assert_eq!(r, Some(4)); + assert_eq!(&v, b"test"); + + let mut v = [0u8; 4]; + let r = runtime_io::read_child_storage(CHILD_KEY, KEY, &mut v, 8); + assert_eq!(r, Some(4)); + assert_eq!(&v, &[0, 0, 0, 0]); +} + #[cfg(test)] mod tests { use substrate_test_runtime_client::{ prelude::*, + consensus::BlockOrigin, DefaultTestClientBuilderExt, TestClientBuilder, runtime::TestAPI, }; @@ -882,7 +944,9 @@ mod tests { generic::BlockId, traits::ProvideRuntimeApi, }; + use primitives::storage::well_known_keys::HEAP_PAGES; use state_machine::ExecutionStrategy; + use codec::Encode; #[test] fn returns_mutable_static() { @@ -930,4 +994,47 @@ mod tests { assert!(ret.is_ok()); } + #[test] + fn heap_pages_is_respected() { + // This tests that the on-chain HEAP_PAGES parameter is respected. + + // Create a client devoting only 8 pages of wasm memory. This gives us ~512k of heap memory. + let client = TestClientBuilder::new() + .set_execution_strategy(ExecutionStrategy::AlwaysWasm) + .set_heap_pages(8) + .build(); + let runtime_api = client.runtime_api(); + let block_id = BlockId::Number(client.info().chain.best_number); + + // Try to allocate 1024k of memory on heap. This is going to fail since it is twice larger + // than the heap. + let ret = runtime_api.vec_with_capacity(&block_id, 1048576); + assert!(ret.is_err()); + + // Create a block that sets the `:heap_pages` to 32 pages of memory which corresponds to + // ~2048k of heap memory. + let new_block_id = { + let mut builder = client.new_block(Default::default()).unwrap(); + builder.push_storage_change(HEAP_PAGES.to_vec(), Some(32u64.encode())).unwrap(); + let block = builder.bake().unwrap(); + let hash = block.header.hash(); + client.import(BlockOrigin::Own, block).unwrap(); + BlockId::Hash(hash) + }; + + // Allocation of 1024k while having ~2048k should succeed. + let ret = runtime_api.vec_with_capacity(&new_block_id, 1048576); + assert!(ret.is_ok()); + } + + #[test] + fn test_storage() { + let client = TestClientBuilder::new() + .set_execution_strategy(ExecutionStrategy::Both) + .build(); + let runtime_api = client.runtime_api(); + let block_id = BlockId::Number(client.info().chain.best_number); + + runtime_api.test_storage(&block_id).unwrap(); + } } diff --git a/core/test-runtime/src/system.rs b/core/test-runtime/src/system.rs index f3c890cf79f54f80b08d5690a09d0d65914f433a..e61e72f3a0e85cb1fa3bdbf343757ddee566c87f 100644 --- a/core/test-runtime/src/system.rs +++ b/core/test-runtime/src/system.rs @@ -18,18 +18,18 @@ //! and depositing logs. use rstd::prelude::*; -use runtime_io::{storage_root, ordered_trie_root, storage_changes_root, twox_128, blake2_256}; +use runtime_io::{storage_root, storage_changes_root, twox_128, blake2_256}; use runtime_support::storage::{self, StorageValue, StorageMap}; use runtime_support::storage_items; -use sr_primitives::traits::{Hash as HashT, BlakeTwo256, Header as _}; -use sr_primitives::generic; -use sr_primitives::{ApplyError, ApplyOutcome, ApplyResult}; -use sr_primitives::transaction_validity::{TransactionValidity, ValidTransaction}; +use sr_primitives::{ + traits::{Hash as HashT, BlakeTwo256, Header as _}, generic, ApplyError, ApplyResult, + transaction_validity::{TransactionValidity, ValidTransaction, InvalidTransaction}, +}; use codec::{KeyedVec, Encode}; -use super::{ +use crate::{ AccountId, BlockNumber, Extrinsic, Transfer, H256 as Hash, Block, Header, Digest, AuthorityId }; -use primitives::{Blake2Hasher, storage::well_known_keys}; +use primitives::storage::well_known_keys; const NONCE_OF: &[u8] = b"nonce:"; const BALANCE_OF: &[u8] = b"balance:"; @@ -62,6 +62,12 @@ pub fn initialize_block(header: &Header) { ::put(&header.parent_hash); ::put(header.digest()); storage::unhashed::put(well_known_keys::EXTRINSIC_INDEX, &0u32); + + // try to read something that depends on current header digest + // so that it'll be included in execution proof + if let Some(generic::DigestItem::Other(v)) = header.digest().logs().iter().next() { + let _: Option = storage::unhashed::get(&v); + } } pub fn get_block_number() -> Option { @@ -95,8 +101,7 @@ fn execute_block_with_state_root_handler( // check transaction trie root represents the transactions. let txs = block.extrinsics.iter().map(Encode::encode).collect::>(); - let txs = txs.iter().map(Vec::as_slice).collect::>(); - let txs_root = ordered_trie_root::(&txs).into(); + let txs_root = BlakeTwo256::ordered_trie_root(txs); info_expect_equal_hash(&txs_root, &header.extrinsics_root); if let Mode::Overwrite = mode { header.extrinsics_root = txs_root; @@ -104,10 +109,16 @@ fn execute_block_with_state_root_handler( assert!(txs_root == header.extrinsics_root, "Transaction trie root must be valid."); } + // try to read something that depends on current header digest + // so that it'll be included in execution proof + if let Some(generic::DigestItem::Other(v)) = header.digest().logs().iter().next() { + let _: Option = storage::unhashed::get(&v); + } + // execute transactions block.extrinsics.iter().enumerate().for_each(|(i, e)| { storage::unhashed::put(well_known_keys::EXTRINSIC_INDEX, &(i as u32)); - execute_transaction_backend(e).unwrap_or_else(|_| panic!("Invalid transaction")); + let _ = execute_transaction_backend(e).unwrap_or_else(|_| panic!("Invalid transaction")); storage::unhashed::kill(well_known_keys::EXTRINSIC_INDEX); }); @@ -146,17 +157,17 @@ impl executive::ExecuteBlock for BlockExecutor { /// This doesn't attempt to validate anything regarding the block. pub fn validate_transaction(utx: Extrinsic) -> TransactionValidity { if check_signature(&utx).is_err() { - return TransactionValidity::Invalid(ApplyError::BadSignature as i8); + return InvalidTransaction::BadProof.into(); } let tx = utx.transfer(); let nonce_key = tx.from.to_keyed_vec(NONCE_OF); let expected_nonce: u64 = storage::hashed::get_or(&blake2_256, &nonce_key, 0); if tx.nonce < expected_nonce { - return TransactionValidity::Invalid(ApplyError::Stale as i8); + return InvalidTransaction::Stale.into(); } if tx.nonce > expected_nonce + 64 { - return TransactionValidity::Unknown(ApplyError::Future as i8); + return InvalidTransaction::Future.into(); } let hash = |from: &AccountId, nonce: u64| { @@ -176,7 +187,7 @@ pub fn validate_transaction(utx: Extrinsic) -> TransactionValidity { p }; - TransactionValidity::Valid(ValidTransaction { + Ok(ValidTransaction { priority: tx.amount, requires, provides, @@ -199,8 +210,7 @@ pub fn execute_transaction(utx: Extrinsic) -> ApplyResult { pub fn finalize_block() -> Header { let extrinsic_index: u32 = storage::unhashed::take(well_known_keys::EXTRINSIC_INDEX).unwrap(); let txs: Vec<_> = (0..extrinsic_index).map(ExtrinsicData::take).collect(); - let txs = txs.iter().map(Vec::as_slice).collect::>(); - let extrinsics_root = ordered_trie_root::(&txs).into(); + let extrinsics_root = BlakeTwo256::ordered_trie_root(txs).into(); let number = ::take().expect("Number is set by `initialize_block`"); let parent_hash = ::take(); let mut digest = ::take().expect("StorageDigest is set by `initialize_block`"); @@ -232,8 +242,7 @@ pub fn finalize_block() -> Header { #[inline(always)] fn check_signature(utx: &Extrinsic) -> Result<(), ApplyError> { use sr_primitives::traits::BlindCheckable; - utx.clone().check().map_err(|_| ApplyError::BadSignature)?; - Ok(()) + utx.clone().check().map_err(|_| InvalidTransaction::BadProof.into()).map(|_| ()) } fn execute_transaction_backend(utx: &Extrinsic) -> ApplyResult { @@ -241,7 +250,7 @@ fn execute_transaction_backend(utx: &Extrinsic) -> ApplyResult { match utx { Extrinsic::Transfer(ref transfer, _) => execute_transfer_backend(transfer), Extrinsic::AuthoritiesChange(ref new_auth) => execute_new_authorities_backend(new_auth), - Extrinsic::IncludeData(_) => Ok(ApplyOutcome::Success), + Extrinsic::IncludeData(_) => Ok(Ok(())), Extrinsic::StorageChange(key, value) => execute_storage_change(key, value.as_ref().map(|v| &**v)), } } @@ -251,7 +260,7 @@ fn execute_transfer_backend(tx: &Transfer) -> ApplyResult { let nonce_key = tx.from.to_keyed_vec(NONCE_OF); let expected_nonce: u64 = storage::hashed::get_or(&blake2_256, &nonce_key, 0); if !(tx.nonce == expected_nonce) { - return Err(ApplyError::Stale) + return Err(InvalidTransaction::Stale.into()); } // increment nonce in storage @@ -263,18 +272,18 @@ fn execute_transfer_backend(tx: &Transfer) -> ApplyResult { // enact transfer if !(tx.amount <= from_balance) { - return Err(ApplyError::CantPay) + return Err(InvalidTransaction::Payment.into()); } let to_balance_key = tx.to.to_keyed_vec(BALANCE_OF); let to_balance: u64 = storage::hashed::get_or(&blake2_256, &to_balance_key, 0); storage::hashed::put(&blake2_256, &from_balance_key, &(from_balance - tx.amount)); storage::hashed::put(&blake2_256, &to_balance_key, &(to_balance + tx.amount)); - Ok(ApplyOutcome::Success) + Ok(Ok(())) } fn execute_new_authorities_backend(new_authorities: &[AuthorityId]) -> ApplyResult { NewAuthorities::put(new_authorities.to_vec()); - Ok(ApplyOutcome::Success) + Ok(Ok(())) } fn execute_storage_change(key: &[u8], value: Option<&[u8]>) -> ApplyResult { @@ -282,7 +291,7 @@ fn execute_storage_change(key: &[u8], value: Option<&[u8]>) -> ApplyResult { Some(value) => storage::unhashed::put_raw(key, value), None => storage::unhashed::kill(key), } - Ok(ApplyOutcome::Success) + Ok(Ok(())) } #[cfg(feature = "std")] @@ -292,7 +301,7 @@ fn info_expect_equal_hash(given: &Hash, expected: &Hash) { println!( "Hash: given={}, expected={}", HexDisplay::from(given.as_fixed_bytes()), - HexDisplay::from(expected.as_fixed_bytes()) + HexDisplay::from(expected.as_fixed_bytes()), ); } } @@ -300,9 +309,9 @@ fn info_expect_equal_hash(given: &Hash, expected: &Hash) { #[cfg(not(feature = "std"))] fn info_expect_equal_hash(given: &Hash, expected: &Hash) { if given != expected { - ::runtime_io::print("Hash not equal"); - ::runtime_io::print(given.as_bytes()); - ::runtime_io::print(expected.as_bytes()); + sr_primitives::print("Hash not equal"); + sr_primitives::print(given.as_bytes()); + sr_primitives::print(expected.as_bytes()); } } diff --git a/core/transaction-pool/Cargo.toml b/core/transaction-pool/Cargo.toml index 747c39a16566a9881d7319fb2ab42d5ae995d512..33ec9e9ece176b49ffca017ca9b7d0603c9e32d9 100644 --- a/core/transaction-pool/Cargo.toml +++ b/core/transaction-pool/Cargo.toml @@ -5,9 +5,9 @@ authors = ["Parity Technologies "] edition = "2018" [dependencies] -derive_more = "0.14.0" -futures = "0.1" -log = "0.4" +derive_more = "0.15.0" +log = "0.4.8" +futures-preview = "0.3.0-alpha.19" codec = { package = "parity-scale-codec", version = "1.0.0" } parking_lot = "0.9.0" sr-primitives = { path = "../sr-primitives" } diff --git a/core/transaction-pool/graph/Cargo.toml b/core/transaction-pool/graph/Cargo.toml index 4dc7ce69cffe943817077c385678580cc0eb0f42..d99291476ea91af25ce4f02be4fb9e6ee114ea2d 100644 --- a/core/transaction-pool/graph/Cargo.toml +++ b/core/transaction-pool/graph/Cargo.toml @@ -5,16 +5,16 @@ authors = ["Parity Technologies "] edition = "2018" [dependencies] -derive_more = "0.14.0" -futures = "0.1" -log = "0.4" +derive_more = "0.15.0" +futures-preview = "0.3.0-alpha.19" +log = "0.4.8" parking_lot = "0.9.0" -serde = { version = "1.0", features = ["derive"] } +serde = { version = "1.0.101", features = ["derive"] } primitives = { package = "substrate-primitives", path = "../../primitives" } sr-primitives = { path = "../../sr-primitives" } [dev-dependencies] assert_matches = "1.3.0" -env_logger = "0.6.1" +env_logger = "0.6.2" codec = { package = "parity-scale-codec", version = "1.0.0" } test_runtime = { package = "substrate-test-runtime", path = "../../test-runtime" } diff --git a/core/transaction-pool/graph/src/error.rs b/core/transaction-pool/graph/src/error.rs index 07e0324354dfae0d866b390ec17e08d0779e58e6..79006461c6e37f0ef0e1ae793fa13f12a459a87b 100644 --- a/core/transaction-pool/graph/src/error.rs +++ b/core/transaction-pool/graph/src/error.rs @@ -16,7 +16,9 @@ //! Transaction pool errors. -use sr_primitives::transaction_validity::TransactionPriority as Priority; +use sr_primitives::transaction_validity::{ + TransactionPriority as Priority, InvalidTransaction, UnknownTransaction, +}; /// Transaction pool result. pub type Result = std::result::Result; @@ -25,11 +27,17 @@ pub type Result = std::result::Result; #[derive(Debug, derive_more::Display, derive_more::From)] pub enum Error { /// Transaction is not verifiable yet, but might be in the future. - #[display(fmt="Unkown Transaction Validity. Error code: {}", _0)] - UnknownTransactionValidity(i8), + #[display(fmt="Unknown transaction validity: {:?}", _0)] + UnknownTransaction(UnknownTransaction), /// Transaction is invalid. - #[display(fmt="Invalid Transaction. Error Code: {}", _0)] - InvalidTransaction(i8), + #[display(fmt="Invalid transaction validity: {:?}", _0)] + InvalidTransaction(InvalidTransaction), + /// The transaction validity returned no "provides" tag. + /// + /// Such transactions are not accepted to the pool, since we use those tags + /// to define identity of transactions (occupance of the same "slot"). + #[display(fmt="The transaction does not provide any tags, so the pool can't identify it.")] + NoTagsProvided, /// The transaction is temporarily banned. #[display(fmt="Temporarily Banned")] TemporarilyBanned, diff --git a/core/transaction-pool/graph/src/lib.rs b/core/transaction-pool/graph/src/lib.rs index ea890a5cd0f2182d3d85c95250bf37c6914957eb..715e60874be951fdabfdb05e04c141f5cfa49c8c 100644 --- a/core/transaction-pool/graph/src/lib.rs +++ b/core/transaction-pool/graph/src/lib.rs @@ -29,6 +29,7 @@ mod listener; mod pool; mod ready; mod rotator; +mod validated_pool; pub mod base_pool; pub mod error; @@ -36,4 +37,8 @@ pub mod watcher; pub use self::error::IntoPoolError; pub use self::base_pool::{Transaction, Status}; -pub use self::pool::{Pool, Options, ChainApi, EventStream, ExtrinsicFor, BlockHash, ExHash, NumberFor, TransactionFor}; +pub use self::pool::{ + Pool, + Options, ChainApi, EventStream, ExtrinsicFor, + BlockHash, ExHash, NumberFor, TransactionFor, +}; diff --git a/core/transaction-pool/graph/src/pool.rs b/core/transaction-pool/graph/src/pool.rs index 6eec0d222f1a3f8fc4621ce9775c13ef814c339d..53b2a62cbee89922f2b86c5fdbd24942c1c6e986 100644 --- a/core/transaction-pool/graph/src/pool.rs +++ b/core/transaction-pool/graph/src/pool.rs @@ -15,29 +15,27 @@ // along with Substrate. If not, see . use std::{ - collections::{HashSet, HashMap}, hash, + collections::HashMap, sync::Arc, - time, }; use crate::base_pool as base; use crate::error; -use crate::listener::Listener; -use crate::rotator::PoolRotator; use crate::watcher::Watcher; use serde::Serialize; -use log::debug; -use futures::sync::mpsc; -use parking_lot::{Mutex, RwLock}; +use futures::{ + Future, FutureExt, + channel::mpsc, + future::{Either, ready, join_all}, +}; use sr_primitives::{ generic::BlockId, traits::{self, SaturatedConversion}, - transaction_validity::{TransactionValidity, TransactionTag as Tag}, + transaction_validity::{TransactionValidity, TransactionTag as Tag, TransactionValidityError}, }; - -pub use crate::base_pool::Limit; +use crate::validated_pool::{ValidatedPool, ValidatedTransaction}; /// Modification notification event stream type; pub type EventStream = mpsc::UnboundedReceiver<()>; @@ -52,6 +50,12 @@ pub type ExtrinsicFor = <::Block as traits::Block>::Extrinsic; pub type NumberFor = traits::NumberFor<::Block>; /// A type of transaction stored in the pool pub type TransactionFor = Arc, ExtrinsicFor>>; +/// A type of validated transaction stored in the pool. +pub type ValidatedTransactionFor = ValidatedTransaction< + ExHash, + ExtrinsicFor, + ::Error, +>; /// Concrete extrinsic validation and query logic. pub trait ChainApi: Send + Sync { @@ -61,9 +65,15 @@ pub trait ChainApi: Send + Sync { type Hash: hash::Hash + Eq + traits::Member + Serialize; /// Error type. type Error: From + error::IntoPoolError; + /// Validate transaction future. + type ValidationFuture: Future> + Send; /// Verify extrinsic at given block. - fn validate_transaction(&self, at: &BlockId, uxt: ExtrinsicFor) -> Result; + fn validate_transaction( + &self, + at: &BlockId, + uxt: ExtrinsicFor, + ) -> Self::ValidationFuture; /// Returns a block number given the block id. fn block_id_to_number(&self, at: &BlockId) -> Result>, Self::Error>; @@ -79,19 +89,19 @@ pub trait ChainApi: Send + Sync { #[derive(Debug, Clone)] pub struct Options { /// Ready queue limits. - pub ready: Limit, + pub ready: base::Limit, /// Future queue limits. - pub future: Limit, + pub future: base::Limit, } impl Default for Options { fn default() -> Self { Options { - ready: Limit { + ready: base::Limit { count: 512, total_bytes: 10 * 1024 * 1024, }, - future: Limit { + future: base::Limit { count: 128, total_bytes: 1 * 1024 * 1024, }, @@ -99,122 +109,60 @@ impl Default for Options { } } -/// Extrinsics pool. +/// Extrinsics pool that performs validation. pub struct Pool { - api: B, - options: Options, - listener: RwLock, BlockHash>>, - pool: RwLock, - ExtrinsicFor, - >>, - import_notification_sinks: Mutex>>, - rotator: PoolRotator>, + validated_pool: Arc>, } impl Pool { + /// Create a new transaction pool. + pub fn new(options: Options, api: B) -> Self { + Pool { + validated_pool: Arc::new(ValidatedPool::new(options, api)), + } + } + /// Imports a bunch of unverified extrinsics to the pool - pub fn submit_at(&self, at: &BlockId, xts: T) -> Result, B::Error>>, B::Error> where + pub fn submit_at(&self, at: &BlockId, xts: T, force: bool) + -> impl Future, B::Error>>, B::Error>> + where T: IntoIterator> { - let block_number = self.api.block_id_to_number(at)? - .ok_or_else(|| error::Error::InvalidBlockId(format!("{:?}", at)).into())?; - - let results = xts - .into_iter() - .map(|xt| -> Result<_, B::Error> { - let (hash, bytes) = self.api.hash_and_length(&xt); - if self.rotator.is_banned(&hash) { - return Err(error::Error::TemporarilyBanned.into()) - } - - match self.api.validate_transaction(at, xt.clone())? { - TransactionValidity::Valid(validity) => { - Ok(base::Transaction { - data: xt, - bytes - , - hash, - priority: validity.priority, - requires: validity.requires, - provides: validity.provides, - propagate: validity.propagate, - valid_till: block_number - .saturated_into::() - .saturating_add(validity.longevity), - }) - }, - TransactionValidity::Invalid(e) => { - Err(error::Error::InvalidTransaction(e).into()) - }, - TransactionValidity::Unknown(e) => { - self.listener.write().invalid(&hash); - Err(error::Error::UnknownTransactionValidity(e).into()) - }, - } - }) - .map(|tx| { - let imported = self.pool.write().import(tx?)?; - - if let base::Imported::Ready { .. } = imported { - self.import_notification_sinks.lock().retain(|sink| sink.unbounded_send(()).is_ok()); - } - - let mut listener = self.listener.write(); - fire_events(&mut *listener, &imported); - Ok(imported.hash().clone()) - }) - .collect::>(); - - let removed = self.enforce_limits(); - - Ok(results.into_iter().map(|res| match res { - Ok(ref hash) if removed.contains(hash) => Err(error::Error::ImmediatelyDropped.into()), - other => other, - }).collect()) - } - - fn enforce_limits(&self) -> HashSet> { - let status = self.pool.read().status(); - let ready_limit = &self.options.ready; - let future_limit = &self.options.future; - - debug!(target: "txpool", "Pool Status: {:?}", status); - - if ready_limit.is_exceeded(status.ready, status.ready_bytes) - || future_limit.is_exceeded(status.future, status.future_bytes) { - // clean up the pool - let removed = { - let mut pool = self.pool.write(); - let removed = pool.enforce_limits(ready_limit, future_limit) - .into_iter().map(|x| x.hash.clone()).collect::>(); - // ban all removed transactions - self.rotator.ban(&std::time::Instant::now(), removed.iter().map(|x| x.clone())); - removed - }; - // run notifications - let mut listener = self.listener.write(); - for h in &removed { - listener.dropped(h, None); - } - - removed - } else { - Default::default() - } + let validated_pool = self.validated_pool.clone(); + self.verify(at, xts, force) + .map(move |validated_transactions| validated_transactions + .map(|validated_transactions| validated_pool.submit(validated_transactions))) } /// Imports one unverified extrinsic to the pool - pub fn submit_one(&self, at: &BlockId, xt: ExtrinsicFor) -> Result, B::Error> { - Ok(self.submit_at(at, ::std::iter::once(xt))?.pop().expect("One extrinsic passed; one result returned; qed")?) + pub fn submit_one( + &self, + at: &BlockId, + xt: ExtrinsicFor, + ) -> impl Future, B::Error>> { + self.submit_at(at, std::iter::once(xt), false) + .map(|import_result| import_result.and_then(|mut import_result| import_result + .pop() + .expect("One extrinsic passed; one result returned; qed") + )) } /// Import a single extrinsic and starts to watch their progress in the pool. - pub fn submit_and_watch(&self, at: &BlockId, xt: ExtrinsicFor) -> Result, BlockHash>, B::Error> { - let hash = self.api.hash_and_length(&xt).0; - let watcher = self.listener.write().create_watcher(hash); - self.submit_one(at, xt)?; - Ok(watcher) + pub fn submit_and_watch( + &self, + at: &BlockId, + xt: ExtrinsicFor, + ) -> impl Future, BlockHash>, B::Error>> { + let block_number = match self.resolve_block_number(at) { + Ok(block_number) => block_number, + Err(err) => return Either::Left(ready(Err(err))) + }; + + let validated_pool = self.validated_pool.clone(); + Either::Right( + self.verify_one(at, block_number, xt, false) + .map(move |validated_transactions| validated_pool.submit_and_watch(validated_transactions)) + ) } /// Prunes ready transactions. @@ -223,41 +171,46 @@ impl Pool { /// To perform pruning we need the tags that each extrinsic provides and to avoid calling /// into runtime too often we first lookup all extrinsics that are in the pool and get /// their provided tags from there. Otherwise we query the runtime at the `parent` block. - pub fn prune(&self, at: &BlockId, parent: &BlockId, extrinsics: &[ExtrinsicFor]) -> Result<(), B::Error> { - let mut tags = Vec::with_capacity(extrinsics.len()); + pub fn prune( + &self, + at: &BlockId, + parent: &BlockId, + extrinsics: &[ExtrinsicFor], + ) -> impl Future> { // Get details of all extrinsics that are already in the pool - let hashes = extrinsics.iter().map(|extrinsic| self.api.hash_and_length(extrinsic).0).collect::>(); - let in_pool = self.pool.read().by_hash(&hashes); - { - // Zip the ones from the pool with the full list (we get pairs `(Extrinsic, Option)`) - let all = extrinsics.iter().zip(in_pool.iter()); - - for (extrinsic, existing_in_pool) in all { - match *existing_in_pool { + let (in_pool_hashes, in_pool_tags) = self.validated_pool.extrinsics_tags(extrinsics); + + // Zip the ones from the pool with the full list (we get pairs `(Extrinsic, Option>)`) + let all = extrinsics.iter().zip(in_pool_tags.into_iter()); + + // Prepare future that collect tags for all extrinsics + let future_tags = join_all(all + .map(|(extrinsic, in_pool_tags)| + match in_pool_tags { // reuse the tags for extrinsics that were found in the pool - Some(ref transaction) => { - tags.extend(transaction.provides.iter().cloned()); - }, + Some(tags) => Either::Left( + ready(tags) + ), // if it's not found in the pool query the runtime at parent block // to get validity info and tags that the extrinsic provides. - None => { - let validity = self.api.validate_transaction(parent, extrinsic.clone()); - match validity { - Ok(TransactionValidity::Valid(mut validity)) => { - tags.append(&mut validity.provides); - }, + None => Either::Right(self.validated_pool.api().validate_transaction(parent, extrinsic.clone()) + .then(|validity| ready(match validity { + Ok(Ok(validity)) => validity.provides, // silently ignore invalid extrinsics, // cause they might just be inherent - _ => {} - } - }, + _ => Vec::new(), + }))), } - } - } - - self.prune_tags(at, tags, in_pool.into_iter().filter_map(|x| x).map(|x| x.hash.clone()))?; - - Ok(()) + )); + + // Prune transactions by tags + let at = at.clone(); + let self_clone = self.clone(); + future_tags.then(move |tags| self_clone.prune_tags( + &at, + tags.into_iter().flat_map(|tags| tags), + in_pool_hashes, + )) } /// Prunes ready transactions that provide given list of tags. @@ -270,6 +223,9 @@ impl Pool { /// 1. Provide that tag directly /// 2. Are a dependency of pruned transaction. /// + /// Returns transactions that have been removed from the pool and must be reverified + /// before reinserting to the pool. + /// /// By removing predecessor transactions as well we might actually end up /// pruning too much, so all removed transactions are reverified against /// the runtime (`validate_transaction`) to make sure they are invalid. @@ -283,196 +239,183 @@ impl Pool { at: &BlockId, tags: impl IntoIterator, known_imported_hashes: impl IntoIterator> + Clone, - ) -> Result<(), B::Error> { - // Perform tag-based pruning in the base pool - let status = self.pool.write().prune_tags(tags); - // Notify event listeners of all transactions - // that were promoted to `Ready` or were dropped. - { - let mut listener = self.listener.write(); - for promoted in &status.promoted { - fire_events(&mut *listener, promoted); - } - for f in &status.failed { - listener.dropped(f, None); - } - } - // make sure that we don't revalidate extrinsics that were part of the recently + ) -> impl Future> { + // Prune all transactions that provide given tags + let prune_status = match self.validated_pool.prune_tags(tags) { + Ok(prune_status) => prune_status, + Err(e) => return Either::Left(ready(Err(e))), + }; + + // Make sure that we don't revalidate extrinsics that were part of the recently // imported block. This is especially important for UTXO-like chains cause the // inputs are pruned so such transaction would go to future again. - self.rotator.ban(&std::time::Instant::now(), known_imported_hashes.clone().into_iter()); + self.validated_pool.ban(&std::time::Instant::now(), known_imported_hashes.clone().into_iter()); - // try to re-submit pruned transactions since some of them might be still valid. + // Try to re-validate pruned transactions since some of them might be still valid. // note that `known_imported_hashes` will be rejected here due to temporary ban. - let hashes = status.pruned.iter().map(|tx| tx.hash.clone()).collect::>(); - let results = self.submit_at(at, status.pruned.into_iter().map(|tx| tx.data.clone()))?; - - // Collect the hashes of transactions that now became invalid (meaning that they are successfully pruned). - let hashes = results.into_iter().enumerate().filter_map(|(idx, r)| match r.map_err(error::IntoPoolError::into_pool_error) { - Err(Ok(error::Error::InvalidTransaction(_))) => Some(hashes[idx].clone()), - _ => None, - }); - // Fire `pruned` notifications for collected hashes and make sure to include - // `known_imported_hashes` since they were just imported as part of the block. - let hashes = hashes.chain(known_imported_hashes.into_iter()); - { - let header_hash = self.api.block_id_to_hash(at)? - .ok_or_else(|| error::Error::InvalidBlockId(format!("{:?}", at)).into())?; - let mut listener = self.listener.write(); - for h in hashes { - listener.pruned(header_hash, &h); - } - } - // perform regular cleanup of old transactions in the pool - // and update temporary bans. - self.clear_stale(at)?; - Ok(()) - } - - /// Removes stale transactions from the pool. - /// - /// Stale transactions are transaction beyond their longevity period. - /// Note this function does not remove transactions that are already included in the chain. - /// See `prune_tags` if you want this. - pub fn clear_stale(&self, at: &BlockId) -> Result<(), B::Error> { - let block_number = self.api.block_id_to_number(at)? - .ok_or_else(|| error::Error::InvalidBlockId(format!("{:?}", at)).into())? - .saturated_into::(); - let now = time::Instant::now(); - let to_remove = { - self.ready() - .filter(|tx| self.rotator.ban_if_stale(&now, block_number, &tx)) - .map(|tx| tx.hash.clone()) - .collect::>() - }; - let futures_to_remove: Vec> = { - let p = self.pool.read(); - let mut hashes = Vec::new(); - for tx in p.futures() { - if self.rotator.ban_if_stale(&now, block_number, &tx) { - hashes.push(tx.hash.clone()); - } - } - hashes - }; - // removing old transactions - self.remove_invalid(&to_remove); - self.remove_invalid(&futures_to_remove); - // clear banned transactions timeouts - self.rotator.clear_timeouts(&now); - - Ok(()) - } - - /// Create a new transaction pool. - pub fn new(options: Options, api: B) -> Self { - Pool { - api, - options, - listener: Default::default(), - pool: Default::default(), - import_notification_sinks: Default::default(), - rotator: Default::default(), - } + let pruned_hashes = prune_status.pruned.iter().map(|tx| tx.hash.clone()).collect::>(); + let pruned_transactions = prune_status.pruned.into_iter().map(|tx| tx.data.clone()); + let reverify_future = self.verify(at, pruned_transactions, false); + + // And finally - submit reverified transactions back to the pool + let at = at.clone(); + let validated_pool = self.validated_pool.clone(); + Either::Right(reverify_future.then(move |reverified_transactions| + ready(reverified_transactions.and_then(|reverified_transactions| + validated_pool.resubmit_pruned( + &at, + known_imported_hashes, + pruned_hashes, + reverified_transactions, + )) + ))) } /// Return an event stream of transactions imported to the pool. pub fn import_notification_stream(&self) -> EventStream { - let (sink, stream) = mpsc::unbounded(); - self.import_notification_sinks.lock().push(sink); - stream + self.validated_pool.import_notification_stream() } /// Invoked when extrinsics are broadcasted. pub fn on_broadcasted(&self, propagated: HashMap, Vec>) { - let mut listener = self.listener.write(); - for (hash, peers) in propagated.into_iter() { - listener.broadcasted(&hash, peers); - } + self.validated_pool.on_broadcasted(propagated) } /// Remove from the pool. pub fn remove_invalid(&self, hashes: &[ExHash]) -> Vec> { - // temporarily ban invalid transactions - debug!(target: "txpool", "Banning invalid transactions: {:?}", hashes); - self.rotator.ban(&time::Instant::now(), hashes.iter().cloned()); - - let invalid = self.pool.write().remove_invalid(hashes); - - let mut listener = self.listener.write(); - for tx in &invalid { - listener.invalid(&tx.hash); - } - - invalid + self.validated_pool.remove_invalid(hashes) } /// Get an iterator for ready transactions ordered by priority pub fn ready(&self) -> impl Iterator> { - self.pool.read().ready() + self.validated_pool.ready() } /// Returns pool status. pub fn status(&self) -> base::Status { - self.pool.read().status() + self.validated_pool.status() } /// Returns transaction hash pub fn hash_of(&self, xt: &ExtrinsicFor) -> ExHash { - self.api.hash_and_length(xt).0 + self.validated_pool.api().hash_and_length(xt).0 + } + + /// Resolves block number by id. + fn resolve_block_number(&self, at: &BlockId) -> Result, B::Error> { + self.validated_pool.api().block_id_to_number(at) + .and_then(|number| number.ok_or_else(|| + error::Error::InvalidBlockId(format!("{:?}", at)).into())) + } + + /// Returns future that validates a bunch of transactions at given block. + fn verify( + &self, + at: &BlockId, + xts: impl IntoIterator>, + force: bool, + ) -> impl Future>, B::Error>> { + // we need a block number to compute tx validity + let block_number = match self.resolve_block_number(at) { + Ok(block_number) => block_number, + Err(err) => return Either::Left(ready(Err(err))), + }; + + // for each xt, prepare a validation future + let validation_futures = xts.into_iter().map(move |xt| + self.verify_one(at, block_number, xt, force) + ); + + // make single validation future that waits all until all extrinsics are validated + Either::Right(join_all(validation_futures).then(|x| ready(Ok(x)))) + } + + /// Returns future that validates single transaction at given block. + fn verify_one( + &self, + block_id: &BlockId, + block_number: NumberFor, + xt: ExtrinsicFor, + force: bool, + ) -> impl Future> { + let (hash, bytes) = self.validated_pool.api().hash_and_length(&xt); + if !force && self.validated_pool.is_banned(&hash) { + return Either::Left(ready(ValidatedTransaction::Invalid(error::Error::TemporarilyBanned.into()))) + } + + Either::Right(self.validated_pool.api().validate_transaction(block_id, xt.clone()) + .then(move |validation_result| ready(match validation_result { + Ok(validity) => match validity { + Ok(validity) => if validity.provides.is_empty() { + ValidatedTransaction::Invalid(error::Error::NoTagsProvided.into()) + } else { + ValidatedTransaction::Valid(base::Transaction { + data: xt, + bytes, + hash, + priority: validity.priority, + requires: validity.requires, + provides: validity.provides, + propagate: validity.propagate, + valid_till: block_number + .saturated_into::() + .saturating_add(validity.longevity), + }) + }, + Err(TransactionValidityError::Invalid(e)) => + ValidatedTransaction::Invalid(error::Error::InvalidTransaction(e).into()), + Err(TransactionValidityError::Unknown(e)) => + ValidatedTransaction::Unknown(hash, error::Error::UnknownTransaction(e).into()), + }, + Err(e) => ValidatedTransaction::Invalid(e), + }))) } } -fn fire_events( - listener: &mut Listener, - imported: &base::Imported, -) where - H: hash::Hash + Eq + traits::Member + Serialize, - H2: Clone, -{ - match *imported { - base::Imported::Ready { ref promoted, ref failed, ref removed, ref hash } => { - listener.ready(hash, None); - for f in failed { - listener.invalid(f); - } - for r in removed { - listener.dropped(&r.hash, Some(hash)); - } - for p in promoted { - listener.ready(p, None); - } - }, - base::Imported::Future { ref hash } => { - listener.future(hash) - }, +impl Clone for Pool { + fn clone(&self) -> Self { + Self { + validated_pool: self.validated_pool.clone(), + } } } #[cfg(test)] mod tests { + use std::{ + collections::HashMap, + time::Instant, + }; + use parking_lot::Mutex; + use futures::executor::block_on; use super::*; - use sr_primitives::transaction_validity::ValidTransaction; - use futures::Stream; + use sr_primitives::transaction_validity::{ValidTransaction, InvalidTransaction}; use codec::Encode; use test_runtime::{Block, Extrinsic, Transfer, H256, AccountId}; use assert_matches::assert_matches; + use crate::base_pool::Limit; use crate::watcher; - #[derive(Debug, Default)] + const INVALID_NONCE: u64 = 254; + + #[derive(Clone, Debug, Default)] struct TestApi { - delay: Mutex>>, + delay: Arc>>>, } impl ChainApi for TestApi { type Block = Block; type Hash = u64; type Error = error::Error; + type ValidationFuture = futures::future::Ready>; /// Verify extrinsic at given block. - fn validate_transaction(&self, at: &BlockId, uxt: ExtrinsicFor) -> Result { - - let block_number = self.block_id_to_number(at)?.unwrap(); + fn validate_transaction( + &self, + at: &BlockId, + uxt: ExtrinsicFor, + ) -> Self::ValidationFuture { + let block_number = self.block_id_to_number(at).unwrap().unwrap(); let nonce = uxt.transfer().nonce; // This is used to control the test flow. @@ -485,17 +428,17 @@ mod tests { } } - if nonce < block_number { - Ok(TransactionValidity::Invalid(0)) + futures::future::ready(if nonce < block_number { + Ok(InvalidTransaction::Stale.into()) } else { - Ok(TransactionValidity::Valid(ValidTransaction { + Ok(Ok(ValidTransaction { priority: 4, requires: if nonce > block_number { vec![vec![nonce as u8 - 1]] } else { vec![] }, - provides: vec![vec![nonce as u8]], + provides: if nonce == INVALID_NONCE { vec![] } else { vec![vec![nonce as u8]] }, longevity: 3, propagate: true, })) - } + }) } /// Returns a block number given the block id. @@ -539,12 +482,12 @@ mod tests { let pool = pool(); // when - let hash = pool.submit_one(&BlockId::Number(0), uxt(Transfer { + let hash = block_on(pool.submit_one(&BlockId::Number(0), uxt(Transfer { from: AccountId::from_h256(H256::from_low_u64_be(1)), to: AccountId::from_h256(H256::from_low_u64_be(2)), amount: 5, nonce: 0, - })).unwrap(); + }))).unwrap(); // then assert_eq!(pool.ready().map(|v| v.hash).collect::>(), vec![hash]); @@ -562,8 +505,8 @@ mod tests { }); // when - pool.rotator.ban(&time::Instant::now(), vec![pool.hash_of(&uxt)]); - let res = pool.submit_one(&BlockId::Number(0), uxt); + pool.validated_pool.rotator().ban(&Instant::now(), vec![pool.hash_of(&uxt)]); + let res = block_on(pool.submit_one(&BlockId::Number(0), uxt)); assert_eq!(pool.status().ready, 0); assert_eq!(pool.status().future, 0); @@ -579,25 +522,25 @@ mod tests { let stream = pool.import_notification_stream(); // when - let _hash = pool.submit_one(&BlockId::Number(0), uxt(Transfer { + let _hash = block_on(pool.submit_one(&BlockId::Number(0), uxt(Transfer { from: AccountId::from_h256(H256::from_low_u64_be(1)), to: AccountId::from_h256(H256::from_low_u64_be(2)), amount: 5, nonce: 0, - })).unwrap(); - let _hash = pool.submit_one(&BlockId::Number(0), uxt(Transfer { + }))).unwrap(); + let _hash = block_on(pool.submit_one(&BlockId::Number(0), uxt(Transfer { from: AccountId::from_h256(H256::from_low_u64_be(1)), to: AccountId::from_h256(H256::from_low_u64_be(2)), amount: 5, nonce: 1, - })).unwrap(); + }))).unwrap(); // future doesn't count - let _hash = pool.submit_one(&BlockId::Number(0), uxt(Transfer { + let _hash = block_on(pool.submit_one(&BlockId::Number(0), uxt(Transfer { from: AccountId::from_h256(H256::from_low_u64_be(1)), to: AccountId::from_h256(H256::from_low_u64_be(2)), amount: 5, nonce: 3, - })).unwrap(); + }))).unwrap(); assert_eq!(pool.status().ready, 2); assert_eq!(pool.status().future, 1); @@ -605,9 +548,9 @@ mod tests { }; // then - let mut it = stream.wait(); - assert_eq!(it.next(), Some(Ok(()))); - assert_eq!(it.next(), Some(Ok(()))); + let mut it = futures::executor::block_on_stream(stream); + assert_eq!(it.next(), Some(())); + assert_eq!(it.next(), Some(())); assert_eq!(it.next(), None); } @@ -615,54 +558,54 @@ mod tests { fn should_clear_stale_transactions() { // given let pool = pool(); - let hash1 = pool.submit_one(&BlockId::Number(0), uxt(Transfer { + let hash1 = block_on(pool.submit_one(&BlockId::Number(0), uxt(Transfer { from: AccountId::from_h256(H256::from_low_u64_be(1)), to: AccountId::from_h256(H256::from_low_u64_be(2)), amount: 5, nonce: 0, - })).unwrap(); - let hash2 = pool.submit_one(&BlockId::Number(0), uxt(Transfer { + }))).unwrap(); + let hash2 = block_on(pool.submit_one(&BlockId::Number(0), uxt(Transfer { from: AccountId::from_h256(H256::from_low_u64_be(1)), to: AccountId::from_h256(H256::from_low_u64_be(2)), amount: 5, nonce: 1, - })).unwrap(); - let hash3 = pool.submit_one(&BlockId::Number(0), uxt(Transfer { + }))).unwrap(); + let hash3 = block_on(pool.submit_one(&BlockId::Number(0), uxt(Transfer { from: AccountId::from_h256(H256::from_low_u64_be(1)), to: AccountId::from_h256(H256::from_low_u64_be(2)), amount: 5, nonce: 3, - })).unwrap(); + }))).unwrap(); // when - pool.clear_stale(&BlockId::Number(5)).unwrap(); + pool.validated_pool.clear_stale(&BlockId::Number(5)).unwrap(); // then assert_eq!(pool.ready().count(), 0); assert_eq!(pool.status().future, 0); assert_eq!(pool.status().ready, 0); // make sure they are temporarily banned as well - assert!(pool.rotator.is_banned(&hash1)); - assert!(pool.rotator.is_banned(&hash2)); - assert!(pool.rotator.is_banned(&hash3)); + assert!(pool.validated_pool.rotator().is_banned(&hash1)); + assert!(pool.validated_pool.rotator().is_banned(&hash2)); + assert!(pool.validated_pool.rotator().is_banned(&hash3)); } #[test] fn should_ban_mined_transactions() { // given let pool = pool(); - let hash1 = pool.submit_one(&BlockId::Number(0), uxt(Transfer { + let hash1 = block_on(pool.submit_one(&BlockId::Number(0), uxt(Transfer { from: AccountId::from_h256(H256::from_low_u64_be(1)), to: AccountId::from_h256(H256::from_low_u64_be(2)), amount: 5, nonce: 0, - })).unwrap(); + }))).unwrap(); // when - pool.prune_tags(&BlockId::Number(1), vec![vec![0]], vec![hash1.clone()]).unwrap(); + block_on(pool.prune_tags(&BlockId::Number(1), vec![vec![0]], vec![hash1.clone()])).unwrap(); // then - assert!(pool.rotator.is_banned(&hash1)); + assert!(pool.validated_pool.rotator().is_banned(&hash1)); } #[test] @@ -677,26 +620,26 @@ mod tests { future: limit.clone(), }, TestApi::default()); - let hash1 = pool.submit_one(&BlockId::Number(0), uxt(Transfer { + let hash1 = block_on(pool.submit_one(&BlockId::Number(0), uxt(Transfer { from: AccountId::from_h256(H256::from_low_u64_be(1)), to: AccountId::from_h256(H256::from_low_u64_be(2)), amount: 5, nonce: 1, - })).unwrap(); + }))).unwrap(); assert_eq!(pool.status().future, 1); // when - let hash2 = pool.submit_one(&BlockId::Number(0), uxt(Transfer { + let hash2 = block_on(pool.submit_one(&BlockId::Number(0), uxt(Transfer { from: AccountId::from_h256(H256::from_low_u64_be(2)), to: AccountId::from_h256(H256::from_low_u64_be(2)), amount: 5, nonce: 10, - })).unwrap(); + }))).unwrap(); // then assert_eq!(pool.status().future, 1); - assert!(pool.rotator.is_banned(&hash1)); - assert!(!pool.rotator.is_banned(&hash2)); + assert!(pool.validated_pool.rotator().is_banned(&hash1)); + assert!(!pool.validated_pool.rotator().is_banned(&hash2)); } #[test] @@ -712,18 +655,36 @@ mod tests { }, TestApi::default()); // when - pool.submit_one(&BlockId::Number(0), uxt(Transfer { + block_on(pool.submit_one(&BlockId::Number(0), uxt(Transfer { from: AccountId::from_h256(H256::from_low_u64_be(1)), to: AccountId::from_h256(H256::from_low_u64_be(2)), amount: 5, nonce: 1, - })).unwrap_err(); + }))).unwrap_err(); // then assert_eq!(pool.status().ready, 0); assert_eq!(pool.status().future, 0); } + #[test] + fn should_reject_transactions_with_no_provides() { + // given + let pool = pool(); + + // when + let err = block_on(pool.submit_one(&BlockId::Number(0), uxt(Transfer { + from: AccountId::from_h256(H256::from_low_u64_be(1)), + to: AccountId::from_h256(H256::from_low_u64_be(2)), + amount: 5, + nonce: INVALID_NONCE, + }))).unwrap_err(); + + // then + assert_eq!(pool.status().ready, 0); + assert_eq!(pool.status().future, 0); + assert_matches!(err, error::Error::NoTagsProvided); + } mod listener { use super::*; @@ -732,24 +693,24 @@ mod tests { fn should_trigger_ready_and_finalized() { // given let pool = pool(); - let watcher = pool.submit_and_watch(&BlockId::Number(0), uxt(Transfer { + let watcher = block_on(pool.submit_and_watch(&BlockId::Number(0), uxt(Transfer { from: AccountId::from_h256(H256::from_low_u64_be(1)), to: AccountId::from_h256(H256::from_low_u64_be(2)), amount: 5, nonce: 0, - })).unwrap(); + }))).unwrap(); assert_eq!(pool.status().ready, 1); assert_eq!(pool.status().future, 0); // when - pool.prune_tags(&BlockId::Number(2), vec![vec![0u8]], vec![]).unwrap(); + block_on(pool.prune_tags(&BlockId::Number(2), vec![vec![0u8]], vec![])).unwrap(); assert_eq!(pool.status().ready, 0); assert_eq!(pool.status().future, 0); // then - let mut stream = watcher.into_stream().wait(); - assert_eq!(stream.next(), Some(Ok(watcher::Status::Ready))); - assert_eq!(stream.next(), Some(Ok(watcher::Status::Finalized(H256::from_low_u64_be(2).into())))); + let mut stream = futures::executor::block_on_stream(watcher.into_stream()); + assert_eq!(stream.next(), Some(watcher::Status::Ready)); + assert_eq!(stream.next(), Some(watcher::Status::Finalized(H256::from_low_u64_be(2).into()))); assert_eq!(stream.next(), None); } @@ -757,24 +718,24 @@ mod tests { fn should_trigger_ready_and_finalized_when_pruning_via_hash() { // given let pool = pool(); - let watcher = pool.submit_and_watch(&BlockId::Number(0), uxt(Transfer { + let watcher = block_on(pool.submit_and_watch(&BlockId::Number(0), uxt(Transfer { from: AccountId::from_h256(H256::from_low_u64_be(1)), to: AccountId::from_h256(H256::from_low_u64_be(2)), amount: 5, nonce: 0, - })).unwrap(); + }))).unwrap(); assert_eq!(pool.status().ready, 1); assert_eq!(pool.status().future, 0); // when - pool.prune_tags(&BlockId::Number(2), vec![vec![0u8]], vec![2u64]).unwrap(); + block_on(pool.prune_tags(&BlockId::Number(2), vec![vec![0u8]], vec![2u64])).unwrap(); assert_eq!(pool.status().ready, 0); assert_eq!(pool.status().future, 0); // then - let mut stream = watcher.into_stream().wait(); - assert_eq!(stream.next(), Some(Ok(watcher::Status::Ready))); - assert_eq!(stream.next(), Some(Ok(watcher::Status::Finalized(H256::from_low_u64_be(2).into())))); + let mut stream = futures::executor::block_on_stream(watcher.into_stream()); + assert_eq!(stream.next(), Some(watcher::Status::Ready)); + assert_eq!(stream.next(), Some(watcher::Status::Finalized(H256::from_low_u64_be(2).into()))); assert_eq!(stream.next(), None); } @@ -782,28 +743,28 @@ mod tests { fn should_trigger_future_and_ready_after_promoted() { // given let pool = pool(); - let watcher = pool.submit_and_watch(&BlockId::Number(0), uxt(Transfer { + let watcher = block_on(pool.submit_and_watch(&BlockId::Number(0), uxt(Transfer { from: AccountId::from_h256(H256::from_low_u64_be(1)), to: AccountId::from_h256(H256::from_low_u64_be(2)), amount: 5, nonce: 1, - })).unwrap(); + }))).unwrap(); assert_eq!(pool.status().ready, 0); assert_eq!(pool.status().future, 1); // when - pool.submit_one(&BlockId::Number(0), uxt(Transfer { + block_on(pool.submit_one(&BlockId::Number(0), uxt(Transfer { from: AccountId::from_h256(H256::from_low_u64_be(1)), to: AccountId::from_h256(H256::from_low_u64_be(2)), amount: 5, nonce: 0, - })).unwrap(); + }))).unwrap(); assert_eq!(pool.status().ready, 2); // then - let mut stream = watcher.into_stream().wait(); - assert_eq!(stream.next(), Some(Ok(watcher::Status::Future))); - assert_eq!(stream.next(), Some(Ok(watcher::Status::Ready))); + let mut stream = futures::executor::block_on_stream(watcher.into_stream()); + assert_eq!(stream.next(), Some(watcher::Status::Future)); + assert_eq!(stream.next(), Some(watcher::Status::Ready)); } #[test] @@ -816,17 +777,17 @@ mod tests { amount: 5, nonce: 0, }); - let watcher = pool.submit_and_watch(&BlockId::Number(0), uxt).unwrap(); + let watcher = block_on(pool.submit_and_watch(&BlockId::Number(0), uxt)).unwrap(); assert_eq!(pool.status().ready, 1); // when - pool.remove_invalid(&[*watcher.hash()]); + pool.validated_pool.remove_invalid(&[*watcher.hash()]); // then - let mut stream = watcher.into_stream().wait(); - assert_eq!(stream.next(), Some(Ok(watcher::Status::Ready))); - assert_eq!(stream.next(), Some(Ok(watcher::Status::Invalid))); + let mut stream = futures::executor::block_on_stream(watcher.into_stream()); + assert_eq!(stream.next(), Some(watcher::Status::Ready)); + assert_eq!(stream.next(), Some(watcher::Status::Invalid)); assert_eq!(stream.next(), None); } @@ -840,7 +801,7 @@ mod tests { amount: 5, nonce: 0, }); - let watcher = pool.submit_and_watch(&BlockId::Number(0), uxt).unwrap(); + let watcher = block_on(pool.submit_and_watch(&BlockId::Number(0), uxt)).unwrap(); assert_eq!(pool.status().ready, 1); // when @@ -851,9 +812,9 @@ mod tests { // then - let mut stream = watcher.into_stream().wait(); - assert_eq!(stream.next(), Some(Ok(watcher::Status::Ready))); - assert_eq!(stream.next(), Some(Ok(watcher::Status::Broadcast(peers)))); + let mut stream = futures::executor::block_on_stream(watcher.into_stream()); + assert_eq!(stream.next(), Some(watcher::Status::Ready)); + assert_eq!(stream.next(), Some(watcher::Status::Broadcast(peers))); } #[test] @@ -874,7 +835,7 @@ mod tests { amount: 5, nonce: 0, }); - let watcher = pool.submit_and_watch(&BlockId::Number(0), xt).unwrap(); + let watcher = block_on(pool.submit_and_watch(&BlockId::Number(0), xt)).unwrap(); assert_eq!(pool.status().ready, 1); // when @@ -884,13 +845,13 @@ mod tests { amount: 4, nonce: 1, }); - pool.submit_one(&BlockId::Number(1), xt).unwrap(); + block_on(pool.submit_one(&BlockId::Number(1), xt)).unwrap(); assert_eq!(pool.status().ready, 1); // then - let mut stream = watcher.into_stream().wait(); - assert_eq!(stream.next(), Some(Ok(watcher::Status::Ready))); - assert_eq!(stream.next(), Some(Ok(watcher::Status::Dropped))); + let mut stream = futures::executor::block_on_stream(watcher.into_stream()); + assert_eq!(stream.next(), Some(watcher::Status::Ready)); + assert_eq!(stream.next(), Some(watcher::Status::Dropped)); } #[test] @@ -900,7 +861,7 @@ mod tests { let (ready, is_ready) = std::sync::mpsc::sync_channel(0); let (tx, rx) = std::sync::mpsc::sync_channel(1); let mut api = TestApi::default(); - api.delay = Mutex::new(rx.into()); + api.delay = Arc::new(Mutex::new(rx.into())); let pool = Arc::new(Pool::new(Default::default(), api)); // when @@ -914,7 +875,7 @@ mod tests { // This transaction should go to future, since we use `nonce: 1` let pool2 = pool.clone(); std::thread::spawn(move || { - pool2.submit_one(&BlockId::Number(0), xt).unwrap(); + block_on(pool2.submit_one(&BlockId::Number(0), xt)).unwrap(); ready.send(()).unwrap(); }); @@ -928,11 +889,11 @@ mod tests { }); // The tag the above transaction provides (TestApi is using just nonce as u8) let provides = vec![0_u8]; - pool.submit_one(&BlockId::Number(0), xt).unwrap(); + block_on(pool.submit_one(&BlockId::Number(0), xt)).unwrap(); assert_eq!(pool.status().ready, 1); // Now block import happens before the second transaction is able to finish verification. - pool.prune_tags(&BlockId::Number(1), vec![provides], vec![]).unwrap(); + block_on(pool.prune_tags(&BlockId::Number(1), vec![provides], vec![])).unwrap(); assert_eq!(pool.status().ready, 0); diff --git a/core/transaction-pool/graph/src/validated_pool.rs b/core/transaction-pool/graph/src/validated_pool.rs new file mode 100644 index 0000000000000000000000000000000000000000..9bf1012628645386fce7a0725125b4fb70523b3c --- /dev/null +++ b/core/transaction-pool/graph/src/validated_pool.rs @@ -0,0 +1,371 @@ +// Copyright 2018-2019 Parity Technologies (UK) Ltd. +// This file is part of Substrate. + +// Substrate 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. + +// Substrate 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 Substrate. If not, see . + +use std::{ + collections::{HashSet, HashMap}, + hash, + time, +}; + +use crate::base_pool as base; +use crate::error; +use crate::listener::Listener; +use crate::rotator::PoolRotator; +use crate::watcher::Watcher; +use serde::Serialize; +use log::debug; + +use futures::channel::mpsc; +use parking_lot::{Mutex, RwLock}; +use sr_primitives::{ + generic::BlockId, + traits::{self, SaturatedConversion}, + transaction_validity::TransactionTag as Tag, +}; + +use crate::base_pool::PruneStatus; +use crate::pool::{EventStream, Options, ChainApi, BlockHash, ExHash, ExtrinsicFor, TransactionFor}; + +/// Pre-validated transaction. Validated pool only accepts transactions wrapped in this enum. +#[derive(Debug)] +pub enum ValidatedTransaction { + /// Transaction that has been validated successfully. + Valid(base::Transaction), + /// Transaction that is invalid. + Invalid(Error), + /// Transaction which validity can't be determined. + /// + /// We're notifying watchers about failure, if 'unknown' transaction is submitted. + Unknown(Hash, Error), +} + +/// A type of validated transaction stored in the pool. +pub type ValidatedTransactionFor = ValidatedTransaction< + ExHash, + ExtrinsicFor, + ::Error, +>; + +/// Pool that deals with validated transactions. +pub(crate) struct ValidatedPool { + api: B, + options: Options, + listener: RwLock, BlockHash>>, + pool: RwLock, + ExtrinsicFor, + >>, + import_notification_sinks: Mutex>>, + rotator: PoolRotator>, +} + +impl ValidatedPool { + /// Create a new transaction pool. + pub fn new(options: Options, api: B) -> Self { + ValidatedPool { + api, + options, + listener: Default::default(), + pool: Default::default(), + import_notification_sinks: Default::default(), + rotator: Default::default(), + } + } + + /// Bans given set of hashes. + pub fn ban(&self, now: &std::time::Instant, hashes: impl IntoIterator>) { + self.rotator.ban(now, hashes) + } + + /// Returns true if transaction with given hash is currently banned from the pool. + pub fn is_banned(&self, hash: &ExHash) -> bool { + self.rotator.is_banned(hash) + } + + /// Imports a bunch of pre-validated transactions to the pool. + pub fn submit(&self, txs: T) -> Vec, B::Error>> where + T: IntoIterator> + { + let results = txs.into_iter() + .map(|validated_tx| self.submit_one(validated_tx)) + .collect::>(); + + let removed = self.enforce_limits(); + + results.into_iter().map(|res| match res { + Ok(ref hash) if removed.contains(hash) => Err(error::Error::ImmediatelyDropped.into()), + other => other, + }).collect() + } + + /// Submit single pre-validated transaction to the pool. + fn submit_one(&self, tx: ValidatedTransactionFor) -> Result, B::Error> { + match tx { + ValidatedTransaction::Valid(tx) => { + let imported = self.pool.write().import(tx)?; + + if let base::Imported::Ready { .. } = imported { + self.import_notification_sinks.lock().retain(|sink| sink.unbounded_send(()).is_ok()); + } + + let mut listener = self.listener.write(); + fire_events(&mut *listener, &imported); + Ok(imported.hash().clone()) + } + ValidatedTransaction::Invalid(err) => Err(err.into()), + ValidatedTransaction::Unknown(hash, err) => { + self.listener.write().invalid(&hash); + Err(err.into()) + } + } + } + + fn enforce_limits(&self) -> HashSet> { + let status = self.pool.read().status(); + let ready_limit = &self.options.ready; + let future_limit = &self.options.future; + + debug!(target: "txpool", "Pool Status: {:?}", status); + + if ready_limit.is_exceeded(status.ready, status.ready_bytes) + || future_limit.is_exceeded(status.future, status.future_bytes) { + // clean up the pool + let removed = { + let mut pool = self.pool.write(); + let removed = pool.enforce_limits(ready_limit, future_limit) + .into_iter().map(|x| x.hash.clone()).collect::>(); + // ban all removed transactions + self.rotator.ban(&std::time::Instant::now(), removed.iter().map(|x| x.clone())); + removed + }; + // run notifications + let mut listener = self.listener.write(); + for h in &removed { + listener.dropped(h, None); + } + + removed + } else { + Default::default() + } + } + + /// Import a single extrinsic and starts to watch their progress in the pool. + pub fn submit_and_watch( + &self, + tx: ValidatedTransactionFor, + ) -> Result, BlockHash>, B::Error> { + match tx { + ValidatedTransaction::Valid(tx) => { + let hash = self.api.hash_and_length(&tx.data).0; + let watcher = self.listener.write().create_watcher(hash); + self.submit(std::iter::once(ValidatedTransaction::Valid(tx))) + .pop() + .expect("One extrinsic passed; one result returned; qed") + .map(|_| watcher) + }, + ValidatedTransaction::Invalid(err) => Err(err.into()), + ValidatedTransaction::Unknown(_, err) => Err(err.into()), + } + } + + /// For each extrinsic, returns tags that it provides (if known), or None (if it is unknown). + pub fn extrinsics_tags(&self, extrinsics: &[ExtrinsicFor]) -> (Vec>, Vec>>) { + let hashes = extrinsics.iter().map(|extrinsic| self.api.hash_and_length(extrinsic).0).collect::>(); + let in_pool = self.pool.read().by_hash(&hashes); + ( + hashes, + in_pool.into_iter() + .map(|existing_in_pool| existing_in_pool + .map(|transaction| transaction.provides.iter().cloned() + .collect())) + .collect(), + ) + } + + /// Prunes ready transactions that provide given list of tags. + pub fn prune_tags( + &self, + tags: impl IntoIterator, + ) -> Result, ExtrinsicFor>, B::Error> { + // Perform tag-based pruning in the base pool + let status = self.pool.write().prune_tags(tags); + // Notify event listeners of all transactions + // that were promoted to `Ready` or were dropped. + { + let mut listener = self.listener.write(); + for promoted in &status.promoted { + fire_events(&mut *listener, promoted); + } + for f in &status.failed { + listener.dropped(f, None); + } + } + + Ok(status) + } + + /// Resubmit transactions that have been revalidated after prune_tags call. + pub fn resubmit_pruned( + &self, + at: &BlockId, + known_imported_hashes: impl IntoIterator> + Clone, + pruned_hashes: Vec>, + pruned_xts: Vec>, + ) -> Result<(), B::Error> { + debug_assert_eq!(pruned_hashes.len(), pruned_xts.len()); + + // Resubmit pruned transactions + let results = self.submit(pruned_xts); + + // Collect the hashes of transactions that now became invalid (meaning that they are successfully pruned). + let hashes = results + .into_iter() + .enumerate() + .filter_map(|(idx, r)| match r.map_err(error::IntoPoolError::into_pool_error) { + Err(Ok(error::Error::InvalidTransaction(_))) => Some(pruned_hashes[idx].clone()), + _ => None, + }); + // Fire `pruned` notifications for collected hashes and make sure to include + // `known_imported_hashes` since they were just imported as part of the block. + let hashes = hashes.chain(known_imported_hashes.into_iter()); + { + let header_hash = self.api.block_id_to_hash(at)? + .ok_or_else(|| error::Error::InvalidBlockId(format!("{:?}", at)).into())?; + let mut listener = self.listener.write(); + for h in hashes { + listener.pruned(header_hash, &h); + } + } + // perform regular cleanup of old transactions in the pool + // and update temporary bans. + self.clear_stale(at)?; + Ok(()) + } + + /// Removes stale transactions from the pool. + /// + /// Stale transactions are transaction beyond their longevity period. + /// Note this function does not remove transactions that are already included in the chain. + /// See `prune_tags` if you want this. + pub fn clear_stale(&self, at: &BlockId) -> Result<(), B::Error> { + let block_number = self.api.block_id_to_number(at)? + .ok_or_else(|| error::Error::InvalidBlockId(format!("{:?}", at)).into())? + .saturated_into::(); + let now = time::Instant::now(); + let to_remove = { + self.ready() + .filter(|tx| self.rotator.ban_if_stale(&now, block_number, &tx)) + .map(|tx| tx.hash.clone()) + .collect::>() + }; + let futures_to_remove: Vec> = { + let p = self.pool.read(); + let mut hashes = Vec::new(); + for tx in p.futures() { + if self.rotator.ban_if_stale(&now, block_number, &tx) { + hashes.push(tx.hash.clone()); + } + } + hashes + }; + // removing old transactions + self.remove_invalid(&to_remove); + self.remove_invalid(&futures_to_remove); + // clear banned transactions timeouts + self.rotator.clear_timeouts(&now); + + Ok(()) + } + + /// Get rotator reference. + #[cfg(test)] + pub fn rotator(&self) -> &PoolRotator> { + &self.rotator + } + + /// Get api reference. + pub fn api(&self) -> &B { + &self.api + } + + /// Return an event stream of transactions imported to the pool. + pub fn import_notification_stream(&self) -> EventStream { + let (sink, stream) = mpsc::unbounded(); + self.import_notification_sinks.lock().push(sink); + stream + } + + /// Invoked when extrinsics are broadcasted. + pub fn on_broadcasted(&self, propagated: HashMap, Vec>) { + let mut listener = self.listener.write(); + for (hash, peers) in propagated.into_iter() { + listener.broadcasted(&hash, peers); + } + } + + /// Remove from the pool. + pub fn remove_invalid(&self, hashes: &[ExHash]) -> Vec> { + // temporarily ban invalid transactions + debug!(target: "txpool", "Banning invalid transactions: {:?}", hashes); + self.rotator.ban(&time::Instant::now(), hashes.iter().cloned()); + + let invalid = self.pool.write().remove_invalid(hashes); + + let mut listener = self.listener.write(); + for tx in &invalid { + listener.invalid(&tx.hash); + } + + invalid + } + + /// Get an iterator for ready transactions ordered by priority + pub fn ready(&self) -> impl Iterator> { + self.pool.read().ready() + } + + /// Returns pool status. + pub fn status(&self) -> base::Status { + self.pool.read().status() + } +} + +fn fire_events( + listener: &mut Listener, + imported: &base::Imported, +) where + H: hash::Hash + Eq + traits::Member + Serialize, + H2: Clone, +{ + match *imported { + base::Imported::Ready { ref promoted, ref failed, ref removed, ref hash } => { + listener.ready(hash, None); + for f in failed { + listener.invalid(f); + } + for r in removed { + listener.dropped(&r.hash, Some(hash)); + } + for p in promoted { + listener.ready(p, None); + } + }, + base::Imported::Future { ref hash } => { + listener.future(hash) + }, + } +} diff --git a/core/transaction-pool/graph/src/watcher.rs b/core/transaction-pool/graph/src/watcher.rs index 44ab8431e8f612b7d5225aa452f5b13af7b41582..11d6b9f40742a3837ea66a3a926c90005fa51b0a 100644 --- a/core/transaction-pool/graph/src/watcher.rs +++ b/core/transaction-pool/graph/src/watcher.rs @@ -18,7 +18,7 @@ use futures::{ Stream, - sync::mpsc, + channel::mpsc, }; use serde::{Serialize, Deserialize}; @@ -60,9 +60,8 @@ impl Watcher { /// Pipe the notifications to given sink. /// /// Make sure to drive the future to completion. - pub fn into_stream(self) -> impl Stream, Error=()> { - // we can safely ignore the error here, `UnboundedReceiver` never fails. - self.receiver.map_err(|_| ()) + pub fn into_stream(self) -> impl Stream> { + self.receiver } } diff --git a/core/transaction-pool/src/api.rs b/core/transaction-pool/src/api.rs index c0c4c787a5012d652ff1aac873f483331d304da5..96403bd3f876f63e044d9a29279554de741bab2c 100644 --- a/core/transaction-pool/src/api.rs +++ b/core/transaction-pool/src/api.rs @@ -37,24 +37,24 @@ use sr_primitives::{ use crate::error; /// The transaction pool logic -pub struct ChainApi { +pub struct FullChainApi { client: Arc, _marker: PhantomData, } -impl ChainApi where +impl FullChainApi where Block: traits::Block, T: traits::ProvideRuntimeApi + HeaderBackend { /// Create new transaction pool logic. pub fn new(client: Arc) -> Self { - ChainApi { + FullChainApi { client, _marker: Default::default() } } } -impl txpool::ChainApi for ChainApi where +impl txpool::ChainApi for FullChainApi where Block: traits::Block, T: traits::ProvideRuntimeApi + HeaderBackend, T::Api: TaggedTransactionQueue @@ -62,9 +62,14 @@ impl txpool::ChainApi for ChainApi where type Block = Block; type Hash = H256; type Error = error::Error; + type ValidationFuture = futures::future::Ready>; - fn validate_transaction(&self, at: &BlockId, uxt: txpool::ExtrinsicFor) -> error::Result { - Ok(self.client.runtime_api().validate_transaction(at, uxt)?) + fn validate_transaction( + &self, + at: &BlockId, + uxt: txpool::ExtrinsicFor, + ) -> Self::ValidationFuture { + futures::future::ready(self.client.runtime_api().validate_transaction(at, uxt).map_err(Into::into)) } fn block_id_to_number(&self, at: &BlockId) -> error::Result>> { diff --git a/core/transaction-pool/src/lib.rs b/core/transaction-pool/src/lib.rs index 1899c601b2fdbbc8b73aac524c5bd030026615e5..6938166299d852ccf53459f09f326bb42a2c3557 100644 --- a/core/transaction-pool/src/lib.rs +++ b/core/transaction-pool/src/lib.rs @@ -25,5 +25,5 @@ mod tests; pub mod error; -pub use api::ChainApi; +pub use api::FullChainApi; pub use txpool; diff --git a/core/transaction-pool/src/tests.rs b/core/transaction-pool/src/tests.rs index 71ed988e5e7b34901cd46d42ca1f6f3bb086e9fe..d1ad27dd260f038cb2b33088cca1348921b02d24 100644 --- a/core/transaction-pool/src/tests.rs +++ b/core/transaction-pool/src/tests.rs @@ -18,6 +18,7 @@ use super::*; use codec::Encode; +use futures::executor::block_on; use txpool::{self, Pool}; use test_client::{runtime::{AccountId, Block, Hash, Index, Extrinsic, Transfer}, AccountKeyring::{self, *}}; use sr_primitives::{ @@ -38,8 +39,13 @@ impl txpool::ChainApi for TestApi { type Block = Block; type Hash = Hash; type Error = error::Error; + type ValidationFuture = futures::future::Ready>; - fn validate_transaction(&self, at: &BlockId, uxt: txpool::ExtrinsicFor) -> error::Result { + fn validate_transaction( + &self, + at: &BlockId, + uxt: txpool::ExtrinsicFor, + ) -> Self::ValidationFuture { let expected = index(at); let requires = if expected == uxt.transfer().nonce { vec![] @@ -48,13 +54,15 @@ impl txpool::ChainApi for TestApi { }; let provides = vec![vec![uxt.transfer().nonce as u8]]; - Ok(TransactionValidity::Valid(ValidTransaction { - priority: 1, - requires, - provides, - longevity: 64, - propagate: true, - })) + futures::future::ready(Ok( + Ok(ValidTransaction { + priority: 1, + requires, + provides, + longevity: 64, + propagate: true, + }) + )) } fn block_id_to_number(&self, at: &BlockId) -> error::Result>> { @@ -105,7 +113,7 @@ fn pool() -> Pool { fn submission_should_work() { let pool = pool(); assert_eq!(209, index(&BlockId::number(0))); - pool.submit_one(&BlockId::number(0), uxt(Alice, 209)).unwrap(); + block_on(pool.submit_one(&BlockId::number(0), uxt(Alice, 209))).unwrap(); let pending: Vec<_> = pool.ready().map(|a| a.data.transfer().nonce).collect(); assert_eq!(pending, vec![209]); @@ -114,8 +122,8 @@ fn submission_should_work() { #[test] fn multiple_submission_should_work() { let pool = pool(); - pool.submit_one(&BlockId::number(0), uxt(Alice, 209)).unwrap(); - pool.submit_one(&BlockId::number(0), uxt(Alice, 210)).unwrap(); + block_on(pool.submit_one(&BlockId::number(0), uxt(Alice, 209))).unwrap(); + block_on(pool.submit_one(&BlockId::number(0), uxt(Alice, 210))).unwrap(); let pending: Vec<_> = pool.ready().map(|a| a.data.transfer().nonce).collect(); assert_eq!(pending, vec![209, 210]); @@ -124,7 +132,7 @@ fn multiple_submission_should_work() { #[test] fn early_nonce_should_be_culled() { let pool = pool(); - pool.submit_one(&BlockId::number(0), uxt(Alice, 208)).unwrap(); + block_on(pool.submit_one(&BlockId::number(0), uxt(Alice, 208))).unwrap(); let pending: Vec<_> = pool.ready().map(|a| a.data.transfer().nonce).collect(); assert_eq!(pending, Vec::::new()); @@ -134,11 +142,11 @@ fn early_nonce_should_be_culled() { fn late_nonce_should_be_queued() { let pool = pool(); - pool.submit_one(&BlockId::number(0), uxt(Alice, 210)).unwrap(); + block_on(pool.submit_one(&BlockId::number(0), uxt(Alice, 210))).unwrap(); let pending: Vec<_> = pool.ready().map(|a| a.data.transfer().nonce).collect(); assert_eq!(pending, Vec::::new()); - pool.submit_one(&BlockId::number(0), uxt(Alice, 209)).unwrap(); + block_on(pool.submit_one(&BlockId::number(0), uxt(Alice, 209))).unwrap(); let pending: Vec<_> = pool.ready().map(|a| a.data.transfer().nonce).collect(); assert_eq!(pending, vec![209, 210]); } @@ -146,13 +154,13 @@ fn late_nonce_should_be_queued() { #[test] fn prune_tags_should_work() { let pool = pool(); - pool.submit_one(&BlockId::number(0), uxt(Alice, 209)).unwrap(); - pool.submit_one(&BlockId::number(0), uxt(Alice, 210)).unwrap(); + block_on(pool.submit_one(&BlockId::number(0), uxt(Alice, 209))).unwrap(); + block_on(pool.submit_one(&BlockId::number(0), uxt(Alice, 210))).unwrap(); let pending: Vec<_> = pool.ready().map(|a| a.data.transfer().nonce).collect(); assert_eq!(pending, vec![209, 210]); - pool.prune_tags(&BlockId::number(1), vec![vec![209]], vec![]).unwrap(); + block_on(pool.prune_tags(&BlockId::number(1), vec![vec![209]], vec![])).unwrap(); let pending: Vec<_> = pool.ready().map(|a| a.data.transfer().nonce).collect(); assert_eq!(pending, vec![210]); @@ -162,14 +170,14 @@ fn prune_tags_should_work() { fn should_ban_invalid_transactions() { let pool = pool(); let uxt = uxt(Alice, 209); - let hash = pool.submit_one(&BlockId::number(0), uxt.clone()).unwrap(); + let hash = block_on(pool.submit_one(&BlockId::number(0), uxt.clone())).unwrap(); pool.remove_invalid(&[hash]); - pool.submit_one(&BlockId::number(0), uxt.clone()).unwrap_err(); + block_on(pool.submit_one(&BlockId::number(0), uxt.clone())).unwrap_err(); // when let pending: Vec<_> = pool.ready().map(|a| a.data.transfer().nonce).collect(); assert_eq!(pending, Vec::::new()); // then - pool.submit_one(&BlockId::number(0), uxt.clone()).unwrap_err(); + block_on(pool.submit_one(&BlockId::number(0), uxt.clone())).unwrap_err(); } diff --git a/core/trie/Cargo.toml b/core/trie/Cargo.toml index 82945d90f33d7d49aec9f4a150cd31bfd4629181..50498a17ba65dda363f79496b4d8e515811d1d8b 100644 --- a/core/trie/Cargo.toml +++ b/core/trie/Cargo.toml @@ -3,7 +3,7 @@ name = "substrate-trie" version = "2.0.0" authors = ["Parity Technologies "] description = "Patricia trie stuff using a parity-scale-codec node format" -repository = "https://github.com/paritytech/parity-common" +repository = "https://github.com/paritytech/substrate" license = "GPL-3.0" edition = "2018" @@ -14,18 +14,18 @@ harness = false [dependencies] codec = { package = "parity-scale-codec", version = "1.0.0", default-features = false } rstd = { package = "sr-std", path = "../sr-std", default-features = false } -hash-db = { version = "0.15.0", default-features = false } -trie-db = { version = "0.15.0", default-features = false } -trie-root = { version = "0.15.0", default-features = false } -memory-db = { version = "0.15.0", default-features = false } +hash-db = { version = "0.15.2", default-features = false } +trie-db = { version = "0.15.2", default-features = false } +trie-root = { version = "0.15.2", default-features = false } +memory-db = { version = "0.15.2", default-features = false } primitives = { package = "substrate-primitives", path = "../primitives", default-features = false } [dev-dependencies] -trie-bench = { version = "0.16.0" } -trie-standardmap = { version = "0.15.0" } -keccak-hasher = { version = "0.15.0" } -criterion = "0.2" -hex-literal = "0.2.0" +trie-bench = "0.16.2" +trie-standardmap = "0.15.2" +keccak-hasher = "0.15.2" +criterion = "0.2.11" +hex-literal = "0.2.1" [features] default = ["std"] diff --git a/core/trie/src/lib.rs b/core/trie/src/lib.rs index e526a27ebefba5f152b4aee379cfb4ec73bf7142..eab05bab28af016ed9d9c092d832f97ad69b6122 100644 --- a/core/trie/src/lib.rs +++ b/core/trie/src/lib.rs @@ -33,15 +33,15 @@ pub use trie_stream::TrieStream; /// The Substrate format implementation of `NodeCodec`. pub use node_codec::NodeCodec; /// Various re-exports from the `trie-db` crate. -pub use trie_db::{Trie, TrieMut, DBValue, Recorder, CError, - Query, TrieLayout, TrieConfiguration, nibble_ops}; +pub use trie_db::{ + Trie, TrieMut, DBValue, Recorder, CError, Query, TrieLayout, TrieConfiguration, nibble_ops, +}; /// Various re-exports from the `memory-db` crate. pub use memory_db::KeyFunction; pub use memory_db::prefixed_key; /// Various re-exports from the `hash-db` crate. pub use hash_db::{HashDB as HashDBT, EMPTY_PREFIX}; - #[derive(Default)] /// substrate trie layout pub struct Layout(rstd::marker::PhantomData); @@ -166,25 +166,6 @@ pub fn read_trie_value_with< Ok(TrieDB::::new(&*db, root)?.get_with(key, query).map(|x| x.map(|val| val.to_vec()))?) } -/// Determine whether a child trie key is valid. -/// -/// For now, the only valid child trie key is `:child_storage:default:`. -/// -/// `child_trie_root` and `child_delta_trie_root` can panic if invalid value is provided to them. -pub fn is_child_trie_key_valid(storage_key: &[u8]) -> bool { - use primitives::storage::well_known_keys; - let has_right_prefix = storage_key.starts_with(b":child_storage:default:"); - if has_right_prefix { - // This is an attempt to catch a change of `is_child_storage_key`, which - // just checks if the key has prefix `:child_storage:` at the moment of writing. - debug_assert!( - well_known_keys::is_child_storage_key(&storage_key), - "`is_child_trie_key_valid` is a subset of `is_child_storage_key`", - ); - } - has_right_prefix -} - /// Determine the default child trie root. pub fn default_child_trie_root(_storage_key: &[u8]) -> Vec { L::trie_root::<_, Vec, Vec>(core::iter::empty()).as_ref().iter().cloned().collect() diff --git a/core/utils/fork-tree/src/lib.rs b/core/utils/fork-tree/src/lib.rs index 5a7480e0651aa0ca1c803e0105c5bdf4db2883a3..f192ee54785b18c402e321500a93f17f6aa9aba1 100644 --- a/core/utils/fork-tree/src/lib.rs +++ b/core/utils/fork-tree/src/lib.rs @@ -86,55 +86,46 @@ impl ForkTree where N: Ord + Clone, V: Clone, { - /// Prune all nodes that are not descendents of `hash` according to - /// `is_descendent_of`. The given function `is_descendent_of` should return - /// `true` if the second hash (target) is a descendent of the first hash - /// (base). After pruning the tree it should have one or zero roots. The - /// number and order of calls to `is_descendent_of` is unspecified and - /// subject to change. - pub fn prune( + /// Prune the tree, removing all non-canonical nodes. We find the node in the + /// tree that is the deepest ancestor of the given hash and that passes the + /// given predicate. If such a node exists, we re-root the tree to this + /// node. Otherwise the tree remains unchanged. The given function + /// `is_descendent_of` should return `true` if the second hash (target) is a + /// descendent of the first hash (base). + pub fn prune( &mut self, hash: &H, - number: N, - is_descendent_of: &F + number: &N, + is_descendent_of: &F, + predicate: &P, ) -> Result<(), Error> where E: std::error::Error, - F: Fn(&H, &H) -> Result + F: Fn(&H, &H) -> Result, + P: Fn(&V) -> bool, { - let mut new_root = None; - for node in self.node_iter() { - // if the node has a lower number than the one being finalized then - // we only keep if it has no children and the finalized block is a - // descendent of this node - if node.number < number { - if !node.children.is_empty() || !is_descendent_of(&node.hash, hash)? { - continue; - } - } - - // if the node has the same number as the finalized block then it - // must have the same hash - if node.number == number && node.hash != *hash { - continue; - } + let new_root = self.find_node_where( + hash, + number, + is_descendent_of, + predicate, + )?; - // if the node has a higher number then we keep it if it is a - // descendent of the finalized block - if node.number > number && !is_descendent_of(hash, &node.hash)? { - continue; - } + if let Some(root) = new_root { + let mut root = root.clone(); - new_root = Some(node); - break; - } + // we found the deepest ancestor of the finalized block, so we prune + // out any children that don't include the finalized block. + let children = std::mem::replace(&mut root.children, Vec::new()); + root.children = children.into_iter().filter(|node| { + node.number == *number && node.hash == *hash || + node.number < *number && is_descendent_of(&node.hash, hash).unwrap_or(false) + }).take(1).collect(); - if let Some(root) = new_root { - self.roots = vec![root.clone()]; + self.roots = vec![root]; } Ok(()) } - } impl ForkTree where @@ -153,6 +144,8 @@ impl ForkTree where /// should return `true` if the second hash (target) is a descendent of the /// first hash (base). This method assumes that nodes in the same branch are /// imported in order. + /// + /// Returns `true` if the imported node is a root. pub fn import( &mut self, mut hash: H, @@ -208,7 +201,7 @@ impl ForkTree where self.node_iter().map(|node| (&node.hash, &node.number, &node.data)) } - /// Find a node in the tree that is the lowest ancestor of the given + /// Find a node in the tree that is the deepest ancestor of the given /// block hash and which passes the given predicate. The given function /// `is_descendent_of` should return `true` if the second hash (target) /// is a descendent of the first hash (base). @@ -228,8 +221,8 @@ impl ForkTree where let node = root.find_node_where(hash, number, is_descendent_of, predicate)?; // found the node, early exit - if let Some(node) = node { - return Ok(node); + if let FindOutcome::Found(node) = node { + return Ok(Some(node)); } } @@ -240,14 +233,16 @@ impl ForkTree where /// with the given hash exists. All other roots are pruned, and the children /// of the finalized node become the new roots. pub fn finalize_root(&mut self, hash: &H) -> Option { - if let Some(position) = self.roots.iter().position(|node| node.hash == *hash) { - let node = self.roots.swap_remove(position); - self.roots = node.children; - self.best_finalized_number = Some(node.number); - return Some(node.data); - } + self.roots.iter().position(|node| node.hash == *hash) + .map(|position| self.finalize_root_at(position)) + } - None + /// Finalize root at given positiion. See `finalize_root` comment for details. + fn finalize_root_at(&mut self, position: usize) -> V { + let node = self.roots.swap_remove(position); + self.roots = node.children; + self.best_finalized_number = Some(node.number); + return node.data; } /// Finalize a node in the tree. This method will make sure that the node @@ -305,6 +300,79 @@ impl ForkTree where } } + /// Finalize a node in the tree and all its ancestors. The given function + /// `is_descendent_of` should return `true` if the second hash (target) is + // a descendent of the first hash (base). + pub fn finalize_with_ancestors( + &mut self, + hash: &H, + number: N, + is_descendent_of: &F, + ) -> Result, Error> + where E: std::error::Error, + F: Fn(&H, &H) -> Result + { + if let Some(ref best_finalized_number) = self.best_finalized_number { + if number <= *best_finalized_number { + return Err(Error::Revert); + } + } + + // check if one of the current roots is being finalized + if let Some(root) = self.finalize_root(hash) { + return Ok(FinalizationResult::Changed(Some(root))); + } + + // we need to: + // 1) remove all roots that are not ancestors AND not descendants of finalized block; + // 2) if node is descendant - just leave it; + // 3) if node is ancestor - 'open it' + let mut changed = false; + let mut idx = 0; + while idx != self.roots.len() { + let (is_finalized, is_descendant, is_ancestor) = { + let root = &self.roots[idx]; + let is_finalized = root.hash == *hash; + let is_descendant = !is_finalized + && root.number > number && is_descendent_of(hash, &root.hash).unwrap_or(false); + let is_ancestor = !is_finalized && !is_descendant + && root.number < number && is_descendent_of(&root.hash, hash).unwrap_or(false); + (is_finalized, is_descendant, is_ancestor) + }; + + // if we have met finalized root - open it and return + if is_finalized { + return Ok(FinalizationResult::Changed(Some(self.finalize_root_at(idx)))); + } + + // if node is descendant of finalized block - just leave it as is + if is_descendant { + idx += 1; + continue; + } + + // if node is ancestor of finalized block - remove it and continue with children + if is_ancestor { + let root = self.roots.swap_remove(idx); + self.roots.extend(root.children); + changed = true; + continue; + } + + // if node is neither ancestor, nor descendant of the finalized block - remove it + self.roots.swap_remove(idx); + changed = true; + } + + self.best_finalized_number = Some(number); + + if changed { + Ok(FinalizationResult::Changed(None)) + } else { + Ok(FinalizationResult::Unchanged) + } + } + /// Checks if any node in the tree is finalized by either finalizing the /// node itself or a child node that's not in the tree, guaranteeing that /// the node being finalized isn't a descendent of any of the node's @@ -435,6 +503,17 @@ impl ForkTree where mod node_implementation { use super::*; + /// The outcome of a search within a node. + pub enum FindOutcome { + // this is the node we were looking for. + Found(T), + // not the node we're looking for. contains a flag indicating + // whether the node was a descendent. true implies the predicate failed. + Failure(bool), + // Abort search. + Abort, + } + #[derive(Clone, Debug, Decode, Encode, PartialEq)] pub struct Node { pub hash: H, @@ -485,9 +564,10 @@ mod node_implementation { } } - /// Find a node in the tree that is the lowest ancestor of the given - /// block hash and which passes the given predicate. The given function - /// `is_descendent_of` should return `true` if the second hash (target) + /// Find a node in the tree that is the deepest ancestor of the given + /// block hash which also passes the given predicate, backtracking + /// when the predicate fails. + /// The given function `is_descendent_of` should return `true` if the second hash (target) /// is a descendent of the first hash (base). // FIXME: it would be useful if this returned a mutable reference but // rustc can't deal with lifetimes properly. an option would be to try @@ -498,23 +578,32 @@ mod node_implementation { number: &N, is_descendent_of: &F, predicate: &P, - ) -> Result>>, Error> + ) -> Result>, Error> where E: std::error::Error, F: Fn(&H, &H) -> Result, P: Fn(&V) -> bool, { // stop searching this branch if *number < self.number { - return Ok(None); + return Ok(FindOutcome::Failure(false)); } + let mut known_descendent_of = false; + // continue depth-first search through all children for node in self.children.iter() { - let node = node.find_node_where(hash, number, is_descendent_of, predicate)?; - // found node, early exit - if node.is_some() { - return Ok(node); + match node.find_node_where(hash, number, is_descendent_of, predicate)? { + FindOutcome::Abort => return Ok(FindOutcome::Abort), + FindOutcome::Found(x) => return Ok(FindOutcome::Found(x)), + FindOutcome::Failure(true) => { + // if the block was a descendent of this child, + // then it cannot be a descendent of any others, + // so we don't search them. + known_descendent_of = true; + break; + }, + FindOutcome::Failure(false) => {}, } } @@ -522,24 +611,23 @@ mod node_implementation { // searching for is a descendent of this node then we will stop the // search here, since there aren't any more children and we found // the correct node so we don't want to backtrack. - if is_descendent_of(&self.hash, hash)? { + let is_descendent_of = known_descendent_of || is_descendent_of(&self.hash, hash)?; + if is_descendent_of { // if the predicate passes we return the node if predicate(&self.data) { - Ok(Some(Some(self))) - - // otherwise we stop the search returning `None` - } else { - Ok(Some(None)) + return Ok(FindOutcome::Found(self)); } - } else { - Ok(None) } + + // otherwise, tell our ancestor that we failed, and whether + // the block was a descendent. + Ok(FindOutcome::Failure(is_descendent_of)) } } } // Workaround for: https://github.com/rust-lang/rust/issues/34537 -use node_implementation::Node; +use node_implementation::{Node, FindOutcome}; struct ForkTreeIterator<'a, H, N, V> { stack: Vec<&'a Node>, @@ -580,23 +668,32 @@ mod test { // / - G // / / // A - F - H - I + // \ + // - L - M - N + // \ + // - O // \ // — J - K // + // (where N is not a part of fork tree) let is_descendent_of = |base: &&str, block: &&str| -> Result { - let letters = vec!["B", "C", "D", "E", "F", "G", "H", "I", "J", "K"]; + let letters = vec!["B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L"]; match (*base, *block) { ("A", b) => Ok(letters.into_iter().any(|n| n == b)), ("B", b) => Ok(b == "C" || b == "D" || b == "E"), ("C", b) => Ok(b == "D" || b == "E"), ("D", b) => Ok(b == "E"), ("E", _) => Ok(false), - ("F", b) => Ok(b == "G" || b == "H" || b == "I"), + ("F", b) => Ok(b == "G" || b == "H" || b == "I" || b == "L" || b == "M" || b == "N" || b == "O"), ("G", _) => Ok(false), - ("H", b) => Ok(b == "I"), + ("H", b) => Ok(b == "I" || b == "L" || b == "M" || b == "O"), ("I", _) => Ok(false), ("J", b) => Ok(b == "K"), ("K", _) => Ok(false), + ("L", b) => Ok(b == "M" || b == "O" || b == "N"), + ("M", b) => Ok(b == "N"), + ("N", _) => Ok(false), + ("O", _) => Ok(false), ("0", _) => Ok(true), _ => Ok(false), } @@ -614,6 +711,9 @@ mod test { tree.import("H", 3, (), &is_descendent_of).unwrap(); tree.import("I", 4, (), &is_descendent_of).unwrap(); + tree.import("L", 4, (), &is_descendent_of).unwrap(); + tree.import("M", 5, (), &is_descendent_of).unwrap(); + tree.import("O", 5, (), &is_descendent_of).unwrap(); tree.import("J", 2, (), &is_descendent_of).unwrap(); tree.import("K", 3, (), &is_descendent_of).unwrap(); @@ -770,7 +870,7 @@ mod test { assert_eq!( tree.roots().map(|(h, n, _)| (h.clone(), n.clone())).collect::>(), - vec![("I", 4)], + vec![("I", 4), ("L", 4)], ); // finalizing a node from another fork that isn't part of the tree clears the tree @@ -782,6 +882,71 @@ mod test { assert!(tree.roots.is_empty()); } + #[test] + fn finalize_with_ancestor_works() { + let (mut tree, is_descendent_of) = test_fork_tree(); + + let original_roots = tree.roots.clone(); + + // finalizing a block prior to any in the node doesn't change the tree + assert_eq!( + tree.finalize_with_ancestors(&"0", 0, &is_descendent_of), + Ok(FinalizationResult::Unchanged), + ); + + assert_eq!(tree.roots, original_roots); + + // finalizing "A" opens up three possible forks + assert_eq!( + tree.finalize_with_ancestors(&"A", 1, &is_descendent_of), + Ok(FinalizationResult::Changed(Some(()))), + ); + + assert_eq!( + tree.roots().map(|(h, n, _)| (h.clone(), n.clone())).collect::>(), + vec![("B", 2), ("F", 2), ("J", 2)], + ); + + // finalizing H: + // 1) removes roots that are not ancestors/descendants of H (B, J) + // 2) opens root that is ancestor of H (F -> G+H) + // 3) finalizes the just opened root H (H -> I + L) + assert_eq!( + tree.finalize_with_ancestors(&"H", 3, &is_descendent_of), + Ok(FinalizationResult::Changed(Some(()))), + ); + + assert_eq!( + tree.roots().map(|(h, n, _)| (h.clone(), n.clone())).collect::>(), + vec![("I", 4), ("L", 4)], + ); + + assert_eq!( + tree.best_finalized_number, + Some(3), + ); + + // finalizing N (which is not a part of the tree): + // 1) removes roots that are not ancestors/descendants of N (I) + // 2) opens root that is ancestor of N (L -> M+O) + // 3) removes roots that are not ancestors/descendants of N (O) + // 4) opens root that is ancestor of N (M -> {}) + assert_eq!( + tree.finalize_with_ancestors(&"N", 6, &is_descendent_of), + Ok(FinalizationResult::Changed(None)), + ); + + assert_eq!( + tree.roots().map(|(h, n, _)| (h.clone(), n.clone())).collect::>(), + vec![], + ); + + assert_eq!( + tree.best_finalized_number, + Some(6), + ); + } + #[test] fn finalize_with_descendent_works() { #[derive(Debug, PartialEq)] @@ -927,7 +1092,9 @@ mod test { vec![ ("A", 1), ("J", 2), ("K", 3), - ("F", 2), ("H", 3), ("I", 4), + ("F", 2), ("H", 3), ("L", 4), ("O", 5), + ("M", 5), + ("I", 4), ("G", 3), ("B", 2), ("C", 3), ("D", 4), ("E", 5), ], @@ -1027,23 +1194,41 @@ mod test { tree.prune( &"C", - 3, + &3, &is_descendent_of, + &|_| true, + ).unwrap(); + + assert_eq!( + tree.roots.iter().map(|node| node.hash).collect::>(), + vec!["B"], + ); + + assert_eq!( + tree.iter().map(|(hash, _, _)| *hash).collect::>(), + vec!["B", "C", "D", "E"], + ); + + tree.prune( + &"E", + &5, + &is_descendent_of, + &|_| true, ).unwrap(); assert_eq!( tree.roots.iter().map(|node| node.hash).collect::>(), - vec!["C"], + vec!["D"], ); assert_eq!( tree.iter().map(|(hash, _, _)| *hash).collect::>(), - vec!["C", "D", "E"], + vec!["D", "E"], ); } #[test] - fn find_node_doesnt_backtrack_after_finding_highest_descending_node() { + fn find_node_backtracks_after_finding_highest_descending_node() { let mut tree = ForkTree::new(); // @@ -1061,11 +1246,12 @@ mod test { }; tree.import("A", 1, 1, &is_descendent_of).unwrap(); - tree.import("B", 2, 4, &is_descendent_of).unwrap(); + tree.import("B", 2, 2, &is_descendent_of).unwrap(); tree.import("C", 2, 4, &is_descendent_of).unwrap(); - // when searching the tree we reach both node `B` and `C`, but the - // predicate doesn't pass. still, we should not backtrack to node `A`. + // when searching the tree we reach node `C`, but the + // predicate doesn't pass. we should backtrack to `B`, but not to `A`, + // since "B" fulfills the predicate. let node = tree.find_node_where( &"D", &3, @@ -1073,6 +1259,6 @@ mod test { &|data| *data < 3, ).unwrap(); - assert_eq!(node, None); + assert_eq!(node.unwrap().hash, "B"); } } diff --git a/core/utils/wasm-builder-runner/Cargo.toml b/core/utils/wasm-builder-runner/Cargo.toml index 4046b7e4e2f2551284fabff97501a3731c204edb..71cdbd283505d1d29bc763fb430aad1fc3d155e8 100644 --- a/core/utils/wasm-builder-runner/Cargo.toml +++ b/core/utils/wasm-builder-runner/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "substrate-wasm-builder-runner" -version = "1.0.2" +version = "1.0.3" authors = ["Parity Technologies "] description = "Runner for substrate-wasm-builder" edition = "2018" diff --git a/core/utils/wasm-builder-runner/src/lib.rs b/core/utils/wasm-builder-runner/src/lib.rs index 1558dbf22044f1e2f414a7e8c2ba73546c895cc2..1fee4a4fd7ccd6b83fc530ce17e579d79ccda484 100644 --- a/core/utils/wasm-builder-runner/src/lib.rs +++ b/core/utils/wasm-builder-runner/src/lib.rs @@ -30,9 +30,6 @@ use std::{env, process::{Command, self}, fs, path::{PathBuf, Path}}; /// Environment variable that tells us to skip building the WASM binary. const SKIP_BUILD_ENV: &str = "SKIP_WASM_BUILD"; -/// Environment variable to extend the `RUSTFLAGS` variable given to the WASM build. -const WASM_BUILD_RUSTFLAGS_ENV: &str = "WASM_BUILD_RUSTFLAGS"; - /// Environment variable that tells us to create a dummy WASM binary. /// /// This is useful for `cargo check` to speed-up the compilation. @@ -102,22 +99,8 @@ impl WasmBuilderSource { pub fn build_current_project_with_rustflags( file_name: &str, wasm_builder_source: WasmBuilderSource, - rustflags: &str, + default_rustflags: &str, ) { - let given_rustflags = env::var(WASM_BUILD_RUSTFLAGS_ENV).unwrap_or_default(); - env::set_var(WASM_BUILD_RUSTFLAGS_ENV, format!("{} {}", given_rustflags, rustflags)); - - build_current_project(file_name, wasm_builder_source) -} - -/// Build the currently built project as WASM binary. -/// -/// The current project is determined using the `CARGO_MANIFEST_DIR` environment variable. -/// -/// `file_name` - The name of the file being generated in the `OUT_DIR`. The file contains the -/// constant `WASM_BINARY` which contains the build wasm binary. -/// `wasm_builder_path` - Path to the wasm-builder project, relative to `CARGO_MANIFEST_DIR`. -pub fn build_current_project(file_name: &str, wasm_builder_source: WasmBuilderSource) { if check_skip_build() { // If we skip the build, we still want to make sure to be called when an env variable changes generate_rerun_if_changed_instructions(); @@ -133,12 +116,20 @@ pub fn build_current_project(file_name: &str, wasm_builder_source: WasmBuilderSo let cargo_toml_path = manifest_dir.join("Cargo.toml"); let out_dir = PathBuf::from(env::var("OUT_DIR").expect("`OUT_DIR` is set by cargo!")); let file_path = out_dir.join(file_name); - let project_folder = out_dir.join("wasm_build_runner"); + let project_name = env::var("CARGO_PKG_NAME").expect("`CARGO_PKG_NAME` is set by cargo!"); + let project_folder = get_workspace_root().join(project_name); if check_provide_dummy_wasm_binary() { provide_dummy_wasm_binary(&file_path); } else { - create_project(&project_folder, &file_path, &manifest_dir, wasm_builder_source, &cargo_toml_path); + create_project( + &project_folder, + &file_path, + &manifest_dir, + wasm_builder_source, + &cargo_toml_path, + default_rustflags, + ); run_project(&project_folder); } @@ -147,12 +138,43 @@ pub fn build_current_project(file_name: &str, wasm_builder_source: WasmBuilderSo generate_rerun_if_changed_instructions(); } +/// Build the currently built project as WASM binary. +/// +/// The current project is determined using the `CARGO_MANIFEST_DIR` environment variable. +/// +/// `file_name` - The name of the file being generated in the `OUT_DIR`. The file contains the +/// constant `WASM_BINARY` which contains the build wasm binary. +/// `wasm_builder_path` - Path to the wasm-builder project, relative to `CARGO_MANIFEST_DIR`. +pub fn build_current_project(file_name: &str, wasm_builder_source: WasmBuilderSource) { + build_current_project_with_rustflags(file_name, wasm_builder_source, ""); +} + +/// Returns the root path of the wasm-builder-runner workspace. +/// +/// The wasm-builder-runner workspace contains all wasm-builder-runner's projects. +fn get_workspace_root() -> PathBuf { + let out_dir_env = env::var("OUT_DIR").expect("`OUT_DIR` is set by cargo!"); + let mut out_dir = PathBuf::from(&out_dir_env); + + loop { + match out_dir.parent() { + Some(parent) if out_dir.ends_with("build") => return parent.join("wbuild-runner"), + _ => if !out_dir.pop() { + break; + } + } + } + + panic!("Could not find target dir in: {}", out_dir_env) +} + fn create_project( project_folder: &Path, file_path: &Path, manifest_dir: &Path, wasm_builder_source: WasmBuilderSource, cargo_toml_path: &Path, + default_rustflags: &str, ) { fs::create_dir_all(project_folder.join("src")) .expect("WASM build runner dir create can not fail; qed"); @@ -179,12 +201,19 @@ fn create_project( project_folder.join("src/main.rs"), format!( r#" + use substrate_wasm_builder::build_project_with_default_rustflags; + fn main() {{ - substrate_wasm_builder::build_project("{file_path}", "{cargo_toml_path}") + build_project_with_default_rustflags( + "{file_path}", + "{cargo_toml_path}", + "{default_rustflags}", + ) }} "#, file_path = replace_back_slashes(file_path.display()), cargo_toml_path = replace_back_slashes(cargo_toml_path.display()), + default_rustflags = default_rustflags, ) ).expect("WASM build runner `main.rs` writing can not fail; qed"); } diff --git a/core/utils/wasm-builder/Cargo.toml b/core/utils/wasm-builder/Cargo.toml index 44288dbcd268f97844230cc9b9f5a701cfcaac9f..bbcfe2ff5288180ec58d4dc53fa060e88dffe79d 100644 --- a/core/utils/wasm-builder/Cargo.toml +++ b/core/utils/wasm-builder/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "substrate-wasm-builder" -version = "1.0.4" +version = "1.0.7" authors = ["Parity Technologies "] description = "Utility for building WASM binaries" edition = "2018" @@ -10,8 +10,8 @@ license = "GPL-3.0" [dependencies] build-helper = "0.1.1" -cargo_metadata = "0.8" +cargo_metadata = "0.8.2" tempfile = "3.1.0" -toml = "0.5.1" -walkdir = "2.2.8" +toml = "0.5.3" +walkdir = "2.2.9" fs2 = "0.4.3" diff --git a/core/utils/wasm-builder/README.md b/core/utils/wasm-builder/README.md index 8a8c67d6a8c1d164e10d1d4f68a714d83086f5d9..0f3d933a2f774671d1cfa44d4a918a80b0bed725 100644 --- a/core/utils/wasm-builder/README.md +++ b/core/utils/wasm-builder/README.md @@ -9,7 +9,6 @@ A project that should be compiled as a WASM binary needs to: 1. Add a `build.rs` file. 2. Add `substrate-wasm-builder-runner` as dependency into `build-dependencies`. -3. Add a feature called `no-std`. The `build.rs` file needs to contain the following code: @@ -26,8 +25,6 @@ fn main() { } ``` -The `no-std` feature will be enabled by WASM builder while compiling your project to WASM. - As the final step, you need to add the following to your project: ```rust diff --git a/core/utils/wasm-builder/src/lib.rs b/core/utils/wasm-builder/src/lib.rs index 5bb0342c665dec533f79c0603b903ef4b4dcbd63..6f7687f446bf175dcd75c0b49413400e69fe4117 100644 --- a/core/utils/wasm-builder/src/lib.rs +++ b/core/utils/wasm-builder/src/lib.rs @@ -25,7 +25,6 @@ //! //! 1. Add a `build.rs` file. //! 2. Add `substrate-wasm-builder-runner` as dependency into `build-dependencies`. -//! 3. Add a feature called `no-std`. //! //! The `build.rs` file needs to contain the following code: //! @@ -42,8 +41,6 @@ //! } //! ``` //! -//! The `no-std` feature will be enabled by WASM builder while compiling your project to WASM. -//! //! As the final step, you need to add the following to your project: //! //! ```ignore @@ -66,6 +63,8 @@ //! needs to change. As WASM builder instructs `cargo` to watch for file changes //! this environment variable should only be required in certain circumstances. //! - `WASM_BUILD_RUSTFLAGS` - Extend `RUSTFLAGS` given to `cargo build` while building the WASM binary. +//! - `WASM_TARGET_DIRECTORY` - Will copy any build WASM binary to the given directory. The path needs +//! to be absolute. //! //! Each project can be skipped individually by using the environment variable `SKIP_PROJECT_NAME_WASM_BUILD`. //! Where `PROJECT_NAME` needs to be replaced by the name of the cargo project, e.g. `node-runtime` will @@ -96,6 +95,11 @@ const WASM_BUILD_TYPE_ENV: &str = "WASM_BUILD_TYPE"; /// Environment variable to extend the `RUSTFLAGS` variable given to the WASM build. const WASM_BUILD_RUSTFLAGS_ENV: &str = "WASM_BUILD_RUSTFLAGS"; +/// Environment variable to set the target directory to copy the final WASM binary. +/// +/// The directory needs to be an absolute path. +const WASM_TARGET_DIRECTORY: &str = "WASM_TARGET_DIRECTORY"; + /// Build the currently built project as WASM binary. /// /// The current project is determined by using the `CARGO_MANIFEST_DIR` environment variable. @@ -104,6 +108,22 @@ const WASM_BUILD_RUSTFLAGS_ENV: &str = "WASM_BUILD_RUSTFLAGS"; /// constant `WASM_BINARY`, which contains the built WASM binary. /// `cargo_manifest` - The path to the `Cargo.toml` of the project that should be built. pub fn build_project(file_name: &str, cargo_manifest: &str) { + build_project_with_default_rustflags(file_name, cargo_manifest, ""); +} + +/// Build the currently built project as WASM binary. +/// +/// The current project is determined by using the `CARGO_MANIFEST_DIR` environment variable. +/// +/// `file_name` - The name + path of the file being generated. The file contains the +/// constant `WASM_BINARY`, which contains the built WASM binary. +/// `cargo_manifest` - The path to the `Cargo.toml` of the project that should be built. +/// `default_rustflags` - Default `RUSTFLAGS` that will always be set for the build. +pub fn build_project_with_default_rustflags( + file_name: &str, + cargo_manifest: &str, + default_rustflags: &str, +) { if check_skip_build() { return; } @@ -123,10 +143,13 @@ pub fn build_project(file_name: &str, cargo_manifest: &str) { process::exit(1); } - let (wasm_binary, bloaty) = wasm_project::create_and_compile(&cargo_manifest); + let (wasm_binary, bloaty) = wasm_project::create_and_compile( + &cargo_manifest, + default_rustflags, + ); - create_out_file( - file_name, + write_file_if_changed( + file_name.into(), format!( r#" pub const WASM_BINARY: &[u8] = include_bytes!("{wasm_binary}"); @@ -143,11 +166,11 @@ fn check_skip_build() -> bool { env::var(SKIP_BUILD_ENV).is_ok() } -fn create_out_file(file_name: &str, content: String) { - fs::write( - file_name, - content - ).expect("Creating and writing can not fail; qed"); +/// Write to the given `file` if the `content` is different. +fn write_file_if_changed(file: PathBuf, content: String) { + if fs::read_to_string(&file).ok().as_ref() != Some(&content) { + fs::write(&file, content).expect(&format!("Writing `{}` can not fail!", file.display())); + } } /// Get a cargo command that compiles with nightly diff --git a/core/utils/wasm-builder/src/prerequisites.rs b/core/utils/wasm-builder/src/prerequisites.rs index 52ff40887cfd829074458134f37794453ee481a1..eeac6df33e3d6b5d2b083d2fa2a46c6824402626 100644 --- a/core/utils/wasm-builder/src/prerequisites.rs +++ b/core/utils/wasm-builder/src/prerequisites.rs @@ -36,11 +36,7 @@ pub fn check() -> Option<&'static str> { return Some("`wasm-gc` not installed, please install it!") } - if !check_wasm_toolchain_installed() { - return Some("Rust WASM toolchain not installed, please install it!") - } - - None + check_wasm_toolchain_installed() } fn check_nightly_installed() -> bool { @@ -48,7 +44,7 @@ fn check_nightly_installed() -> bool { command.is_nightly() } -fn check_wasm_toolchain_installed() -> bool { +fn check_wasm_toolchain_installed() -> Option<&'static str> { let temp = tempdir().expect("Creating temp dir does not fail; qed"); fs::create_dir_all(temp.path().join("src")).expect("Creating src dir does not fail; qed"); @@ -72,13 +68,24 @@ fn check_wasm_toolchain_installed() -> bool { fs::write(&test_file, "pub fn test() {}") .expect("Writing to the test file does not fail; qed"); + let err_msg = "Rust WASM toolchain not installed, please install it!"; let manifest_path = manifest_path.display().to_string(); crate::get_nightly_cargo() .command() .args(&["build", "--target=wasm32-unknown-unknown", "--manifest-path", &manifest_path]) - .stdout(Stdio::null()) - .stderr(Stdio::null()) - .status() - .map(|s| s.success()) - .unwrap_or(false) + .output() + .map_err(|_| err_msg) + .and_then(|s| + if s.status.success() { + Ok(()) + } else { + match String::from_utf8(s.stderr) { + Ok(ref err) if err.contains("linker `rust-lld` not found") => { + Err("`rust-lld` not found, please install it!") + }, + _ => Err(err_msg) + } + } + ) + .err() } diff --git a/core/utils/wasm-builder/src/wasm_project.rs b/core/utils/wasm-builder/src/wasm_project.rs index 4bc908114cf4612c655692e2fc90d46b26b48d8a..afe6faa07051c10f715b98c54f833c81bbc7f64d 100644 --- a/core/utils/wasm-builder/src/wasm_project.rs +++ b/core/utils/wasm-builder/src/wasm_project.rs @@ -14,6 +14,8 @@ // You should have received a copy of the GNU General Public License // along with Substrate. If not, see . +use crate::write_file_if_changed; + use std::{fs, path::{Path, PathBuf}, borrow::ToOwned, process::{Command, self}, env}; use toml::value::Table; @@ -75,7 +77,10 @@ impl Drop for WorkspaceLock { /// /// # Returns /// The path to the compact WASM binary and the bloaty WASM binary. -pub fn create_and_compile(cargo_manifest: &Path) -> (WasmBinary, WasmBinaryBloaty) { +pub fn create_and_compile( + cargo_manifest: &Path, + default_rustflags: &str, +) -> (WasmBinary, WasmBinaryBloaty) { let wasm_workspace_root = get_wasm_workspace_root(); let wasm_workspace = wasm_workspace_root.join("wbuild"); @@ -83,10 +88,16 @@ pub fn create_and_compile(cargo_manifest: &Path) -> (WasmBinary, WasmBinaryBloat let _lock = WorkspaceLock::new(&wasm_workspace_root); let project = create_project(cargo_manifest, &wasm_workspace); - create_wasm_workspace_project(&wasm_workspace); + create_wasm_workspace_project(&wasm_workspace, cargo_manifest); - build_project(&project); - let (wasm_binary, bloaty) = compact_wasm_file(&project, cargo_manifest, &wasm_workspace); + build_project(&project, default_rustflags); + let (wasm_binary, bloaty) = compact_wasm_file( + &project, + cargo_manifest, + &wasm_workspace, + ); + + copy_wasm_to_target_directory(cargo_manifest, &wasm_binary); generate_rerun_if_changed_instructions(cargo_manifest, &project, &wasm_workspace); @@ -122,6 +133,7 @@ fn find_cargo_lock(cargo_manifest: &Path) -> Option { cargo_manifest.display(), build_helper::out_dir().display() ); + None } @@ -160,7 +172,7 @@ fn get_wasm_workspace_root() -> PathBuf { panic!("Could not find target dir in: {}", build_helper::out_dir().display()) } -fn create_wasm_workspace_project(wasm_workspace: &Path) { +fn create_wasm_workspace_project(wasm_workspace: &Path, cargo_manifest: &Path) { let members = WalkDir::new(wasm_workspace) .min_depth(1) .max_depth(1) @@ -169,25 +181,66 @@ fn create_wasm_workspace_project(wasm_workspace: &Path) { .map(|d| d.into_path()) .filter(|p| p.is_dir() && !p.ends_with("target")) .filter_map(|p| p.file_name().map(|f| f.to_owned()).and_then(|s| s.into_string().ok())) - .map(|s| format!("\"{}\", ", s)) - .collect::(); + .collect::>(); + + let crate_metadata = MetadataCommand::new() + .manifest_path(cargo_manifest) + .exec() + .expect("`cargo metadata` can not fail on project `Cargo.toml`; qed"); + let workspace_root_path = crate_metadata.workspace_root; + + let mut workspace_toml: Table = toml::from_str( + &fs::read_to_string( + workspace_root_path.join("Cargo.toml"), + ).expect("Workspace root `Cargo.toml` exists; qed") + ).expect("Workspace root `Cargo.toml` is a valid toml file; qed"); + + let mut wasm_workspace_toml = Table::new(); + + // Add `profile` with release and dev + let mut release_profile = Table::new(); + release_profile.insert("panic".into(), "abort".into()); + release_profile.insert("lto".into(), true.into()); + + let mut dev_profile = Table::new(); + dev_profile.insert("panic".into(), "abort".into()); + + let mut profile = Table::new(); + profile.insert("release".into(), release_profile.into()); + profile.insert("dev".into(), dev_profile.into()); + + wasm_workspace_toml.insert("profile".into(), profile.into()); + + // Add `workspace` with members + let mut workspace = Table::new(); + workspace.insert("members".into(), members.into()); + + wasm_workspace_toml.insert("workspace".into(), workspace.into()); + + // Add patch section from the project root `Cargo.toml` + if let Some(mut patch) = workspace_toml.remove("patch").and_then(|p| p.try_into::().ok()) { + // Iterate over all patches and make the patch path absolute from the workspace root path. + patch.iter_mut() + .filter_map(|p| + p.1.as_table_mut().map(|t| t.iter_mut().filter_map(|t| t.1.as_table_mut())) + ) + .flatten() + .for_each(|p| + p.iter_mut() + .filter(|(k, _)| k == &"path") + .for_each(|(_, v)| { + if let Some(path) = v.as_str() { + *v = workspace_root_path.join(path).display().to_string().into(); + } + }) + ); + + wasm_workspace_toml.insert("patch".into(), patch.into()); + } fs::write( wasm_workspace.join("Cargo.toml"), - format!( - r#" - [profile.release] - panic = "abort" - lto = true - - [profile.dev] - panic = "abort" - - [workspace] - members = [ {members} ] - "#, - members = members, - ) + toml::to_string_pretty(&wasm_workspace_toml).expect("Wasm workspace toml is valid; qed"), ).expect("WASM workspace `Cargo.toml` writing can not fail; qed"); } @@ -203,7 +256,7 @@ fn create_project(cargo_manifest: &Path, wasm_workspace: &Path) -> PathBuf { fs::create_dir_all(project_folder.join("src")).expect("Wasm project dir create can not fail; qed"); - fs::write( + write_file_if_changed( project_folder.join("Cargo.toml"), format!( r#" @@ -217,18 +270,18 @@ fn create_project(cargo_manifest: &Path, wasm_workspace: &Path) -> PathBuf { crate-type = ["cdylib"] [dependencies] - wasm_project = {{ package = "{crate_name}", path = "{crate_path}", default-features = false, features = [ "no_std" ] }} + wasm_project = {{ package = "{crate_name}", path = "{crate_path}", default-features = false }} "#, crate_name = crate_name, crate_path = crate_path.display(), wasm_binary = wasm_binary, ) - ).expect("Project `Cargo.toml` writing can not fail; qed"); + ); - fs::write( + write_file_if_changed( project_folder.join("src/lib.rs"), - "#![no_std] pub use wasm_project::*;", - ).expect("Project `lib.rs` writing can not fail; qed"); + "#![no_std] pub use wasm_project::*;".into(), + ); if let Some(crate_lock_file) = find_cargo_lock(cargo_manifest) { // Use the `Cargo.lock` of the main project. @@ -257,12 +310,13 @@ fn is_release_build() -> bool { } /// Build the project to create the WASM binary. -fn build_project(project: &Path) { +fn build_project(project: &Path, default_rustflags: &str) { let manifest_path = project.join("Cargo.toml"); let mut build_cmd = crate::get_nightly_cargo().command(); let rustflags = format!( - "-C link-arg=--export-table {}", + "-C link-arg=--export-table {} {}", + default_rustflags, env::var(crate::WASM_BUILD_RUSTFLAGS_ENV).unwrap_or_default(), ); @@ -349,4 +403,29 @@ fn generate_rerun_if_changed_instructions( println!("cargo:rerun-if-env-changed={}", crate::SKIP_BUILD_ENV); println!("cargo:rerun-if-env-changed={}", crate::WASM_BUILD_TYPE_ENV); println!("cargo:rerun-if-env-changed={}", crate::WASM_BUILD_RUSTFLAGS_ENV); + println!("cargo:rerun-if-env-changed={}", crate::WASM_TARGET_DIRECTORY); +} + +/// Copy the WASM binary to the target directory set in `WASM_TARGET_DIRECTORY` environment variable. +/// If the variable is not set, this is a no-op. +fn copy_wasm_to_target_directory(cargo_manifest: &Path, wasm_binary: &WasmBinary) { + let target_dir = match env::var(crate::WASM_TARGET_DIRECTORY) { + Ok(path) => PathBuf::from(path), + Err(_) => return, + }; + + if !target_dir.is_absolute() { + panic!( + "Environment variable `{}` with `{}` is not an absolute path!", + crate::WASM_TARGET_DIRECTORY, + target_dir.display(), + ); + } + + fs::create_dir_all(&target_dir).expect("Creates `WASM_TARGET_DIRECTORY`."); + + fs::copy( + wasm_binary.wasm_binary_path(), + target_dir.join(format!("{}.wasm", get_wasm_binary_name(cargo_manifest))), + ).expect("Copies WASM binary to `WASM_TARGET_DIRECTORY`."); } diff --git a/core/wasm-interface/Cargo.toml b/core/wasm-interface/Cargo.toml new file mode 100644 index 0000000000000000000000000000000000000000..b8169031d0bb6ecb6612536ea939167df1700cfe --- /dev/null +++ b/core/wasm-interface/Cargo.toml @@ -0,0 +1,8 @@ +[package] +name = "substrate-wasm-interface" +version = "2.0.0" +authors = ["Parity Technologies "] +edition = "2018" + +[dependencies] +wasmi = "0.5.1" diff --git a/core/wasm-interface/src/lib.rs b/core/wasm-interface/src/lib.rs new file mode 100644 index 0000000000000000000000000000000000000000..b3cbde556eea0dbfe6c985c089706d9469a9d1e0 --- /dev/null +++ b/core/wasm-interface/src/lib.rs @@ -0,0 +1,324 @@ +// Copyright 2019 Parity Technologies (UK) Ltd. +// This file is part of Substrate. + +// Substrate 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. + +// Substrate 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 Substrate. If not, see . + +//! Types and traits for interfacing between the host and the wasm runtime. + +use std::{borrow::Cow, marker::PhantomData, mem, iter::Iterator, result}; + +mod wasmi_impl; + +/// Result type used by traits in this crate. +pub type Result = result::Result; + +/// Value types supported by Substrate on the boundary between host/Wasm. +#[derive(Copy, Clone, PartialEq, Debug, Eq)] +pub enum ValueType { + /// An `i32` value type. + I32, + /// An `i64` value type. + I64, + /// An `f32` value type. + F32, + /// An `f64` value type. + F64, +} + +/// Values supported by Substrate on the boundary between host/Wasm. +#[derive(PartialEq, Debug, Clone, Copy)] +pub enum Value { + /// An `i32` value. + I32(i32), + /// An `i64` value. + I64(i64), + /// An nan-preserving `f32` value. + F32(u32), + /// An nan-preserving `f64` value. + F64(u64), +} + +/// Provides `Sealed` trait to prevent implementing trait `PointerType` outside of this crate. +mod private { + pub trait Sealed {} + + impl Sealed for u8 {} + impl Sealed for u16 {} + impl Sealed for u32 {} + impl Sealed for u64 {} +} + +/// Something that can be wrapped in a wasm `Pointer`. +/// +/// This trait is sealed. +pub trait PointerType: Sized { + /// The size of the type in wasm. + const SIZE: u32 = mem::size_of::() as u32; +} + +impl PointerType for u8 {} +impl PointerType for u16 {} +impl PointerType for u32 {} +impl PointerType for u64 {} + +/// Type to represent a pointer in wasm at the host. +#[derive(Debug, PartialEq, Eq, Clone, Copy)] +pub struct Pointer { + ptr: u32, + _marker: PhantomData, +} + +impl Pointer { + /// Create a new instance of `Self`. + pub fn new(ptr: u32) -> Self { + Self { + ptr, + _marker: Default::default(), + } + } + + /// Calculate the offset from this pointer. + /// + /// `offset` is in units of `T`. So, `3` means `3 * mem::size_of::()` as offset to the pointer. + /// + /// Returns an `Option` to respect that the pointer could probably overflow. + pub fn offset(self, offset: u32) -> Option { + offset.checked_mul(T::SIZE).and_then(|o| self.ptr.checked_add(o)).map(|ptr| { + Self { + ptr, + _marker: Default::default(), + } + }) + } + + /// Create a null pointer. + pub fn null() -> Self { + Self::new(0) + } + + /// Cast this pointer of type `T` to a pointer of type `R`. + pub fn cast(self) -> Pointer { + Pointer::new(self.ptr) + } +} + +impl From> for u32 { + fn from(ptr: Pointer) -> Self { + ptr.ptr + } +} + +impl From> for usize { + fn from(ptr: Pointer) -> Self { + ptr.ptr as _ + } +} + +impl IntoValue for Pointer { + const VALUE_TYPE: ValueType = ValueType::I32; + fn into_value(self) -> Value { Value::I32(self.ptr as _) } +} + +impl TryFromValue for Pointer { + fn try_from_value(val: Value) -> Option { + match val { + Value::I32(val) => Some(Self::new(val as _)), + _ => None, + } + } +} + +/// The word size used in wasm. Normally known as `usize` in Rust. +pub type WordSize = u32; + +/// The Signature of a function +#[derive(Eq, PartialEq, Debug, Clone)] +pub struct Signature { + /// The arguments of a function. + pub args: Cow<'static, [ValueType]>, + /// The optional return value of a function. + pub return_value: Option, +} + +impl Signature { + /// Create a new instance of `Signature`. + pub fn new>>(args: T, return_value: Option) -> Self { + Self { + args: args.into(), + return_value, + } + } + + /// Create a new instance of `Signature` with the given `args` and without any return value. + pub fn new_with_args>>(args: T) -> Self { + Self { + args: args.into(), + return_value: None, + } + } + +} + +/// Something that provides a function implementation on the host for a wasm function. +pub trait Function { + /// Returns the name of this function. + fn name(&self) -> &str; + /// Returns the signature of this function. + fn signature(&self) -> Signature; + /// Execute this function with the given arguments. + fn execute( + &self, + context: &mut dyn FunctionContext, + args: &mut dyn Iterator, + ) -> Result>; +} + +/// Context used by `Function` to interact with the allocator and the memory of the wasm instance. +pub trait FunctionContext { + /// Read memory from `address` into a vector. + fn read_memory(&self, address: Pointer, size: WordSize) -> Result> { + let mut vec = Vec::with_capacity(size as usize); + vec.resize(size as usize, 0); + self.read_memory_into(address, &mut vec)?; + Ok(vec) + } + /// Read memory into the given `dest` buffer from `address`. + fn read_memory_into(&self, address: Pointer, dest: &mut [u8]) -> Result<()>; + /// Write the given data at `address` into the memory. + fn write_memory(&mut self, address: Pointer, data: &[u8]) -> Result<()>; + /// Allocate a memory instance of `size` bytes. + fn allocate_memory(&mut self, size: WordSize) -> Result>; + /// Deallocate a given memory instance. + fn deallocate_memory(&mut self, ptr: Pointer) -> Result<()>; + /// Provides access to the sandbox. + fn sandbox(&mut self) -> &mut dyn Sandbox; +} + +/// Sandbox memory identifier. +pub type MemoryId = u32; + +/// Something that provides access to the sandbox. +pub trait Sandbox { + /// Get sandbox memory from the `memory_id` instance at `offset` into the given buffer. + fn memory_get( + &self, + memory_id: MemoryId, + offset: WordSize, + buf_ptr: Pointer, + buf_len: WordSize, + ) -> Result; + /// Set sandbox memory from the given value. + fn memory_set( + &mut self, + memory_id: MemoryId, + offset: WordSize, + val_ptr: Pointer, + val_len: WordSize, + ) -> Result; + /// Delete a memory instance. + fn memory_teardown(&mut self, memory_id: MemoryId) -> Result<()>; + /// Create a new memory instance with the given `initial` size and the `maximum` size. + /// The size is given in wasm pages. + fn memory_new(&mut self, initial: u32, maximum: u32) -> Result; + /// Invoke an exported function by a name. + fn invoke( + &mut self, + instance_id: u32, + export_name: &str, + args: &[u8], + return_val: Pointer, + return_val_len: WordSize, + state: u32, + ) -> Result; + /// Delete a sandbox instance. + fn instance_teardown(&mut self, instance_id: u32) -> Result<()>; + /// Create a new sandbox instance. + fn instance_new( + &mut self, + dispatch_thunk_id: u32, + wasm: &[u8], + raw_env_def: &[u8], + state: u32, + ) -> Result; +} + +/// Something that provides implementations for host functions. +pub trait HostFunctions { + /// Returns all host functions. + fn functions() -> &'static [&'static dyn Function]; +} + +/// Something that can be converted into a wasm compatible `Value`. +pub trait IntoValue { + /// The type of the value in wasm. + const VALUE_TYPE: ValueType; + + /// Convert `self` into a wasm `Value`. + fn into_value(self) -> Value; +} + +/// Something that can may be created from a wasm `Value`. +pub trait TryFromValue: Sized { + /// Try to convert the given `Value` into `Self`. + fn try_from_value(val: Value) -> Option; +} + +macro_rules! impl_into_and_from_value { + ( + $( + $type:ty, $( < $gen:ident >, )? $value_variant:ident, + )* + ) => { + $( + impl $( <$gen> )? IntoValue for $type { + const VALUE_TYPE: ValueType = ValueType::$value_variant; + fn into_value(self) -> Value { Value::$value_variant(self as _) } + } + + impl $( <$gen> )? TryFromValue for $type { + fn try_from_value(val: Value) -> Option { + match val { + Value::$value_variant(val) => Some(val as _), + _ => None, + } + } + } + )* + } +} + +impl_into_and_from_value! { + u32, I32, + i32, I32, + u64, I64, + i64, I64, +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn pointer_offset_works() { + let ptr = Pointer::::null(); + + assert_eq!(ptr.offset(10).unwrap(), Pointer::new(40)); + assert_eq!(ptr.offset(32).unwrap(), Pointer::new(128)); + + let ptr = Pointer::::null(); + + assert_eq!(ptr.offset(10).unwrap(), Pointer::new(80)); + assert_eq!(ptr.offset(32).unwrap(), Pointer::new(256)); + } +} diff --git a/core/wasm-interface/src/wasmi_impl.rs b/core/wasm-interface/src/wasmi_impl.rs new file mode 100644 index 0000000000000000000000000000000000000000..be9b724d29b74bab16905ab9b905d88cff307c54 --- /dev/null +++ b/core/wasm-interface/src/wasmi_impl.rs @@ -0,0 +1,79 @@ +// Copyright 2019 Parity Technologies (UK) Ltd. +// This file is part of Substrate. + +// Substrate 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. + +// Substrate 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 Substrate. If not, see . + +//! Implementation of conversions between Substrate and wasmi types. + +use crate::{Value, ValueType, Signature}; + +impl From for wasmi::RuntimeValue { + fn from(value: Value) -> Self { + match value { + Value::I32(val) => Self::I32(val), + Value::I64(val) => Self::I64(val), + Value::F32(val) => Self::F32(val.into()), + Value::F64(val) => Self::F64(val.into()), + } + } +} + +impl From for Value { + fn from(value: wasmi::RuntimeValue) -> Self { + match value { + wasmi::RuntimeValue::I32(val) => Self::I32(val), + wasmi::RuntimeValue::I64(val) => Self::I64(val), + wasmi::RuntimeValue::F32(val) => Self::F32(val.into()), + wasmi::RuntimeValue::F64(val) => Self::F64(val.into()), + } + } +} + +impl From for wasmi::ValueType { + fn from(value: ValueType) -> Self { + match value { + ValueType::I32 => Self::I32, + ValueType::I64 => Self::I64, + ValueType::F32 => Self::F32, + ValueType::F64 => Self::F64, + } + } +} + +impl From for ValueType { + fn from(value: wasmi::ValueType) -> Self { + match value { + wasmi::ValueType::I32 => Self::I32, + wasmi::ValueType::I64 => Self::I64, + wasmi::ValueType::F32 => Self::F32, + wasmi::ValueType::F64 => Self::F64, + } + } +} + +impl From for wasmi::Signature { + fn from(sig: Signature) -> Self { + let args = sig.args.iter().map(|a| (*a).into()).collect::>(); + wasmi::Signature::new(args, sig.return_value.map(Into::into)) + } +} + +impl From<&wasmi::Signature> for Signature { + fn from(sig: &wasmi::Signature) -> Self { + Signature::new( + sig.params().into_iter().copied().map(Into::into).collect::>(), + sig.return_type().map(Into::into), + ) + } +} diff --git a/node-template/Cargo.toml b/node-template/Cargo.toml index 4112452b2722f7741a8f3e71d941a7d171fb3596..2aa305486ce216619b756d93c5c80fa7de6c8647 100644 --- a/node-template/Cargo.toml +++ b/node-template/Cargo.toml @@ -10,15 +10,15 @@ name = "node-template" path = "src/main.rs" [dependencies] -derive_more = "0.14.0" -futures = "0.1" -ctrlc = { version = "3.0", features = ["termination"] } -log = "0.4" -tokio = "0.1" -exit-future = "0.1" +derive_more = "0.15.0" +futures = "0.1.29" +ctrlc = { version = "3.1.3", features = ["termination"] } +log = "0.4.8" +tokio = "0.1.22" +exit-future = "0.1.4" parking_lot = "0.9.0" codec = { package = "parity-scale-codec", version = "1.0.0" } -trie-root = "0.15.0" +trie-root = "0.15.2" sr-io = { path = "../core/sr-io" } substrate-cli = { path = "../core/cli" } primitives = { package = "substrate-primitives", path = "../core/primitives" } @@ -27,12 +27,13 @@ substrate-service = { path = "../core/service" } inherents = { package = "substrate-inherents", path = "../core/inherents" } transaction-pool = { package = "substrate-transaction-pool", path = "../core/transaction-pool" } network = { package = "substrate-network", path = "../core/network" } -consensus = { package = "substrate-consensus-aura", path = "../core/consensus/aura" } -aura-primitives = { package = "substrate-consensus-aura-primitives", path = "../core/consensus/aura/primitives" } +babe = { package = "substrate-consensus-babe", path = "../core/consensus/babe" } +babe-primitives = { package = "substrate-consensus-babe-primitives", path = "../core/consensus/babe/primitives" } +grandpa = { package = "substrate-finality-grandpa", path = "../core/finality-grandpa" } grandpa-primitives = { package = "substrate-finality-grandpa-primitives", path = "../core/finality-grandpa/primitives" } substrate-client = { path = "../core/client" } basic-authorship = { package = "substrate-basic-authorship", path = "../core/basic-authorship" } node-template-runtime = { path = "runtime" } [build-dependencies] -vergen = "3" +vergen = "3.0.4" diff --git a/node-template/README.md b/node-template/README.md index 497ed84a52bcd33920af114154ed34e17d5cde3d..5a59652c1b352c1f2dbf64cbe360d64b1ee8c714 100644 --- a/node-template/README.md +++ b/node-template/README.md @@ -1,8 +1,8 @@ -# Template Node +# Substrate Node Template A new SRML-based Substrate node, ready for hacking. -# Building +## Build Install Rust: @@ -16,13 +16,15 @@ Install required tools: ./scripts/init.sh ``` -Build all native code: +Build Wasm and native code: ```bash cargo build ``` -# Run +## Run + +### Single node development chain You can start a development chain with: @@ -32,7 +34,13 @@ cargo run -- --dev Detailed logs may be shown by running the node with the following environment variables set: `RUST_LOG=debug RUST_BACKTRACE=1 cargo run -- --dev`. -If you want to see the multi-node consensus algorithm in action locally, then you can create a local testnet with two validator nodes for Alice and Bob, who are the initial authorities of the genesis chain that have been endowed with testnet units. Give each node a name and expose them so they are listed on the Polkadot [telemetry site](https://telemetry.polkadot.io/#/Local%20Testnet). You'll need two terminal windows open. +### Multi-node local testnet + +If you want to see the multi-node consensus algorithm in action locally, then you can create a local testnet with two validator nodes for Alice and Bob, who are the initial authorities of the genesis chain that have been endowed with testnet units. + +Optionally, give each node a name and expose them so they are listed on the Polkadot [telemetry site](https://telemetry.polkadot.io/#/Local%20Testnet). + +You'll need two terminal windows open. We'll start Alice's substrate node first on default TCP port 30333 with her chain database stored locally at `/tmp/alice`. The bootnode ID of her node is `QmRpheLN4JWdAnY7HGJfWFNbfkQCb6tFf4vvA6hgjMZKrR`, which is generated from the `--node-key` value that we specify below: diff --git a/node-template/runtime/Cargo.toml b/node-template/runtime/Cargo.toml index 2f41513048dc056f10c2ff13f8f273c44766ba54..18948d503cdbe51c62924a932bb7b4777c30141e 100644 --- a/node-template/runtime/Cargo.toml +++ b/node-template/runtime/Cargo.toml @@ -5,9 +5,8 @@ authors = ["Anonymous"] edition = "2018" [dependencies] - -serde = { version = "1.0", optional = true, features = ["derive"] } -safe-mix = { version = "1.0", default-features = false } +serde = { version = "1.0.101", optional = true, features = ["derive"] } +safe-mix = { version = "1.0.0", default-features = false } codec = { package = "parity-scale-codec", version = "1.0.0", default-features = false, features = ["derive"] } rstd = { package = "sr-std", path = "../../core/sr-std", default_features = false } runtime-io = { package = "sr-io", path = "../../core/sr-io", default_features = false } @@ -16,15 +15,16 @@ support = { package = "srml-support", path = "../../srml/support", default_featu primitives = { package = "substrate-primitives", path = "../../core/primitives", default_features = false } substrate-session = { path = "../../core/session", default-features = false } balances = { package = "srml-balances", path = "../../srml/balances", default_features = false } -aura = { package = "srml-aura", path = "../../srml/aura", default_features = false } +babe = { package = "srml-babe", path = "../../srml/babe", default-features = false } +babe-primitives = { package = "substrate-consensus-babe-primitives", path = "../../core/consensus/babe/primitives", default-features = false } executive = { package = "srml-executive", path = "../../srml/executive", default_features = false } indices = { package = "srml-indices", path = "../../srml/indices", default_features = false } +grandpa = { package = "srml-grandpa", path = "../../srml/grandpa", default-features = false } system = { package = "srml-system", path = "../../srml/system", default_features = false } timestamp = { package = "srml-timestamp", path = "../../srml/timestamp", default_features = false } sudo = { package = "srml-sudo", path = "../../srml/sudo", default_features = false } sr-primitives = { path = "../../core/sr-primitives", default_features = false } client = { package = "substrate-client", path = "../../core/client", default_features = false } -consensus-aura = { package = "substrate-consensus-aura-primitives", path = "../../core/consensus/aura/primitives", default_features = false } offchain-primitives = { package = "substrate-offchain-primitives", path = "../../core/offchain/primitives", default-features = false } [build-dependencies] @@ -39,9 +39,11 @@ std = [ "runtime-io/std", "support/std", "balances/std", + "babe/std", + "babe-primitives/std", "executive/std", - "aura/std", "indices/std", + "grandpa/std", "primitives/std", "sr-primitives/std", "system/std", @@ -50,8 +52,6 @@ std = [ "version/std", "serde", "safe-mix/std", - "consensus-aura/std", "offchain-primitives/std", "substrate-session/std", ] -no_std = [] diff --git a/node-template/runtime/build.rs b/node-template/runtime/build.rs index 7000c602e852514254baef95a37676238cd59626..ddbeefa11273dd572f97c9fdd4e027ed7f96ecc0 100644 --- a/node-template/runtime/build.rs +++ b/node-template/runtime/build.rs @@ -19,7 +19,7 @@ use wasm_builder_runner::{build_current_project_with_rustflags, WasmBuilderSourc fn main() { build_current_project_with_rustflags( "wasm_binary.rs", - WasmBuilderSource::Crates("1.0.4"), + WasmBuilderSource::Crates("1.0.7"), // This instructs LLD to export __heap_base as a global variable, which is used by the // external memory allocator. "-Clink-arg=--export=__heap_base", diff --git a/node-template/runtime/src/lib.rs b/node-template/runtime/src/lib.rs index 16235db1183c3b6c6b7e27992988d1651219bc3e..216cb0edc266af8265e7c69ea92c29d80bbece49 100644 --- a/node-template/runtime/src/lib.rs +++ b/node-template/runtime/src/lib.rs @@ -9,16 +9,19 @@ include!(concat!(env!("OUT_DIR"), "/wasm_binary.rs")); use rstd::prelude::*; -use primitives::{sr25519, OpaqueMetadata, crypto::key_types}; +use primitives::{OpaqueMetadata, crypto::key_types}; use sr_primitives::{ ApplyResult, transaction_validity::TransactionValidity, generic, create_runtime_str, - impl_opaque_keys, + impl_opaque_keys, AnySignature }; use sr_primitives::traits::{NumberFor, BlakeTwo256, Block as BlockT, StaticLookup, Verify, ConvertInto}; use sr_primitives::weights::Weight; +use babe::{AuthorityId as BabeId}; +use grandpa::{AuthorityId as GrandpaId, AuthorityWeight as GrandpaWeight}; +use grandpa::fg_primitives; use client::{ block_builder::api::{CheckInherentsResult, InherentData, self as block_builder_api}, - runtime_api, impl_runtime_apis + runtime_api as client_api, impl_runtime_apis }; use version::RuntimeVersion; #[cfg(feature = "std")] @@ -32,29 +35,31 @@ pub use balances::Call as BalancesCall; pub use sr_primitives::{Permill, Perbill}; pub use support::{StorageValue, construct_runtime, parameter_types}; -/// Alias to the signature scheme used for Aura authority signatures. -pub type AuraSignature = consensus_aura::sr25519::AuthoritySignature; +/// An index to a block. +pub type BlockNumber = u32; -/// The Ed25519 pub key of an session that belongs to an Aura authority of the chain. -pub type AuraId = consensus_aura::sr25519::AuthorityId; +/// Alias to 512-bit hash when used in the context of a transaction signature on the chain. +pub type Signature = AnySignature; -/// Alias to pubkey that identifies an account on the chain. -pub type AccountId = ::Signer; +/// 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; -/// The type used by authorities to prove their ID. -pub type AccountSignature = sr25519::Signature; +/// The type for looking up accounts. We don't expect more than 4 billion of them, but you +/// never know... +pub type AccountIndex = u32; -/// A hash of some data used by the chain. -pub type Hash = primitives::H256; +/// Balance of an account. +pub type Balance = u128; -/// Index of a block number in the chain. -pub type BlockNumber = u32; +/// Index of a transaction in the chain. +pub type Index = u32; -/// Index of an account's extrinsic in the chain. -pub type Nonce = u32; +/// A hash of some data used by the chain. +pub type Hash = primitives::H256; -/// Balance type for the node. -pub type Balance = u128; +/// Digest item type. +pub type DigestItem = generic::DigestItem; /// Used for the module template in `./template.rs` mod template; @@ -75,10 +80,14 @@ pub mod opaque { /// Opaque block identifier type. pub type BlockId = generic::BlockId; + pub type SessionHandlers = (Grandpa, Babe); + impl_opaque_keys! { pub struct SessionKeys { - #[id(key_types::AURA)] - pub aura: AuraId, + #[id(key_types::GRANDPA)] + pub grandpa: GrandpaId, + #[id(key_types::BABE)] + pub babe: BabeId, } } } @@ -93,6 +102,34 @@ pub const VERSION: RuntimeVersion = RuntimeVersion { apis: RUNTIME_API_VERSIONS, }; +/// Constants for Babe. + +/// Since BABE is probabilistic this is the average expected block time that +/// we are targetting. Blocks will be produced at a minimum duration defined +/// by `SLOT_DURATION`, but some slots will not be allocated to any +/// authority and hence no block will be produced. We expect to have this +/// block time on average following the defined slot duration and the value +/// of `c` configured for BABE (where `1 - c` represents the probability of +/// a slot being empty). +/// This value is only used indirectly to define the unit constants below +/// that are expressed in blocks. The rest of the code should use +/// `SLOT_DURATION` instead (like the timestamp module for calculating the +/// minimum period). +/// +pub const MILLISECS_PER_BLOCK: u64 = 6000; + +pub const SLOT_DURATION: u64 = MILLISECS_PER_BLOCK; + +pub const EPOCH_DURATION_IN_BLOCKS: u32 = 10 * MINUTES; + +// These time units are defined in number of blocks. +pub const MINUTES: BlockNumber = 60_000 / (MILLISECS_PER_BLOCK as BlockNumber); +pub const HOURS: BlockNumber = MINUTES * 60; +pub const DAYS: BlockNumber = HOURS * 24; + +// 1 in 4 blocks (on average, not counting collisions) will be primary babe blocks. +pub const PRIMARY_PROBABILITY: (u64, u64) = (1, 4); + /// The version infromation used to identify this runtime when compiled natively. #[cfg(feature = "std")] pub fn native_version() -> NativeVersion { @@ -107,6 +144,7 @@ parameter_types! { pub const MaximumBlockWeight: Weight = 1_000_000; pub const AvailableBlockRatio: Perbill = Perbill::from_percent(75); pub const MaximumBlockLength: u32 = 5 * 1024 * 1024; + pub const Version: RuntimeVersion = VERSION; } impl system::Trait for Runtime { @@ -117,7 +155,7 @@ impl system::Trait for Runtime { /// The lookup mechanism to get account ID from whatever is passed in dispatchers. type Lookup = Indices; /// The index type for storing how many extrinsics an account has signed. - type Index = Nonce; + type Index = Index; /// The index type for blocks. type BlockNumber = BlockNumber; /// The type for hashing blocks and tries. @@ -140,11 +178,22 @@ impl system::Trait for Runtime { type MaximumBlockLength = MaximumBlockLength; /// Portion of the block weight that is available to all normal transactions. type AvailableBlockRatio = AvailableBlockRatio; + type Version = Version; +} + +parameter_types! { + pub const EpochDuration: u64 = EPOCH_DURATION_IN_BLOCKS as u64; + pub const ExpectedBlockTime: u64 = MILLISECS_PER_BLOCK; } -impl aura::Trait for Runtime { - type HandleReport = (); - type AuthorityId = AuraId; +impl babe::Trait for Runtime { + type EpochDuration = EpochDuration; + type ExpectedBlockTime = ExpectedBlockTime; + type EpochChangeTrigger = babe::SameAuthoritiesForever; +} + +impl grandpa::Trait for Runtime { + type Event = Event; } impl indices::Trait for Runtime { @@ -160,13 +209,13 @@ impl indices::Trait for Runtime { } parameter_types! { - pub const MinimumPeriod: u64 = 5000; + pub const MinimumPeriod: u64 = SLOT_DURATION / 2; } impl timestamp::Trait for Runtime { /// A timestamp: milliseconds since the unix epoch. type Moment = u64; - type OnTimestampSet = Aura; + type OnTimestampSet = Babe; type MinimumPeriod = MinimumPeriod; } @@ -187,7 +236,6 @@ impl balances::Trait for Runtime { type OnNewAccount = Indices; /// The ubiquitous event type. type Event = Event; - type TransactionPayment = (); type DustRemoval = (); type TransferPayment = (); @@ -200,7 +248,6 @@ impl balances::Trait for Runtime { } impl sudo::Trait for Runtime { - /// The ubiquitous event type. type Event = Event; type Proposal = Call; } @@ -218,37 +265,44 @@ construct_runtime!( { System: system::{Module, Call, Storage, Config, Event}, Timestamp: timestamp::{Module, Call, Storage, Inherent}, - Aura: aura::{Module, Config, Inherent(Timestamp)}, + Babe: babe::{Module, Call, Storage, Config, Inherent(Timestamp)}, + Grandpa: grandpa::{Module, Call, Storage, Config, Event}, Indices: indices::{default, Config}, - Balances: balances, + Balances: balances::{default, Error}, Sudo: sudo, // Used for the module template in `./template.rs` TemplateModule: template::{Module, Call, Storage, Event}, } ); -/// The type used as a helper for interpreting the sender of transactions. -type Context = system::ChainContext; /// The address format for describing accounts. -type Address = ::Source; +pub type Address = ::Source; /// 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 = (system::CheckNonce, system::CheckWeight, balances::TakeFees); +pub type SignedExtra = ( + system::CheckVersion, + system::CheckGenesis, + system::CheckEra, + system::CheckNonce, + system::CheckWeight, + balances::TakeFees +); /// Unchecked extrinsic type as expected by this runtime. -pub type UncheckedExtrinsic = generic::UncheckedExtrinsic; +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 = executive::Executive; +pub type Executive = executive::Executive, Runtime, AllModules>; -// Implement our runtime API endpoints. This is just a bunch of proxying. impl_runtime_apis! { - impl runtime_api::Core for Runtime { + impl client_api::Core for Runtime { fn version() -> RuntimeVersion { VERSION } @@ -262,7 +316,7 @@ impl_runtime_apis! { } } - impl runtime_api::Metadata for Runtime { + impl client_api::Metadata for Runtime { fn metadata() -> OpaqueMetadata { Runtime::metadata().into() } @@ -290,24 +344,39 @@ impl_runtime_apis! { } } - impl runtime_api::TaggedTransactionQueue for Runtime { + impl client_api::TaggedTransactionQueue for Runtime { fn validate_transaction(tx: ::Extrinsic) -> TransactionValidity { Executive::validate_transaction(tx) } } - impl consensus_aura::AuraApi for Runtime { - fn slot_duration() -> u64 { - Aura::slot_duration() + impl offchain_primitives::OffchainWorkerApi for Runtime { + fn offchain_worker(number: NumberFor) { + Executive::offchain_worker(number) } - fn authorities() -> Vec { - Aura::authorities() + } + + impl fg_primitives::GrandpaApi for Runtime { + fn grandpa_authorities() -> Vec<(GrandpaId, GrandpaWeight)> { + Grandpa::grandpa_authorities() } } - impl offchain_primitives::OffchainWorkerApi for Runtime { - fn offchain_worker(n: NumberFor) { - Executive::offchain_worker(n) + impl babe_primitives::BabeApi for Runtime { + fn configuration() -> babe_primitives::BabeConfiguration { + // The choice of `c` parameter (where `1 - c` represents the + // probability of a slot being empty), is done in accordance to the + // slot duration and expected target block time, for safely + // resisting network delays of maximum two seconds. + // + babe_primitives::BabeConfiguration { + slot_duration: Babe::slot_duration(), + epoch_length: EpochDuration::get(), + c: PRIMARY_PROBABILITY, + genesis_authorities: Babe::authorities(), + randomness: Babe::randomness(), + secondary_slots: true, + } } } diff --git a/node-template/runtime/src/template.rs b/node-template/runtime/src/template.rs index aa399a8edde9cac4ea996cad3816bb419d9c5bf3..5a4225e63a29e83b0f68eac1825b828c0127d364 100644 --- a/node-template/runtime/src/template.rs +++ b/node-template/runtime/src/template.rs @@ -8,7 +8,7 @@ /// For more guidance on Substrate modules, see the example module /// https://github.com/paritytech/substrate/blob/master/srml/example/src/lib.rs -use support::{decl_module, decl_storage, decl_event, StorageValue, dispatch::Result}; +use support::{decl_module, decl_storage, decl_event, dispatch::Result}; use system::ensure_signed; /// The module's configuration trait. @@ -35,7 +35,7 @@ decl_module! { pub struct Module for enum Call where origin: T::Origin { // Initializing events // this is needed only if you are using events in your module - fn deposit_event() = default; + fn deposit_event() = default; // Just a dummy entry point. // function that can be called by the external world as an extrinsics call @@ -107,6 +107,7 @@ mod tests { type MaximumBlockWeight = MaximumBlockWeight; type MaximumBlockLength = MaximumBlockLength; type AvailableBlockRatio = AvailableBlockRatio; + type Version = (); } impl Trait for Test { type Event = (); diff --git a/node-template/src/chain_spec.rs b/node-template/src/chain_spec.rs index 65caab70dbe5ff5c6ad1c25771dfee42d030a250..9fdc6ee2ca6b3510eabc2ba89a7e4a8b2a7cfa18 100644 --- a/node-template/src/chain_spec.rs +++ b/node-template/src/chain_spec.rs @@ -1,9 +1,10 @@ -use primitives::{sr25519, Pair}; +use primitives::{Pair, Public}; use node_template_runtime::{ - AccountId, GenesisConfig, AuraConfig, BalancesConfig, - SudoConfig, IndicesConfig, SystemConfig, WASM_BINARY, AuraId + AccountId, BabeConfig, BalancesConfig, GenesisConfig, GrandpaConfig, + SudoConfig, IndicesConfig, SystemConfig, WASM_BINARY, }; -use aura_primitives::sr25519::AuthorityPair as AuraPair; +use babe_primitives::{AuthorityId as BabeId}; +use grandpa_primitives::{AuthorityId as GrandpaId}; use substrate_service; // Note this is the URL for the telemetry server @@ -23,16 +24,21 @@ pub enum Alternative { LocalTestnet, } -fn authority_key(s: &str) -> AuraId { - AuraPair::from_string(&format!("//{}", s), None) +/// Helper function to generate a crypto pair from seed +pub fn get_from_seed(seed: &str) -> ::Public { + TPublic::Pair::from_string(&format!("//{}", seed), None) .expect("static values are valid; qed") .public() } -fn account_key(s: &str) -> AccountId { - sr25519::Pair::from_string(&format!("//{}", s), None) - .expect("static values are valid; qed") - .public() +/// Helper function to generate stash, controller and session key from seed +pub fn get_authority_keys_from_seed(seed: &str) -> (AccountId, AccountId, GrandpaId, BabeId) { + ( + get_from_seed::(&format!("{}//stash", seed)), + get_from_seed::(seed), + get_from_seed::(seed), + get_from_seed::(seed), + ) } impl Alternative { @@ -43,12 +49,16 @@ impl Alternative { "Development", "dev", || testnet_genesis(vec![ - authority_key("Alice") - ], vec![ - account_key("Alice") + get_authority_keys_from_seed("Alice"), + ], + get_from_seed::("Alice"), + vec![ + get_from_seed::("Alice"), + get_from_seed::("Bob"), + get_from_seed::("Alice//stash"), + get_from_seed::("Bob//stash"), ], - account_key("Alice") - ), + true), vec![], None, None, @@ -59,18 +69,25 @@ impl Alternative { "Local Testnet", "local_testnet", || testnet_genesis(vec![ - authority_key("Alice"), - authority_key("Bob"), - ], vec![ - account_key("Alice"), - account_key("Bob"), - account_key("Charlie"), - account_key("Dave"), - account_key("Eve"), - account_key("Ferdie"), + get_authority_keys_from_seed("Alice"), + get_authority_keys_from_seed("Bob"), + ], + get_from_seed::("Alice"), + vec![ + get_from_seed::("Alice"), + get_from_seed::("Bob"), + get_from_seed::("Charlie"), + get_from_seed::("Dave"), + get_from_seed::("Eve"), + get_from_seed::("Ferdie"), + get_from_seed::("Alice//stash"), + get_from_seed::("Bob//stash"), + get_from_seed::("Charlie//stash"), + get_from_seed::("Dave//stash"), + get_from_seed::("Eve//stash"), + get_from_seed::("Ferdie//stash"), ], - account_key("Alice"), - ), + true), vec![], None, None, @@ -89,15 +106,15 @@ impl Alternative { } } -fn testnet_genesis(initial_authorities: Vec, endowed_accounts: Vec, root_key: AccountId) -> GenesisConfig { +fn testnet_genesis(initial_authorities: Vec<(AccountId, AccountId, GrandpaId, BabeId)>, + root_key: AccountId, + endowed_accounts: Vec, + _enable_println: bool) -> GenesisConfig { GenesisConfig { system: Some(SystemConfig { code: WASM_BINARY.to_vec(), changes_trie_config: Default::default(), }), - aura: Some(AuraConfig { - authorities: initial_authorities.clone(), - }), indices: Some(IndicesConfig { ids: endowed_accounts.clone(), }), @@ -108,5 +125,11 @@ fn testnet_genesis(initial_authorities: Vec, endowed_accounts: Vec(args: I, exit: E, version: VersionInfo) -> error::Result<()> T: Into + Clone, E: IntoExit, { + type Config = Configuration<(), T>; match parse_and_prepare::(&version, "substrate-node", args) { - ParseAndPrepare::Run(cmd) => cmd.run(load_spec, exit, |exit, _cli_args, _custom_args, config| { + ParseAndPrepare::Run(cmd) => cmd.run(load_spec, exit, + |exit, _cli_args, _custom_args, config: Config<_>| { info!("{}", version.name); info!(" version {}", config.full_version()); info!(" by {}, 2017, 2018", version.author); @@ -27,21 +28,24 @@ pub fn run(args: I, exit: E, version: VersionInfo) -> error::Result<()> match config.roles { ServiceRoles::LIGHT => run_until_exit( runtime, - service::Factory::new_light(config).map_err(|e| format!("{:?}", e))?, + service::new_light(config).map_err(|e| format!("{:?}", e))?, exit ), _ => run_until_exit( runtime, - service::Factory::new_full(config).map_err(|e| format!("{:?}", e))?, + service::new_full(config).map_err(|e| format!("{:?}", e))?, exit ), }.map_err(|e| format!("{:?}", e)) }), ParseAndPrepare::BuildSpec(cmd) => cmd.run(load_spec), - ParseAndPrepare::ExportBlocks(cmd) => cmd.run::(load_spec, exit), - ParseAndPrepare::ImportBlocks(cmd) => cmd.run::(load_spec, exit), + ParseAndPrepare::ExportBlocks(cmd) => cmd.run_with_builder(|config: Config<_>| + Ok(new_full_start!(config).0), load_spec, exit), + ParseAndPrepare::ImportBlocks(cmd) => cmd.run_with_builder(|config: Config<_>| + Ok(new_full_start!(config).0), load_spec, exit), ParseAndPrepare::PurgeChain(cmd) => cmd.run(load_spec), - ParseAndPrepare::RevertChain(cmd) => cmd.run::(load_spec), + ParseAndPrepare::RevertChain(cmd) => cmd.run_with_builder(|config: Config<_>| + Ok(new_full_start!(config).0), load_spec), ParseAndPrepare::CustomCommand(_) => Ok(()) }?; @@ -55,14 +59,13 @@ fn load_spec(id: &str) -> Result, String> { }) } -fn run_until_exit( +fn run_until_exit( mut runtime: Runtime, service: T, e: E, -) -> error::Result<()> where - T: Deref>, - T: Future + Send + 'static, - C: substrate_service::Components, +) -> error::Result<()> +where + T: AbstractService, E: IntoExit, { let (exit_send, exit) = exit_future::signal(); @@ -99,7 +102,8 @@ impl IntoExit for Exit { let exit_send_cell = RefCell::new(Some(exit_send)); ctrlc::set_handler(move || { - if let Some(exit_send) = exit_send_cell.try_borrow_mut().expect("signal handler not reentrant; qed").take() { + let exit_send = exit_send_cell.try_borrow_mut().expect("signal handler not reentrant; qed").take(); + if let Some(exit_send) = exit_send { exit_send.send(()).expect("Error sending exit notification"); } }).expect("Error setting Ctrl-C handler"); diff --git a/node-template/src/main.rs b/node-template/src/main.rs index 18e9638833fd22230ae292df41d9268acf6054b4..024efcc7db5413eef320efa722ef3c02c5f9b42a 100644 --- a/node-template/src/main.rs +++ b/node-template/src/main.rs @@ -4,6 +4,7 @@ #![warn(unused_extern_crates)] mod chain_spec; +#[macro_use] mod service; mod cli; diff --git a/node-template/src/service.rs b/node-template/src/service.rs index 7f2c80c48b2b821f42086c2befbc83d1ed531208..24b22082c5de7faac972bb09d56b1afa30357385 100644 --- a/node-template/src/service.rs +++ b/node-template/src/service.rs @@ -1,141 +1,228 @@ -//! Service and ServiceFactory implementation. Specialized wrapper over Substrate service. - -#![warn(unused_extern_crates)] +//! Service and ServiceFactory implementation. Specialized wrapper over substrate service. use std::sync::Arc; -use transaction_pool::{self, txpool::{Pool as TransactionPool}}; -use node_template_runtime::{self, GenesisConfig, opaque::Block, RuntimeApi, WASM_BINARY}; -use substrate_service::{ - FactoryFullConfiguration, LightComponents, FullComponents, FullBackend, - FullClient, LightClient, LightBackend, FullExecutor, LightExecutor, - error::{Error as ServiceError}, -}; -use basic_authorship::ProposerFactory; -use consensus::{import_queue, start_aura, AuraImportQueue, SlotDuration}; +use std::time::Duration; +use substrate_client::LongestChain; +use babe; +use grandpa::{self, FinalityProofProvider as GrandpaFinalityProofProvider}; use futures::prelude::*; -use substrate_client::{self as client, LongestChain}; +use node_template_runtime::{self, GenesisConfig, opaque::Block, RuntimeApi}; +use substrate_service::{error::{Error as ServiceError}, AbstractService, Configuration, ServiceBuilder}; +use transaction_pool::{self, txpool::{Pool as TransactionPool}}; use inherents::InherentDataProviders; -use network::{config::DummyFinalityProofRequestBuilder, construct_simple_protocol}; +use network::construct_simple_protocol; use substrate_executor::native_executor_instance; -use substrate_service::construct_service_factory; -use aura_primitives::sr25519::AuthorityPair as AuraAuthorityPair; - pub use substrate_executor::NativeExecutor; + // Our native executor instance. native_executor_instance!( pub Executor, node_template_runtime::api::dispatch, node_template_runtime::native_version, - WASM_BINARY ); -#[derive(Default)] -pub struct NodeConfig { - inherent_data_providers: InherentDataProviders, -} - construct_simple_protocol! { /// Demo protocol attachment for substrate. pub struct NodeProtocol where Block = Block { } } -construct_service_factory! { - struct Factory { - Block = Block, - RuntimeApi = RuntimeApi, - NetworkProtocol = NodeProtocol { |config| Ok(NodeProtocol::new()) }, - RuntimeDispatch = Executor, - FullTransactionPoolApi = transaction_pool::ChainApi< - client::Client, FullExecutor, Block, RuntimeApi>, - Block - > { - |config, client| Ok(TransactionPool::new(config, transaction_pool::ChainApi::new(client))) - }, - LightTransactionPoolApi = transaction_pool::ChainApi< - client::Client, LightExecutor, Block, RuntimeApi>, - Block - > { - |config, client| Ok(TransactionPool::new(config, transaction_pool::ChainApi::new(client))) - }, - Genesis = GenesisConfig, - Configuration = NodeConfig, - FullService = FullComponents - { |config: FactoryFullConfiguration| - FullComponents::::new(config) - }, - AuthoritySetup = { - |service: Self::FullService| { - if service.config().roles.is_authority() { - let proposer = ProposerFactory { - client: service.client(), - transaction_pool: service.transaction_pool(), - }; - let client = service.client(); - let select_chain = service.select_chain() - .ok_or_else(|| ServiceError::SelectChainRequired)?; - let aura = start_aura::<_, _, _, _, _, AuraAuthorityPair, _, _, _>( - SlotDuration::get_or_compute(&*client)?, - client.clone(), - select_chain, - client, - proposer, - service.network(), - service.config().custom.inherent_data_providers.clone(), - service.config().force_authoring, - Some(service.keystore()), +/// Starts a `ServiceBuilder` for a full service. +/// +/// Use this macro if you don't actually need the full service, but just the builder in order to +/// be able to perform chain operations. +macro_rules! new_full_start { + ($config:expr) => {{ + let mut import_setup = None; + let inherent_data_providers = inherents::InherentDataProviders::new(); + + let builder = substrate_service::ServiceBuilder::new_full::< + node_template_runtime::opaque::Block, node_template_runtime::RuntimeApi, crate::service::Executor + >($config)? + .with_select_chain(|_config, backend| { + Ok(substrate_client::LongestChain::new(backend.clone())) + })? + .with_transaction_pool(|config, client| + Ok(transaction_pool::txpool::Pool::new(config, transaction_pool::FullChainApi::new(client))) + )? + .with_import_queue(|_config, client, mut select_chain, _transaction_pool| { + let select_chain = select_chain.take() + .ok_or_else(|| substrate_service::Error::SelectChainRequired)?; + let (grandpa_block_import, grandpa_link) = + grandpa::block_import::<_, _, _, node_template_runtime::RuntimeApi, _, _>( + client.clone(), &*client, select_chain )?; - service.spawn_task(Box::new(aura.select(service.on_exit()).then(|_| Ok(())))); - } + let justification_import = grandpa_block_import.clone(); + + let (babe_block_import, babe_link) = babe::block_import( + babe::Config::get_or_compute(&*client)?, + grandpa_block_import, + client.clone(), + client.clone(), + )?; + + let import_queue = babe::import_queue( + babe_link.clone(), + babe_block_import.clone(), + Some(Box::new(justification_import)), + None, + client.clone(), + client, + inherent_data_providers.clone(), + )?; + + import_setup = Some((babe_block_import, grandpa_link, babe_link)); + + Ok(import_queue) + })?; + + (builder, import_setup, inherent_data_providers) + }} +} + +/// Builds a new service for a full client. +pub fn new_full(config: Configuration) + -> Result +{ + + let is_authority = config.roles.is_authority(); + let name = config.name.clone(); + let disable_grandpa = config.disable_grandpa; + let force_authoring = config.force_authoring; + + let (builder, mut import_setup, inherent_data_providers) = new_full_start!(config); - Ok(service) - } + let service = builder.with_network_protocol(|_| Ok(NodeProtocol::new()))? + .with_finality_proof_provider(|client, backend| + Ok(Arc::new(GrandpaFinalityProofProvider::new(backend, client)) as _) + )? + .build()?; + + let (block_import, grandpa_link, babe_link) = + import_setup.take() + .expect("Link Half and Block Import are present for Full Services or setup failed before. qed"); + + if is_authority { + let proposer = basic_authorship::ProposerFactory { + client: service.client(), + transaction_pool: service.transaction_pool(), + }; + + let client = service.client(); + let select_chain = service.select_chain() + .ok_or(ServiceError::SelectChainRequired)?; + + let babe_config = babe::BabeParams { + keystore: service.keystore(), + client, + select_chain, + env: proposer, + block_import, + sync_oracle: service.network(), + inherent_data_providers: inherent_data_providers.clone(), + force_authoring, + babe_link, + }; + + let babe = babe::start_babe(babe_config)?; + let select = babe.select(service.on_exit()).then(|_| Ok(())); + + // the BABE authoring task is considered infallible, i.e. if it + // fails we take down the service with it. + service.spawn_essential_task(select); + } + + let grandpa_config = grandpa::Config { + // FIXME #1578 make this available through chainspec + gossip_duration: Duration::from_millis(333), + justification_period: 512, + name: Some(name), + keystore: Some(service.keystore()), + }; + + match (is_authority, disable_grandpa) { + (false, false) => { + // start the lightweight GRANDPA observer + service.spawn_task(Box::new(grandpa::run_grandpa_observer( + grandpa_config, + grandpa_link, + service.network(), + service.on_exit(), + )?)); }, - LightService = LightComponents - { |config| >::new(config) }, - FullImportQueue = AuraImportQueue< - Self::Block, - > - { | - config: &mut FactoryFullConfiguration, - client: Arc>, - _select_chain: Self::SelectChain, - transaction_pool: Option>>, - | { - import_queue::<_, _, aura_primitives::sr25519::AuthorityPair, _>( - SlotDuration::get_or_compute(&*client)?, - Box::new(client.clone()), - None, - None, - client, - config.custom.inherent_data_providers.clone(), - transaction_pool, - ).map_err(Into::into) - } - }, - LightImportQueue = AuraImportQueue< - Self::Block, - > - { |config: &mut FactoryFullConfiguration, client: Arc>| { - let fprb = Box::new(DummyFinalityProofRequestBuilder::default()) as Box<_>; - import_queue::<_, _, AuraAuthorityPair, TransactionPool>( - SlotDuration::get_or_compute(&*client)?, - Box::new(client.clone()), - None, - None, - client, - config.custom.inherent_data_providers.clone(), - None, - ).map(|q| (q, fprb)).map_err(Into::into) - } - }, - SelectChain = LongestChain, Self::Block> - { |config: &FactoryFullConfiguration, client: Arc>| { - #[allow(deprecated)] - Ok(LongestChain::new(client.backend().clone())) - } + (true, false) => { + // start the full GRANDPA voter + let voter_config = grandpa::GrandpaParams { + config: grandpa_config, + link: grandpa_link, + network: service.network(), + inherent_data_providers: inherent_data_providers.clone(), + on_exit: service.on_exit(), + telemetry_on_connect: Some(service.telemetry_on_connect_stream()), + }; + + // the GRANDPA voter task is considered infallible, i.e. + // if it fails we take down the service with it. + service.spawn_essential_task(grandpa::run_grandpa_voter(voter_config)?); + }, + (_, true) => { + grandpa::setup_disabled_grandpa( + service.client(), + &inherent_data_providers, + service.network(), + )?; }, - FinalityProofProvider = { |_client: Arc>| { - Ok(None) - }}, } + + Ok(service) +} + +/// Builds a new service for a light client. +pub fn new_light(config: Configuration) + -> Result +{ + let inherent_data_providers = InherentDataProviders::new(); + + ServiceBuilder::new_light::(config)? + .with_select_chain(|_config, backend| { + Ok(LongestChain::new(backend.clone())) + })? + .with_transaction_pool(|config, client| + Ok(TransactionPool::new(config, transaction_pool::FullChainApi::new(client))) + )? + .with_import_queue_and_fprb(|_config, client, backend, fetcher, _select_chain, _tx_pool| { + let fetch_checker = fetcher + .map(|fetcher| fetcher.checker().clone()) + .ok_or_else(|| "Trying to start light import queue without active fetch checker")?; + let grandpa_block_import = grandpa::light_block_import::<_, _, _, RuntimeApi, _>( + client.clone(), backend, Arc::new(fetch_checker), client.clone() + )?; + + let finality_proof_import = grandpa_block_import.clone(); + let finality_proof_request_builder = + finality_proof_import.create_finality_proof_request_builder(); + + let (babe_block_import, babe_link) = babe::block_import( + babe::Config::get_or_compute(&*client)?, + grandpa_block_import, + client.clone(), + client.clone(), + )?; + + let import_queue = babe::import_queue( + babe_link.clone(), + babe_block_import, + None, + Some(Box::new(finality_proof_import)), + client.clone(), + client, + inherent_data_providers.clone(), + )?; + + Ok((import_queue, finality_proof_request_builder)) + })? + .with_network_protocol(|_| Ok(NodeProtocol::new()))? + .with_finality_proof_provider(|client, backend| + Ok(Arc::new(GrandpaFinalityProofProvider::new(backend, client)) as _) + )? + .build() } diff --git a/node/cli/Cargo.toml b/node/cli/Cargo.toml index c266427439d781e1e96965ab9809bf527aaf9f25..ca3ec92630789cfa8e965778f7a45f40691db655 100644 --- a/node/cli/Cargo.toml +++ b/node/cli/Cargo.toml @@ -7,10 +7,11 @@ build = "build.rs" edition = "2018" [dependencies] -log = "0.4" -tokio = "0.1.7" -futures = "0.1" -exit-future = "0.1" +log = "0.4.8" +tokio = "0.1.22" +futures = "0.1.29" +exit-future = "0.1.4" +jsonrpc-core = "13.2.0" cli = { package = "substrate-cli", path = "../../core/cli" } codec = { package = "parity-scale-codec", version = "1.0.0" } sr-io = { path = "../../core/sr-io" } @@ -18,10 +19,13 @@ client = { package = "substrate-client", path = "../../core/client" } primitives = { package = "substrate-primitives", path = "../../core/primitives" } inherents = { package = "substrate-inherents", path = "../../core/inherents" } node-runtime = { path = "../runtime" } +node-rpc = { path = "../rpc" } node-primitives = { path = "../primitives" } -hex-literal = "0.2" +hex-literal = "0.2.1" +substrate-rpc = { package = "substrate-rpc", path = "../../core/rpc" } substrate-basic-authorship = { path = "../../core/basic-authorship" } substrate-service = { path = "../../core/service" } +chain-spec = { package = "substrate-chain-spec", path = "../../core/chain-spec" } transaction_pool = { package = "substrate-transaction-pool", path = "../../core/transaction-pool" } network = { package = "substrate-network", path = "../../core/network" } babe = { package = "substrate-consensus-babe", path = "../../core/consensus/babe" } @@ -31,27 +35,32 @@ grandpa_primitives = { package = "substrate-finality-grandpa-primitives", path = sr-primitives = { path = "../../core/sr-primitives" } node-executor = { path = "../executor" } substrate-telemetry = { package = "substrate-telemetry", path = "../../core/telemetry" } -structopt = "0.2" +structopt = "0.2.0" transaction-factory = { path = "../../test-utils/transaction-factory" } keyring = { package = "substrate-keyring", path = "../../core/keyring" } indices = { package = "srml-indices", path = "../../srml/indices" } timestamp = { package = "srml-timestamp", path = "../../srml/timestamp", default-features = false } -rand = "0.6" +rand = "0.7.2" finality_tracker = { package = "srml-finality-tracker", path = "../../srml/finality-tracker", default-features = false } contracts = { package = "srml-contracts", path = "../../srml/contracts" } system = { package = "srml-system", path = "../../srml/system" } balances = { package = "srml-balances", path = "../../srml/balances" } support = { package = "srml-support", path = "../../srml/support", default-features = false } im_online = { package = "srml-im-online", path = "../../srml/im-online", default-features = false } +sr-authority-discovery = { package = "srml-authority-discovery", path = "../../srml/authority-discovery", default-features = false } +authority-discovery = { package = "substrate-authority-discovery", path = "../../core/authority-discovery"} +serde = { version = "1.0.101", features = [ "derive" ] } +client_db = { package = "substrate-client-db", path = "../../core/client/db", features = ["kvdb-rocksdb"] } +offchain = { package = "substrate-offchain", path = "../../core/offchain" } [dev-dependencies] keystore = { package = "substrate-keystore", path = "../../core/keystore" } babe = { package = "substrate-consensus-babe", path = "../../core/consensus/babe", features = ["test-helpers"] } consensus-common = { package = "substrate-consensus-common", path = "../../core/consensus/common" } service-test = { package = "substrate-service-test", path = "../../core/service/test" } -futures03 = { package = "futures-preview", version = "=0.3.0-alpha.17" } -tempfile = "3.1" +futures03 = { package = "futures-preview", version = "0.3.0-alpha.19" } +tempfile = "3.1.0" [build-dependencies] cli = { package = "substrate-cli", path = "../../core/cli" } -structopt = "0.2" +structopt = "0.2.0" diff --git a/node/cli/res/flaming-fir.json b/node/cli/res/flaming-fir.json index 851aaa21b4a9a332147279495349e32a5fc95862..5cd11eb97fa008d124b4d51322520610538d6d8c 100644 --- a/node/cli/res/flaming-fir.json +++ b/node/cli/res/flaming-fir.json @@ -21,86 +21,91 @@ "protocolId": "fir", "consensusEngine": null, "genesis": { - "raw": [{ - "0xbc3717660105a864bd63dcd430de64128d58bd0917fa8dd75aee827cf086e19c": "0x0000c16ff28623000000000000000000", - "0x8f9a319405d14f3953657373696f6e204b65794f776e6572343a73657373696f6e3a6b657973a6e391e5d17627fa5aaa7a76b39ebee4b139bff595608fe41aea21aa7ea48053": "0x68655684472b743e456907b398d3a44c113f189e56d1bbfd55e889e295dfde78", - "0x7eb7a404bf7e3466c3f6c5914e25edfaab48b1e24fd29ea5a94deaaa1aba80e6": "0x0c0001547ff0ab649283a7ae01dbc2eb73932eba2fb09075e9485ff369082a2ff38d65019c7a2ee14e565db0c69f78c7b4cd839fbf52b607d867e9e9c5a79042898a0d12", - "0x8f9a319405d14f3953657373696f6e204b65794f776e6572343a73657373696f6e3a6b65797372fff749dbf31067eff27b442ec22922d2b7817d7c6fbc6895d90847fd91504c": "0xf26cdb14b5aec7b2789fd5ca80f979cef3761897ae1f37ffb3e154cbcc1c2663", - "0xc98362e2ca21b342cc749022ed9b560e4d29ec9862a960c2538c314f1d279635": "0x149ee5e5bdc0ec239eb164f865ecc345ce4c88e76ee002e0f7e3180973474718099c7a2ee14e565db0c69f78c7b4cd839fbf52b607d867e9e9c5a79042898a0d1268655684472b743e456907b398d3a44c113f189e56d1bbfd55e889e295dfde78547ff0ab649283a7ae01dbc2eb73932eba2fb09075e9485ff369082a2ff38d65f26cdb14b5aec7b2789fd5ca80f979cef3761897ae1f37ffb3e154cbcc1c2663", - "0xf4adb4c4f708c4b753657373696f6e204e6578744b657973343a73657373696f6e3a6b657973e54094c2d5af8ae10b91e1288f4f59f2946d7738f2c509b7effd909e5e9ba0ad": "0x5633b70b80a6c8bb16270f82cca6d56b27ed7b76c8fd5af2986a25a4788ce440482a3389a6cf42d8ed83888cfd920fec738ea30f97e44699ada7323f08c3380a", - "0xc63b8a0db7e72fd87c88d8dcf4777b883f86728613c57148c4e5cdceb05b7a1a": "0x0c0001f26cdb14b5aec7b2789fd5ca80f979cef3761897ae1f37ffb3e154cbcc1c26630168655684472b743e456907b398d3a44c113f189e56d1bbfd55e889e295dfde78", - "0xf4adb4c4f708c4b753657373696f6e204e6578744b657973343a73657373696f6e3a6b6579737f325c981c2b001f5fe8c51cc7b89e50ebb1f60feb7ab3fa3bc79d6ab71d45cb": "0x9becad03e6dcac03cee07edebca5475314861492cdfc96a2144a67bbe96993326e7e4eb42cbd2e0ab4cae8708ce5509580b8c04d11f6758dbf686d50fe9f9106", - "0x2b334d6ac6698775ed17edf8cd3cbd9dae56cead0d69cb54f6af6aaecba544d8": "0x0f0000c16ff286230f0000c16ff2862300", - "0x9651d20f401bfac47731a01d6eba33b4": "0x00000000", - "0x8f9a319405d14f3953657373696f6e204b65794f776e6572343a73657373696f6e3a6b65797361be8e37f76f246c8d427bc3a669795df24fff7035dc10ba08f864f7d286c05e": "0x68655684472b743e456907b398d3a44c113f189e56d1bbfd55e889e295dfde78", - "0x154ebcb2c318b2e1c23e43e65aea27cd1348c4c5157502d7669a31c7635019cc": "0x9e42241d7cd91d001773b0b616d523dd80e13c6c2cab860b1234ef1b9ffc1526", - "0x26ac4a74e1ba94e0e7dbfc3b2aea083cf3c0f0d80eb999c7cebb340ee8934da9": "0x68655684472b743e456907b398d3a44c113f189e56d1bbfd55e889e295dfde780f0000c16ff286230f0000c16ff2862300", - "0x2d5205eddfc20f1a616c0391abb78a3920e823abe7ed33cfd7945dd1a1bf8651": "0x047374616b696e67200000c16ff28623000000000000000000ffffffffffffffff0e", - "0x121725e2f949944d00a8c011c0db54ae07b84a6ca772adf3c65417345d91522d": "0x0000c16ff28623000000000000000000", - "0x2dce29f1a768624dc5343063cb77f77d": "0x07000000", - "0x46cef122497fefa60faf6c66d3ef05caf9870446796ae11f0a4f734fee993d8b": "0x00", - "0xfff675c76ad8a5dfbd7db9a4e80f7c0ece595ad1878d2b6fca6086b2483a055b": "0x0000c16ff28623000000000000000000", - "0x75f6361fd25fec35714be80f2d9870af8c92e73cb6d299ba4774f5b0ad842275": "0x00", - "0x633daafcb669e97549c1b9d65660881016f969040bc16171709159437c31294a": "0x0f0000c16ff286230f0000c16ff2862300", - "0x7c79972b34b7e51bdd5f168ba3accd35fbec396be75dfad19dd1121327f1a1ad": "0x0c000168655684472b743e456907b398d3a44c113f189e56d1bbfd55e889e295dfde7800", - "0x4e62513de81454ce76df887573f7f98b101eb4585b1485a222b7db599f4e93e2": "0x047374616b696e67200000c16ff28623000000000000000000ffffffffffffffff0e", - "0xd437fe93b0bd0a5d67d30d85d010edc2": "0x40420f00", - "0xb2029f8665aac509629f2d28cea790a3": "0x10f26cdb14b5aec7b2789fd5ca80f979cef3761897ae1f37ffb3e154cbcc1c26633919132b851ef0fd2dae42a7e734fe547af5a6b809006100f48944d7fae8e8ef00299981a2b92f878baaf5dbeba5c18d4e70f2a1fcd9c61b32ea18daf38f4378547ff0ab649283a7ae01dbc2eb73932eba2fb09075e9485ff369082a2ff38d655633b70b80a6c8bb16270f82cca6d56b27ed7b76c8fd5af2986a25a4788ce440482a3389a6cf42d8ed83888cfd920fec738ea30f97e44699ada7323f08c3380a68655684472b743e456907b398d3a44c113f189e56d1bbfd55e889e295dfde787932cff431e748892fa48e10c63c17d30f80ca42e4de3921e641249cd7fa3c2f482dbd7297a39fa145c570552249c2ca9dd47e281f0c500c971b59c9dcdcd82e9c7a2ee14e565db0c69f78c7b4cd839fbf52b607d867e9e9c5a79042898a0d129becad03e6dcac03cee07edebca5475314861492cdfc96a2144a67bbe96993326e7e4eb42cbd2e0ab4cae8708ce5509580b8c04d11f6758dbf686d50fe9f9106", - "0xdfaac108e0d4bc78fc9419a7fcfa84dc": "0x10f26cdb14b5aec7b2789fd5ca80f979cef3761897ae1f37ffb3e154cbcc1c2663547ff0ab649283a7ae01dbc2eb73932eba2fb09075e9485ff369082a2ff38d6568655684472b743e456907b398d3a44c113f189e56d1bbfd55e889e295dfde789c7a2ee14e565db0c69f78c7b4cd839fbf52b607d867e9e9c5a79042898a0d12", - "0x8f9a319405d14f3953657373696f6e204b65794f776e6572343a73657373696f6e3a6b657973887a8c8429d90d6cf7a8ba6b60877979bff529eab6930cb2fdea5edf5a79c7d5": "0xf26cdb14b5aec7b2789fd5ca80f979cef3761897ae1f37ffb3e154cbcc1c2663", - "0x579ab55d37b1220812be3c3df29d4858": "0x00000000", - "0xa902f1f0ef97177b8df9f9fd413768e7": "0x00000000", - "0x8f9a319405d14f3953657373696f6e204b65794f776e6572343a73657373696f6e3a6b657973559fe6ed570e93d5c6b0b335ecf466e5fbbbe8261673da66a68c9fcc835db06b": "0x547ff0ab649283a7ae01dbc2eb73932eba2fb09075e9485ff369082a2ff38d65", - "0x366a192e1ce90bf109f11cf4d4bdab1ce310d835c09411b1be3ad53814e33196": "0x0c000001547ff0ab649283a7ae01dbc2eb73932eba2fb09075e9485ff369082a2ff38d65", - "0x125dc846383907f5846f72ce53ca0e4b": "0x00ca9a3b000000000000000000000000", - "0x8b4621d5f16433d6024b5a31547c59ee24e749e051dbb4bc7e64502f2a4f62fb": "0x66bc1e5d275da50b72b15de072a2468a5ad414919ca9054d2695767cf650012f", - "0x4ac2684a5a20e7a5adf17ed7aa792a3f6334a0505f02b2a44c3934d36cc4ee0a": "0xc8dc79e36b29395413399edaec3e20fcca7205fb19776ed8ddb25d6f427ec40e", - "0xd546f8df064d356bc9db11de6d1207a8": "0x00", - "0x71020fee971bd00e8248d1830b8cffbe5b9cf4de1ea2911a1665c44fd70ab6f3": "0xf26cdb14b5aec7b2789fd5ca80f979cef3761897ae1f37ffb3e154cbcc1c26630f0000c16ff286230f0000c16ff2862300", - "0xf4adb4c4f708c4b753657373696f6e204e6578744b657973343a73657373696f6e3a6b65797394f72a73893fbd00b11fcce65a014cc5b9ff5066ec15aa6be068b4cabfe67fdb": "0x3919132b851ef0fd2dae42a7e734fe547af5a6b809006100f48944d7fae8e8ef00299981a2b92f878baaf5dbeba5c18d4e70f2a1fcd9c61b32ea18daf38f4378", - "0x3a636f6465": "0x0061736d0100000001c6022b60027f7f0060017f0060037f7f7f0060047f7f7f7f0060027f7f017f60037f7f7f017f60057f7f7f7f7f0060057f7f7f7f7f017f60067f7f7f7f7f7f017f60087f7f7f7f7f7f7f7f017f60067f7f7f7f7f7f0060047f7f7f7f017f60077f7f7f7f7f7f7f017f60027e7f017f60017f017f60047e7f7f7f017f60017e0060000060077f7e7e7e7e7e7e0060087f7f7f7f7f7f7f7f0060047f7f7f7f017e60047f7f7e7e0060037f7e7e0060057f7f7e7e7f0060057f7f7f7e7e0060077f7e7e7f7f7f7f0060047f7f7e7f0060037f7f7e0060067f7f7e7e7e7f0060037e7f7f017f60087f7f7e7e7f7f7f7f0060097f7f7f7e7e7f7f7f7f0060047f7e7e7e0060027f7e0060027f7f017e60087f7f7f7f7f7e7e7f0060017e017f60057f7e7f7f7e0060037f7e7f0060017f017e60047f7e7e7f0060057f7e7e7e7e0060067f7e7e7e7e7f0002cd072503656e760e6578745f626c616b65325f323536000203656e761f6578745f6765745f616c6c6f63617465645f6368696c645f73746f72616765000703656e76176578745f636c6561725f6368696c645f73746f72616765000303656e760f6578745f7365745f73746f72616765000303656e760c6578745f74776f785f313238000203656e76196578745f6765745f616c6c6f63617465645f73746f72616765000503656e76166578745f73616e64626f785f6d656d6f72795f6e6577000403656e761b6578745f73616e64626f785f6d656d6f72795f74656172646f776e000103656e76176578745f73616e64626f785f696e7374616e7469617465000803656e76126578745f73616e64626f785f696e766f6b65000903656e761d6578745f73616e64626f785f696e7374616e63655f74656172646f776e000103656e76146578745f6765745f73746f726167655f696e746f000703656e76116578745f636c6561725f73746f72616765000003656e76166578745f6b696c6c5f6368696c645f73746f72616765000003656e76106578745f636c6561725f707265666978000003656e76166578745f6368696c645f73746f726167655f726f6f74000503656e760e6578745f7072696e745f75746638000003656e76156578745f7365745f6368696c645f73746f72616765000a03656e76166578745f73616e64626f785f6d656d6f72795f676574000b03656e76166578745f73616e64626f785f6d656d6f72795f736574000b03656e76126578745f737232353531395f766572696679000b03656e76126578745f656432353531395f766572696679000b03656e760d6578745f7072696e745f686578000003656e76156578745f6c6f63616c5f73746f726167655f676574000b03656e76216578745f6c6f63616c5f73746f726167655f636f6d706172655f616e645f736574000c03656e760a6578745f7075626b6579000d03656e76116578745f6e6574776f726b5f7374617465000e03656e76086578745f7369676e000f03656e76166578745f7375626d69745f7472616e73616374696f6e000403656e76156578745f6c6f63616c5f73746f726167655f736574000603656e76106578745f73746f726167655f726f6f74000103656e76186578745f73746f726167655f6368616e6765735f726f6f74000503656e760b6578745f74776f785f3634000203656e76236578745f626c616b65325f3235365f656e756d6572617465645f747269655f726f6f74000303656e760d6578745f7072696e745f6e756d001003656e760a6578745f6d616c6c6f63000e03656e76086578745f66726565000103b404b20400000e0501001100000000000000000000000200110100000100000000000000000000000000000000000000000000000404000100040000001202020013110303030303030303030303030303030303030303030314020e00020004040515021502010216000100000200171800000200190101010100160101151a00030101011b001c041d08151601010000020010020001000003020001010001000000000000000002040600000002060204020000010000011e0202060403031f02020402000001010020010101000000000015022001000002000200000101010002020300210002040000000000000000000000001111000000000000010101010101010101010101010002110311020202020201010001001003222200020210012222000200000000222222002222220222222222222222000000010101000000010000000000000000000000000000000101010e120500000001000300000004000e02000102020101000100010102000002000100010101000001001111230100242400000006012100000001000100002500010100000001000000000000000b0000000001010101000000000000000100150000010200000402020602260000040000020502060002000400020000040003040204040001000203030202040606020202020304050104040405040404070204020402020000040204010404010404040400010100020000000e01050e050404270b0304040e0404040404030105010404050404040505050528282929292a0407017001cf01cf0105030100120611027f01418080c0000b7f0041c882c6000b07ab0414066d656d6f72790200195f5f696e6469726563745f66756e6374696f6e5f7461626c6501000b5f5f686561705f6261736503010c436f72655f76657273696f6e00bd0212436f72655f657865637574655f626c6f636b00be0215436f72655f696e697469616c697a655f626c6f636b00c402114d657461646174615f6d6574616461746100c5021c426c6f636b4275696c6465725f6170706c795f65787472696e73696300cc021b426c6f636b4275696c6465725f66696e616c697a655f626c6f636b00cd0220426c6f636b4275696c6465725f696e686572656e745f65787472696e7369637300ce021c426c6f636b4275696c6465725f636865636b5f696e686572656e747300d00218426c6f636b4275696c6465725f72616e646f6d5f7365656400d1022b5461676765645472616e73616374696f6e51756575655f76616c69646174655f7472616e73616374696f6e00d202214f6666636861696e576f726b65724170695f6f6666636861696e5f776f726b657200d402214772616e6470614170695f6772616e6470615f70656e64696e675f6368616e676500d502204772616e6470614170695f6772616e6470615f666f726365645f6368616e676500d6021e4772616e6470614170695f6772616e6470615f617574686f72697469657300d70214426162654170695f737461727475705f6461746100d8020d426162654170695f65706f636800d90218436f6e73656e7375734170695f617574686f72697469657300da02098903010041010bce01f403ca0155565a6465666768696a6b6c6d6e6f707172737475767778797a8001c204e503f703f903fa03ef039e0483048b049004bf0497049904bb04bc04f7018101e0029b01bb03c601e902ea02ce038d03c401a104a901b001e802e202c701c501c301c201bf01c101ee02c104c004ea01f101f001ef01f801f901fa0182029b039a03a0029e03b003b2038c038b038e0391039003fd02a1029a019901a2029d01cc03cb03a302d4038002ff01a4028102b803b703a502bc03f502f402a602f602be01bd01a702c001ae01af01e901e801a802ed01ec01a902ee01df02de02aa02e402b602b7029f02a401a301ab02a501b802e302e102f002ef02ed02ec02eb02e702e602e5028f03d001d101d301d201cf01d4019d039c03a303dd01e301e501e401e201e601b103b403b303ba03b903c003bf03be03bd03d203d103d003cf03cd03d503d903ae03d703da038d0492048e048f04a0049404a204a304a504a604a704a804a904aa04b504b604b704cc04b804c604c504c704c804c904ca04cb040a84f838b2049a1002187f017e230041f0006b2202240002400240024020012802042203200128020022046b41e100490d0003402001200441206a3602002001280208220341306a280200210520032802282106200241d0006a41186a22034200370300200241d0006a41106a22074200370300200241d0006a41086a220842003703002002420037035020044120200241d0006a1000200241106a41186a22092003290300370300200241106a41106a220a2007290300370300200241106a41086a220b2008290300370300200220022903503703102002410036025020062005200241106a4120200241d0006a100121060240024020022802502205417f470d002002200c36020c2002200d3602082002200e3602040c010b2001280208220f2802302110200f280228210f2003420037030020074200370300200842003703002002420037035020044120200241d0006a1000200241306a41186a2003290300370300200241306a41106a2007290300370300200241306a41086a200829030037030020022002290350370330200f2010200241306a412010022002200536020c20022005360208200220063602042006210e2005210d2005210c2004450d00200241046a21010c030b20012001280200220441206a3602002001280208220541306a2802002106200528022821052003420037030020074200370300200842003703002002420037035020044120200241d0006a100020092003290300370300200a2007290300370300200b2008290300370300200220022903503703102002410036025020052006200241106a4120200241d0006a100121060240024020022802502205417f470d002002201136020c20022012360208200220133602040c010b2001280208220f2802302110200f280228210f2003420037030020074200370300200842003703002002420037035020044120200241d0006a1000200241306a41186a2003290300370300200241306a41106a2007290300370300200241306a41086a200829030037030020022002290350370330200f2010200241306a412010022002200536020c20022005360208200220063602042006211320052112200521112004450d00200241046a21010c030b20012001280200220441206a3602002001280208220541306a2802002106200528022821052003420037030020074200370300200842003703002002420037035020044120200241d0006a100020092003290300370300200a2007290300370300200b2008290300370300200220022903503703102002410036025020052006200241106a4120200241d0006a100121060240024020022802502205417f470d002002201436020c20022015360208200220163602040c010b2001280208220f2802302110200f280228210f2003420037030020074200370300200842003703002002420037035020044120200241d0006a1000200241306a41186a2003290300370300200241306a41106a2007290300370300200241306a41086a200829030037030020022002290350370330200f2010200241306a412010022002200536020c20022005360208200220063602042006211620052115200521142004450d00200241046a21010c030b20012001280200220441206a3602002001280208220541306a2802002106200528022821052003420037030020074200370300200842003703002002420037035020044120200241d0006a100020092003290300370300200a2007290300370300200b2008290300370300200220022903503703102002410036025020052006200241106a4120200241d0006a1001210a0240024020022802502209417f470d002002201736020c20022018360208200220193602040c010b2001280208220b2802302105200b280228210b2003420037030020074200370300200842003703002002420037035020044120200241d0006a1000200241306a41186a2003290300370300200241306a41106a2007290300370300200241306a41086a200829030037030020022002290350370330200b2005200241306a412010022002200936020c200220093602082002200a360204200a211920092118200921172004450d00200241046a21010c030b20012802042203200128020022046b41e0004b0d000b0b024020042003460d0003402001200441206a3602002001280208220341306a280200210a20032802282103200241d0006a41186a22074200370300200241d0006a41106a22084200370300200241d0006a41086a220942003703002002420037035020044120200241d0006a1000200241106a41186a2007290300370300200241106a41106a2008290300370300200241106a41086a200929030037030020022002290350370310200241003602502003200a200241106a4120200241d0006a1001210a0240024020022802502203417f470d002002200b36020c20022005360208200220063602040c010b2001280208220b2802302105200b280228210b2007420037030020084200370300200942003703002002420037035020044120200241d0006a1000200241306a41186a2007290300370300200241306a41106a2008290300370300200241306a41086a200929030037030020022002290350370330200b2005200241306a412010022002200336020c200220033602082002200a360204200a2106200321052003210b2004450d00200241046a21010c030b200128020022042001280204470d000b0b200041003602000c010b200241d0006a41086a200141086a280200220336020020022001290200221a370350200020043602002000201a3702042000410c6a20033602000b200241f0006a24000b910202077f017e0240024002400240200041046a2802002202200041086a28020022036b2001410c6a2802002204200141086a28020022056b220641a8016d2207490d00200028020021020c010b200320076a22082003490d0220024101742203200820082003491b2203ad42a8017e2209422088a70d022009a722084100480d020240024020020d002008102721020c010b2000280200200241a8016c2008102821020b2002450d0120002002360200200041046a2003360200200041086a28020021030b2002200341a8016c6a2005200610ce041a200141086a2004360200200041086a2200200028020020076a36020002402001280204450d00200128020010290b0f0b20084108102a000b102b000b0700200010b1040b0b0020002001200210b3040b0700200010b2040b0e0041e8cfc500412210ac0400000b0a0041b0d2c5001058000b910202077f017e0240024002400240200041046a2802002202200041086a28020022036b2001410c6a2802002204200141086a28020022056b220641e8006d2207490d00200028020021020c010b200320076a22082003490d0220024101742203200820082003491b2203ad42e8007e2209422088a70d022009a722084100480d020240024020020d002008102721020c010b2000280200200241e8006c2008102821020b2002450d0120002002360200200041046a2003360200200041086a28020021030b2002200341e8006c6a2005200610ce041a200141086a2004360200200041086a2200200028020020076a36020002402001280204450d00200128020010290b0f0b20084108102a000b102b000b9904010f7f230041d0006b22022400200241086a2001102e02400240024020022802080d00200041003602000c010b02400240200228020c22034180012003418001491b22040d00410121050c010b2004410574220610272205450d020b02402003450d00200241306a41186a2107200241306a41106a2108200241306a41086a21094100210a4100210b4100210c034020074200370300200842003703002009420037030020024200370330200241306a2001280200220d20012802042206412020064120491b220e10ce041a20012006200e6b3602042001200d200e6a36020002402006411f4b0d00200041003602002004450d03200510290c030b200c41016a2106200241106a41186a220e2007290300370300200241106a41106a220d2008290300370300200241106a41086a220f2009290300370300200220022903303703100240200c2004470d000240200a20062006200a491b220441ffffff3f712004470d00200441057422104100480d0002400240200c0d002010102721050c010b2005200b2010102821050b20050d0120104101102a000b102b000b2005200b6a220c2002290310370000200c41186a200e290300370000200c41106a200d290300370000200c41086a200f290300370000200a41026a210a200b41206a210b2006210c20032006470d000b0b2000200436020420002005360200200041086a20033602000b200241d0006a24000f0b20064101102a000bbd0301077f230041106b22022400200241003a0003200241036a2001280200220320012802042204410047220510ce041a0240024002400240024020042005490d002001200420056b22063602042001200320056a22053602002004450d02024020022d0003220341037122044103460d0002400240024020040e03000102000b20034102762101410121040c070b200241003a000b2002410b6a20052006410047220410ce041a20062004490d032001200620046b3602042001200520046a3602002006450d0420022d000b4108742003724102762101410121040c060b41002104200241003a000e200241003b010c2002410c6a200520064103200641034922071b220810ce041a2001200620086b3602042001200520086a36020020070d0520022f010c20022d000e411074724108742003724102762101410121040c050b200341034b0d024100210420024100360204200241046a200520064104200641044922081b220310ce041a2001200620036b3602042001200520036a36020020080d0320022802042101410121040c040b20052004103e000b20042006103e000b410021040b0b2000200136020420002004360200200241106a24000b860402077f017e230041106b2202240020024100360208200242013703002000280200210320022000280208220036020c2002410c6a200210300240024002400240024020000d002002280208210020022802042104200228020021050c010b2003200041286c6a21062002280204210420022802082100034002400240200420006b4120490d00200041206a2107200228020021050c010b200041206a22072000490d0520044101742205200720072005491b22084100480d050240024020040d002008102721050c010b200228020020042008102821050b2005450d032002200836020420022005360200200821040b200520006a220041186a200341186a290000370000200041106a200341106a290000370000200041086a200341086a2900003700002002200736020820002003290000370000200341206a290300210902400240200420076b4108490d00200741086a21000c010b200741086a22002007490d0520044101742208200020002008491b22084100480d050240024020040d002008102721050c010b200520042008102821050b2005450d042002200836020420022005360200200821040b20022000360208200520076a20093700002006200341286a2203470d000b0b2001280200200128020420052000100302402004450d00200510290b200241106a24000f0b20084101102a000b20084101102a000b102b000b9e0701037f02400240024002400240024020002802002202413f4b0d0002400240200141046a280200200141086a2802002200460d00200128020021030c010b200041016a22032000490d0620004101742204200320032004491b22044100480d060240024020000d002004102721030c010b200128020020002004102821030b2003450d0220012003360200200141046a2004360200200141086a28020021000b200141086a200041016a360200200320006a20024102743a00000f0b200241808001490d032002418080808004490d020c010b20044101102a000b0240024002400240200141046a280200200141086a2802002202460d00200128020021030c010b200241016a22032002490d0520024101742204200320032004491b22044100480d050240024020020d002004102721030c010b200128020020022004102821030b2003450d0120012003360200200141046a2004360200200141086a28020021020b200141086a2204200241016a360200200320026a41033a00002000280200210302400240200141046a2802002202200428020022006b4104490d00200128020021020c010b200041046a22042000490d0520024101742200200420042000491b22004100480d050240024020020d002000102721020c010b200128020020022000102821020b2002450d0220012002360200200141046a2000360200200141086a28020021000b200141086a200041046a360200200220006a20033600000f0b20044101102a000b20004101102a000b024002400240200141046a2802002203200141086a28020022006b4104490d00200128020021030c010b200041046a22042000490d0320034101742200200420042000491b22004100480d030240024020030d002000102721030c010b200128020020032000102821030b2003450d0120012003360200200141046a2000360200200141086a28020021000b200141086a200041046a360200200320006a20024102744102723600000f0b20004101102a000b024002400240200141046a2802002203200141086a28020022006b4102490d00200128020021030c010b200041026a22042000490d0220034101742200200420042000491b22004100480d020240024020030d002000102721030c010b200128020020032000102821030b2003450d0120012003360200200141046a2000360200200141086a28020021000b200141086a200041026a360200200320006a20024102744101723b00000f0b20004101102a000b102b000b800501067f230041106b2202240020024100360208200242013703002000280200210320022000280208220036020c2002410c6a20021030024002400240024002402000450d0020004190016c2104034020022802042105200228020821000240024020032802004112470d000240024020052000460d00200228020021050c010b200041016a22052000490d0820004101742206200520052006491b22064100480d080240024020000d002006102721050c010b200228020020002006102821050b2005450d052002200636020420022005360200200228020821000b2002200041016a360208200520006a41003a00000c010b0240024020052000460d00200228020021050c010b200041016a22052000490d0720004101742206200520052006491b22064100480d070240024020000d002006102721050c010b200228020020002006102821050b2005450d052002200636020420022005360200200228020821000b2002200041016a360208200520006a41013a000020032002103220034188016a28020021060240024020022802042205200228020822006b4104490d00200228020021050c010b200041046a22072000490d0720054101742200200720072000491b22004100480d070240024020050d002000102721050c010b200228020020052000102821050b2005450d062002200036020420022005360200200228020821000b2002200041046a360208200520006a20063600000b20034190016a2103200441f07e6a22040d000b0b2002280204210020012802002001280204200228020022032002280208100302402000450d00200310290b200241106a24000f0b20064101102a000b20064101102a000b20004101102a000b102b000be3d00104057f017e067f017e230041206b220224000240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002402000280200220341114b0d0002400240024002400240024002400240024002400240024002400240024002400240024020030e12000102030405060708090a0b0c0d0e0f1011000b02400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490d5e20034101742205200420042005491b22054100480d5e0240024020030d002005102721040c010b200128020020032005102821040b2004450d1320012004360200200141046a2005360200200141086a28020021030b200141086a200341016a360200200420036a41003a00002000280208417f6a220341054b0d1102400240024002400240024020030e06000102030405000b200241003a001c02400240200141046a280200200141086a2802002200460d00200128020021030c010b200041016a22032000490d6320004101742204200320032004491b22044100480d630240024020000d002004102721030c010b200128020020002004102821030b2003450d1920012003360200200141046a2004360200200141086a28020021000b200141086a200041016a360200200320006a41003a00000c160b200241013a001c02400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490d6220034101742205200420042005491b22054100480d620240024020030d002005102721040c010b200128020020032005102821040b2004450d1920012004360200200141046a2005360200200141086a28020021030b200141086a2205200341016a360200200420036a41013a0000200028020c21062002200041146a2802002200360208200241086a2001103002400240200141046a2802002204200528020022036b2000490d00200128020021040c010b200320006a22052003490d6220044101742203200520052003491b22034100480d620240024020040d002003102721040c010b200128020020042003102821040b2004450d1a20012004360200200141046a2003360200200141086a28020021030b200141086a200320006a360200200420036a2006200010ce041a0c150b200241023a001c02400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490d6120034101742205200420042005491b22054100480d610240024020030d002005102721040c010b200128020020032005102821040b2004450d1a20012004360200200141046a2005360200200141086a28020021030b200141086a2205200341016a360200200420036a41023a00002000290310210702400240200141046a2802002203200528020022006b4108490d00200128020021030c010b200041086a22042000490d6120034101742200200420042000491b22004100480d610240024020030d002000102721030c010b200128020020032000102821030b2003450d1b20012003360200200141046a2000360200200141086a28020021000b200141086a200041086a360200200320006a20073700000c140b200241033a001c02400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490d6020034101742205200420042005491b22054100480d600240024020030d002005102721040c010b200128020020032005102821040b2004450d1b20012004360200200141046a2005360200200141086a28020021030b200141086a2205200341016a360200200420036a41033a0000200028020c21062002200041146a2802002200360208200241086a2001103002400240200141046a2802002204200528020022036b2000490d00200128020021040c010b200320006a22052003490d6020044101742203200520052003491b22034100480d600240024020040d002003102721040c010b200128020020042003102821040b2004450d1c20012004360200200141046a2003360200200141086a28020021030b200141086a200320006a360200200420036a2006200010ce041a0c130b200141086a2802002103200241043a001c024002402003200141046a280200460d00200128020021050c010b200341016a22042003490d5f20034101742205200420042005491b22044100480d5f0240024020030d002004102721050c010b200128020020032004102821050b2005450d1c20012005360200200141046a2004360200200141086a28020021030b200141086a2204200341016a360200200520036a41043a0000200028020c21032002200041146a2802002200360208200241086a200110302000450d122003200041186c6a2108200141046a21060340200328020021092002200341086a2802002200360208200241086a20011030024002402006280200220a200428020022056b2000490d002001280200210a0c010b200520006a220b2005490d60200a4101742205200b200b2005491b22054100480d6002400240200a0d0020051027210a0c010b2001280200200a20051028210a0b200a450d1e2001200a36020020062005360200200428020021050b2004200520006a360200200a20056a2009200010ce041a2003410c6a28020021092002200341146a2802002200360208200241086a20011030024002402006280200220a200428020022056b2000490d002001280200210a0c010b200520006a220b2005490d60200a4101742205200b200b2005491b22054100480d6002400240200a0d0020051027210a0c010b2001280200200a20051028210a0b200a450d1f2001200a36020020062005360200200428020021050b2004200520006a360200200a20056a2009200010ce041a200341186a22032008470d000c130b0b200241053a001c02400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490d5e20034101742205200420042005491b22054100480d5e0240024020030d002005102721040c010b200128020020032005102821040b2004450d1e20012004360200200141046a2005360200200141086a28020021030b200141086a2206200341016a360200200420036a41053a0000200028020c21042002200041146a2802002200360208200241086a200110302000450d1120042000410c6c6a2108200141046a210903402004280200210a2002200441086a2802002203360208200241086a200110300240024020092802002205200628020022006b2003490d00200128020021050c010b200020036a220b2000490d5f20054101742200200b200b2000491b22004100480d5f0240024020050d002000102721050c010b200128020020052000102821050b2005450d202001200536020020092000360200200628020021000b2006200020036a360200200520006a200a200310ce041a2004410c6a22042008470d000c120b0b02400240200141046a280200200141086a2802002200460d00200128020021030c010b200041016a22032000490d5d20004101742204200320032004491b22044100480d5d0240024020000d002004102721030c010b200128020020002004102821030b2003450d1f20012003360200200141046a2004360200200141086a28020021000b200141086a200041016a360200200320006a41013a00000c100b02400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490d5c20034101742205200420042005491b22054100480d5c0240024020030d002005102721040c010b200128020020032005102821040b2004450d1f20012004360200200141046a2005360200200141086a28020021030b200141086a2205200341016a360200200420036a41023a000002400240200141046a28020020052802002203460d00200128020021040c010b200341016a22042003490d5c20034101742205200420042005491b22054100480d5c0240024020030d002005102721040c010b200128020020032005102821040b2004450d2020012004360200200141046a2005360200200141086a28020021030b200141086a200341016a360200200420036a41003a0000200041086a200110540c0f0b02400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490d5b20034101742205200420042005491b22054100480d5b0240024020030d002005102721040c010b200128020020032005102821040b2004450d2020012004360200200141046a2005360200200141086a28020021030b200141086a2205200341016a360200200420036a41033a000002400240200141046a28020020052802002203460d00200128020021040c010b200341016a22042003490d5b20034101742205200420042005491b22054100480d5b0240024020030d002005102721040c010b200128020020032005102821040b2004450d2120012004360200200141046a2005360200200141086a28020021030b200141086a2206200341016a360200200420036a41003a00002000280204210c20022000410c6a2802002200360208200241086a200110302000450d0e200c200041f8006c6a210d200141046a210b034002400240200b2802002203200628020022006b4120490d00200128020021030c010b200041206a22042000490d5c20034101742200200420042000491b22004100480d5c0240024020030d002000102721030c010b200128020020032000102821030b2003450d2320012003360200200b2000360200200628020021000b2006200041206a360200200320006a220041186a200c412c6a290000370000200041106a200c41246a290000370000200041086a200c411c6a2900003700002000200c290014370000200c2001105402400240200b2802002203200628020022006b4120490d00200128020021030c010b200041206a22042000490d5c20034101742200200420042000491b22004100480d5c0240024020030d002000102721030c010b200128020020032000102821030b2003450d2420012003360200200b2000360200200628020021000b2006200041206a360200200320006a220041186a200c41cc006a290000370000200041106a200c41c4006a290000370000200041086a200c413c6a2900003700002000200c29003437000002400240200b2802002203200628020022006b4120490d00200128020021030c010b200041206a22042000490d5c20034101742200200420042000491b22004100480d5c0240024020030d002000102721030c010b200128020020032000102821030b2003450d2520012003360200200b2000360200200628020021000b2006200041206a360200200320006a220041186a200c41ec006a290000370000200041106a200c41e4006a290000370000200041086a200c41dc006a2900003700002000200c290054370000200c28020821042002200c2802102200360208200241086a2001103002402000450d00200041246c21090340200241086a2004104f2002280208210a02400240200b2802002205200628020022006b20022802102203490d00200128020021050c010b200020036a22082000490d5e20054101742200200820082000491b22004100480d5e0240024020050d002000102721050c010b200128020020052000102821050b2005450d2820012005360200200b2000360200200628020021000b2006200020036a360200200520006a200a200310ce041a0240200228020c450d00200a10290b200441246a21042009415c6a22090d000b0b200c41f8006a220c200d470d000c0f0b0b02400240200141046a280200200141086a2802002200460d00200128020021030c010b200041016a22032000490d5a20004101742204200320032004491b22044100480d5a0240024020000d002004102721030c010b200128020020002004102821030b2003450d2520012003360200200141046a2004360200200141086a28020021000b200141086a200041016a360200200320006a41043a00000c0d0b02400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490d5920034101742205200420042005491b22054100480d590240024020030d002005102721040c010b200128020020032005102821040b2004450d2520012004360200200141046a2005360200200141086a28020021030b200141086a200341016a360200200420036a41053a00002000280208417f6a220341014b0d0c02400240024020030e020001000b200241003a001c02400240200141046a280200200141086a2802002203460d00200128020021050c010b200341016a22042003490d5b20034101742205200420042005491b22044100480d5b0240024020030d002004102721050c010b200128020020032004102821050b2005450d2820012005360200200141046a2004360200200141086a28020021030b200041306a2104200141086a200341016a360200200520036a41003a00002000410c6a20011051200241186a21000c010b200241013a001c02400240200141046a280200200141086a2802002203460d00200128020021050c010b200341016a22042003490d5a20034101742205200420042005491b22044100480d5a0240024020030d002004102721050c010b200128020020032004102821050b2005450d2820012005360200200141046a2004360200200141086a28020021030b200041c0006a2104200141086a200341016a360200200520036a41013a00002000410c6a200110512002200041306a36021c2002411c6a20011059200241086a21000b200020043602002000200110590c0c0b02400240200141046a2206280200200141086a22042802002203460d00200128020021050c010b200341016a22052003490d582003410174220a20052005200a491b220a4100480d580240024020030d00200a102721050c010b20012802002003200a102821050b2005450d2720012005360200200141046a200a360200200141086a28020021030b2004200341016a360200200520036a41063a000020002d0008417f6a2203410c4b0d0b024002400240024002400240024002400240024002400240024020030e0d000102030405060708090a0b0c000b200241003a001c02400240200628020020042802002203460d00200128020021050c010b200341016a22052003490d642003410174220a20052005200a491b220a4100480d640240024020030d00200a102721050c010b20012802002003200a102821050b2005450d3420012005360200200141046a200a360200200141086a28020021030b200141086a200341016a360200200520036a41003a00002000410c6a200110512002200041306a360208200241086a2001105920002d0009220041024b0d1702400240024020000e03000102000b200241003a001c02400240200628020020042802002200460d00200128020021030c010b200041016a22032000490d6620004101742205200320032005491b22054100480d660240024020000d002005102721030c010b200128020020002005102821030b2003450d3720012003360200200141046a2005360200200141086a28020021000b2004200041016a360200200320006a41003a00000c190b200241013a001c02400240200628020020042802002200460d00200128020021030c010b200041016a22032000490d6520004101742205200320032005491b22054100480d650240024020000d002005102721030c010b200128020020002005102821030b2003450d3720012003360200200141046a2005360200200141086a28020021000b2004200041016a360200200320006a41013a00000c180b200241023a001c02400240200628020020042802002200460d00200128020021030c010b200041016a22032000490d6420004101742205200320032005491b22054100480d640240024020000d002005102721030c010b200128020020002005102821030b2003450d3720012003360200200141046a2005360200200141086a28020021000b2004200041016a360200200320006a41023a00000c170b200241013a001c02400240200628020020042802002203460d00200128020021040c010b200341016a22042003490d6320034101742205200420042005491b22054100480d630240024020030d002005102721040c010b200128020020032005102821040b2004450d3720012004360200200141046a2005360200200141086a28020021030b200141086a200341016a360200200420036a41013a00002002200041106a360208200241086a200110590c160b200241023a001c02400240200628020020042802002203460d00200128020021040c010b200341016a22042003490d6220034101742205200420042005491b22054100480d620240024020030d002005102721040c010b200128020020032005102821040b2004450d3720012004360200200141046a2005360200200141086a28020021030b200141086a200341016a360200200420036a41023a00002002200041106a360208200241086a200110590c150b200241033a001c02400240200628020020042802002200460d00200128020021030c010b200041016a22032000490d6120004101742205200320032005491b22054100480d610240024020000d002005102721030c010b200128020020002005102821030b2003450d3720012003360200200141046a2005360200200141086a28020021000b2004200041016a360200200320006a41033a00000c140b200241043a001c02400240200628020020042802002203460d00200128020021040c010b200341016a22042003490d6020034101742205200420042005491b22054100480d600240024020030d002005102721040c010b200128020020032005102821040b2004450d3720012004360200200141046a2005360200200141086a28020021030b200141086a200341016a360200200420036a41043a0000200041206a200110302002200041106a360208200241086a200110590c130b200241053a001c02400240200628020020042802002203460d00200128020021040c010b200341016a22042003490d5f20034101742205200420042005491b22054100480d5f0240024020030d002005102721040c010b200128020020032005102821040b2004450d3720012004360200200141046a2005360200200141086a28020021030b200141086a200341016a360200200420036a41053a0000200028020c21032002200041146a2802002200360208200241086a200110302000450d12200041246c21000340200320011051200341246a21032000415c6a22000d000c130b0b200241063a001c02400240200628020020042802002200460d00200128020021030c010b200041016a22032000490d5e20004101742205200320032005491b22054100480d5e0240024020000d002005102721030c010b200128020020002005102821030b2003450d3720012003360200200141046a2005360200200141086a28020021000b2004200041016a360200200320006a41063a00000c110b200241073a001c02400240200628020020042802002203460d00200128020021050c010b200341016a22052003490d5d2003410174220a20052005200a491b220a4100480d5d0240024020030d00200a102721050c010b20012802002003200a102821050b2005450d3720012005360200200141046a200a360200200141086a28020021030b2004200341016a360200200520036a41073a000020002d0009220041024b0d1002400240024020000e03000102000b200241003a001c02400240200628020020042802002200460d00200128020021030c010b200041016a22032000490d5f20004101742205200320032005491b22054100480d5f0240024020000d002005102721030c010b200128020020002005102821030b2003450d3a20012003360200200141046a2005360200200141086a28020021000b2004200041016a360200200320006a41003a00000c120b200241013a001c02400240200628020020042802002200460d00200128020021030c010b200041016a22032000490d5e20004101742205200320032005491b22054100480d5e0240024020000d002005102721030c010b200128020020002005102821030b2003450d3a20012003360200200141046a2005360200200141086a28020021000b2004200041016a360200200320006a41013a00000c110b200241023a001c02400240200628020020042802002200460d00200128020021030c010b200041016a22032000490d5d20004101742205200320032005491b22054100480d5d0240024020000d002005102721030c010b200128020020002005102821030b2003450d3a20012003360200200141046a2005360200200141086a28020021000b2004200041016a360200200320006a41023a00000c100b200241083a001c02400240200628020020042802002203460d00200128020021040c010b200341016a22042003490d5c20034101742205200420042005491b22054100480d5c0240024020030d002005102721040c010b200128020020032005102821040b2004450d3a20012004360200200141046a2005360200200141086a28020021030b200141086a200341016a360200200420036a41083a00002000410c6a200110510c0f0b200241093a001c02400240200628020020042802002203460d00200128020021040c010b200341016a22042003490d5b20034101742205200420042005491b22054100480d5b0240024020030d002005102721040c010b200128020020032005102821040b2004450d3a20012004360200200141046a2005360200200141086a28020021030b200141086a200341016a360200200420036a41093a00002000410c6a200110300c0e0b2002410a3a001c02400240200628020020042802002200460d00200128020021030c010b200041016a22032000490d5a20004101742205200320032005491b22054100480d5a0240024020000d002005102721030c010b200128020020002005102821030b2003450d3a20012003360200200141046a2005360200200141086a28020021000b2004200041016a360200200320006a410a3a00000c0d0b2002410b3a001c02400240200628020020042802002203460d00200128020021040c010b200341016a22042003490d5920034101742205200420042005491b22054100480d590240024020030d002005102721040c010b200128020020032005102821040b2004450d3a20012004360200200141046a2005360200200141086a28020021030b200141086a200341016a360200200420036a410b3a00002000410c6a200110300c0c0b2002410c3a001c02400240200628020020042802002203460d00200128020021050c010b200341016a22052003490d582003410174220a20052005200a491b220a4100480d580240024020030d00200a102721050c010b20012802002003200a102821050b2005450d3a20012005360200200141046a200a360200200141086a28020021030b200141086a220b200341016a360200200520036a410c3a0000200028020c21032002200041146a2802002200360208200241086a200110302000450d0b2000410574210a200141046a210803400240024020062802002205200428020022006b4120490d00200128020021050c010b200041206a22092000490d5920054101742200200920092000491b22004100480d590240024020050d002000102721050c010b200128020020052000102821050b2005450d3c2001200536020020082000360200200b28020021000b2004200041206a360200200520006a220041186a200341186a290000370000200041106a200341106a290000370000200041086a200341086a29000037000020002003290000370000200341206a2103200a41606a220a0d000c0c0b0b02400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490d5720034101742205200420042005491b22054100480d570240024020030d002005102721040c010b200128020020032005102821040b2004450d3b20012004360200200141046a2005360200200141086a28020021030b200141086a2205200341016a360200200420036a41073a000002400240200141046a28020020052802002203460d00200128020021040c010b200341016a22042003490d5720034101742205200420042005491b22054100480d570240024020030d002005102721040c010b200128020020032005102821040b2004450d3c20012004360200200141046a2005360200200141086a28020021030b200141086a2205200341016a360200200420036a41003a000002400240200141046a2802002204200528020022036b4120490d00200128020021040c010b200341206a22052003490d5720044101742203200520052003491b22034100480d570240024020040d002003102721040c010b200128020020042003102821040b2004450d3d20012004360200200141046a2003360200200141086a28020021030b200141086a2205200341206a360200200420036a220341186a200041106a220441186a290000370000200341106a200441106a290000370000200341086a200441086a2900003700002003200429000037000002400240200141046a2802002204200528020022036b4120490d00200128020021040c010b200341206a22052003490d5720044101742203200520052003491b22034100480d570240024020040d002003102721040c010b200128020020042003102821040b2004450d3e20012004360200200141046a2003360200200141086a28020021030b200141086a2205200341206a360200200420036a220341186a200041306a220441186a290000370000200341106a200441106a290000370000200341086a200441086a290000370000200320042900003700002000280204210620022000410c6a2802002200360208200241086a2001103002400240200141046a2802002204200528020022036b2000490d00200128020021040c010b200320006a22052003490d5720044101742203200520052003491b22034100480d570240024020040d002003102721040c010b200128020020042003102821040b2004450d3f20012004360200200141046a2003360200200141086a28020021030b200141086a200320006a360200200420036a2006200010ce041a0c0a0b02400240200141046a2206280200200141086a22042802002203460d00200128020021050c010b200341016a22052003490d562003410174220a20052005200a491b220a4100480d560240024020030d00200a102721050c010b20012802002003200a102821050b2005450d3f20012005360200200141046a200a360200200141086a28020021030b2004200341016a360200200520036a41083a0000200041086a22032d0000417f6a220541104b0d090240024002400240024002400240024002400240024002400240024002400240024020050e11000102030405060708090a0b0c0d0e0f10000b02400240200628020020042802002203460d00200128020021040c010b200341016a22042003490d6620034101742205200420042005491b22054100480d660240024020030d002005102721040c010b200128020020032005102821040b2004450d5020012004360200200141046a2005360200200141086a28020021030b200141086a200341016a360200200420036a41003a0000200028020c200110322002200041106a360208200241086a200110590c190b02400240200628020020042802002203460d00200128020021040c010b200341016a22042003490d6520034101742205200420042005491b22054100480d650240024020030d002005102721040c010b200128020020032005102821040b2004450d5020012004360200200141046a2005360200200141086a28020021030b200141086a200341016a360200200420036a41013a00002000410c6a200110300c180b02400240200628020020042802002205460d00200128020021060c010b200541016a22062005490d642005410174220a20062006200a491b220a4100480d640240024020050d00200a102721060c010b20012802002005200a102821060b2006450d5020012006360200200141046a200a360200200141086a28020021050b200141086a220a200541016a360200200620056a41023a00002000410c6a2001103020032d00012105200341026a2d0000210602400240200141046a280200200a2802002200460d00200128020021030c010b200041016a22032000490d642000410174220a20032003200a491b220a4100480d640240024020000d00200a102721030c010b20012802002000200a102821030b2003450d5120012003360200200141046a200a360200200141086a28020021000b2004200041016a360200200320006a20054100474107742006723a00000c170b02400240200628020020042802002205460d00200128020021060c010b200541016a22062005490d632005410174220a20062006200a491b220a4100480d630240024020050d00200a102721060c010b20012802002005200a102821060b2006450d5120012006360200200141046a200a360200200141086a28020021050b200141086a220a200541016a360200200620056a41033a00002000410c6a2001103020032d00012105200341026a2d0000210602400240200141046a280200200a2802002200460d00200128020021030c010b200041016a22032000490d632000410174220a20032003200a491b220a4100480d630240024020000d00200a102721030c010b20012802002000200a102821030b2003450d5220012003360200200141046a200a360200200141086a28020021000b2004200041016a360200200320006a20054100474107742006723a00000c160b02400240200628020020042802002203460d00200128020021050c010b200341016a22052003490d622003410174220a20052005200a491b220a4100480d620240024020030d00200a102721050c010b20012802002003200a102821050b2005450d5220012005360200200141046a200a360200200141086a28020021030b200141086a220a200341016a360200200520036a41043a0000200028020c2001103220002d0009210902400240200141046a280200200a2802002203460d00200128020021050c010b200341016a22052003490d622003410174220a20052005200a491b220a4100480d620240024020030d00200a102721050c010b20012802002003200a102821050b2005450d5320012005360200200141046a200a360200200141086a28020021030b2004200341016a360200200520036a20093a0000200029031021070240024020062802002205200428020022036b4108490d00200128020021050c010b200341086a220a2003490d6220054101742203200a200a2003491b22034100480d620240024020050d002003102721050c010b200128020020052003102821050b2005450d5420012005360200200141046a2003360200200141086a28020021030b2004200341086a360200200520036a2007370000200029031821070240024020062802002203200428020022006b4108490d00200128020021030c010b200041086a22052000490d6220034101742200200520052000491b22004100480d620240024020030d002000102721030c010b200128020020032000102821030b2003450d5520012003360200200141046a2000360200200141086a28020021000b2004200041086a360200200320006a20073700000c150b02400240200628020020042802002203460d00200128020021050c010b200341016a22052003490d612003410174220a20052005200a491b220a4100480d610240024020030d00200a102721050c010b20012802002003200a102821050b2005450d5520012005360200200141046a200a360200200141086a28020021030b2004200341016a360200200520036a41053a0000200028020c21050240024020062802002203200428020022006b4104490d00200128020021030c010b200041046a22062000490d6120034101742200200620062000491b22004100480d610240024020030d002000102721030c010b200128020020032000102821030b2003450d5620012003360200200141046a2000360200200141086a28020021000b2004200041046a360200200320006a20053600000c140b02400240200628020020042802002203460d00200128020021040c010b200341016a22042003490d6020034101742205200420042005491b22054100480d600240024020030d002005102721040c010b200128020020032005102821040b2004450d5620012004360200200141046a2005360200200141086a28020021030b200141086a200341016a360200200420036a41063a0000200028020c200110320c130b02400240200628020020042802002203460d00200128020021040c010b200341016a22042003490d5f20034101742205200420042005491b22054100480d5f0240024020030d002005102721040c010b200128020020032005102821040b2004450d5620012004360200200141046a2005360200200141086a28020021030b200141086a200341016a360200200420036a41073a0000200028020c200110320c120b02400240200628020020042802002205460d002001280200210a0c010b200541016a220a2005490d5e20054101742209200a200a2009491b22094100480d5e0240024020050d0020091027210a0c010b2001280200200520091028210a0b200a450d562001200a360200200141046a2009360200200141086a28020021050b2004200541016a360200200a20056a41083a0000024002402006280200220a200428020022056b4120490d002001280200210a0c010b200541206a22092005490d5e200a4101742205200920092005491b22054100480d5e02400240200a0d0020051027210a0c010b2001280200200a20051028210a0b200a450d572001200a360200200141046a2005360200200141086a28020021050b2004200541206a360200200a20056a220541186a200341196a290000370000200541106a200341116a290000370000200541086a200341096a29000037000020052003290001370000200029033021070240024020062802002205200428020022036b4108490d00200128020021050c010b200341086a220a2003490d5e20054101742203200a200a2003491b22034100480d5e0240024020050d002003102721050c010b200128020020052003102821050b2005450d5820012005360200200141046a2003360200200141086a28020021030b2004200341086a360200200520036a2007370000200029033821070240024020062802002203200428020022006b4108490d00200128020021030c010b200041086a22052000490d5e20034101742200200520052000491b22004100480d5e0240024020030d002000102721030c010b200128020020032000102821030b2003450d5920012003360200200141046a2000360200200141086a28020021000b2004200041086a360200200320006a20073700000c110b02400240200628020020042802002200460d00200128020021050c010b200041016a22052000490d5d2000410174220a20052005200a491b220a4100480d5d0240024020000d00200a102721050c010b20012802002000200a102821050b2005450d5920012005360200200141046a200a360200200141086a28020021000b2004200041016a360200200520006a41093a00000240024020062802002205200428020022006b4120490d00200128020021050c010b200041206a22062000490d5d20054101742200200620062000491b22004100480d5d0240024020050d002000102721050c010b200128020020052000102821050b2005450d5a20012005360200200141046a2000360200200141086a28020021000b2004200041206a360200200520006a220041186a200341196a290000370000200041106a200341116a290000370000200041086a200341096a290000370000200020032900013700000c100b02400240200628020020042802002203460d00200128020021040c010b200341016a22042003490d5c20034101742205200420042005491b22054100480d5c0240024020030d002005102721040c010b200128020020032005102821040b2004450d5a20012004360200200141046a2005360200200141086a28020021030b200141086a200341016a360200200420036a410a3a00002000410c6a200110300c0f0b02400240200628020020042802002203460d00200128020021040c010b200341016a22042003490d5b20034101742205200420042005491b22054100480d5b0240024020030d002005102721040c010b200128020020032005102821040b2004450d5a20012004360200200141046a2005360200200141086a28020021030b200141086a200341016a360200200420036a410b3a0000200041186a200110542000410c6a20011030200041106a200110300c0e0b02400240200628020020042802002200460d00200128020021050c010b200041016a22052000490d9a012000410174220a20052005200a491b220a4100480d9a010240024020000d00200a102721050c010b20012802002000200a102821050b2005450d5b20012005360200200141046a200a360200200141086a28020021000b2004200041016a360200200520006a410c3a00000240024020062802002205200428020022006b4120490d00200128020021050c010b200041206a22062000490d9a0120054101742200200620062000491b22004100480d9a010240024020050d002000102721050c010b200128020020052000102821050b2005450d5c20012005360200200141046a2000360200200141086a28020021000b2004200041206a360200200520006a220041186a200341196a290000370000200041106a200341116a290000370000200041086a200341096a290000370000200020032900013700000c0d0b02400240200628020020042802002200460d00200128020021030c010b200041016a22032000490d990120004101742205200320032005491b22054100480d99010240024020000d002005102721030c010b200128020020002005102821030b2003450d5c20012003360200200141046a2005360200200141086a28020021000b2004200041016a360200200320006a410d3a00000c0c0b02400240200628020020042802002200460d00200128020021050c010b200041016a22052000490d98012000410174220a20052005200a491b220a4100480d98010240024020000d00200a102721050c010b20012802002000200a102821050b2005450d5c20012005360200200141046a200a360200200141086a28020021000b2004200041016a360200200520006a410e3a00000240024020062802002205200428020022006b4120490d00200128020021050c010b200041206a22062000490d980120054101742200200620062000491b22004100480d98010240024020050d002000102721050c010b200128020020052000102821050b2005450d5d20012005360200200141046a2000360200200141086a28020021000b2004200041206a360200200520006a220041186a200341196a290000370000200041106a200341116a290000370000200041086a200341096a290000370000200020032900013700000c0b0b02400240200628020020042802002200460d00200128020021050c010b200041016a22052000490d97012000410174220a20052005200a491b220a4100480d97010240024020000d00200a102721050c010b20012802002000200a102821050b2005450d5d20012005360200200141046a200a360200200141086a28020021000b2004200041016a360200200520006a410f3a00000240024020062802002205200428020022006b4120490d00200128020021050c010b200041206a220a2000490d970120054101742200200a200a2000491b22004100480d97010240024020050d002000102721050c010b200128020020052000102821050b2005450d5e20012005360200200141046a2000360200200141086a28020021000b2004200041206a360200200520006a220041186a200341196a290000370000200041106a200341116a290000370000200041086a200341096a2900003700002000200329000137000020032d0021220041054b0d0a024002400240024002400240024020000e06000102030405000b410021030c050b410121030c040b410221030c030b410321030c020b410421030c010b410521030b200220033a001c02400240200628020020042802002200460d00200128020021050c010b200041016a22052000490d970120004101742206200520052006491b22064100480d97010240024020000d002006102721050c010b200128020020002006102821050b2005450d5f20012005360200200141046a2006360200200141086a28020021000b2004200041016a360200200520006a20033a00000c0a0b02400240200628020020042802002200460d00200128020021030c010b200041016a22032000490d960120004101742205200320032005491b22054100480d96010240024020000d002005102721030c010b200128020020002005102821030b2003450d5f20012003360200200141046a2005360200200141086a28020021000b2004200041016a360200200320006a41103a00000c090b02400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490d950120034101742205200420042005491b22054100480d95010240024020030d002005102721040c010b200128020020032005102821040b2004450d5f20012004360200200141046a2005360200200141086a28020021030b200141086a200341016a360200200420036a41093a0000200041046a20011092020c080b02400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490d940120034101742205200420042005491b22054100480d94010240024020030d002005102721040c010b200128020020032005102821040b2004450d5f20012004360200200141046a2005360200200141086a28020021030b200141086a200341016a360200200420036a410a3a0000200041046a20011092020c070b02400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490d930120034101742205200420042005491b22054100480d93010240024020030d002005102721040c010b200128020020032005102821040b2004450d5f20012004360200200141046a2005360200200141086a28020021030b200141086a200341016a360200200420036a410b3a00002000280208417f6a220341094b0d06024002400240024002400240024002400240024020030e0a00010203040506070809000b200241003a001c02400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490d9c0120034101742205200420042005491b22054100480d9c010240024020030d002005102721040c010b200128020020032005102821040b2004450d6920012004360200200141046a2005360200200141086a28020021030b200141086a2206200341016a360200200420036a41003a0000200028020c21042002200041146a280200220a360208200241086a200110300240200a450d00200141046a2109034002400240200928020020062802002203460d00200128020021050c010b200341016a22052003490d9e012003410174220b20052005200b491b220b4100480d9e010240024020030d00200b102721050c010b20012802002003200b102821050b2005450d6c200120053602002009200b360200200628020021030b2006200341016a360200200520036a20042d00003a0000200441016a2104200a417f6a220a0d000b0b200041186a20011030200028021c210402400240200141046a2802002203200628020022006b4104490d00200128020021030c010b200041046a22052000490d9c0120034101742200200520052000491b22004100480d9c010240024020030d002000102721030c010b200128020020032000102821030b2003450d6b20012003360200200141046a2000360200200141086a28020021000b200141086a200041046a360200200320006a20043600000c0f0b200241013a001c02400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490d9b0120034101742205200420042005491b22054100480d9b010240024020030d002005102721040c010b200128020020032005102821040b2004450d6b20012004360200200141046a2005360200200141086a28020021030b200141086a2206200341016a360200200420036a41013a0000200028020c21042002200041146a280200220a360208200241086a200110300240200a450d00200141046a2109034002400240200928020020062802002203460d00200128020021050c010b200341016a22052003490d9d012003410174220b20052005200b491b220b4100480d9d010240024020030d00200b102721050c010b20012802002003200b102821050b2005450d6e200120053602002009200b360200200628020021030b2006200341016a360200200520036a20042d00003a0000200441016a2104200a417f6a220a0d000b0b200041186a20011030200028021c210402400240200141046a2802002203200628020022006b4104490d00200128020021030c010b200041046a22052000490d9b0120034101742200200520052000491b22004100480d9b010240024020030d002000102721030c010b200128020020032000102821030b2003450d6d20012003360200200141046a2000360200200141086a28020021000b200141086a200041046a360200200320006a20043600000c0e0b200241023a001c02400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490d9a0120034101742205200420042005491b22054100480d9a010240024020030d002005102721040c010b200128020020032005102821040b2004450d6d20012004360200200141046a2005360200200141086a28020021030b200141086a200341016a360200200420036a41023a00002000410c6a20011030200041106a20011051200041346a20011030200041386a200110300c0d0b200241033a001c02400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490d990120034101742205200420042005491b22054100480d99010240024020030d002005102721040c010b200128020020032005102821040b2004450d6d20012004360200200141046a2005360200200141086a28020021030b200141086a200341016a360200200420036a41033a00002000410c6a200110300c0c0b200141086a2802002103200241043a001c024002402003200141046a280200460d00200128020021040c010b200341016a22042003490d980120034101742205200420042005491b22054100480d98010240024020030d002005102721040c010b200128020020032005102821040b2004450d6d20012004360200200141046a2005360200200141086a28020021030b200141086a200341016a360200200420036a41043a00002000410c6a200110300c0b0b200241053a001c02400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490d970120034101742205200420042005491b22054100480d97010240024020030d002005102721040c010b200128020020032005102821040b2004450d6d20012004360200200141046a2005360200200141086a28020021030b200141086a200341016a360200200420036a41053a00002000410c6a200110512002200041386a360208200241086a20011059200041306a200110300c0a0b200241063a001c02400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490d960120034101742205200420042005491b22054100480d96010240024020030d002005102721040c010b200128020020032005102821040b2004450d6d20012004360200200141046a2005360200200141086a28020021030b200141086a200341016a360200200420036a41063a00002000410c6a200110300c090b200241073a001c02400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490d950120034101742205200420042005491b22054100480d95010240024020030d002005102721040c010b200128020020032005102821040b2004450d6d20012004360200200141046a2005360200200141086a28020021030b200141086a200341016a360200200420036a41073a00002000410c6a200110510c080b200141046a2802002104200241083a001c024002402004200141086a2802002203460d00200128020021040c010b200341016a22042003490d940120034101742205200420042005491b22054100480d94010240024020030d002005102721040c010b200128020020032005102821040b2004450d6d20012004360200200141046a2005360200200141086a28020021030b200141086a200341016a360200200420036a41083a0000200041106a200110540c070b200241093a001c02400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490d930120034101742205200420042005491b22054100480d93010240024020030d002005102721040c010b200128020020032005102821040b2004450d6d20012004360200200141046a2005360200200141086a28020021030b200141086a200341016a360200200420036a41093a0000200041106a200110540c060b02400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490d920120034101742205200420042005491b22054100480d92010240024020030d002005102721040c010b200128020020032005102821040b2004450d6d20012004360200200141046a2005360200200141086a28020021030b200141086a2205200341016a360200200420036a410c3a000002400240200141046a28020020052802002203460d00200128020021040c010b200341016a22042003490d920120034101742205200420042005491b22054100480d92010240024020030d002005102721040c010b200128020020032005102821040b2004450d6e20012004360200200141046a2005360200200141086a28020021030b200141086a200341016a360200200420036a41003a0000200041086a200110540c050b02400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490d910120034101742205200420042005491b22054100480d91010240024020030d002005102721040c010b200128020020032005102821040b2004450d6e20012004360200200141046a2005360200200141086a28020021030b200141086a2205200341016a360200200420036a410d3a000002400240200141046a28020020052802002203460d00200128020021040c010b200341016a22042003490d910120034101742205200420042005491b22054100480d91010240024020030d002005102721040c010b200128020020032005102821040b2004450d6f20012004360200200141046a2005360200200141086a28020021030b200141086a2205200341016a360200200420036a41003a00002000280204210620022000410c6a2802002200360208200241086a2001103002400240200141046a2802002204200528020022036b2000490d00200128020021040c010b200320006a22052003490d910120044101742203200520052003491b22034100480d91010240024020040d002003102721040c010b200128020020042003102821040b2004450d7020012004360200200141046a2003360200200141086a28020021030b200141086a200320006a360200200420036a2006200010ce041a0c040b02400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490d900120034101742205200420042005491b22054100480d90010240024020030d002005102721040c010b200128020020032005102821040b2004450d7020012004360200200141046a2005360200200141086a28020021030b200141086a200341016a360200200420036a410e3a00002000280208417f6a220341024b0d0302400240024020030e03000102000b200241003a001c02400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490d920120034101742205200420042005491b22054100480d92010240024020030d002005102721040c010b200128020020032005102821040b2004450d7320012004360200200141046a2005360200200141086a28020021030b200141086a200341016a360200200420036a41003a00002002200041306a360208200241086a200110592000410c6a200110510c050b200241013a001c02400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490d910120034101742205200420042005491b22054100480d91010240024020030d002005102721040c010b200128020020032005102821040b2004450d7320012004360200200141046a2005360200200141086a28020021030b200141086a200341016a360200200420036a41013a00002000410c6a200110300c040b200241023a001c02400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490d900120034101742205200420042005491b22054100480d90010240024020030d002005102721040c010b200128020020032005102821040b2004450d7320012004360200200141046a2005360200200141086a28020021030b200141086a200341016a360200200420036a41023a00002000410c6a200110300c030b02400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490d8f0120034101742205200420042005491b22054100480d8f010240024020030d002005102721040c010b200128020020032005102821040b2004450d7320012004360200200141046a2005360200200141086a28020021030b200141086a200341016a360200200420036a410f3a0000200041086a22032d0000417f6a220441054b0d0202400240024002400240024020040e06000102030405000b200241003a001c02400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490d940120034101742205200420042005491b22054100480d94010240024020030d002005102721040c010b200128020020032005102821040b2004450d7920012004360200200141046a2005360200200141086a28020021030b200141086a200341016a360200200420036a41003a0000200041106a20011093020c070b200241013a001c02400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490d930120034101742205200420042005491b22054100480d93010240024020030d002005102721040c010b200128020020032005102821040b2004450d7920012004360200200141046a2005360200200141086a28020021030b200141086a2205200341016a360200200420036a41013a0000200041186a20011054200028020c21062002200041146a2802002200360208200241086a2001103002400240200141046a2802002204200528020022036b2000490d00200128020021040c010b200320006a22052003490d930120044101742203200520052003491b22034100480d93010240024020040d002003102721040c010b200128020020042003102821040b2004450d7a20012004360200200141046a2003360200200141086a28020021030b200141086a200320006a360200200420036a2006200010ce041a0c060b200241023a001c02400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490d920120034101742205200420042005491b22054100480d92010240024020030d002005102721040c010b200128020020032005102821040b2004450d7a20012004360200200141046a2005360200200141086a28020021030b200141086a2205200341016a360200200420036a41023a00002000410c6a200110512002200041c0006a360208200241086a20011059200041d0006a20011054200028023021062002200041386a2802002200360208200241086a2001103002400240200141046a2802002204200528020022036b2000490d00200128020021040c010b200320006a22052003490d920120044101742203200520052003491b22034100480d92010240024020040d002003102721040c010b200128020020042003102821040b2004450d7b20012004360200200141046a2003360200200141086a28020021030b200141086a200320006a360200200420036a2006200010ce041a0c050b200241033a001c02400240200141046a280200200141086a2802002204460d00200128020021050c010b200441016a22052004490d910120044101742206200520052006491b22064100480d91010240024020040d002006102721050c010b200128020020042006102821050b2005450d7b20012005360200200141046a2006360200200141086a28020021040b200141086a2206200441016a360200200520046a41033a00002002200041386a360208200241086a20011059200041c8006a2001105402400240200141046a2802002205200628020022046b4120490d00200128020021050c010b200441206a22062004490d910120054101742204200620062004491b22044100480d91010240024020050d002004102721050c010b200128020020052004102821050b2005450d7c20012005360200200141046a2004360200200141086a28020021040b200141086a2206200441206a360200200520046a220441186a200341196a290000370000200441106a200341116a290000370000200441086a200341096a29000037000020042003290001370000200028022c21052002200041346a2802002200360208200241086a2001103002400240200141046a2802002204200628020022036b2000490d00200128020021040c010b200320006a22062003490d910120044101742203200620062003491b22034100480d91010240024020040d002003102721040c010b200128020020042003102821040b2004450d7d20012004360200200141046a2003360200200141086a28020021030b200141086a200320006a360200200420036a2005200010ce041a0c040b200141086a2802002100200241043a001c024002402000200141046a280200460d00200128020021040c010b200041016a22042000490d900120004101742205200420042005491b22054100480d90010240024020000d002005102721040c010b200128020020002005102821040b2004450d7d20012004360200200141046a2005360200200141086a28020021000b200141086a2205200041016a360200200420006a41043a000002400240200141046a2802002204200528020022006b4120490d00200128020021040c010b200041206a22052000490d900120044101742200200520052000491b22004100480d90010240024020040d002000102721040c010b200128020020042000102821040b2004450d7e20012004360200200141046a2000360200200141086a28020021000b200141086a2205200041206a360200200420006a220041186a200341196a290000370000200041106a200341116a290000370000200041086a200341096a29000037000020002003290001370000024020032d00214101460d00200241003a001c02400240200141046a28020020052802002200460d00200128020021030c010b200041016a22032000490d910120004101742204200320032004491b22044100480d91010240024020000d002004102721030c010b200128020020002004102821030b2003450d800120012003360200200141046a2004360200200141086a28020021000b200141086a200041016a360200200320006a41003a00000c040b200241013a001c02400240200141046a28020020052802002200460d00200128020021040c010b200041016a22042000490d900120004101742205200420042005491b22054100480d90010240024020000d002005102721040c010b200128020020002005102821040b2004450d800120012004360200200141046a2005360200200141086a28020021000b200141086a2205200041016a360200200420006a41013a000002400240200141046a2802002204200528020022006b4120490d00200128020021040c010b200041206a22052000490d900120044101742200200520052000491b22004100480d90010240024020040d002000102721040c010b200128020020042000102821040b2004450d810120012004360200200141046a2000360200200141086a28020021000b200141086a200041206a360200200420006a220041186a200341226a220341186a290000370000200041106a200341106a290000370000200041086a200341086a290000370000200020032900003700000c030b200241053a001c02400240200141046a280200200141086a2802002204460d00200128020021050c010b200441016a22052004490d8f0120044101742206200520052006491b22064100480d8f010240024020040d002006102721050c010b200128020020042006102821050b2005450d810120012005360200200141046a2006360200200141086a28020021040b200141086a2206200441016a360200200520046a41053a000002400240200141046a2802002205200628020022046b4120490d00200128020021050c010b200441206a22062004490d8f0120054101742204200620062004491b22044100480d8f010240024020050d002004102721050c010b200128020020052004102821050b2005450d820120012005360200200141046a2004360200200141086a28020021040b200141086a2206200441206a360200200520046a220441186a200341196a290000370000200441106a200341116a290000370000200441086a200341096a2900003700002004200329000137000002400240200141046a2802002205200628020022046b4120490d00200128020021050c010b200441206a22062004490d8f0120054101742204200620062004491b22044100480d8f010240024020050d002004102721050c010b200128020020052004102821050b2005450d830120012005360200200141046a2004360200200141086a28020021040b200141086a2206200441206a360200200520046a220441186a200341216a220341186a290000370000200441106a200341106a290000370000200441086a200341086a29000037000020042003290000370000200041e0006a29030021072000290358210e02400240200141046a2802002204200628020022036b4110490d00200128020021040c010b200341106a22052003490d8f0120044101742203200520052003491b22034100480d8f010240024020040d002003102721040c010b200128020020042003102821040b2004450d840120012004360200200141046a2003360200200141086a28020021030b200141086a2205200341106a360200200420036a220320073700082003200e370000200028024c21032002200041d4006a2802002200360208200241086a200110302000450d0220004105742106200141046a210a034002400240200a2802002204200528020022006b4120490d00200128020021040c010b200041206a22092000490d900120044101742200200920092000491b22004100480d90010240024020040d002000102721040c010b200128020020042000102821040b2004450d860120012004360200200a2000360200200528020021000b2005200041206a360200200420006a220041186a200341186a290000370000200041106a200341106a290000370000200041086a200341086a29000037000020002003290000370000200341206a2103200641606a22060d000c030b0b02400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490d8e0120034101742205200420042005491b22054100480d8e010240024020030d002005102721040c010b200128020020032005102821040b2004450d850120012004360200200141046a2005360200200141086a28020021030b200141086a200341016a360200200420036a41103a00002000280204417f6a220341014b0d010240024020030e020001000b02400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490d8f0120034101742205200420042005491b22054100480d8f010240024020030d002005102721040c010b200128020020032005102821040b2004450d870120012004360200200141046a2005360200200141086a28020021030b200141086a200341016a360200200420036a41003a00002000280208200110320c020b02400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490d8e0120034101742205200420042005491b22054100480d8e010240024020030d002005102721040c010b200128020020032005102821040b2004450d870120012004360200200141046a2005360200200141086a28020021030b200141086a200341016a360200200420036a41013a0000200041086a200110510c010b02400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490d8d0120034101742205200420042005491b22054100480d8d010240024020030d002005102721040c010b200128020020032005102821040b2004450d870120012004360200200141046a2005360200200141086a28020021030b200141086a2205200341016a360200200420036a41113a0000200241003a001c02400240200141046a28020020052802002203460d00200128020021040c010b200341016a22042003490d8d0120034101742205200420042005491b22054100480d8d010240024020030d002005102721040c010b200128020020032005102821040b2004450d880120012004360200200141046a2005360200200141086a28020021030b200141086a2205200341016a360200200420036a41003a00002000290308210702400240200141046a2802002204200528020022036b4108490d00200128020021040c010b200341086a22052003490d8d0120044101742203200520052003491b22034100480d8d010240024020040d002003102721040c010b200128020020042003102821040b2004450d890120012004360200200141046a2003360200200141086a28020021030b200141086a2205200341086a360200200420036a2007370000200041106a20011061200041286a280200210602400240200141046a2802002204200528020022036b4104490d00200128020021040c010b200341046a22052003490d8d0120044101742203200520052003491b22034100480d8d010240024020040d002003102721040c010b200128020020042003102821040b2004450d8a0120012004360200200141046a2003360200200141086a28020021030b200141086a2205200341046a360200200420036a200636000002400240200141046a2802002204200528020022036b4120490d00200128020021040c010b200341206a22052003490d8d0120044101742203200520052003491b22034100480d8d010240024020040d002003102721040c010b200128020020042003102821040b2004450d8b0120012004360200200141046a2003360200200141086a28020021030b200141086a2205200341206a360200200420036a220341186a2000412c6a220441186a290000370000200341106a200441106a290000370000200341086a200441086a29000037000020032004290000370000200028025021062002200041d8006a2802002200360208200241086a2001103002400240200141046a2802002204200528020022036b2000490d00200128020021040c010b200320006a22052003490d8d0120044101742203200520052003491b22034100480d8d010240024020040d002003102721040c010b200128020020042003102821040b2004450d8c0120012004360200200141046a2003360200200141086a28020021030b200141086a200320006a360200200420036a2006200010ce041a0b200241206a24000f0b20054101102a000b20044101102a000b20054101102a000b20034101102a000b20054101102a000b20004101102a000b20054101102a000b20034101102a000b20044101102a000b20054101102a000b20054101102a000b20054101102a000b20004101102a000b20044101102a000b20054101102a000b20054101102a000b20054101102a000b20054101102a000b20004101102a000b20004101102a000b20004101102a000b20004101102a000b20044101102a000b20054101102a000b20044101102a000b20044101102a000b200a4101102a000b200a4101102a000b20054101102a000b20054101102a000b20054101102a000b20054101102a000b20054101102a000b20054101102a000b20054101102a000b20054101102a000b20054101102a000b200a4101102a000b20054101102a000b20054101102a000b20054101102a000b20054101102a000b20054101102a000b20054101102a000b20054101102a000b200a4101102a000b20004101102a000b20054101102a000b20054101102a000b20034101102a000b20034101102a000b20034101102a000b200a4101102a000b20054101102a000b20054101102a000b200a4101102a000b200a4101102a000b200a4101102a000b200a4101102a000b200a4101102a000b200a4101102a000b20034101102a000b20004101102a000b200a4101102a000b20004101102a000b20054101102a000b20054101102a000b20094101102a000b20054101102a000b20034101102a000b20004101102a000b200a4101102a000b20004101102a000b20054101102a000b20054101102a000b102b000b200a4101102a000b20004101102a000b20054101102a000b200a4101102a000b20004101102a000b200a4101102a000b20004101102a000b20064101102a000b20054101102a000b20054101102a000b20054101102a000b20054101102a000b20054101102a000b200b4101102a000b20004101102a000b20054101102a000b200b4101102a000b20004101102a000b20054101102a000b20054101102a000b20054101102a000b20054101102a000b20054101102a000b20054101102a000b20054101102a000b20054101102a000b20054101102a000b20054101102a000b20054101102a000b20054101102a000b20034101102a000b20054101102a000b20054101102a000b20054101102a000b20054101102a000b20054101102a000b20054101102a000b20054101102a000b20034101102a000b20054101102a000b20034101102a000b20064101102a000b20044101102a000b20034101102a000b20054101102a000b20004101102a000b20044101102a000b20054101102a000b20004101102a000b20064101102a000b20044101102a000b20044101102a000b20034101102a000b20004101102a000b20054101102a000b20054101102a000b20054101102a000b20054101102a000b20054101102a000b20034101102a000b20034101102a000b20034101102a000b20034101102a000b102b000bae0401067f230041106b2202240020024100360208200242013703002000280200210320022000280208220036020c2002410c6a200210300240024002400240024020000d002002280208210020022802042104200228020021050c010b200041b0016c21062002280204210420022802082100034020034188016a280200210702400240200420006b4104490d00200228020021040c010b200041046a22052000490d0520044101742200200520052000491b22004100480d050240024020040d002000102721040c010b200228020020042000102821040b2004450d032002200036020420022004360200200228020821000b2002200041046a360208200420006a20073600002003200210320240024020022802042204200228020822006b4120490d00200228020021050c010b200041206a22072000490d0520044101742200200720072000491b22074100480d050240024020040d002007102721050c010b200228020020042007102821050b2005450d04200220073602042002200536020020022802082100200721040b200520006a220741086a20034194016a290000370000200741106a2003419c016a290000370000200741186a200341a4016a2900003700002002200041206a220036020820072003418c016a290000370000200341b0016a2103200641d07e6a22060d000b0b2001280200200128020420052000100302402004450d00200510290b200241106a24000f0b20004101102a000b20074101102a000b102b000b840403057f027e027f230041106b2202240020024100360208200242013703002000280200210320022000280208220036020c2002410c6a200210300240024020000d002002280208210420022802042100200228020021050c010b2003200041306c6a21062002280200210520022802042100200228020821040340200341086a29030021072003290300210802400240024002400240200020046b4110490d00200441106a21090c010b200441106a22092004490d012000410174220a20092009200a491b220a4100480d010240024020000d00200a102721050c010b20052000200a102821050b2005450d02200a21000b200520046a22042007370008200420083700000240200020096b4120490d00200941206a21040c030b200941206a22042009490d002000410174220a20042004200a491b220a4100480d000240024020000d00200a102721050c010b20052000200a102821050b02402005450d00200a21000c030b200a4101102a000b102b000b200a4101102a000b200520096a220941186a200341286a290000370000200941106a200341206a290000370000200941086a200341186a2900003700002009200341106a290000370000200341306a22032006470d000b2002200036020420022004360208200220053602000b2001280200200128020420052004100302402000450d00200510290b200241106a24000b990501077f230041106b2202240020024100360208200242013703002000280200210320022000280208220036020c2002410c6a2002103002400240024002400240024020000d002002280208210420022802042105200228020021000c010b200041216c210603400240024020032d00004101460d00024002402002280204220520022802082207460d00200228020021000c010b200741016a22002007490d0820074101742205200020002005491b22054100480d080240024020070d002005102721000c010b200228020020072005102821000b2000450d0520022005360204200220003602000b2002200741016a2204360208200020076a41003a00000c010b024002402002280204220520022802082207460d00200228020021000c010b200741016a22002007490d0720074101742205200020002005491b22054100480d070240024020070d002005102721000c010b200228020020072005102821000b2000450d0520022005360204200220003602000b2002200741016a2208360208200020076a41013a000002400240200520086b4120490d00200741216a21040c010b200841206a22042008490d0720054101742207200420042007491b22074100480d070240024020050d002007102721000c010b200020052007102821000b2000450d062002200736020420022000360200200721050b200020086a220741086a200341016a220841086a290000370000200741106a200841106a290000370000200741186a200841186a29000037000020022004360208200720082900003700000b200341216a21032006415f6a22060d000b0b2001280200200128020420002004100302402005450d00200010290b200241106a24000f0b20054101102a000b20054101102a000b20074101102a000b102b000b9203010a7f200041086a220228020021034100210420024100360200024002402003450d004100210541002106410021044100210702400340024002402004450d00200741057421080340200720034f0d062001200028020022096b2008460d02200920086a220a2001412010d004450d020240200620076a220b20034f0d00200920056a20086a2209200a290000370000200941186a200a41186a290000370000200941106a200a41106a290000370000200941086a200a41086a290000370000200841206a2108200741016a22072003490d010c050b0b419481c000200b20031037000b200028020020074105746a21080340200720034f0d0520012008460d0120082001412010d004450d01200841206a2108200741016a22072003490d000b410021040c030b200541606a21052006417f6a2106200441016a2104200741016a22072003490d000b0b2004450d00200320074d0d00200028020020074105746a220820044105746b2008200320076b41057410cf041a0b2002200320046b3602000f0b41b880c000200720031037000b6c01017f230041306b2203240020032002360204200320013602002003411c6a41023602002003412c6a41013602002003420237020c200341a8d6c500360208200341013602242003200341206a360218200320033602282003200341046a360220200341086a20001057000bae0a03027f017e1a7f230041f0006b22022400024002400240024002400240024020012802082203ad42f8007e2204422088a70d002004a72205417f4c0d00200128020021060240024020050d00410821070c010b200510272207450d020b0240024020030d00410021080c010b2006200341f8006c6a2109410021082007210a0340200241c0006a41086a220b2006411c6a290000370300200241c0006a41106a220c200641246a290000370300200241c0006a41186a220d2006412c6a290000370300200241206a41086a220e2006413c6a29000037030020062900142104200241206a41106a220f200641c4006a290000370300200241206a41186a2210200641cc006a290000370300200241106a2211200641e4006a290000370300200241086a2212200641dc006a290000370300200241186a2213200641ec006a29000037030020022004370340200220062900343703202002200629005437030020062802102214ad42247e2204422088a70d022004a72201417f4c0d0220062903002104200628020821150240024020010d00410421160c010b200110272216450d050b0240024020140d00410021170c010b201441246c211841002119410021170340024002400240024002400240201520196a22012d00000e050001020304000b2002200141146a2900003703602002200141196a290000370065200141056a2f0000200141076a2d000041107472211a200141106a280000211b2001410c6a2800002105200141086a280000211c200141016a280000211d4100211e0c040b200141106a2802002205417f4c0d08200141086a280200211b200141016a280000211d4101211e4101211c02402005450d0020051027221c450d0c0b201c201b200510ce041a2005211b0c030b200141106a2802002205417f4c0d07200141086a280200211e200141016a280000211d0240024020050d004101211c0c010b20051027221c450d0c0b201c201e200510ce041a4102211e2005211b0c020b200141106a2802002205417f4c0d06200141086a280200211e200141016a280000211d0240024020050d004101211c0c010b20051027221c450d0c0b201c201e200510ce041a4103211e2005211b0c010b2001410c6a280200221c417f4c0d05200141046a280200210102400240201c0d00410121050c010b201c10272205450d0c0b20052001201c10ce042201410876211a2001411874211d4104211e201c21050b201620196a2201201e3a0000200141076a201a4110763a0000200141056a201a3b0000200141106a201b3600002001410c6a2005360000200141086a201c360000200141016a201d360000200141146a20022903603702002001411c6a200241e0006a41086a290300370200201741016a21172018201941246a2219470d000b0b200a2016360208200a410c6a2014360200200a41106a2017360200200a2002290340370214200a411c6a200b290300370200200a2004370300200a2002290320370234200a41246a200c290300370200200a412c6a200d290300370200200a413c6a200e290300370200200a41c4006a200f290300370200200a41cc006a2010290300370200200a41ec006a2013290300370200200a41e4006a2011290300370200200a41dc006a2012290300370200200a2002290300370254200841016a2108200a41f8006a210a200641f8006a22062009470d000b0b200020083602082000200336020420002007360200200241f0006a24000f0b1039000b20054108102a000b20014104102a000b20054101102a000b20054101102a000b20054101102a000b201c4101102a000b0500102b000b900201077f024020002802082201200028020c460d0003402000200141306a36020820012d00284102460d01200141246a2802002102200141206a2802002103200141146a2802002104200128021c2105200128021021060240200141186a2802002201450d002001410c6c21072006210103400240200141046a280200450d00200128020010290b2001410c6a2101200741746a22070d000b0b02402004450d00200610290b02402002450d002002410c6c21072005210103400240200141046a280200450d00200128020010290b2001410c6a2101200741746a22070d000b0b02402003450d00200510290b20002802082201200028020c470d000b0b02402000280204450d00200028020010290b0bbb06020c7f017e230041b0056b2202240020022001102e02400240024002400240024020022802000d00200041003602000c010b0240024020022802042203411c2003411c491b22040d00410821050c010b20044190016c220610272205450d020b02402003450d0020024198036a41047221074100210841002106410021090340200241003a00a004200241a0046a2001280200220a2001280204220b410047220c10ce041a200b200c490d042001200b200c6b3602042001200a200c6a36020002400240024002400240200b450d0020022d00a004220b41014b0d000240200b0e020400040b200241a0046a2001103c0240024020022802a0044112460d0020024198036a200241a0046a41880110ce041a200241003602ac05200241ac056a2001280200220a2001280204220b4104200b4104491b220c10ce041a2001200b200c6b3602042001200a200c6a360200200b41034b0d0120024198036a103d0b200241a0046a20024194026a41840110ce041a0c010b20022802ac05210d200228029803210c20024194026a200741840110ce041a200241a0046a20024194026a41840110ce041a200c4112470d010b200241a0046a20024190016a41840110ce041a0c010b20024190016a200241a0046a41840110ce041a200241a0046a20024190016a41840110ce041a200c4113470d020b2000410036020002402009450d00200521010340024020012802004112460d002001103d0b20014190016a2101200641f07e6a22060d000b0b2004450d04200510290c040b200241a0046a20024190016a41840110ce041a4112210c0b200941016a210b2002410c6a200241a0046a41840110ce041a024020092004470d002008200b200b2008491b2204ad4290017e220e422088a70d07200ea7220a4100480d070240024020090d00200a102721050c010b20052006200a102821050b2005450d060b200520066a2209200c360200200941046a2002410c6a41840110ce041a20094188016a200d360200200841026a210820064190016a2106200b21092003200b470d000b0b2000200436020420002005360200200041086a20033602000b200241b0056a24000f0b20064108102a000b200c200b103e000b200a4108102a000b102b000bfe5e07067f017e047f037e017f037e047f23004190096b22022400200241003a00e803200241e8036a2001280200220320012802042204410047220510ce041a0240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024020042005490d002001200420056b22063602042001200320056a2205360200024020040d00200041123602000c290b0240024002400240024002400240024002400240024020022d00e803220441114b0d0002400240024002400240024002400240024002400240024002400240024002400240024020040e12000102030405060708090a0b0c0d0e0f1011000b200241003a00f008200241f0086a20052006410047220410ce041a20062004490d1d2001200620046b22033602042001200520046a22053602002006450d4220022d00f008220641054b0d42410121070240024002400240024020060e06480001020304480b200241f8056a2001104420022802f8052204450d4620022902fc052108410221070c470b200242003703f805200241f8056a20052003410820034108491b220410ce041a2001200320046b3602042001200520046a360200200341074d0d4520022903f8052108410321070c460b200241f8056a2001104420022802f8052204450d4420022902fc052108410421070c450b20022001102e2002280200450d43024002402002280204220941aa01200941aa01491b220a0d00410421040c010b200a41186c220510272204450d200b02402009450d0020024180066a210b4100210741002105410021030340200241e8036a200110440240024020022802e803220c450d0020022902ec032108200241f8056a2001104420022802f8050d012008a7450d00200c10290b02402003450d002004210103400240200141046a280200450d00200128020010290b0240200141106a280200450d002001410c6a28020010290b200141186a2101200541686a22050d000b0b200a0d450c460b200341016a2106200b350200210d20022903f805210e02402003200a470d002007200620062007491b220aad42187e220f422088a70d3c200fa722104100480d3c0240024020030d002010102721040c010b200420052010102821040b2004450d230b200420056a2203200c360200200341146a200d3e02002003410c6a200e370200200341046a2008370200200741026a2107200541186a21052006210320092006470d000b0b2004450d432009ad422086200aad842108410521070c440b200241086a2001102e2002280208450d4202400240200228020c220941d502200941d502491b220a0d00410421040c010b200a410c6c220510272204450d210b02402009450d004100210741002105410021030340200241f8056a20011044024020022802f805220c0d0002402003450d002004210103400240200141046a280200450d00200128020010290b2001410c6a2101200541746a22050d000b0b200a450d450c440b200341016a210620022902fc05210802402003200a470d002007200620062007491b220aad420c7e220d422088a70d3b200da7220b4100480d3b0240024020030d00200b102721040c010b20042005200b102821040b2004450d240b200420056a2203200c360200200341046a2008370200200741026a21072005410c6a21052006210320092006470d000b0b2004450d422009ad422086200aad842108410621070c430b200241003a00e803200241e8036a20052006410047220410ce041a20062004490d212001200620046b3602042001200520046a360200200041123602000c430b200241003a00e803200241e8036a20052006410047220410ce041a20062004490d212001200620046b3602042001200520046a36020002402006450d0020022d00e8030d00200241106a200110522002290310a7450d002002290318210820004102360200200041086a2008370300200041106a200241f0046a41f80010ce041a0c430b200041123602000c420b200241003a00e803200241e8036a20052006410047220410ce041a20062004490d212001200620046b3602042001200520046a36020002402006450d0020022d00e8030d00200241206a2001102e2002280220450d000240024020022802242209412220094122491b220a0d004108210c0c010b200a41f8006c22041027220c450d240b02402009450d00200241f0046a410c6a210b4100210741002106410021050340200241f0046a2001108e0220022903f004210820022802f8042103200241e8036a200b41ec0010ce041a024020030d0002402005450d00200c20066a2103200c210603400240200641106a2802002204450d0020062802082101200441246c210403400240024020012d0000220541034b0d0002400240024020050e0404000102040b2001410c6a280200450d03200141086a28020010290c030b2001410c6a280200450d02200141086a28020010290c020b2001410c6a280200450d01200141086a28020010290c010b200141086a280200450d00200141046a28020010290b200141246a21012004415c6a22040d000b0b200641f8006a210102402006410c6a280200450d00200628020810290b2001210620032001470d000b0b200a450d03200c10290c030b200541016a210420024180086a200241e8036a41ec0010ce041a02402005200a470d002007200420042007491b220aad42f8007e220d422088a70d39200da722104100480d390240024020050d0020101027210c0c010b200c200620101028210c0b200c450d270b200c20066a22052008370300200541086a20033602002005410c6a20024180086a41ec0010ce041a200741026a2107200641f8006a21062004210520092004470d000b0b200c0d120b200041123602000c410b200241003a00e803200241e8036a20052006410047220410ce041a20062004490d232001200620046b3602042001200520046a360200200041123602000c400b200241003a00f008200241f0086a20052006410047220410ce041a20062004490d232001200620046b3602042001200520046a36020002402006450d0020022d00f008220441014b0d0002400240024020040e020001000b200241f8056a2001105020022d00f80522044102460d0220022d00fb05210320022f00f905210720024184066a290200210820024198066a280200210520024190066a290300210d2002418c066a280200210620022902fc05210e200241286a200110532002280228450d0220072003411074722101200241286a41106a290300210f41012103200229033021110c010b200241f8056a2001105020022d00f80522044102460d0120022d00fb05210320022f00f905210720024184066a290200210820024198066a280200210520024190066a290300210d2002418c066a280200210620022902fc05210e200241d8006a200110532002290358a7450d01200241d8006a41106a290300210f20022903602111200241c0006a200110532002290340a7450d0120072003411074722101200241d0006a290300211220022903482113410221030b200020013b000d200041053602002000410f6a20014110763a0000200041c8006a2012370200200041c0006a2013370200200041386a200f370200200041306a2011370200200041186a2008370000200041106a200e3700002000412c6a2005360000200041246a200d370000200041206a20063600002000410c6a20043a0000200041086a2003360200200041d0006a20022903f004370300200041d8006a200241f0046a41086a290300370300200041e0006a200241f0046a41106a290300370300200041e8006a200241f0046a41186a290300370300200041f0006a200241f0046a41206a290300370300200041f8006a20024198056a29030037030020004180016a200241f0046a41306a2903003703000c400b200041123602000c3f0b200241003a00f008200241f0086a20052006410047220410ce041a20062004490d232001200620046b22093602042001200520046a220b3602002006450d3a20022d00f008220a410c4b0d3a41042107024002400240024002400240024002400240024002400240200a0e0d00010245030405060708090a0b000b200241f8056a2001105020022d00f80522044102460d4520022d00fb05210a20022f00f905210920024184066a290200210d20024198066a280200210320024190066a29030021082002418c066a280200210520022902fc05210e200241f0006a200110532002290370a7450d45200241f0006a41106a29030021112002290378210f200241003a00f008200241f0086a2001280200220c20012802042206410047220710ce041a20062007490d2f2001200620076b3602042001200c20076a3602002006450d4520022d00f008220641024b0d452009200a41107472210c410121070c440b20024188016a20011053200229038801a7450d4420024198016a290300210d200229039001210e200220022f01f8053b018008410221074100210c0c430b200241a0016a2001105320022903a001a7450d43200241b0016a290300210d20022903a801210e200220022f01f8053b018008410321074100210c0c420b200241d0016a2001102e20022802d001450d4220022802d4012105200241b8016a2001105320022903b801a7450d42200241c8016a290300210d20022903c001210e200220022f01f8053b018008410521074100210c0c410b200241d8016a2001102e20022802d801450d410240024020022802dc01221441f100201441f100491b22150d00410421040c010b201541246c220510272204450d2d0b02402014450d004120210320024184066a211641002107410021050340200241f8056a20011050024020022d00f805220c4102470d002015450d44200410290c440b200541016a210620022d00fb05210a20022f00f90521092016290200210820022902fc05210d200228029806210b200229039006210e200228028c062110024020052015470d002007200620062007491b2215ad42247e220f422088a70d3c200fa722174100480d3c0240024020050d002017102721040c010b2004200341606a2017102821040b2004450d300b200420036a2205200b360000200541616a220b2009200a41107472220a3b0000200541646a220920083700082009200d370000200541786a200e370000200541746a2010360000200541606a200c3a0000200b41026a200a4110763a0000200741026a2107200341246a21032006210520142006470d000b0b2004450d412014ad4220862015ad84210e200220022f01e8033b0180082004410876210c410621070c400b410721070c3f0b200241003a00f008200241f0086a200b2009410047220410ce041a20092004490d2c2001200920046b3602042001200b20046a3602002009450d3f20022d00f008220641034f0d3f200220022f01f8053b018008410821074200210d4100210c0c3e0b200241f8056a2001105020022d00f80522044102460d3e20024184066a290200210d20022902fc05210e200220022f01e8033b01800820022f00f90520022d00fb0541107472210c2002418c066a280200210520024190066a290300210820024198066a2802002103410921070c3d0b200241e0016a2001102e20022802e001450d3d20022802e4012104200220022f01f8053b0180082004410876210c410a21074200210d0c3c0b410b21070c3b0b200241e8016a2001102e20022802e801450d3b20022802ec012104200220022f01f8053b0180082004410876210c410c21074200210d0c3a0b200241f8056a2001102d20022802f8052204450d3a200220022f01e8033b0180082004410876210c20022902fc05210e410d21070c390b200241003a00f008200241f0086a20052006410047220410ce041a20062004490d272001200620046b22033602042001200520046a220436020002402006450d0020022d00f0080d00200241e0076a2003412020034120491b22056a41004100412020056b2005411f4b1b10cd041a200241e0076a2004200510ce041a2001200320056b22063602042001200420056a22053602002003411f4d0d00200241f0086a41086a2203200241e0076a41086a2207290300370300200241f0086a41106a220c200241e0076a41106a220a290300370300200241f0086a41186a2209200241e0076a41186a220b290300370300200220022903e00722083703a007200220083703f008200241e0076a2006412020064120491b22046a41004100412020046b2004411f4b1b10cd041a200241e0076a2005200410ce041a2001200620046b3602042001200520046a3602002006411f4d0d0020024180076a41086a2204200729030037030020024180076a41106a2205200a29030037030020024180076a41186a2206200b290300370300200241f0046a41186a22072009290300370300200241f0046a41106a220a200c290300370300200241f0046a41086a220c2003290300370300200220022903e00722083703a0072002200837038007200220022903f0083703f004200241f0046a41386a22032006290300370300200241f0046a41306a22062005290300370300200241f0046a41286a22052004290300370300200220022903800737039005200241f8056a41386a22042003290300370300200241f8056a41306a22032006290300370300200241f8056a41286a22062005290300370300200241f8056a41206a2205200229039005370300200241f8056a41186a2007290300370300200241f8056a41106a200a290300370300200241f8056a41086a200c290300370300200220022903f0043703f805200241f0046a2001104420022802f00422010d0f0b200041123602000c3d0b200241f8056a2001108f02200220022f01fa053b01e80320022d00f80522014112470d0e200041123602000c3c0b200241f8056a2001109002200241e8036a41086a2201200241f8056a41096a290000370300200241e8036a41106a220420024189066a290000370300200241e8036a41186a220520024191066a290000370300200241e8036a411f6a220620024198066a290000370000200220022900f9053703e80320022d00f80522034105470d0e200041123602000c3b0b200241f8056a2001109002200241e8036a41086a220120024181066a290000370300200241e8036a41106a220420024189066a290000370300200241e8036a41186a220520024191066a290000370300200241e8036a411f6a220620024198066a290000370000200220022900f9053703e80320022d00f80522034105470d0e200041123602000c3a0b200241003a00f008200241f0086a20052006410047220410ce041a20062004490d242001200620046b3602042001200520046a3602002006450d3320022d00f008220441094b0d33024002400240024002400240024002400240024020040e0a00010203040506070809000b200241f8056a2001104220022802f8052204450d3c20022902fc052108200241f0016a2001102e2008a72105024020022802f0010d002005450d3d0c3c0b20022802f4012106200241003602f805200241f8056a2001280200220c20012802042203410420034104491b220710ce041a2001200320076b3602042001200c20076a3602000240200341034b0d0020050d3c0c3d0b2008422088210820024180086a41086a200241e8036a41086a280200360200200220022902e80337038008200541087621092004410876210b20022802f80521014101210a0c3a0b200241f8056a2001104220022802f8052204450d3b20022902fc052108200241f8016a2001102e2008a72105024020022802f8010d0020050d3b0c3c0b20022802fc012106200241003602f805200241f8056a2001280200220c20012802042203410420034104491b220710ce041a2001200320076b3602042001200c20076a3602000240200341034b0d0020050d3b0c3c0b2008422088210820024180086a41086a200241e8036a41086a280200360200200220022902e80337038008200541087621092004410876210b20022802f80521014102210a0c390b20024190026a2001102e200228029002450d3a2002280294022104200241f8056a2001105020022d00f80522054102460d3a20022d00fb05210620022f00f905210320024184066a290200210e20024198066a280200210720024190066a290300210d2002418c066a280200210a20022902fc05210820024188026a2001102e200228028802450d3a200228028c02210c20024180026a2001102e200228028002450d3a2003200641107472210920022802840221012002200d370284082002200a360280082004410876210b2008422088a72106200e422088a721032001ad210d200ea721014200210e4103210a0c380b20024198026a2001102e200228029802450d39200228029c02210420024180086a41086a200241f8056a41086a280200360200200220022902f805370380082004410876210b4104210a0c360b200241a0026a2001102e20022802a002450d3820022802a402210420024180086a41086a200241f8056a41086a280200360200200220022902f805370380082004410876210b4105210a0c350b200241f8056a2001105020022d00f80522044102460d3720022d00fb05210520022f00f905210620024184066a290200210f20024198066a280200210c20024190066a29030021082002418c066a280200210320022902fc052111200241b0026a2001105320022903b002a7450d37200241b0026a41106a290300210e20022903b802210d200241a8026a2001102e20022802a802450d372006200541107472210b20022802ac0221072002200c360288082002200837038008201142208821082011a722054108762109200f422088a72101200fa721064106210a0c350b200241c8026a2001102e20022802c802450d3620022802cc02210420024180086a41086a200241f8056a41086a280200360200200220022902f805370380082004410876210b4107210a0c330b200241f8056a2001105020022d00f80522044102460d3520024184066a290200210d20022902fc05210e200220024198066a28020036028808200220024190066a29030037038008200e42208821084108210a200ea72205410876210920022f00f90520022d00fb0541107472210b200d422088a721012002418c066a2802002103200da721060c330b200241d0026a2001105220022903d002a7450d3420022903d802220d4220882108200da7220541087621094109210a0c320b200241e0026a2001105220022903e002a7450d3320022903e802220d4220882108200da722054108762109410a210a0c310b200241003a00e803200241e8036a20052006410047220410ce041a20062004490d242001200620046b3602042001200520046a36020002402006450d0020022d00e8030d00200241f0026a2001105220022903f002a7450d0020022903f80221082000410c360200200041086a2008370300200041106a200241f0046a41f80010ce041a0c390b200041123602000c380b200241003a00e803200241e8036a20052006410047220410ce041a20062004490d242001200620046b3602042001200520046a36020002402006450d0020022d00e8030d00200241f8056a2001104420022802f80522010d0d0b200041123602000c370b200241003a00f008200241f0086a20052006410047220410ce041a20062004490d242001200620046b3602042001200520046a36020002402006450d0020022d00f008220441024b0d0002400240024020040e03000102000b20024180036a20011053200229038003a7450d0220024190036a2903002108200229038803210d200241f8056a2001105020022d00f80522014102460d0220022f00f90520022d00fb0541107472210420024184066a290200210e2002418c066a280200210520024190066a290300210f20024198066a280200210620022902fc052111410121030c2f0b20024198036a2001102e200228029803450d01200228029c032201410876210442002111410221030c2d0b200241a0036a2001102e20022802a003450d0020022802a4032201410876210442002111410321030c2c0b200041123602000c360b200241f0046a200110910220022d00f0042101200241f8056a200241f0046a41017241ff0010ce041a20014107470d0b200041123602000c350b200241003a00e803200241e8036a20052006410047220410ce041a20062004490d232001200620046b3602042001200520046a36020002402006450d0020022d00e803220441014b0d0002400240024020040e020001000b200241f0046a2001103c20022802f0042104200241f8056a200241f0046a41047241840110ce041a20044112460d02200241e8036a200241f8056a41840110ce041a41880110272201450d2720012004360200200141046a200241e8036a41840110ce041a200241f0086a41086a200241b0036a41086a290200370300200241f0086a41106a200241b0036a41106a290200370300200241f0086a41186a200241b0036a41186a290200370300200220022902b0033703f008410121040c010b200241f0046a20011050200241f8056a41086a2201200241fc046a290200370300200241f8056a41106a220520024184056a290200370300200241f8056a41186a22062002418c056a290200370300200220022902f4043703f8054102210420022d00f00422034102460d0120022d00f304210720022f00f104210c200241f0086a41186a2006290300370300200241f0086a41106a2005290300370300200241f0086a41086a2001290300370300200220022903f8053703f008200c20074110747241087420037221010b200241e0076a41086a200241f0086a41086a2903002208370300200241e0076a41106a200241f0086a41106a290300220d370300200241e0076a41186a200241f0086a41186a290300220e370300200220022903f008220f3703e007200041086a200136020020002004360204200041103602002000410c6a200f370200200041146a20083702002000411c6a200d370200200041246a200e3702002000412c6a20024180086a41dc0010ce041a0c350b200041123602000c340b200241003a00f008200241f0086a20052006410047220410ce041a20062004490d242001200620046b22033602042001200520046a220436020002402006450d0020022d00f0080d00200242003703f805200241f8056a20042003410820034108491b220510ce041a2001200320056b3602042001200420056a360200200341074d0d0020022903f805210f200241f8056a2001104420022802f8052210450d0020022902fc05210e200241a8036a2001102e200ea721150240024020022802a803450d000240024020022802ac03220941d502200941d502491b220a0d00410421070c010b200a410c6c220410272207450d290b02402009450d004100210341002104410021060340200241f8056a20011044024020022802f805220c0d0002402006450d002007210103400240200141046a280200450d00200128020010290b2001410c6a2101200441746a22040d000b0b200a450d03200710290c030b200641016a210520022902fc05210802402006200a470d002003200520052003491b220aad420c7e220d422088a70d2d200da7220b4100480d2d0240024020060d00200b102721070c010b20072004200b102821070b2007450d2c0b200720046a2206200c360200200641046a2008370200200341026a21032004410c6a21042005210620092005470d000b0b20070d010b2015450d01201010290c010b200241003602f805200241f8056a2001280200220320012802042204410420044104491b220610ce041a2001200420066b22053602042001200320066a22033602002009ad422086200aad842208422088a721062008a7210c02400240200441034b0d0002402015450d00201010290b02402006450d002006410c6c21042007210103400240200141046a280200450d00200128020010290b2001410c6a2101200441746a22040d000b0b200c0d010c020b20022802f805210a200241e0076a2005412020054120491b22046a41004100412020046b2004411f4b1b10cd041a200241e0076a2003200410ce041a2001200520046b3602042001200320046a36020002402005411f4b0d0002402015450d00201010290b02402006450d002006410c6c21042007210103400240200141046a280200450d00200128020010290b2001410c6a2101200441746a22040d000b0b200c0d010c020b200241a0076a41086a2204200241e0076a41086a290300370300200241a0076a41106a2205200241e0076a41106a290300370300200241a0076a41186a2203200241e0076a41186a290300370300200220022903e0073703a007200241f8056a2001104420022802f80522010d0302402015450d00201010290b02402006450d002006410c6c21042007210103400240200141046a280200450d00200128020010290b2001410c6a2101200441746a22040d000b0b200c450d010b200710290b200241f8056a41186a200241e8036a41186a290300370300200241f8056a41106a200241e8036a41106a290300370300200241f8056a41086a200241e8036a41086a290300370300200220022903e8033703f8050c020b200041123602000c320b200241e8036a41086a20042903002208370300200241e8036a41106a2005290300220d370300200241e8036a41186a20032903002211370300200220022903a00722133703e80320022902fc052112200241f8056a41186a2011370300200241f8056a41106a200d370300200241f8056a41086a2008370300200220133703f80520100d080b200041123602000c300b2000200c36020420004103360200200041086a2009ad422086200aad84370200200041106a200241f8056a41f80010ce041a0c2f0b200241e8036a41086a2207200241f8056a41086a290300370300200241e8036a41106a220c200241f8056a41106a290300370300200241e8036a41186a220a200241f8056a41186a290300370300200241e8036a41206a22092005290300370300200241e8036a41286a22052006290300370300200241e8036a41306a22062003290300370300200241e8036a41386a22032004290300370300200220022903f8053703e80320022902f404210820024180086a41386a2204200329030037030020024180086a41306a2203200629030037030020024180086a41286a2206200529030037030020024180086a41206a2205200929030037030020024180086a41186a2209200a29030037030020024180086a41106a220a200c29030037030020024180086a41086a220c2007290300370300200220022903e80337038008200041086a20083702002000200136020420004107360200200041106a200229038008370200200041186a200c290300370200200041206a200a290300370200200041286a2009290300370200200041306a2005290300370200200041386a2006290300370200200041c0006a2003290300370200200041c8006a200429030037020020004180016a200241b0036a41306a290300370300200041f8006a200241b0036a41286a290300370300200041f0006a200241b0036a41206a290300370300200041e8006a200241b0036a41186a290300370300200041e0006a200241b0036a41106a290300370300200041d8006a200241b0036a41086a290300370300200041d0006a20022903b0033703000c2e0b20022d00f9052104200220022f01e80322053b018008200241f8056a41186a280200210620024194066a2902002108200241f8056a41246a2802002103200241f8056a41086a290300210d200241f8056a41106a290300210e200241a0066a290300210f20022802fc052107200041386a200241f8056a41306a290300370200200041306a200f370200200041186a200e370200200041106a200d370200200020043a0009200041086a20013a0000200041083602002000412c6a2003360200200041246a2008370200200041206a20063602002000410c6a2007360200200020053b000a200041c0006a200241f0046a41c80010ce041a0c2d0b20024180086a411f6a2207200629000037000020024180086a41186a2206200529030037030020024180086a41106a2004290300220837030020024180086a41086a2001290300220d370300200220022903e803220e37038008200020033a0004200041093602002000200e3700052000410d6a200d370000200041156a20083700002000411d6a2006290300370000200041246a20072900003700002000412c6a200241f0046a41dc0010ce041a0c2c0b20024180086a411f6a2207200629000037000020024180086a41186a2206200529030037030020024180086a41106a2004290300220837030020024180086a41086a2001290300220d370300200220022903e803220e37038008200020033a00042000410a3602002000200e3700052000410d6a200d370000200041156a20083700002000411d6a2006290300370000200041246a20072900003700002000412c6a200241f0046a41dc0010ce041a0c2b0b200041086a20022902fc05370200200020013602042000410d360200200041106a200241f0046a41f80010ce041a0c2a0b200241e8036a200241f8056a41ff0010ce041a200041086a20013a00002000410f360200200041096a200241e8036a41ff0010ce041a0c290b20024180086a41186a2204200241f8056a41186a29030037030020024180086a41106a2205200241f8056a41106a29030037030020024180086a41086a2203200241f8056a41086a290300370300200220022903f80537038008200041286a200a360200200041246a2006360200200041206a200c3602002000411c6a2007360200200041186a200e422088a7360200200041146a2015360200200041106a2010360200200041086a200f37020020004111360200200041d4006a2012370200200041d0006a20013602002000412c6a200229038008370200200041346a20032903003702002000413c6a2005290300370200200041c4006a200429030037020020004180016a200241f0046a41206a290300370300200041f8006a200241f0046a41186a290300370300200041f0006a200241f0046a41106a290300370300200041e8006a200241f0046a41086a290300370300200041e0006a20022903f0043703000c280b20052004103e000b20042006103e000b20054104102a000b20104104102a000b20054104102a000b200b4104102a000b20042006103e000b20042006103e000b20042006103e000b20044108102a000b20104108102a000b20042006103e000b20042006103e000b20042006103e000b20072006103e000b20054104102a000b20174104102a000b20042009103e000b20042006103e000b20042006103e000b20042006103e000b20042006103e000b20042006103e000b20042006103e000b4188014108102a000b20042006103e000b20044104102a000b200b4104102a000b102b000b4200210e4200210f0b2000410e360200200041386a2008370200200041306a200d370200200041186a200e370200200041106a20113702002000412c6a2006360200200041246a200f370200200041206a2005360200200041086a20033602002000410c6a2004410874200141ff017172360200200041c0006a200241f0046a41c80010ce041a0c090b42002108410021090b200241b0036a41086a20024180086a41086a28020022103602002002200229038008220f3703b003200041206a20033602002000411c6a2001360200200041186a2006360200200041106a20084220862009ad42ffffff07834208862005ad42ff018384843702002000410c6a200b410874200441ff017172360200200041086a200a3602002000410b360200200041c0006a200e370200200041386a200d370200200041246a200f3702002000412c6a2010360200200041346a200c360200200041306a2007360200200041c8006a20022903f004370300200041d0006a200241f0046a41086a290300370300200041d8006a200241f0046a41106a290300370300200041e0006a200241f0046a41186a290300370300200041e8006a200241f0046a41206a290300370300200041f0006a20024198056a290300370300200041f8006a200241f0046a41306a29030037030020004180016a200241f0046a41386a2903003703000c070b200410290b200041123602000c050b200220022f01800822013b01b003200041386a2011370200200041306a200f370200200041186a200d370200200041106a200e370200200020063a0009200041086a20073a0000200041063602002000412c6a2003360200200041246a2008370200200041206a20053602002000410c6a200c410874200441ff017172360200200020013b000a200041c0006a200241f0046a41c80010ce041a0c040b200041123602000c030b200410290b200041123602000c010b20004100360200200041106a20083702002000410c6a2004360200200041086a2007360200200041186a200241f0046a41f00010ce041a0b20024190096a24000b960b01057f024002402000280200220141104b0d000240024002400240024002400240024002400240024020010e11000c0c010c0c0203040506070c080c090a000b0240200041086a280200220141054b0d0002400240024020010e060f0f000f01020f0b200041106a280200450d0e2000410c6a28020010290f0b200041106a280200450d0d2000410c6a28020010290f0b0240200041146a2802002202450d002000410c6a2802002101200241186c210203400240200141046a280200450d00200128020010290b0240200141106a280200450d002001410c6a28020010290b200141186a2101200241686a22020d000b0b200041106a280200450d0c200028020c10290f0b0240200041146a2802002202450d002000410c6a28020021012002410c6c210203400240200141046a280200450d00200128020010290b2001410c6a2101200241746a22020d000b0b200041106a280200450d0b200028020c10290f0b02402000410c6a2802002201450d0020002802042203200141f8006c6a210403400240200341106a2802002202450d0020032802082101200241246c210203400240024020012d0000220541034b0d0002400240024020050e0404000102040b2001410c6a280200450d03200141086a28020010290c030b2001410c6a280200450d02200141086a28020010290c020b2001410c6a280200450d01200141086a28020010290c010b200141086a280200450d00200141046a28020010290b200141246a21012002415c6a22020d000b0b200341f8006a210102402003410c6a280200450d00200328020810290b2001210320012004470d000b0b200041086a280200450d0a200028020410290f0b0240200041086a2d00002201410c4b0d0020014106470d0a200041106a280200450d0a2000410c6a28020010290f0b200041106a280200450d092000410c6a28020010290f0b200041086a280200450d08200028020410290f0b200041086a2d0000417f6a220141074b0d07024002400240024020010e08000b0b0b010b0203000b2000410c6a2201280200103d200128020010290f0b2000410c6a2201280200103d200128020010290f0b2000410c6a2201280200103d200128020010290f0b2000410c6a2201280200103d200128020010290f0b20002d0004417f6a220141024b0d0602400240024020010e03000102000b2000410c6a280200450d08200041086a28020010290f0b200041086a2201280200103d200128020010290f0b2000410c6a2201280200103d200128020010290f0b20002d0004417f6a220141024b0d0502400240024020010e03000102000b2000410c6a280200450d07200041086a28020010290f0b200041086a2201280200103d200128020010290f0b2000410c6a2201280200103d200128020010290f0b200041086a280200417f6a220141014b0d040240024020010e020001000b200041106a280200450d052000410c6a28020010290f0b200041106a280200450d042000410c6a28020010290f0b200041086a280200450d03200028020410290f0b0240200041086a2d0000220141054b0d0002400240024020010e06060600010206060b200041106a280200450d052000410c6a28020010290f0b200041346a280200450d04200041306a28020010290f0b200041306a280200450d032000412c6a28020010290c030b200041d0006a280200450d02200041cc006a28020010290f0b20002802044101470d01200041086a2201280200103d200128020010290f0b0240200041146a280200450d00200041106a28020010290b0240200041246a2802002202450d002000411c6a28020021012002410c6c210203400240200141046a280200450d00200128020010290b2001410c6a2101200241746a22020d000b0b0240200041206a280200450d00200028021c10290b200041d4006a280200450d00200041d0006a28020010290f0b0b6f01017f230041306b2202240020022001360204200220003602002002411c6a41023602002002412c6a41013602002002420237020c200241a4d9c500360208200241013602242002200241206a3602182002200241046a36022820022002360220200241086a41b4d9c5001057000bfa0702137f017e23004190056b22022400200241086a2001102e0240024002400240024020022802080d00200041003602000c010b02400240200228020c2203411720034117491b22040d00410821050c010b200441b0016c220610272205450d020b02402003450d00200241e0026a4104722107200241f0046a41186a2108200241f0046a41106a2109200241f0046a41086a210a4100210b4100210c4100210d0340200241003602e803200241e8036a2001280200220e20012802042206410420064104491b220f10ce041a20012006200f6b3602042001200e200f6a36020002400240200641034b0d004112210e0c010b20022802e8032110200241e8036a2001103c024020022802e8034112470d004112210e0c010b200241e0026a200241e8036a41880110ce041a2008420037030020094200370300200a4200370300200242003703f004200241f0046a2001280200220e20012802042206412020064120491b220f10ce041a20012006200f6b3602042001200e200f6a36020002402006411f4b0d00200241e0026a103d4112210e0c010b200241b8016a41186a2008290300370300200241b8016a41106a2009290300370300200241b8016a41086a200a290300370300200220022903f0043703b80120022802e002210e200241dc016a200741840110ce041a201021110b200241e8036a200241dc016a41840110ce041a200241e0026a41186a2206200241b8016a41186a290300370300200241e0026a41106a2210200241b8016a41106a290300370300200241e0026a41086a2212200241b8016a41086a290300370300200220022903b8013703e0020240200e4112470d00200041003602000240200d450d002005210603402006103d200641b0016a2106200c41d07e6a220c0d000b0b2004450d03200510290c030b200d41016a210f200241346a200241e8036a41840110ce041a200241106a41186a22132006290300370300200241106a41106a22142010290300370300200241106a41086a22102012290300370300200220022903e0023703100240200d2004470d00200b200f200f200b491b2204ad42b0017e2215422088a70d062015a722064100480d0602400240200d0d002006102721050c010b2005200c2006102821050b2005450d050b2005200c6a2206200e360200200641046a200241346a41840110ce041a20064188016a20113602002006418c016a200229031037020020064194016a20102903003702002006419c016a2014290300370200200641a4016a2013290300370200200b41026a210b200c41b0016a210c200f210d2003200f470d000b0b2000200436020420002005360200200041086a20033602000b20024190056a24000f0b20064108102a000b20064108102a000b102b000b8303020a7f017e230041106b2202240020022001102e0240024002400240024020022802000d00200041003602000c010b02400240200228020422034180042003418004491b22040d00410821050c010b2004410374220610272205450d020b02402003450d00410021074100210841002109034020024200370308200241086a2001280200220a20012802042206410820064108491b220b10ce041a20012006200b6b3602042001200a200b6a3602000240200641074b0d00200041003602002004450d03200510290c030b200941016a21062002290308210c024020092004470d002007200620062007491b220441ffffffff01712004470d062004410374220b4100480d060240024020090d00200b102721050c010b20052008200b102821050b2005450d050b200520086a200c370300200741026a2107200841086a21082006210920032006470d000b0b2000200436020420002005360200200041086a20033602000b200241106a24000f0b20064108102a000b200b4108102a000b102b000bb40502107f027e230041f0006b22022400200241086a2001102e0240024002400240024020022802080d00200041003602000c010b02400240200228020c220341e600200341e600491b22040d00410821050c010b200441286c220610272205450d020b02402003450d00200241d0006a41186a2107200241d0006a41106a2108200241d0006a41086a21094100210a4100210b4100210c034020074200370300200842003703002009420037030020024200370350200241d0006a2001280200220d2001280204220e4120200e4120491b220f10ce041a2001200e200f6b22063602042001200d200f6a220f36020002400240200e411f4d0d00200241306a41186a220d2007290300370300200241306a41106a22102008290300370300200241306a41086a221120092903003703002002200229035037033020024200370350200241d0006a200f2006410820064108491b220e10ce041a20012006200e6b3602042001200f200e6a360200200641074b0d010b200041003602002004450d03200510290c030b200c41016a210e200241106a41086a220f2011290300370300200241106a41106a22112010290300370300200241106a41186a2210200d29030037030020022002290330370310200229035021120240200c2004470d00200a200e200e200a491b2204ad42287e2213422088a70d062013a722064100480d0602400240200c0d002006102721050c010b2005200b2006102821050b2005450d050b2005200b6a22062002290310370300200641186a2010290300370300200641106a2011290300370300200641086a200f290300370300200641206a2012370300200a41026a210a200b41286a210b200e210c2003200e470d000b0b2000200436020420002005360200200041086a20033602000b200241f0006a24000f0b20064108102a000b20064108102a000b102b000be30201097f230041106b2202240020022001102e024002400240024020022802000d00200041003602000c010b02400240200228020422034180202003418020491b22040d00410121050c010b200410272205450d020b02402003450d0041002106410021070340200241003a000f2002410f6a2001280200220820012802042209410047220a10ce041a2009200a490d0420012009200a6b36020420012008200a6a360200024020090d00200041003602002004450d03200510290c030b200741016a210920022d000f210a024020072004470d0002402006200920092006491b22044100480d000240024020070d002004102721050c010b200520072004102821050b20050d0120044101102a000b102b000b200520076a200a3a0000200641026a21062009210720032009470d000b0b2000200436020420002005360200200041086a20033602000b200241106a24000f0b20044101102a000b200a2009103e000bf10b030e7f017e067f230041e0006b22022400200241086a2001102e0240024020022802080d00200041003602000c010b0240024002400240024002400240200228020c220341f100200341f100491b22040d00410421050c010b200441246c220610272205450d010b024020030d00410021070c050b2002412d6a2108200241d3006a220941056a210a4100210b410021070340200241003a0040200241c0006a2001280200220c20012802042206410047220d10ce041a2006200d490d0220012006200d6b220e3602042001200c200d6a220c3602000240024020060d004105210d0c010b4105210d20022d0040220641064b0d000240024002400240024020060e0704050005020301040b200241c0006a200e4120200e4120491b22066a41004100412020066b2006411f4b1b10cd041a200241c0006a200c200610ce041a2001200e20066b3602042001200c20066a360200200e411f4d0d04200220092900003703202002200a2900003700252002280047210f200229004b211020022f0140210620022d0042210d20022800432111200841026a200241306a41026a2d00003a0000200820022f00303b0000201141087621122006200d4110747221132010422088a721142010a721154100210d0c040b20024100360240200241c0006a200c200e4104200e4104491b220610ce041a2001200e20066b3602042001200c20066a360200200e41034d0d0320022d0043210620022f0140210e20022d0042210c200241c0006a2001104420022802402216450d03200e200c41107472211320022902442210422088a721142010a721154101210d200621112016210f0c030b20024100360240200241c0006a200c200e4104200e4104491b220610ce041a2001200e20066b3602042001200c20066a360200200e41034d0d0220022d0043210620022f0140210e20022d0042210c200241c0006a2001104420022802402216450d02200e200c41107472211320022902442210422088a721142010a721154102210d200621112016210f0c020b20024100360240200241c0006a200c200e4104200e4104491b220610ce041a2001200e20066b3602042001200c20066a360200200e41034d0d0120022d0043210620022f0140210e20022d0042210c200241c0006a2001104420022802402216450d01200e200c41107472211320022902442210422088a721142010a721154103210d200621112016210f0c010b200241306a2001104420022802302206450d00200241206a41086a200241c0006a41086a2902003703002002200229024037032020064108762112200228023821152002280234210f4104210d200621110b200241c0006a41086a2206200241206a41086a290300370300200220022903203703400240200d4105470d002000410036020002402007450d002005210603400240024020062d0000220141034b0d0002400240024020010e0404000102040b2006410c6a280200450d03200641086a28020010290c030b2006410c6a280200450d02200641086a28020010290c020b2006410c6a280200450d01200641086a28020010290c010b200641086a280200450d00200641046a28020010290b200641246a2106200b415c6a220b0d000b0b2004450d07200510290c070b200241106a41086a220e200629030037030020022002290340370310024020072004470d00200441016a22062004490d052004410174220c20062006200c491b2206ad42247e2210422088a70d052010a7220c4100480d050240024020040d00200c102721050c010b2005200441246c200c102821050b2005450d04200621040b2005200b6a2206200d3a0000200641106a20143602002006410c6a2015360200200641086a200f360200200641046a2012410874201141ff017172360200200641036a20134110763a0000200641016a20133b0000200641146a20022903103702002006411c6a200e290300370200200b41246a210b2003200741016a2207460d050c000b0b20064104102a000b200d2006103e000b200c4104102a000b102b000b2000200436020420002005360200200041086a20073602000b200241e0006a24000bbd04010a7f230041106b22022400200241086a2001102e0240024002400240024020022802080d00200041003602000c010b0240200228020c2203418020490d00418020107c2204450d044101210541002106410021070340200420012802002001280204220820034180202003418020491b220920082009491b220810ce04210a024002400240200128020422092008490d002001200920086b3602042001200128020020086a36020002402008450d0020084181204f0d020240200620076b2008490d00200820076a21090c040b0240200720086a22092007490d002006410174220b20092009200b491b220b4100480d000240024020060d00200b102721050c010b20052006200b102821050b02402005450d00200b21060c050b200b4101102a000b102b000b20004100360200200a10292006450d05200510290c050b20082009103e000b2008418020107f000b200520076a200a200810ce041a20092107200320086b22030d000b2000200636020420002005360200200041086a2009360200200a10290c010b0240024020030d0041012107410021080c010b2003107c2207450d032007200128020020012802042208200320082003491b220810ce041a200128020422092008490d022001200920086b3602042001200128020020086a3602000b024020082003470d002000200336020420002007360200200041086a20033602000c010b200041003602002003450d00200710290b200241106a24000f0b20082009103e000b20034101102a000b4180204101102a000b8103010a7f230041106b2202240020022001102e0240024002400240024020022802000d00200041003602000c010b02400240200228020422034180082003418008491b22040d00410421050c010b2004410274220610272205450d020b02402003450d0041002107410021084100210903402002410036020c2002410c6a2001280200220a20012802042206410420064104491b220b10ce041a20012006200b6b3602042001200a200b6a3602000240200641034b0d00200041003602002004450d03200510290c030b200941016a2106200228020c210b024020092004470d002007200620062007491b220441ffffffff03712004470d062004410274220a4100480d060240024020090d00200a102721050c010b20052008200a102821050b2005450d050b200520086a200b360200200741026a2107200841046a21082006210920032006470d000b0b2000200436020420002005360200200041086a20033602000b200241106a24000f0b20064104102a000b200a4104102a000b102b000bda0f040d7f017e077f017e23004180026b2202240020022001102e02400240024002400240024020022802000d00200041003602000c010b0240024020022802042203413820034138491b22040d00410821050c010b200441c8006c220610272205450d020b02402003450d00200241ef016a210741c2002108200241b8016a41036a21094100210a4100210b0340200241003a00e001200241e0016a2001280200220c2001280204220d410047220e10ce041a200d200e490d042001200d200e6b22063602042001200c200e6a220e360200024002400240200d450d0020022d00e001220d41014b0d00024002400240200d0e020001000b200242003703a001200241a0016a200e2006410820064108491b220d10ce041a20012006200d6b3602042001200e200d6a360200200641074d0d02200241f8006a41086a200241c0016a41086a290300370300200241f8006a41106a200241c0016a41106a2d00003a0000200241d8006a41086a200241e0016a41086a290100370300200241d8006a41106a200241e0016a41106a290100370300200241d8006a41186a200241e0016a41186a290100370300200220022800b80136029001200220022903c001370378200220022901e001370358200220092800003600930120022903a001210f200241d0006a41046a2002419a016a41046a2f01003b01002002200228019a013602504100210e0c010b200241e0016a2006412020064120491b220d6a410041004120200d6b200d411f4b1b10cd041a200241e0016a200e200d10ce041a20012006200d6b220c3602042001200e200d6a220d3602002006411f4d0d01200241a0016a41086a2210200741086a290000370300200241a0016a41106a2211200741106a2d00003a0000200220022800e0013602b801200220072900003703a0012002200241e0016a41036a2800003600bb0120022900e701210f200241003a00e001200241e0016a200d200c410047220610ce041a200c2006490d092001200c20066b220e3602042001200d20066a220d360200200c450d0120022d00e001220641014b0d014100210c0240024020060e020100010b200241e0016a200e4120200e4120491b22066a41004100412020066b2006411f4b1b10cd041a200241e0016a200d200610ce041a2001200e20066b3602042001200d20066a360200200e411f4d0d02200241c0016a41186a200241e0016a41186a290000370300200241c0016a41106a200241e0016a41106a290000370300200241c0016a41086a200241e0016a41086a290000370300200220022900e0013703c0014101210c0b200241d8006a41186a200241c0016a41186a290300370300200241d8006a41106a200241c0016a41106a290300370300200241d8006a41086a200241c0016a41086a290300370300200241f8006a41086a2010290300370300200241f8006a41106a20112d00003a0000200220022903c001370358200220022802b80136029001200220022800bb0136009301200220022903a001370378200241d0006a41046a2002419a016a41046a2f01003b01002002200228019a013602504101210e0b200b41016a210d200241c0016a41086a2206200241f8006a41086a290300370300200241c0016a41106a2210200241f8006a41106a2d00003a0000200241e0016a41086a2211200241d8006a41086a290300370300200241e0016a41106a2212200241d8006a41106a290300370300200241e0016a41186a2213200241d8006a41186a29030037030020022002280290013602a00120022002280093013600a301200220022903783703c001200220022903583703e001200241b8016a41046a2214200241d0006a41046a2f01003b0100200241306a41086a22152006290300370300200241306a41106a221620102d00003a0000200241106a41086a22102011290300370300200241106a41106a22112012290300370300200241106a41186a22122013290300370300200220022802503602b801200220022800a30136004b200220022802a001360248200220022903c001370330200220022903e001370310200241086a41046a221320142f01003b0100200220022802b801360208200b2004470d020240200a200d200d200a491b2204ad42c8007e2217422088a70d002017a7220641004e0d020b102b000b200241c0016a41086a200241f8006a41086a290300370300200241e0016a41086a200241d8006a41086a290300370300200241e0016a41106a200241d8006a41106a290300370300200220022903783703c001200220022903583703e001200041003602002004450d04200510290c040b02400240200b0d002006102721050c010b2005200841be7f6a2006102821050b2005450d070b200520086a220641be7f6a200e3a0000200641466a200f370000200641bf7f6a220e2002280248360000200e41036a200228004b3600002006414e6a220e2002290330370000200e41086a2015290300370000200e41106a20162d00003a00002006415f6a200c3a0000200641606a220e2002290310370000200e41086a2010290300370000200e41106a2011290300370000200e41186a201229030037000020062002280208360000200641046a20132f01003b0000200a41026a210a200841c8006a2108200d210b2003200d470d000b0b2000200436020420002005360200200041086a20033602000b20024180026a24000f0b20064108102a000b200e200d103e000b2006200c103e000b20064108102a000bff04040c7f027e017f017e230041d0006b22022400200241086a2001102e0240024002400240024020022802080d00200041003602000c010b02400240200228020c220341d500200341d500491b22040d00410821050c010b200441306c220610272205450d020b02402003450d00200241306a41086a210741002108410021094100210a03402002420037033820024200370330200241306a2001280200220b20012802042206411020064110491b220c10ce041a20012006200c6b220d3602042001200b200c6a220c360200024002402006410f4d0d002007290300210e2002290330210f200241306a200d4120200d4120491b22066a41004100412020066b2006411f4b1b10cd041a200241306a200c200610ce041a2001200d20066b3602042001200c20066a360200200d411f4b0d010b200041003602002004450d03200510290c030b200a41016a210d200241106a41186a220c200241306a41186a290000370300200241106a41106a220b200241306a41106a290000370300200241106a41086a22102007290000370300200220022900303703100240200a2004470d002008200d200d2008491b2204ad42307e2211422088a70d062011a722064100480d0602400240200a0d002006102721050c010b200520092006102821050b2005450d050b200520096a2206200e3703082006200f370300200641106a2002290310370300200641186a2010290300370300200641206a200b290300370300200641286a200c290300370300200841026a2108200941306a2109200d210a2003200d470d000b0b2000200436020420002005360200200041086a20033602000b200241d0006a24000f0b20064108102a000b20064108102a000b102b000bff0305087f017e017f017e017f230041e0066b22022400200241086a2001102e024002400240024020022802080d00200041003602000c010b02400240200228020c2203410e2003410e491b22040d00410821050c010b200441a0026c220610272205450d020b02402003450d00200241a8026a41f0006a21074100210841002106410021090340200241a8026a20011049200241f8056a200241a8026a41e80010ce041a200229039003210a200241c8046a200741b00110ce041a024002400240200a4203510d00200941016a210b200241c0016a200241f8056a41e80010ce041a200241106a200241c8046a41b00110ce041a20092004470d0202402008200b200b2008491b2204ad42a0027e220c422088a70d00200ca7220d41004e0d020b102b000b2000410036020002402009450d0020054198016a210b0340200b103d200b41a0026a210b200641e07d6a22060d000b0b2004450d04200510290c040b0240024020090d00200d102721050c010b20052006200d102821050b2005450d050b200520066a200241c0016a41e80010ce04220941e8006a200a370300200941f0006a200241106a41b00110ce041a200841026a2108200641a0026a2106200b21092003200b470d000b0b2000200436020420002005360200200041086a20033602000b200241e0066a24000f0b20064108102a000b200d4108102a000bae0b04047f017e087f057e230041c0056b22022400200241286a2001102e0240024020022802280d00200042033703680c010b200241003a00a002200241a0026a2001280200220320012802042204410047220510ce041a0240024020042005490d002001200420056b3602042001200320056a36020020040d01200042033703680c020b20052004103e000b02400240024020022d00a002220441ff00714102470d0020044118744118754100480d01420221060c020b200042033703680c020b200241d8046a200110500240024020022d00d8044102460d00200241b0046a41206a200241d8046a41206a280200360200200241b0046a41186a200241d8046a41186a290300370300200241b0046a41106a200241d8046a41106a290300370300200241b0046a41086a200241d8046a41086a290300370300200220022903d8043703b00420024198016a41386a2207420037030020024198016a41306a2208420037030020024198016a41286a2209420037030020024198016a41206a220a420037030020024198016a41186a220b420037030020024198016a41106a220c420037030020024198016a41086a220d4200370300200242003703980120024198016a2001280200220e2001280204220441c000200441c000491b220510ce041a2001200420056b22033602042001200e20056a22053602002004413f4d0d0020024180056a41386a200729030037030020024180056a41306a200829030037030020024180056a41286a200929030037030020024180056a41206a200a29030037030020024180056a41186a200b29030037030020024180056a41106a200c29030037030020024180056a41086a200d290300370300200220022903980137038005200241003a00980120024198016a20052003410047220410ce041a0240024020032004490d002001200320046b220e3602042001200520046a22043602002003450d0202400240200231009801220f50450d00420021060c010b200241003a00980120024198016a2004200e410047220510ce041a200e2005490d022001200e20056b3602042001200420056a360200200e450d034202200f420f838622104204540d0342012106200231009801420886200f844204882010420c88220f4201200f4201561b7e220f20105a0d030b200241186a200110522002290318a7450d02200229032021112002200110532002290300a7450d02200241106a290300211220022903082113200241a0026a41206a200241b0046a41206a280200360200200241a0026a41186a200241b0046a41186a290300370300200241a0026a41106a200241b0046a41106a290300370300200241a0026a41086a200241b0046a41086a290300370300200241cc026a20024180056a41086a290300370200200241d4026a20024180056a41106a290300370200200241dc026a20024180056a41186a290300370200200241e4026a20024180056a41206a290300370200200241ec026a200241a8056a290300370200200241f4026a200241b0056a290300370200200241fc026a200241b8056a290300370200200220022903b0043703a00220022002290380053702c402200241a8036a200241a0026a41e80010ce041a0c030b20042003103e000b2005200e103e000b420221060b200241a0026a200241a8036a41e80010ce041a024020064202520d00200042033703680c020b200241306a200241a0026a41e80010ce041a0b200241a0026a2001103c20022802a0022104200241a8036a200241a0026a41047241840110ce041a024020044112470d00200042033703680c010b20024198016a200241a8036a41840110ce041a2000200241306a41e80010ce0422014190016a201237030020014188016a201337030020014198016a200436020020014180016a2011370300200141f8006a200f37030020012010370370200120063703682001419c016a20024198016a41840110ce041a0b200241c0056a24000be20805077f047e087f017e017f230041a0016b22022400024002400240200141086a220328020022042001410c6a2802002205460d0020012802102106200241f8006a41186a2107034020032004220841286a2204360200200841086a2903002109200841106a290300210a200841186a290300210b2008290300210c200241f8006a41206a200841206a2903003703002007200b370300200241f8006a41106a200a370300200241f8006a41086a20093703002002200c3703780240200a2006290300580d002001280214220d2007460d002007290000200d290000520d030b20052004470d000b200521040b2000410036020820004208370200024020042005460d00200141086a200520046b41586a41286e41286c20046a41286a3602000b2001280204450d01200128020010290c010b200241286a41086a200241f8006a41086a290300220a370300200241086a2204200a370300200241106a2207200241f8006a41106a290300370300200241186a2203200241f8006a41186a290300370300200241206a220e200241f8006a41206a29030037030020022002290378220a3703282002200a37030002400240024041281027220f450d00200f2002290300370300200f41206a200e290300370300200f41186a2003290300370300200f41106a2007290300370300200f41086a200429030037030020012802042110200128020021114101210e02400240200541586a2008470d00410121120c010b0240200d200241f8006a41186a2204470d00410121120c010b200841286a2113200541586a21144101210e4101211203402013210802400340200241f8006a41206a2207200841206a2903003703002004200841186a290300370300200241f8006a41106a2203200841106a290300220a370300200241f8006a41086a2201200841086a290300370300200220082903003703780240200a2006290300580d002004290000200d290000520d020b2005200841286a2208470d000c030b0b200241d0006a41206a2007290300220a370300200241286a41086a20012903002209370300200241286a41106a2003290300220b370300200241286a41186a2004290300220c370300200241286a41206a200a3703002002200229037822153703282007200a3703002004200c3703002003200b370300200120093703002002201537037802402012200e470d00200e41016a2212200e490d05200e4101742213201220122013491b2212ad42287e220a422088a70d05200aa722134100480d0502400240200e0d0020131027210f0c010b200f200e41286c20131028210f0b200f450d040b200841286a2113200f200e41286c6a22162002290378370300201641206a2007290300370300201641186a2004290300370300201641106a2003290300370300201641086a2001290300370300200e41016a210e20142008470d000b0b02402010450d00201110290b2000200e360208200020123602042000200f3602000c030b41284108102a000b20134108102a000b102b000b200241a0016a24000bd408040c7f017e057f037e23004180016b22022400024002400240200141086a220328020022042001410c6a2802002205460d002001280210220628020021072006280208220841014b210903402003200441206a220a360200200241e0006a41186a200441186a290000370300200241e0006a41106a200441106a290000370300200241e0006a41086a200441086a29000037030020022004290000370360410021040240024020090d0020080e020401040b2008210b0340200b410176220c20046a220d20042007200d4105746a200241e0006a412010d0044101481b2104200b200c6b220b41014b0d000b0b200720044105746a200241e0006a412010d0040d02200a2104200a2005470d000b200521040b2000410036020820004201370200024020042005460d00200141086a200520046b41606a41607120046a41206a3602000b2001280204450d01200128020010290c010b200241c0006a41086a2204200241e0006a41086a290300370300200241c0006a41106a220b200241e0006a41106a290300370300200241c0006a41186a220c200241e0006a41186a29030037030020022002290360220e3703002002200e370340024041201027220f450d00200f2002290340370000200f41186a200c290300370000200f41106a200b290300370000200f41086a2004290300370000200128020421102001280200211102400240200a2005470d0041012112410121130c010b41012112410121130340200628020821032006280200210702400340200241e0006a41186a2208200a41186a290000370300200241e0006a41106a2209200a41106a290000370300200241e0006a41086a2201200a41086a2900003703002002200a290000370360200a41206a210a4100210402400240200341014b0d0020030e020301030b2003210b0340200b410176220c20046a220d20042007200d4105746a200241e0006a412010d0044101481b2104200b200c6b220b41014b0d000b0b200720044105746a200241e0006a412010d0040d01200a2005470d000c030b0b200241c0006a41086a2001290300220e370300200241c0006a41106a20092903002214370300200241c0006a41186a20082903002215370300200220022903602216370340200241186a220b2015370300200241106a220c2014370300200241086a220d200e37030020022016370300024020132012470d000240201241016a22042012490d0020124101742207200420042007491b221341ffffff3f712013470d00201341057422044100480d000240024020120d0020041027210f0c010b200f201241057420041028210f0b200f0d0120044101102a000b102b000b200f20124105746a22042002290300370000200441186a200b290300370000200441106a200c290300370000200441086a200d290300370000201241016a2112200a2005470d000b0b02402010450d00201110290b20002012360208200020133602042000200f3602000c010b41204101102a000b20024180016a24000b810c05047f037e017f037e0d7f230041e0016b22022400200241e8006a200128020022032001280204220428020c220511000002400240200228026822010d002000410036020820004208370200200320042802001101002004280204450d01200310290c010b200241e0006a20024184016a290200370300200241c8006a41106a200241fc006a290200370300200241c8006a41086a200241f4006a2902003703002002200229026c370348200241a0016a2001104d200241a0016a41086a290300210620022903a001210742002108200241d0016a41086a22014200370300200242003703d00141b18ac0004116200241d0016a100420024190016a41086a2001290300370300200220022903d00137039001200241003602d00120024190016a4110200241d0016a100521090240024020022802d0012201417f460d00200242003703d801200242003703d001200241d0016a20092001411020014110491b10ce041a02402001410f4d0d00200241d0016a41086a290300210a20022903d001210b200910294201210c42002108200b427d56200a420156200a4201511b450d02200241386a200b200a427f420010d404200241386a41086a29030021082002290338210c0c020b418f89c3004133104e000b4201210c0b200241286a20072006200c200810d404200229032821080240200241c4016a280200450d0020022802c00110290b200241a0016a20032004280210220d1100000240024002400240417f20022802a001220141016a220920092001491b220ead42287e220c422088a70d00200ca72201417f4c0d000240024020010d004108210f410821100c010b20011027220f450d02200f21100b200f2002290348370300200f41186a200241c8006a41186a2211290300370300200f41106a200241c8006a41106a2212290300370300200f41086a200241c8006a41086a29030037030020102008370320200241e8006a2003200511000002400240200228026822010d00410121090c010b200241e8006a410472211341022114412821154101210903402011201341186a2902003703002012201341106a290200370300200241c8006a41086a2216201341086a29020037030020022013290200370348200241a0016a2001104d200241a0016a41086a2217290300210a20022903a0012106200241d0016a41086a22184200370300200242003703d00141b18ac0004116200241d0016a100420024190016a41086a2018290300370300200220022903d00137039001200241003602d00120024190016a4110200241d0016a1005210102400240024020022802d0012219417f460d002001450d00200242003703d801200242003703d001200241d0016a20012019411020194110491b10ce041a2019410f4b0d01418f89c3004133104e000b420021084201210c0c010b2018290300210720022903d001210b200110294201210c42002108200b427e5420075020074201511b0d00200241186a200b2007427f420010d404200241186a41086a29030021082002290318210c0b200241086a2006200a200c200810d40420022903082108024020022802c401450d0020022802c00110290b200241a0016a41186a22182011290300370300200241a0016a41106a2219201229030037030020172016290300370300200220022903483703a00102402009200e470d00200241e8006a2003200d1100002009417f2002280268220141016a221620162001491b6a22012009490d062014200120012014491b220ead42287e220c422088a70d06200ca722014100480d060240024020090d0020011027210f0c010b200f201520011028210f0b200f450d05200f21100b201020156a220120022903a001370300200141186a2018290300370300200141106a2019290300370300200141086a2017290300370300200141206a2008370300200241e8006a20032005110000201441026a2114201541286a2115200941016a2109200228026822010d000b0b2003200428020011010002402004280204450d00200310290b200020093602082000200e360204200020103602000c040b1039000b20014108102a000b20014108102a000b102b000b200241e0016a24000ba70906067f047e077f027e027f017e230041e0016b22022400024002400240024002400240410f10272203450d00200341076a4100290091a3443700002003410029008aa3443700002003410f412f10282204450d012004200129000037000f200441276a200141186a2900003700002004411f6a200141106a290000370000200441176a200141086a290000370000200241f8006a41186a22014200370300200241f8006a41106a22034200370300200241f8006a41086a22054200370300200242003703782004412f200241f8006a1000200241d8006a41186a2001290300370300200241d8006a41106a2003290300370300200241d8006a41086a200529030037030020022002290378370358200241003602c001200241d8006a4120200241c0016a100521060240024020022802c0012207417f460d002002200736029c012002200636029801200241c0006a20024198016a10532002290340a7450d07200241c0006a41106a290300210820022903482109200241286a20024198016a10532002290328a7450d07200241386a290300210a2002290330210b200241206a20024198016a102e2002280220450d07024002402002280224220c41d500200c41d500491b220d0d004108210e0c010b200d41306c22011027220e450d050b0240200c450d004100210f410021104100210503402002280298012111200241f8006a200228029c012203412020034120491b22016a41004100412020016b2001411f4b1b10cd041a200241f8006a2011200110ce041a2002200320016b36029c012002201120016a36029801024002402003411f4d0d00200241c0016a41186a2201200241f8006a41186a290300370300200241c0016a41106a2211200241f8006a41106a290300370300200241c0016a41086a2212200241f8006a41086a290300370300200220022903783703c001200241086a20024198016a10532002290308a70d010b200d450d0a200e10290c0a0b200541016a2103200241086a41106a290300211320022903102114200241a0016a41186a22152001290300370300200241a0016a41106a22162011290300370300200241a0016a41086a22112012290300370300200220022903c0013703a00102402005200d470d00200f20032003200f491b220dad42307e2217422088a70d092017a722014100480d090240024020050d0020011027210e0c010b200e201020011028210e0b200e450d080b200e20106a2201201337030820012014370300200141106a20022903a001370300200141186a2011290300370300200141206a2016290300370300200141286a2015290300370300200f41026a210f201041306a211020032105200c2003470d000b0b200e450d07200cad422086200dad84211302402007450d00200610290b2000200b370310200020093703002000200e360220200041186a200a37030020002008370308200041246a20133702000c010b200041186a4200370300200041106a4200370300200041086a420037030020004200370300200041286a4100360200200042083703200b20041029200241e0016a24000f0b410f4101102a000b412f4101102a000b20014108102a000b20014108102a000b102b000b418f89c3004133104e000b5e01017f230041306b220224002002200136020c20022000360208200241246a4101360200200242013702142002419c81c6003602102002410236022c2002200241286a3602202002200241086a360228200241106a41a481c6001057000b950e01057f230041106b220224000240024002400240024002400240024002400240024002400240024002400240024002400240024020012d00000e050003010204000b2002410036020820024201370300410110272203450d05200242818080801037020420022003360200200341023a00000240024020022802042204200228020822036b4120490d00200341206a2105200228020021040c010b200341206a22052003490d1320044101742206200520052006491b22064100480d130240024020040d002006102721040c010b200228020020042006102821040b2004450d0720022006360204200220043602000b20022005360208200420036a22032001290001370000200341086a200141096a290000370000200341106a200141116a290000370000200341186a200141196a2900003700000c040b2002410036020820024201370300410110272203450d06200242818080801037020420022003360200200341043a00000240024020022802042205200228020822036b4104490d00200228020021050c010b200341046a22042003490d1220054101742206200420042006491b22044100480d120240024020050d002004102721050c010b200228020020052004102821050b2005450d0820022004360204200220053602000b2002200341046a360208200520036a2001280001360000200128020821042002200141106a280200220136020c2002410c6a200210300240024020022802042205200228020822036b2001490d00200228020021050c010b200320016a22062003490d1220054101742203200620062003491b22034100480d120240024020050d002003102721050c010b200228020020052003102821050b2005450d092002200336020420022005360200200228020821030b2002200320016a360208200520036a2004200110ce041a0c030b2002410036020820024201370300410110272203450d08200242818080801037020420022003360200200341053a00000240024020022802042204200228020822036b4104490d00200341046a2105200228020021040c010b200341046a22052003490d1120044101742206200520052006491b22064100480d110240024020040d002006102721040c010b200228020020042006102821040b2004450d0a20022006360204200220043602000b20022005360208200420036a2001280001360000200128020821042002200141106a280200220136020c2002410c6a200210300240024020022802042205200228020822036b2001490d00200228020021050c010b200320016a22062003490d1120054101742203200620062003491b22034100480d110240024020050d002003102721050c010b200228020020052003102821050b2005450d0b2002200336020420022005360200200228020821030b2002200320016a360208200520036a2004200110ce041a0c020b2002410036020820024201370300410110272203450d0a200242818080801037020420022003360200200341063a00000240024020022802042205200228020822036b4104490d00200228020021050c010b200341046a22042003490d1020054101742206200420042006491b22044100480d100240024020050d002004102721050c010b200228020020052004102821050b2005450d0c20022004360204200220053602000b2002200341046a360208200520036a2001280001360000200128020821042002200141106a280200220136020c2002410c6a200210300240024020022802042205200228020822036b2001490d00200228020021050c010b200320016a22062003490d1020054101742203200620062003491b22034100480d100240024020050d002003102721050c010b200228020020052003102821050b2005450d0d2002200336020420022005360200200228020821030b2002200320016a360208200520036a2004200110ce041a0c010b2002410036020820024201370300410110272203450d0c200242818080801037020420022003360200200341003a0000200141046a280200210420022001410c6a280200220136020c2002410c6a200210300240024020022802042205200228020822036b2001490d00200228020021050c010b200320016a22062003490d0f20054101742203200620062003491b22034100480d0f0240024020050d002003102721050c010b200228020020052003102821050b2005450d0e2002200336020420022005360200200228020821030b2002200320016a360208200520036a2004200110ce041a0b200020022201290200370200200041086a200141086a280200360200200241106a24000f0b41014101102a000b20064101102a000b41014101102a000b20044101102a000b20034101102a000b41014101102a000b20064101102a000b20034101102a000b41014101102a000b20044101102a000b20034101102a000b41014101102a000b20034101102a000b102b000bf50601067f230041f0006b22022400200241003a0050200241d0006a2001280200220320012802042204410047220510ce041a02400240024002400240024020042005490d002001200420056b22063602042001200320056a22053602002004450d04024020022d0050220441ef014b0d00410121010c030b200441847e6a220441034b0d040240024020040e0400010503000b200241003b0150200241d0006a20052006410220064102491b220410ce041a2001200620046b3602042001200520046a360200200641014d0d0520022f0150220441f001490d05410121010c030b20024100360250200241d0006a20052006410420064104491b220410ce041a2001200620046b3602042001200520046a360200200641034d0d04410121012002280250220441808004490d040c020b20052004103e000b41002103200241d0006a20064120200641204922071b22046a41004100412020046b2004411f4b1b10cd041a200241d0006a2005200410ce041a2001200620046b3602042001200520046a360200024020070d002002412c6a41026a200241d0006a41026a2d00003a0000200241186a200241df006a290000370300200241206a200241e7006a290000370300200241286a200241d0006a411f6a2d00003a0000200220022f00503b012c2002200229005737031041012103200228005321040b200241cc006a41026a22012002412c6a41026a2d00003a0000200241306a41086a2205200241106a41086a290300370300200241306a41106a2206200241106a41106a290300370300200241306a41186a2207200241106a41186a2d00003a0000200220022f012c3b014c200220022903103703302003450d022002410c6a41026a20012d00003a0000200241d0006a41086a2005290300370300200241d0006a41106a2006290300370300200241d0006a41186a20072d00003a0000200220022f014c3b010c20022002290330370350410021010b200020013a0000200020022f010c3b0001200041046a2004360200200041086a2002290350370200200041036a2002410e6a2d00003a0000200041106a200241d0006a41086a290300370200200041186a200241d0006a41106a290300370200200041206a200241d0006a41186a2802003602000c020b200120062006410420064104491b22046b3602042001200520046a3602000b200041023a00000b200241f0006a24000b880a01037f02400240024002400240024002400240024020002d00004101460d0002400240200141046a280200200141086a2802002202460d00200128020021030c010b200241016a22032002490d0920024101742204200320032004491b22044100480d090240024020020d002004102721030c010b200128020020022004102821030b2003450d0220012003360200200141046a2004360200200141086a28020021020b200141086a2204200241016a360200200320026a41ff013a000002400240200141046a2802002203200428020022026b4120490d00200128020021030c010b200241206a22042002490d0920034101742202200420042002491b22024100480d090240024020030d002002102721030c010b200128020020032002102821030b2003450d0320012003360200200141046a2002360200200141086a28020021020b200141086a200241206a360200200320026a220141186a200041196a290000370000200141106a200041116a290000370000200141086a200041096a290000370000200120002900013700000f0b0240024002400240200041046a280200220241ffff034b0d00200241ef014b0d03200141046a280200200141086a2802002200460d01200128020021030c020b02400240200141046a280200200141086a2802002200460d00200128020021030c010b200041016a22032000490d0b20004101742204200320032004491b22044100480d0b0240024020000d002004102721030c010b200128020020002004102821030b2003450d0620012003360200200141046a2004360200200141086a28020021000b200141086a2204200041016a360200200320006a41fd013a000002400240200141046a2802002203200428020022006b4104490d00200128020021030c010b200041046a22042000490d0b20034101742200200420042000491b22004100480d0b0240024020030d002000102721030c010b200128020020032000102821030b2003450d0720012003360200200141046a2000360200200141086a28020021000b200141086a200041046a360200200320006a20023600000f0b200041016a22032000490d0920004101742204200320032004491b22044100480d090240024020000d002004102721030c010b200128020020002004102821030b2003450d0620012003360200200141046a2004360200200141086a28020021000b200141086a200041016a360200200320006a20023a00000f0b02400240200141046a280200200141086a2802002200460d00200128020021030c010b200041016a22032000490d0820004101742204200320032004491b22044100480d080240024020000d002004102721030c010b200128020020002004102821030b2003450d0620012003360200200141046a2004360200200141086a28020021000b200141086a2204200041016a360200200320006a41fc013a000002400240200141046a2802002203200428020022006b4102490d00200128020021030c010b200041026a22042000490d0820034101742200200420042000491b22004100480d080240024020030d002000102721030c010b200128020020032000102821030b2003450d0720012003360200200141046a2000360200200141086a28020021000b200141086a200041026a360200200320006a20023b00000f0b20044101102a000b20024101102a000b20044101102a000b20004101102a000b20044101102a000b20044101102a000b20004101102a000b102b000ba60503057f027e037f230041106b22022400200241003a000020022001280200220320012802042204410047220510ce04210202400240024002400240024020042005490d002001200420056b22063602042001200320056a22053602002004450d03024020022d0000220441037122034103460d002004ad210702400240024020030e03000102000b2004410276ad2107420121080c080b200241003a0000200220052006410047220410ce04210320062004490d032001200620046b3602042001200520046a3602002006450d0520033100004208862007844202882107420121080c070b200241003a000e200241003b010c2002410c6a200520064103200641034922031b220410ce041a2001200620046b3602042001200520046a36020020030d04200233010c200231000e421086844208862007844202882107420121080c060b02402004410276220441044b0d000240024020040e050002020201000b200241003602002002200520064104200641044922031b220410ce0421092001200620046b3602042001200520046a36020020030d0520093502002107420121080c070b42002108200242003703002002200520064108200641084922031b220410ce0421092001200620046b3602042001200520046a36020020030d0520092903002107420121080c060b200441046a220a41084b0d0342002107410021030340200241003a0000200220052006410047220410ce04210920062004490d032001200620046b220b3602042001200520046a22053602002006450d0420093100002003410374413871ad86200784210742012108200b2106200341016a22042103200441ff0171200a4f0d060c000b0b20052004103e000b20042006103e000b20042006103e000b420021080b0b2000200737030820002008370300200241106a24000bc10605057f017e017f027e027f230041306b22022400200241003a0018200241186a2001280200220320012802042204410047220510ce041a024002400240024002400240024020042005490d002001200420056b22063602042001200320056a22053602002004450d04024020022d0018220441037122034103460d0002400240024020030e03000102000b2004410276ad21070c060b200241003a0018200241186a20052006410047220310ce041a20062003490d032001200620036b3602042001200520036a3602002006450d0620022d001841087420047241fcff0371410276ad21070c050b200241003a002e200241003b012c2002412c6a200520064103200641034922081b220310ce041a2001200620036b3602042001200520036a36020020080d0520022f012c20022d002e41107472410874200472410276ad21070c040b024020044102762204410c4b0d0002400240024020040e0d00030303010303030303030302000b20024100360218200241186a200520064104200641044922031b220410ce041a2001200620046b3602042001200520046a36020020030d07200235021821070c060b4200210920024200370318200241186a200520064108200641084922031b220410ce041a2001200620046b3602042001200520046a36020020030d07200229031821070c050b420021092002420037032020024200370318200241186a200520064110200641104922031b220410ce041a2001200620046b3602042001200520046a36020020030d06200241206a290300210a20022903182107420121090c070b200441046a220b41104b0d04200241106a210c420021074200210a410021030340200241003a0018200241186a20052006410047220410ce041a20062004490d032001200620046b22083602042001200520046a22053602002006450d05200241086a20023100184200200341037441f8007110d104200c290300200a84210a200229030820078421074201210920082106200341016a22042103200441ff0171200b4f0d070c000b0b20052004103e000b20032006103e000b20042006103e000b4200210a420121090c020b420021090b0b2000200737030820002009370300200041106a200a370300200241306a24000bbd0903017f017e057f230041e0006b220224000240024002400240024002400240024002400240024020002903002203423f560d0002400240200141046a280200200141086a2802002200460d00200128020021040c010b200041016a22042000490d0b20004101742205200420042005491b22054100480d0b0240024020000d002005102721040c010b200128020020002005102821040b2004450d0220012004360200200141046a2005360200200141086a28020021000b200141086a200041016a360200200420006a2003a74102743a00000c080b200342808001540d062003428080808004540d054108200379a741037622056b4104490d0402400240200141046a280200200141086a2802002204460d00200128020021060c010b200441016a22072004490d0a20044101742206200720072006491b22074100480d0a0240024020040d002007102721060c010b200128020020042007102821060b2006450d0220012006360200200141046a2007360200200141086a28020021040b200141086a2207200441016a360200200620046a411320054102746b3a0000200220002903002203370308200541786a2104200141046a2106034002400240200628020020072802002200460d00200128020021050c010b200041016a22052000490d0b20004101742208200520052008491b22084100480d0b0240024020000d002008102721050c010b200128020020002008102821050b2005450d042001200536020020062008360200200728020021000b2007200041016a360200200520006a2003a73a000020034208882103200441016a22002004492105200021042005450d000b20022003370308200350450d030c070b20054101102a000b20074101102a000b20084101102a000b200241286a41146a4103360200200241346a4104360200200241106a41146a41033602002002200241086a3602402002418883c000360244200241c8006a41146a41003602002002420337021420024190d1c5003602102002410436022c200241b8d6c5003602582002420137024c200241e081c0003602482002200241286a3602202002200241c8006a3602382002200241c4006a3602302002200241c0006a360228200241106a419083c0001057000b41ec82c0001058000b024002400240200141046a2802002204200141086a28020022006b4104490d00200128020021040c010b200041046a22052000490d0520044101742200200520052000491b22004100480d050240024020040d002000102721040c010b200128020020042000102821040b2004450d0120012004360200200141046a2000360200200141086a28020021000b200141086a200041046a360200200420006a2003a74102744102723600000c020b20004101102a000b02400240200141046a2802002204200141086a28020022006b4102490d00200128020021040c010b200041026a22052000490d0320044101742200200520052000491b22004100480d030240024020040d002000102721040c010b200128020020042000102821040b2004450d0220012004360200200141046a2000360200200141086a28020021000b200141086a200041026a360200200420006a2003a74102744101723b00000b200241e0006a24000f0b20004101102a000b102b000b6501027f230041206b220224002001411c6a280200210320012802182101200241086a41106a200041106a290200370300200241086a41086a200041086a2902003703002002200029020037030820012003200241086a1091042100200241206a240020000bc20202027f017e23004180016b220224002000280200210002400240024002400240200128020022034110710d002000290300210420034120710d0120044101200110aa0121000c020b20002903002104410021000340200220006a41ff006a2004a7410f712203413072200341d7006a2003410a491b3a00002000417f6a2100200442048822044200520d000b20004180016a22034181014f0d022001410141e8d9c5004102200220006a4180016a410020006b10ab0121000c010b410021000340200220006a41ff006a2004a7410f712203413072200341376a2003410a491b3a00002000417f6a2100200442048822044200520d000b20004180016a22034181014f0d022001410141e8d9c5004102200220006a4180016a410020006b10ab0121000b20024180016a240020000f0b2003418001103e000b2003418001103e000b4b02017f017e230041206b2202240020012902002103200241146a20012902083702002002200337020c20022000360208200241b8d6c500360204200241b8d6c500360200200210ab04000b6802017f037e230041306b22012400200029020821022000290210210320002902002104200141146a4100360200200141b8d6c50036021020014201370204200120043703182001200141186a36020020012003370328200120023703202001200141206a1057000b910a03017f027e057f230041e0006b2202240002400240024002400240024002400240024002400240200028020022002903002203423f56200041086a290300220442005220045022051b0d0002400240200141046a280200200141086a2802002200460d00200128020021050c010b200041016a22052000490d0b20004101742206200520052006491b22064100480d0b0240024020000d002006102721050c010b200128020020002006102821050b2005450d0220012005360200200141046a2006360200200141086a28020021000b200141086a200041016a360200200520006a2003a74102743a00000c080b20034280800154410020051b0d06200342808080800454410020051b0d05411020047920037942c0007c20044200521ba741037622066b4104490d0402400240200141046a280200200141086a2802002205460d00200128020021070c010b200541016a22082005490d0a20054101742207200820082007491b22084100480d0a0240024020050d002008102721070c010b200128020020052008102821070b2007450d0220012007360200200141046a2008360200200141086a28020021050b200141086a2208200541016a360200200720056a413320064102746b3a0000200029030021032002200041086a290300220437030820022003370300200641706a2105200141046a2107034002400240200728020020082802002200460d00200128020021060c010b200041016a22062000490d0b20004101742209200620062009491b22094100480d0b0240024020000d002009102721060c010b200128020020002009102821060b2006450d042001200636020020072009360200200828020021000b2008200041016a360200200620006a2003a73a00002003420888200442388684210320044208882104200541016a22002005492106200021052006450d000b2002200337030020022004370308200320048450450d030c070b20064101102a000b20084101102a000b20094101102a000b200241286a41146a4103360200200241346a4105360200200241106a41146a410336020020022002360240200241d081c000360244200241c8006a41146a41003602002002420337021420024190d1c5003602102002410536022c200241b8d6c5003602582002420137024c200241e081c0003602482002200241286a3602202002200241c8006a3602382002200241c4006a3602302002200241c0006a360228200241106a41e881c0001057000b41b881c0001058000b024002400240200141046a2802002205200141086a28020022006b4104490d00200128020021050c010b200041046a22062000490d0520054101742200200620062000491b22004100480d050240024020050d002000102721050c010b200128020020052000102821050b2005450d0120012005360200200141046a2000360200200141086a28020021000b200141086a200041046a360200200520006a2003a74102744102723600000c020b20004101102a000b02400240200141046a2802002205200141086a28020022006b4102490d00200128020021050c010b200041026a22062000490d0320054101742200200620062000491b22004100480d030240024020050d002000102721050c010b200128020020052000102821050b2005450d0220012005360200200141046a2000360200200141086a28020021000b200141086a200041026a360200200520006a2003a74102744101723b00000b200241e0006a24000f0b20004101102a000b102b000b840605027f027e017f027e027f230041a0016b220224002000280200210002400240024002400240024002400240200128020022034110710d00200041086a29030021042000290300210520034120710d0220054290ce005441002004501b450d012005a72103412721000c060b200041086a2903002105200029030021044180012100024003402000450d01200241206a20006a417f6a2004a7410f712203413072200341d7006a2003410a491b3a00002000417f6a210020044204882005423c8684220420054204882205844200520d000b0b20004181014f0d022001410141e8d9c5004102200241206a20006a41800120006b10ab0121000c060b41272100200241186a21060340200241106a200520044290ce00420010d4042002200229031022072006290300220842f0b17f427f10d304200241206a20006a2203417c6a200520022903007ca7220941ffff037141e4006e220a41017441fad6c5006a2f00003b00002003417e6a200a419c7f6c20096a41ffff037141017441fad6c5006a2f00003b0000200542ffc1d72f56210320044200522109200450210a2000417c6a2100200721052008210420032009200a1b0d000c040b0b4180012100024003402000450d01200241206a20006a417f6a2005a7410f712203413072200341376a2003410a491b3a00002000417f6a210020054204882004423c8684220520044204882204844200520d000b0b20004181014f0d012001410141e8d9c5004102200241206a20006a41800120006b10ab0121000c040b2000418001103e000b2000418001103e000b2007a721030b02400240200341e3004a0d00200321090c010b200241206a2000417e6a22006a2003200341ffff037141e4006e2209419c7f6c6a41ffff037141017441fad6c5006a2f00003b00000b024002402009410a480d00200241206a2000417e6a22006a200941017441fad6c5006a2f00003b00000c010b200241206a2000417f6a22006a200941306a3a00000b2001410141b8d6c5004100200241206a20006a412720006b10ab0121000b200241a0016a240020000ba80301067f230041106b220224002002410036020820024201370300200020021030200041046a20021030200041086a2002103020002d0018210302400240024002400240200228020420022802082204460d00200228020021050c010b200441016a22052004490d0320044101742206200520052006491b22064100480d030240024020040d002006102721050c010b200228020020042006102821050b2005450d0120022006360204200220053602000b2002200441016a360208200520046a20033a0000200028020c21062002200041146a280200220436020c2002410c6a200210300240024020022802042203200228020822056b2004490d00200228020021000c010b200520046a22002005490d0320034101742207200020002007491b22074100480d030240024020030d002007102721000c010b200228020020032007102821000b2000450d022002200736020420022000360200200721030b200020056a2006200410ce041a200128020020012802042000200520046a100302402003450d00200010290b200241106a24000f0b20064101102a000b20074101102a000b102b000be80201097f230041206b22022400200241003602082002420137030020002802002103200220002802082200360210200241106a20021030024002400240024020000d002002280208210420022802042105200228020021060c010b200041246c210720022802042105200228020821000340200241106a2003104f2002280210210802400240200520006b20022802182209490d00200020096a2104200228020021060c010b200020096a22042000490d0420054101742206200420042006491b220a4100480d040240024020050d00200a102721060c010b20022802002005200a102821060b2006450d032002200a36020420022006360200200a21050b20022004360208200620006a2008200910ce041a02402002280214450d00200810290b200341246a2103200421002007415c6a22070d000b0b2001280200200128020420062004100302402005450d00200610290b200241206a24000f0b200a4101102a000b102b000bcd0c02077f017e230041206b22022400200241003602102002420137030802400240024002400240024002400240024002400240024002402001280200220341044b0d0002400240024002400240024020030e050001020304000b410110272203450d06200242818080801037020c20022003360208200341013a0000200141106a28020021032002200141186a2802002204360218200241186a200241086a103002402004450d002003200441286c6a2105034002400240200228020c2206200228021022076b4120490d00200228020821040c010b200741206a22042007490d1420064101742207200420042007491b22084100480d140240024020060d002008102721040c010b200228020820062008102821040b2004450d0a2002200836020c2002200436020820022802102107200821060b200420076a220841186a200341186a290000370000200841106a200341106a290000370000200841086a200341086a2900003700002002200741206a220736021020082003290000370000200341206a29030021090240200620076b41074b0d00200741086a22082007490d1420064101742207200820082007491b22074100480d140240024020060d002007102721040c010b200420062007102821040b2004450d0b2002200736020c20022004360208200228021021070b2002200741086a360210200420076a20093700002005200341286a2203470d000b0b200220012903082209370318200241186a21070c040b410110272203450d08200242818080801037020c20022003360208200341023a00002001290308210902400240200228020c2207200228021022036b4108490d00200341086a2104200228020821070c010b200341086a22042003490d1120074101742206200420042006491b22064100480d110240024020070d002006102721070c010b200228020820072006102821070b2007450d0a2002200636020c200220073602080b20022004360210200720036a2009370000200141186a28020021032002200141206a2802002204360218200241186a200241086a103002402004450d002003200441286c6a2105034002400240200228020c2206200228021022076b4120490d00200228020821040c010b200741206a22042007490d1320064101742207200420042007491b22084100480d130240024020060d002008102721040c010b200228020820062008102821040b2004450d0d2002200836020c2002200436020820022802102107200821060b200420076a220841186a200341186a290000370000200841106a200341106a290000370000200841086a200341086a2900003700002002200741206a220736021020082003290000370000200341206a29030021090240200620076b41074b0d00200741086a22082007490d1320064101742207200820082007491b22074100480d130240024020060d002007102721040c010b200420062007102821040b2004450d0e2002200736020c20022004360208200228021021070b2002200741086a360210200420076a20093700002005200341286a2203470d000b0b200220012903102209370318200241186a21070c030b410110272203450d0b200242818080801037020c20022003360208200341033a0000200220012903082209370318200241186a21070c020b410110272203450d0b200242818080801037020c20022003360208200341043a0000200220012903082209370318200241186a21070c010b410110272203450d0b200242818080801037020c20022003360208200341053a0000200220012903082209370318200241186a21070b02400240200228020c2204200228021022036b4108490d00200228020821040c010b200341086a22062003490d0d20044101742203200620062003491b22034100480d0d0240024020040d002003102721040c010b200228020820042003102821040b2004450d0c2002200336020c2002200436020820072903002109200228021021030b2002200341086a360210200420036a20093700000b20002002290308370200200041086a200241086a41086a280200360200200241206a24000f0b41014101102a000b20084101102a000b20074101102a000b41014101102a000b20064101102a000b20084101102a000b20074101102a000b41014101102a000b41014101102a000b41014101102a000b20034101102a000b102b000bcd0a04037f037e027f017e230041c0006b220724002004a7210802400240024002400240024002400240024020014201510d0041012109024020084101460d00427f200320067c200220057c220a2002542208ad7c220b2008200b200354200b2003511b22081b210b427f200a20081b210a4200210c4100210d0c040b2002200556200320065620032006511b450d01200320067d2002200554ad7d210b200220057d210a4200210c0c020b4101210d024020084101470d00427f200320067c200220057c22012002542208ad7c22022008200220035420022003511b22081b210b427f200120081b210a410021094201210c0c040b200741086a200420052006420120022003105e200741186a290300210b2007290310210a2007290308210c0c070b200620037d2005200254ad7d210b200520027d210a4201210c0b410021094101210d0b2001500d0042002101200741306a41086a220842003703002007420037033041b18ac0004116200741306a1004200741206a41086a20082903003703002007200729033037032020074100360230200741206a4110200741306a1005210e0240024020072802302208417f470d004200210f0c010b2007420037033820074200370330200741306a200e2008411020084110491b10ce041a2008410f4d0d02200741386a290300210f20072903302101200e10290b200741306a41086a220842003703002007420037033041b18ac0004116200741306a1004200741206a41086a20082903003703002007200729033037032020074200200f20037d2001200254ad7d2203200120027d22022001562003200f562003200f511b22081b37033820074200200220081b370330200741206a4110200741306a411010030b2004500d020c010b418f89c3004133104e000b2009450d0142002103200741306a41086a220842003703002007420037033041b18ac0004116200741306a1004200741206a41086a20082903003703002007200729033037032020074100360230200741206a4110200741306a1005210902400240024020072802302208417f470d00420021020c010b2007420037033820074200370330200741306a20092008411020084110491b10ce041a2008410f4d0d01200741386a290300210220072903302103200910290b200741306a41086a220842003703002007420037033041b18ac0004116200741306a1004200741206a41086a20082903003703002007200729033037032020074200200220067d2003200554ad7d2204200320057d2205200356200420025620042002511b22081b37033820074200200520081b370330200741206a4110200741306a411010030c020b418f89c3004133104e000b200d450d0042002102200741306a41086a220842003703002007420037033041b18ac0004116200741306a1004200741206a41086a20082903003703002007200729033037032020074100360230200741206a4110200741306a1005210902400240024020072802302208417f470d00420021030c010b2007420037033820074200370330200741306a20092008411020084110491b10ce041a2008410f4d0d01200741386a290300210320072903302102200910290b200741306a41086a220842003703002007420037033041b18ac0004116200741306a1004200741206a41086a2008290300370300200720072903303703202007427f200320067c200220057c22052002542208ad7c22022008200220035420022003511b22081b3703382007427f200520081b370330200741206a4110200741306a411010030c010b418f89c3004133104e000b2000200a3703082000200c370300200041106a200b370300200741c0006a24000b890604077f017e017f047e230041e0006b220324002003200236021020032001280200220236020820032002200128020841246c22016a220436020c2003200341086a41086a360214024002400240200141ed00490d00200341386a41086a210103402003200241246a360208200341386a200341146a20021060200341186a41086a2202200141086a2204290300370300200341186a41106a2205200141106a2206290300370300200341186a41186a2207200141186a220829030037030020032001290300370318200341186a21092003290338220a4205520d0220032003280208220b41246a360208200341386a200341146a200b1060200220042903003703002005200629030037030020072008290300370300200320012903003703182003290338220a4205520d0220032003280208220b41246a360208200341386a200341146a200b1060200220042903003703002005200629030037030020072008290300370300200320012903003703182003290338220a4205520d0220032003280208220b41246a360208200341386a200341146a200b1060200220042903003703002005200629030037030020072008290300370300200320012903003703182003290338220a4205520d02200328020c2204200328020822026b41ec004b0d000b0b024020022004460d00200341386a41086a210103402003200241246a360208200341386a200341146a20021060200341186a41086a200141086a290300370300200341186a41106a200141106a290300370300200341186a41186a200141186a2903003703002003200129030037031802402003290338220a4205510d00200341186a21090c030b20032802082202200328020c470d000b0b200042053703000c010b200341386a41186a200941186a290300220c370300200341386a41106a200941106a290300220d370300200341386a41086a200941086a290300220e37030020032009290300220f3703382000200a3703002000200f370308200041106a200e370300200041186a200d370300200041206a200c3703000b200341e0006a24000be00802047f037e230041206b220324002001280200280200220128020421042001280200210102400240024002400240024002400240024002400240024020022d00000e050001020304000b200241016a21024100210520010e0406040507060b200241086a210641012105200241016a210220010e0405030406050b200241086a2106200241016a21024102210520010e0404020305040b200241086a2106200241016a21024103210520010e0403010204030b41042105200241046a210220010e0402000103020b20054102470d04024020022004470d00200621020c040b200228000021012006210220012004280000470d040c030b20054103470d03024020022004470d00200621020c030b200228000021012006210220012004280000460d020c030b20054101470d02024020022004470d00200621020c020b200228000021012006210220012004280000470d020c010b20054104470d010b2002280200210120032002280208220236020c20032001360208200341003a0010200341106a20012002410047220510ce041a024020022005490d002003200220056b220436020c2003200120056a22013602082002450d0120032d0010417f6a220241044b0d010240024002400240024002400240024020020e050001020304000b200341106a200341086a104120032802102202450d08200329021421074200210820034200370310200341106a20032802082204200328020c2205410820054108491b220110ce041a2003200520016b36020c2003200420016a3602082007a72101200541074b0d052001450d08200210290c080b20034200370310200341106a20012004410820044108491b220210ce041a2003200420026b36020c2003200120026a360208200441074d0d0720032903102107200341106a200341086a104120032802102205450d072003290214210820034200370310200341106a20032802082204200328020c2202410820024108491b220110ce041a2003200220016b36020c2003200420016a3602082008a72104200241074b0d032004450d07200510290c070b20034200370310200341106a20012004410820044108491b220210ce041a2003200420026b36020c2003200120026a360208200441074d0d0620032903102107420221080c040b20034200370310200341106a20012004410820044108491b220210ce041a2003200420026b36020c2003200120026a360208200441074d0d0520032903102107420321080c030b20034200370310200341106a20012004410820044108491b220210ce041a2003200420026b36020c2003200120026a360208200441074d0d0420032903102107420421080c020b2008422088210920032903102208422088a721012008a72102420121080c010b2007422088a72105200329031021070b2000200436021c200020013602142000200737030820002008370300200041206a2009370200200041186a2005360200200041106a20023602000c020b20052002103e000b200042053703000b200341206a24000bec0301097f230041106b2202240020002802002103200220002802082204360204200241046a2001103002400240024002400240200141046a2802002205200141086a28020022066b2004490d00200128020021050c010b200620046a22072006490d0320054101742206200720072006491b22064100480d030240024020050d002006102721050c010b200128020020052006102821050b2005450d0120012005360200200141046a2006360200200141086a28020021060b200141086a2207200620046a360200200520066a2003200410ce041a200028020c21062002200041146a2802002200360208200241086a2001103002402000450d0020062000410c6c6a2108200141046a21090340200628020021032002200641086a280200220036020c2002410c6a200110300240024020092802002205200728020022046b2000490d00200128020021050c010b200420006a220a2004490d0520054101742204200a200a2004491b22044100480d050240024020050d002004102721050c010b200128020020052004102821050b2005450d042001200536020020092004360200200728020021040b2007200420006a360200200520046a2003200010ce041a2006410c6a22062008470d000b0b200241106a24000f0b20064101102a000b20044101102a000b102b000be23101077f23004180016b22082400024002402002410c6a280200200241106a28020010062209417f460d00410c1027220a0d01410c4104102a000b1063000b200a2009360208200a4281808080103702000240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002404101450d00200a410141016a3602004101417e460d00200a410141027236020041041027220b450d01200b200a360200200a280208210c41031027220d450d02200d41026a41002d009cb0453a0000200d41002f009ab0453b000041061027220e450d03200e41046a41002f00a0f4423b0000200e410028009cf442360000412010272209450d042009200c36021c2009410136021820094286808080e0003702102009200e36020c20094283808080303702042009200d360200200a200a280200417f6a220d3602000240200d0d00200a2802081007200a200a280204417f6a220d360204200d0d00200a10290b41031027220d450d05200d41026a41002d009cb0453a0000200d41002f009ab0453b000041031027220e450d06200e41026a41002d009fb0453a0000200e41002f009db0453b00002009412041c00010282209450d072009410636023c2009410036023820094283808080303702302009200e36022c20094283808080303702242009200d36022041031027220d450d08200d41026a41002d009cb0453a0000200d41002f009ab0453b0000410f1027220e450d09200e41076a41002900af8845370000200e41002900a88845370000200941c00041800110282209450d0a2009410736025c200941003602582009428f808080f0013702502009200e36024c20094283808080303702442009200d36024041031027220d450d0b200d41026a41002d009cb0453a0000200d41002f009ab0453b0000410f1027220e450d0c200e41076a41002900be8845370000200e41002900b788453700002009410836027c200941003602782009428f808080f0013702702009200e36026c20094283808080303702642009200d36026041031027220d450d0d200d41026a41002d009cb0453a0000200d41002f009ab0453b000041081027220e450d0e200e42e5f0d1fbb5ac98b6ec00370000200941800141800210282209450d0f2009410936029c012009410036029801200942888080808001370290012009200e36028c012009428380808030370284012009200d3602800141031027220d450d10200d41026a41002d009cb0453a0000200d41002f009ab0453b0000410a1027220e450d11200e41086a41002f00d688453b0000200e41002900ce88453700002009410a3602bc01200941003602b8012009428a808080a0013702b0012009200e3602ac0120094283808080303702a4012009200d3602a00141031027220d450d12200d41026a41002d009cb0453a0000200d41002f009ab0453b0000410a1027220e450d13200e41086a41002f00e088453b0000200e41002900d888453700002009410b3602dc01200941003602d8012009428a808080a0013702d0012009200e3602cc0120094283808080303702c4012009200d3602c00141031027220d450d14200d41026a41002d009cb0453a0000200d41002f009ab0453b0000410a1027220e450d15200e41086a41002f00ea88453b0000200e41002900e288453700002009410c3602fc01200941003602f8012009428a808080a0013702f0012009200e3602ec0120094283808080303702e4012009200d3602e00141031027220d450d16200d41026a41002d009cb0453a0000200d41002f009ab0453b0000410b1027220e450d17200e41076a41002800f38845360000200e41002900ec8845370000200941800241800410282209450d182009410d36029c0220094100360298022009428b808080b001370290022009200e36028c022009428380808030370284022009200d3602800241031027220d450d19200d41026a41002d009cb0453a0000200d41002f009ab0453b0000410d1027220e450d1a200e41056a41002900fc8845370000200e41002900f788453700002009410e3602bc02200941003602b8022009428d808080d0013702b0022009200e3602ac0220094283808080303702a4022009200d3602a00241031027220d450d1b200d41026a41002d009cb0453a0000200d41002f009ab0453b0000410c1027220e450d1c200e41086a410028008c8945360000200e410029008489453700002009410f3602dc02200941003602d8022009428c808080c0013702d0022009200e3602cc0220094283808080303702c4022009200d3602c00241031027220d450d1d200d41026a41002d009cb0453a0000200d41002f009ab0453b0000410b1027220e450d1e200e41076a41002800978945360000200e41002900908945370000200941103602fc02200941003602f8022009428b808080b0013702f0022009200e3602ec0220094283808080303702e4022009200d3602e00241031027220e450d1f200e41026a41002d009cb0453a0000200e41002f009ab0453b000041151027220d450d20200d410d6a41002900a88945370000200d41086a41002900a38945370000200d410029009b89453700002009411136029c03200941003602980320094295808080d002370290032009200d36028c032009428380808030370284032009200e3602800341031027220d450d21200d41026a41002d009cb0453a0000200d41002f009ab0453b0000410a1027220e450d22200e41086a41002f00b889453b0000200e41002900b08945370000200941123602bc03200941003602b8032009428a808080a0013702b0032009200e3602ac0320094283808080303702a4032009200d3602a00341031027220d450d23200d41026a41002d009cb0453a0000200d41002f009ab0453b000041071027220e450d24200e41036a41002800bd8945360000200e41002800ba8945360000200941133602dc03200941003602d80320094287808080f0003702d0032009200e3602cc0320094283808080303702c4032009200d3602c00341031027220e450d25200e41026a41002d009cb0453a0000200e41002f009ab0453b000041111027220d450d26200d41106a41002d00d189453a0000200d41086a41002900c98945370000200d41002900c18945370000200941143602fc03200941003602f8032009429180808090023702f0032009200d3602ec0320094283808080303702e4032009200e3602e00341031027220d450d27200d41026a41002d009cb0453a0000200d41002f009ab0453b000041101027220e450d28200e41086a41002900da8945370000200e41002900d2894537000020094180044180081028220c450d29200c411536029c04200c410036029804200c4290808080800237029004200c200e36028c04200c42838080803037028404200c200d36028004410310272209450d2a200941026a41002d009cb0453a0000200941002f009ab0453b000041101027220d450d2b200d41086a41002900ea8945370000200d41002900e28945370000200c41163602bc04200c41003602b804200c429080808080023702b004200c200d3602ac04200c4283808080303702a404200c20093602a00441031027220d450d2c200d41026a41002d009cb0453a0000200d41002f009ab0453b0000411110272209450d2d200941106a41002d00828a453a0000200941086a41002900fa8945370000200941002900f28945370000200c41173602dc04200c41003602d804200c429180808090023702d004200c20093602cc04200c4283808080303702c404200c200d3602c00441031027220d450d2e200d41026a41002d009cb0453a0000200d41002f009ab0453b0000411610272209450d2f2009410e6a41002900918a45370000200941086a410029008b8a45370000200941002900838a45370000200c41183602fc04200c41003602f804200c4296808080e0023702f004200c20093602ec04200c4283808080303702e404200c200d3602e00441031027220d450d30200d41026a41002d009cb0453a0000200d41002f009ab0453b0000411210272209450d31200941106a41002f00a98a453b0000200941086a41002900a18a45370000200941002900998a45370000200c411936029c05200c410036029805200c4292808080a00237029005200c200936028c05200c42838080803037028405200c200d36028005410310272209450d32200941026a41002d009cb0453a0000200941002f009ab0453b0000410b1027220d450d33200d41076a41002800b28a45360000200d41002900ab8a45370000200c411a3602bc05200c41003602b805200c428b808080b0013702b005200c200d3602ac05200c4283808080303702a405200c20093602a005410310272209450d34200941026a41002d009cb0453a0000200941002f009ab0453b000041101027220d450d35200d41086a41002900be8a45370000200d41002900b68a45370000200c411b3602dc05200c41003602d805200c429080808080023702d005200c200d3602cc05200c4283808080303702c405200c20093602c0052005417f4c0d364101210902402005450d00200510272209450d380b20092004200510ce042109200841086a41186a2005360200200841086a41146a2005360200200841086a410c6a200641086a28020036020020082003360208200841003602302008200736022c2008200a360228200820093602182008200629020037020c20082001280200360224200241146a28020021042002411c6a2802002107200841003602482008420137034020084117360278200841f8006a200841c0006a1030410021010340200c20016a2205280200210e2008200541086a2802002209360278200841f8006a200841c0006a1030024002402008280244220d2008280248220a6b2009490d002008280240210d0c010b200a20096a2206200a490d3f200d4101742203200620062003491b22064100480d3f02400240200d0d0020061027210d0c010b2008280240200d20061028210d0b200d450d3a200820063602442008200d3602400b2008200a20096a360248200d200a6a200e200910ce041a2005410c6a28020021032008200541146a280200220d360278200841f8006a200841c0006a1030024002402008280244220a2008280248220e6b200d490d00200828024021090c010b200e200d6a2209200e490d3f200a4101742206200920092006491b22064100480d3f02400240200a0d002006102721090c010b2008280240200a2006102821090b2009450d3b20082006360244200820093602402006210a0b2008200e200d6a22063602482009200e6a2003200d10ce041a02400240200541186a2802004101460d0002400240200a2006460d00200a210d0c010b200a41016a220d200a490d41200a410174220e200d200d200e491b220d4100480d4102400240200a0d00200d102721090c010b2009200a200d102821090b2009450d3e2008200d360244200820093602400b2008200641016a220a360248200920066a41013a000020082005411c6a2802002205360278200841f8006a210e0c010b02400240200a2006460d00200a210d0c010b200a41016a220d200a490d40200a410174220e200d200d200e491b220d4100480d4002400240200a0d00200d102721090c010b2009200a200d102821090b2009450d3e2008200d360244200820093602400b2008200641016a220a360248200920066a41023a000020082005411c6a2802002205360278200841f8006a210e0b0240200d200a6b41034b0d00200a41046a2205200a490d3f200d4101742206200520052006491b22054100480d3f02400240200d0d002005102721090c010b2009200d2005102821090b2009450d3e2008200536024420082009360240200e28020021050b2008200a41046a3602482009200a6a2005360000200141206a220141e005470d000b2008280244210a4102210902400240411c200420072008280240220e2008280248200841086a1008220541036a220d41024b0d0002400240200d0e03010200010b410021090b0240200a450d00200e10290b2009450d01200841c0006a41306a200841086a41306a280200360200200841c0006a41286a200841086a41286a290300370300200841c0006a41206a200841086a41206a290300370300200841c0006a41186a200841086a41186a290300370300200841c0006a41106a200841086a41106a290300370300200841c0006a41086a200841086a41086a290300370300200820082903083703402000200841c0006a2009107b4100210e410121060c420b41041027220d450d3f200b280200220928020041016a220641014d0d0120092006360200200d20093602000240200a450d00200e10290b2002280204210e20022802002106200841003602482008420137034020084100360278200841f8006a200841c0006a10302008280240210a2008280244210120082802482103410a107c2209450d4002400240024002400240024020052006200e200a20032009410a200841086a100941036a220e41034b0d0041012106200e0e0402000001020b41c0cdc1001058000b2008410936027c2008200941016a36027820092d0000220e41014b0d0102400240200e0e020100010b200841c0006a200841f8006a107d2008280240417e714104460d020b410021060b2009102902402001450d00200a10290b4103210920060d010c020b200910292001450d00200a10290b410221090b200841c0006a41306a200841086a41306a280200360200200841c0006a41286a200841086a41286a290300370300200841c0006a41206a200841086a41206a290300370300200841c0006a41186a200841086a41186a290300370300200841c0006a41106a200841086a41106a290300370300200841c0006a41086a200841086a41086a290300370300200820082903083703402000200841c0006a2009107b2005100a200d28020022092009280200417f6a3602000240200d28020022092802000d0020092802081007200d28020022092009280204417f6a360204200d28020022092802040d00200910290b200d10294101210e410021060c410b200041a083c00036020420004102360200200041086a41103602000240200828020c2209450d00200841086a41086a280200450d00200910290b0240200828021c450d00200828021810290b200828022822092009280200417f6a3602000240200828022822092802000d0020092802081007200828022822092009280204417f6a360204200828022822092802040d00200910290b024020082802302209450d00200841346a280200450d00200910290b4100210a03400240200c200a6a220941046a280200450d00200928020010290b0240200941106a280200450d002009410c6a28020010290b200a41206a220a41e005470d000b200c1029200b28020022092009280200417f6a3602000240200b28020022092802000d0020092802081007200b28020022092009280204417f6a360204200b28020022092802040d00200910290b200b10290c410b00000b41044104102a000b41034101102a000b41064101102a000b41204104102a000b41034101102a000b41034101102a000b41c0004104102a000b41034101102a000b410f4101102a000b4180014104102a000b41034101102a000b410f4101102a000b41034101102a000b41084101102a000b4180024104102a000b41034101102a000b410a4101102a000b41034101102a000b410a4101102a000b41034101102a000b410a4101102a000b41034101102a000b410b4101102a000b4180044104102a000b41034101102a000b410d4101102a000b41034101102a000b410c4101102a000b41034101102a000b410b4101102a000b41034101102a000b41154101102a000b41034101102a000b410a4101102a000b41034101102a000b41074101102a000b41034101102a000b41114101102a000b41034101102a000b41104101102a000b4180084104102a000b41034101102a000b41104101102a000b41034101102a000b41114101102a000b41034101102a000b41164101102a000b41034101102a000b41124101102a000b41034101102a000b410b4101102a000b41034101102a000b41104101102a000b1039000b20054101102a000b20064101102a000b20064101102a000b200d4101102a000b200d4101102a000b20054101102a000b102b000b41044104102a000b410a4101102a000b4100210a03400240200c200a6a220941046a280200450d00200928020010290b0240200941106a280200450d002009410c6a28020010290b200a41206a220a41e005470d000b200c1029200b28020022092009280200417f6a3602000240200b28020022092802000d0020092802081007200b28020022092009280204417f6a360204200b28020022092802040d00200910290b200b1029410021092006410047200e720d002005100a0340200d20096a220a28020022052005280200417f6a3602000240200a28020022052802000d0020052802081007200a28020022052005280204417f6a360204200a280200220a2802040d00200a10290b200941046a22094104470d000b200d10290b20084180016a24000b0a0041b083c0001058000b5101027e024002402003450d002002280200450d010b4182abc10041f403104e000b2001280224220342002003290308220420023502047d2205200520045622021b37030820004105410420021b3602000b9d0f05047f027e027f017e027f230041d00c6b2204240002400240024002400240024002402003450d0020022802000d0020034101460d0120022802100d0120034102460d0220022802200d0220034103460d0320022802300d0320022802042105200241246a2802002106200241346a28020021030240200241146a2802002207450d004105210220012802002802202802502802bc012003490d070b200441306a4200370300200441286a4200370300200441206a420037030020012802242202420020022903082208427f200128021c2903482209420586200942ffffffffffffffff07832009521b7d22092009200856220a1b3703082004420037031841052102200a0d060240024020012802202802082005200441186a4120101241026a220a41024b0d00200a0e03080001080b4194c0c5001058000b024002400240024020070d004100210b0c010b200441086a200128021c29034842002003ad220c420010d3042001280224220a4200200a2903082209427f200429030820042903104200521b7d22082008200956220a1b370308200a0d090240024020030d00410021034101210b4200210c0c010b0240024020034100480d0020031027220b0d0120034101102a000b102b000b200b21054100210a024020034102490d00200b41002003417f6a220a10cd04200a6a21050b200541003a0000200a41016a21030b02400240024020012802202802082006200b2003101241026a220a41024b0d00200a0e03010002010b4194c0c5001058000b200c50450d020c0a0b200b450d09200c2003ad4220868421090b20012802002103200441386a41186a2201200441186a41186a290300370300200441386a41106a220a200441186a41106a290300370300200441386a41086a2205200441186a41086a2903003703002004200429031837033820032802202107200b450d0120072802502802bc012009422088a74f0d012009a7450d080b200b10290c070b200441d8006a41186a2001290300370300200441d8006a41106a200a290300370300200441d8006a41086a200529030037030020042004290338370358200728021c0d042007417f36021c200441b0016a200741f4006a290000370300200441a8016a200741ec006a290000370300200441a0016a200741e4006a2900003703002004200729005c3703980102400240200741206a220d280200220a418883c000460d00200741246a28020021060c010b41002106200441f0096a410041e00210cd041a200441d0016a410041a00810cd041a41880b1027220a450d06200a41003b0106200a4100360200200a41086a200441f0096a41e00210ce041a200a41e8026a200441d0016a41a00810ce041a200741246a41003602002007200a3602200b024002400340200a2f0106220e4105742105410021024100210302400240034020052002460d0120044198016a200a20026a41086a412010d0042201450d02200241206a2102200341016a21032001417f4a0d000b2003417f6a210e0b2006450d022006417f6a2106200a200e4102746a41880b6a280200210a0c010b0b200741286a2101410121020c010b200441f8006a41186a20044198016a41186a290300370300200441f8006a41106a20044198016a41106a290300370300200441f8006a41086a20044198016a41086a2903003703002004200429039801370378200741286a210141002106200e2103410021020b0240024020020d002004418c0a6a200441f8006a41086a290300370200200441940a6a200441f8006a41106a2903003702002004419c0a6a200441f8006a41186a290300370200200420013602800a200420033602fc092004200d3602f8092004200a3602f409200420063602f009200420042903783702840a200441f0016a20042903c001370300200441f8016a200441c0016a41086a29030037030020044184026a4200370200200442003703e801200442003703d0012004418883c00036028002200441003a008c022004418d026a20042900980137000020044195026a20044198016a41086a2900003700002004419d026a20044198016a41106a290000370000200441a5026a20044198016a41186a290000370000200441ac026a200441b7016a280000360000200441f0096a200441d0016a10de0121020c010b200441e8016a4200370300200441e4016a418883c000360200200441003602f001200441003602e001200442003703d8012004418883c0003602d401200441003602d001200a200341e0006c6a41e8026a2102200441d0016a10d6010b200441d0016a41186a200441d8006a41186a290300370300200441d0016a41106a200441d8006a41106a290300370300200441d0016a41086a200441d8006a41086a290300370300200420042903583703d0012004200937029c012004200b36029801200441f0096a200241306a200441d0016a20044198016a10df01024020042802f009450d0020042802f4092202450d00200441f8096a280200450d00200210290b2007200728021c41016a36021c410421020c060b4182abc10041f403104e000b4182abc10041f403104e000b4182abc10041f403104e000b4182abc10041f403104e000b41c8a8c1004110200441d0016a41f0a8c10010a201000b41880b4108102a000b20002002360200200441d00c6a24000b900302017f027e230041c0006b22042400024002402003450d0020022802000d0020022802042103200441186a4200370300200441106a4200370300200441086a420037030020012802242202420020022903082205427f200128021c2903482206420586200642ffffffffffffffff07832006521b7d2206200620055622021b3703082004420037030002400240024020020d00024002402001280220280208200320044120101241026a220241024b0d0020020e03020001020b4194c0c5001058000b200441206a20012802002802202202411c6a200241dc006a200241106a410020022802101b200410dd012004280220450d01200441306a41086a2203200441206a41086a28020036020020042004290320370330200141106a21020240200141146a280200450d00200228020010290b20022004290330370200200241086a2003280200360200410021010c020b200041053602000c030b200141186a4100360200410121010b20004100360200200020013602040c010b4182abc10041f403104e000b200441c0006a24000bb40d06027f017e047f027e027f027e230041b0016b220424000240024002400240024002400240024002400240024002400240024002402003450d0020022802000d0020034101460d0120022802100d0120034102460d0220022802204101470d0220034103460d0320022802300d0320034104460d0420022802400d0420034105460d0520022802500d0520034106460d0620022802600d0620022802042105200241286a2903002106200241346a2802002107200241c4006a2802002108200241d4006a2802002109200241e4006a280200210a200441206a200128021c2903484200200241146a2802002202ad420010d3042001280224220342002003290308220b427f200429032020042903284200521b7d220c200c200b5622031b37030820030d0d0240024020020d0041002102410121034100210d0c010b20024100480d0b200210272203450d082003210e4100210d024020024102490d00200341002002417f6a220d10cd04200d6a210e0b200e41003a0000200d41016a210d0b024002400240200128022028020820052003200d101241026a220541024b0d0020050e03010002010b4194c0c5001058000b2002450d0e200310290c0e0b2003450d0d20044180016a200d4120200d412049220e1b22056a41004100412020056b2005411f4b1b10cd041a20044180016a2003200510ce041a02400240200e0d00200441306a41186a20044180016a41186a290000370300200441306a41106a20044180016a41106a290000370300200441306a41086a20044180016a41086a290000370300200420042900800137033002402002450d00200310290b200441106a200128021c29034842002008ad420010d3042001280224220242002002290308220b427f200429031020042903184200521b7d220c200c200b5622021b37030820020d0f0240024020080d004100210841012102410021030c010b20084100480d0d200810272202450d0b2002210541002103024020084102490d00200241002008417f6a220310cd0420036a21050b200541003a0000200341016a21030b024002402001280220280208200720022003101241026a220541024b0d0020050e03010003010b4194c0c5001058000b2008450d0f200210290c0f0b2002450d0e200310290c0e0b20020d090c0d0b4182abc10041f403104e000b4182abc10041f403104e000b4182abc10041f403104e000b4182abc10041f403104e000b4182abc10041f403104e000b4182abc10041f403104e000b4182abc10041f403104e000b20024101102a000b20084101102a000b2004420037038801200442003703800120044180016a20022003411020034110491b10ce041a02402003410f4b0d002008450d04200210290c040b20044188016a290300210f200429038001211002402008450d00200210290b2004200128021c2903484200200aad420010d3042001280224220242002002290308220b427f200429030020042903084200521b7d220c200c200b5622021b37030820020d030240200a0d004100210a41012102410021030c030b200a4100480d00200a102722020d01200a4101102a000b102b000b41012103200221050240200a4102490d0020024100200a417f6a220310cd0420036a2105200a21030b200541003a00000b0240024002402001280220280208200920022003101241026a220541024b0d0020050e03010002010b4194c0c5001058000b200a450d01200210290c010b2002450d00200141186a4100360200200141146a280200210d200128021021082001420137021020012802242205290308220c210b0240024002402006500d002006210b200c2006540d010b2005200c200b7d3703082005290310210c200441d0006a41186a200541186a2903003703002004200b3703582004200b3703502004200c3703602001280200280220210720044180016a41186a200441306a41186a29030037030020044180016a41106a200441306a41106a29030037030020044180016a41086a200441306a41086a2903003703002004200429033037038001200441003602a8012004200d3602a401200420083602a001200441f0006a200720044180016a2010200f200441d0006a20022003200441a0016a10e101200441f0006a41086a290300210b2004280274210d200428027021082005200429035820052903087c3703084101210320084101460d01200d450d010240200141146a2203280200450d00200128021010290b2001200d3602102003200b370200410021030c010b41012103200d450d00200810290b0240200a450d00200210290b20004100360200200020033602040c010b200041053602000b200441b0016a24000bfe0f06027f017e047f027e027f027e230041e0016b22042400024002400240024002400240024002400240024002400240024002400240024002402003450d0020022802000d0020034101460d0120022802100d0120034102460d0220022802204101470d0220034103460d0320022802300d0320034104460d0420022802400d0420034105460d0520022802500d0520034106460d0620022802600d0620022802042105200241286a2903002106200241346a2802002107200241c4006a2802002108200241d4006a2802002109200241e4006a280200210a200441286a200128021c2903484200200241146a2802002202ad420010d3042001280224220342002003290308220b427f200429032820042903304200521b7d220c200c200b5622031b37030820030d0a0240024020020d0041002102410121034100210d0c010b20024100480d0f200210272203450d082003210e4100210d024020024102490d00200341002002417f6a220d10cd04200d6a210e0b200e41003a0000200d41016a210d0b024002400240200128022028020820052003200d101241026a220541024b0d0020050e03010002010b4194c0c5001058000b2002450d0b200310290c0b0b2003450d0a200441f8006a200d4120200d412049220e1b22056a41004100412020056b2005411f4b1b10cd041a200441f8006a2003200510ce041a02400240200e0d00200441386a41186a200441f8006a41186a290000370300200441386a41106a200441f8006a41106a290000370300200441386a41086a200441f8006a41086a2900003703002004200429007837033802402002450d00200310290b200441186a200128021c29034842002008ad420010d3042001280224220242002002290308220b427f200429031820042903204200521b7d220c200c200b5622021b37030820020d0c0240024020080d004100210841012102410021030c010b20084100480d11200810272202450d0b2002210541002103024020084102490d00200241002008417f6a220310cd0420036a21050b200541003a0000200341016a21030b024002402001280220280208200720022003101241026a220541024b0d0020050e03010003010b4194c0c5001058000b2008450d0c200210290c0c0b2002450d0b200310290c0b0b20020d090c0a0b4182abc10041f403104e000b4182abc10041f403104e000b4182abc10041f403104e000b4182abc10041f403104e000b4182abc10041f403104e000b4182abc10041f403104e000b4182abc10041f403104e000b20024101102a000b20084101102a000b200442003703c001200442003703b801200441b8016a20022003411020034110491b10ce041a02402003410f4b0d002008450d01200210290c010b200441c0016a290300210f20042903b801211002402008450d00200210290b200441086a200128021c2903484200200aad420010d3042001280224220242002002290308220b427f200429030820042903104200521b7d220c200c200b5622021b37030820020d0002400240200a0d004100210a41012102410021030c010b200a4100480d05200a10272202450d0641012103200221050240200a4102490d0020024100200a417f6a220310cd0420036a2105200a21030b200541003a00000b0240024002402001280220280208200920022003101241026a220541024b0d0020050e03010002010b4194c0c5001058000b200a450d01200210290c010b2002450d00200141186a410036020020012802242205290308220c210b02402006500d004101210d2006210b200c2006540d030b2005200c200b7d3703082005290310210c20044198016a41186a200541186a2903003703002004200b3703a0012004200b370398012004200c3703a801200441b8016a20012802002802202010200f20044198016a200441386a2002200310da014101210d20042d00b8014101460d01200441f8006a41186a200441d1016a290000220b370300200441f8006a41106a200441c9016a290000220c370300200441f8006a41086a200441c1016a2900002206370300200441d8006a41086a22032006370300200441d8006a41106a220d200c370300200441d8006a41186a2208200b370300200420042900b901220b370378200520042903a00120052903087c3703082004200b370358200441b8016a41186a2008290300370300200441b8016a41106a200d290300370300200441b8016a41086a2003290300370300200420042903583703b80102400240200141146a2802002205200141186a28020022036b4120490d00200128021021050c010b200341206a220d2003490d0520054101742203200d200d2003491b22034100480d050240024020050d002003102721050c010b200128021020052003102821050b2005450d0420012005360210200141146a2003360200200141186a28020021030b200141186a200341206a360200200520036a220341186a200441b8016a41186a290300370000200341106a200441b8016a41106a290300370000200341086a200441b8016a41086a290300370000200320042903b8013700004100210d0c020b200041053602000c050b200520042903a00120052903087c370308200441d8006a41086a200441f8006a41086a290300370300200441d8006a41106a200441f8006a41106a290300370300200441d8006a41186a200441f8006a41186a290300370300200420042903783703580b0240200a450d00200210290b200041003602002000200d3602040c030b20034101102a000b102b000b200a4101102a000b200441e0016a24000bc70403027f027e057f230041106b22042400024002400240024002402003450d0020022802000d0020034101460d0120022802100d01200228020421052004200128021c2903184200200241146a2802002203ad420010d30420012802242202420020022903082206427f200429030020042903084200521b7d2207200720065622021b370308024020020d0020012802042102200141003602042002450d0302400240200141086a290200220642ffffffff0f560d000240024020032006422088a722084b0d002003200820032008491b21030c010b024002402006a7220920086b200320086b220a490d00200821090c010b2008200a6a220b2008490d092009410174220c200b200b200c491b220b4100480d090240024020090d00200b102721020c010b20022009200b102821020b2002450d082006422088a72109200bad21060b200220096a210b0240200a4102490d00200b410020032008417f7322086a10cd041a2002200920036a20086a22096a210b0b200b41003a0000200941016a21030b024002402001280220280208200520022003101241026a220841024b0d0020080e03010003010b4194c0c5001058000b2006a7450d02200210290c020b41d08bc3001058000b2006a72108024020012802282205450d002001412c6a280200450d00200510290b20012002360228200141306a20033602002001412c6a20083602000b20004105360200200441106a24000f0b4182abc10041f403104e000b4182abc10041f403104e000b41f6aec10041fd00104e000b200b4101102a000b102b000bf00101037f41002104200141186a4100360200200128020021050240024002400240200141146a28020022064120490d00200128021021060c010b200641017422044120200441204b1b22044100480d020240024020060d002004102721060c010b200128021020062004102821060b2006450d0120012006360210200141146a2004360200200141186a28020021040b200141186a200441206a360200200620046a220141186a2005413c6a290000370000200141106a200541346a290000370000200141086a2005412c6a29000037000020012005290024370000200041043602000f0b20044101102a000b102b000bf60101037f41002104200141186a4100360200200128020028022021050240024002400240200141146a28020022064120490d00200128021021060c010b200641017422044120200441204b1b22044100480d020240024020060d002004102721060c010b200128021020062004102821060b2006450d0120012006360210200141146a2004360200200141186a28020021040b200141186a200441206a360200200620046a220141186a200541f4006a290000370000200141106a200541ec006a290000370000200141086a200541e4006a2900003700002001200529005c370000200041043602000f0b20044101102a000b102b000bd50102027f027e41002104200141186a41003602002001280224220541186a2903002106200529031021070240024002400240200141146a28020022054110490d00200128021021050c010b200541017422044110200441104b1b22044100480d020240024020050d002004102721050c010b200128021020052004102821050b2005450d0120012005360210200141146a2004360200200141186a28020021040b200141186a200441106a360200200520046a2201200637000820012007370000200041043602000f0b20044101102a000b102b000bc20103017f017e017f41002104200141186a4100360200200128022429030821050240024002400240200141146a28020022064108490d00200128021021060c010b200641017422044108200441084b1b22044100480d020240024020060d002004102721060c010b200128021020062004102821060b2006450d0120012006360210200141146a2004360200200141186a28020021040b200141186a200441086a360200200620046a2005370000200041043602000f0b20044101102a000b102b000b9d04020b7f027e230041206b22042400200141186a41003602000240024002402001280200280220220528021c41016a220641004c0d00200541dc006a21072005200636021c200541206a2108200541246a28020021090240024003402008280200220a41086a210b200a2f0106220c41057421084100210d0240024003402008450d012007200b412010d004220e450d02200841606a2108200d41016a210d200b41206a210b200e417f4a0d000b200d417f6a210c0b2009450d022009417f6a2109200a200c4102746a41880b6a21080c010b0b200a200d41e0006c6a220841e8026a280200450d00200841f8026a290300210f200841f0026a29030021100c010b200441086a2005412c6a2802002007200541306a28020028021c110200200441106a290300210f200528021c2106200429030821100b20052006417f6a36021c02400240200141146a280200220b200141186a28020022086b4110490d002001280210210b0c010b200841106a220d2008490d03200b4101742208200d200d2008491b22084100480d0302400240200b0d0020081027210b0c010b2001280210200b20081028210b0b200b450d022001200b360210200141146a2008360200200141186a28020021080b200141186a200841106a360200200b20086a2208200f3700082008201037000020004104360200200441206a24000f0b41d8a8c1004118200441186a4180a9c10010a201000b20084101102a000b102b000bd50102027f027e41002104200141186a41003602002001280200220541086a2903002106200529030021070240024002400240200141146a28020022054110490d00200128021021050c010b200541017422044110200441104b1b22044100480d020240024020050d002004102721050c010b200128021020052004102821050b2005450d0120012005360210200141146a2004360200200141186a28020021040b200141186a200441106a360200200520046a2201200637000820012007370000200041043602000f0b20044101102a000b102b000bf30403047f027e017f230041306b2204240002400240024002400240024002402003450d0020022802000d0020034101460d0120022802100d0141052105200241146a2802002203200128021c220628026c4b0d06200228020421072004200629034842002003ad420010d30420012802242202420020022903082208427f200429030020042903084200521b7d2209200920085622021b37030820020d060240024020030d004100210341012102410021060c010b20034100480d04200310272202450d05410121062002210a024020034102490d00200241002003417f6a220610cd0420066a210a200321060b200a41003a00000b0240024002402001280220280208200720022006101241026a220741024b0d0020070e03010002010b4194c0c5001058000b2003450d070c060b2002450d06200141186a22054100360200200441106a2002200610db0102400240200141146a2802002206200528020022056b4120490d00200128021021060c010b200541206a22072005490d0420064101742205200720072005491b22054100480d040240024020060d002005102721060c010b200128021020062005102821060b2006450d0320012006360210200141146a2005360200200141186a28020021050b200141186a200541206a360200200620056a220141186a200441106a41186a290300370000200141106a200441106a41106a290300370000200141086a200441106a41086a290300370000200120042903103700004104210520030d050c060b4182abc10041f403104e000b4182abc10041f403104e000b20054101102a000b102b000b20034101102a000b200210290b20002005360200200441306a24000bc20103017f017e017f41002104200141186a4100360200200128020029031021050240024002400240200141146a28020022064108490d00200128021021060c010b200641017422044108200441084b1b22044100480d020240024020060d002004102721060c010b200128021020062004102821060b2006450d0120012006360210200141146a2004360200200141186a28020021040b200141186a200441086a360200200620046a2005370000200041043602000f0b20044101102a000b102b000bee0704027f027e037f027e230041f0036b2204240002400240024002400240024002402003450d0020022802000d0020034101460d0120022802100d0120022802042105200441206a200128021c2903484200200241146a2802002202ad420010d30420012802242203420020032903082206427f200429032020042903284200521b7d2207200720065622031b3703084105210820030d060240024020020d004100210241012103410021090c010b20024100480d05200210272203450d06410121092003210a024020024102490d00200341002002417f6a220910cd0420096a210a200221090b200a41003a00000b024002400240024002402001280220280208200520032009101241026a220541024b0d0020050e03010002010b4194c0c5001058000b20020d010c090b2003450d08200420093602bc01200420033602b801200441c8026a200441b8016a103c024020042802c80222054112460d00200441c0016a200441c8026a41047241840110ce041a20042005360230200441306a410472200441c0016a41840110ce041a02402002450d00200310290b200441003602d002200442013703c802200441306a200441c8026a103220042802d0022103024020042802cc02450d0020042802c80210290b200128022422022903102206200241186a2903002207844200510d05200441106a2003ad42004280c8afa025420010d30420042004290310220b4280a094a58d1d7c220c200441106a41086a290300200c200b54ad7c2006200710d40420024200200229030822062004290300427f200441086a290300501b7d220720072006561b37030820072006580d02200441306a103d0c090b2002450d080b200310290c070b20012802002102200441c0016a200441306a41880110ce041a200441e0026a2002280220220241f4006a290000370300200441d8026a200241ec006a290000370300200441c8026a41086a200241e4006a2900003703002004200229005c3703c802200441e8026a200441c0016a41880110ce041a0240200241cc006a2802002201200241c8006a280200470d00200141016a22032001490d0520014101742208200320032008491b2203ad42a8017e2206422088a70d052006a722084100480d050240024020010d002008102721010c010b2002280244200141a8016c2008102821010b2001450d0420022001360244200241c8006a2003360200200228024c21010b2002280244200141a8016c6a200441c8026a41a80110ce041a2002200228024c41016a36024c410421080c060b4182abc10041f403104e000b4182abc10041f403104e000b41fcecc2001058000b20084108102a000b102b000b20024101102a000b20002008360200200441f0036a24000b1600200041003602002000200141186a2802003602040bab0202057f027e230041106b220424000240024002402003450d0020022802000d0020034101460d0120022802100d0120034102460d0220022802200d02410521030240200141186a2802002205200241146a2802002206490d00200520066b200241246a2802002205470d0020022802042107200128021021082004200128021c29035042002005ad420010d30420012802242202420020022903082209427f200429030020042903084200521b7d220a200a20095622021b37030820020d000240024020012802202802082007200820066a2005101341026a220241024b0d0020020e03020001020b41fcc0c5001058000b410421030b20002003360200200441106a24000f0b4182abc10041f403104e000b4182abc10041f403104e000b4182abc10041f403104e000bd30b05047f027e037f017e047f23004190016b2204240002400240024002400240024002400240024002402003450d0020022802000d0020034101460d0120022802100d0120034102460d0220022802200d0220034103460d0320022802300d03200241246a2802002105200241346a280200210602400240024002400240200241146a2802002203450d0020022802042107200441306a200128021c29034842002003ad420010d30420012802242202420020022903082208427f200429033020042903384200521b7d22092009200856220a1b37030841052102200a0d0e20034100480d0a20031027220a450d0b200a210b4100210c024020034102490d00200a41002003417f6a220c10cd04200c6a210b0b200b41003a0000024020012802202802082007200a200c41016a220c101241026a220341024b0d0020030e03040002040b4194c0c5001058000b4101210c410021074100210b0c010b2004200c3602742004200a360270200441c0006a200441f0006a102d2004280240220c450d01200441c8006a28020021072004280244210b200a10292007200128021c28025c4b0d0b0b200c2007410041202007676b10e001024020074102490d00200c21022007210303402002200241206a220a412010d004450d0c200a21022003417f6a220341024f0d000b0b200441206a200128021c29034842002006ad220d420010d30420012802242202420020022903082208427f200429032020042903284200521b7d2209200920085622021b37030820020d0a0240024020060d0041002106410121024100210a0c010b20064100480d08200610272202450d0a4101210a20022103024020064102490d00200241002006417f6a220310cd0420036a21032006210a0b200341003a00000b024002400240200128022028020820052002200a101241026a220341024b0d0020030e03010002010b4194c0c5001058000b2006450d0b200210290c0b0b2002450d0a2004200128021c220529032842002007ad420010d304200441106a20052903204200200d420010d30420012802242103427f2109024020042903184200520d0020042903084200520d002004290310220820042903007c220d2008540d00427f200d20052903307c22082008200d541b21090b200342002003290308220820097d220920092008561b37030820092008580d012006450d0a200210290c0a0b200a10290c0a0b200441f0006a41086a22052001280200280220220141e4006a290000370300200441f0006a41106a220e200141ec006a290000370300200441f0006a41186a220f200141f4006a2900003703002004200129005c3703700240200141c0006a28020022032001413c6a280200470d00200341016a22102003490d0620034101742211201020102011491b2210ad42e8007e2208422088a70d062008a722114100480d060240024020030d002011102721030c010b2001280238200341e8006c2011102821030b2003450d05200120033602382001413c6a2010360200200128024021030b2001280238200341e8006c6a220341053a000020032004290370370001200341096a2005290300370000200341116a200e290300370000200341196a200f290300370000200341216a20042f006d3b0000200341236a200441ef006a2d00003a00002003412c6a200a360000200341286a2006360000200341246a2002360000200341306a2004290340370300200341386a200441c0006a41086a290300370300200341c0006a200441c0006a41106a290300370300200341c8006a200441c0006a41186a290300370300200341d0006a200441e0006a290300370300200341e0006a2007360200200341dc006a200b3602002003200c3602582001200128024041016a360240410421020c090b4182abc10041f403104e000b4182abc10041f403104e000b4182abc10041f403104e000b4182abc10041f403104e000b20114108102a000b102b000b20034101102a000b20064101102a000b41052102200b450d00200c10290b2000200236020020044190016a24000bef0a03027f027e057f230041f00b6b22042400024002400240024002402003450d0020022802000d0020034101460d0120022802100d0120022802042105200441086a200128021c2903484200200241146a2802002202ad420010d30420012802242203420020032903082206427f200429030820042903104200521b7d2207200720065622031b3703084105210820030d040240024020020d004100210241012103410021090c010b0240024020024100480d002002102722030d0120024101102a000b102b000b410121092003210a024020024102490d00200341002002417f6a220910cd0420096a210a200221090b200a41003a00000b024002400240024002402001280220280208200520032009101241026a220541024b0d0020050e03010002010b4194c0c5001058000b20020d010c070b2003450d062004420037037820044200370370200441f0006a20032009411020094110491b10ce041a2009410f4b0d012002450d060b200310290c050b200441f8006a29030021062004290370210702402002450d00200310290b2001280200280220220528021c0d022005417f36021c200441d0006a200541f4006a290000370300200441c8006a200541ec006a290000370300200441c0006a200541e4006a2900003703002004200529005c37033802400240200541206a220b2802002208418883c000460d00200541246a280200210a0c010b4100210a20044190096a410041e00210cd041a200441f0006a410041a00810cd041a41880b10272208450d04200841003b010620084100360200200841086a20044190096a41e00210ce041a200841e8026a200441f0006a41a00810ce041a200541246a4100360200200520083602200b02400240034020082f0106220c4105742109410021024100210102400240034020092002460d01200441386a200820026a41086a412010d0042203450d02200241206a2102200141016a21012003417f4a0d000b2001417f6a210c0b200a450d02200a417f6a210a2008200c4102746a41880b6a28020021080c010b0b200541286a2103410121020c010b200441186a41186a200441386a41186a290300370300200441186a41106a200441386a41106a290300370300200441186a41086a200441386a41086a29030037030020042004290338370318200541286a21034100210a200c2101410021020b0240024020020d00200441ac096a200441186a41086a290300370200200441b4096a200441186a41106a290300370200200441bc096a200441186a41186a290300370200200420033602a0092004200136029c092004200b3602980920042008360294092004200a36029009200420042903183702a40920044190016a200429036037030020044198016a200441e0006a41086a290300370300200441a4016a42003702002004420037038801200442003703702004418883c0003602a001200441003a00ac01200441ad016a2004290038370000200441b5016a200441386a41086a290000370000200441bd016a200441386a41106a290000370000200441c5016a200441386a41186a290000370000200441cc016a200441d7006a28000036000020044190096a200441f0006a10de0121020c010b20044188016a420037030020044184016a418883c00036020020044100360290012004410036028001200442003703782004418883c000360274200441003602702008200141e0006c6a41e8026a2102200441f0006a10d6010b200241286a2006370300200241206a2007370300200242013703182005200528021c41016a36021c410421080c040b4182abc10041f403104e000b4182abc10041f403104e000b41c8a8c1004110200441f0006a41f0a8c10010a201000b41880b4108102a000b20002008360200200441f00b6a24000bad04020b7f027e230041206b22042400200141186a41003602000240024002402001280200280220220528021c41016a220641004c0d00200541dc006a21072005200636021c200541206a2108200541246a28020021090240024003402008280200220a41086a210b200a2f0106220c41057421084100210d0240024003402008450d012007200b412010d004220e450d02200841606a2108200d41016a210d200b41206a210b200e417f4a0d000b200d417f6a210c0b2009450d022009417f6a2109200a200c4102746a41880b6a21080c010b0b200a200d41e0006c6a22084180036a280200220b450d0020084190036a290300210f20084188036a29030021100c010b20042005412c6a2802002007200541306a280200280214110200200441106a290300210f200528021c2106200429030821102004280200210b0b20052006417f6a36021c02400240200141146a280200220d200141186a28020022086b4110490d002001280210210d0c010b200841106a220e2008490d03200d4101742208200e200e2008491b22084100480d0302400240200d0d0020081027210d0c010b2001280210200d20081028210d0b200d450d022001200d360210200141146a2008360200200141186a28020021080b200141186a200841106a360200200d20086a2208200f427f200b1b37000820082010427f200b1b37000020004104360200200441206a24000f0b41d8a8c1004118200441186a4180a9c10010a201000b20084101102a000b102b000b8d0303027f027e037f230041206b2204240002400240024002402003450d0020022802000d0020034101460d0120022802100d01200228020421052004200128021c2903484200200241146a2802002202ad420010d30420012802242203420020032903082206427f200429030020042903084200521b7d2207200720065622081b3703084105210320080d030240024020020d004100210241012108410021090c010b0240024020024100480d002002102722080d0120024101102a000b102b000b410121092008210a024020024102490d00200841002002417f6a220910cd0420096a210a200221090b200a41003a00000b0240024002402001280220280208200520082009101241026a220141024b0d0020010e03010002010b4194c0c5001058000b2002450d040c030b2008450d03200441106a2008200910dc01024020042802100d002004280214200441186a28020010100b4104210320020d020c030b4182abc10041f403104e000b4182abc10041f403104e000b200810290b20002003360200200441206a24000bc20103017f017e017f41002104200141186a4100360200200128020029031821050240024002400240200141146a28020022064108490d00200128021021060c010b200641017422044108200441084b1b22044100480d020240024020060d002004102721060c010b200128021020062004102821060b2006450d0120012006360210200141146a2004360200200141186a28020021040b200141186a200441086a360200200620046a2005370000200041043602000f0b20044101102a000b102b000bdf05020a7f017e230041c0006b220424002004200136020c2004200041b8d6c50020011b3602082004200441086a102e02402004280200450d00024002400240024002400240024002400240200428020422054180022005418002491b22060d00410821070c010b2006410474220110272207450d010b02402005450d00200441206a4104722108410021094100210a410021000340200441206a200441086a107d200441306a41086a220b200841086a2802003602002004200829020037033002402004280220220c4104470d002006450d0a200710290c0a0b200041016a2101200441106a41086a220d200b28020036020020042004290330370310024020002006470d002009200120012009491b220641ffffffff00712006470d052006410474220b4100480d050240024020000d00200b102721070c010b2007200a200b102821070b2007450d040b2007200a6a2200200c360200200041046a20042903103702002000410c6a200d280200360200200941026a2109200a41106a210a2001210020052001470d000b0b2007450d07200441206a20022007200520031103002004410036023820044201370330200428022021004101102721010240024020004105460d002001450d05200141003a000020044281808080103702342004200136023020014101410210282101024020004104470d002001450d07200141003a00012004428280808020370234200420013602304202210e0c020b2001450d07200141013a0001200442828080802037023420042001360230200441206a200441306a10fe012004350238210e200428023021010c010b2001450d07200141013a00002004428180808010370234200420013602304201210e0b2001ad422086200e84210e02402006450d00200710290b200441c0006a2400200e0f0b20014108102a000b200b4108102a000b102b000b41014101102a000b41024101102a000b41024101102a000b41014101102a000b41cdccc10041f000104e000b920201027f20012802282103024002400240200241ff017122024103470d0020030d01200041003602000c020b2001412c6a2802002104024020024102470d002003450d00200141306a280200210220002003360204200041013602002000410c6a2002360200200041086a20043602000c020b200041a1a6c10036020420004102360200200041086a41103602002003450d012004450d01200310290c010b41b4a6c1001058000b024020012802042200450d00200141086a280200450d00200010290b0240200141146a280200450d00200128021010290b200128022022012001280200417f6a2200360200024020000d002001280208100720012001280204417f6a220036020420000d00200110290b0b0700200010b4040b890401057f230041106b22022400200241003a0008200241086a2001280200220320012802042204410047220510ce041a0240024020042005490d002001200420056b22063602042001200320056a2205360200024020040d00200041043602000c020b024020022d0008417f6a220441034b0d00024002400240024020040e0400010203000b20024100360208200241086a20052006410420064104491b220410ce041a2001200620046b3602042001200520046a3602000240200641034b0d00200041043602000c060b20002002280208360204200041003602000c050b20024200370308200241086a20052006410820064108491b220410ce041a2001200620046b3602042001200520046a3602000240200641074b0d00200041043602000c050b200041086a2002290308370300200041013602000c040b20024100360208200241086a20052006410420064104491b220410ce041a2001200620046b3602042001200520046a3602000240200641034b0d00200041043602000c040b20002002280208360204200041023602000c030b20024200370308200241086a20052006410820064108491b220410ce041a2001200620046b3602042001200520046a3602000240200641074b0d00200041043602000c030b200041086a2002290308370300200041033602000c020b200041043602000c010b20052004103e000b200241106a24000be40301027f230041e0006b22032400200341003a0005024002402000413f4b0d00200320004102743a0000410121040c010b02400240200041808001490d0020004180808080044f0d01200341033a0005200320004106763a000120032000410e763a0002200320004116763a0003200320004102744102723a0000410421040c020b200320004106763a000141022104200341013a0005200320004102744101723a00000c010b200341043a0005200341033a0000200320003a0001200320004108763a0002200320004110763a0003200320004118763a0004410521040b200320043a0005024002402001280200220028020822012002490d0020002802002100200320023602082003200436020c20042002470d0120002003200210ce041a200341e0006a24000f0b20022001107f000b200341286a41146a4103360200200341346a411d360200200341106a41146a41033602002003200341086a36024020032003410c6a360244200341c8006a41146a41003602002003420337021420034190d1c5003602102003411d36022c200341b8d6c5003602582003420137024c200341e4d1c5003602482003200341286a3602202003200341c8006a3602382003200341c4006a3602302003200341c0006a360228200341106a41a0d2c5001057000b6f01017f230041306b2202240020022001360204200220003602002002411c6a41023602002002412c6a41013602002002420237020c200241c4d8c500360208200241013602242002200241206a3602182002200241046a36022820022002360220200241086a41d4d8c5001057000bb90201037f23004180016b220224002000280200210002400240024002400240200128020022034110710d002000280200210420034120710d012004ad4101200110aa0121000c020b20002802002104410021000340200220006a41ff006a2004410f712203413072200341d7006a2003410a491b3a00002000417f6a2100200441047622040d000b20004180016a22044181014f0d022001410141e8d9c5004102200220006a4180016a410020006b10ab0121000c010b410021000340200220006a41ff006a2004410f712203413072200341376a2003410a491b3a00002000417f6a2100200441047622040d000b20004180016a22044181014f0d022001410141e8d9c5004102200220006a4180016a410020006b10ab0121000b20024180016a240020000f0b2004418001103e000b2004418001103e000b11002000280200200028020420011082010bbe0f020d7f017e230041206b220324004101210402400240200228021841222002411c6a2802002802101104000d000240024020010d00410021050c010b200020016a21062000210741002105410021080240034020072109200741016a210a02400240024020072c0000220b417f4a0d0002400240200a2006470d004100210c200621070c010b20072d0001413f71210c200741026a220a21070b200b411f7121040240200b41ff0171220b41df014b0d00200c200441067472210b0c020b0240024020072006470d004100210d2006210e0c010b20072d0000413f71210d200741016a220a210e0b200d200c41067472210c0240200b41f0014f0d00200c2004410c7472210b0c020b02400240200e2006470d004100210b200a21070c010b200e41016a2107200e2d0000413f71210b0b200c4106742004411274418080f0007172200b72220b418080c400470d020c040b200b41ff0171210b0b200a21070b4102210a024002400240024002400240200b41776a220c411e4d0d00200b41dc00470d010c020b41f400210e02400240200c0e1f05010202000202020202020202020202020202020202020202030202020203050b41f200210e0c040b41ee00210e0c030b02400240200b10bd040d0002400240200b41808004490d00024002400240200b418080084f0d00200b4180fe0371410876210f41e1edc500210c410021040340200c41026a210d2004200c2d0001220a6a210e0240200c2d0000220c200f460d00200c200f4b0d06200e2104200d210c200d41a7eec500470d010c060b200e2004490d02200e41a6014b0d03200441a7eec5006a210c02400340200a450d01200a417f6a210a200c2d00002104200c41016a210c2004200b41ff0171470d000c080b0b200e2104200d210c200d41a7eec500470d000c050b0b200b41ef83384b0d04200b41e28b746a41e28d2c490d04200b419fa8746a419f18490d04200b41dee2746a410e490d04200b41feffff0071419ef00a460d04200b41a9b2756a4129490d04200b41cb91756a410a4b0d090c040b2004200e103e000b200e41a601107f000b200b4180fe0371410876210f41b0e8c500210c41002104024002400340200c41026a210d2004200c2d0001220a6a210e0240200c2d0000220c200f460d00200c200f4b0d03200e2104200d210c200d4182e9c500470d010c030b0240200e2004490d00200e41a5024b0d0220044182e9c5006a210c02400340200a450d01200a417f6a210a200c2d00002104200c41016a210c2004200b41ff0171470d000c070b0b200e2104200d210c200d4182e9c500470d010c030b0b2004200e103e000b200e41a502107f000b200b41ffff0371210441a7ebc500210a4101210e02400340200a41016a210d02400240200a2d0000220c411874411875220f4100480d00200d210a0c010b200d41e1edc500460d02200f41ff0071410874200a2d000172210c200a41026a210a0b02402004200c6b22044100480d00200e410173210e200a41e1edc500470d010b0b200e410171450d020c070b41c8dac5001058000b200b41ffff0371210441cdefc500210a4101210e0340200a41016a210d02400240200a2d0000220c411874411875220f4100480d00200d210a0c010b200d41e5f2c500460d03200f41ff0071410874200a2d000172210c200a41026a210a0b02402004200c6b22044100480d00200e410173210e200a41e5f2c500470d010b0b200e4101710d050b200b41017267410276410773ad4280808080d0008421104103210a0c020b41c8dac5001058000b0b200b210e0b2003200136020420032000360200200320053602082003200836020c0240024020082005490d0002402005450d0020052001460d00200520014f0d01200020056a2c000041bf7f4c0d010b02402008450d0020082001460d00200820014f0d01200020086a2c000041bf7f4c0d010b2002280218200020056a200820056b200228021c28020c110500450d01410121040c060b20032003410c6a3602182003200341086a36021420032003360210200341106a10c404000b0340200a210c4101210441dc0021054101210a024002400240024002400240200c0e0402010500020b02400240024002402010422088a741ff01710e06050302010006050b201042ffffffff8f60834280808080308421104103210a41f50021050c070b201042ffffffff8f60834280808080208421104103210a41fb0021050c060b200e2010a7220c410274411c7176410f71220a413072200a41d7006a200a410a491b21050240200c450d002010427f7c42ffffffff0f832010428080808070838421100c050b201042ffffffff8f60834280808080108421100c040b201042ffffffff8f608321104103210a41fd0021050c040b4100210a200e21050c030b4101210a0240200b418001490d004102210a200b418010490d0041034104200b41808004491b210a0b200a20086a21050c040b201042ffffffff8f60834280808080c0008421100b4103210a0b20022802182005200228021c2802101104000d050c000b0b200820096b20076a210820062007470d000b0b2005450d0020052001460d00200520014f0d02200020056a2c000041bf7f4c0d020b410121042002280218200020056a200120056b200228021c28020c1105000d0020022802184122200228021c28021011040021040b200341206a240020040f0b200020012005200110ba04000bfb0304027f027e017f017e230041e0006b22042400024002400240411410272205450d00200541106a41002800bb8c40360000200541086a41002900b38c40370000200541002900ab8c4037000020054114413410282205450d01200520012900003700142005412c6a200141186a290000370000200541246a200141106a2900003700002005411c6a200141086a290000370000200441186a20054134108401200441186a41106a290300210620042903202107200428021821082005102942002109200441306a20012007420020081b220720027c22022006420020081b20037c2002200754ad7c108501200441306a41106a290300210220042903382103024020042903304200520d00200321090c030b200441b18ac0004116108601200441106a29030021062004290308210720042802002105200441306a41086a220142003703002004420037033041b18ac0004116200441306a1004200441d0006a41086a200129030037030020042004290330370350200442002006420020051b220620027d2007420020051b2202200354ad7d2207200220037d2203200256200720065620072006511b22051b37033820044200200320051b370330200441d0006a4110200441306a41101003420021020c020b41144101102a000b41344101102a000b2000200937030020002002370308200441e0006a24000ba10204017f017e037f027e230041c0006b2203240042002104200341206a41186a22054200370300200341206a41106a22064200370300200341206a41086a220742003703002003420037032020012002200341206a1000200341186a2005290300370300200341106a2006290300370300200341086a2007290300370300200320032903203703002003410036022020034120200341206a1005210202400240024020032802202201417f470d000c010b2003420037032820034200370320200341206a20022001411020014110491b10ce041a2001410f4d0d01200341286a29030021082003290320210920021029420121040b2000200937030820002004370300200041106a2008370300200341c0006a24000f0b418f89c3004133104e000bdb0605027f027e017f017e047f230041b0016b220424000240024002400240411410272205450d00200541106a41002800bb8c40360000200541086a41002900b38c40370000200541002900ab8c4037000020054114413410282205450d01200520012900003700142005412c6a200141186a290000370000200541246a200141106a2900003700002005411c6a200141086a290000370000200441086a20054134108401200441086a41106a29030021062004290310210720042802082108200510292006420020081b21092007420020081b2106024002400240200242ffffe883b1de1656200342005220035022051b0d002006200984500d010b4101210802402002428080e983b1de1654410020051b0d00411410272205450d0541002108200541106a41002800bb8c40360000200541086a41002900b38c40370000200541002900ab8c4037000020054114413410282205450d06200520012900003700142005412c6a200141186a220a290000370000200541246a200141106a2900003700002005411c6a200141086a290000370000200441206a41186a220b4200370300200441206a41106a220c4200370300200441206a41086a220d42003703002004420037032020054134200441206a100020044190016a41186a200b29030037030020044190016a41106a200c29030037030020044190016a41086a200d290300370300200420042903203703900120044190016a412041b8d6c50041004100100b210b20051029200b417f470d002001108701200441d8006a2003370300200441d0006a200237030041002108200441206a41086a41003a0000200441296a2001290000370000200441316a200141086a290000370000200441396a200141106a290000370000200441c1006a200a290000370000200441023a002041b8d6c5004100200441206a1088010b200120022003108901200041106a200920037d2006200254ad7d200320097d2002200654ad7d2006200256200920035620092003511b22051b3703002000200620027d200220067d20051b370308200020083a001820002005ad3703000c010b20004200370300200041013a0018200041106a4200370300200041086a42003703000b200441b0016a24000f0b41144101102a000b41344101102a000b41144101102a000b41344101102a000be70104017f017e017f027e230041206b2203240042002104200341106a41086a220542003703002003420037031020012002200341106a1004200341086a2005290300370300200320032903103703002003410036021020034110200341106a1005210202400240024020032802102201417f470d000c010b2003420037031820034200370310200341106a20022001411020014110491b10ce041a2001410f4d0d01200341186a29030021062003290310210720021029420121040b2000200737030820002004370300200041106a2006370300200341206a24000f0b418f89c3004133104e000ba10703047f017e067f230041a0016b22012400200141186a41f8f3c200411310b50120012802182102200128021c210302400240412010272204450d00200420002900002205370000200441186a200041186a290000370000200441106a200041106a290000370000200441086a200041086a29000037000020042d000121062004102920014190016a20064108742005a7220441c0017172410676220610cc0102402004413f7122042001280298014f0d00200141086a20012802900120044105746a22041095012001290308200141086a41086a290300844200520d0020042000290000370000200441186a200041186a290000370000200441106a200041106a290000370000200441086a200041086a290000370000200141206a41086a20014190016a41086a28020036020020012001290390013703202006200141206a10fe020c020b2003410020021b21040240200128029401450d0020012802900110290b200141206a200410cc01024020012802282206413f4d0d000340200441016a210402402001280224450d00200128022010290b200141206a200410cc0120012802282206413f4b0d000b0b2001280220210220012802242107200141206a41186a2208200041186a290000370300200141206a41106a2209200041106a290000370300200141206a41086a220a200041086a29000037030020012000290000370320200641016a2103024020072006470d00024020064101742207200320032007491b2207410574220b4100480d000240024020060d00200b102721020c010b20022006410574200b102821020b20020d01200b4101102a000b102b000b200620044106746a210b200220064105746a22062001290320370000200641186a2008290300370000200641106a2009290300370000200641086a200a2903003700000240200341c000470d00200141206a41086a220642003703002001420037032041f8f3c2004113200141206a100420014190016a41086a200629030037030020012001290320370390012001200441016a36022020014190016a4110200141206a410410030b2001200336022820012007360224200120023602202004200141206a10fe02200141206a41086a2000290000370300200141206a41106a200041086a290000370300200141206a41186a200041106a290000370300200141c0006a200041186a2900003703002001200b360224200141013a002041b8d6c5004100200141206a1088010c010b41204101102a000b200141a0016a24000b942603087f047e037f230041c0036b22032400200341003602b80141ff88c3004110200341b8016a100521040240024020032802b8012205417f460d002004450d0041002106200341003602b801200341b8016a20042005410420054104491b10ce041a0240200541034d0d0020032802b8012107200410290c020b418f89c3004133104e000b410121060b4101210841002104410021050240024002400240024002400240024002400240024002400240024002402001450d00200141057422044100480d09200410272208450d012001410574220941606a410576210a410021040340200341b8016a41186a200020046a220541186a290000220b370300200341b8016a41106a200541106a290000220c370300200341b8016a41086a200541086a290000220d37030020032005290000220e3703b801200820046a220541186a200b370000200541106a200c370000200541086a200d3700002005200e3700002009200441206a2204470d000b200a41016a2105200121040b200341a4016a2007360200200320063602a001200341306a200241f00010ce041a200341b0016a2005360200200341ac016a2004360200200320083602a801200341286a4187cec500411110b501024002400240024002400240200328022c410020032802281b220f41016a2205200f490d00200341d0026a41086a22044200370300200342003703d0024187cec5004111200341d0026a100420034188036a41086a22082004290300370300200320032903d00237038803200320053602b80120034188036a4110200341b8016a41041003200341b8016a200341306a41880110ce041a20044200370300200342003703d002418890c300410d200341d0026a100420082004290300370300200320032903d00237038803200341003602d00220034188036a4110200341d0026a100521050240024020032802d0022204417f460d0020050d010b200341003602c802200342013703c0020c090b200320043602c802200320043602c402200320053602c0022004450d08200320043602d402200320053602d002200341206a200341d0026a102e2003280220450d07410121052003280224220841016a22092008490d070240200841c000490d0041022105200841808001490d00410441052008418080808004491b21050b410121080240200941c000490d0041022108200941808001490d00410441052009418080808004491b21080b024020082005460d002004200820056b6a2204417f4c0d100240024020040d00410121020c010b200410272202450d030b200320043602a803200320043602a403200320023602a0032003200341a0036a3602d0022009200341d0026a2008107e20042008490d0320032802a80322092004490d0420032802c80222092005490d0520032802a003210220032802c00221062003200420086b22043602b0032003200920056b22093602b40320042009470d06200220086a200620056a200410ce041a200341b8016a200341a0036a10980320032802a803210820032802a403210520032802a003210420032802c402450d0b20032802c00210290c0b0b2003200341c0026a3602d0022009200341d0026a2005107e200341b8016a200341c0026a10980320032802c802210820032802c402210520032802c00221040c0a0b200341306a1099030c0a0b20044101102a000b20082004103e000b20042009107f000b20052009103e000b20034188036a41146a410336020020034194036a411d360200200341f0026a41146a41033602002003200341b0036a3602b8032003200341b4036a3602bc03200341d0026a41146a4100360200200342033702f40220034190d1c5003602f0022003411d36028c03200341b8d6c5003602e002200342013702d402200341e4d1c5003602d002200320034188036a360280032003200341d0026a360298032003200341bc036a360290032003200341b8036a36028803200341f0026a41a0d2c5001057000b20044101102a000b410021040c010b200341003602d802200342013703d002200341013602880320034188036a200341d0026a10300240024020032802a8024101460d000240024020032802d40220032802d8022204460d0020032802d00221050c010b200441016a22052004490d0820044101742208200520052008491b22084100480d080240024020040d002008102721050c010b20032802d00220042008102821050b2005450d0d200320083602d402200320053602d00220032802d80221040b2003200441016a3602d802200520046a41003a000020032802ac0221080240024020032802d402220520032802d80222046b4104490d0020032802d00221050c010b200441046a22092004490d0820054101742204200920092004491b22044100480d080240024020050d002004102721050c010b20032802d00220052004102821050b2005450d0c200320043602d402200320053602d00220032802d80221040b2003200441046a3602d802200520046a20083600000c010b0240024020032802d40220032802d8022204460d0020032802d00221050c010b200441016a22052004490d0720044101742208200520052008491b22084100480d070240024020040d002008102721050c010b20032802d00220042008102821050b2005450d0a200320083602d402200320053602d00220032802d80221040b2003200441016a3602d802200520046a41013a00000b200341b8016a200341d0026a109d0220032802b0022104200320032802b80222053602880320034188036a200341d0026a103002402005450d002005410574210220032802d402210920032802d8022105034002400240200920056b4120490d0020032802d00221080c010b200541206a22082005490d0820094101742205200820082005491b22064100480d080240024020090d002006102721080c010b20032802d00220092006102821080b2008450d0a200320063602d402200320083602d00220032802d8022105200621090b200820056a220841086a200441086a290000370000200841106a200441106a290000370000200841186a200441186a2900003700002003200541206a22053602d80220082004290000370000200441206a2104200241606a22020d000b0b20032802d802210820032802d402210520032802d002210420032802c402450d010b20032802c00210290b024020040d00200341b8016a1099030c010b200341d0026a41086a22094200370300200342003703d002418890c300410d200341d0026a100420034188036a41086a2009290300370300200320032903d0023703880320034188036a411020042008100302402005450d00200410290b200341b8016a109903200341106a41888dc300410d1094012001450d002003290318420020032802101b210c2001410574211003402003200f3602f8022003200c3703f002024002400240024002400240024002400240024002400240024002400240411210272204450d00200441106a41002f00a590433b0000200441086a410029009d9043370000200441002900959043370000200341b8016a41186a22084200370300200341b8016a41106a22094200370300200341b8016a41086a22024200370300200342003703b80120044112200341b8016a1000200341d0026a41186a22062008290300370300200341d0026a41106a22012009290300370300200341d0026a41086a22072002290300370300200320032903b8013703d002412010272205450d01200520032903d002370000200541186a2006290300370000200541106a2001290300370000200541086a200729030037000020041029200842003703002009420037030020024200370300200342003703b80120004120200341b8016a1000200620082903003703002001200929030037030020072002290300370300200320032903b8013703d0022005412041c00010282204450d02200420032903d002370020200441386a2006290300370000200441306a2001290300370000200441286a2007290300370000200341003602b801200441c000200341b8016a10052105024020032802b8012208417f470d00200341003602c802200342013703c0020c0d0b200320083602c802200320083602c402200320053602c0022008450d0c200320083602bc01200320053602b801200341086a200341b8016a102e024020032802080d00410021050c0e0b41002105200328020c220941016a22062009490d0d41012105410121020240200941c000490d0041022102200941808001490d00410441052009418080808004491b21020b0240200641c000490d0041022105200641808001490d00410441052006418080808004491b21050b024020052002460d002008200520026b6a2208417f4c0d150240024020080d00410121090c010b200810272209450d050b200320083602a803200320083602a403200320093602a0032003200341a0036a3602b8012006200341b8016a2005107e20082005490d0520032802a80322092008490d0620032802c80222092002490d0720032802a003210620032802c00221012003200820056b22083602b0032003200920026b22093602b40320082009470d08200620056a200120026a200810ce041a20032903f002210b0240024020032802a403220820032802a80322056b4108490d0020032802a00321080c010b200541086a22092005490d1520084101742205200920092005491b22054100480d150240024020080d002005102721080c010b20032802a00320082005102821080b2008450d0a200320053602a403200320083602a00320032802a80321050b2003200541086a3602a803200820056a200b37000020032802f80221090240024020032802a403220820032802a80322056b4104490d0020032802a00321080c010b200541046a22022005490d1520084101742205200220022005491b22054100480d150240024020080d002005102721080c010b20032802a00320082005102821080b2008450d0b200320053602a403200320083602a00320032802a80321050b2003200541046a3602a803200820056a200936000020032802a803211120032802a403210a20032802a003210520032802c402450d0f20032802c00210290c0f0b2003200341c0026a3602b8012006200341b8016a2002107e20032903f002210b0240024020032802c402220820032802c80222056b4108490d0020032802c00221080c010b200541086a22092005490d1420084101742205200920092005491b22054100480d140240024020080d002005102721080c010b20032802c00220082005102821080b2008450d0b200320053602c402200320083602c00220032802c80221050b2003200541086a3602c802200820056a200b37000020032802f80221090240024020032802c402220820032802c80222056b4104490d0020032802c00221080c010b200541046a22022005490d1420084101742205200220022005491b22054100480d140240024020080d002005102721080c010b20032802c00220082005102821080b2008450d0c200320053602c402200320083602c00220032802c80221050b2003200541046a3602c802200820056a200936000020032802c802211120032802c402210a20032802c00221050c0e0b41124101102a000b41204101102a000b41c0004101102a000b20084101102a000b20052008103e000b20082009107f000b20022009103e000b20034188036a41146a410336020020034194036a411d360200200341d0026a41146a41033602002003200341b0036a3602b8032003200341b4036a3602bc03200341b8016a41146a4100360200200342033702d40220034190d1c5003602d0022003411d36028c03200341b8d6c5003602c801200342013702bc01200341e4d1c5003602b801200320034188036a3602e0022003200341b8016a360298032003200341bc036a360290032003200341b8036a36028803200341d0026a41a0d2c5001057000b20054101102a000b20054101102a000b20054101102a000b20054101102a000b200341003602c001200342013703b801200341013602d002200341d0026a200341b8016a103020032903f002210b0240024020032802bc01220820032802c00122096b4108490d0020032802b80121050c010b200941086a22052009490d0720084101742202200520052002491b22024100480d070240024020080d002002102721050c010b20032802b80120082002102821050b2005450d05200320023602bc01200320053602b801200221080b2003200941086a22023602c001200520096a200b37000020032802f802210602400240200820026b41034d0d002008210a0c010b200241046a22012002490d0720084101742207200120012007491b220a4100480d070240024020080d00200a102721050c010b20052008200a102821050b2005450d062003200a3602bc01200320053602b8010b20032009410c6a22113602c001200520026a20063600000b20032802c402450d0020032802c00210290b024020050d00200410290c020b200441c0002005201110030240200a450d00200510290b200041206a210020041029201041606a22100d000b0b200341c0036a24000f0b20024101102a000b200a4101102a000b102b000b1039000b20064101102a000b20084101102a000b20044101102a000b20084101102a000bfb1603067f027e037f230041a0026b22032400024002400240024002400240024002400240024002400240411410272204450d00200441106a41002800bb8c40360000200441086a41002900b38c40370000200441002900ab8c4037000020044114413410282204450d01200420002900003700142004412c6a200041186a290000370000200441246a200041106a2900003700002004411c6a200041086a290000370000200341c8016a41186a22054200370300200341c8016a41106a22064200370300200341c8016a41086a22074200370300200342003703c80120044134200341c8016a1000200341c8006a41186a2005290300370300200341c8006a41106a2006290300370300200341c8006a41086a2007290300370300200320032903c801370348200320013703c801200320023703d001200341c8006a4120200341c8016a4110100320041029200142ffffe883b1de165620024200522002501b0d07411410272204450d02200441106a41002800bb8c40360000200441086a41002900b38c40370000200441002900ab8c4037000020044114413410282204450d03200420002900003700142004412c6a200041186a290000370000200441246a200041106a2900003700002004411c6a200041086a290000370000200341c8016a41186a22054200370300200341c8016a41106a22064200370300200341c8016a41086a22074200370300200342003703c80120044134200341c8016a1000200341c8006a41186a2005290300370300200341c8006a41106a2006290300370300200341c8006a41086a2007290300370300200320032903c801370348200341306a200341c8006a108a01200341306a41106a2903002101200329033821022003280230210820041029410e10272204450d04200441066a41002900dd8c40370000200441002900d78c403700002004410e412e10282204450d052004200029000037000e200441266a200041186a2900003700002004411e6a200041106a290000370000200441166a200041086a290000370000200341c8016a41186a22054200370300200341c8016a41106a22064200370300200341c8016a41086a22074200370300200342003703c8012004412e200341c8016a1000200341c8006a41186a2005290300370300200341c8006a41106a2006290300370300200341c8006a41086a2007290300370300200320032903c801370348200341c8006a4120100c2004102902402002200184500d002008450d00200341186a41b18ac0004116108601200341186a41106a29030021092003290320210a20032802182104200341b8016a41086a22054200370300200342003703b80141b18ac0004116200341b8016a1004200341c8016a41086a2005290300370300200320032903b8013703c801200342002009420020041b220920017d200a420020041b2201200254ad7d220a200120027d2202200156200a200956200a2009511b22041b37035020034200200220041b370348200341c8016a4110200341c8006a411010030b2000108b01200341c8006a2000108c0102400240024020032d004822044103714103460d0020040e03020001020b20040d08200341fc006a280200450d08200341f8006a28020010290c080b20040d07200341fc006a280200450d07200341f8006a28020010290c070b200341fc006a2802002104200341f8006a280200220520034180016a280200100d2004450d06200510290c060b41144101102a000b41344101102a000b41144101102a000b41344101102a000b410e4101102a000b412e4101102a000b02400240024002400240411710272204450d002004410f6a41002900af9342370000200441086a41002900a89342370000200441002900a0934237000020044117413710282204450d01200420002900003700172004412f6a200041186a290000370000200441276a200041106a2900003700002004411f6a200041086a290000370000200341c8016a41186a22054200370300200341c8016a41106a22064200370300200341c8016a41086a22074200370300200342003703c80120044137200341c8016a1000200341c8006a41186a2005290300370300200341c8006a41106a2006290300370300200341c8006a41086a2007290300370300200320032903c801370348200341c8006a4120100c2004102920034190026a2000108d01200341c8006a20032802900222042003280298022207108e0120032d00484101470d0320042007100c200341c8016a41386a220720034181016a290000370300200341c8016a41306a2208200341f9006a290000370300200341c8016a41286a220b200341f1006a290000370300200341c8016a41206a200341e9006a2900003703002005200341e1006a2900003703002006200341d9006a290000370300200341c8016a41086a2205200341d1006a290000370300200320032900493703c8010240200328029402450d00200410290b200341c8006a41386a2007290300370300200341c8006a41306a2008290300370300200341c8006a41286a200b290300370300200341c8006a41206a220c200341c8016a41206a290300370300200341c8006a41186a200341c8016a41186a290300370300200341c8006a41106a200341c8016a41106a290300370300200341c8006a41086a2005290300370300200320032903c801370348200341c8006a210b4120417f4a210d41042105410a2106034002400240200641766a2204410a4b0d00200b21070240024020040e0b0102020202020202020200010b200c21070b200d450d05024041200d0041012108410021040c020b0240412010272208450d00412021040c020b41204101102a000b410121084100210441b8d6c50021070b20082007200410ce0421072003200436029c02200320043602980220032007360294022003200636029002200341b8016a20034190026a108f0120032802b801220620032802c001100c024020032802bc01450d00200610290b02402004450d00200710290b024020054108460d00200541d0e3c1006a2802002106200541046a21050c010b0b200341013a008f02200341b8016a41086a22044200370300200342003703b80141a7c8c500410f200341b8016a100420034190026a41086a2004290300370300200320032903b8013703900220034190026a41102003418f026a410110030c040b41174101102a000b41374101102a000b1039000b200328029402450d00200410290b411810272204450d01200441106a41002900cf8c40370000200441086a41002900c78c40370000200441002900bf8c4037000020044118413810282204450d0220042000290000370018200441306a200041186a290000370000200441286a200041106a290000370000200441206a200041086a290000370000200320044138108401200341106a290300210220032802002105200329030821012004102902402001200284500d0020050d010b411310272204450d032004410f6a41002800d68d43360000200441086a41002900cf8d43370000200441002900c78d4337000020044113413310282204450d04200420002900003700132004412b6a200041186a2206290000370000200441236a200041106a22072900003700002004411b6a200041086a2208290000370000200341c8006a41186a220b4200370300200341c8006a41106a220d4200370300200341c8006a41086a220542003703002003420037034820044133200341c8006a1000200341c8016a41186a200b290300370300200341c8016a41106a200d290300370300200341c8016a41086a2005290300370300200320032903483703c801200341c8016a4120100c20041029200541013a0000200341d1006a2000290000370000200341d9006a2008290000370000200341e1006a2007290000370000200341e9006a2006290000370000200341023a004841b8d6c5004100200341c8006a1088010b200341a0026a24000f0b41184101102a000b41384101102a000b41134101102a000b41334101102a000bb00104037f017e017f027e230041106b22022400200241003602002001412020021005210302400240024020022802002204417f470d00420021050c010b2002420037030820024200370300200220032004411020044110491b10ce0421062004410f4d0d01200641086a2903002107200629030021082003102920014120100c420121050b2000200537030020002008370308200041106a2007370300200241106a24000f0b418f89c3004133104e000b930b01087f23004180016b22012400024002400240024002400240024002400240410e10272202450d00200241066a41002900c7a244370000200241002900c1a2443700002002410e412e10282202450d012002200029000037000e200241266a200041186a2900003700002002411e6a200041106a290000370000200241166a200041086a290000370000200141c0006a41186a22034200370300200141c0006a41106a22044200370300200141c0006a41086a22054200370300200142003703402002412e200141c0006a1000200141206a41186a2003290300370300200141206a41106a2004290300370300200141206a41086a20052903003703002001200129034037032020014100360260200141206a4120200141e0006a100521050240024020012802602203417f460d00200141c0006a2003412020034120491b22046a41004100412020046b2004411f4b1b10cd041a200141c0006a2005200410ce041a2003411f4d0d04200141e0006a41186a2203200141c0006a41186a290300370300200141e0006a41106a2204200141c0006a41106a290300370300200141e0006a41086a2206200141c0006a41086a2903003703002001200129034037036020051029200141186a22052003290300370300200141106a22072004290300370300200141086a2208200629030037030020012001290360370300200141206a4120100c2002102920032005290300370300200420072903003703002006200829030037030020012001290300370360410e10272202450d05200241066a410029009fa34437000020024100290099a3443700002002410e412e10282202450d062002200129036037000e200241266a200141e0006a41186a2903003700002002411e6a200141e0006a41106a290300370000200241166a200141e0006a41086a290300370000200141c0006a41186a22034200370300200141c0006a41106a22044200370300200141c0006a41086a22054200370300200142003703402002412e200141c0006a1000200141206a41186a2003290300370300200141206a41106a2004290300370300200141206a41086a200529030037030020012001290340370320200141206a4120100c200210290c010b200210290b410d10272202450d05200241056a41002900aca344370000200241002900a7a3443700002002410d412d10282202450d062002200029000037000d200241256a200041186a2900003700002002411d6a200041106a290000370000200241156a200041086a290000370000200141c0006a41186a22034200370300200141c0006a41106a22044200370300200141c0006a41086a22054200370300200142003703402002412d200141c0006a1000200141206a41186a2003290300370300200141206a41106a2004290300370300200141206a41086a200529030037030020012001290340370320200141206a4120100c20021029411210272202450d07200241106a41002f00c4a3443b0000200241086a41002900bca344370000200241002900b4a34437000020024112413210282202450d08200220002900003700122002412a6a200041186a290000370000200241226a200041106a2900003700002002411a6a200041086a290000370000200141c0006a41186a22034200370300200141c0006a41106a22044200370300200141c0006a41086a220542003703002001420037034020024132200141c0006a1000200141206a41186a2003290300370300200141206a41106a2004290300370300200141206a41086a200529030037030020012001290340370320200141206a4120100c20021029200010c903200010ca0320014180016a24000f0b410e4101102a000b412e4101102a000b418f89c3004133104e000b410e4101102a000b412e4101102a000b410d4101102a000b412d4101102a000b41124101102a000b41324101102a000bce0d04067f017e037f087e230041f0006b22022400024002400240024002400240411710272203450d002003410f6a41002900af9342370000200341086a41002900a89342370000200341002900a0934237000020034117413710282203450d01200320012900003700172003412f6a200141186a290000370000200341276a200141106a2900003700002003411f6a200141086a290000370000200241286a41186a22014200370300200241286a41106a22044200370300200241286a41086a220542003703002002420037032820034137200241286a1000200241186a2001290300370300200241106a2004290300370300200241086a2005290300370300200220022903283703002002410036022820024120200241286a100521010240024020022802282204417f460d002001450d002002200136022020022004360224200241003a0028200241286a20012004410047220510ce041a20042005490d042002200420056b22063602242002200120056a22053602202004450d0720022d0028220441014b0d0702400240024020040e020001000b200241286a200241206a104420022802282207450d09200229022c210820024100360228200241286a2002280220220920022802242204410420044104491b220610ce041a2002200420066b22053602242002200920066a220a3602200240200441034b0d002008a7450d0a0c090b20022802282109200241286a2005412020054120491b22046a41004100412020046b2004411f4b1b10cd041a200241286a200a200410ce041a2002200520046b22063602242002200a20046a220b360220024002402005411f4b0d00410021040c010b2002200228002b36006b20022002280228360268200220022802683602602002200228006b360063200241376a290000210c200229002f210d200229003f210e20022d0047210a410121040b2002200228006336002b20022002280260360228024020040d002008a70d090c0a0b2002200228002b36005b200220022802283602582002420037033020024200370328200241286a200b2006411020064110491b220510ce041a2002200620056b22043602242002200b20056a220b36022002402006410f4b0d002008a70d090c0a0b200241286a41086a290300210f2002290328211020024200370328200241286a200b2004410820044108491b220610ce041a2002200420066b22053602242002200b20066a22063602200240200441074d0d0020022903282111200241003a0028200241286a20062005410047220410ce041a20052004490d082002200520046b220b3602242002200620046a220436022002402005450d0020022d0028220541014b0d00420021120240024020050e020100010b20024200370328200241286a2004200b4108200b41084922061b220510ce041a2002200b20056b3602242002200420056a36022020060d0120022903282113420121120b2002200228005b36005320022002280258360250200220022802503602282002200228005336002b200220022800493602682002200241cc006a28000036006b410021040c030b2008a70d090c0a0b2008a70d080c090b41002107200241286a2006412020064120491b22046a41004100412020046b2004411f4b1b10cd041a200241286a2005200410ce041a2002200620046b3602242002200520046a360220024002402006411f4b0d00420021120c010b2002200228002b36006b20022002280228360268200220022802683602602002200228006b360063200241376a290000210f200229002f2110200229003f211120023100472112410121070b2002200228006336002b200220022802603602282007450d082002200228002b36005b200220022802283602582002200228005b36005320022002280258360250200220022802503602682002200228005336006b2002200241cc006a28000036002b20022002280049360228410121040b2002200228006b36006320022002280268360260200220022802283602582002200228002b36005b20011029200041106a200f370000200041086a2010370000200041cf006a200c370000200041c7006a200d370000200020043a000020002002280260360001200041046a20022800633600002000413c6a2009360000200041346a2008370000200041306a2007360000200041286a2013370000200041206a2012370000200041186a2011370000200041c0006a2002280258360000200041c3006a200228005b360000200041df006a200a3a0000200041d7006a200e3700000c010b200041023a00000b20031029200241f0006a24000f0b41174101102a000b41374101102a000b20052004103e000b20042005103e000b200710290b418f89c3004133104e000be80501067f230041c0006b2202240002400240024002400240411010272203450d00200341086a41002900c5cc41370000200341002900bdcc41370000200242908080808002370204200220033602002002410d360220200241206a20021030024002400240024020022802042204200228020822056b410d490d002005410d6a2103200228020021060c010b2005410d6a22032005490d0120044101742206200320032006491b22074100480d010240024020040d002007102721060c010b200228020020042007102821060b2006450d042002200736020420022006360200200721040b20022003360208200620056a2205410029009ecc41370000200541056a41002900a3cc41370000200241206a2006200310830220022802282203417f4c0d04200228022021050240024020030d00410121070c010b200310272207450d0620072005200310ce041a0b02402004450d00200610290b02402002280224450d00200510290b412010272206450d0620062001290000370000200641186a200141186a290000370000200641106a200141106a290000370000200641086a200141086a290000370000200241206a41186a22014200370300200241206a41106a22044200370300200241206a41086a220542003703002002420037032020064120200241206a1000200241186a2001290300370300200241106a2004290300370300200241086a20052903003703002002200229032037030020034101742201200341206a220420042001491b22054100480d000240024020030d002005102721010c010b200720032005102821010b20010d0120054101102a000b102b000b200120036a22032002290300370000200341186a200241186a290300370000200341106a200241106a290300370000200341086a200241086a29030037000020061029200020043602082000200536020420002001360200200241c0006a24000f0b41104101102a000b20074101102a000b1039000b20034101102a000b41204101102a000bd60503097f017e027f23004180026b220324002003410036024020012002200341c0006a10052102024002400240024020032802402204417f460d0020020d010b200041003a00000c010b20032004412020044120491b22056a41004100412020056b2005411f4b1b10cd041a20032002200510ce0421012004411f4d0d0120014180016a41086a2206200141086a220729000037030020014180016a41106a2208200141106a220929000037030020014180016a41186a220a200141186a220b29000037030020012001290000220c3703c0012001200c370380012001200420056b220d4120200d4120491b22046a41004100412020046b2004411f4b1b10cd041a2001200220056a200410ce042101200d411f4d0d01200141a0016a41086a22042007290000370300200141a0016a41106a22052009290000370300200141a0016a41186a220d200b290000370300200141c0006a41186a220e200a290300370300200141c0006a41106a220a2008290300370300200141c0006a41086a2208200629030037030020012001290000220c3703c0012001200c3703a0012001200129038001370340200141c0006a41386a2206200d290300370300200141c0006a41306a220d2005290300370300200141c0006a41286a22052004290300370300200120012903a001370360200141386a22042006290300370300200141306a2206200d290300370300200141286a220d2005290300370300200141206a22052001290360370300200b200e2903003703002009200a290300370300200720082903003703002001200129034037030020021029200041013a0000200041396a2004290300370000200041316a2006290300370000200041296a200d290300370000200041216a2005290300370000200041196a200b290300370000200041116a2009290300370000200041096a2007290300370000200020012903003700010b20034180026a24000f0b418f89c3004133104e000ba00701097f230041c0006b22022400024002400240024002400240411010272203450d00200341086a4100290081e241370000200341002900f9e141370000200242908080808002370204200220033602002002410d360220200241206a20021030024002400240024020022802042204200228020822056b410d490d002005410d6a2103200228020021060c010b2005410d6a22032005490d0120044101742206200320032006491b22074100480d010240024020040d002007102721060c010b200228020020042007102821060b2006450d042002200736020420022006360200200721040b20022003360208200620056a2205410029009ecc41370000200541056a41002900a3cc41370000200241206a2006200310830220022802282203417f4c0d04200228022021050240024020030d00410121080c010b200310272208450d0620082005200310ce041a0b02402004450d00200610290b02402002280224450d00200510290b200241003602282002420137032020012802002104410410272206450d062006200436000020024284808080c000370224200220063602202001280204210720022001410c6a28020022013602002002200241206a10300240024020022802242205200228022822046b2001490d00200228022021060c010b200420016a22062004490d0120054101742209200620062009491b22094100480d010240024020050d002009102721060c010b200228022020052009102821060b2006450d082002200936022420022006360220200921050b200620046a2007200110ce041a200241206a41186a22074200370300200241206a41106a22094200370300200241206a41086a220a4200370300200242003703202006200420016a200241206a1000200241186a2007290300370300200241106a2009290300370300200241086a200a29030037030020022002290320370300200341206a22012003490d0020034101742204200120012004491b22074100480d000240024020030d002007102721040c010b200820032007102821040b20040d0120074101102a000b102b000b200420036a22032002290300370000200341186a200241186a290300370000200341106a200241106a290300370000200341086a200241086a29030037000002402005450d00200610290b200020013602082000200736020420002004360200200241c0006a24000f0b41104101102a000b20074101102a000b1039000b20034101102a000b41044101102a000b20094101102a000bb80304027f027e017f017e230041206b22052400024002400240411410272206450d00200641106a41002800bb8c40360000200641086a41002900b38c40370000200641002900ab8c4037000020064114413410282206450d01200620012900003700142006412c6a200141186a290000370000200641246a200141106a2900003700002006411c6a200141086a290000370000200541086a20064134108401200541086a41106a29030021072005290310210820052802082109200610294101210602402008420020091b220820027d220a2008562007420020091b220720037d2008200254ad7d220820075620082007511b4101470d00200041bf88c000360204200041086a411d3602000c030b024002400240200a428080e983b1de165441002008501b0d00200520012004200a200810910120052802002206450d022005280204210120002006360204200041086a20013602000c010b200041dc88c000360204200041086a411a3602000b410121060c030b2001200a2008108901200041106a2003370300200041086a2002370300410021060c020b41144101102a000b41344101102a000b20002006360200200541206a24000b8d0304027f017e027f017e230041c0006b22052400024002400240200241ff0171417e6a220641024b0d000240024020060e03000201000b200541106a20011092012005290310200358200541186a290300220720045820072004511b0d010c020b200541206a20011092012005290320200356200541286a290300220720045620072004511b0d010b200541306a20011093010240200528023822010d0002402005280234450d00200528023010290b410021010c020b200541888dc300410d1094012005290308420020052802001b2107200141286c210620052802342108200528023022092101024002400240034002402007200141106a2903005a0d002001290300200358200141086a290300220a200458200a2004511b0d00200141206a2d000020027141ff0171200241ff0171460d020b200141286a2101200641586a22060d000b4100210120080d010c020b41ec87c00021012008450d010b200910290b413121060c010b41c687c0002101412621060b2000200636020420002001360200200541c0006a24000b820804067f027e017f077e230041a0016b220224000240024002400240411010272203450d00200341086a41002900ab8d40370000200341002900a38d4037000020034110413010282203450d0120032001290000370010200341286a200141186a290000370000200341206a200141106a290000370000200341186a200141086a29000037000020024180016a41186a2204420037030020024180016a41106a2205420037030020024180016a41086a2206420037030020024200370380012003413020024180016a1000200241e0006a41186a2004290300370300200241e0006a41106a2005290300370300200241e0006a41086a200629030037030020022002290380013703602002410036028001200241e0006a412020024180016a100521040240024002402002280280012205417f460d002004450d002002420037038801200242003703800120024180016a20042005411020054110491b220610ce041a02402005410f4d0d0020024180016a41086a2207290300210820022903800121092002420037038801200242003703800120024180016a200420066a220a200520066b2205411020054110491b220610ce041a2005410f4d0d002007290300210b200229038001210c200242003703800120024180016a200a20066a200520066b2205410820054108491b10ce041a200541074b0d020b418f89c3004133104e000b200310294200210c4200210b0c010b200229038001210d2004102920031029411410272203450d03200341106a41002800bb8c40360000200341086a41002900b38c40370000200341002900ab8c4037000020034114413410282203450d04200320012900003700142003412c6a200141186a290000370000200341246a200141106a2900003700002003411c6a200141086a290000370000200241c8006a20034134108401200241c8006a41106a290300210e2002290350210f2002280248210120031029200241386a41888dc300410d10940142002110200241186a200b420042002002290340420020022802381b2211200d7d220d200d2011561b220d420010d304200241286a200d4200200c420010d304200241086a42004200200c420010d304200e420020011b210b200f420020011b210d4200210c02402002290310200229032084420052200241286a41086a290300220f200229030820022903187c7c220e200f54720d002008200e20022903282210200954200e200854200e2008511b22031b200e7d2009201020031b220e201054ad7d210c200e20107d21100b200c200b200d201056200b200c56200b200c511b22031b210b2010200d20031b210c0b2000200c3703002000200b370308200241a0016a24000f0b41104101102a000b41304101102a000b41144101102a000b41344101102a000bd408040e7f047e017f017e230041f0006b220224000240024002400240024002400240410e10272203450d00200341066a41002900dd8c40370000200341002900d78c403700002003410e412e10282204450d012004200129000037000e200441266a200141186a2900003700002004411e6a200141106a290000370000200441166a200141086a290000370000200241386a41186a22014200370300200241386a41106a22034200370300200241386a41086a22054200370300200242003703382004412e200241386a1000200241106a41186a2001290300370300200241106a41106a2003290300370300200241106a41086a20052903003703002002200229033837031020024100360238200241106a4120200241386a100521060240024020022802382207417f460d002002200736023420022006360230200241086a200241306a102e2002280208450d0802400240200228020c220841e600200841e600491b22090d004108210a0c010b200941286c22011027220a450d050b02402008450d002002280230210b20022802342103200241ec006a210c4100210d4100210e4100210f034020024200370338200241386a200b2003410820034108491b220510ce041a2002200320056b22013602342002200b20056a220536023002400240200341074d0d00200229033821102002420037034020024200370338200241386a20052001411020014110491b220b10ce041a20022001200b6b220336023420022005200b6a22053602302001410f4d0d00200241386a41086a29030021112002290338211220024200370338200241386a20052003410820034108491b220b10ce041a20022003200b6b220136023420022005200b6a220b360230200341074d0d0020022903382113200241003a0038200241386a200b2001410047220510ce041a20012005490d092002200120056b22033602342002200b20056a220b36023020010d010b2009450d0b200a10290c0b0b200f41016a2105200220022800693602602002200c28000036006320022d003821142002200228006336003b20022002280260360238200220022802383602582002200228003b36005b0240200f2009470d00200d20052005200d491b2209ad42287e2215422088a70d0a2015a722014100480d0a02400240200f0d0020011027210a0c010b200a200e20011028210a0b200a450d090b200a200e6a220141206a20143a00002001201137030820012012370300200141186a2010370300200141106a2013370300200141216a2002280258360000200141246a200228005b360000200d41026a210d200e41286a210e2005210f20082005470d000b0b200a450d082008ad4220862009ad84211002402007450d00200610290b200020103702042000200a3602000c010b20004100360208200042083702000b20041029200241f0006a24000f0b410e4101102a000b412e4101102a000b20014108102a000b20052001103e000b20014108102a000b102b000b418f89c3004133104e000bcc0104017f017e017f017e230041206b2203240042002104200341106a41086a220542003703002003420037031020012002200341106a1004200341086a2005290300370300200320032903103703002003410036021020034110200341106a1005210202400240024020032802102201417f470d000c010b20034200370310200341106a20022001410820014108491b10ce041a200141074d0d012003290310210620021029420121040b2000200637030820002004370300200341206a24000f0b418f89c3004133104e000bba0304027f027e017f027e230041306b220224000240024002400240411410272203450d00200341106a41002800bb8c40360000200341086a41002900b38c40370000200341002900ab8c4037000020034114413410282203450d01200320012900003700142003412c6a200141186a290000370000200341246a200141106a2900003700002003411c6a200141086a290000370000200241186a20034134108401200241186a41106a2903002104200229032021052002280218210620031029411810272203450d02200341106a41002900cf8c40370000200341086a41002900c78c40370000200341002900bf8c4037000020034118413810282203450d0320032001290000370018200341306a200141186a290000370000200341286a200141106a290000370000200341206a200141086a290000370000200220034138108401200241106a290300210720022903082108200228020021012003102920002008420020011b22082005420020061b7c220537030020002007420020011b2004420020061b7c2005200854ad7c370308200241306a24000f0b41144101102a000b41344101102a000b41184101102a000b41384101102a000bef0e06017f037e017f017e017f067e230041e0016b220724004200210842002109024020050d0020074190016a2006ad42004280c8afa025420010d30420074198016a290300200729039001220a4280a094a58d1d7c2208200a54ad7c21090b200741c0016a41086a22054200370300200742003703c00141d8cdc500411b200741c0016a1004200741a0016a41086a2005290300370300200720072903c0013703a00141002106200741003602d001200741a0016a4110200741d0016a1005210b024002400240024020072802d0012205417f470d004200210a0c010b200742003703d001200741d0016a200b2005410820054108491b10ce041a200541074d0d0120072903d001210c200b1029200c200c423f87220a7c200a85210a200c42005521060b2007418094ebdc033602a4012007200a200a428094ebdc037f220c4280ec94a37c7e7ca722053602a00120074180016a417f2004418094ebdc032004418094ebdc03491b2204417f417f2004ad200ca7417f200c428080808010541bad7e220aa7200a422088a71b220b200741a0016a2005418094ebdc034b4102746a28020022052004418094ebdc036e220d6c2005ad2004200d4180ec94a37c6c6aad7e428094ebdc0380a76a6a22052005200b491b22056a220b200b2004491b4100200420056b2205200520044b1b20061bad420042e807420010d30441012104200741a0016a2003427f20082007290380017c220a20017c220c200c200a542205200920074180016a41086a2903007c200a200854ad7c220820027c2005ad7c220a200854200a2008511b22051b220e427f200a20051b220f4101109001024020072802a0014101470d00200041003a00010c020b200741a0016a41106a290300210a200741386a200741a0016a41086a290300220242004204420010d304200741286a420042002002420010d304200741c8006a2007290338200741386a41086a2903002208200a42028620072903287c7c220c4205420010d40420072903302109200741c8006a41086a290300210120072903482110200741a0016a109701200741f0006a200741a0016a42b3e6cc99b3e6cc99332010200a200a42ffffffffffffffff3f8352200942005272200c2008547222041b22082002200820025442b3e6cc99b3e6cc9933200120041b220c200a54200c200a511b22041b2208200c200a20041b220c108301200741f0006a41086a290300211020072903702109200741d8006a41b18ac0004116108601200820097d200920087d20092008582010200c582010200c5122041b22051b2111200c20107d2008200954ad7d2010200c7d2009200854ad7d20051b2112200a200c7d2002200854ad7d2101200220087d210a200741d8006a41106a2903004200200728025822051b21022007290360420020051b21130240024020092008562010200c5620041b0d00200741d0016a41086a22044200370300200742003703d00141b18ac0004116200741d0016a1004200741c0016a41086a2004290300370300200720072903d0013703c00120074200200220127d2013201154ad7d2208201320117d220c201356200820025620082002511b22041b3703d80120074200200c20041b3703d001200741d0016a21040c010b200741d0016a41086a22044200370300200742003703d00141b18ac0004116200741d0016a1004200741c0016a41086a2004290300370300200720072903d0013703c0012007427f200220127c201320117c220c2013542204ad7c22082004200820025420082002511b22041b3703d8012007427f200c20041b3703d001200741d0016a21040b200741c0016a4110200441101003200741a0016a109801200741186a200741a0016a200a2001108301200741186a41086a290300210c20072903182108200741b18ac0004116108601200a20087d2008200a7d2008200a58200c200158200c20015122041b22051b21102001200c7d200a200854ad7d200c20017d2008200a54ad7d20051b2113200741106a2903004200200728020022051b21092007290308420020051b2102024002402008200a56200c20015620041b0d00200741d0016a41086a22044200370300200742003703d00141b18ac0004116200741d0016a1004200741c0016a41086a2004290300370300200720072903d0013703c00120074200200920137d2002201054ad7d2208200220107d220a200256200820095620082009511b22041b3703d80120074200200a20041b3703d001200741d0016a21040c010b200741d0016a41086a22044200370300200742003703d00141b18ac0004116200741d0016a1004200741c0016a41086a2004290300370300200720072903d0013703c0012007427f200920137c200220107c220a2002542204ad7c22082004200820095420082009511b22041b3703d8012007427f200a20041b3703d001200741d0016a21040b200741c0016a4110200441101003200041306a41013a0000200041286a4200370300200041206a4280808080c000370300200041186a4204370300200041106a427f370300200041086a200e427f200f501b370300410021040c010b418f89c3004133104e000b200020043a0000200741e0016a24000b840201067f230041c0006b2201240002400240410410272202450d00200241edde91e30636000020024104410c10282202450d01200242f0f2bda1a7ee9cb9f900370004200141346a42003702002001413c6a4100360200200141206a41086a2203200241086a2800003602002001420037022c200141106a2204200141206a41106a290300370300200141186a2205200141206a41186a290300370300200141086a220620032903003703002001200229000037030020021029200041186a2005290300370000200041106a2004290300370000200041086a200629030037000020002001290300370000200141c0006a24000f0b41044101102a000b410c4101102a000bc60502057f017e230041d0006b22012400200141306a41086a220242003703002001420037033041dbecc2004111200141306a1004200141086a22032002290300370300200120012903303703002001410036023020014110200141306a10052104024002400240024020012802302205417f460d00200141306a2005412020054120491b22026a41004100412020026b2002411f4b1b10cd041a200141306a2004200210ce041a2005411f4d0d01200141106a41186a2205200141306a41186a290000370300200141106a41106a2202200141306a41106a290000370300200141106a41086a2203200141306a41086a2900003703002001200129003037031020041029200041186a2005290300370000200041106a2002290300370000200041086a2003290300370000200020012903103700000c030b200242003703002001420037033041aa8dc300410d200141306a100420032002290300370300200120012903303703002001410036023020014110200141306a100521020240024020012802302205417f460d002001200536021420012002360210200141306a200141106a104320012802302204450d03200129023421062005450d01200210290c010b41042104420021060b20004200370000200041186a4200370000200041106a4200370000200041086a420037000002402006422088a72200450d00200041246c21052004210003400240024020002d0000220241034b0d0002400240024020020e0404000102040b2000410c6a280200450d03200041086a28020010290c030b2000410c6a280200450d02200041086a28020010290c020b2000410c6a280200450d01200041086a28020010290c010b200041086a280200450d00200041046a28020010290b200041246a21002005415c6a22050d000b0b2006a7450d02200410290c020b418f89c3004133104e000b418f89c3004133104e000b200141d0006a24000b130020004102360204200041b48dc0003602000b3400200041f8f3c10036020420004100360200200041146a4105360200200041106a41b49cc000360200200041086a42083702000b3701017f02404110102722020d0041104101102a000b2002420037000820024200370000200042908080808002370204200020023602000bbd0b03057f027e037f230041e0016b2203240002400240024002400240024002400240411810272204450d00200441106a41002900cf8c40370000200441086a41002900c78c40370000200441002900bf8c4037000020044118413810282204450d0120042000290000370018200441306a200041186a290000370000200441286a200041106a290000370000200441206a200041086a290000370000200341c0016a41186a22054200370300200341c0016a41106a22064200370300200341c0016a41086a22074200370300200342003703c00120044138200341c0016a1000200341d0006a41186a2005290300370300200341d0006a41106a2006290300370300200341d0006a41086a2007290300370300200320032903c001370350200320013703c001200320023703c801200341d0006a4120200341c0016a41101003200410290240200142ffffe883b1de165620024200522002501b0d00411810272204450d03200441106a41002900cf8c40370000200441086a41002900c78c40370000200441002900bf8c4037000020044118413810282204450d0420042000290000370018200441306a200041186a290000370000200441286a200041106a290000370000200441206a200041086a290000370000200341c0016a41186a22054200370300200341c0016a41106a22064200370300200341c0016a41086a22074200370300200342003703c00120044138200341c0016a1000200341d0006a41186a2005290300370300200341d0006a41106a2006290300370300200341d0006a41086a2007290300370300200320032903c001370350200341386a200341d0006a108a01200341386a41106a290300210120032802382105200329034021022004102902402002200184500d002005450d00200341206a41b18ac0004116108601200341206a41106a29030021082003290328210920032802202104200341d0006a41086a220542003703002003420037035041b18ac0004116200341d0006a1004200341c0016a41086a2005290300370300200320032903503703c001200342002008420020041b220820017d2009420020041b2201200254ad7d2209200120027d2202200156200920085620092008511b22041b37035820034200200220041b370350200341c0016a4110200341d0006a411010030b411410272204450d05200441106a41002800bb8c40360000200441086a41002900b38c40370000200441002900ab8c4037000020044114413410282204450d06200420002900003700142004412c6a200041186a290000370000200441246a200041106a2900003700002004411c6a200041086a290000370000200341086a20044134108401200341086a41106a290300210220032802082105200329031021012004102902402001200284500d0020050d010b411310272204450d072004410f6a41002800d68d43360000200441086a41002900cf8d43370000200441002900c78d4337000020044113413310282204450d08200420002900003700132004412b6a200041186a2206290000370000200441236a200041106a22072900003700002004411b6a200041086a220a290000370000200341d0006a41186a220b4200370300200341d0006a41106a220c4200370300200341d0006a41086a220542003703002003420037035020044133200341d0006a1000200341c0016a41186a200b290300370300200341c0016a41106a200c290300370300200341c0016a41086a2005290300370300200320032903503703c001200341c0016a4120100c20041029200541013a0000200341d9006a2000290000370000200341e1006a200a290000370000200341e9006a2007290000370000200341f1006a2006290000370000200341023a005041b8d6c5004100200341d0006a1088010b200341e0016a24000f0b41184101102a000b41384101102a000b41184101102a000b41384101102a000b41144101102a000b41344101102a000b41134101102a000b41334101102a000b130020004105360204200041c0adc0003602000bcb0201057f230041c0006b22012400024002400240411b10272202450d00200241176a4100280081b140360000200241106a41002900fab040370000200241086a41002900f2b040370000200241002900eab0403700002002411b413610282203450d012003200036001b200141206a41186a22024200370300200141206a41106a22004200370300200141206a41086a22044200370300200142003703202003411f200141206a1000200141186a22052002290300370300200141106a2000290300370300200141086a200429030037030020012001290320370300412010272202450d0220022001290300370000200241186a2005290300370000200241106a200141106a290300370000200241086a200141086a2903003700002003102920024120100e20021029200141c0006a24000f0b411b4101102a000b41364101102a000b41204101102a000bd50204037f027e017f017e230041306b22042400200441206a200110950102400240024002402004290320200441206a41086a29030084500d00411410272205450d0241002106200541106a41002800bb8c40360000200541086a41002900b38c40370000200541002900ab8c4037000020054114413410282205450d03200520012900003700142005412c6a200141186a290000370000200541246a200141106a2900003700002005411c6a200141086a290000370000200441086a20054134108401200441086a41106a290300210720042903102108200428020821092005102920012008420020091b220820027c220a2007420020091b20037c200a200854ad7c108901200041106a2003370300200041086a20023703000c010b2000419d88c000360204200041086a4122360200410121060b20002006360200200441306a24000f0b41144101102a000b41344101102a000be61805057f027e047f0a7e027f23004190036b22042400200441f0006a2001108c010240024020042d00702205417f6a41ff017141024f0d00200041003a0000200041086a200441f0006a41e00010ce041a0c010b200441d0016a41086a2206200441f0006a41c8006a290300370300200441d0016a41106a2207200441f0006a41d0006a290300370300200441d0016a41186a2208200441f0006a41d8006a2903003703002004200441f0006a41c0006a2903003703d001200441f0006a41106a2903002109200441f0006a41086a290300210a200441f0006a413c6a280200210b200441f0006a41386a280200210c200441a4016a280200210d200441f0006a41306a280200210e200441f0006a41286a290300210f200441f0006a41206a2903002110200441f0006a41186a2903002111200441e0006a41888dc300410d1094010240024002400240024002400240024002400240024002400240420042002004290368420020042802601b221220027d220220022012561b220220117d221320132002561b2214500d00411410272206450d02200641106a41002800bb8c40360000200641086a41002900b38c40370000200641002900ab8c4037000020064114413410282206450d03200620012900003700142006412c6a200141186a290000370000200641246a200141106a2900003700002006411c6a200141086a290000370000200441c8006a20064134108401200441386a20042903504200200428024822071b2202200441c8006a41106a290300420020071b221542e807420010d404200610294200200bad2213200429033822167d221720172013564200200441386a41086a2903002013201654ad7c7d22134200522013501b22061b22164200201320061b221384500d0402400240024002402002429080e983b1de165441002015501b0d00200441206a201642028620134202862016423e8884201442ffffffff0f8342ffffffff0f2014428080808010541b420010d304200441306a2001410842002002200242f0ff96fccea1697c2213200a200a201356200920152013200254ad7c427f7c22135620092013511b22061b22142004290320221620142016542013200920061b2214200441206a41086a29030022135420142013511b22061b22177d2218201820025620152014201320061b22147d2002201754ad7d220220155620022015511b22071b4200200220071b10910120042802300d010240024020060d002003450d010b20044190026a20012017201441081090012004280290024101460d0c20044190026a41106a290300211420044190026a41086a22072903002102200441086a41b18ac0004116108601200441086a41106a2903002115200429031021172004280208210820074200370300200442003703900241b18ac000411620044190026a1004200441f0026a41086a200729030037030020042004290390023703f002200442002015420020081b221520147d2017420020081b2214200254ad7d2217201420027d2202201456201720155620172015511b22071b3703980220044200200220071b37039002200441f0026a411020044190026a411010030b20060d0120030d03200041003a0008200041023a0000200041186a2009370000200041106a200a370000200041c4006a200b360000200041c0006a200c3600002000413c6a200d360000200041386a200e360000200041306a200f370000200041286a2010370000200041206a2011370000200041c8006a20042903d001370000200041d0006a200441d8016a290300370000200041d8006a200441d0016a41106a290300370000200041e0006a200441d0016a41186a290300370000200541037122004103460d0520000e03110505110b411710272206450d082006410f6a41002900af9342370000200641086a41002900a89342370000200641002900a0934237000020064117413710282206450d09200620012900003700172006412f6a200141186a290000370000200641276a200141106a2900003700002006411f6a200141086a29000037000020044190026a41186a2201420037030020044190026a41106a220b420037030020044190026a41086a2203420037030020044200370390022006413720044190026a1000200441f0026a41186a2001290300370300200441f0026a41106a200b290300370300200441f0026a41086a200329030037030020042004290390023703f002200441f0026a4120100c20061029200e200c100d200041023a0008200041013a00000c010b2004410036029002200e200c20044190026a100f2108200428029002220b417f460d0a200441f0026a41186a200441d0016a41186a290300370300200441f0026a41106a200441d0016a41106a290300370300200441f0026a41086a200441d0016a41086a290300370300200420042903d0013703f002200441003602980220044201370390022004200b3602f001200441f0016a20044190026a10300240024002400240200428029402220720042802980222066b200b490d0020042802900221030c010b2006200b6a22032006490d0120074101742219200320032019491b22194100480d010240024020070d002019102721030c010b20042802900220072019102821030b2003450d0e20042019360294022004200336029002201921070b200320066a2008200b10ce041a024002402006200b6a22060d00410121190c010b20064100480d01200610272219450d0f20192003200610ce041a0b02402007450d00200310290b20064101742203200641206a220720072003491b221a4100480d000240024020060d00201a102721030c010b20192006201a102821030b20030d01201a4101102a000b102b000b200320066a220620042903f002370000200641186a200441f0026a41186a290300370000200641106a200441f0026a41106a290300370000200641086a200441f0026a41086a29030037000020044190026a41186a2206420037030020044190026a41106a2219420037030020044190026a41086a221a420037030020044200370390022003200720044190026a1000200441f0016a41186a22072006290300370300200441f0016a41106a22062019290300370300200441f0016a41086a2219201a29030037030020042004290390023703f00120031029200441a9026a2007290300370000200441a1026a200629030037000020044199026a2019290300370000200420042903f00137009102200441013a009002200120044190026a10a101200e200c100d200041013a0000200041086a20044190026a41e00010ce041a200b450d00200810290b200d450d0c200e10290c0c0b200441cc026a200b360200200441c8026a200c360200200441c4026a200d360200200441c0026a200e360200200441b8026a200f370300200441b0026a201037030020044190026a41186a2012370300200441d0026a20042903d001370300200441d8026a200441d0016a41086a290300370300200441e0026a200441d0016a41106a290300370300200441e8026a200441d0016a41186a29030037030020044190026a41106a200920137d200a201654ad7d370300200441003a0090022004200a20167d37039802200120044190026a10a101200041023a0000200041086a20044190026a41e00010ce041a0c0b0b200041003a0008200041003a0000200041186a2009370000200041106a200a370000200041c4006a200b360000200041c0006a200c3600002000413c6a200d360000200041386a200e360000200041306a200f370000200041286a2010370000200041206a2011370000200041c8006a20042903d001370000200041d0006a2006290300370000200041d8006a2007290300370000200041e0006a20082903003700000c0a0b200d450d0b0c0a0b41144101102a000b41344101102a000b200041003a0008200041003a0000200041186a2009370000200041106a200a370000200041c4006a200b360000200041c0006a200c3600002000413c6a200d360000200041386a200e360000200041306a200f370000200041286a2010370000200041206a2011370000200041c8006a20042903d001370000200041d0006a200441d8016a290300370000200041d8006a200441d0016a41106a290300370000200041e0006a200441d0016a41186a2903003700000c060b41174101102a000b41374101102a000b20042004290294023703f00241a1b1c00041fe00200441f0026a41e88cc00010a201000b41b0cfc5004138104e000b20194101102a000b20064101102a000b0240200541037122004103460d0020000e03020000020b200d450d010b200e10290b20044190036a24000bb10201047f230041c0006b2202240002400240411710272203450d002003410f6a41002900af9342370000200341086a41002900a89342370000200341002900a0934237000020034117413710282203450d01200320002900003700172003412f6a200041186a290000370000200341276a200041106a2900003700002003411f6a200041086a290000370000200241206a41186a22004200370300200241206a41106a22044200370300200241206a41086a220542003703002002420037032020034137200241206a1000200241186a2000290300370300200241106a2004290300370300200241086a20052903003703002002200229032037030020024120360224200220023602202001200241206a10dc0220031029200241c0006a24000f0b41174101102a000b41374101102a000b810101017f230041c0006b220424002004200136020c2004200036020820042003360214200420023602102004412c6a41023602002004413c6a411e3602002004420237021c200441b481c600360218200441023602342004200441306a3602282004200441106a3602382004200441086a360230200441186a41c881c6001057000b130020004101360204200041a0b2c0003602000b3400200041d4f4c10036020420004100360200200041146a4103360200200041106a41bcb3c000360200200041086a42083702000b130020004101360204200041c0b6c0003602000bf51007017f017e047f017e037f067e057f23004190016b22032400200341086a41888dc300410d1094012003290310210420032802082105200341286a427f370300200341186a41286a41023a0000200341186a41186a2002370300200341386a20002900003703002003427f3703204201210220034201370318200341e8006a200110930120032802682106200328026c2107024002400240024002400240024020032802702208450d002004420020051b210902400240200341e8006a41186a220a2000460d0020034189016a210b200841286c210c42012102200621050340200541086a2903002104200541106a290300210d200541186a290300210e2005290300210f200341e8006a41206a200541206a290300370300200341e8006a41186a200e370300200341e8006a41106a200d370300200341e8006a41086a20043703002003200f37036802400240200a2900002000290000510d00200329037822042009580d012003200b2800003602602003200b41036a280000360063200541286a2105200341f0006a290300210d2003290368210e20032d008801210c0c060b20032903182104420021022003420037031820044201520d00200341186a41186a29030021102003290328211120032903202112200541286a21050c030b200541286a2105200c41586a220c0d000c030b0b200841286c210c200341186a41186a29030021102003290328211120032903202112200329031821022006210502400340200541086a2903002104200541106a290300210d200541186a290300210e2005290300210f200341e8006a41206a200541206a290300370300200341e8006a41186a200e370300200341e8006a41106a200d370300200341e8006a41086a2004370300200342003703182003200f37036820024201510d01200541286a210542002102200c41586a220c0d000c030b0b200541286a21050b200341f0006a2903002202201120122003290368220454201120025420112002511b220c1b210d20042012200c1b210e20032903782202201020102002541b210420032d008801410272210c420021020c010b41002108024020070d00410021134108210b410821050c020b200610294108210b41002113410821050c010b200329038001210f2003200328006336005b200320032802603602582003200328005b36005320032003280258360250200320032802503602482003200328005336004b41281027220b450d03200b200e370300200b200c3a0020200b200f370318200b2004370310200b2003280248360021200b200d370308200b41246a200328004b3600000240024020052006200841286c6a220a470d0041012108410121130c010b200341e8006a41186a210c20034189016a221441036a211541012108410121130340024002400240200c2000470d00200341186a41186a290300210d200329032821042003290320210e200329031821020340200341e8006a41206a200541206a290300370300200c200541186a290300370300200341e8006a41106a200541106a290300370300200341e8006a41086a200541086a290300370300200320052903003703682003420037031820024201510d0242002102200a200541286a2205470d000c050b0b02400340200341e8006a41206a200541206a290300370300200c200541186a290300370300200341e8006a41106a200541106a290300370300200341e8006a41086a2216200541086a2903003703002003200529030037036802400240200c2900002000290000510d00200329037822042009580d012003201428000036026020032015280000360063200541286a21052016290300210f2003290368210e20032d00880121170c050b20032903182104420021022003420037031820044201510d020b200a200541286a2205460d050c000b0b200341186a41186a290300210d200329032821042003290320210e0b200541286a2105200341e8006a41086a29030022022004200e2003290368221154200420025420042002511b22161b210f2011200e20161b210e20032903782202200d200d2002541b210420032d0088014102722117420021020b200329038001210d2003200328006336005b20032003280260360258200320032802583602502003200328005b3600532003200328005336006b20032003280250360268024020132008470d00200841016a22162008490d0720084101742213201620162013491b2213ad42287e2211422088a70d072011a722164100480d070240024020080d0020161027210b0c010b200b200841286c20161028210b0b200b450d040b200b200841286c6a221620173a00202016200f3703082016200e3703002016200d3703182016200437031020162003280268360021201641246a200328006b360000200841016a21082005200a470d000b0b02402007450d00200610290b200b21050b024020024201520d00200341e8006a41206a200341206a220041206a290300370300200341e8006a41186a200041186a290300370300200341e8006a41106a200041106a290300370300200341e8006a41086a200041086a29030037030020032000290300370368024020132008470d00200841016a22052008490d0520084101742200200520052000491b2213ad42287e2202422088a70d052002a722004100480d050240024020080d002000102721050c010b200b200841286c2000102821050b2005450d030b2005200841286c6a22002003290368370300200041206a200341e8006a41206a290300370300200041186a200341e8006a41186a290300370300200041106a200341e8006a41106a290300370300200041086a200341e8006a41086a290300370300200841016a21080b200320083602702003201336026c200320053602682001200341e8006a10a70120034190016a24000f0b20164108102a000b20004108102a000b41284108102a000b102b000b9c0802087f027e230041d0006b220224000240024002400240024002400240410e10272203450d00200341066a41002900dd8c40370000200341002900d78c403700002003410e412e10282204450d012004200029000037000e200441266a200041186a2900003700002004411e6a200041106a290000370000200441166a200041086a290000370000200241286a41186a22004200370300200241286a41106a22034200370300200241286a41086a22054200370300200242003703282004412e200241286a1000200241086a41186a2000290300370300200241086a41106a2003290300370300200241086a41086a20052903003703002002200229032837030820024100360230200242013703282001280200210520022001280208220036024c200241cc006a200241286a10300240024020000d0020022802302106200228022c2100200228022821070c010b200041286c2108200228022c210020022802302106034002400240200020066b4108490d00200641086a2107200228022821030c010b200641086a22072006490d0920004101742203200720072003491b22094100480d090240024020000d002009102721030c010b200228022820002009102821030b2003450d052002200936022c20022003360228200921000b20022007360230200320066a200541186a290000370000200541086a290300210a2005290300210b02400240200020076b4110490d00200741106a21060c010b200741106a22062007490d0920004101742209200620062009491b22094100480d090240024020000d002009102721030c010b200320002009102821030b2003450d062002200936022c20022003360228200921000b200320076a2207200a3700082007200b37000020022006360230200541106a290300210a0240200020066b41074b0d00200641086a22072006490d0920004101742209200720072009491b22074100480d090240024020000d002007102721030c010b200320002007102821030b2003450d072002200736022c200220033602280b2002200641086a360230200320066a200a37000002400240200228022c220020022802302203460d00200228022821070c010b200341016a22002003490d0920034101742206200020002006491b22004100480d090240024020030d002000102721070c010b200228022820032000102821070b2007450d082002200036022c200220073602280b2002200341016a2206360230200720036a200541206a2d00003a0000200541286a2105200841586a22080d000b0b200241086a412020072006100302402000450d00200710290b200410290240200141046a280200450d00200128020010290b200241d0006a24000f0b410e4101102a000b412e4101102a000b20094101102a000b20094101102a000b20074101102a000b20004101102a000b102b000bc10f07017f017e057f047e017f057e047f230041b0016b22062400200641086a41888dc300410d1094012006290310210720062802082108200641286a2003370300200641186a41286a20053a0000200641186a41186a22052004370300200641386a2209200029000037030020062002370320420121032006420137031820064188016a2001109301200628028801210a200628028c01210b024002400240024002400240024002400240200628029001220c450d002007420020081b210d2005290300210e2006290328210f2006290320211020062903182103024020064188016a41186a22112000470d00200c41286c2108200a41286a21050340200641f8006a41086a200941086a2903003703002006200929030037037820034201510d03200541286a210542002103200841586a22080d000b42002103200642003703180c010b200c41286c21082003210220102112200f2113200e2114200a21050340200541086a2903002104200541106a2903002107200541186a29030021152005290300211620064188016a41206a200541206a29030037030020064188016a41186a201537030020064188016a41106a2217200737030020064188016a41086a2004370300200620163703880102400240024020112900002000290000510d00200629039801200d560d0120022104420021020c020b200641f8006a41086a200941086a2903003703002006200929030037037842002103420021104200210f4200210e420021042012210720132115201421160c010b200641f8006a41086a201141086a29030037030020062011290300370378201729030021162006290390012115200629038801210720022104420121020b20024201510d03200541286a210520042102200841586a22080d000b200641306a200e37030020062003370318200620103703202006200f3703280b410021170240200b0d004100211841082119410821050c040b200a10294108211941002118410821050c030b42002104200642003703180c010b200641306a2014370300200620043703182006201237032020062013370328200541286a2105200721102015210f2016210e0b200641c8006a41086a2208200641f8006a41086a29030037030020062006290378370348412810272219450d0420192006290348370318201920103703002019200f370308201941206a2008290300370300201941106a200e370300024002402005200a200c41286c6a2211470d0041012117410121180c010b20064188016a41186a210820042102410121174101211803400240024020082000460d0020022103034020064188016a41206a200541206a2903003703002008200541186a29030037030020064188016a41106a220c200541106a29030037030020064188016a41086a200541086a290300370300200620052903003703880102400240024020082900002000290000510d00200629039801200d560d0120032102420021030c020b200641f8006a41086a200941086a290300370300420021042006420037031820062009290300370378420021022012210720132115201421160c010b200641f8006a41086a200841086a29030037030020062008290300370378200c29030021162006290390012115200629038801210720032102420121030b024020034201510d00200221032011200541286a2205470d010c050b0b200541286a21050c010b02400340200641f8006a41086a200941086a290300370300200642003703182006200929030037037820024201510d01420021022011200541286a2205470d000b420021040c030b200541286a210542002104420021022012210720132115201421160b200641d8006a41086a200641f8006a41086a290300220337030020062006290378220e37035820064188016a41086a221a20033703002006200e37038801024020182017470d00201741016a220c2017490d0620174101742218200c200c2018491b2218ad42287e2203422088a70d062003a7220c4100480d060240024020170d00200c102721190c010b2019201741286c200c102821190b2019450d040b2019201741286c6a220c2015370308200c2007370300200c200629038801370318200c41106a2016370300200c41206a201a290300370300201741016a211720052011470d000b0b0240200b450d00200a10290b20042103201921050b024020034201520d0020064188016a41206a200641206a220941206a29030037030020064188016a41186a200941186a29030037030020064188016a41106a200941106a29030037030020064188016a41086a200941086a2903003703002006200929030037038801024020182017470d00201741016a22052017490d0420174101742209200520052009491b2218ad42287e2202422088a70d042002a722094100480d040240024020170d002009102721050c010b2019201741286c2009102821050b2005450d030b2005201741286c6a2209200629038801370300200941206a20064188016a41206a290300370300200941186a20064188016a41186a290300370300200941106a20064188016a41106a290300370300200941086a20064188016a41086a290300370300201741016a21170b20062017360290012006201836028c012006200536028801200120064188016a10a701200641b0016a24000f0b200c4108102a000b20094108102a000b102b000b41284108102a000bb20201037f23004180016b2202240002400240024002400240200128020022034110710d002000280200210420034120710d012004ad4101200110aa0121000c020b20002802002104410021000340200220006a41ff006a2004410f712203413072200341d7006a2003410a491b3a00002000417f6a2100200441047622040d000b20004180016a22044181014f0d022001410141e8d9c5004102200220006a4180016a410020006b10ab0121000c010b410021000340200220006a41ff006a2004410f712203413072200341376a2003410a491b3a00002000417f6a2100200441047622040d000b20004180016a22044181014f0d022001410141e8d9c5004102200220006a4180016a410020006b10ab0121000b20024180016a240020000f0b2004418001103e000b2004418001103e000bd50203027f017e037f230041306b22032400412721040240024020004290ce005a0d00200021050c010b412721040340200341096a20046a2206417c6a200020004290ce0080220542f0b17f7e7ca7220741ffff037141e4006e220841017441fad6c5006a2f00003b00002006417e6a2008419c7f6c20076a41ffff037141017441fad6c5006a2f00003b00002004417c6a2104200042ffc1d72f5621062005210020060d000b0b02402005a7220641e3004c0d00200341096a2004417e6a22046a2005a7220741ffff037141e4006e2206419c7f6c20076a41ffff037141017441fad6c5006a2f00003b00000b024002402006410a480d00200341096a2004417e6a22046a200641017441fad6c5006a2f00003b00000c010b200341096a2004417f6a22046a200641306a3a00000b2002200141b8d6c5004100200341096a20046a412720046b10ab012104200341306a240020040be40501057f024002402001450d00412b418080c4002000280200220641017122011b2107200120056a21080c010b200541016a210820002802002106412d21070b0240024020064104710d00410021020c010b4100210902402003450d002003210a200221010340200920012d000041c00171418001466a2109200141016a2101200a417f6a220a0d000b0b200820036a20096b21080b410121010240024020002802084101460d00200020072002200310b9040d012000280218200420052000411c6a28020028020c1105000f0b02402000410c6a280200220920084b0d00200020072002200310b9040d012000280218200420052000411c6a28020028020c1105000f0b0240024020064108710d00200920086b210941002101024002400240410120002d0030220a200a4103461b0e0402000100020b20092101410021090c010b20094101762101200941016a41017621090b200141016a210103402001417f6a2201450d0220002802182000280204200028021c280210110400450d000b41010f0b41012101200041013a003020004130360204200020072002200310b9040d01200920086b210941002101024002400240410120002d0030220a200a4103461b0e0402000100020b20092101410021090c010b20094101762101200941016a41017621090b200141016a2101024003402001417f6a2201450d0120002802182000280204200028021c280210110400450d000b41010f0b2000280204210a41012101200028021820042005200028021c28020c1105000d01200941016a2109200028021c210320002802182100034002402009417f6a22090d0041000f0b410121012000200a2003280210110400450d000c020b0b2000280204210a41012101200020072002200310b9040d00200028021820042005200028021c28020c1105000d00200941016a2109200028021c210320002802182100034002402009417f6a22090d0041000f0b410121012000200a2003280210110400450d000b0b20010bb80405027f027e017f027e017f230041c0006b22042400024002400240024002400240411410272205450d00200541106a41002800bb8c40360000200541086a41002900b38c40370000200541002900ab8c4037000020054114413410282205450d01200520012900003700142005412c6a200141186a290000370000200541246a200141106a2900003700002005411c6a200141086a290000370000200441286a20054134108401200441286a41106a290300210620042903302107200428022821082005102902402007420020081b220720025422052006420020081b220620035420062003511b450d0041cbb9c0002105411521010c060b200441206a20014104200720027d2207200620037d2005ad7d2206109101200428022022050d04411810272208450d0241002105200841106a41002900cf8c40370000200841086a41002900c78c40370000200841002900bf8c4037000020084118413810282208450d0320082001290000370018200841306a200141186a290000370000200841286a200141106a290000370000200841206a200141086a290000370000200441086a20084138108401200441086a41106a29030021092004290310210a2004280208210b200810292001200a4200200b1b220a20027c220220094200200b1b20037c2002200a54ad7c109c012001200720061089010c050b41144101102a000b41344101102a000b41184101102a000b41384101102a000b200428022421010b2000200136020420002005360200200441c0006a24000bf10306027f027e017f027e017f017e230041306b220324000240024002400240411810272204450d00200441106a41002900cf8c40370000200441086a41002900c78c40370000200441002900bf8c4037000020044118413810282204450d0120042000290000370018200441306a200041186a290000370000200441286a200041106a290000370000200441206a200041086a290000370000200341186a20044138108401200341186a41106a2903002105200329032021062003280218210720041029411410272204450d02200441106a41002800bb8c40360000200441086a41002900b38c40370000200441002900ab8c4037000020044114413410282204450d03200420002900003700142004412c6a200041186a290000370000200441246a200041106a2900003700002004411c6a200041086a290000370000200320044134108401200341106a2903002108200329030821092003280200210a20041029200020094200200a1b220920012006420020071b220620062001562005420020071b220520025620052002511b22041b22017c220b20084200200a1b2002200520041b22027c200b200954ad7c1089012000200620017d200520027d2006200154ad7d109c01200341306a24000f0b41184101102a000b41384101102a000b41144101102a000b41344101102a000b130020004101360204200041e0b9c0003602000b13002000410236020420004198bbc0003602000b3101017f02404108102722020d0041084101102a000b20004288808080800137020420002002360200200242e5003700000bfa0405037f017e037f017e067f230041206b2202240002400240024002400240200141106a2802002203417f4c0d0020012802082104200129030021050240024020030d00410121060c010b200310272206450d020b20062004200310ce0421072001411c6a2802002208ad420c7e2209422088a70d002009a72204417f4c0d002001280214210a0240024020040d004104210b0c010b20041027220b450d030b0240024020080d004100210c0c010b200a2008410c6c6a210d4100210c200b21060340200a41086a2802002204417f4c0d02200a280200210e0240024020040d004101210f0c010b20041027220f450d060b200f200e200410ce04210e200641086a2004360200200641046a20043602002006200e3602002006410c6a2106200c41016a210c200a410c6a220a200d470d000b0b200241086a2001412c6a290200370300200241106a200141346a290200370300200241186a2001413c6a29020037030020022001290224370300200141d0006a2802002204417f4c0d00200128024821062001280220210a0240024020040d004101210e0c010b20041027220e450d050b200e2006200410ce0421062000200a3602202000411c6a200c360200200041186a2008360200200041146a200b360200200041106a20033602002000410c6a20033602002000200736020820002005370300200041d0006a2004360200200041cc006a200436020020002006360248200020022903003702242000412c6a200241086a290300370200200041346a200241106a2903003702002000413c6a200241186a290300370200200241206a24000f0b1039000b20034101102a000b20044104102a000b20044101102a000b20044101102a000bdf0401077f230041c0006b2203240002400240024002400240411b10272204450d00200441176a4100280081b140360000200441106a41002900fab040370000200441086a41002900f2b040370000200441002900eab0403700002004411b413610282204450d012004200136001b200341186a22014200370300200341106a22054200370300200341086a22064200370300200342003703002004411f20031000200341206a41186a22072001290300370300200341206a41106a2005290300370300200341206a41086a200629030037030020032003290300370320412010272201450d0220012003290320370000200141186a2007290300370000200141106a200341206a41106a2205290300370000200141086a200341206a41086a220629030037000020041029412010272204450d0320042002290000370000200441186a200241186a290000370000200441106a200241106a290000370000200441086a200241086a290000370000200341186a22024200370300200341106a22074200370300200341086a22084200370300200342003703002004412020031000200341206a41186a220920022903003703002005200729030037030020062008290300370300200320032903003703202001412041c00010282201450d0420012003290320370020200141386a2009290300370000200141306a200341306a290300370000200141286a200341286a29030037000020041029200042c0808080800837020420002001360200200341c0006a24000f0b411b4101102a000b41364101102a000b41204101102a000b41204101102a000b41c0004101102a000bd30102027f027e200028022021020240024002400240410410272203450d00200320023600002000280224210220034104410810282203450d0120032002360004200041086a29030021042000290300210520034108411810282203450d0220032005370008200341106a2004370000200041186a29030021042000290310210520034118413010282200450d0320002005370018200041206a200437000020012802002001280204200041281003200010290f0b41044101102a000b41084101102a000b41184101102a000b41304101102a000bb6750b097f027e087f017e047f017e017f027e027f017e127f230041b0036b22012400024002400240024020004280e101824200520d00200141f8006a4194c1c500411410b5012001280278450d00200128027c2202450d0020014180026a41086a22034200370300200142003703800241d1c2c000410f20014180026a100420014190036a41086a2003290300370300200120012903800237039003200141003602800220014190036a411020014180026a1005210302400240024002400240024002400240024002402001280280022204417f460d002003450d00200120043602f402200120033602f00220014180026a200141f0026a10412001280280022205450d0220014188026a280200210620012802840221072004450d01200310290c010b4108210541002106410021070b20014180026a41086a22034200370300200142003703800241e0c2c000411420014180026a100420014190036a41086a2003290300370300200120012903800237039003200141003602800220014190036a411020014180026a10052103024002402001280280022204417f460d002003450d00200120033602f002200120043602f402200142003703800220014180026a20032004410820044108491b220810ce041a2001200420086b22093602f4022001200320086a22083602f002200441074d0d03200129038002210a200141003602800220014180026a20082009410420094104491b220410ce041a2001200920046b3602f4022001200820046a3602f002200941034d0d03200128028002210420014180026a200141f0026a102d2001280280022209450d03200129028402210b200310292004200b422088a76b20066a2103200ba7450d01200910290c010b200141e8006a41888dc300410d1094012001290370420020012802681b210a41002104200621030b200320024f0d020c030b418f89c3004133104e000b418f89c3004133104e000b0240200420024f0d00200420026b220220066a220320024f0d022005200341286c6a290320210a0c010b200141d8006a4184c3c00041141094012001290360420020012802581b200a7c210a0b200a42ffe0017c220a200a4280e101827d210a02402007450d00200510290b200a2000520d0420014180026a41086a22024200370300200142003703800241d1c2c000410f20014180026a100420014190036a41086a2002290300370300200120012903800237039003200141003602800220014190036a411020014180026a100521020240024002402001280280022203417f460d002002450d00200120033602f402200120023602f00220014180026a200141f0026a1041200128028002220c450d0220014188026a280200210d200128028402210e2003450d01200210290c010b4108210c4100210d4100210e0b200141d0006a4194c1c500411410b5012001280254210f20012802502110200141c0006a41888dc300410d1094012001290348420020012802401b210a0240024002400240200d41286c2202450d00200c41206a290300200a580d010b4101211141002108410021120c010b20014180026a41186a2203200c41186a29030037030020014180026a41106a2204200c41106a29030037030020014180026a41086a2206200c41086a2903003703002001200c29030037038002412010272211450d012011200129038002370000201141186a2003290300370000201141106a2004290300370000201141086a20062903003700000240200c20026a200c41286a2202470d0041012108410121120c010b200d41286c41586a210641202104410121034101210803400240200241206a290300200a580d00200321120c020b200141f0026a41186a2207200241186a290300370300200141f0026a41106a2209200241106a290300370300200141f0026a41086a2205200241086a290300370300200120022903003703f0020240024020082003460d00200321120c010b200341016a22122003490d0a20034101742213201220122013491b221241ffffff3f712012470d0a201241057422134100480d0a0240024020030d002013102721110c010b201120034105742013102821110b20110d0020134101102a000b200241286a2102201120046a220320012903f002370000200341186a2007290300370000200341106a2009290300370000200341086a2005290300370000200441206a2104200841016a210820122103200641586a22060d000b0b02400240024002400240200f410020101b220f200d20086b22034d0d00200141306a4198c3c000411c1094012001290338210b2001290330211420014180026a41086a22024200370300200142003703800241e0c2c000411420014180026a100420014190036a41086a200229030037030020012001290380023703900320014100360288022001420137038002410810272202450d012001428880808080013702840220012002360280022002200b42002014a71b200a7c37000020024108411010282202450d0220014290808080c001370284022002200f20036b22103600082001200236028002200120083602f002200141f0026a20014180026a1030024002400240024020080d002001280288022103200128028402210720012802800221090c010b20084105742105410020012802880222036b2106200128028002210920012802840221072011210203400240200720066a411f4b0d00200341206a22042003490d1120074101742213200420042013491b22044100480d110240024020070d002004102721090c010b200920072004102821090b2009450d03200421070b200920036a22042002290000370000200441186a200241186a290000370000200441106a200241106a290000370000200441086a200241086a290000370000200641606a2106200341206a2103200241206a2102200541606a22050d000b2001200736028402200120033602880220012009360280020b20014190036a411020092003100302402007450d00200910290b02402012450d00201110290b200141a8036a4200370300200141a0036a420037030020014198036a42003703002001420037039003201041066a2212ad42307e220a422088a7450d010c100b20044101102a000b200aa72202417f4c0d0e0240024020020d0041082111410821020c010b200210272211450d04201121020b20014180026a41186a220920014190036a41186a29030037030020014180026a41106a220520014190036a41106a29030037030020014180026a41086a20014190036a41086a29030037030020012001290390033703800220124102490d04200f20086a200d6b41056a21030340200141f0026a41186a22042009290300370300200141f0026a41106a22062005290300370300200141f0026a41086a220720014180026a41086a29030037030020012001290380023703f0022002420037030820024200370300200241106a20012903f002370300200241186a2007290300370300200241206a2006290300370300200241286a2004290300370300200241306a21022003417f6a22030d000b201041056a21030c080b2012450d09201110290c090b41084101102a000b41104101102a000b20024108102a000b4100210320120d030c040b41204101102a000b418f89c3004133104e000b41f4c2c000200320061037000b20024200370308200242003703002002200129038002370310200241186a20014188026a290300370300200241206a20014190026a290300370300200241286a20014180026a41186a290300370300200341016a21030b200120033602f802200120123602f402200120113602f00220014180026a41086a22024200370300200142003703800241b4c3c000411320014180026a100420014190036a41086a20022903003703002001200129038002370390032001411036028402200120014190036a36028002200141f0026a20014180026a103402402012450d00201110290b200141083a00800220022010360200200141023a00840241b8d6c500410020014180026a1088010b200e450d00200c10290b20014180026a41086a22024200370300200142003703800241e0c2c000411420014180026a100420014190036a41086a2002290300370300200120012903800237039003200141003602800220014190036a411020014180026a100521022001280280022203417f460d012002450d01200120023602f002200120033602f402200142003703800220014180026a20022003410820034108491b220610ce041a2001200320066b22043602f4022001200220066a22063602f0020240024002400240024002400240200341074d0d002001200420044104200441044922031b22076b3602f4022001200620076a3602f00220030d00200129038002210a20014180026a200141f0026a102d2001280280022215450d00200128028402211620021029200a2000520d0520014180026a41086a22024200370300200142003703800241e0c2c000411420014180026a100420014190036a41086a2002290300370300200120012903800237039003200141003602800220014190036a411020014180026a10052102024002400240024002400240024002400240024002402001280280022203417f460d002002450d00200120023602d001200120033602d401200142003703800220014180026a20022003410820034108491b220610ce041a2001200320066b22043602d4012001200220066a22063602d00102400240200341074d0d00200141003602800220014180026a20062004410420044104491b220310ce041a2001200420036b3602d4012001200620036a3602d001200441034d0d00200128028002211720014180026a200141d0016a102d20012802800222180d010b418f89c3004133104e000b20012902840221192002102920014190036a4110100c20014180026a41086a22024200370300200142003703800241b4c3c000411320014180026a100420014190036a41086a2002290300370300200120012903800237039003200141003602800220014190036a411020014180026a10052102024002402001280280022203417f460d002002450d00200120033602f402200120023602f00220014180026a200141f0026a1047200128028002221a450d03200129028402211b02402003450d00200210290b20014190036a4110100c0c010b4200211b4108211a0b200141206a41888dc300410d1094012001290328211c2001280220211d200141106a4184c3c00041141094012001280210211e2001290318211f201a201b422088a7222041306c6a21030240024020170d004100210941002106410021040c010b2017417f6a2106410021040240201a2003460d000240201a202041306c6a220241506a2203290300200341086a2903008450450d00410121090c020b20014190036a41186a200241606a220241186a29000037030020014190036a41106a200241106a29000037030020014190036a41086a200241086a2900003703002001200229000037039003410121040b410021090b20014189026a20014190036a41086a29030037000020014191026a20014190036a41106a29030037000020014199026a20014190036a41186a290300370000200120043a0080022001200129039003370081024101210f20014180026a41017221020240024020040d00200141f0026a41186a200241186a290000370300200141f0026a41106a200241106a2900003703004100212141012122410021230c010b20024280809aa6eaafe301420010ad01200141f0026a41186a200241186a290000370300200141f0026a41106a200241106a290000370300200141f0026a41086a200241086a290000370300200120022900003703f002412010272222450d03202220012903f002370000202241186a200141f0026a41186a2211290300370000202241106a200141f0026a41106a2213290300370000202241086a200141f0026a41086a220c290300370000410020066b211220014180026a41017221024102210641202104410121234101212102400340201220236a4101460d01200941ff01710d01201a2003460d01200341506a2207290300200741086a29030084500d012011200341606a220341186a29000022003703002013200341106a290000220a370300200c200341086a290000220b3703002001200329000022143703f00220022014370000200241086a2203200b370000200241106a2209200a370000200241186a22052000370000200141013a00800220024280809aa6eaafe301420010ad0120014190036a41186a2005290000220037030020014190036a41106a2009290000220a37030020014190036a41086a2003290000220b3703002001200229000022143703900320014180026a41186a2209200037030020014180026a41106a2205200a37030020014180026a41086a2208200b3703002001201437038002024020232021470d00202341016a22032023490d162006200320032006491b222141ffffff3f712021470d16202141057422034100480d160240024020230d002003102721220c010b202220042003102821220b2022450d100b202220046a2203200129038002370000200341186a2009290300370000200341106a2005290300370000200341086a2008290300370000200641026a2106200441206a2104202341016a212341002109200721030c000b0b202220046a210f2023450d0020014180026a41086a21052022210c034020014190016a200c10b60102402001280290014101470d002001280298012104200141b0016a10b70120012802b0012110024020012802b8012202450d00200241216c2103201041016a21022004410876210841012004411f7174210d20044105764107712212417f73210e034002402002417f6a2d00004101470d0020014180026a41186a200241186a220629000037030020014180026a41106a200241106a22072900003703002005200241086a22092900003703002001200229000037038002200120083602a00220014190036a20014180026a10b8010240201220012802980322044f0d002004200e6a221120044f0d0a200128029003221320114102746a280200200d7121040240200128029403450d00201310290b2004450d0120014180026a200210b90102402001290380024201510d00411310272204450d0c2004410f6a41002800f9c340360000200441086a41002900f2c340370000200441002900eac34037000020044113413310282204450d0d200420022900003700132004412b6a2006290000370000200441236a20072900003700002004411b6a2009290000370000200141f0026a41186a22064200370300200141f0026a41106a22074200370300200141f0026a41086a22094200370300200142003703f00220044133200141f0026a1000200141d0016a41186a2006290300370300200141d0016a41106a2007290300370300200141d0016a41086a2009290300370300200120012903f0023703d001200141d0016a4120100c200410290c020b200141086a41a8c1c500411110b5012001200128020c41016a410120012802081b3602ac02411310272204450d0d2004410f6a41002800f9c340360000200441086a41002900f2c340370000200441002900eac34037000020044113413310282204450d0e200420022900003700132004412b6a2006290000370000200441236a20072900003700002004411b6a2009290000370000200141f0026a41186a22064200370300200141f0026a41106a22074200370300200141f0026a41086a22094200370300200142003703f00220044133200141f0026a1000200141d0016a41186a2006290300370300200141d0016a41106a2007290300370300200141d0016a41086a2009290300370300200120012903f0023703d00120014120360294032001200141d0016a36029003200520014190036a10b301200410290c010b200128029403450d0020012802900310290b200241216a21022003415f6a22030d000b0b20012802b401450d00201010290b200f200c41206a220c470d000b0b20014180026a41086a22024200370300200142003703800241d1c2c000410f20014180026a100420014190036a41086a2002290300370300200120012903800237039003200141003602800220014190036a411020014180026a10052102024002402001280280022203417f460d002002450d00200120033602f402200120023602f00220014180026a200141f0026a10412001280280022224450d0a20014188026a280200210920012802840221252003450d01200210290c010b4100212541082124410021090b20014101360280022019422088a72207450d0a4100212641002127024020072024200941286c6a220620246b41286e2202200220074b1b2202450d00200241057422034100480d13200310272204450d0a2001200436028002200221270b20242102200721042001280280022228210303400240200620026b41f8004b0d0020062002460d112024200941286c6a2108410121060240034020032002290000370000200341186a200241186a290000370000200341106a200241106a290000370000200341086a200241086a290000370000200420062205460d01200541016a2106200341206a21032008200241286a2202470d000b0b202620056a21260c110b20032002290000370000200341186a200241186a290000370000200341106a200241106a290000370000200341086a200241086a290000370000024020044101470d00202641017221260c110b20032002290028370020200341386a200241c0006a290000370000200341306a200241386a290000370000200341286a200241306a29000037000020044102460d0f20032002290050370040200341d8006a200241e8006a290000370000200341d0006a200241e0006a290000370000200341c8006a200241d8006a29000037000020044103460d0e20032002290078370060200341f8006a20024190016a290000370000200341f0006a20024188016a290000370000200341e8006a20024180016a290000370000202641046a212620034180016a2103200241a0016a21022004417c6a22040d000c100b0b02402016450d00201510290b41fdc3c000410f1010418cc4c000413510100c120b418f89c3004133104e000b41204101102a000b41f4c2c000201120041037000b41134101102a000b41334101102a000b41134101102a000b41334101102a000b418f89c3004133104e000b20034101102a000b410021272001280280022128410021260c040b418f89c3004133104e000b20034101102a000b202641037221260c010b202641027221260b201f4200201e1b201c4200201d1b7c21142024200941286c6a21100240024002400240024002400240024002402007450d0020102024460d01200741016a2103200941286c2104202421020340200141f0026a41186a200241186a290300370300200141f0026a41106a200241106a290300370300200141f0026a41086a200241086a290300370300200120022903003703f0022003417f6a2203450d04200241286a2102200441586a22040d000b201021020c020b20102024470d040b202421020b2022200f460d01202241086a2900002100202241106a290000210a2022290000210b20014190036a41186a202241186a29000037030020014190036a41106a200a37030020014190036a41086a20003703002001200b37039003202241206a210441022106201421000c040b200241206a290300210020014180026a41186a200141f0026a41186a29030037030020014180026a41106a200141f0026a41106a29030037030020014180026a41086a200141f0026a41086a290300370300200120012903f00237038002200241286a21020c020b200141003602880120014208370380012025450d03202410290c030b20014180026a41186a202441186a29030037030020014180026a41106a202441106a29030037030020014180026a41086a202441086a2903003703002001202429030037038002202441286a2102202429032021000b20014190036a41186a20014180026a41186a29030037030020014190036a41106a20014180026a41106a29030037030020014190036a41086a20014180026a41086a29030037030020012001290380023703900341002106202221040b417f417f201020026b41286d2203200f20046b4105766a220720072003491b220341016a220720072003491b220ead42287e220a422088a70d05200aa72203417f4c0d050240024002400240024002400240024020030d00410821124108211e0c010b200310272212450d012012211e0b2012200129039003370300201241186a20014190036a41186a290300370300201241106a20014190036a41106a290300370300201241086a20014190036a41086a290300370300201e200037032002402006450d0002402004200f470d00410121290c050b200441086a2900002100200441106a290000210a2004290000210b20014190036a41186a200441186a29000037030020014190036a41106a200a37030020014190036a41086a20003703002001200b37039003200441206a21040c020b024020022010470d0002402004200f460d00200441086a2900002100200441106a290000210a2004290000210b20014190036a41186a200441186a29000037030020014190036a41106a200a37030020014190036a41086a20003703002001200b37039003200441206a21040c030b410121290c040b20014180026a41186a200241186a220329030037030020014180026a41106a200241106a220629030037030020014180026a41086a200241086a2207290300370300200120022903003703800220014190036a41086a200729030037030020014190036a41106a200629030037030020014190036a41186a200329030037030020012002290300370390032002290320210041002111200241286a21020c020b20034108102a000b41022111201421000b410221074102210341282106034020014180026a41186a220920014190036a41186a221329030037030020014180026a41106a220520014190036a41106a220c29030037030020014180026a41086a220820014190036a41086a220d290300370300200120012903900337038002024020032229417f6a2203200e470d002003417f417f201020026b41286d220e200f20046b4105766a221d201d200e491b220e41016a221d201d200e491b6a220e2003490d082007200e200e2007491b220ead42287e220a422088a70d08200aa722034100480d080240024020294101470d002003102721120c010b201220062003102821120b2012450d032012211e0b201e20066a2203200129038002370300200341186a2009290300370300200341106a2005290300370300200341086a2008290300370300200341206a20003703000240024002400240201141ff01710e03010200010b2004200f460d04200441086a2900002100200441106a290000210a2004290000210b2013200441186a290000370300200c200a370300200d20003703002001200b37039003200441206a21044201210a41022111201421000c020b024020102002470d004102211102402004200f470d004200210a0c030b200441086a2900002100200441106a290000210a2004290000210b2013200441186a290000370300200c200a370300200d20003703002001200b37039003200441206a21044201210a201421000c020b2009200241186a22032903003703002005200241106a22092903003703002008200241086a22052903003703002001200229030037038002200529030021002009290300210a2002290300210b20132003290300370300200c200a370300200d20003703002001200b37039003200229032021004201210a41002111200241286a21020c010b20102002460d022013200241186a290300370300200c200241106a290300370300200d200241086a2903003703002001200229030037039003200229032021004201210a41012111200241286a21020b200741026a2107202941016a2103200641286a2106200a4200520d000b0b02402025450d00202410290b2001200e360284012001201e36028001200120293602880120294115490d012029410176222aad42287e2200422088a70d072000a72202417f4c0d0702400240024020020d004108212b410821050c010b20021027222b450d01202b21050b201e41586a212c201e41a87f6a212d4104210c4100212e410021092029211d0340201d21064100211d4101210702402006417f6a222f450d00024002400240024002400240201e202f41286c6a41206a290300200641286c2202201e6a41506a2903002200540d002006417e6a2107202d20026a21034100211d410021020340024020072002470d00200621070c080b200241016a210220002003290300220a5a2104200341586a2103200a210020040d000b200241016a21072002417f7320066a21040c010b202d200641056c41037422126a2102202f210402400340024020044101470d00410021040c020b2004417f6a210420002002290300220a542103200241586a2102200a210020030d000b0b20062004490d01200620294b0d03200620046b22074101762208450d00202c20126a2102201e200441286c6a2103034020014180026a41206a2212200341206a221129030037030020014180026a41186a2213200341186a220d29030037030020014180026a41106a220e200341106a220f29030037030020014180026a41086a2210200341086a221d2903003703002001200329030037038002200241206a22242903002100200241186a2225290300210a200241106a2230290300210b200241086a2231290300211420032002290300370300201d2014370300200f200b370300200d200a3703002011200037030020242012290300370300202520132903003703002030200e290300370300203120102903003703002002200129038002370300200241586a2102200341286a21032008417f6a22080d000b0b024020040d002004211d0c050b0240200741094d0d002004211d0c050b200620294b0d01201e200441286c6a2112034020062004417f6a221d490d0402402006201d6b22074102490d00201e200441286c6a220241206a2203290300201e201d41286c6a221141206a220829030022005a0d00200141f0026a41186a2213201141186a220d290300370300200141f0026a41106a220e201141106a220f290300370300200141f0026a41086a2210201141086a2224290300370300200120112903003703f002201120022903003703002024200241086a290300370300200f200241106a290300370300200d200241186a29030037030020082003290300370300024020074103490d00202f210320122108201141f0006a29030020005a0d00024003402008220241206a200241c8006a290300370300200241186a200241c0006a290300370300200241106a200241386a290300370300200241086a200241306a2903003703002002200241286a220829030037030020042003417f6a2203460d01200241f0006a2903002000540d000b0b200241286a21020b200220012903f00237030020022000370320200241186a2013290300370300200241106a200e290300370300200241086a20102903003703000b201d450d05201241586a2112201d21042007410a4f0d050c000b0b20042006103e000b20062004417f6a221d490d010b20062029107f000b201d2006103e000b024002400240202e2009470d00202e41016a2202202e490d0a202e4101742203200220022003491b220241ffffffff01712002470d0a200241037422034100480d0a02400240202e0d0020031027210c0c010b200c202e41037420031028210c0b200c450d012002212e0b200c20094103746a220220073602042002201d360200200941016a220d2109200d4102490d0103400240024002400240200c200d2211417f6a220d4103746a2202280200450d002011410374200c6a220741746a2802002206200228020422034d0d0041022109201141024d0d06200c2011417d6a22024103746a2802042204200320066a4d0d0141032109201141034d0d06200741646a280200200420066a4d0d01201121090c060b20114103490d0120022802042103200c2011417d6a22024103746a28020421040b20042003490d010b2011417e6a21020b0240024002400240024002402011200241016a22244d0d00201120024d0d01200c20024103746a220e2802042225200e2802006a2202200c20244103746a220f2802002210490d02200220294b0d03200e41046a2130201e201041286c6a2212200f280204221341286c22036a2107200241286c2104200220106b220920136b220220134f0d04202b2007200241286c220310ce041a200520036a21060240024020134101480d00200241014e0d010b20072102200521030c060b202c20046a21042007210203402004200241586a2209200641586a2208200641786a290300200241786a2903005422071b2203290300370300200441206a200341206a290300370300200441186a200341186a290300370300200441106a200341106a290300370300200441086a200341086a2903003703002006200820071b2106024020122009200220071b2202490d00200521030c070b200441586a21042005210320052006490d000c060b0b41d8e3c100202420111037000b41d8e3c100200220111037000b20102002103e000b20022029107f000b202b2012200310ce041a200520036a21060240024020134101480d00200920134a0d010b20122102200521030c010b201e20046a210820052103201221020340200220072003200741206a290300200341206a2903005422091b2204290300370300200241206a200441206a290300370300200241186a200441186a290300370300200241106a200441106a290300370300200241086a200441086a2903003703002003200341286a20091b2103200241286a2102200741286a200720091b220720084f0d01200620034b0d000b0b20022003200620036b220420044128706b10ce041a2030202520136a360200200e2010360200200f200f41086a2024417f7320116a41037410cf041a200d2109200d41014d0d020c000b0b20034104102a000b201d0d000b0240202e450d00200c10290b202a450d03202b10290c030b20024108102a000b20034108102a000b20294102490d002029417f6a2104201e202941286c6a2107410021090340024002400240202920042202417f6a2204490d00202920046b22034102490d02201e200241286c6a220241206a2206290300201e200441286c6a220541206a220829030022005a0d02200141f0026a41186a2212200541186a2211290300370300200141f0026a41106a2213200541106a220c290300370300200141f0026a41086a220d200541086a220e290300370300200120052903003703f00220052002290300370300200e200241086a290300370300200c200241106a2903003703002011200241186a2903003703002008200629030037030020034103490d012009210620072103200541f0006a29030020005a0d0103402003220241586a22032002290300370300200341206a200241206a290300370300200341186a200241186a290300370300200341106a200241106a290300370300200341086a200241086a2903003703002006417f6a2206450d02200241286a2103200241c8006a29030020005a0d020c000b0b20042029103e000b200220012903f00237030020022000370320200241186a2012290300370300200241106a2013290300370300200241086a200d2903003703000b200941016a2109200741586a210720040d000b0b20014180026a41086a22024200370300200142003703800241d1c2c000410f20014180026a100420014190036a41086a20022903003703002001200129038002370390032001411036028402200120014190036a3602800220014180016a20014180026a102f410021042001280284012109200128028001210702400240200128028801220241286c22030d004101210e4100210f0c010b200341286d220f41ffffff3f71200f470d03200f41057422034100480d0320031027220e0d0020034101102a000b02402002450d00200241286c210641002104200e2102200721030340200341086a2900002100200341106a290000210a2003290000210b200241186a200341186a290000370000200241106a200a370000200241086a20003700002002200b370000200441016a2104200241206a2102200341286a2103200641586a22060d000b0b02402009450d00200710290b20282026200e200410ba0120014180026a41086a22024200370300200142003703800241d8c3c000411220014180026a100420014190036a41086a2002290300370300200120012903800237039003200141003602800220014190036a411020014180026a1005210202400240024002400240024002402001280280022203417f460d002002450d00200120033602f402200120023602f00220014180026a200141f0026a102d200128028002221d450d0220014188026a280200211320012802840221242003450d01200210290c010b410021244101211d410021130b200141e8016a4200370300200141e0016a4200370300200141d8016a4200370300200142003703d001201341ffffff3f712013470d0920134105742202417f4c0d090240024020020d00410121120c010b200210272212450d020b20014180026a41186a2204200141d0016a41186a29030037030020014180026a41106a2206200141d0016a41106a29030037030020014180026a41086a2207200141d0016a41086a290300370300200120012903d0013703800220134102490d022013417f6a21032012210203402002200129038002370000200241186a2004290300370000200241106a2006290300370000200241086a2007290300370000200241206a21022003417f6a22030d000b2013417f6a21110c030b418f89c3004133104e000b20024101102a000b41002111201221022013450d010b2002200129038002370000200241186a20014180026a41186a290300370000200241106a20014180026a41106a290300370000200241086a20014180026a41086a290300370000201141016a21110b201a202041306c6a2102201ba7210d410021100240024002400240024002400240034002402017450d002002201a460d02200241506a2202290300200241086a29030084500d0203402017417f6a2217450d01201a2002460d03200241506a2103200241506a21022003290300200341086a2903008450450d000c030b0b2002201a460d0102400340200241506a22042903002100200441086a290300210a20014190036a41186a2206200241606a220341186a29030037030020014190036a41106a2207200341106a29030037030020014190036a41086a2209200341086a29030037030020012003290300370390032000200a84500d0120014180026a41186a2203200629030037030020014180026a41106a2205200729030037030020014180026a41086a22082009290300370300200120012903900337038002200141f0016a20014180026a10b601200141d0016a41186a220c2006290300370300200141d0016a41106a22062007290300370300200141d0016a41086a2207200929030037030020012001290390033703d001024020012802f0014101460d0020042102201a2004470d010c040b0b20014190016a41086a2209200729030037030020014190016a41106a2207200629030037030020014190016a41186a2206200c290300370300200120012903d00122003703b001200120003703900120012802f8012104200320062903003703002005200729030037030020082009290300370300200120012903900137038002201120044d0d03200241506a2102201220044105746a2204200129038002370000200441186a2003290300370000200441106a2005290300370000200441086a2008290300370000201041016a2110410021170c010b0b200141b0016a41086a200141f0026a41086a290300370300200141b0016a41106a200141f0026a41106a290300370300200141b0016a41186a200141f0026a41186a290300370300200120012903f0023703b0010b0240200d450d00201a10290b02402011201341ffffff3f712202200220114b1b2207450d00201d210220122103410021060340024020022003460d0020022003412010d004450d00411610272204450d042004410e6a41002900c9c240370000200441086a41002900c3c240370000200441002900bbc24037000020044116413610282204450d05200420022900003700162004412e6a200241186a290000370000200441266a200241106a2900003700002004411e6a200241086a290000370000200141f0026a41186a22094200370300200141f0026a41106a22054200370300200141f0026a41086a22084200370300200142003703f00220044136200141f0026a1000200141d0016a41186a2009290300370300200141d0016a41106a2005290300370300200141d0016a41086a2008290300370300200120012903f0023703d001200141d0016a4120100c200410290b200241206a2102200341206a2103200641016a22062007490d000b0b201220114105746a21022011210920114104490d0320014180026a41206a2105200141c0026a210820014180026a41e0006a210c20014180036a210d20014198026a210420014190026a210620014188026a2107200221032011210903402004420037030020064200370300200742003703002001420037038002024020052003460d00200341606a20014180026a412010d004450d002009417f6a21030c060b2004420037030020064200370300200742003703002001420037038002024020082003460d00200341406a20014180026a412010d004450d002009417e6a21030c060b20044200370300200642003703002007420037030020014200370380020240200c2003460d00200341a07f6a20014180026a412010d004450d002009417d6a21030c060b2004420037030020064200370300200742003703002001420037038002200341807f6a210202400240200d2003460d00200220014180026a412010d0040d010b2009417c6a210920022103200220126b41e0004b0d010c050b0b2009417c6a21030c040b41c8c3c000200420111037000b41164101102a000b41364101102a000b20022012460d012009417f6a210320014180026a41206a210420014198026a210620014190026a210720014188026a210903402006420037030020074200370300200942003703002001420037038002024020042002460d00200241606a20014180026a412010d0040d020b2003417f6a21032012200241606a2202470d000c020b0b200341016a22022011201120024b1b21110b2001419c026a202636020020014180026a41186a202736020020014194026a202836020020014180026a41106a20233602002001418c026a2021360200200141083a00800220014180026a41086a22022022360200200141033a00840241b8d6c500410020014180026a10880120024200370300200142003703800241d8c3c000411220014180026a100420014190036a41086a200229030037030020012001290380023703900320014100360288022001420137038002200120113602f002200141f0026a20014180026a10300240024020110d002001280288022103200128028402210720012802800221090c010b20114105742105410020012802880222036b2106200128028002210920012802840221072012210203400240200720066a411f4b0d00200341206a22042003490d0520074101742208200420042008491b22044100480d050240024020070d002004102721090c010b200920072004102821090b2009450d04200421070b200920036a22042002290000370000200441186a200241186a290000370000200441106a200241106a290000370000200441086a200241086a290000370000200641606a2106200341206a2103200241206a2102200541606a22050d000b2001200736028402200120033602880220012009360280020b20014190036a411020092003100302402007450d00200910290b02402013450d00201210290b20014180026a41086a22024200370300200142003703800241dfc1c500411620014180026a100420014190036a41086a22032002290300370300200120012903800237039003200120103602800220014190036a411020014180026a41041003200141a8c1c500411110b501200128020021042001280204210620024200370300200142003703800241a8c1c500411120014180026a1004200320022903003703002001200129038002370390032001200641016a410120041b3602800220014190036a411020014180026a4104100302402024450d00201d10290b0240200f450d00200e10290b2019a7450d00201810290b2016450d02201510290c020b20044101102a000b102b000b200141b0036a24000f0b1039000bc60101027f230041206b22032400200341106a41086a220442003703002003420037031020012002200341106a1004200341086a200429030037030020032003290310370300410021022003410036021020034110200341106a1005210402400240024020032802102201417f470d000c010b20034100360210200341106a20042001410420014104491b10ce041a200141034d0d012003280210210120041029410121020b2000200136020420002002360200200341206a24000f0b418f89c3004133104e000bdb0201047f230041c0006b2202240002400240411610272203450d002003410e6a41002900c9c240370000200341086a41002900c3c240370000200341002900bbc24037000020034116413610282203450d01200320012900003700162003412e6a200141186a290000370000200341266a200141106a2900003700002003411e6a200141086a290000370000200241206a41186a22014200370300200241206a41106a22044200370300200241206a41086a220542003703002002420037032020034136200241206a1000200241186a2001290300370300200241106a2004290300370300200241086a200529030037030020022002290320370300200241206a2002412010bb010240024020022802204101460d00200041003602000c010b20002002290320370200200041086a200241206a41086a2802003602000b20031029200241c0006a24000f0b41164101102a000b41364101102a000bed02030a7f017e017f230041206b220124002001410010bc01200141106a410110bc0102400240024020012802182202450d004102210320012802042104200128020821050340200128021421062001280210210702400240200420056b200241216c220841216d2209490d00200520096a2109200128020021020c010b200520096a22092005490d0420044101742202200920092002491b220aad42217e220b422088a70d04200ba7220c4100480d040240024020040d00200c102721020c010b2001280200200441216c200c102821020b2002450d0320012002360200200a21040b2002200541216c6a2007200810ce041a02402006450d00200710290b200141106a200310bc01200341016a210320092105200128021822020d000b20012004360204200120093602080b02402001280214450d00200128021010290b20002001290300370200200041086a200141086a280200360200200141206a24000f0b200c4101102a000b102b000bd60302047f017e230041d0006b220224000240024002400240411310272203450d002003410f6a41002800d0c440360000200341086a41002900c9c440370000200341002900c1c44037000020034113413310282203450d01200320012900003700132003412b6a200141186a290000370000200341236a200141106a2900003700002003411b6a200141086a290000370000200128022021042003413341e60010282201450d0220012004360033200241306a41186a22034200370300200241306a41106a22044200370300200241306a41086a220542003703002002420037033020014137200241306a1000200241086a41186a2003290300370300200241086a41106a2004290300370300200241086a41086a20052903003703002002200229033037030820024100360230200241086a4120200241306a100521040240024020022802302203417f460d002002200336022c20022004360228200241306a200241286a104520022802302205450d052002290234210602402003450d00200410290b20002006370204200020053602000c010b20004100360208200042043702000b20011029200241d0006a24000f0b41134101102a000b41334101102a000b41e6004101102a000b418f89c3004133104e000b8f0502087f047e230041c0006b2202240002400240411310272203450d002003410f6a41002800f9c340360000200341086a41002900f2c340370000200341002900eac34037000020034113413310282203450d01200320012900003700132003412b6a200141186a290000370000200341236a200141106a2900003700002003411b6a200141086a290000370000200241206a41186a22014200370300200241206a41106a22044200370300200241206a41086a220542003703002002420037032020034133200241206a1000200241186a2001290300370300200241106a2004290300370300200241086a2005290300370300200220022903203703002002410036022020024120200241206a1005210102400240024020022802202204417f460d002001450d0020024100360220200241206a20012004410420044104491b220510ce041a0240200441034d0d002002280220210620024100360220200241206a200120056a2207200420056b2204410420044104491b220510ce041a200441034d0d00200228022021082002420037032820024200370320200241206a200720056a2207200420056b2204411020044110491b220510ce041a2004410f4d0d00200241286a2209290300210a2002290320210b2002420037032820024200370320200241206a200720056a200420056b2204411020044110491b10ce041a2004410f4b0d020b418f89c3004133104e000b4200210a0c010b2009290300210c2002290320210d20011029200041206a200c370300200041186a200d370300200041106a200a3703002000200b3703082000412c6a2008360200200041286a20063602004201210a0b2000200a37030020031029200241c0006a24000f0b41134101102a000b41334101102a000b9411030e7f077e017f230022042105200441c0016b4160712204240002400240024002400240024002400240200141ffffff3f712001470d0020014105742206417f4c0d000240024020060d00410121070c010b200610272207450d020b410021084100210602402001450d0020014105742109416020006b210a2007210620002108034020062008290000370000200641186a200841186a290000370000200641106a200841106a290000370000200641086a200841086a290000370000200641206a2106200841206a2108200941606a22090d000b200020014105746a200a6a41057641016a2106200121080b20042006360218200420083602142004200736021020072006410041202006676b10e00120044180016a41086a220642003703002004420037038001419acec200411d20044180016a1004200441a0016a41086a200629030037030020042004290380013703a0012004410036028001200441a0016a411020044180016a10052108024002402004280280012206417f460d00200420063602442004200836024020044180016a200441c0006a102d200428028001220b450d0420044188016a2802002109200428028401210c2006450d01200810290c010b4101210b410021094100210c0b2009410574220a450d07200441a0016a411472210d200441a0016a410872210e200b21080340200441206a41186a220f200841186a290000370300200441206a41106a2210200841106a290000370300200441206a41086a2211200841086a29000037030020042008290000370320200441c0006a200441206a10f202200441003602a80120042903582112200420042903b801221337035820042903502114200420042903b001221537035020042903402116200420042903a00137034020042903482117200420042903a80122183703482015422088a721002018422088a721012013a721072018a7210902402017a72206450d00200420163703a001200420173703a801200420143703b001200420123703b801200420062014a74105746a36028c01200420063602880120042017422088a73602840120042006360280012004200441106a36029001200441f0006a20044180016a104b200e41086a200441f0006a41086a2219280200360200200e200429037037020020042014422088a722062012422088a74105746a36028c01200420063602880120042012a73602840120042006360280012004200441106a36029001200441f0006a20044180016a104b200d41086a2019280200360200200d200429037037020020042903a801211720042903a001211420042903b801211820042903b001211202402009450d0002402001450d00200910290b2007450d00200010290b20042014370340200420173703482017422088a72101200420123703502012422088a72100200420183703582017a721092018a721070b411a102721060240024020090d002006450d06200641186a41002f00cfce423b0000200641106a41002900c7ce42370000200641086a41002900bfce42370000200641002900b7ce423700002006411a413a10282206450d072006200429032037001a200641326a200f2903003700002006412a6a2010290300370000200641226a2011290300370000200441a0016a41186a22094200370300200441a0016a41106a22014200370300200441a0016a41086a22074200370300200442003703a0012006413a200441a0016a100020044180016a41186a200929030037030020044180016a41106a200129030037030020044180016a41086a2007290300370300200420042903a0013703800120044180016a4120100c200610290c010b2006450d07200641186a41002f00cfce423b0000200641106a41002900c7ce42370000200641086a41002900bfce42370000200641002900b7ce423700002006411a413a10282206450d082006200429032037001a200641326a200f2903003700002006412a6a2010290300370000200641226a2011290300370000200441a0016a41186a220f4200370300200441a0016a41106a22104200370300200441a0016a41086a22114200370300200442003703a0012006413a200441a0016a100020044180016a41186a200f29030037030020044180016a41106a201029030037030020044180016a41086a2011290300370300200420042903a00137038001200441203602a401200420044180016a3602a001200441c0006a200441a0016a10db022006102902402001450d00200910290b2007450d00200010290b200841206a2108200a41606a220a0d000c080b0b1039000b20064101102a000b418f89c3004133104e000b411a4101102a000b413a4101102a000b411a4101102a000b413a4101102a000b0240200c450d00200b10290b200441003602a801200442013703a001200420033602800120044180016a200441a0016a1030024002400240024020030d0020042802a801210620042802a401210120042802a00121070c010b20034105742100410020042802a80122066b210920042802a001210720042802a401210103400240200120096a411f4b0d00200641206a22082006490d042001410174220a20082008200a491b22084100480d040240024020010d002008102721070c010b200720012008102821070b2007450d03200821010b200720066a22082002290000370000200841186a200241186a290000370000200841106a200241106a290000370000200841086a200241086a290000370000200941606a2109200641206a2106200241206a2102200041606a22000d000b200420013602a401200420063602a801200420073602a0010b20044180016a41086a22024200370300200442003703800141d692c200411b20044180016a1004200441a0016a41086a200229030037030020042004290380013703a001200441a0016a411020072006100302402001450d00200710290b02402004280214450d00200428021010290b200524000f0b20084101102a000b102b000bcb0101037f230041106b22032400410021042003410036020c200120022003410c6a1005210102400240200328020c2202417f460d002001450d0020034100360204200341046a200120024104200241044922051b220410ce041a20050d012003280204210520034100360208200341086a200120046a200220046b2204410420044104491b10ce041a200441034d0d012003280208210420011029200041086a200436020020002005360204410121040b20002004360200200341106a24000f0b418f89c3004133104e000b830802117f017e23004190016b22022400024002400240024002400240410e10272203450d00200341066a41002900dac440370000200341002900d4c4403700002003410e411c10282204450d012004200136000e200241306a41186a22034200370300200241306a41106a22014200370300200241306a41086a220542003703002002420037033020044112200241306a1000200241086a41186a2003290300370300200241086a41106a2001290300370300200241086a41086a20052903003703002002200229033037030820024100360270200241086a4120200241f0006a100521060240024020022802702207417f460d002002200736022c200220063602282002200241286a102e2002280200450d07024002402002280204220841fc00200841fc00491b22090d004101210a0c010b200941216c22031027220a450d050b02402008450d0020022802282105200228022c21034100210b4100210c4100210d0340200241003a0030200241306a20052003410047220110ce041a20032001490d072002200320016b220e36022c2002200520016a22053602280240024002402003450d0020022d0030220141014b0d004100210f200e21030240024020010e020100010b200241306a200e4120200e4120491b22016a41004100412020016b2001411f4b1b10cd041a200241306a2005200110ce041a2002200e20016b220336022c2002200520016a2205360228200e411f4d0d01200241f0006a41186a200241306a41186a290300370300200241f0006a41106a200241306a41106a290300370300200241f0006a41086a200241306a41086a290300370300200220022903303703704101210f0b200d41016a210e200241d0006a41186a2210200241f0006a41186a290300370300200241d0006a41106a2211200241f0006a41106a290300370300200241d0006a41086a2212200241f0006a41086a29030037030020022002290370370350200d2009470d020240200b200e200e200b491b2209ad42217e2213422088a70d002013a7220141004e0d020b102b000b2009450d0b200a10290c0b0b02400240200d0d0020011027210a0c010b200a200c20011028210a0b200a450d090b200a200c6a2201200f3a0000200141016a2002290350370000200141096a2012290300370000200141116a2011290300370000200141196a2010290300370000200b41026a210b200c41216a210c200e210d2008200e470d000b0b200a450d072008ad4220862009ad84211302402007450d00200610290b200020133702042000200a3602000c010b20004100360208200042013702000b2004102920024190016a24000f0b410e4101102a000b411c4101102a000b20034101102a000b20012003103e000b20014101102a000b418f89c3004133104e000b13002000410a360204200041b8c5c0003602000b340020004187f4c10036020420004100360200200041146a4110360200200041106a41d4ebc000360200200041086a42073702000b3001017f02404104102722020d0041044101102a000b20004284808080c00037020420002002360200200241003600000b13002000410a360204200041a487c1003602000b3101017f02404104102722020d0041044101102a000b20004284808080c00037020420002002360200200241c0003600000b3201017f02404108102722020d0041084101102a000b2000428880808080013702042000200236020020024280e1013700000b3001017f02404104102722020d0041044101102a000b20004284808080c00037020420002002360200200241013600000b3001017f02404104102722020d0041044101102a000b20004284808080c00037020420002002360200200241063600000b3d01017f02404110102722020d0041104101102a000b200242003700082002428080d287e2bc2d370000200042908080808002370204200020023602000b3d01017f02404110102722020d0041104101102a000b200242003700082002428080e983b1de16370000200042908080808002370204200020023602000b3e01017f02404110102722020d0041104101102a000b2002420037000820024280809aa6eaafe301370000200042908080808002370204200020023602000bf10901047f230041206b220224000240024002400240024002400240024002400240024002400240024002402001280200417f6a220341094b0d0020030e0a0102030405060708090a010b419498c1001058000b2001410c6a2802002203417f4c0d0a200128020421044101210502402003450d00200310272205450d0c0b20052004200310ce0421052000410c6a2003360200200041086a20033602002000200536020420004101360200200041106a20012902103703000c090b2001410c6a2802002203417f4c0d09200128020421050240024020030d00410121040c010b200310272204450d0c0b20042005200310ce0421052000410c6a2003360200200041086a20033602002000200536020420004102360200200041106a20012902103703000c080b200128020421054101210302400240200141086a22042d00004101460d002002411e6a200441036a2d00003a0000200241086a200141186a290200370300200241106a200141206a290200370300200241186a200141286a2d00003a0000200220042f00013b011c2002200141106a2902003703002001410c6a2802002104410021030c010b2001410c6a28020021040b20002005360204200020022f011c3b0009200041086a20033a00002000410c6a2004360200200041106a20022903003702002000412c6a200129022c3702002000410b6a2002411e6a2d00003a0000200041186a200241086a290300370200200041206a200241106a290300370200200041286a200241186a280200360200200041033602000c070b20004104360200200020012802043602040c060b20004105360200200020012802043602040c050b410121030240024020012d00044101460d002002411e6a200141046a220341036a2d00003a0000200241086a200141146a290200370300200241106a2001411c6a290200370300200241186a200141246a2d00003a0000200220032f00013b011c20022001410c6a290200370300200141086a2802002105410021030c010b200141086a28020021050b200020033a0004200020022f011c3b0005200041306a2001290330370300200041086a20053602002000410c6a2002290300370200200041386a200141386a290300370300200041076a2002411e6a2d00003a0000200041146a200241086a2903003702002000411c6a200241106a290300370200200041246a200241186a2802003602002001280228210120004106360200200041286a20013602000c040b20004107360200200020012802043602040c030b410121030240024020012d00044101460d002002411e6a200141046a220341036a2d00003a0000200241086a200141146a290200370300200241106a2001411c6a290200370300200241186a200141246a2d00003a0000200220032f00013b011c20022001410c6a290200370300200141086a2802002101410021030c010b200141086a28020021010b200020033a0004200020022f011c3b000520004108360200200041086a20013602002000410c6a2002290300370200200041076a2002411e6a2d00003a0000200041146a200241086a2903003702002000411c6a200241106a290300370200200041246a200241186a2802003602000c020b20004109360200200041086a200141086a2903003703000c010b2000410a360200200041086a200141086a2903003703000b200241206a24000f0b1039000b20034101102a000b20034101102a000bd8a60104197f037e0b7f0a7e230041d0046b22032400024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024020012802000e0b000102030405060708090a000b200341fc026a4101360200200342013702ec02200341ccfdc4003602e802200341023602ac04200341c4fdc4003602a8042003200341a8046a3602f802200341e8026a41f098c1001057000b200141086a2802002104200128020421050240024020022d00000d004101210620022d00014101460d010b41d588c3002107412a210841002109410121062004450d32200510290c320b200241196a2d00002107200241186a2d00002108200241166a2f01002109200241156a2d0000210a200241146a2d0000210b200241126a2f0100210c200241116a2d0000210d200241106a2d0000210e2002410e6a2f0100210f2002410d6a2d000021102002410c6a2d000021112002410a6a2f01002112200241096a2d00002113200241086a2d00002114200241066a2f01002115200241056a2d00002116200241046a2d00002117200241026a2f010021182001410c6a2802002119200141146a280200211a200141106a280200211b20032002411a6a29010037038003200320073a00ff02200320083a00fe02200320093b01fc022003200a3a00fb022003200b3a00fa022003200c3b01f8022003200d3a00f7022003200e3a00f6022003200f3b01f402200320103a00f302200320173a00ea02200320183b01e802200320132012410874201141187472723600ef02200320162015410874722014411874723600eb02200320193602b004200320043602ac04200320053602a804200341086a200341e8026a200341a8046a201b201a10cb01200328020c210820032802082107410021090c310b200141086a28020021042001280204210541d588c3002107412a210820022d00000d2f20022d00014101470d2f2002411a6a290100211c200241196a2d00002107200241186a2d00002108200241166a2f01002106200241156a2d00002109200241146a2d0000210a200241126a2f0100210b200241116a2d0000210c200241106a2d0000210d2002410e6a2f0100210e2002410d6a2d0000210f2002410c6a2d000021102002410a6a2f01002111200241096a2d00002112200241086a2d00002113200241066a2f01002114200241056a2d00002115200241046a2d00002116200241026a2f010021172001410c6a2802002118200141146a2802002119200141106a280200211a410d10272202450d08200241056a410029008599413700002002410029008099413700002002410d412d10282202450d092002201c370025200220073a0024200220083a0023200220063b0021200220093a00202002200a3a001f2002200b3b001d2002200c3a001c2002200d3a001b2002200e3b00192002200f3a00182002201141087420104118747220127236001420022014410874201572201341187472360010200220163a000f200220173b000d200341e8026a41186a22074200370300200341e8026a41106a22084200370300200341e8026a41086a22064200370300200342003703e8022002412d200341e8026a1000200341a8046a41186a2007290300370300200341a8046a41106a2008290300370300200341a8046a41086a2006290300370300200320032903e8023703a804200341003602e802200341a8046a4120200341e8026a100521090240024020032802e8022207417f460d0041002106200341e8026a2007412020074120491b22086a41004100412020086b2008411f4b1b10cd041a200341e8026a2009200810ce041a2007411f4b0d01418f89c3004133104e000b2002102941959bc4002107410b21080c300b20032f01e802210720032d00ea02210820032900eb02211c20032d00f302210a20032902f402211d20032802fc02210b200329038003211e20091029200210292003201e370380032003200b3602fc022003201d3702f4022003200a3a00f3022003201c3700eb02200320083a00ea02200320073b01e802200320183602b004200320043602ac04200320053602a804200341106a200341e8026a200341a8046a201a201910cb012003280214210820032802102107410121090c300b200141216a290000211c200141206a2d0000210a2001411d6a2f0000210b2001411c6a2d0000210c200141196a2f0000210d200141186a2d0000210e200141156a2f0000210f200141146a2d00002110200141106a28020021112001410c6a2802002105200141086a2d00002117200141306a280200211f2001412c6a280200212020012d001f211220012d001b211320012d0017211420012d000b211520012f00092116200128020421212002411a6a290100211d200241196a2d00002118200241186a2d00002119200241166a2f0100211a200241156a2d0000211b200241146a2d00002122200241126a2f01002123200241116a2d00002124200241106a2d000021252002410e6a2f010021262002410d6a2d00002127200241046a2d00002128200241026a2f01002129412a210441d588c30021070240024020022d0000450d004101210641002108410021090c010b41012106410021084100210920022d00014101470d002002410c6a2d000021082002410a6a2f01002109200241096a2d00002104200241066a2f0100410874200241056a2d000072200241086a2d0000411874722107410021060b200941ffff0371410874200841187472200441ff017172210820060d2d2003201d3703d002200320183a00cf02200320193a00ce022003201a3b01cc022003201b3a00cb02200320223a00ca02200320233b01c802200320243a00c702200320253a00c602200320263b01c402200320273a00c302200320083600bf02200320073600bb02200320283a00ba02200320293b01b8020240201741ff01714101470d00200341e8026a200541067610cc0120032802e80221070240024020032802f0022005413f7122024b0d00410021020c010b200720024105746a2202290018211c20022d0017210a20022d0016211220022f0014210b20022d0013210c20022d0012211320022f0010210d20022d000f210e20022d000e211420022f000c210f20022d000b2110200228000721112002280003210520022d0002211520022f00002116410121020b024020032802ec02450d00200710290b2002450d2d0b2003201c3703f0032003200a3a00ef03200320123a00ee032003200b3b01ec032003200c3a00eb03200320133a00ea032003200d3b01e8032003200e3a00e703200320143a00e6032003200f3b01e403200320103a00e303200320113600df03200320053600db03200320153a00da03200320163b01d803200341e8026a41086a22024200370300200342003703e80241e0c2c0004114200341e8026a1004200341d8026a41086a2002290300370300200320032903e8023703d8020240200341d8026a411041b8d6c50041004100100b417f460d00418d99c1002107412621080c2e0b200341e8026a200341b8026a10b901024020032903e8024201510d0041b399c1002107411821080c2e0b200341e8026a200341d8036a10b901024020032903e8024201510d0041969ac1002107412c21080c2e0b20034190036a280200210c20034180016a41a8c1c500411110b50141e199c10021074116210820032802840141002003280280011b201f470d2d0240200c41016a201f490d0041f799c1002107411f21080c2e0b200341e8026a202141067610bc01410021072021413f71220220032802f0024f0d2020032802e802200241216c6a22022d00004101470d2020022f00012106200241196a290000211c200241186a2d00002109200241176a2d00002104200241156a2f00002105200241146a2d0000210a200241136a2d0000210b200241116a2f0000210d200241106a2d0000210e2002410f6a2d0000210f2002410d6a2f000021102002410c6a2d00002111200241086a2800002113200241046a2800002112200241036a2d00002102410121070c210b41d588c3002107412a210820022d00000d2c20022d00014101470d2c20012802042116200241196a2d00002107200241186a2d00002108200241166a2f01002106200241156a2d00002109200241146a2d00002104200241126a2f01002105200241116a2d0000210a200241106a2d0000210b2002410e6a2f0100210c2002410d6a2d0000210d2002410c6a2d0000210e2002410a6a2f0100210f200241096a2d00002110200241086a2d00002111200241066a2f01002112200241056a2d00002113200241046a2d00002114200241026a2f0100211520032002411a6a29010037039804200320073a009704200320083a009604200320063b019404200320093a009304200320043a009204200320053b0190042003200a3a008f042003200b3a008e042003200c3b018c042003200d3a008b04200320143a008204200320153b01800420032010200f41087472200e41187472360087042003201320124108747220114118747236008304200341e8026a41086a22024200370300200342003703e80241e0c2c0004114200341e8026a1004200341d8026a41086a2002290300370300200320032903e8023703d8020240200341d8026a411041b8d6c50041004100100b417f460d0041a99bc1002107411e21080c2d0b411310272202450d082002410f6a41002800f9c340360000200241086a41002900f2c340370000200241002900eac34037000020024113413310282202450d092002200329038004370013411821082002412b6a20034180046a41186a290300370000200241236a20034180046a41106a2903003700002002411b6a20034180046a41086a290300370000200341e8026a41186a22074200370300200341e8026a41106a22064200370300200341e8026a41086a22094200370300200342003703e80220024133200341e8026a1000200341a8046a41186a2007290300370300200341a8046a41106a2006290300370300200341a8046a41086a2009290300370300200320032903e8023703a804200341a8046a412041b8d6c50041004100100b21072002102902402007417f470d0041c79bc10021070c2d0b200341a8046a201641067610bc01410021072016413f71220220032802b0044f0d1d20032802a804200241216c6a22022d00004101470d1d20022f00012106200241196a290000211c200241186a2d00002109200241176a2d00002104200241156a2f00002105200241146a2d0000210a200241136a2d0000210b200241116a2f0000210c200241106a2d0000210d2002410f6a2d0000210e2002410d6a2f0000210f2002410c6a2d00002110200241086a2800002112200241046a2800002111200241036a2d00002102410121070c1e0b200128020421052002411a6a290100211c200241196a2d0000210a200241186a2d0000210b200241166a2f0100210c200241156a2d0000210d200241146a2d0000210e200241126a2f0100210f200241116a2d00002110200241106a2d000021112002410e6a2f010021122002410d6a2d00002113200241046a2d00002114200241026a2f0100211541d588c3002107412a21040240024020022d0000450d004101210641002108410021090c010b41012106410021084100210920022d00014101470d002002410c6a2d000021092002410a6a2f01002108200241096a2d00002104200241066a2f0100410874200241056a2d000072200241086a2d0000411874722107410021060b200841ffff0371410874200441ff017172200941187472210820060d2b2003201c370398042003200a3a0097042003200b3a0096042003200c3b0194042003200d3a0093042003200e3a0092042003200f3b019004200320103a008f04200320113a008e04200320123b018c04200320133a008b0420032008360087042003200736008304200320143a008204200320153b018004411610272202450d092002410e6a41002900c9c240370000200241086a41002900c3c240370000200241002900bbc24037000020024116413610282202450d0a20022003290380043700162002412e6a20034180046a41186a290300370000200241266a20034180046a41106a290300370000411e21082002411e6a20034180046a41086a290300370000200341e8026a41186a22074200370300200341e8026a41106a22064200370300200341e8026a41086a22094200370300200342003703e80220024136200341e8026a1000200341a8046a41186a2007290300370300200341a8046a41106a2006290300370300200341a8046a41086a2009290300370300200320032903e8023703a804200341a8046a412041b8d6c50041004100100b21062002102941df9bc10021072006417f470d2b200341a8016a41dfc1c500411610b50120032802ac01210820032802a8012106200341e8026a41086a22024200370300200342003703e80241d8c3c0004112200341e8026a1004200341d8026a41086a2002290300370300200320032903e8023703d802200341003602e802200341d8026a4110200341e8026a100521070240024020032802e8022209417f460d002007450d00200320093602ac04200320073602a804200341e8026a200341a8046a102d20032802e802220b450d0d200341f0026a280200210220032802ec02210c2009450d01200710290c010b4100210c4101210b410021020b02400240024002402008410020061b220d2005470d0020022005460d010b41fd9bc100210741162108200220054d0d0120034180036a4200370300200341f8026a4200370300200341f0026a4200370300200342003703e802200b20054105746a2206200341e8026a460d002006200341e8026a412010d0040d010b200341a0016a20034180046a4280809aa6eaafe301420010ac0120032802a001450d0141939cc1002107411e21080b200c450d2c200b10290c2c0b20034198016a41a8c1c500411110b501200328029c0121062003280298012109411610272207450d0c2007410e6a41002900c9c240370000200741086a41002900c3c240370000200741002900bbc24037000020074116413610282207450d0d20072003290380043700162007412e6a20034180046a41186a290300370000200741266a20034180046a41106a2903003700002007411e6a20034180046a41086a290300370000200341e8026a41186a22084200370300200341e8026a41106a22044200370300200341e8026a41086a220a4200370300200342003703e80220074136200341e8026a1000200341a8046a41186a2008290300370300200341a8046a41106a2004290300370300200341a8046a41086a200a290300370300200320032903e8023703a804410410272208450d0e20082006410020091b36000020084104410810282208450d0f20082005360004200341a8046a412020084108100320081029200710290240024020022005460d00200341e8026a41186a220820034180046a41186a290300370300200341e8026a41106a220620034180046a41106a290300370300200341e8026a41086a220920034180046a41086a29030037030020032003290380043703e802200220054d0d12200b20054105746a220720032903e802370000200741186a2008290300370000200741106a2006290300370000200741086a20092903003700000c010b200341e8026a41186a220720034180046a41186a290300370300200341e8026a41106a220820034180046a41106a290300370300200341e8026a41086a220620034180046a41086a29030037030020032003290380043703e8020240200c2005470d00200541016a22022005490d2b20054101742209200220022009491b220c41ffffff3f71200c470d2b200c41057422024100480d2b0240024020050d0020021027210b0c010b200b200541057420021028210b0b200b450d180b200b20054105746a220220032903e802370000200241186a2007290300370000200241106a2008290300370000200241086a2006290300370000200541016a21020b200341e8026a41086a22074200370300200342003703e80241d8c3c0004112200341e8026a1004200341d8026a41086a2007290300370300200320032903e8023703d802200341003602f002200342013703e802200320023602a804200341a8046a200341e8026a103002400240024020020d0020032802f002210720032802ec02210920032802e80221040c010b20024105742105410020032802f00222076b210620032802e802210420032802ec022109200b210203400240200920066a411f4b0d00200741206a22082007490d2d2009410174220a20082008200a491b22084100480d2d0240024020090d002008102721040c010b200420092008102821040b2004450d03200821090b200420076a22082002290000370000200841186a200241186a290000370000200841106a200241106a290000370000200841086a200241086a290000370000200641606a2106200741206a2107200241206a2102200541606a22050d000b200320093602ec02200320073602f002200320043602e8020b200341d8026a411020042007100302402009450d00200410290b0240200c450d00200b10290b200341e8026a41086a22024200370300200342003703e80241dfc1c5004116200341e8026a1004200341d8026a41086a2002290300370300200320032903e8023703d802410121062003200d41016a3602e802200341d8026a4110200341e8026a410410030c190b20084101102a000b200141386a290300211c200141306a290300211d2001411d6a290000212a2001411c6a2d00002116200141196a2f00002117200141186a2d00002118200141156a2f00002119200141146a2d0000211a200141116a2f0000211b200141106a2d000021222001410c6a2802002123200141086a2802002105200141286a280200211f20012d001b212420012d0017212520012d0013212620012d0007212720012f0005212820012d000421292002411a6a290100211e200241196a2d0000210a200241186a2d0000210b200241166a2f0100210c200241156a2d0000210d200241146a2d0000210e200241126a2f0100210f200241116a2d00002110200241106a2d000021112002410e6a2f010021122002410d6a2d00002113200241046a2d00002114200241026a2f0100211541d588c3002107412a21040240024020022d0000450d004101210641002108410021090c010b41012106410021084100210920022d00014101470d002002410c6a2d000021092002410a6a2f01002108200241096a2d00002104200241066a2f0100410874200241056a2d000072200241086a2d0000411874722107410021060b200841ffff0371410874200441ff017172200941187472210820060d2a2003201e3703f0032003200a3a00ef032003200b3a00ee032003200c3b01ec032003200d3a00eb032003200e3a00ea032003200f3b01e803200320103a00e703200320113a00e603200320123b01e403200320133a00e303200320083600df03200320073600db03200320143a00da03200320153b01d8030240201d201c8450450d0041ef9cc100210741d00021080c2b0b0240202941ff01714101470d00200341e8026a200541067610cc0120032802e80221070240024020032802f0022005413f7122024b0d00410021020c010b200720024105746a2202290018212a20022d0017211620022d0016212420022f0014211720022d0013211820022d0012212520022f0010211920022d000f211a20022d000e212620022f000c211b20022d000b2122200228000721232002280003210520022d0002212720022f00002128410121020b024020032802ec02450d00200710290b2002450d2a0b2003202a37039804200320163a009704200320243a009604200320173b019404200320183a009304200320253a009204200320193b0190042003201a3a008f04200320263a008e042003201b3b018c04200320223a008b0420032023360087042003200536008304200320273a008204200320283b0180044111210820034198026a41a8c1c500411110b50141de9cc1002107200328029c0241002003280298021b201f470d2a200341e8026a41086a22024200370300200342003703e80241e0c2c0004114200341e8026a1004200341d8026a41086a2002290300370300200320032903e8023703d802200341003602e802200341d8026a4110200341e8026a100521020240024020032802e8022207417f460d002002450d002003200720074108200741084922081b22066b22073602ac042003200220066a22063602a804024020080d002003200720074104200741044922081b22096b3602ac042003200620096a3602a80420080d00200341e8026a200341a8046a102d20032802e802220a0d020b418f89c3004133104e000b41b19cc1002107412d21080c2b0b20032902ec02212b2002102920034190026a41cdc1c500411210b50120034180026a20032802940241002003280290021bad42004280a094a58d1d420010d304411410272202450d1020034180026a41086a290300211e200329038002212a200241106a41002800bb8c40360000200241086a41002900b38c40370000200241002900ab8c4037000020024114413410282202450d11200220032903d8033700142002412c6a200341f0036a290300370000200241246a200341d8036a41106a2903003700002002411c6a200341d8036a41086a290300370000200341e8016a20024134108401200341e8016a41106a290300212c20032903f001212d20032802e801210720021029202d420020071b202a54202c420020071b222c201e54202c201e511b450d1941f09dc1002107412e21080c1a0b4101210620022d000120022d0000720d1720012802042102200341e8026a41086a22074200370300200342003703e8024194c1c5004114200341e8026a1004200341d8026a41086a2007290300370300200320032903e8023703d802200320023602e802200341d8026a4110200341e8026a410410030c160b024020022d000120022d000072450d0041ad88c3002107412821080c290b200141086a28020021070240024020012d00044101460d00200141106a2d00002108200141146a2d00002106200141186a2d000021092001411c6a2d0000210420012f0005210220012d00072105200128020c210a20012f0011210b20012d0013210c20012f0015210d20012d0017210e20012f0019210f20012d001b2110200129001d211c0c010b200341e8026a200741067610cc0120032802e80221110240024020032802f0022007413f7122024b0d00410021120c010b201120024105746a2202290018211c20022d0017210420022d0016211020022f0014210f20022d0013210920022d0012210e20022f0010210d20022d000f210620022d000e210c20022f000c210b20022d000b21082002280007210a2002280003210720022d0002210520022f00002102410121120b024020032802ec02450d00201110290b2012450d280b2003201c3703d002200320043a00cf02200320103a00ce022003200f3b01cc02200320093a00cb022003200e3a00ca022003200d3b01c802200320063a00c7022003200c3a00c6022003200b3b01c402200320083a00c3022003200a3600bf02200320073600bb02200320053a00ba02200320023b01b802200341e8026a41086a22024200370300200342003703e80241d1c2c000410f200341e8026a1004200341d8026a41086a2002290300370300200320032903e8023703d802200341003602e802200341d8026a4110200341e8026a100521020240024020032802e8022207417f460d002002450d00200320073602ac04200320023602a804200341e8026a200341a8046a104120032802e8022208450d12200341f0026a280200210920032802ec02210d2007450d01200210290c010b4100210d41082108410021090b024002400240200941286c2206450d00410021070340200341e8026a41206a200820076a220241206a290300370300200341e8026a41186a200241186a290300370300200341e8026a41106a200241106a290300370300200341e8026a41086a200241086a290300370300200320022903003703e802200341e8026a200341b8026a412010d0040d022006200741286a2207470d000b0b4100210a200341003602b004200342083703a8044108210b0240200d0d004100210c0c020b200810294100210c0c010b20034180046a41086a200341e8026a41086a290300221c370300200341d8036a41086a2206201c370300200341d8036a41106a2204200341e8026a41106a290300370300200341d8036a41186a2205200341e8026a41186a290300370300200341d8036a41206a220a200341e8026a41206a290300370300200320032903e802221c370380042003201c3703d80341281027220b450d12200b20032903d803370300200b41206a200a290300370300200b41186a2005290300370300200b41106a2004290300370300200b41086a200629030037030002400240200941286c41586a2007470d004101210a4101210c0c010b200241286a210f2008200941286c6a220541586a21104101210a4101210c0340200f210202400340200341e8026a41206a2207200241206a290300370300200341e8026a41186a2206200241186a290300370300200341e8026a41106a2209200241106a290300370300200341e8026a41086a2204200241086a290300370300200320022903003703e802200341e8026a200341b8026a412010d0040d012005200241286a2202470d000c030b0b200341a8046a41206a2007290300221c37030020034180046a41086a2004290300221d37030020034180046a41106a2009290300221e37030020034180046a41186a2006290300222a37030020034180046a41206a201c370300200320032903e802222b370380042007201c3703002006202a3703002009201e3703002004201d3703002003202b3703e8020240200c200a470d00200a41016a220c200a490d2a200a410174220e200c200c200e491b220cad42287e221c422088a70d2a201ca7220e4100480d2a02400240200a0d00200e1027210b0c010b200b200a41286c200e1028210b0b200b450d160b200241286a210f200b200a41286c6a220e20032903e802370300200e41206a2007290300370300200e41186a2006290300370300200e41106a2009290300370300200e41086a2004290300370300200a41016a210a20102002470d000b0b0240200d450d00200810290b2003200a3602b0042003200c3602ac042003200b3602a8040b200341e8026a41086a22024200370300200342003703e80241d1c2c000410f200341e8026a1004200341d8026a41086a2002290300370300200320032903e8023703d802200341103602ec022003200341d8026a3602e802200341a8046a200341e8026a102f410021080240200a41286c22020d0041012104410021090c150b200241286d220941ffffff3f712009470d26200941057422024100480d262002102722040d1420024101102a000b4101210620022d000120022d0000720d15200141086a290300211c200341e8026a41086a22024200370300200342003703e8024198c3c000411c200341e8026a1004200341d8026a41086a2002290300370300200320032903e8023703d8022003201c3703e802200341d8026a4110200341e8026a410810030c140b4101210620022d000120022d0000720d14200141086a290300211c200341e8026a41086a22024200370300200342003703e8024184c3c0004114200341e8026a1004200341d8026a41086a2002290300370300200320032903e8023703d8022003201c3703e802200341d8026a4110200341e8026a410810030c130b410d4101102a000b412d4101102a000b41134101102a000b41334101102a000b41164101102a000b41364101102a000b418f89c3004133104e000b41164101102a000b41364101102a000b41044101102a000b41084101102a000b41c8c3c000200520021037000b41144101102a000b41344101102a000b418f89c3004133104e000b41284108102a000b200e4108102a000b20024101102a000b0240200a450d00200a41286c21064100210820042102200b21070340200741086a290000211c200741106a290000211d2007290000211e200241186a200741186a290000370000200241106a201d370000200241086a201c3700002002201e370000200841016a2108200241206a2102200741286a2107200641586a22060d000b0b0240200c450d00200b10290b200341e8026a41186a200341b8026a41186a290300370300200341e8026a41106a200341b8026a41106a290300370300200341e8026a41086a200341b8026a41086a290300370300200320032903b8023703e80241012106200341e8026a41012004200810ba012009450d00200410290b410021070c070b41ad88c300210741282108410121090c130b200341e8026a41086a22024200370300200342003703e80241b4c3c0004113200341e8026a1004200341d8026a41086a2002290300370300200320032903e8023703d802200341003602e802200341d8026a4110200341e8026a1005210202400240024002400240024002400240024020032802e8022207417f460d002002450d00200320073602ac04200320023602a804200341e8026a200341a8046a104720032802e802220c450d03200341f0026a280200210f20032802ec02211102402007450d00200210290b200f450d0541c19ec100210741232108200c290300201d54200c41086a290300222c201c54202c201c511b450d07200341e8026a41086a22024200370300200342003703e80241d1c2c000410f200341e8026a1004200341d8026a41086a2002290300370300200320032903e8023703d802200341003602e802200341d8026a4110200341e8026a1005210220032802e8022207417f460d012002450d01200320073602ac04200320023602a804200341e8026a200341a8046a104120032802e8022204450d04200341f0026a280200210520032802ec02210b2007450d02200210290c020b41bf9dc1002107413121080c080b4100210b41082104410021050b2004200541286c6a21092004210241002107024003400240200920026b41f8004b0d0020092002460d062004200541286c6a2109034020034180046a2002460d032007200220034180046a412010d00422064100476a21072006450d032009200241286a2202470d000c070b0b200220034180046a460d012007200220034180046a412010d00422064100476a21072006450d01200241286a220620034180046a460d012007200620034180046a412010d00422064100476a21072006450d01200241d0006a220620034180046a460d012007200620034180046a412010d00422064100476a21072006450d01200241f8006a220620034180046a460d01200241a0016a21022007200620034180046a412010d00422064100476a210720060d000b0b2007202b422088a7490d0341e49ec100210741362108200b450d04200410290c040b418f89c3004133104e000b418f89c3004133104e000b41f4c2c000410041001037000b0240200b450d00200410290b200341a8026a10b701200341e8026a20034180046a10b60120032802e8024101460d01024020032802ac02450d0020032802a80210290b419e9ec10021070b2011450d01200c10290c010b20032802a802212602400240024002400240024020032802b00222020d004200212e4200212f0c010b20032802ec022106200241216c2107202641016a2102200341f0026a2802002208410876210941012008411f7174210d20084105764107712204417f73210e20034188036a21054200212e4200212f034002402002417f6a2d00004101470d00200341e8026a200210b90120032903e8024201520d002003280290032006490d0020052903002130200341e8026a41106a2903002131200329038003213220032903f0022133200341e0016a41a8c1c500411110b501200341a8046a41186a200241186a290000370300200341a8046a41106a200241106a290000370300200341a8046a41086a200241086a290000370300200320022900003703a804200320093602c804200341b8026a200341a8046a10b8014200212c4200212d0240200420032802c00222084f0d002008200e6a220b20084f0d04203020317c203220337c222c203254ad7c420020032802b802200b4102746a280200200d7122081b212d202c420020081b212c0b024020032802bc02450d0020032802b80210290b202d202f7c202c202e7c222e202c54ad7c212f0b200241216a21022007415f6a22070d000b0b200c200f41306c6a2106200c210202400240024002400240024002400240024003400240200620026b4190014b0d00024020022006460d00034041012108200241106a220220034180046a460d04200220034180046a412010d004450d04200241206a22022006470d000b0b41002108202e201d85202f201c858450450d0220034180046a41186a290300211e20034190046a290300212a20034188046a290300212c200329038004212d200c201c370308200c201d370300200c202d370310200c41186a202c370300200c41206a202a370300200c41286a201e370300200f4115490d0c200f4101762221ad42307e221c422088a70d1c201ca72202417f4c0d1c20020d03410821254108210b0c040b41012108200241106a220720034180046a460d01200720034180046a412010d004450d01200241c0006a220720034180046a460d01200720034180046a412010d004450d01200241f0006a220720034180046a460d01200720034180046a412010d004450d01200241a0016a220720034180046a460d01200241c0016a2102200720034180046a412010d0040d000b0b411410272202450d07200241106a41002800bb8c40360000200241086a41002900b38c40370000200241002900ab8c4037000020024114413410282202450d06200220032903d8033700142002412c6a200341d8036a41186a290300370000200241246a200341d8036a41106a2903003700002002411c6a200341d8036a41086a290300370000200341c8016a20024134108401200341c8016a41106a290300211c20032903d001211d20032802c801210720021029200341d8036a201d420020071b221d202a201d201d202a56201c420020071b222c201e56202c201e511b22021b221c7d202c201e202c20021b222d7d201d201c54ad7d1089010240202a201c7d222c201e202d7d202a201c54ad7d221d84500d00411810272202450d06200241106a41002900cf8c40370000200241086a41002900c78c40370000200241002900bf8c4037000020024118413810282202450d05200220032903d803370018200241306a200341d8036a41186a290300370000200241286a200341d8036a41106a290300370000200241206a200341d8036a41086a290300370000200341b0016a20024138108401200341b0016a41106a290300212a20032903b801211e20032802b001210720021029200341d8036a201e420020071b221e202c201e201e202c56202a420020071b222a201d56202a201d511b22021b222c7d202a201d202a20021b221d7d201e202c54ad7d109c01201d202d7c202c201c7c222a202c54ad7c211e0b200341e8026a41086a22024200370300200342003703e80241b18ac0004116200341e8026a1004200341d8026a41086a2002290300370300200320032903e8023703d802200341003602e802200341d8026a4110200341e8026a100521070240024020032802e8022202417f470d004200211c4200211d0c010b200342003703f002200342003703e802200341e8026a20072002411020024110491b10ce041a2002410f4d0d04200341f0026a290300211d20032903e802211c200710290b200341e8026a41086a22024200370300200342003703e80241b18ac0004116200341e8026a1004200341d8026a41086a2002290300370300200320032903e8023703d80220034200201d201e7d201c202a54ad7d221e201c202a7d222a201c56201e201d56201e201d511b22021b3703f00220034200202a20021b3703e802200341d8026a4110200341e8026a41101003419a9fc10041b09fc10020081b21074116410f20081b2108410121020c0b0b200210272225450d012025210b0b200c41506a2128200c41306a211f200c41f07e6a2129410421124100212741002105200f2117034020172104410021174101210902402004417f6a2208450d00024002400240024002400240200c200841306c6a2202290300200441306c220e200c6a41a07f6a2207290300221d54200241086a290300221e200741086a290300221c54201e201c511b0d002004417e6a210d2029200e6a2102410021174100210703400240200d2007470d00200421090c080b201d2002290300222a5a2108201c200241086a290300221e512106201c201e5a2109200241506a2102200741016a2107202a211d201e211c2008200920061b0d000b200741016a21092007417f7320046a21080c010b2029200e6a210202400340024020084101470d00410021080c020b201d2002290300222a542107201c200241086a290300221e512106201c201e542109200241506a21022008417f6a2108202a211d201e211c2007200920061b0d000b0b20042008490d012004200f4b0d03200420086b22094101762206450d002028200e6a2102200c200841306c6a21070340200341e8026a41286a220d200741286a220e290300370300200341e8026a41206a2210200741206a2213290300370300200341e8026a41186a2214200741186a2215290300370300200341e8026a41106a2216200741106a2217290300370300200341e8026a41086a2218200741086a2219290300370300200320072903003703e802200241086a221a290300211c200241106a221b290300211d200241186a2222290300211e200241206a2223290300212a200241286a2224290300212c20072002290300370300200e202c3703002013202a3703002015201e3703002017201d3703002019201c3703002024200d2903003703002023201029030037030020222014290300370300201b2016290300370300201a2018290300370300200220032903e802370300200741306a2107200241506a21022006417f6a22060d000b0b024020080d00200821170c050b0240200941094d0d00200821170c050b2004200f4b0d01200420086b2106201f200841306c6a210d034020042008417f6a2217490d040240200420176b22094102490d00200c200841306c6a2202290300200c201741306c6a2208290300221e5a200241086a2207290300221d200841086a220e290300221c5a201d201c511b0d00200341e8026a41186a2213200841286a2210290300370300200341e8026a41106a2214200841206a2215290300370300200341e8026a41086a2216200841186a2218290300370300200320082903103703e80220082002290300370300200e2007290300370300200841106a200241106a2903003703002018200241186a2903003703002015200241206a2903003703002010200241286a29030037030041012107024020094103490d002008290360201e5a200841e8006a290300221d201c5a201d201c511b0d004102210e200d211003402010220241506a22072002290300370300200741286a200241286a290300370300200741206a200241206a290300370300200741186a200241186a290300370300200741106a200241106a290300370300200741086a200241086a2903003703002006200e2207460d01200741016a210e200241306a2210290300201e5a200241386a290300221d201c5a201d201c511b450d000b0b2002201e3703002002201c3703082008200741306c6a220241286a2013290300370300200241206a2014290300370300200241186a2016290300370300200220032903e8023703100b2017450d05200d41506a210d200641016a2106201721082009410a4f0d050c000b0b20082004103e000b20042008417f6a2217490d010b2004200f107f000b20172004103e000b02400240024020272005470d00202741016a22022027490d1c20274101742207200220022007491b220241ffffffff01712002470d1c200241037422074100480d1c0240024020270d002007102721120c010b201220274103742007102821120b2012450d01200221270b201220054103746a2202200936020420022017360200200541016a2213210520134102490d010340024002400240024020122013220e417f6a22134103746a2202280200450d00200e41037420126a220941746a2802002206200228020422074d0d0041022105200e41024d0d062012200e417d6a22024103746a2802042208200720066a4d0d0141032105200e41034d0d06200941646a280200200820066a4d0d01200e21050c060b200e4103490d01200228020421072012200e417d6a22024103746a28020421080b20082007490d010b200e417e6a21020b024002400240024002400240200e200241016a22184d0d00200e20024d0d01201220024103746a2214280204221920142802006a2202201220184103746a22152802002216490d022002200f4b0d03201441046a211a200c201641306c6a220d2015280204221041306c22076a2106200241306c2108200220166b220420106b220220104f0d0420252006200241306c220710ce041a200b20076a21090240024020104101480d00200241014e0d010b20062102200b21070c060b202820086a21082006210203402008200241506a2206200941506a22042004290300200629030054200441086a290300221c200641086a290300221d54201c201d511b22051b2207290300370300200841086a200741086a290300370300200841106a200741106a290300370300200841186a200741186a290300370300200841206a200741206a290300370300200841286a200741286a2903003703002009200420051b21090240200d2006200220051b2202490d00200b21070c070b200841506a2108200b2107200b2009490d000c060b0b41d8e3c1002018200e1037000b41d8e3c1002002200e1037000b20162002103e000b2002200f107f000b2025200d200710ce041a200b20076a21090240024020104101480d00200420104a0d010b200d2102200b21070c010b200c20086a2105200b2107200d210203402002200620072006290300200729030054200641086a290300221c200741086a290300221d54201c201d511b22041b2208290300370300200241086a200841086a290300370300200241106a200841106a290300370300200241186a200841186a290300370300200241206a200841206a290300370300200241286a200841286a2903003703002007200741306a20041b2107200241306a2102200641306a200620041b220620054f0d01200920074b0d000b0b20022007200920076b220820084130706b10ce041a201a201920106a360200201420163602002015201541086a2018417f73200e6a41037410cf041a20132105201341014d0d020c000b0b20074104102a000b20170d000b02402027450d00201210290b2021450d08202510290c080b20024108102a000b418f89c3004133104e000b41384101102a000b41184101102a000b41344101102a000b41144101102a000b41f4c2c000200b20081037000b200f4102490d00200f417f6a2108200c200f41306c6a21044101210603400240024002400240200f20082202417f6a2208490d00200f20086b22074102490d03200c200241306c6a2202290300200c200841306c6a2209290300221e5a200241086a2205290300221d200941086a220b290300221c5a201d201c511b0d03200341e8026a41186a220d200941286a220e290300370300200341e8026a41106a2210200941206a2212290300370300200341e8026a41086a2213200941186a2214290300370300200320092903103703e80220092002290300370300200b2005290300370300200941106a200241106a2903003703002014200241186a2903003703002012200241206a290300370300200e200241286a2903003703004101210520074103490d022009290360201e5a200941e8006a290300221d201c5a201d201c511b0d02410021052004210703402007220241506a22072002290300370300200741286a200241286a290300370300200741206a200241206a290300370300200741186a200241186a290300370300200741106a200241106a290300370300200741086a200241086a29030037030020062005220b460d02200b417f6a2105200241306a2207290300201e5a200241386a290300221d201c5a201d201c511b0d020c000b0b2008200f103e000b4102200b6b21050b2002201e3703002002201c3703082009200541306c6a220241286a200d290300370300200241206a2010290300370300200241186a2013290300370300200220032903e8023703100b200441506a21042006417f6a210620080d000b0b2003200f3602b004200320113602ac042003200c3602a804200341e8026a41086a22024200370300200342003703e80241b4c3c0004113200341e8026a1004200341d8026a41086a2002290300370300200320032903e8023703d802200341103602ec022003200341d8026a3602e802200341a8046a200341e8026a103402402011450d00200c10290b41002102410021070b024020032802ac02450d00202610290b0240024020020d00202ba7450d120c010b02402011450d00200c10290b202ba7450d110b200a10290c100b202ba7450d0f200a10290c0f0b0b024020032802ac04450d0020032802a80410290b024020070d0041919bc10021070c0e0b2003201c37038003200320093a00ff02200320043a00fe02200320053b01fc022003200a3a00fb022003200b3a00fa022003200c3b01f8022003200d3a00f7022003200e3a00f6022003200f3b01f402200320103a00f302200320123600ef02200320113600eb02200320023a00ea02200320063b01e8020240200341e8026a20034180046a412010d0040d0020034180046a201610cd0120034180046a428080e983b1de16420010ad01200342f0f2bda9c6add9b1f4003703d80220034188016a41888dc300410d109401200320032903900142002003280288011b3703b802200341a8046a20034180046a10930120032802ac04210720032802a804210220032802b0042108200341bc046a200341d8026a36020020032002200841286c6a3602b404200320023602b004200320073602ac04200320023602a8042003200341b8026a3602b804200341d8036a200341a8046a104a200341a8046a41086a200341d8036a41086a280200360200200320032903d8033703a80420034180046a200341a8046a10a701410021070c0e0b41f89ac1002107411921080c0d0b0b024020032802ec02450d0020032802e80210290b024020070d0041cb99c10021070c0c0b2003201c37039804200320093a009704200320043a009604200320053b0194042003200a3a0093042003200b3a0092042003200d3b0190042003200e3a008f042003200f3a008e04200320103b018c04200320113a008b0420032013360087042003201236008304200320023a008204200320063b018004200341e8026a202041067610bc0141002107024002402020413f71220220032802f0024f0d0020032802e802200241216c6a22022d00004101470d0020022f00012108200241196a290000211c200241186a2d00002106200241176a2d00002109200241156a2f00002104200241146a2d00002105200241136a2d0000210a200241116a2f0000210b200241106a2d0000210d2002410f6a2d0000210e2002410d6a2f0000210f2002410c6a2d00002110200241086a2800002112200241046a2800002111200241036a2d00002102410121070c010b0b024020032802ec02450d0020032802e80210290b024020070d0041e49ac1002107411421080c0c0b2003201c3703c004200320063a00bf04200320093a00be04200320043b01bc04200320053a00bb042003200a3a00ba042003200b3b01b8042003200d3a00b7042003200e3a00b6042003200f3b01b404200320103a00b304200320123600af04200320113600ab04200320023a00aa04200320083b01a804024020034180046a200341b8026a412010d004450d0041c29ac1002107411221080c0c0b0240200341a8046a200341d8036a412010d004450d0041d49ac1002107411021080c0c0b200341e8026a41186a2213200341d8036a41186a2214290300370300200341e8026a41106a2215200341d8036a41106a2216290300370300200341e8026a41086a2217200341d8036a41086a2218290300370300200320032903d8033703e802410021022003410036028803200341d8026a200341e8026a10b8010240024020032802e00222050d004101210e4100210f0c010b4100210d4100210f4101210e4100211103402005417f4c0d0a20032802dc02211220032802d80221100240024020051027220a450d00024002400240200541027422020d00410021040c010b201020026a210b410021042010210903402009280200210702404120102722020d0041204101102a000b200941046a210920022007411f763a001f200220074101713a000020022007411e764101713a001e20022007411d764101713a001d20022007411c764101713a001c20022007411b764101713a001b20022007411a764101713a001a200220074119764101713a0019200220074118764101713a0018200220074117764101713a0017200220074116764101713a0016200220074115764101713a0015200220074114764101713a0014200220074113764101713a0013200220074112764101713a0012200220074111764101713a0011200220074110764101713a001020022007410f764101713a000f20022007410e764101713a000e20022007410d764101713a000d20022007410c764101713a000c20022007410b764101713a000b20022007410a764101713a000a200220074109764101713a0009200220074108764101713a00082002200741ff017122074107763a0007200220074106764101713a0006200220074105764101713a0005200220074104764101713a0004200220074103764101713a0003200220074102764101713a0002200220074101764101713a00014100210702400240024002400340200741206a220841034d0d010240200220076a2208411f6a2d0000450d002007411f6a21060c040b02402008411e6a2d0000450d002007411e6a21060c040b02402008411d6a2d00000d002007417c6a21072008411c6a2d00000d030c010b0b2007411d6a21060c020b03402008450d03200220086a21072008417f6a220621082007417f6a2d0000450d000c020b0b200741206a21060b200641016a22082006490d000240200520046b2008412020084120491b22074f0d00200420076a22072004490d1220054101742206200720072006491b22074100480d120240024020050d0020071027210a0c010b200a200520071028210a0b200a450d04200721050b200a20046a2106410021070240034020074120460d01200620076a200220076a2d00004101713a00002008200741016a2207470d000b0b200420076a21040b200210292009200b470d000b0b02402012450d00201010290b0240200f200d6b2004490d00200d20046a21020c030b200d20046a2202200d490d0e200f4101742207200220022007491b22074100480d0e02400240200f0d0020071027210e0c010b200e200f20071028210e0b0240200e450d002007210f0c030b20074101102a000b20074101102a000b20054101102a000b200e200d6a200a200410ce041a02402005450d00200a10290b201320142903003703002015201629030037030020172018290300370300200320032903d8033703e8022003201141016a221136028803200341d8026a200341e8026a10b8012002210d20032802e00222050d000b0b024020032802dc02450d0020032802d80210290b200341e8026a41086a22074200370300200342003703e80241d8c3c0004112200341e8026a1004200341d8026a41086a2007290300370300200320032903e8023703d802200341003602e802200341d8026a4110200341e8026a100521070240024020032802e8022206417f460d002007450d00200320063602ac02200320073602a802200341e8026a200341a8026a102d20032802e802220a450d03200341f0026a280200210820032802ec02210b2006450d01200710290c010b4101210a410021084100210b0b02400240200841ffffff3f7122072002200220074b1b2208450d004100210720034180036a2106200341f8026a2109200341f0026a2104200a210203400240200e20076a2d0000450d00200642003703002009420037030020044200370300200342003703e802200341e8026a2002460d002002200341e8026a412010d004450d00200341e8026a200210b6014101210520032802e8024101470d0020032802ec02200c4d0d030b200241206a2102200741016a22072008490d000b0b410021050b0240200b450d00200a10290b0240200f450d00200e10290b200341b8026a200341d8036a20051b22072021202020051b10cd01200342f0f2bda9c6add9b1f4003703a002200341f0006a41888dc300410d10940120032003290378420020032802701b3703a802200341e8026a200710930120032802ec02210820032802e802210220032802f0022106200341fc026a200341a0026a36020020032002200641286c6a3602f402200320023602f002200320083602ec02200320023602e8022003200341a8026a3602f802200341d8026a200341e8026a104a200341e8026a41086a200341d8026a41086a280200360200200320032903d8023703e8022007200341e8026a10a701024002402005450d00411810272202450d04200241106a41002900cf8c40370000200241086a41002900c78c40370000200241002900bf8c4037000020024118413810282202450d05200220032903b802370018200241306a200341d0026a290300370000200241286a200341b8026a41106a290300370000200241206a200341b8026a41086a290300370000200341186a20024138108401200341186a41106a290300211e2003290320211d20032802182107200210294200211c200341b8026a201d420020071b221d201d428080e983b1de16201d428080e983b1de16544100201e420020071b222a501b22021b221e7d202a202a420020021b222b7d201d201e54ad7d109c01200341e8026a41086a22024200370300200342003703e80241b18ac0004116200341e8026a1004200341d8026a41086a2002290300370300200320032903e8023703d802200341003602e802200341d8026a4110200341e8026a100521070240024020032802e8022202417f470d004200211d0c010b200342003703f002200342003703e802200341e8026a20072002411020024110491b10ce041a2002410f4d0d07200341f0026a290300211d20032903e802211c200710290b200341e8026a41086a22024200370300200342003703e80241b18ac0004116200341e8026a1004200341d8026a41086a2002290300370300200320032903e8023703d80220034200201d202b7d201c201e54ad7d222a201c201e7d221e201c56202a201d56202a201d511b22021b3703f00220034200201e20021b3703e802200341d8026a4110200341e8026a41101003200341013a00ec02200341083a00e802200341e8026a4105722102200341e8026a21080c010b200341e0006a200341b8026a109501024002402003290360200341e0006a41086a29030084500d00411810272202450d08200241106a41002900cf8c40370000200241086a41002900c78c40370000200241002900bf8c4037000020024118413810282202450d09200220032903d803370018200241306a200341f0036a290300370000200241286a200341d8036a41106a290300370000200241206a200341d8036a41086a290300370000200341c8006a20024138108401200341c8006a41106a290300211d2003290350211c2003280248210720021029411410272202450d0a200241106a41002800bb8c40360000200241086a41002900b38c40370000200241002900ab8c40370000200241144134102822020d0141344101102a000b419d88c0002107412221080c0d0b200220032903b8023700142002412c6a200341b8026a41186a290300370000200241246a200341b8026a41106a2903003700002002411c6a200341b8026a41086a290300370000200341306a20024134108401200341306a41106a290300212a2003290338211e2003280230210820021029200341b8026a201e420020081b222b201c420020071b221c428080e983b1de16201c428080e983b1de16544100201d420020071b221d501b22021b221e7c222c202a420020081b201d420020021b222a7c202c202b54ad7c108901200341d8036a201c201e7d201d202a7d201c201e54ad7d109c01200341f5026a200341d8036a41086a290300370000200341fd026a200341d8036a41106a29030037000020034185036a200341d8036a41186a290300370000200341003a00ec02200341083a00e802200320032903d8033700ed022003418d036a2102200341e8026a21080b200220032903b802370000200241186a200341b8026a41186a290300370000200241106a200341b8026a41106a290300370000200241086a200341b8026a41086a2903003700004100210741b8d6c50041002008108801410121060b410121090c0c0b418f89c3004133104e000b41184101102a000b41384101102a000b418f89c3004133104e000b41184101102a000b41384101102a000b41144101102a000b1039000b102b000b4184efc2002107411521080b41012106410121090c010b41012109410021062004450d00200510290b02402001280200417f6a220241014b0d000240024020020e020001000b2009450d01200141086a280200450d01200128020410290c010b2006450d00200141086a280200450d00200128020410290b2000200836020420002007360200200341d0046a24000b110020012000280200200028020410e9030bae2505077f047e037f027e067f23004180026b22052400200541e0016a41086a22064200370300200542003703e00141d8c3c0004112200541e0016a1004200541f8006a41086a2006290300370300200520052903e00137037820054100360248200541f8006a4110200541c8006a1005210602400240024002400240024002400240024002400240024002400240024002400240024002400240024020052802482207417f460d002006450d00200520073602e401200520063602e001200541c8006a200541e0016a102d20052802482208450d02200541d0006a2802002109200528024c210a2007450d01200610290c010b41012108410021094100210a0b200541e0016a41086a22074200370300200542003703e0014114210641e0c2c0004114200541e0016a1004200541f8006a41086a2007290300370300200520052903e0013703780240200541f8006a411041b8d6c50041004100100b417f460d0041bf9fc1002107412e21060c120b200541c0006a41a8c1c500411110b50141ed9fc10021072005280244410020052802401b2003470d11024020090d004181a0c100210741c10021060c120b02402009200241086a280200220b4f0d0041c2a0c1002107413c21060c120b200541306a2001109501200541306a41086a290300210c2005290330210d200541c8006a200110b9010240024020052903484201510d00411410272207450d03200741106a41002800bb8c40360000200741086a41002900b38c40370000200741002900ab8c403700004134210620074114413410282207450d04200720012900003700142007412c6a200141186a290000370000200741246a200141106a2900003700002007411c6a200141086a290000370000200541186a20074134108401200541186a41106a290300210e200528021821092005290320210f2007102941a2a1c1002107200f428180e983b1de16544100200e501b0d132009450d13200541e0016a2004410676220910bc0141002106024020052802e8012004413f7122074d0d004101410220052802e001200741216c6a2d00001b21060b024020052802e401450d0020052802e00110290b20064102490d01200541f8006a200910bc01200541e0016a41186a2204200141186a290000370300200541e0016a41106a2210200141106a290000370300200541e0016a41086a2211200141086a290000370300200520012900003703e001200528028001220620074d0d0520052802782212200741216c6a220641013a0000200620052903e001370001200641096a2011290300370000200641116a2010290300370000200641196a2004290300370000410e10272206450d06200641066a41002900dac440370000200641002900d4c4403700002006410e411c10282206450d072006200936000e200541e0016a41186a22074200370300200541e0016a41106a22094200370300200541e0016a41086a22044200370300200542003703e00120064112200541e0016a1000200541c0016a41186a2007290300370300200541c0016a41106a2009290300370300200541c0016a41086a2004290300370300200520052903e0013703c001200541203602e4012005200541c0016a3602e001200541f8006a200541e0016a103520061029200528027c450d0d201210290c0d0b200541d8006a290300210f2005290350210e200541c0016a200441067610bc01410021092004413f71220620052802c8014f0d0e20052802c001200641216c6a22072d00004101470d0e200541b2016a200741036a2d00003a000020054198016a41086a200741146a290000370300200541a5016a200741196a290000370000200520072f00013b01b00120052007410c6a29000037039801200741086a2800002106200741046a2800002107410121090c0f0b200541106a41b9c1c500411410b50120054198016a2005280214410020052802101b220910bc010240024020052802a00122060d00200541e0016a2001428080d287e2bc2d4200410810900120052802e0014101470d0120052802e801210620052802e4012107200528029c01450d1320052802980110290c130b200541c0016a41186a200141186a290000370300200541c0016a41106a200141106a290000370300200541c0016a41086a200141086a290000370300200520012900003703c001200541c0016a2107200d210e200641c000460d0b0c0a0b200541e0016a41106a290300211320052903e8012114200541e0016a41086a22074200370300200542003703e00141b18ac0004116200541e0016a1004200541f8006a41086a2007290300370300200520052903e001370378200541003602e001200541f8006a4110200541e0016a1005210720052802e0012204417f460d072007450d07200542003703e801200542003703e001200541e0016a20072004411020044110491b10ce041a2004410f4d0d06200541e8016a290300210f20052903e001210e200710290c080b418f89c3004133104e000b41144101102a000b41344101102a000b41c8c3c000200720061037000b410e4101102a000b411c4101102a000b418f89c3004133104e000b4200210e4200210f0b200541e0016a41086a22074200370300200542003703e00141b18ac0004116200541e0016a1004200541f8006a41086a2007290300370300200520052903e00137037820054200200f20137d200e201454ad7d2213200e20147d2214200e562013200f562013200f511b22071b3703e80120054200201420071b3703e001200541f8006a4110200541e0016a41101003200541c0016a41186a200141186a290000370300200541c0016a41106a200141106a290000370300200541c0016a41086a200141086a290000370300200520012900003703c001200c200d428080aef89dc3527c220e200d54ad7c427f7c210c200541c0016a21070b200541e0016a41186a200741186a290000370300200541e0016a41106a200741106a290000370300200541e0016a41086a200741086a290000370300200520072900003703e00102400240200528029c012006460d0020052802980121070c010b200641016a22072006490d0720064101742204200720072004491b2204ad42217e220d422088a70d07200da722104100480d070240024020060d002010102721070c010b200528029801200641216c2010102821070b2007450d032005200436029c0120052007360298010b2007200641216c6a220741013a0000200720052903e001370001200741096a200541e0016a41086a2204290300370000200741116a200541e0016a41106a290300370000200741196a200541f8016a2903003700002005200641016a3602a00102402006413f470d0020044200370300200542003703e00141b9c1c5004114200541e0016a1004200541f8006a41086a2004290300370300200520052903e0013703782005200941016a3602e001200541f8006a4110200541e0016a410410030b200e210d0b200541e0016a41086a20054198016a41086a28020036020020052005290398013703e0012009200541e0016a10ce010b4200210e200541086a2001428080e983b1de16420010ac01024020052802082207450d00200528020c21060c060b200541cdc1c500411210b5012005280200210620052802042107200541e0016a41086a22094200370300200542003703e00141cdc1c5004112200541e0016a1004200541f8006a41086a2009290300370300200520052903e0013703782005200741016a410120061b3602e001200541f8006a4110200541e0016a410410034200210f0c030b20104101102a000b0b024020052802c401450d0020052802c00110290b0240024020090d00410121094113210641fea0c10021070c010b20054194016a41026a200541b0016a41026a2d00003a0000200541c0016a41086a20054198016a41086a290300370300200541c0016a410d6a20054198016a410d6a290000370000200520052f01b0013b01940120052005290398013703c001410021090b20054190016a41026a220420054194016a41026a2d00003a0000200541f8006a41086a2210200541c0016a41086a290300370300200541f8006a41106a200541c0016a41106a290300370300200520052f0194013b019001200520052903c00137037820090d02200541f3016a2010290300370000200541f8016a20054185016a290000370000200520052f0190013b01e001200520063600e701200520073600e301200520052903783700eb01200520042d00003a00e201200541e0016a2001460d00200541e0016a2001412010d004450d004191a1c1002107411121060c020b200542f0f2bda9c6add9b1f4003703b801200541b8016a2001200d200c427f410e10a801200541e0006a200c3703002005200d3703582005200f3703502005200e3703482005200336026c20052003360268024002400240411310272206450d002006410f6a41002800f9c340360000200641086a41002900f2c340370000200641002900eac340370000024020064113413310282206450d00200620012900003700132006412b6a200141186a290000370000200641236a200141106a2900003700002006411b6a200141086a290000370000200541e0016a41186a22074200370300200541e0016a41106a22034200370300200541e0016a41086a22094200370300200542003703e00120064133200541e0016a1000200541c0016a41186a2007290300370300200541c0016a41106a2003290300370300200541c0016a41086a2009290300370300200520052903e0013703c001200541203602e4012005200541c0016a3602e001200541c8006a200541e0016a10b301200610292002280204211020022802002103024002400240200b41057622150d0041042116410421170c010b2015410274220610272216450d01201621170b200b450d030240024020150d00410410272216450d0141012115201621170b20174100360200200b417f6a210941012118410021024100210602400340024002400240024002400240024002400240201820024d0d00201720024102746a22072007280200200320066a2d00002006411f71746a360200024020092006460d00200641016a2206411f710d0920152018470d08201541016a22072015490d1220154101742204200720072004491b220741ffffffff03712007470d122007410274220441004e0d070c120b02402010450d00200310290b410021190340200541c8006a41186a2207200141186a290000370300200541c8006a41106a2203200141106a290000370300200541c8006a41086a2209200141086a290000370300200520012900003703482018410820184108491b2202410274221110272206450d0220062017201110ce042112411310272206450d032006410f6a41002800d0c440360000200641086a41002900c9c440370000200641002900c1c44037000020064113413310282206450d04200620052903483700132006412b6a2007290300370000200641236a20032903003700002006411b6a20092903003700002006413341e6001028221a450d05201820026b2118201720116a2117201a2019360033200541e0016a41186a22064200370300200541e0016a41106a22074200370300200541e0016a41086a22034200370300200542003703e001201a4137200541e0016a1000200541c0016a41186a2006290300370300200541c0016a41106a2007290300370300200541c0016a41086a2003290300370300200520052903e0013703c00141002106200541003602e801200542013703e00120052002360278200541f8006a200541e0016a1030410020052802e80122046b210720052802e40121090340200420066a2103201220066a280200210b02400240200920076a4104490d0020052802e00121020c010b200341046a22022003490d1420094101742210200220022010491b22104100480d140240024020090d002010102721020c010b20052802e00120092010102821020b2002450d08200520103602e401200520023602e001201021090b2005200341046a3602e801200220046a20066a200b3600002007417c6a21072011200641046a2206470d000b200541c0016a41202002200420066a100302402009450d00200210290b201a102920121029201941016a211920180d000b2015450d10201610290c100b41c8c3c000200220181037000b20114104102a000b41134101102a000b41334101102a000b41e6004101102a000b20104101102a000b0240024020150d002004102721160c010b201620154102742004102821160b2016450d0320162117200721150b201720184102746a4100360200200241016a2102201841016a21180b200b20064b0d000b41f4c2c0002006200b1037000b20044104102a000b41044104102a000b20064104102a000b41334101102a000b41134101102a000b2010450d00200310290b410021070240200a450d00200810290b0c020b102b000b0240200a450d00200810290b200241046a280200450d00200228020010290b200020063602042000200736020020054180026a24000bed0202047f017e230041d0006b22022400024002400240410f10272203450d00200341076a41002900f3ec42370000200341002900ecec423700002003410f411e10282203450d012003200136000f200241306a41186a22014200370300200241306a41106a22044200370300200241306a41086a220542003703002002420037033020034113200241306a1000200241086a41186a2001290300370300200241086a41106a2004290300370300200241086a41086a20052903003703002002200229033037030820024100360230200241086a4120200241306a100521040240024020022802302201417f460d002002200136022c20022004360228200241306a200241286a102d20022802302205450d042002290234210602402001450d00200410290b20002006370204200020053602000c010b20004100360208200042013702000b20031029200241d0006a24000f0b410f4101102a000b411e4101102a000b418f89c3004133104e000bee08010c7f23004190016b22022400200241086a2001410676220310bc01024002400240024002400240200228021022042001413f7122014d0d002002280208200141216c6a220141003a000020012002290028370001200141096a200241286a41086a2204290000370000200141116a200241286a41106a2205290000370000200141196a200241286a41186a22062900003700002004200241086a41086a280200360200200220022903083703282003200241286a10ce01200241cdc1c500411210b5012002280200210120022802042103200442003703002002420037032841cdc1c5004112200241286a1004200241f0006a41086a220720042903003703002002200229032837037020022003417f6a417f20011b360228200241f0006a4110200241286a410410032006200041186a22082900003703002005200041106a22092900003703002004200041086a220a2900003703002002410036024820022000290000370328200241186a200241286a10b80102402002280220450d00410021030340200241d0006a41186a220b2008290000370300200241d0006a41106a220c2009290000370300200241d0006a41086a220d200a29000037030020022000290000370350411310272201450d032001410f6a41002800d0c440360000200141086a41002900c9c440370000200141002900c1c44037000020014113413310282201450d04200120022903503700132001412b6a200b290300370000200141236a200c2903003700002001411b6a200d2903003700002001413341e60010282201450d05200120033600332006420037030020054200370300200442003703002002420037032820014137200241286a1000200241f0006a41186a2006290300370300200241f0006a41106a20052903003703002007200429030037030020022002290328370370200241f0006a4120100c20011029200341016a21030240200228021c450d00200228021810290b20062008290000370300200520092900003703002004200a2900003703002002200336024820022000290000370328200241186a200241286a10b80120022802200d000b0b0240200228021c450d00200228021810290b411310272201450d042001410f6a41002800f9c340360000200141086a41002900f2c340370000200141002900eac34037000020014113413310282201450d05200120002900003700132001412b6a200041186a290000370000200141236a200041106a2900003700002001411b6a200041086a290000370000200241286a41186a22034200370300200241286a41106a22044200370300200241286a41086a220542003703002002420037032820014133200241286a1000200241f0006a41186a2003290300370300200241f0006a41106a2004290300370300200241f0006a41086a200529030037030020022002290328370370200241f0006a4120100c2001102920024190016a24000f0b41c8c3c000200120041037000b41134101102a000b41334101102a000b41e6004101102a000b41134101102a000b41334101102a000b830201047f230041c0006b2202240002400240410e10272203450d00200341066a41002900dac440370000200341002900d4c4403700002003410e411c10282203450d012003200036000e200241206a41186a22004200370300200241206a41106a22044200370300200241206a41086a220542003703002002420037032020034112200241206a1000200241186a2000290300370300200241106a2004290300370300200241086a20052903003703002002200229032037030020024120360224200220023602202001200241206a1035200310290240200141046a280200450d00200128020010290b200241c0006a24000f0b410e4101102a000b411c4101102a000be80102027f027e230041206b2203240002400240411410272204450d00200441106a41002800bb8c40360000200441086a41002900b38c40370000200441002900ab8c4037000020044114413410282204450d01200420022900003700142004412c6a200241186a290000370000200441246a200241106a2900003700002004411c6a200241086a290000370000200341086a20044134108401200341086a41106a290300210520032903102106200328020821022004102920002005420020021b37030820002006420020021b370300200341206a24000f0b41144101102a000b41344101102a000bef0101057f230041c0006b220524000240024020030d00200041003602000c010b2003280208210620032802002103200541206a41186a22074200370300200541206a41106a22084200370300200541206a41086a220942003703002005420037032020044120200541206a1000200541186a2007290300370300200541106a2008290300370300200541086a200929030037030020052005290320370300200541003602202003200620054120200541206a10012104024020052802202203417f460d002000200336020420002004360200200041086a20033602000c010b200041003602000b200541c0006a24000bfd0101057f23004190016b22032400200341086a2002108c010240024020032d000822024102470d00200041003a00000c010b200341f0006a200341c8006a290300370300200341f8006a2204200341d0006a29030037030020034180016a2205200341d8006a29030037030020034188016a2206200341e0006a2903003703002003200341c0006a29030037036802402002450d00200041003a00000c010b2003413c6a2802002102200341386a280200210720002003290370370001200041013a0000200041196a2006290300370000200041116a2005290300370000200041096a20042903003700002002450d00200710290b20034190016a24000baf0201047f230041c0006b2202240002400240411710272203450d002003410f6a41002900af9342370000200341086a41002900a89342370000200341002900a0934237000020034117413710282203450d01200320012900003700172003412f6a200141186a290000370000200341276a200141106a2900003700002003411f6a200141086a290000370000200241206a41186a22014200370300200241206a41106a22044200370300200241206a41086a220542003703002002420037032020034137200241206a1000200241186a2001290300370300200241106a2004290300370300200241086a2005290300370300200220022903203703002002412041b8d6c50041004100100b210120031029200241c0006a24002001417f470f0b41174101102a000b41374101102a000b840102017f037e230041e0006b2203240020032002108c010240024020032d000022024102470d00420021040c010b2002410173ad2104200341106a2903002105200341086a290300210620020d00200341346a280200450d00200341306a28020010290b2000200637030820002004370300200041106a2005370300200341e0006a24000be6230a057f047e0c7f067e057f027e047f037e017f037e230041f0046b22022400200128020821032001280200210402400240200128020422050d00200421010c010b2005210620042101034020012802880b21012006417f6a22060d000b0340200420042f01064102746a41880b6a28020021042005417f6a22050d000b0b200241e4006a20042f0106360200200241c8006a41186a4100360200200241dc006a2004360200200220033602682002410036025842002107200242003703502002200136024c20024100360248200241b0016a200241c8006a10d5010240024020022903d00122084202520d00420021094200210a0c010b200241b0016a41c0006a210b200241b0016a41386a210c200241b0016a410472210d2002418d026a210e200241b0016a41086a210320024190036a41386a210f200241e0016a2110200241f8016a211141808bc20041f88ac2006b200241e8036a6b200241e8036a41206a6a410f6a211242002107420021094200210a034020024190016a41186a2205200241b0016a41186a220129030037030020024190016a41106a2206200241b0016a41106a220429030037030020024190016a41086a22132003290300370300200241f0006a41086a2214200e41086a290000370300200241f0006a41106a2215200e41106a290000370300200241f0006a41186a2216200e41186a290000370300200220022903b001370390012002200e290000370370201029030021172011290300211820022903d801211920022903f001211a20022903e801211b200229038002211c200228028802211d20022d008c02211e200241b0026a41186a221f2005290300370300200241b0026a41106a22202006290300370300200241b0026a41086a2206201329030037030020022002290390013703b002200241d0026a41186a22052016290300370300200241d0026a41106a22132015290300370300200241d0026a41086a22152014290300370300200220022903703703d002024002400240024002400240024002400240024020084201520d00200241b0016a200241b0026a2019201710850120022d00c8012114200241306a200a2007200920022903b00120022903b8012004290300105e200241306a41106a2903002109200229033821072002290330210a20140d010b02400240024002400240201d0d00201b4201510d00201e41ff01714101470d010b200241b0016a200241b0026a108c010240024020022d00b0012214417f6a221641014b0d00024020160e020002000b20140d0620022802e401450d0620022802e00110290c060b200241f0026a41086a2214200b41086a290300370300200241f0026a41106a2216200b41106a290300370300200241f0026a41186a2221200b41186a2903003703002002200b2903003703f0022004290300212220022903b801212320022802ec01212420022802e801212520022802e401212620022802e001212720022903d801212820022903c801212920022903d00122174202510d042025417f4c0d020240024020250d00410121060c010b202510272206450d0420062027202510ce041a0b200f20022903f002370300200f41086a2014290300370300200f41106a2016290300370300200f41186a20212903003703002002202337039003200220243602c403200220253602c003200220253602bc03200220063602b803200220283703b003200220293703a003200220223703980320022017420151ad222a3703a8032025212b2025211f2029212c2023212d2022212e202421140c070b024020140d0020022802e401450d0020022802e00110290b420221170c030b201ca7210402400240201c422088a722050d00200421010c010b2005210620042101034020012802ec0321012006417f6a22060d000b0340200420042f01064102746a41ec036a28020021042005417f6a22050d000b0b200241003602d001200241003602c801200241003602c001200242003703b801200220013602b401200241003602b001200220043602c401200220042f01063602cc01200241b0016a10d6010c0b0b1039000b20254101102a000b201e41ff01710d010b201ca7210402400240201c422088a722050d00200421010c010b2005210620042101034020012802ec0321012006417f6a22060d000b0340200420042f01064102746a41ec036a28020021042005417f6a22050d000b0b2002201d3602d001200241003602c801200241003602c001200242003703b801200220013602b401200241003602b001200220043602c401200220042f01063602cc01200241b0016a10d6010c070b200241206a419188c5004117109401200228022021142002290328210820034200370300200242003703b001419188c5004117200241b0016a1004200241e8036a41086a22162003290300370300200220022903b0013703e8032002200842017c420120141b22083703b001200241e8036a4110200241b0016a41081003412010272214450d03201420022903b002370000201441186a201f290300370000201441106a2020290300370000201441086a20062903003700002014412041c00010282214450d0220142008370020200142003703002004420037030020034200370300200242003703b00120144128200241b0016a1000200241e8036a41186a2001290300370300200241e8036a41106a200429030037030020162003290300370300200220022903b0013703e803413710272206450d01200642bac6a1cbc68dd9aff300370000200642f4dec98bf6ac999de400370008200641e5cc85ab073600102006413a3a0016200641ece8013b0014200620022903e803370017200620022f01f0033b001f200620022801f203360021200620022f01f6033b0025200620022d00f8033a0027200620022d00f9033a0028200620022d00fa033a0029200620022d00fb033a002a200620022d00fc033a002b200620022d00fd033a002c200620022d00fe033a002d200620022d00ff033a002e200620022d0080043a002f200620022d0081043a0030200620022d0082043a0031200620022d0083043a0032200620022d0084043a0033200620022d0085043a0034200620022d0086043a0035200620022d0087043a003620141029200241106a41888dc300410d1094012002290318210820022802102116200f20022903d00237000041082114200f41086a200241d0026a41086a290300370000200f41106a2013290300370000200f41186a2005290300370000427f212d2002427f370398032002427f37039003200241083602c403200220123602c0034137212b200241373602bc03200220063602b8034200212a200242003703a80320022008420020161b222c3703a0032012211f427f212e0b0240201b4201520d002002201a370390032002201837039803201a212d2018212e0b0240201e41ff0171450d00200f20022903d002370000200f41186a2005290300370000200f41106a2013290300370000200f41086a20152903003700000b0240201d450d00200241888dc300410d1094014201212a200242013703a80320022002290308420020022802001b3703b0030b201ca7210502400240201c422088a722150d00200521130c010b2015211620052113034020132802ec0321132016417f6a22160d000b0340200520052f01064102746a41ec036a28020021052015417f6a22150d000b0b20052f010621152002201d3602880420022015360284042002410036028004200220053602fc03200241003602f803200242003703f003200220133602ec03200241003602e803200241b0016a200241e8036a10d70120022802b0014101470d04034020024190046a41186a200d41186a290200221c37030020024190046a41106a200d41106a290200220837030020024190046a41086a200d41086a290200221b3703002002200d29020022193703900420022802d401210520022802d801212020022802dc012113200241b0046a41186a201c370300200241b0046a41106a2008370300200241b0046a41086a201b370300200220193703b004200142003703002004420037030020034200370300200242003703b001200241b0046a4120200241b0016a1000200241d0046a41186a22162001290300370300200241d0046a41106a221d2004290300370300200241d0046a41086a221e2003290300370300200220022903b0013703d004200241003602b0012006201f200241d0046a4120200241b0016a10012121024020022802b0012215417f460d00201420156b21142015450d00202110290b024002402005450d00200142003703002004420037030020034200370300200242003703b001200241b0046a4120200241b0016a100020162001290300370300201d2004290300370300201e2003290300370300200220022903b0013703d0042006201f200241d0046a4120200520131011201420136a21142020450d01200510290c010b200142003703002004420037030020034200370300200242003703b001200241b0046a4120200241b0016a100020162001290300370300201d2004290300370300201e2003290300370300200220022903b0013703d0042006201f200241d0046a412010020b200241b0016a200241e8036a10d70120022802b0014101470d040c000b0b41374101102a000b41c0004101102a000b41204101102a000b200220143602c4030b200241e8036a10d601200241e8036a41186a2204200241f0026a41186a290300370300200241e8036a41106a2201200241f0026a41106a290300370300200241e8036a41086a2205200241f0026a41086a290300370300200220022903f0023703e8030240024020174202510d00200c20022903e803370300200c41086a2005290300370300200c41106a2001290300370300200c41186a2004290300370300200220233703b001200220243602e401200220263602dc01200220273602d801200220283703d001200220173703c801200220293703c001200220223703b801200220253602e0014101210402402025201f470d000240024020272006460d0020272006202510d0040d0220242014470d020c010b20242014470d010b200c200f412010d0040d002023202d852022202e85844200520d002029202c520d002017a72201202aa7470d002001410146202820022903b003527121040b02402026450d00202710290b20044102460d002004450d010b200320024190036a41d80010ce041a200241003a00b001200241b0026a200241b0016a10d8010c010b202b450d00200610290b200241b0016a200241c8006a10d50120022903d00122084202520d000b0b200241c8006a10d90102400240024002400240200a500d004200211c200241b0016a41086a22044200370300200242003703b00141b18ac0004116200241b0016a100420024190036a41086a2004290300370300200220022903b00137039003200241003602b00120024190036a4110200241b0016a100521010240024020022802b0012204417f470d00420021080c010b200242003703b801200242003703b001200241b0016a20012004411020044110491b10ce041a2004410f4d0d02200241b8016a290300210820022903b001211c200110290b200241b0016a41086a22044200370300200242003703b00141b18ac0004116200241b0016a100420024190036a41086a2004290300370300200220022903b0013703900320024200200820097d201c200754ad7d221b201c20077d2219201c56201b200856201b2008511b22041b3703b80120024200201920041b3703b001200241b0016a21040c030b2007200984500d0141eca9c1001058000b418f89c3004133104e000b4200211c200241b0016a41086a22044200370300200242003703b00141b18ac0004116200241b0016a100420024190036a41086a2004290300370300200220022903b00137039003200241003602b00120024190036a4110200241b0016a100521010240024020022802b0012204417f470d00420021080c010b200242003703b801200242003703b001200241b0016a20012004411020044110491b10ce041a2004410f4d0d02200241b8016a290300210820022903b001211c200110290b200241b0016a41086a22044200370300200242003703b00141b18ac0004116200241b0016a100420024190036a41086a2004290300370300200220022903b00137039003200220083703b8012002201c3703b001200241b0016a21040b20024190036a4110200441101003200241f0046a24000f0b418f89c3004133104e000bf90503087f017e017f23004180026b2202240002400240024020012802202203450d0020012003417f6a36022020012802082104200128020c2203200128020422052f01064f0d01200241186a2206200520034105746a220741206a290000370300200241106a2208200741186a290000370300200241086a2209200741106a2900003703002002200741086a290000370300200241206a2005200341e0006c6a41e8026a41e00010ce041a2001200341016a36020c200120043602082001200536020420024180016a41186a200629030037030020024180016a41106a200829030037030020024180016a41086a2009290300370300200220022903003703800120024180016a41206a200241206a41e00010ce041a200020024180016a41800110ce041a0c020b200042023703200c010b2001280200210702400240200528020022030d002004ad210a410021030c010b200741016a210720053301044220862004ad84210a0b20051029200aa7210402400240200a422088a7220620032f01064f0d00200321050c010b034002400240200328020022050d002004ad210a410021050c010b200741016a210720033301044220862004ad84210a0b20031029200aa7210420052103200a422088a7220620052f01064f0d000b0b200241186a2208200520064105746a220341206a290000370300200241106a2209200341186a290000370300200241086a220b200341106a2900003703002002200341086a290000370300200241206a2005200641e0006c6a41e8026a41e00010ce041a200641027420056a418c0b6a280200210302402007417f6a2205450d00034020032802880b21032005417f6a22050d000b0b2001410036020c20012004360208200120033602042001410036020020024180016a41186a200829030037030020024180016a41106a200929030037030020024180016a41086a200b290300370300200220022903003703800120024180016a41206a200241206a41e00010ce041a200020024180016a41800110ce041a0b20024180026a24000bb00101037f230041306b220124002001200010d701024020012802004101470d000340024020012802242202450d002001280228450d00200210290b2001200010d70120012802004101460d000b0b024020002802042202418883c000460d0020022802002103200210292003450d0020032802002100200310292000450d00024020002802002202450d000340200010292002210020022802002203210220030d000b0b200010290b200141306a24000bdd0605057f047e017f017e047f23004190016b2202240002400240024020012802202203450d0020012003417f6a36022020012802082104200128020c2203200128020422052f01064f0d01200241e0006a41186a200520034105746a220641206a2900002207370300200241e0006a41106a200641186a2900002208370300200241e0006a41086a200641106a29000022093703002002200641086a290000220a370360200241306a41086a20052003410c6c6a220641f0026a280200220b360200200641e8026a290200210c2001200341016a36020c20012004360208200120053602042002200c3703302000200a3702042000410c6a2009370200200041146a20083702002000411c6a2007370200200041246a200c3702002000412c6a200b360200200041013602000c020b200041003602000c010b2001280200210602400240200528020022030d002004ad210c410021030c010b200641016a210620053301044220862004ad84210c0b20051029200ca7210402400240200c422088a7220b20032f01064f0d00200321050c010b034002400240200328020022050d002004ad210c410021050c010b200641016a210620033301044220862004ad84210c0b20031029200ca7210420052103200c422088a7220b20052f01064f0d000b0b200241306a41186a220d2005200b4105746a220341206a290000370300200241306a41106a220e200341186a290000370300200241306a41086a220f200341106a2900003703002002200341086a290000370330200241d0006a41086a22102005200b410c6c6a220341f0026a2802003602002002200341e8026a290200370350200b41027420056a41f0036a280200210302402006417f6a2205450d00034020032802ec0321032005417f6a22050d000b0b2001410036020c200120043602082001200336020420014100360200200241e0006a41186a200d290300220c370300200241e0006a41106a200e2903002207370300200241e0006a41086a200f290300220837030020024188016a201028020022033602002000200229033022093702042000410c6a2008370200200041146a20073702002000411c6a200c370200200041246a2002290350220c3702002000412c6a2003360200200220093703602002200c37038001200041013602000b20024190016a24000bd00201047f230041c0006b2202240002400240411710272203450d002003410f6a41002900af9342370000200341086a41002900a89342370000200341002900a0934237000020034117413710282203450d01200320002900003700172003412f6a200041186a290000370000200341276a200041106a2900003700002003411f6a200041086a290000370000200241206a41186a22004200370300200241206a41106a22044200370300200241206a41086a220542003703002002420037032020034137200241206a1000200241186a2000290300370300200241106a2004290300370300200241086a20052903003703002002200229032037030020024120360224200220023602202001200241206a10dc0220031029024020012d00000d00200141346a280200450d00200141306a28020010290b200241c0006a24000f0b41174101102a000b41374101102a000bca0201067f230041b0016b22012400200141086a200010d501024020012903284202510d000340200128026021022001280258210302400240200128025c22040d00200321050c010b2004210620032105034020052802ec0321052006417f6a22060d000b0340200320032f01064102746a41ec036a28020021032004417f6a22040d000b0b200120023602a801200141003602a001200141003602980120014200370390012001200536028c0120014100360288012001200336029c01200120032f01063602a40120014188016a10d601200141086a200010d50120012903284202520d000b0b024020002802042203418883c000460d0020032802002104200310292004450d0020042802002105200410292005450d00024020052802002203450d000340200510292003210520032802002204210320040d000b0b200510290b200141b0016a24000b821e04027f027e097f027e230041c00d6b220824000240024002402001280234200128025022092802b801460d00200442002004290308220a200941c0006a2903007d220b200b200a5622091b3703082009450d01200041013a0000200041086a412a360200200041046a419cb5c3003602000c020b200041013a0000200041086a4124360200200041046a41d3b4c3003602000c010b200841106a41186a200141f4006a290000370300200841106a41106a200141ec006a290000370300200841106a41086a200141e4006a2900003703002008200129005c370310200841c0026a41186a22094200370300200841c0026a41106a220c4200370300200841c0026a41086a220d4200370300200842003703c00220062007200841c0026a1000200841e00a6a41186a2009290300370300200841e00a6a41106a200c290300370300200841e00a6a41086a200d290300370300200820082903c0023703e00a024002400240024002400240024002400240412010272209450d0020092005290000370000200941186a200541186a290000370000200941106a200541106a290000370000200941086a200541086a2900003700002009412041c00010282209450d01200920082903e00a370020200941386a200841e00a6a41186a290300370000200941306a200841e00a6a41106a290300370000200941286a200841e00a6a41086a290300370000200941c00041800110282209450d0220092008290310370040200941d8006a200841106a41186a290300370000200941d0006a200841106a41106a290300370000200941c8006a200841106a41086a290300370000200841c0026a41186a220c4200370300200841c0026a41106a220d4200370300200841c0026a41086a220e4200370300200842003703c002200941e000200841c0026a1000200841306a41186a220f200c290300370300200841306a41106a220c200d290300370300200841306a41086a220d200e290300370300200820082903c00237033020091029200841c4016a200d290300370200200841cc016a200c290300370200200841d4016a200f290300370200200841e0006a41c8006a4200370300200841a0016a42808080808001370300200841e0006a41306a41f8b4c3003602002008418c016a2001411c6a221036020020084184016a420037020020084180016a2211418883c000360200200820082903303702bc0120084208370398012008410036027c20084100360270200820012802583602b801200820012903503703b0012008200128023441016a360294012001290300210a200820012903083703682008200a370360200841e0016a41186a200541186a290000370300200841e0016a41106a200541106a290000370300200841e0016a41086a200541086a2900003703002008410136027c200820052900003703e0012010200841306a10e40121092008200828027c417f6a220c36027c024020090d00200c0d042008417f36027c200841a0026a41186a200841306a41186a290300370300200841a0026a41106a200841306a41106a290300370300200841a0026a41086a200841306a41086a290300370300200820082903303703a00202400240200828028001220f418883c000460d0020082802840121120c010b41002112200841e00a6a410041e00210cd041a200841c0026a410041a00810cd041a41880b1027220f450d06200f41003b0106200f4100360200200f41086a200841e00a6a41e00210ce041a200f41e8026a200841c0026a41a00810ce041a20084100360284012008200f360280010b200841e0006a411c6a2113024002400340200f41086a210c200f2f0106221441057421094100210d024003402009450d01200841a0026a200c412010d004220e450d03200941606a2109200d41016a210d200c41206a210c200e417f4a0d000b200d417f6a21140b02402012450d002012417f6a2112200f20144102746a41880b6a280200210f0c010b0b20084180026a41186a200841a0026a41186a290300220a37030020084180026a41106a200841a0026a41106a290300220b37030020084180026a41086a200841a0026a41086a2903002215370300200820082903a002221637038002200841fc0a6a2015370200200841840b6a200b3702002008418c0b6a200a370200200820084188016a3602f00a200820143602ec0a200820113602e80a2008200f3602e40a200841003602e00a200820163702f40a200841f4026a4200370200200841003a00fc02200842003703c0022008418883c0003602f002200842003703d802200841e00a6a200841c0026a10de0121090c010b200f200d41e0006c6a41e8026a21090b200841f8016a290300210a20094201370318200941013a003c200941286a427f370300200941206a427f3703002009413d6a20082903e001370000200941d5006a200a370000200941cd006a200841f0016a290300370000200941c5006a200841e8016a2903003700002008200828027c41016a36027c200841086a20044101200841106a200841306a20022003200841e0006a10a20302402008280208220f450d00200828020c21010c0a0b200841c0026a200520082802b801280200108402024020082802c0024101470d00200841c8026a280200210120082802c402210f0c0a0b200841a0026a41186a200841c0026a410472220941186a280200220c360200200841e00a6a41106a200941086a290200370300200841e00a6a41186a220d200941106a290200370300200841800b6a200c360200200841063602e40a200841bd8fc5003602e00a200820092902003703e80a20082802b40121092008200841e0006a3602e0022008290360210a2008290368210b200841ec026a200841106a41086a290300370200200841f4026a200841106a41106a290300370200200841fc026a200841106a41186a290300370200200820033703c802200820023703c0022008200b3703d8022008200a3703d002200820082903103702e40220084100360288022008420137038002200841a0026a2009200841e00a6a200841c0026a2006200720084180026a2004106220082802a0020e03070608070b41f7a5c100210f412a21010c080b41204101102a000b41c0004101102a000b4180014101102a000b41c8a8c1004110200841c0026a41f0a8c10010a201000b41880b4108102a000b200841a0026a41086a280200450d0020082802a40210290b200841c0026a41086a200841106a41086a290300370300200841c0026a41106a200841106a41106a290300370300200841c0026a41186a200841106a41186a290300370300200841a0026a41086a200841306a41086a290300370300200841a0026a41106a200841306a41106a290300370300200841a0026a41186a200841306a41186a290300370300200820082903103703c002200820082903303703a0020240024020082802a0012209200828029c01460d00200828029801210c0c010b02400240200941016a220c2009490d002009410174220d200c200c200d491b220dad42e8007e2202422088a70d002002a7220e4100480d000240024020090d00200e1027210c0c010b200828029801200941e8006c200e1028210c0b200c450d012008200d36029c012008200c3602980120082802a00121090c020b102b000b200e4108102a000b200c200941e8006c6a220941013a0000200920082903c002370001200941096a200841c0026a41086a220c290300370000200941116a200841c0026a41106a290300370000200941196a200841c0026a41186a290300370000200941216a20082903a002370000200941296a200841a0026a41086a290300370000200941316a200841a0026a41106a290300370000200941396a200841a0026a41186a290300370000200941d0006a2008418f026a290000370000200941c9006a20084180026a41086a290000370000200941c1006a200829008002370000200941e0006a410036020020094201370358200820082802a00141016a220d3602a0010240200841e00a6a41186a280200450d00200841f40a6a280200102920082802a001210d0b200c201341086a290200370300200841d0006a41086a200841cc026a280200360200200820132902003703c002200820082902c40237035020082802ac01210e20082802a801210520082802a4012109200828029c012104200828029801210c02402008280270220f450d00200841f4006a280200450d00200f10290b200841e00a6a41086a200841d0006a41086a280200220f3602002008200829035022023703e00a200841c0026a41086a200f360200200820023703c0022010200841c0026a10e6012008200c200d41e8006c6a3602cc022008200c3602c802200820043602c4022008200c3602c002200141386a200841c0026a102c20082009200e41a8016c6a3602cc02200820093602c802200820053602c402200820093602c002200141c4006a200841c0026a1026200041196a200841c8006a290300370000200041116a200841c0006a290300370000200041096a200841306a41086a29030037000020002008290330370001200041003a00000c020b200841a0026a41086a280200210120082802a402210f200d280200450d00200841f40a6a28020010290b024020082802702209450d00200841f4006a280200450d00200910290b2008280288012105200828028001210902400240200828028401220d0d002009210c0c010b200d210e2009210c0340200c2802880b210c200e417f6a220e0d000b0340200920092f01064102746a41880b6a2802002109200d417f6a220d0d000b0b200841dc026a20092f0106360200200841d8026a4100360200200841d4026a2009360200200820053602e002200841003602d002200842003703c8022008200c3602c402200841003602c002200841c0026a10d901024020082802a001220c450d002008280298012109200c41e8006c210c03400240200941dc006a280200450d00200941d8006a28020010290b024020092d00004105490d00200941286a280200450d00200941246a28020010290b200941e8006a2109200c41987f6a220c0d000b0b0240200828029c01450d0020082802980110290b024020082802ac012209450d00200941a8016c210c20082802a40141206a210903402009103d200941a8016a2109200c41d87e6a220c0d000b0b024020082802a801450d0020082802a40110290b200041086a2001360200200041046a200f360200200041013a00000b200841c00d6a24000bff18012e7f230041b00d6b220324002003200236020420032001360200200341086a41086a220142003703002003420037030841e28fc3004115200341086a1004200341900d6a41086a2001290300370300200320032903083703900d200341e80c6a200341900d6a10ba02024002400240024020032802ec0c22040d0041012104410021050c010b20032802f00c2105200341e80c6a410c6a28020022020d010b20004200370000200041186a4200370000200041106a4200370000200041086a42003700000c010b20032c00e80c2101200341086a410041e00c10cd041a200441206a21064100210741002108410021094100210a4100210b4100210c4100210d4100210e4100210f410021104100211141002112410021134100211441002115410021164100211741002118410021194100211a4100211b4100211c4100211d4100211e4100211f41002120410021214100212241002123410021244100212541002126200420024105746a22272128200421294100212a41d100212b02400340202a212c0240024002402001450d00024020042027460d00200141016a212d20282102202921010340202720022001200246222e1b210220272028202e1b212820042001202e1b222e41206a2101202d417f6a222d0d000c030b0b200141016a2101034020282029460d05202941206a21292001417f6a22010d000b202941606a212e202921010c010b024020292028460d00202941206a21012029212e0c020b20042027460d0320272128200621012004212e0b202e450d020b200121292003280204212d2003280200212f200341003602980d200342013703900d02400240024002400240410110272201450d002001202c3a000020034281808080103702940d200320013602900d2003202d36028c0d2003418c0d6a200341900d6a10300240024020032802940d220220032802980d22306b202d490d0020032802900d21010c010b2030202d6a22012030490d042002410174222a20012001202a491b222a4100480d040240024020020d00202a102721010c010b20032802900d2002202a102821010b2001450d022003202a3602940d200320013602900d202a21020b20032030202d6a222a3602980d200120306a202f202d10ce041a024002402002202a6b4120490d00202a41206a21300c010b202a41206a2230202a490d042002410174222d20302030202d491b222d4100480d040240024020020d00202d102721010c010b20012002202d102821010b2001450d032003202d3602940d200320013602900d202d21020b2001202a6a222d202e290000370000202d41186a202e41186a290000370000202d41106a202e41106a290000370000202d41086a202e41086a290000370000200341900d6a41186a222e4200370300200341900d6a41106a222d4200370300200341900d6a41086a222a4200370300200342003703900d20012030200341900d6a1000200341e80c6a41186a2230202e290300370300200341e80c6a41106a222e202d290300370300200341e80c6a41086a222d202a290300370300200320032903900d3703e80c02402002450d00200110290b202b417f6a212b202c41016a212a200341086a202c4103704105746a220120032903e80c370000200141186a2030290300370000200141106a202e290300370000200141086a202d290300370000410021020340202c202c41036e222e417d6c6a4102470d05200341086a20026a220141df006a2d0000222d2001411f6a2d0000220771202d2007722001413f6a2d00007172211e200141de006a2d0000222d2001411e6a2d0000220771202d2007722001413e6a2d00007172211d200141dd006a2d0000222d2001411d6a2d0000220771202d2007722001413d6a2d00007172211c200141dc006a2d0000222d2001411c6a2d0000220771202d2007722001413c6a2d00007172211b200141db006a2d0000222d2001411b6a2d0000220771202d2007722001413b6a2d00007172211a200141da006a2d0000222d2001411a6a2d0000220771202d2007722001413a6a2d000071722119200141d9006a2d0000222d200141196a2d0000220771202d200772200141396a2d000071722118200141d8006a2d0000222d200141186a2d0000220771202d200772200141386a2d000071722117200141d7006a2d0000222d200141176a2d0000220771202d200772200141376a2d000071722116200141d6006a2d0000222d200141166a2d0000220771202d200772200141366a2d000071722115200141d5006a2d0000222d200141156a2d0000220771202d200772200141356a2d000071722114200141d4006a2d0000222d200141146a2d0000220771202d200772200141346a2d000071722113200141d3006a2d0000222d200141136a2d0000220771202d200772200141336a2d000071722112200141d2006a2d0000222d200141126a2d0000220771202d200772200141326a2d000071722111200141d1006a2d0000222d200141116a2d0000220771202d200772200141316a2d000071722110200141d0006a2d0000222d200141106a2d0000220771202d200772200141306a2d00007172210f200141cf006a2d0000222d2001410f6a2d0000220771202d2007722001412f6a2d00007172210e200141ce006a2d0000222d2001410e6a2d0000220771202d2007722001412e6a2d00007172210d200141cd006a2d0000222d2001410d6a2d0000220771202d2007722001412d6a2d00007172210c200141cc006a2d0000222d2001410c6a2d0000220771202d2007722001412c6a2d00007172210b200141cb006a2d0000222d2001410b6a2d0000220771202d2007722001412b6a2d00007172210a200141ca006a2d0000222d2001410a6a2d0000220771202d2007722001412a6a2d000071722109200141c9006a2d0000222d200141096a2d0000220771202d200772200141296a2d000071722108200141c8006a2d0000222d200141086a2d0000220771202d200772200141286a2d000071722107200141c7006a2d0000222d200141076a2d0000221f71202d201f72200141276a2d00007172211f200141c6006a2d0000222d200141066a2d0000222071202d202072200141266a2d000071722120200141c5006a2d0000222d200141056a2d0000222171202d202172200141256a2d000071722121200141c4006a2d0000222d200141046a2d0000222271202d202272200141246a2d000071722122200141c3006a2d0000222d200141036a2d0000222371202d202372200141236a2d000071722123200141c2006a2d0000222d200141026a2d0000222471202d202472200141226a2d000071722124200141c1006a2d0000222d200141016a2d0000222571202d202572200141216a2d000071722125200141c0006a2d0000222d20012d0000222671202d202672200141206a2d000071722126200241800c460d05200341086a2002202e410574202c41096e41e0006c6b6a6a220141ff006a201e3a0000200141fe006a201d3a0000200141fd006a201c3a0000200141fc006a201b3a0000200141fb006a201a3a0000200141fa006a20193a0000200141f9006a20183a0000200141f8006a20173a0000200141f7006a20163a0000200141f6006a20153a0000200141f5006a20143a0000200141f4006a20133a0000200141f3006a20123a0000200141f2006a20113a0000200141f1006a20103a0000200141f0006a200f3a0000200141ef006a200e3a0000200141ee006a200d3a0000200141ed006a200c3a0000200141ec006a200b3a0000200141eb006a200a3a0000200141ea006a20093a0000200141e9006a20083a0000200141e8006a20073a0000200141e7006a201f3a0000200141e6006a20203a0000200141e5006a20213a0000200141e4006a20223a0000200141e3006a20233a0000200141e2006a20243a0000200141e1006a20253a0000200141e0006a20263a0000202e212c200241e0006a220241e00c470d000c050b0b41014101102a000b202a4101102a000b202d4101102a000b102b000b41002101202b0d000b0b2000201e3a001f2000201d3a001e2000201c3a001d2000201b3a001c2000201a3a001b200020193a001a200020183a0019200020173a0018200020163a0017200020153a0016200020143a0015200020133a0014200020123a0013200020113a0012200020103a00112000200f3a00102000200e3a000f2000200d3a000e2000200c3a000d2000200b3a000c2000200a3a000b200020093a000a200020083a0009200020073a00082000201f3a0007200020203a0006200020213a0005200020223a0004200020233a0003200020243a0002200020253a0001200020263a00000b02402005450d00200410290b200341b00d6a24000b850804057f017e017f017e02400240024002402002450d00410020016b410020014103711b2103200241796a4100200241074b1b210441002105034002400240200120056a2d000022064118744118752207417f4a0d0042808080801021080240200641a6d4c5006a2d0000417e6a220941024d0d0042808080808020210a0c070b0240024002400240024020090e03000102000b200541016a22062002490d024200210a0c090b4200210a200541016a220920024f0d08200120096a2d0000210902400240200641a07e6a2206410d4b0d000240024020060e0e0002020202020202020202020201000b200941e0017141a001460d0242808080808020210a0c0c0b02402009411874411875417f4c0d0042808080808020210a0c0c0b200941ff017141a001490d0142808080808020210a0c0b0b02402007411f6a41ff0171410b4b0d0002402009411874411875417f4c0d0042808080808020210a0c0c0b200941ff017141c001490d0142808080808020210a0c0b0b0240200941ff017141bf014d0d0042808080808020210a0c0b0b0240200741fe017141ee01460d0042808080808020210a0c0b0b2009411874411875417f4c0d0042808080808020210a0c0a0b42002108200541026a220620024f0d09200120066a2d000041c00171418001460d020c070b4200210a200541016a220920024f0d07200120096a2d0000210902400240200641907e6a220641044b0d000240024020060e050002020201000b200941f0006a41ff01714130490d0242808080808020210a0c0b0b02402009411874411875417f4c0d0042808080808020210a0c0b0b200941ff0171419001490d0142808080808020210a0c0a0b0240200941ff017141bf014d0d0042808080808020210a0c0a0b02402007410f6a41ff017141024d0d0042808080808020210a0c0a0b2009411874411875417f4c0d0042808080808020210a0c090b200541026a220620024f0d07200120066a2d000041c00171418001470d0642002108200541036a220620024f0d08200120066a2d000041c00171418001460d01428080808080e000210a42808080801021080c080b42808080808020210a4280808080102108200120066a2d000041c00171418001470d070b200641016a21050c010b0240200320056b4103710d000240200520044f0d000340200120056a220641046a280200200628020072418081828478710d01200541086a22052004490d000b0b200520024f0d010340200120056a2c00004100480d022002200541016a2205470d000c040b0b200541016a21050b20052002490d000b0b20002001360204200041086a2002360200200041003602000f0b428080808080c000210a42808080801021080c010b420021080b2000200a2008842005ad84370204200041013602000ba00501097f230041206b22052400024002400240200128020041016a220641004c0d0020012006360200200141086a2802002107200141046a220821060340200628020022092f0106220a410574210b410021064100210c0240024002400340200b2006460d0102402002200920066a41086a412010d004220d0d00410021060c030b200641206a2106200c41016a210c200d417f4a0d000b200c417f6a210a0b20070d014101210641002107200a210c0b200541186a200c360200200541146a2008360200200541086a41086a20093602002005200736020c2005200636020820060d032009200c41e0006c6a2206419c036a280200210720064198036a2208210602400340200628020022092f0106220a410574210b410021064100210c02400240024002400340200b2006460d0102402004200920066a41086a412010d004220d0d00410021060c030b200641206a2106200c41016a210c200d417f4a0d000b200c417f6a210a0b20070d014101210641002107200a210c0b200541186a200c360200200541086a410c6a2008360200200541106a20093602002005200736020c2005200636020820060d0702400240200941e8026a2206200c410c6c6a280200220d0d004100210c0c010b2006200c410c6c6a2802082206417f4c0d02024020060d004101210c0c010b20061027220c450d04200c200d200610ce041a0b200020063602042000200c360200200041086a20063602000c080b2007417f6a21072009200a4102746a41ec036a21060c010b0b1039000b20064101102a000b2007417f6a21072009200a4102746a41880b6a21060c000b0b41d8a8c1004118200541086a4180a9c10010a201000b20002001280210200220032004200141146a28020028020c1106000b20012001280200417f6a360200200541206a24000b8f1901187f230041d0116b2202240020002802102203200328020041016a360200200028020c21042000280208210520002802042103200241206a41186a22062000412c6a290000370300200241206a41106a2207200041246a290000370300200241206a41086a22082000411c6a29000037030020022000290014370320200241a0026a200141e00010ce041a024002400240024020032f01062201410b490d00200241b0036a410041e00210cd041a20024198066a410041a00810cd041a0240024041880b10272209450d00200941003b010620094100360200200941086a200241b0036a41e00210ce042101200941e8026a20024198066a41a00810ce042106200220032f00c8013b01ac032002200341ca016a2d00003a00ae03200220032900db01370398032002200341e0016a29000037009d03200341cb016a280000210a200341cf016a280000210b200341d3016a280000210c200341d7016a280000210d20024198066a200341a8076a41e00010ce041a2001200341e8016a20032f010641796a220041057410ce042101200620034188086a200041e0006c10ce042106200341063b0106200920003b0106200220022f01ac033b019403200220022d00ae033a0096032002200229039803370380032002200229009d0337008503200241b0036a20024198066a41e00010ce041a0240024020044107490d00200441057420016a41c07e6a2001200441796a22074105746a2201200041ffff037120076b41057410cf041a200141186a200241206a41186a290300370000200141106a200241206a41106a290300370000200141086a200241206a41086a29030037000020012002290320370000200441e0006c20066a220041c07b6a200041e07a6a220e200941066a22002f010020076b41e0006c10cf041a200e200241a0026a41e00010ce041a0c010b200341086a20044105746a220141206a2001200341066a22002f010020046b41057410cf041a200141186a200241206a41186a290300370000200141106a200241206a41106a290300370000200141086a200241206a41086a29030037000020012002290320370000200341e8026a200441e0006c6a220e41e0006a200e20002f010020046b41e0006c10cf041a200e200241a0026a41e00010ce041a0b20024188026a41026a220420022d0096033a0000200020002f010041016a3b0100200220022f0194033b01880220022002290380033703800120022002290085033700850120024190016a200241b0036a41e00010ce041a2002411c6a41026a220f20042d00003a0000200220022f0188023b011c2002200229038001370308200220022900850137000d200241206a20024190016a41e00010ce041a20032802002206450d0320032f0104211020024198066a410272211103402002419c026a41026a2212200f2d00003a0000200220022f011c3b019c0220022002290308370388022002200229000d37008d02200241a0026a200241206a41e00010ce041a201041ffff0371210702400240024020062f01062203410b490d002011410041b20b10cd041a41b80b10272201450d0520014100360200200141046a20024198066a41b40b10ce041a200220062f00c8013b01ac032002200641ca016a2d00003a00ae03200220062900db01370398032002200641e0016a29000037009d03200641cb016a2800002113200641cf016a2800002114200641d3016a2800002115200641d7016a280000211620024198066a200641a8076a41e00010ce041a200141086a200641e8016a20062f0106220041796a220341057410ce042117200141e8026a20064188086a200341e0006c10ce042118200141880b6a200641a40b6a2000417a6a220841027410ce042119200641063b0106200120033b010602402008450d00410021032019210003402000280200220420033b010420042001360200200041046a21002008200341016a2203470d000b0b200241b0036a20024198066a41e00010ce041a200220022d00ae0322033a009603200220022f01ac0322003b0194032002200229009d033700850320022002290398033703800320024194066a41026a220820033a0000200220003b01940620022002290380033703800120022002290085033700850120024198066a200241b0036a41e00010ce041a201041ffff037122004107490d0120172007417a6a22044105746a2017200741796a22034105746a220020012f010620036b41057410cf041a200041186a200229008d023700002000200d36000f2000200c36000b2000200b3600072000200a360003200041026a20122d00003a0000200020022f019c023b00002000200229038802370013200741e0006c20186a220041c07b6a200041e07a6a220020012f010620036b41e0006c10cf041a2000200241a0026a41e00010ce041a200120012f010641016a22003b01062007410274220a20196a416c6a201920044102746a2210200041ffff0371220720046b41027410cf041a2010200936020020072004490d022001200a6a41f00a6a2100034020002802002204200341016a22033b010420042001360200200041046a210020032007490d000c030b0b200641086a2200200741016a22044105746a200020074105746a2200200320076b220141057410cf041a2000200d36000f2000200c36000b2000200b3600072000200a360003200041026a2002419c026a41026a2d00003a0000200020022f019c023b00002000200229038802370013200041186a200229008d023700002006200741e0006c6a220041c8036a200041e8026a2200200141e0006c10cf041a2000200241a0026a41e00010ce041a2006200341016a22033b01062007410274200641880b6a22006a41086a200020044102746a2200200341ffff037120046b41027410cf041a20002009360200201041ffff037120062f010622034f0d07200920043b010420092006360200200420034f0d072003417f6a210120062004417f6a22034102746a41900b6a2100034020002802002204200341026a3b010420042006360200200041046a21002001200341016a2203470d000c080b0b200641086a2203200741016a22044105746a200320074105746a220320062f0106221020076b221941057410cf041a2003200d36000f2003200c36000b2003200b3600072003200a360003200341026a20122d00003a0000200320022f019c023b00002003200229038802370013200341186a200229008d02370000200641e8026a200741e0006c6a220341e0006a2003201941e0006c10cf041a2003200241a0026a41e00010ce041a2006201041016a22033b010620074102742219200641880b6a22106a41086a201020044102746a2210200341ffff037120046b41027410cf041a20102009360200200020062f010622044f0d00200620196a418c0b6a2103034020032802002200200741016a22073b010420002006360200200341046a210320042007470d000b0b20024184026a41026a220320082d00003a0000200220022f0194063b01840220022002290380013703f00120022002290085013700f50120024190016a20024198066a41e00010ce041a200f20032d00003a0000200220022f0184023b011c200220022903f001370308200220022900f50137000d200241206a20024190016a41e00010ce041a0240200628020022030d002013210a2016210d2015210c2014210b200121090c050b20062f010421102013210a2016210d2015210c2014210b20032106200121090c000b0b41880b4108102a000b41b80b4108102a000b200320044105746a220041286a200041086a2210200120046b41057410cf041a200041206a2006290300370000200041186a2007290300370000200041106a2008290300370000201020022903203700002003200441e0006c6a220041c8036a200041e8026a220e20032f010620046b41e0006c10cf041a200e200241a0026a41e00010ce041a200320032f010641016a3b01060c010b20024198066a410272410041b20b10cd041a41b80b10272203450d0120034100360200200341046a20024198066a41b40b10ce041a2003200528020022003602880b200520033602002005200528020441016a360204200041003b010420002003360200200320032f010622044105746a220041086a20022f011c3b00002000410a6a2002411c6a41026a2d00003a0000200041176a200d360000200041136a200c3600002000410f6a200b3600002000410b6a200a3600002000411b6a2002290308370000200041206a200229000d3700002003200441e0006c6a41e8026a200241206a41e00010ce041a200341880b6a200441016a22004102746a2009360200200320003b0106200920003b0104200920033602000b200241d0116a2400200e0f0b41b80b4108102a000bc31e03087f037e127f23004180076b22042400200441e0006a41186a200241186a290000370300200441e0006a41106a200241106a290000370300200441e0006a41086a200241086a2900003703002004200229000037036002400240024002400240024002400240024020012802002205418883c000460d00200128020421060c010b41002106200441e8026a410041e00210cd041a200441c0016a410041840110cd041a41ec0310272205450d01200541003b010620054100360200200541086a200441e8026a41e00210ce041a200541e8026a200441c0016a41840110ce041a20014100360204200120053602000b02400340200541086a2107200541066a210820052f0106220941057421024100210a0240024003402002450d01200441e0006a2007412010d004220b450d02200241606a2102200a41016a210a200741206a2107200b417f4a0d000b200a417f6a21090b2006450d022006417f6a2106200520094102746a41ec036a28020021050c010b0b200441e8026a41086a22022005200a410c6c6a220741f0026a220a2802003602002004200741e8026a22072902003703e80220072003290200370200200a200341086a280200360200200441c0016a41086a20022802002202360200200420042903e802220c3703c0012000410c6a20023602002000200c370204200041013602000c060b200441086a41186a220b200441e0006a41186a2202290300370300200441086a41106a200441e0006a41106a2207290300220c370300200441086a41086a200441e0006a41086a220a290300220d37030020042004290360220e3703082001200128020841016a3602082007200c370300200a200d3703002002200b2903003703002004200e370360200441d8026a41086a2206200341086a280200360200200420032902003703d802024020082f01002203410b490d00200441e8026a410041e00210cd041a200441c0016a410041840110cd041a41ec031027220f450d02200f41003b0106200f4100360200200f41086a200441e8026a41e00210ce042107200f41e8026a200441c0016a41840110ce04210a200441e8026a41086a220b200541b8036a280200360200200420052900db013703a8012004200541e0016a2900003700ad01200420052902b0033703e802200420052f00c8013b01bc012004200541ca016a2d00003a00be01200541cb016a2800002110200541cf016a2800002111200541d3016a2800002112200541d7016a28000021132007200541e8016a20052f010641796a220241057410ce042107200a200541bc036a2002410c6c10ce04210a200541063b0106200f20023b0106200420042f01bc013b01a401200420042d00be013a00a601200420042903a8013703c001200420042900ad013700c501200441286a41086a200b280200360200200420042903e8023703280240024020094107490d00200941057420076a41c07e6a2007200941796a220b4105746a2207200241ffff0371200b6b41057410cf041a200741186a200441e0006a41186a290300370000200741106a200441e0006a41106a290300370000200741086a200441e0006a41086a290300370000200720042903603700002009410c6c200a6a220241b87f6a200241ac7f6a2202200f41066a22082f0100200b6b410c6c10cf041a200241086a200441d8026a41086a280200360200200220042903d8023702000c010b200541086a20094105746a220241206a200220082f010020096b41057410cf041a200241186a200441e0006a41186a290300370000200241106a200441e0006a41106a290300370000200241086a200441e0006a41086a29030037000020022004290360370000200541e8026a2009410c6c6a2202410c6a200220082f010020096b410c6c10cf041a200241086a200441d8026a41086a280200360200200220042903d8023702000b200820082f010041016a3b010020044198016a41026a220220042d00a6013a0000200441c8026a41086a2214200441286a41086a280200360200200420042f01a4013b019801200420042903c001370350200420042900c501370055200420042903283703c8022004413c6a41026a221520022d00003a0000200420042f0198013b013c2004200429005537002d20042004290350370328200441c0006a41086a22162014280200360200200420042903c80237034020052802002206450d0420052f01042103200441e8026a4102722117034020044194016a41026a221820152d00003a0000200420042f013c3b019401200420042903283703602004200429002d37006520044198016a41086a221920162802003602002004200429034037039801200341ffff0371210502400240024020062f01062202410b490d002017410041960410cd041a419c041027220b450d07200b4100360200200b41046a200441e8026a41980410ce041a200420062f00c8013b01bc012004200641ca016a2d00003a00be012004200641db016a2900003703a8012004200641e0016a2900003700ad01200641cb016a280000211a200641cf016a280000211b200641d3016a280000211c200641d7016a280000211d200441e8026a41086a221e200641b8036a2802003602002004200641b0036a2902003703e802200b41086a200641e8016a20062f0106220741796a220241057410ce04211f200b41e8026a200641bc036a2002410c6c10ce042120200b41ec036a20064188046a2007417a6a220941027410ce042108200641063b0106200b20023b010602402009450d00410021022008210703402007280200220a20023b0104200a200b360200200741046a21072009200241016a2202470d000b0b200441d8026a41086a2202201e280200360200200420042d00be0122073a00a601200420042f01bc01220a3b01a401200420042903a8013703c001200420042900ad013700c501200420042903e8023703d802200441c4026a41026a220920073a00002004200a3b01c402200420042903c0013703e802200420042900c5013700ed0220142002280200360200200420042903d8023703c802200341ffff037122074107490d01201f2005417a6a220a4105746a201f200541796a22024105746a2207200b2f010620026b41057410cf041a200741186a20042900653700002007201336000f2007201236000b2007201136000720072010360003200741026a20182d00003a0000200720042f0194013b0000200720042903603700132005410c6c20206a220741b87f6a200741ac7f6a2207200b2f0106220320026b410c6c10cf041a200741086a20192802003602002007200429039801370200200b200341016a22073b01062005410274221020086a416c6a2008200a4102746a2203200741ffff03712205200a6b41027410cf041a2003200f3602002005200a490d02200b20106a41d4036a210703402007280200220a200241016a22023b0104200a200b360200200741046a210720022005490d000c030b0b200641086a2207200541016a220a4105746a200720054105746a2207200220056b41057410cf041a200741186a20042900653700002007201336000f2007201236000b2007201136000720072010360003200741026a20044194016a41026a2d00003a0000200720042f0194013b00002007200429036037001320062005410c6c6a220241f4026a200241e8026a220720062f0106220b20056b410c6c10cf041a200241f0026a20044198016a41086a28020036020020072004290398013702002006200b41016a22023b01062005410274200641ec036a22076a41086a2007200a4102746a2207200241ffff0371220b200a6b41027410cf041a2007200f360200200341ffff0371200b4f0d082006200a417f6a22024102746a41f0036a210703402007280200220a200241016a22023b0104200a2006360200200741046a21072002200b490d000c090b0b200641086a2202200541016a22034105746a200220054105746a220220062f010620056b41057410cf041a200241186a20042900653700002002201336000f2002201236000b2002201136000720022010360003200241026a20182d00003a0000200220042f0194013b000020022004290360370013200641e8026a2005410c6c6a2202410c6a200220062f0106220a20056b410c6c10cf041a200241086a201928020036020020022004290398013702002006200a41016a22023b010620054102742210200641ec036a220a6a41086a200a20034102746a2208200241ffff0371220a20036b41027410cf041a2008200f3602002007200a4f0d00200620106a41f0036a2102034020022802002207200541016a22053b010420072006360200200241046a2102200a2005470d000b0b20044190016a41026a220220092d00003a000020044180016a41086a22072014280200360200200420042f01c402220a3b019001200420042903e802370350200420042900ed02370055200420042903c80237038001201520022d00003a00002004200a3b013c2004200429005537002d200420042903503703282016200728020036020020042004290380013703400240200628020022020d00201a2110201d2113201c2112201b2111200b210f0c060b20062f01042103201a2110201d2113201c2112201b211120022106200b210f0c000b0b200520094105746a220b41286a200b41086a2201200320096b41057410cf041a200b41206a2002290300370000200b41186a2007290300370000200b41106a200a2903003700002001200429036037000020052009410c6c6a220241f4026a200241e8026a220720052f010620096b410c6c10cf041a200241f0026a2006280200360200200720042903d802370200200520052f010641016a3b01060c040b41ec034104102a000b41ec034104102a000b419c044104102a000b200441e8026a410272410041960410cd041a419c0410272202450d0220024100360200200241046a200441e8026a41980410ce041a2002200128020022073602ec03200120023602002001200128020441016a360204200741003b010420072002360200200220022f0106220a4105746a220741086a20042f013c3b00002007410a6a2004413c6a41026a2d00003a0000200741176a2013360000200741136a20123600002007410f6a20113600002007410b6a20103600002007411b6a2004290328370000200741206a200429002d3700002002200a410c6c6a220741f0026a200441c0006a41086a280200360200200741e8026a2004290340370200200241ec036a200a41016a22074102746a200f360200200220073b0106200f20073b0104200f20023602000b200041003602000b20044180076a24000f0b419c044104102a000bde2003167f037e067f230041c0026b220424000240024020014115490d0041012105410121060240024002400340200121072000210820052006712109024002400240024002400240034002400240024002402003450d00024020054101710d002000200110db032003417f6a21030b2001410276220a41036c210b200a410174210c4100210d024020014132490d00200a200a417f6a220d2000200a4105746a2000200d4105746a412010d004220e410048220f1b2210200a41016a2211200d200a200f1b220a200020114105746a2000200a4105746a412010d00441004822111b220a2000200a4105746a200020104105746a412010d00422104100481b210a200c200c417f6a220d2000200c4105746a2000200d4105746a412010d004221241004822131b2214200c4101722215200d200c20131b220c200020154105746a2000200c4105746a412010d00422134100481b220c2000200c4105746a200020144105746a412010d00422144100481b210c200b200b417f6a220d2000200b4105746a2000200d4105746a412010d004221541004822161b2217200b41016a2218200d200b20161b220b200020184105746a2000200b4105746a412010d004220d4100481b220b2000200b4105746a200020174105746a412010d00422164100481b210b41024101200f1b200e411f7620111b2010411f766a2012411f766a2013411f766a2014411f766a2015411f766a200d411f766a2016411f766a210d0b2000200c4105746a2000200a4105746a412010d004220f411f76200d6a2000200b4105746a2000200a200c200f410048220f1b220e4105746a412010d0042210411f766a210d2000200b200e20104100481b220b4105746a2000200c200a200f1b22194105746a412010d004417f4c0d01200b21190c020b2000200110dc030c0f0b200d41016a220d410c490d0002402001410176220b450d00200020014105746a41606a210a2000210c0340200441206a41186a220d200c41186a220f290000370300200441206a41106a220e200c41106a2210290000370300200441206a41086a2211200c41086a22122900003703002004200c290000370320200a41086a2213290000211a200a41106a2214290000211b200a41186a2215290000211c200c200a290000370000200f201c3700002010201b3700002012201a3700002015200d2903003700002014200e29030037000020132011290300370000200a2004290320370000200a41606a210a200c41206a210c200b417f6a220b0d000b0b20012019417f736a21194101210a0c010b200d45210a0b02402009417f73200a45724101710d002000200110dd030d0d0b2002450d02201920014f0d0102402002200020194105746a220a412010d00441004e0d0020002108200121070c040b200441206a41186a2212200041186a220e290000370300200441206a41106a2213200041106a2210290000370300200441206a41086a2214200041086a221129000037030020042000290000370320200a41086a220c290000211a200a41106a220b290000211b200a41186a220d290000211c2000200a290000370000200e201c3700002010201b3700002011201a370000200d2012290300370000200b2013290300370000200c2014290300370000200a2004290320370000200441c0016a41186a2217200e290000370300200441c0016a41106a22182010290000370300200441c0016a41086a22192011290000370300200420002900003703c001200041606a2115200041206a21164100210c2001210b03400240200c200b417f6a220d4f0d002016200c4105746a210a0340200441c0016a200a412010d004417f4c0d01200a41206a210a200d200c41016a220c470d000b200d210c0b2015200b4105746a210a02400340200c200b417f6a220b4f0d01200441c0016a200a412010d004210d200a41606a220f210a200d4100480d000b20122016200c4105746a220a41186a220d2900003703002013200a41106a221d2900003703002014200a41086a22062900003703002004200a290000370320200f41286a221e290000211a200f41306a221f290000211b200f41386a2220290000211c200a200f41206a220f290000370000200d201c370000201d201b3700002006201a37000020202012290300370000201f2013290300370000201e2014290300370000200f2004290320370000200c41016a210c0c010b0b200020042903c001370000200e2017290300370000201020182903003700002011201929030037000002402001200c41016a220a490d002000200a4105746a21002001200a6b220141154f0d010c0c0b0b200a2001103e000b41ec81c500201920011037000b2007450d010b201920074f0d01200441206a41186a2216200841186a221e290000370300200441206a41106a2217200841106a221f290000370300200441206a41086a2218200841086a222029000037030020042008290000370320200820194105746a220a41086a220c290000211a200a41106a220b290000211b200a41186a220d290000211c2008200a290000370000201e201c370000201f201b3700002020201a370000200d2016290300370000200b2017290300370000200c2018290300370000200a2004290320370000200441186a2205201e290000370300200441106a2209201f290000370300200441086a2221202029000037030020042008290000370300200841206a21014100211d2007417f6a220d450d022001210a0340200a2004412010d00441004e0d03200a41206a210a200d201d41016a221d470d000b200d211d0c020b41b481c500410041001037000b41c481c500201920071037000b200820074105746a210c200d210b02400340200c2100200b220a201d4d22060d01200a417f6a210b200041606a220c2004412010d004417f4a0d000b0b0240200a201d490d00200d200a490d0241800121144100210f410021124100210d4100211141800121152001201d4105746a2222210103400240200020016b220a419fc0004b22190d00200a410576220a41807f6a200a2012200f492011200d49220c72220b1b210a0240200b450d002015200a200c1b2115200a2014200c1b21140c010b200a200a41017622156b21140b02402011200d470d00024020150d00200441c0006a220d21110c010b4100210a200441c0006a2211210d2001210c0340200d200a3a0000200d200c2004412010d004417f73411f766a210d200c41206a210c2015200a41016a220a470d000b0b02402012200f470d00024020140d00200441c0016a220f21120c010b200041606a210a4100210c200441c0016a2212210f0340200f200c3a0000200f200a2004412010d004411f766a210f200a41606a210a2014200c41016a220c470d000b0b0240200f20126b220a200d20116b220c200c200a4b1b2213450d002016200120112d00004105746a220a41186a2900003703002017200a41106a2900003703002018200a41086a2900003703002004200a290000370320200120112d00004105746a220a200020122d0000417f734105746a220c290000370000200a41186a200c41186a290000370000200a41106a200c41106a290000370000200a41086a200c41086a290000370000024020134101460d004100210a034020002012200a6a220e2d0000417f734105746a220c20012011200a6a41016a22102d00004105746a220b290000370000200c41186a200b41186a290000370000200c41106a200b41106a290000370000200c41086a200b41086a290000370000200120102d00004105746a220c2000200e41016a2d0000417f734105746a220b290000370000200c41186a200b41186a290000370000200c41106a200b41106a290000370000200c41086a200b41086a290000370000200a41026a210c200a41016a220b210a200c2013490d000b2012200b6a21122011200b6a21110b200020122d0000417f734105746a220a2004290320370000200a41186a2016290300370000200a41106a2017290300370000200a41086a2018290300370000201241016a2112201141016a21110b200020144105746b20002012200f461b2100200120154105746a20012011200d461b210120190d000b024002402011200d4f0d002000210a034020162001200d417f6a220d2d00004105746a220c41186a220b2900003703002017200c41106a220f2900003703002018200c41086a22002900003703002004200c290000370320200a41606a220a41086a220e290000211a200a41106a2210290000211b200a41186a2212290000211c200c200a290000370000200b201c370000200f201b3700002000201a3700002012201629030037000020102017290300370000200e2018290300370000200a20042903203700002011200d490d000c020b0b2001210a2012200f4f0d000340200f417f6a220f2d0000210c2016200a41186a220b2900003703002017200a41106a220d2900003703002018200a41086a22012900003703002004200a2900003703202000200c417f734105746a220c41086a220e290000211a200c41106a2210290000211b200c41186a2211290000211c200a200c290000370000200b201c370000200d201b3700002001201a3700002011201629030037000020102017290300370000200e2018290300370000200c2004290320370000200a41206a210a2012200f490d000b0b20082004290300370000201e2005290300370000201f2009290300370000202020212903003700002007200a20226b410576201d6a22014d0d032016201e2900003703002017201f2900003703002018202029000037030020042008290000370320200820014105746a220a41086a220c290000211a200a41106a220b290000211b200a41186a220d290000211c2008200a290000370000201e201c370000201f201b3700002020201a370000200d2016290300370000200b2017290300370000200c2018290300370000200a2004290320370000200720016b220c450d04200c20012001200c4b1b210b2007410376210d200a41206a2100024002402001200c417f6a220c490d002000200c200a200310e001200821000c010b200820012002200310e001200a2102200c21010b200b200d4f2105200141154f0d010c050b0b201d200a103e000b200a200d107f000b41c481c500200120071037000b41d481c5001058000b20014102490d00200041606a210f4101210b0340200b410574210a200b417f6a210c200b41016a210b02402000200a6a220a2000200c4105746a220d412010d004417f4a0d00200441c0016a41186a220e200a41186a2210290000370300200441c0016a41106a2211200a41106a2212290000370300200441c0016a41086a2213200a41086a22142900003703002004200a2900003703c001200a200d2900003700002014200d41086a2900003700002012200d41106a2900003700002010200d41186a2900003700004100210d0240200c450d00200f210a03400240200441c0016a200a412010d0044100480d00200c210d0c020b200a41206a200a290000370000200a41386a200a41186a290000370000200a41306a200a41106a290000370000200a41286a200a41086a290000370000200a41606a210a200c417f6a220c0d000b0b2000200d4105746a220a20042903c001370000200a41186a200e290300370000200a41106a2011290300370000200a41086a20132903003700000b200f41206a210f200b2001470d000b0b200441c0026a24000bf51602097f027e23004180046b2209240020092004370310200920033703082009200536021c2009200736022420092006360220024002400240024002400240024002400240024002402001280234200128025022062802b801460d002005420020052903082203200641386a2903007d2204200420035622061b37030802400240024020060d00200941d8006a20024200410110a00120094194016a280200210a200941d8006a41386a280200210b20092d0060220641037122054103460d0120050e03020102020b200041fab6c30036020420004101360200200041086a41233602000c030b2000419db7c30036020420004101360200200041086a411936020020060d02200a450d02200b10290c020b20094198016a2802002105200941286a41186a220c200141f4006a290000370300200941286a41106a220d200141ec006a290000370300200941286a41086a220e200141e4006a2900003703002009200129005c3703284100210f41002107024020060d002005417f4c0d030240024020050d00410121070c010b200510272207450d052007200b200510ce041a0b200a450d00200b10290b200941a0016a420037030020094198016a4280808080800137030020094188016a41f8b4c300360200200941d8006a412c6a2001411c6a2210360200200941d8006a41246a4200370200200941f8006a418883c000360200200941d8006a41186a2005360200200941ec006a2005360200200941d8006a41e4006a200241086a290000370200200941d8006a41ec006a200241106a290000370200200941d8006a41f4006a200241186a29000037020020094208370390012009410036027420092007360268200920022900003702b401200920012802583602b001200920012903503703a8012009200128023441016a36028c01200129030021032009200129030837036020092003370358200941d8016a41246a200e290300370200200941d8016a412c6a200d2903003702002009418c026a200c290300370200200941d8016a41186a200841086a280200360200200920023602e001200920092903283702f401200920082902003703e8012009200941206a3602e40120092009411c6a3602dc012009200941086a3602d801200941d8016a411c6a210d0240024002400240024020092903082203200941086a41086a290300220484500d002009200928021c4100200d200220032004200941d8006a10a203200928020022020d012009280274210f20092802e00121020b200f41016a220541004c0d08200941d8016a41106a2111200941d8006a411c6a210e20092005360274200941d8006a41206a2105200941fc006a280200210b0240024003402005280200220a41086a2108200a2f0106220c4105742105410021060240024003402005450d0120022008412010d0042207450d02200541606a2105200641016a2106200841206a21082007417f4a0d000b2006417f6a210c0b200b450d02200b417f6a210b200a200c4102746a41880b6a21050c010b0b200941a0036a2208200a200641e0006c6a220541ad036a290000370300200941a8036a2206200541b5036a290000370300200941b0036a2207200541bd036a2900003703002009200541a5036a29000037039803200541a4036a2d00004101470d00200941a1026a2008290300370000200941a9026a2006290300370000200941b1026a2007290300370000200941013a0098022009200929039803370099022009200f3602740c010b20094198026a200928028401200220092802880128021011020020092009280274417f6a3602744101210620092d0098024101470d040b200941c0026a41186a200941b1026a290000370300200941c0026a41106a200941a9026a290000370300200941c0026a41086a200941a1026a29000037030020092009290099023703c00220094198036a200941c0026a20092802b001280200108402410121062009280298034101470d0220094198036a41086a2802002101200928029c0321020c010b200928020421010b200941ec016a280200450d0b20092802e80110290c0b0b200941e0036a41186a220820094198036a410472220541186a2802002207360200200941e0026a41106a200541086a290200370300200941e0026a41186a200541106a29020037030020094180036a2007360200200941043602e402200941b98fc5003602e002200920052902003703e80220092802ac0121052008200d41186a2900002203370300200941e0036a41106a200d41106a2900002204370300200941e0036a41086a2208200d41086a2900002212370300200941c4036a2012370200200941cc036a2004370200200941d4036a20033702002009200d29000022033703e003200920033702bc0320092802d801220741086a29030021032009200941d8006a3602b803200729030021042009290358211220092903602113200920033703a0032009200437039803200920133703b003200920123703a80320092802e40122072802042102200728020021072008201141086a280200360200200920112902003703e00320094188036a2005200941e0026a20094198036a20072002200941e0036a20092802dc01280200106241002102410021072009280288030e03070609070b410021070240200941ec016a280200450d0020092802e80110290b410021020c070b200041d1b6c30036020420004101360200200041086a41293602000b200841046a280200450d08200828020010290c080b1039000b20054101102a000b41d8a8c1004118200941e0026a4180a9c10010a201000b20094194036a280200210720094190036a2802002102200928028c0321060b200941f8026a280200450d00200941f4026a28020010290b20094198036a41086a220a200e41086a290200370300200941c8006a41086a220b20094198036a410c6a2802003602002009200e290200370398032009200929029c0337034820092802a401210c20092802a001210d200928029c012105200928029801210f200928029401210e2009280290012108024020092802682211450d00200928026c450d00201110290b200a200b280200220b36020020092009290348220337039803200941d8006a41086a200b360200200920033703582010200941d8006a10e60120092008200f41e8006c6a360264200920083602602009200e36025c20092008360258200141386a200941d8006a102c20092005200c41a8016c6a360264200920053602602009200d36025c20092005360258200141c4006a200941d8006a10262000410c6a2007360200200041086a200236020020002006360204200041003602000c020b20094190036a2802002101200928028c032102200941f8026a280200450d00200941f4026a28020010290b024020092802682205450d00200928026c450d00200510290b200941f8006a2802002105200928028001210a02400240200928027c22060d00200521080c010b2006210720052108034020082802880b21082007417f6a22070d000b0340200520052f01064102746a41880b6a28020021052006417f6a22060d000b0b200941b4036a20052f0106360200200941b0036a4100360200200941ac036a20053602002009200a3602b803200941003602a803200942003703a0032009200836029c03200941003602980320094198036a10d90102402009280298012208450d002009280290012105200841e8006c210803400240200541dc006a280200450d00200541d8006a28020010290b024020052d00004105490d00200541286a280200450d00200541246a28020010290b200541e8006a2105200841987f6a22080d000b0b0240200928029401450d0020092802900110290b024020092802a4012205450d00200541a8016c2108200928029c0141206a210503402005103d200541a8016a2105200841d87e6a22080d000b0b024020092802a001450d00200928029c0110290b200041086a200136020020002002360204200041013602000b20094180046a24000bcd0202097f027e230041206b220324000240200128020041016a220441004c0d0020012004360200200141046a2105200141086a28020021060240024003402005280200220741086a210820072f0106220941057421054100210a0240024003402005450d0120022008412010d004220b450d02200541606a2105200a41016a210a200841206a2108200b417f4a0d000b200a417f6a21090b2006450d022006417f6a2106200720094102746a41880b6a21050c010b0b2007200a41e0006c6a220541e8026a280200450d00200541f8026a290300210c200541f0026a290300210d0c010b200341086a20012802102002200141146a28020028021c110200200341106a290300210c200128020021042003290308210d0b20012004417f6a3602002000200c3703082000200d370300200341206a24000f0b41d8a8c1004118200341186a4180a9c10010a201000b940301097f230041206b220324000240200128020041016a220441004c0d0020012004360200200141046a2105200141086a280200210602400240024003402005280200220741086a210820072f0106220941057421054100210a0240024003402005450d0120022008412010d004220b450d02200541606a2105200a41016a210a200841206a2108200b417f4a0d000b200a417f6a21090b2006450d022006417f6a2106200720094102746a41880b6a21050c010b0b200341086a22082007200a41e0006c6a220541ad036a290000370300200341106a220a200541b5036a290000370300200341186a220b200541bd036a2900003703002003200541a5036a290000370300200541a4036a2d00004101460d010b200020012802102002200141146a280200280210110200200128020021040c010b200041013a000020002003290300370001200041096a2008290300370000200041116a200a290300370000200041196a200b2903003700000b20012004417f6a360200200341206a24000f0b41d8a8c100411820034180a9c10010a201000b950201097f230041106b220224000240200028020041016a220341004c0d0020002003360200200041046a2104200041086a28020021050240024003402004280200220641086a210720062f01062208410574210441002109024003402004450d0120012007412010d004220a450d03200441606a2104200941016a2109200741206a2107200a417f4a0d000b2009417f6a21080b02402005450d002005417f6a2105200620084102746a41880b6a21040c010b0b20002802102001200041146a2802002802181104002104200028020021030c010b2006200941e0006c6a41a4036a2d000041014621040b20002003417f6a360200200241106a240020040f0b41d8a8c1004118200241086a4180a9c10010a201000bde0202097f037e230041206b220324000240200128020041016a220441004c0d0020012004360200200141046a2105200141086a28020021060240024003402005280200220741086a210820072f0106220941057421054100210a0240024003402005450d0120022008412010d004220b450d02200541606a2105200a41016a210a200841206a2108200b417f4a0d000b200a417f6a21090b2006450d022006417f6a2106200720094102746a41880b6a21050c010b0b2007200a41e0006c6a22054180036a290300220ca7450d0020054190036a290300210d20054188036a290300210e0c010b200320012802102002200141146a280200280214110200200341106a290300210d200128020021042003290308210e2003290300210c0b20012004417f6a360200200041106a200d3703002000200e3703082000200c370300200341206a24000f0b41d8a8c1004118200341186a4180a9c10010a201000b961208057f017e107f047e017f017e0a7f047e230041800d6b22022400024020002802000d002000417f360200200128020821032001280200210402400240200128020422050d00200421010c010b2005210620042101034020012802880b21012006417f6a22060d000b0340200420042f01064102746a41880b6a28020021042005417f6a22050d000b0b200241246a20042f0106360200200241086a41186a4100360200200241086a41146a20043602002002200336022820024100360218200242003703102002200136020c2002410036020820024180026a200241086a10d501024020022903a00222074202510d002000410c6a2108200041046a2109200241a00a6a41146a210a200241a00a6a41206a210b20024180026a4104722104200241dd026a210c200241bd026a210d200241fd026a210e200241c8026a210f200241b0026a211020024180026a41286a21110340200241d0006a41086a220120024180026a41086a2212290300370300200241d0006a41106a220520024180026a41106a2213290300370300200241d0006a41186a220620024180026a41186a2214290300370300200241306a41086a2215200c41086a290000370300200241306a41106a2216200c41106a290000370300200241306a41186a2217200c41186a29000037030020022002290380023703502002200c290000370330200f29030021182010290300211920022903c002211a20022903a802211b20022d00dc02211c20022903b802211d20022802d002210320022802d402211e20022802d802211f2002412c6a41026a200e41026a2d000022203a00002002200e2f000022213b012c200241f8006a41086a22222015290300370300200241f8006a41106a22232016290300370300200241f8006a41186a22242017290300370300200241f4006a41026a222520203a000020022002290330370378200220213b017420024198016a41186a2221200629030037030020024198016a41106a2226200529030037030020024198016a41086a2227200129030037030020022002290350370398010240024002400240024020092802002216418883c000460d00200028020821170c010b200241a00a6a410041e00210cd041a20024180026a410041a00810cd041a41880b10272216450d0141002117201641003b010620164100360200201641086a200241a00a6a41e00210ce041a201641e8026a20024180026a41a00810ce041a20004100360208200020163602040b0340201641086a210520162f01062220410574210141002106024003402001450d0120024198016a2005412010d0042215450d04200141606a2101200641016a2106200541206a21052015417f4a0d000b2006417f6a21200b02402017450d002017417f6a2117201620204102746a41880b6a28020021160c010b0b200241d0016a41186a20212903002228370300200241d0016a41106a20262903002229370300200241d0016a41086a2027290300222a3703002002200229039801222b3703d001200a202b370200200a41086a202a370200200a41106a2029370200200a41186a2028370200200220083602b00a200220203602ac0a200220093602a80a200220163602a40a200241003602a00a20112018370300201320193703002002201a3703a0022002201b370388022002201c3a00bc022002201f3602b8022002201e3602b402200220033602b0022002201d370398022002200737038002200d2002290378370000200d41086a2022290300370000200d41106a2023290300370000200d41186a2024290300370000200c20022f01743b0000200c41026a20252d00003a0000200241a00a6a20024180026a10de011a0c020b41880b4108102a000b2016200641e0006c6a220641f0026a22012001290300201b20075022011b370300200641f8026a22052005290300201920011b370300200641e8026a22052005290300200720011b370300200241a00a6a41186a22152024290300370300200241a00a6a41106a22162023290300370300200241a00a6a41086a22172022290300370300200220022903783703a00a200641a4036a22052d000021202014200641bd036a22222900003703002013200641b5036a22232900003703002012200641ad036a22132900003703002002200641a5036a2224290000370380022027200241a00a6a20024180026a201c41ff0171410146221c1b220141086a2900003703002026200141106a2900003703002021200141186a2900003703002002200129000037039801200541012020201c1b3a0000202420022903980137000020132027290300370000202320262903003700002022202129030037000020064188036a2201201a2001290300201da722011b37030020064190036a22052018200529030020011b37030020064180036a2205201d200529030020011b37030002400240201e0d00200321010c010b201e210520032101034020012802ec0321012005417f6a22050d000b0340200320032f01064102746a41ec036a2802002103201e417f6a221e0d000b0b20032f010621052002201f3602b801200220053602b401200241003602b001200220033602ac01200241003602a801200242003703a0012002200136029c01200241003602980120024180026a20024198016a10d70102402002280280024101470d0020064198036a21030340200241a00a6a41286a200441286a280200360200200b200441206a2902003703002015200441186a22012902003703002016200441106a22052902003703002017200441086a2206290200370300200220042902003703a00a200241d0016a41186a2001290000370300200241d0016a41106a2005290000370300200241d0016a41086a2006290000370300200220042900003703d001200241f0016a41086a200b41086a2802003602002002200b2902003703f001200241c0016a2003200241d0016a200241f0016a10df01024020022802c001450d0020022802c4012201450d0020022802c801450d00200110290b20024180026a20024198016a10d7012002280280024101460d000b0b20024198016a10d6010b20024180026a200241086a10d50120022903a00222074202520d000b0b200241086a10d9012000200028020041016a360200200241800d6a24000f0b41c8a8c100411020024180026a41f0a8c10010a201000bd80202027f017e0240024002400240024002400240024002400240024002400240024020012802000e0400010203000b41012102410110272201450d05200141003a0000410121030c040b410110272202450d05200241013a00002001290308210420024101410910282202450d0620022004370001200129031021044112210320024109411210282201450d07200120043700090c020b41012102410110272201450d07200141023a0000410121030c020b410110272202450d07200241033a00002001290308210420024101410910282202450d0820022004370001200129031021044112210320024109411210282201450d09200120043700090b411121020b2000200236020820002003360204200020013602000f0b41014101102a000b41014101102a000b41094101102a000b41124101102a000b41014101102a000b41014101102a000b41094101102a000b41124101102a000b130020004101360204200041f4afc1003602000b3400200041f4b0c10036020420004100360200200041146a4105360200200041106a4184b1c100360200200041086a420f3702000b2501017f230041206b22022400200242003703082000200241086a10e701200241206a24000b820603037f027e017f230041206b220424004101210502402001a722064101470d002000427f2000290300220720027c220820082007542205200041086a2209290300220720037c2005ad7c220820075420082007511b22051b3703002009427f200820051b370300410021050b024002400240024020014201560d00024020060e020400040b2005450d0342002107200441106a41086a220042003703002004420037031041b18ac0004116200441106a1004200441086a2000290300370300200420042903103703002004410036021020044110200441106a100521050240024020042802102200417f470d00420021010c010b2004420037031820044200370310200441106a20052000411020004110491b10ce041a2000410f4d0d02200441186a290300210120042903102107200510290b200441106a41086a220042003703002004420037031041b18ac0004116200441106a1004200441086a2000290300370300200420042903103703002004427f200120037c200720027c22032007542200ad7c22022000200220015420022001511b22001b3703182004427f200320001b37031020044110200441106a411010030c030b42002107200441106a41086a220042003703002004420037031041b18ac0004116200441106a1004200441086a2000290300370300200420042903103703002004410036021020044110200441106a100521050240024020042802102200417f470d00420021010c010b2004420037031820044200370310200441106a20052000411020004110491b10ce041a2000410f4d0d02200441186a290300210120042903102107200510290b200441106a41086a220042003703002004420037031041b18ac0004116200441106a1004200441086a2000290300370300200420042903103703002004427f200120037c200720027c22032007542200ad7c22022000200220015420022001511b22001b3703182004427f200320001b37031020044110200441106a411010030c020b418f89c3004133104e000b418f89c3004133104e000b200441206a24000b130020004103360204200041f0b7c1003602000b3400200041bff4c10036020420004100360200200041146a4103360200200041106a41d8bec100360200200041086a42083702000b130020004104360204200041f0c2c1003602000b3201017f02404104102722020d0041044101102a000b20004284808080c00037020420002002360200200241a0c21e3600000b3201017f02404108102722020d0041084101102a000b20004288808080800137020420002002360200200242c0f0003700000b3201017f02404104102722020d0041044101102a000b20004284808080c00037020420002002360200200241d086033600000ba70201047f23004190016b2202240002400240411210272203450d00200341106a41002f00c0a7413b0000200341086a41002900b8a741370000200341002900b0a74137000020034112412410282203450d0120032001360012200241086a41186a22014200370300200241086a41106a22044200370300200241086a41086a220542003703002002420037030820034116200241086a1000200241f0006a41186a2001290300370300200241f0006a41106a2004290300370300200241f0006a41086a200529030037030020022002290308370370200241086a200241f0006a10f3010240024020022903084201510d00200042003703000c010b2000200241086a41e80010ce041a0b2003102920024190016a24000f0b41124101102a000b41244101102a000bcb0706047f017e027f017e047f027e230041c0016b22022400200241003602a00120014120200241a0016a10052101024002400240024020022802a0012203417f460d0020010d010b200042003703000c010b200241a0016a2003412020034120491b22046a41004100412020046b2004411f4b1b10cd041a200241a0016a2001200410ce041a2003411f4d0d01200241206a41086a200241a0016a41086a2205290000370300200241206a41106a200241a0016a41106a290000370300200241206a41186a200241a0016a41186a290000370300200220022900a001220637036020022006370320200242003703a801200242003703a001200241a0016a200120046a2207200320046b2203411020034110491b220810ce041a2003410f4d0d012005290300210620022903a0012109200241a0016a200320086b2204412020044120491b22036a41004100412020036b2003411f4b1b10cd041a200241a0016a200720086a220a200310ce041a2004411f4d0d01200241c0006a41086a220b200241a0016a41086a2208290000370300200241c0006a41106a220c200241a0016a41106a2205290000370300200241c0006a41186a220d200241a0016a41186a2207290000370300200220022900a001220e3703602002200e3703402002420037036820024200370360200241e0006a200a20036a200420036b2203411020034110491b10ce041a2003410f4d0d012008200241206a41086a2903003703002005200241206a41106a2903003703002007200241206a41186a29030037030020024180016a41086a2204200b29030037030020024180016a41106a220a200c29030037030020024180016a41186a220b200d290300370300200220022903203703a0012002200229034037038001200241e0006a41086a2203290300210e2002290360210f20032008290300370300200241e0006a41106a22082005290300370300200241e0006a41186a22052007290300370300200241086a22072004290300370300200241106a2204200a290300370300200241186a220a200b290300370300200220022903a001370360200220022903800137030020011029200041206a200e370300200041186a200f370300200041106a20063703002000200937030820004201370300200041286a2002290360370300200041306a2003290300370300200041386a2008290300370300200041c0006a2005290300370300200041c8006a2002290300370300200041d0006a2007290300370300200041d8006a2004290300370300200041e0006a200a2903003703000b200241c0016a24000f0b418f89c3004133104e000bc30701087f230041e00b6b220424000240024020002802000d002000417f360200200441286a41186a200141186a290000370300200441286a41106a200141106a290000370300200441286a41086a200141086a290000370300200420012900003703280240024020002802042205418883c000460d00200041086a28020021060c010b4100210620044180096a410041e00210cd041a200441e0006a410041a00810cd041a41880b10272205450d02200541003b010620054100360200200541086a20044180096a41e00210ce041a200541e8026a200441e0006a41a00810ce041a200041086a4100360200200020053602040b200041046a210702400240034020052f010622084105742109410021014100210a02400240034020092001460d01200441286a200520016a41086a412010d004220b450d02200141206a2101200a41016a210a200b417f4a0d000b200a417f6a21080b2006450d022006417f6a2106200520084102746a41880b6a28020021050c010b0b2000410c6a210b410121010c010b200441086a41186a200441286a41186a290300370300200441086a41106a200441286a41106a290300370300200441086a41086a200441286a41086a290300370300200420042903283703082000410c6a210b410021062008210a410021010b0240024020010d002004419c096a200441086a41086a290300370200200441a4096a200441086a41106a290300370200200441ac096a200441086a41186a2903003702002004200b360290092004200a36028c09200420073602880920042005360284092004200636028009200420042903083702940920044180016a200429035037030020044188016a200441d0006a41086a29030037030020044194016a420037020020044200370378200442003703602004418883c00036029001200441003a009c012004419d016a2004290028370000200441a5016a200441286a41086a290000370000200441ad016a200441286a41106a290000370000200441b5016a200441286a41186a290000370000200441bc016a200441c7006a28000036000020044180096a200441e0006a10de0121010c010b200441f8006a4200370300200441f4006a418883c000360200200441003602800120044100360270200442003703682004418883c000360264200441003602602005200a41e0006c6a41e8026a2101200441e0006a10d6010b200141106a200337030020012002370308200142013703002000200028020041016a360200200441e00b6a24000f0b41c8a8c1004110200441e0006a41f0a8c10010a201000b41880b4108102a000bad2304017f027e147f047e230041a0056b220324000240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024020012802000e0400010203000b200341c4046a4101360200200342013702b404200341ccfdc4003602b0042003410236028c01200341c4fdc40036028801200320034188016a3602c004200341b0046a41c0c9c1001057000b200141306a2903002104200141286a2903002105200341fc006a41026a200141076a2d00003a0000200341e0006a41086a200141186a290200370300200341e0006a410d6a2001411d6a290000370000200320012f00053b017c2003200141106a29020037036041d588c3002106412a210720022d00000d1520022d00014101470d15200141086a28020021062001410c6a280200210720012d00042101200241196a2d00002108200241186a2d00002109200241166a2f0100210a200241156a2d0000210b200241146a2d0000210c200241126a2f0100210d200241116a2d0000210e200241106a2d0000210f2002410e6a2f010021102002410d6a2d000021112002410c6a2d000021122002410a6a2f01002113200241096a2d00002114200241086a2d00002115200241066a2f01002116200241056a2d00002117200241046a2d00002118200241026a2f0100211920032002411a6a2901003703c003200320083a00bf03200320093a00be032003200a3b01bc032003200b3a00bb032003200c3a00ba032003200d3b01b8032003200e3a00b7032003200f3a00b603200320103b01b403200320113a00b303200320183a00aa03200320193b01a803200320142013410874722012411874723600af03200320172016410874722015411874723600ab0320034188046a41026a2202200341fc006a41026a2d00003a0000200320032f017c3b018804200341b0046a41086a2208200341e0006a41086a290300370300200341b0046a410d6a2209200341e0006a410d6a290000370000200320032903603703b0040240200141ff01714101460d0020034184046a41026a20022d00003a0000200341c8026a41086a2008290300370300200341c8026a410d6a2009290000370000200320032f0188043b018404200320032903b0043703c8020c130b20034190046a200641067610cc012003280290042102024002402003280298042006413f7122014b0d00410021010c010b20034184046a41026a200220014105746a220141026a2d00003a0000200341d0026a200141136a290000370300200341d5026a200141186a290000370000200320012f00003b0184042003200129000b3703c8022001280007210720012800032106410121010b0240200328029404450d00200210290b20010d1241012101411521074184efc20021060c130b41a584c2002106410e210720022d00004101470d14200241086a2802004102490d14200241046a28020041ff01710d1420012802042102411210272201450d01200141106a41002f00c0a7413b0000200141086a41002900b8a741370000200141002900b0a74137000020014112412410282201450d0220012002360012200341b0046a41186a22024200370300200341b0046a41106a22064200370300200341b0046a41086a22074200370300200342003703b00420014116200341b0046a100020034190046a41186a200229030037030020034190046a41106a200629030037030020034190046a41086a2007290300370300200320032903b00437039004200341b0046a20034190046a10f301024020032903b00442015222020d0020034190046a4120100c0b20032802b8042106200341a8036a200341bc046a41dc0010ce041a20020d03200341c8026a200341a8036a41dc0010ce041a20011029200341e8016a200341c8026a41dc0010ce041a200320063602880120034188016a410472200341e8016a41dc0010ce041a20034188016a41186a2903002104200329039801211a411810272201450d04200141106a41002900cf8c40370000200141086a41002900c78c40370000200141002900bf8c4037000020014118413810282201450d052001200341a8016a2202290000370018200141306a200241186a290000370000200141286a200241106a290000370000200141206a200241086a290000370000200341c8006a20014138108401200341c8006a41106a290300211b2003290350211c2003280248210620011029420021052002201c420020061b221c201a201c201c201a56201b420020061b221b200456201b2004511b22011b221a7d201b2004201b20011b221d7d201c201a54ad7d109c01200341b0046a41086a22014200370300200342003703b00441b18ac0004116200341b0046a1004200341c8026a41086a2001290300370300200320032903b0043703c802200341003602b004200341c8026a4110200341b0046a100521020240024020032802b0042201417f470d00420021040c010b200342003703b804200342003703b004200341b0046a20022001411020014110491b10ce041a2001410f4d0d07200341b8046a290300210420032903b0042105200210290b200341b0046a41086a22014200370300200342003703b00441b18ac0004116200341b0046a1004200341c8026a41086a2001290300370300200320032903b0043703c802200342002004201d7d2005201a54ad7d221c2005201a7d221b200556201c200456201c2004511b22011b3703b80420034200201b20011b3703b004200341c8026a4110200341b0046a41101003410021060c130b41a584c2002106410e210720022d00004101470d13200241086a2802004104490d13200241046a28020041ff01710d1320012802042106411210272201450d06200141106a41002f00c0a7413b0000200141086a41002900b8a741370000200141002900b0a74137000020014112412410282201450d0720012006360012200341b0046a41186a22024200370300200341b0046a41106a22074200370300200341b0046a41086a22084200370300200342003703b00420014116200341b0046a100020034190046a41186a200229030037030020034190046a41106a200729030037030020034190046a41086a2008290300370300200320032903b0043703900420034190046a412041b8d6c50041004100100b2102200110292002417f460d0f200341b0046a41086a22014200370300200342003703b004418486c5004112200341b0046a1004200341c8026a41086a2001290300370300200320032903b0043703c80241002102200341003602b004200341c8026a4110200341b0046a1005210720032802b0042201417f460d092003200136028c012003200736028801200341b0046a20034188016a104520032802b004220c450d08200341b8046a280200210220032902b404210520032802b404210d02402001450d00200710290b2005a72005422088a72201470d0b0c0a0b41124101102a000b41244101102a000b200110290c0c0b41184101102a000b41384101102a000b418f89c3004133104e000b41124101102a000b41244101102a000b418f89c3004133104e000b4104210c410021010b200141016a22072001490d0320014101742208200720072008491b220d41ffffffff0371200d470d03200d41027422074100480d030240024020010d0020071027210c0c010b200c200141027420071028210c0b200c450d01200221010b200c20014102746a2006360200200341b0046a41086a22014200370300200342003703b004418486c5004112200341b0046a1004200341c8026a41086a2001290300370300200320032903b0043703c802200341003602b804200342013703b0042003200241016a22013602880120034188016a200341b0046a103002400240200120024f0d0020032802b804210920032802b404210820032802b00421020c010b410020032802b80422016b2106200241027441046a210a20032802b4042108200c210703402007280200210b02400240200820066a4104490d0020032802b00421020c010b200141046a22022001490d0520084101742209200220022009491b22094100480d050240024020080d002009102721020c010b20032802b00420082009102821020b2002450d04200320093602b404200320023602b004200921080b200741046a21072003200141046a22093602b804200220016a200b3600002006417c6a210620092101200a417c6a220a0d000b0b200341c8026a411020022009100302402008450d00200210290b41002106200d450d06200c10290c060b20074104102a000b20094101102a000b102b000b41eac9c1002106411921070c030b20034190046a41026a20034184046a41026a2d00003a0000200341b0046a41086a200341c8026a41086a290300370300200341b0046a410d6a200341c8026a410d6a290000370000200320032f0184043b019004200320032903c8023703b004410021010b20034184016a41026a220220034190046a41026a2d00003a000020034188016a41086a2208200341b0046a41086a29030037030020034188016a41106a200341b0046a41106a290300370300200320032f0190043b018401200320032903b0043703880120010d01200341306a2005200442c0843d420010d404200341206a2003290330221c200341306a41086a290300221b42c0fb42427f10d304200341106a201c201b42d08603420010d30420034180016a41026a20022d00003a0000200341e8016a41086a2008290300370300200341e8016a410d6a220220034188016a410d6a290000370000200320032f0184013b01800120032003290388013703e801200341c0006a200341a8036a2003290310221b200520032903207c42148042ffffffff0f837c221c428080e983b1de16201c428080e983b1de1656200341106a41086a290300201c201b54ad7c221c420052201c501b22011b221b201c420020011b221c10ac0102402003280240450d0041d0c9c1002106411a21070c020b200341086a41ee85c500411610b501200328020c210120032802082108200341b0046a41086a22094200370300200342003703b00441ee85c5004116200341b0046a1004200341c8026a41086a220a2009290300370300200320032903b0043703c80220032001410020081b220841016a3602b004200341c8026a4110200341b0046a4104100320034188016a41086a200341a8036a41086a29030037030020034188016a41106a200341a8036a41106a29030037030020034188016a41186a200341a8036a41186a290300370300200a200341e8016a41086a290300370300200341c8026a410d6a2002290000370000200320032903a80337038801200320032f0180013b018804200320034182016a2d00003a008a04200320032903e8013703c802411210272201450d02200141106a41002f00c0a7413b0000200141086a41002900b8a741370000200141002900b0a74137000020014112412410282202450d0320022008360012200341b0046a41186a22014200370300200341b0046a41106a22094200370300200341b0046a41086a220a4200370300200342003703b00420024116200341b0046a100020034190046a41186a200129030037030020034190046a41106a200929030037030020034190046a41086a200a290300370300200320032903b00437039004412010272201450d042001200329038801370000200141186a20034188016a41186a290300370000200141106a20034188016a41106a290300370000200141086a20034188016a41086a2903003700002001412041c00010282201450d0520012005370020200141286a2004370000200141c00041800110282201450d062001201b370050200120032f0188043b00302001200736003720012006360033200120032903c80237003b200141d8006a201c370000200141326a20032d008a043a0000200141c3006a200341c8026a41086a290300370000200141c8006a200341d5026a29000037000020034190046a4120200141e00010032001102920021029200341bc046a200836020041002106200341b0046a41086a41003a00002003410a3a00b00441b8d6c5004100200341b0046a1088010b0b2000200736020420002006360200200341a0056a24000f0b41124101102a000b41244101102a000b41204101102a000b41c0004101102a000b4180014101102a000bf90a03027f017e077f230041d0006b22042400200441306a41086a220542003703002004420037033041c1c8c100411d200441306a1004200441206a41086a20052903003703002004200429033037032002400240024002400240024002400240024002400240200441206a411041b8d6c50041004100100b417f470d00200441106a41888dc300410d1094012004290318420020042802101b210602402002a74101470d0020044184ccc100411a109401024020042903082006580d0020042802000d0b0b200441306a41086a22054200370300200442003703304184ccc100411a200441306a1004200441206a41086a2005290300370300200420042903303703202004200620014201867c370330200441206a4110200441306a410810030b200028020821052000280204210720002802002108200441306a41086a220042003703002004420037033041c1c8c100411d200441306a1004200441206a41086a2000290300370300200420042903303703202004410036023820044201370330410810272200450d01200442888080808001370234200420003602302000200637000020004108411010282200450d02200442908080808002370234200020013700082004200036023020042005360244200441c4006a200441306a103002402005450d002008200541286c6a21092004280234210a2004280238210b20082100034002400240200a200b6b4120490d00200b41206a21052004280230210c0c010b200b41206a2205200b490d0b200a410174220c20052005200c491b220d4100480d0b02400240200a0d00200d1027210c0c010b2004280230200a200d1028210c0b200c450d062004200d3602342004200c360230200d210a0b200c200b6a220b41186a200041186a290000370000200b41106a200041106a290000370000200b41086a200041086a29000037000020042005360238200b2000290000370000200041206a29030021010240200a20056b41074b0d00200541086a220b2005490d0b200a410174220d200b200b200d491b220b4100480d0b02400240200a0d00200b1027210c0c010b200c200a200b1028210c0b200c450d072004200b3602342004200c360230200b210a0b2004200541086a220b360238200c20056a20013700002009200041286a2200470d000b0b2004280234210c200428023821000240024020024201510d0002400240200c2000460d00200428023021050c010b200041016a22052000490d0b2000410174220c20052005200c491b220c4100480d0b0240024020000d00200c102721050c010b20042802302000200c102821050b2005450d082004200c360234200420053602300b2004200041016a220a360238200520006a41003a00000c010b02400240200c2000460d00200428023021050c010b200041016a22052000490d0a2000410174220c20052005200c491b220c4100480d0a0240024020000d00200c102721050c010b20042802302000200c102821050b2005450d082004200c360234200420053602300b2004200041016a220b360238200520006a41013a00000240200c200b6b41074b0d00200b41086a220a200b490d0a200c410174220d200a200a200d491b220a4100480d0a02400240200c0d00200a102721050c010b2005200c200a102821050b2005450d092004200a36023420042005360230200a210c0b2004200041096a220a3602382005200b6a20033700000b200441206a41102005200a10030240200c450d00200510290b2007450d0a200810290c0a0b200041046a280200450d09200028020010290c090b41084101102a000b41104101102a000b200d4101102a000b200b4101102a000b200c4101102a000b200c4101102a000b200a4101102a000b102b000b200041046a280200450d00200028020010290b200441d0006a24000b02000ba80102027f047e230041c0006b21020240200128020022032001280204470d00200041003602000f0b2001200341e0006a360200200241086a200341c8006a2900002204370300200241106a200341d0006a2900002205370300200241186a200341d8006a29000022063703002002200341c0006a290000220737030020002003360200200020073700042000410c6a2004370000200041146a20053700002000411c6a20063700000b290020004101360204200041086a200128020420012802006b41e0006e2201360200200020013602000bd10304037f027e067f027e23004180016b210302402001280200220420012802042205460d002001200441e0006a360200200341206a41186a200441d8006a2900002206370300200341206a41106a200441d0006a2900002207370300200341106a22082007370300200341086a2209200441c8006a290000370300200341186a220a20063703002003200441c0006a290000370300200341e0006a41186a220b200a290300370300200341e0006a41106a220c2008290300370300200341e0006a41086a220d20092903003703002003200329030037036002402002450d00200541a07f6a2105034020052004460d022001200441c0016a360200200441a0016a2900002106200441b8016a2900002107200441b0016a290000210e200341206a41086a200441a8016a290000220f3703002009200f3703002008200e370300200a20073703002003200637032020032006370300200b200a290300370300200c2008290300370300200d200929030037030020032003290300370360200441e0006a21042002417f6a22020d000b0b20002004360200200020032903603702042000410c6a200d290300370200200041146a200c2903003702002000411c6a200b2903003702000f0b200041003602000bf60505097f017e017f017e037f23004180026b2202240020024100360218200241186a2001280200220320012802042204410420044104491b220510ce041a2001200420056b22063602042001200320056a2205360200024002400240200441034b0d00200041003602000c010b20022802182107200242003702042002418883c000360200200241086a210802402007450d00200241a0016a41027221094100210a034020024200370318200241186a20052006410820064108491b220410ce041a2001200620046b3602042001200520046a36020002400240200641074d0d002002290318210b200241186a200110442002280218220c0d010b2000410036020020022802002002280204200228020810fc010c030b200229021c210d2002200b370310024002402002280200220e418883c000460d002002280204210f0c010b2009410041da0010cd041a200241186a410041840110cd041a41e4011027220e450d044100210f200e4100360200200e41046a200241a0016a41dc0010ce041a200e41e0006a200241186a41840110ce041a200241003602042002200e3602000b200a41016a210a024002400340200e41086a2105200e2f01062210410374210641002104024003402006450d01200241106a2005410810d0042203450d03200641786a2106200441016a2104200541086a21052003417f4a0d000b2004417f6a21100b0240200f450d00200f417f6a210f200e20104102746a41e4016a280200210e0c010b0b2002200b37022c20022008360228200220103602242002200e36021c20024100360218200220023602202002200d3702a4012002200c3602a001200241186a200241a0016a10fd010c010b200e2004410c6c6a220641e4006a220528020021042005200d370200200641e0006a220528020021062005200c3602002006450d002004450d00200610290b200a2007460d0120012802002105200128020421060c000b0b20002002290300370200200041086a20082802003602000b20024180026a24000f0b41e4014104102a000bd90303027f017e027f02402001450d00034020002802e40121002001417f6a22010d000b0b02402002450d004100210341002101034002400240200120002f01064f0d0020002001410c6c6a220441e4006a2902002105200441e0006a2802002104200141016a21010c010b02400240200028020022010d002003ad210541002106410021010c010b20003301044220862003ad842105410121060b200010292005a72103024002402005422088a7220720012f01064f0d00200121040c010b034002400240200128020022040d002003ad2105410021040c010b200641016a210620013301044220862003ad8421050b200110292005a72103200421012005422088a7220720042f01064f0d000b0b200741027420046a41e8016a280200210020042007410c6c6a220141e4006a2902002105200141e0006a280200210402402006417f6a2201450d00034020002802e40121002001417f6a22010d000b0b410021010b2004450d012002417f6a210202402005a7450d00200410290b20020d000b0b02402000418883c000460d0020002802002101200010292001450d0020012802002104200110292004450d00024020042802002201450d000340200410292001210420012802002200210120000d000b0b200410290b0be71207027f017e057f027e017f017e0a7f230041b0036b2202240020002802102203200328020041016a36020020002902142104200028020c2103200028020821052000280200210620002802042100200241f0016a41086a2207200141086a280200360200200220012902003703f001024002400240024020002f01062201410b490d00200241d0026a410272410041da0010cd041a200241386a410041840110cd041a0240024041e40110272208450d0020084100360200200841046a200241d0026a41dc0010ce041a200841e0006a200241386a41840110ce042107200241386a41086a2209200041b0016a280200360200200220002902a8013703382000413c6a330000210a2000413e6a310000210b20002d003f210c2000350038210d200841086a200041c0006a20002f010641796a220141037410ce04210e2007200041b4016a2001410c6c10ce042107200041063b0106200820013b0106200241d0026a41086a2009280200360200200220022903383703d002200d200a200b4210868442208684210a0240024020034107490d002003410374200e6a41506a200e200341796a22094103746a220e200141ffff037120096b41037410cf041a200e20043700002003410c6c20076a220341b87f6a200341ac7f6a2203200841066a22012f010020096b410c6c10cf041a200341086a200241f0016a41086a280200360200200320022903f0013702000c010b200041086a20034103746a220741086a2007200041066a22012f010020036b41037410cf041a20072004370000200041e0006a2003410c6c6a2207410c6a200720012f010020036b410c6c10cf041a200741086a200241f0016a41086a280200360200200720022903f0013702000b200120012f010041016a3b0100200241286a41086a220f200241d0026a41086a22102802002203360200200241086a221120033602002002200c3a0017200220022903d00222043703282002200a3e02102002200a4230883c00162002200a4220883d011420022004370300200229031021042000280200220c450d0320002f01042112200241d0026a410272211303402002200641016a22063602202002200c360224200f201128020036020020022002290300370328201241ffff03712109024002400240200c2f01062200410b490d002013410041da0010cd041a200241f0016a200241d0026a41dc0010ce041a200241386a410041b40110cd041a41940210272207450d0520074100360200200741046a200241f0016a41dc0010ce041a200741e0006a200241386a41b40110ce042103200c41386a290000210a200241386a41086a2214200c41b0016a2802003602002002200c41a8016a290200370338200741086a200c41c0006a200c2f0106220141796a220041037410ce0421152003200c41b4016a2000410c6c10ce042116200741e4016a200c4180026a2001417a6a220e41027410ce042117200c41063b0106200720003b01060240200e450d00410021002017210303402003280200220120003b010420012007360200200341046a2103200e200041016a2200470d000b0b20102014280200220036020020022002290338220b3703d002201420003602002002200b370338201241ffff037122034107490d0120152009417a6a22034103746a2015200941796a22004103746a220120072f010620006b41037410cf041a200120043700002009410c6c20166a220141b87f6a200141ac7f6a220120072f0106220e20006b410c6c10cf041a200141086a200f280200360200200120022903283702002007200e41016a22013b01062009410274221220176a416c6a201720034102746a220e200141ffff0371220920036b41027410cf041a200e200836020020092003490d02200720126a41cc016a2103034020032802002201200041016a22003b010420012007360200200341046a210320002009490d000c030b0b200c41086a2201200941016a22034103746a200120094103746a2201200020096b220741037410cf041a20012004370000200c2009410c6c6a220141ec006a200141e0006a220e2007410c6c10cf041a200141e8006a200241286a41086a280200360200200e2002290328370200200c200041016a22003b01062009410274200c41e4016a22016a41086a200120034102746a2201200041ffff0371220720036b41027410cf041a20012008360200201241ffff037120074f0d07200c2003417f6a22004102746a41e8016a2103034020032802002201200041016a22003b01042001200c360200200341046a210320002007490d000c080b0b200c41086a2200200941016a220e4103746a200020094103746a2200200c2f0106220120096b221241037410cf041a20002004370000200c41e0006a2009410c6c6a2200410c6a20002012410c6c10cf041a200041086a200f28020036020020002002290328370200200c200141016a22003b010620094102742217200c41e4016a22016a41086a2001200e4102746a2212200041ffff03712201200e6b41027410cf041a20122008360200200320014f0d00200c20176a41e8016a2100034020002802002203200941016a22093b01042003200c360200200041046a210020012009470d000b0b200241106a41086a2014280200220036020020112000360200200220022903382204370310200220043703000240200c28020022000d0020072108200a21040c050b200c2f010421122000210c200a2104200721080c000b0b41e4014104102a000b4194024104102a000b200020034103746a220941106a200941086a2209200120036b41037410cf041a2009200437000020002003410c6c6a220141ec006a200141e0006a220920002f010620036b410c6c10cf041a200141e8006a2007280200360200200920022903f001370200200020002f010641016a3b01060c010b200241d0026a410272410041da0010cd041a200241f0016a200241d0026a41dc0010ce041a200241386a410041b40110cd041a41940210272200450d0120004100360200200041046a200241f0016a41dc0010ce041a200041e0006a200241386a41b40110ce0421012000200528020022033602e401200520003602002005200528020441016a360204200341003b010420032000360200200120002f01062203410c6c6a22012002290300370200200020034103746a41086a2004370000200141086a200241086a280200360200200041e4016a200341016a22034102746a2008360200200020033b0106200820033b0104200820003602000b200241b0036a24000f0b4194024104102a000b840b02037f017e024002400240024002400240024002400240024002400240024020002802000e0400010203000b02400240200141046a280200200141086a2802002202460d00200128020021030c010b200241016a22032002490d0c20024101742204200320032004491b22044100480d0c0240024020020d002004102721030c010b200128020020022004102821030b2003450d0420012003360200200141046a2004360200200141086a28020021020b200141086a2204200241016a360200200320026a41013a00002000280204210302400240200141046a2802002202200428020022006b4104490d00200128020021020c010b200041046a22042000490d0c20024101742200200420042000491b22004100480d0c0240024020020d002000102721020c010b200128020020022000102821020b2002450d0520012002360200200141046a2000360200200141086a28020021000b200141086a200041046a360200200220006a20033600000f0b02400240200141046a280200200141086a2802002202460d00200128020021030c010b200241016a22032002490d0b20024101742204200320032004491b22044100480d0b0240024020020d002004102721030c010b200128020020022004102821030b2003450d0520012003360200200141046a2004360200200141086a28020021020b200141086a2204200241016a360200200320026a41023a00002000290308210502400240200141046a2802002202200428020022006b4108490d00200128020021020c010b200041086a22032000490d0b20024101742200200320032000491b22004100480d0b0240024020020d002000102721020c010b200128020020022000102821020b2002450d0620012002360200200141046a2000360200200141086a28020021000b200141086a200041086a360200200220006a20053700000f0b02400240200141046a280200200141086a2802002202460d00200128020021030c010b200241016a22032002490d0a20024101742204200320032004491b22044100480d0a0240024020020d002004102721030c010b200128020020022004102821030b2003450d0620012003360200200141046a2004360200200141086a28020021020b200141086a2204200241016a360200200320026a41033a00002000280204210302400240200141046a2802002202200428020022006b4104490d00200128020021020c010b200041046a22042000490d0a20024101742200200420042000491b22004100480d0a0240024020020d002000102721020c010b200128020020022000102821020b2002450d0720012002360200200141046a2000360200200141086a28020021000b200141086a200041046a360200200220006a20033600000f0b02400240200141046a280200200141086a2802002202460d00200128020021030c010b200241016a22032002490d0920024101742204200320032004491b22044100480d090240024020020d002004102721030c010b200128020020022004102821030b2003450d0720012003360200200141046a2004360200200141086a28020021020b200141086a2204200241016a360200200320026a41043a00002000290308210502400240200141046a2802002202200428020022006b4108490d00200128020021020c010b200041086a22032000490d0920024101742200200320032000491b22004100480d090240024020020d002000102721020c010b200128020020022000102821020b2002450d0820012002360200200141046a2000360200200141086a28020021000b200141086a200041086a360200200220006a20053700000f0b20044101102a000b20004101102a000b20044101102a000b20004101102a000b20044101102a000b20004101102a000b20044101102a000b20004101102a000b102b000b130020004101360204200041d8cdc1003602000b340020004180f4c10036020420004100360200200041146a4107360200200041106a41a4d1c100360200200041086a42073702000b130020004101360204200041f8dcc1003602000bff0101057f230041106b2202240020024100360208200242013703002002410d36020c2002410c6a20021030024002400240024020022802042203200228020822046b410d490d002004410d6a2105200228020021030c010b2004410d6a22052004490d0220034101742206200520052006491b22064100480d020240024020030d002006102721030c010b200228020020032006102821030b2003450d0120022006360204200220033602000b20022005360208200320046a2204410029009ecc41370000200441056a41002900a3cc4137000020002002290300370200200041086a2002280208360200200241106a24000f0b20064101102a000b102b000ba504010b7f230041106b220324002003420037030820012002200341086a102020032003290308370300200120026a21040240024002400240200241086a220520024f0d00200341086a2106200321074100210841002105410121094100210a0340200841017421022006200741016a220b6b210c034020072d00002107024002400240024020082005470d002008417f417f200c200420016b6a22052005200c491b220541016a220d200d2005491b6a22052008490d072002200520052002491b22054100480d070240024020080d002005102721090c010b200920082005102821090b2009450d010b200920086a20073a00000240024002400240200a41ff01710e03010300010b20042001460d010c050b0240200b2006460d004100210a0c040b20042001470d040b200841016a21080c090b4101210a200b2006470d01200841016a21080c080b20054101102a000b200841016a2108200b21070c020b200841016a21084102210a200241026a21022001220741016a21010c000b0b0b410121092005450d0120054100480d002005102722090d0120054101102a000b102b000b410021080340200920086a200320086a2d00003a0000200841016a22084108470d000b024020020d00410821080c010b200920086a2107410021080340200720086a200120086a2d00003a00002002200841016a2208470d000b200420016b41086a21080b200020083602082000200536020420002009360200200341106a24000bad10030a7f027e047f23004190016b22032400024002400240024002400240411410272204450d00200441106a410028009c9342360000200441086a410029009493423700002004410029008c934237000020044114413410282204450d01200420012900003700142004412c6a200141186a290000370000200441246a200141106a2900003700002004411c6a200141086a290000370000200341e8006a41186a22054200370300200341e8006a41106a22064200370300200341e8006a41086a220742003703002003420037036820044134200341e8006a1000200341c0006a41186a2005290300370300200341c0006a41106a2006290300370300200341c0006a41086a20072903003703002003200329036837034020034100360268200341c0006a4120200341e8006a1005210820032802682209417f460d042008450d042003200936022420032008360220200341106a200341206a102e2003280210450d0320032802142105200341086a200341206a102e2003280208450d03200328020c21072003200341206a102e2003280200450d032003280204210a200341003a0068200341e8006a2003280220220b20032802242206410047220c10ce041a2006200c490d0220032006200c6b3602242003200b200c6a3602202006450d0320032d0068220c41014b0d034100210602400240200c0e020100010b410121060b200341e8006a200341206a10442003280268220c450d032003413c6a41026a220b2003418c016a41026a2d00003a0000200320032f008c013b013c200329026c220d422088210e02402009450d00200810290b200ea72108200da72109200341e8006a41026a200b2d00003a0000200320032f013c3b01680c050b41144101102a000b41344101102a000b200c2006103e000b418f89c3004133104e000b410221060b200410290240024020064102470d004101210441a2e1c1002105411121070c010b200341c0006a41026a200341e8006a41026a2d00003a0000200320032f01683b0140410021040b2003411c6a41026a200341c0006a41026a2d00003a0000200320032f01403b011c024002402004450d002000200536020420004101360200200041086a20073602000c010b2003418c016a41026a220b2003411c6a41026a2d00003a0000200320032f011c3b018c01024002400240024002400240024002400240200228025820054b0d0020092102200c21040c010b411510272204450d012004410d6a41002900ce9242370000200441086a41002900c99242370000200441002900c1924237000020044115413510282204450d02200420012900003700152004412d6a200141186a290000370000200441256a200141106a2900003700002004411d6a200141086a290000370000200341e8006a41186a22054200370300200341e8006a41106a22064200370300200341e8006a41086a220742003703002003420037036820044135200341e8006a1000200341c0006a41186a2005290300370300200341c0006a41106a2006290300370300200341c0006a41086a20072903003703002003200329036837034020034100360268200341c0006a4120200341e8006a1005210502400240024020032802682206417f460d002005450d002003200636022420032005360220200341e8006a200341206a10442003280268220f450d06200329026c210d02402006450d00200510290b20041029200341e8006a200f200d422088a72002108502200da72110200341e8006a41086a2802002107200328026c210520032802684101470d022000200536020420004101360200200041086a20073602002010450d01200f10290c010b20041029200041086a411a360200200041b3e1c100360204200041013602000b2009450d09200c10290c090b200341c0006a41026a221120034187016a2d00003a0000200320032f0085013b014020034184016a2d0000210620034180016a2802002108200341fc006a2802002102200341f8006a2802002104200341f4006a280200210a02402009450d00200c10290b2003418c016a41026a20112d00003a0000200320032f01403b018c012008417f4c0d044101210c02402008450d0020081027220c450d06200c2004200810ce041a0b200341206a41146a2008360200200341206a41106a20083602002003200a36022820032007360224200320053602202003200c36022c2003200641ff01714101463a0038411410272209450d06200941106a410028009c9342360000200941086a410029009493423700002009410029008c934237000020094114413410282209450d07200920012900003700142009412c6a200141186a290000370000200941246a200141106a2900003700002009411c6a200141086a290000370000200341e8006a41186a22014200370300200341e8006a41106a22114200370300200341e8006a41086a221242003703002003420037036820094134200341e8006a1000200341c0006a41186a2001290300370300200341c0006a41106a2011290300370300200341c0006a41086a2012290300370300200320032903683703402003412036026c2003200341c0006a360268200341206a200341e8006a105b2009102902402008450d00200c10290b2010450d00200f10290b20002005360204200020032f018c013b001d200041003602002000411c6a20063a0000200041186a2008360200200041146a2002360200200041106a20043602002000410c6a200a360200200041086a20073602002000411f6a200b2d00003a00000c070b41154101102a000b41354101102a000b418f89c3004133104e000b1039000b20084101102a000b41144101102a000b41344101102a000b20034190016a24000b9e6a04147f027e0d7f027e230041c0046b22042400200441b0036a20012002200310ff02200441b0036a41086a280200210520042802b40321060240024020042802b0034101470d002000200636020420004101360200200041086a20053602000c010b200441c4036a2802002207412c6c2108200441c8036a2802002109200441c0036a280200210a200441bc036a280200210b4100210c4100210102400340024020082001470d000c020b200b20016a21022001412c6a220d210120022d00004102470d000b200441d8006a200b200d6a41586a1080032004280258210c200428025c21010b4100210e20014100200c1b210f2007412c6c2108200c41b8d6c500200c1b21104100210102400340024020082001470d000c020b200b20016a21022001412c6a220d210120022d00004108470d000b200441d0006a200b200d6a41586a1080032004280250210e200428025421010b4100211120014100200e1b21122007412c6c2108200e41b8d6c500200e1b210d4100210102400340024020082001470d000c020b200b20016a21022001412c6a220c210120022d00004104470d000b200441c8006a200b200c6a41586a10800320042802482111200428024c21010b4100210e2001410020111b21132007412c6c2108201141b8d6c50020111b21144100210102400340024020082001470d000c020b200b20016a21022001412c6a220c210120022d00004103470d000b200441c0006a200b200c6a41586a1080032004280240210e200428024421010b4100211541002102024020014100200e1b2201450d00200141286c2108200e41b8d6c500200e1b41186a2101410021020340200220012d0000456a2102200141286a2101200841586a22080d000b0b200d201241146c6a21114100211202400240024003400240200d2011470d0020122015714101710d0341bb91c50041c38fc500201241017122011b2108411c411e20011b21010c020b41e18fc500210841382101200d41086a280200417c6a220e41024b0d01200d280200210c024002400240200e0e03000401000b41012115200c41b98fc500460d01200c28000041e3c2b1e306460d010c030b41012112200c41bd8fc500460d00200c41bd8fc500410610d0040d020b0240200d410c6a280200450d0041df90c5002108411321010c020b0240200d41106a280200220120026b220c20014d0d0041f290c5002108412a21010c020b41b990c5002108412621012013200c4d0d012014200c4102746a220c450d01419990c500210841202101200f200c280200220c4d0d012010200c4104746a220c450d01419c91c5002108411f2101200c2802080d01200d41146a210d200c2d000d4104460d000b0b200020083602040c010b2007412c6c2108410021010240034020082001460d01200b20016a21022001412c6a220d210120022d00004106470d000b200441386a200b200d6a41586a108003200428023c450d00200041878dc500360204411f21010c010b2007412c6c21082003280268210c410021010240034020082001460d01200b20016a21022001412c6a220d210120022d00004105470d000b200441306a200b200d6a41586a22011080030240200428023441014d0d0041182101200041a68dc5003602040c020b200441286a2001108003200428022c450d0020042802282201450d002001280200200c4d0d0041222101200041be8dc5003602040c010b2007412c6c2108410021010240034020082001460d01200b20016a21022001412c6a220d210120022d00004107470d000b200441206a200b200d6a41586a1080032004280220220120042802244104746a2108034020012008460d012001450d012001410c6a2102200141106a210120022d0000410271450d000b41322101200041ca8ec5003602040c010b2007412c6c2108410021010240034020082001460d01200b20016a21022001412c6a220d210120022d0000410b470d000b200b200d6a220141606a2802002202450d00200141586a280200220d200241186c6a210c0340200d220241186a210d2002280208410374210120022802002102024003402001450d01200141786a210120022d00042108200241086a21022008410271450d000b41312101200041998ec5003602040c030b200d200c470d000b0b2007412c6c2108410021010240034020082001460d01200b20016a21022001412c6a220d210120022d00004102470d000b200441186a200b200d6a41586a108003200428021c2201450d002004280218220220014104746a211103402002450d01200241106a210e200420022d000d22083a00b0032002280200220120022802086a210c410021024100200441b0036a20084104461b210d024003400240024002400240200241ff01710e03000102000b2001200c460d014100210220012108200141016a21010c020b2001200c460d034101210220012108200141016a21010c010b200d450d0241022102200d21084100210d0b20082d0000410271450d000b41392101200041e08dc5003602040c030b200e2102200e2011470d000b0b2007412c6c21084100210c4100210102400340024020082001470d000c020b200b20016a21022001412c6a220d210120022d00004102470d000b200441106a200b200d6a41586a1080032004280210210c200428021421010b4100210e20014100200c1b210f2007412c6c2108200c41b8d6c500200c1b21104100210102400340024020082001470d000c020b200b20016a21022001412c6a220d210120022d00004103470d000b200441086a200b200d6a41586a1080032004280208210e200428020c21010b200e41b8d6c500200e1b220220014100200e1b41286c6a210d4100211302400240024003400240024002400240024002400240024002400240024002400240024002400240024002400240024002402002200d460d00412d210141dff5c200210820022802084103470d1102402002280200220c419ab0c500460d00200c419ab0c500410310d0040d120b200241286a21114115210c41d8f4c200210e4114210141cbf5c200210802400240024020022d00180e040014011b000b4136210c41a2f4c200210e200f200228021c22014d0d1a201020014104746a2214450d1a2002280214210c200228020c210220092d00700d01200c410b470d01413821014193f5c2002108200241ab8ac500460d13200241ab8ac500410b10d004450d130c160b412f2101418cf6c200210820022802144106470d120240200228020c220c419cf4c200460d00200c419cf4c200410610d0040d130b02402013450d00411f2101200041bbf6c2003602040c1b0b2002411c6a2113201121020c160b4126210141edf4c2002108200c417d6a220c41134b0d110240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240200c0e14002a2a2a0e042a062d0b0a2a011110172a2a0c15000b2002419db0c500460d292002419db0c500410310d004450d29419db0c5002002410310d0040d2941011027220e450d19200e41003a0000024020142d000c41e000470d0020142802084101470d002014280200211241002102034020024101460d03200e20026a2108201220026a210c200241016a2102200c2d000020082d0000460d000b0b200e1029200041edf4c2003602040c310b200241a888c500460d0141a888c5002002410f10d004450d010240200241b788c500460d0041b788c5002002410f10d0040d290b410110272212450d1a201241003a000020142d000c41e000470d2a20142802084101470d2a2014280200211541002102034020024101460d04201220026a210c201520026a210e200241016a2102200e2d0000200c2d0000460d000c2b0b0b20142d000d2101200e10292011210220014104460d2b0c2d0b41041027220e450d17200e4100360000024020142d000c41e000470d0020142802084104470d002014280200211241002102034020024104460d23200e20026a2108201220026a210c200241016a2102200c2d000020082d0000460d000b0b200e1029200041edf4c2003602040c2e0b0240200241c688c500460d00200229000042e5f0d1fbb5ac98b6ec00520d260b410710272212450d1820124100360003201241013a0002201241003b000020142d000c41e000470d2620142802084107470d262014280200211541002102034020024107460d03201220026a210c201520026a210e200241016a2102200e2d0000200c2d0000460d000c270b0b20142d000d220c4104460d262012102920112102200c41fb0171450d280c240b200241ce88c500460d0141ce88c5002002410a10d004450d01200241d888c500460d0241d888c5002002410a10d004450d020240200241e288c500460d0041e288c5002002410a10d0040d070b4126210c41edf4c200210e20142d000c41e000470d2a20142802080d2a2011210220142d000d4104460d270c2a0b20142d000d220c4104460d232012102920112102200c41fb0171450d260c220b410710272212450d1520124100360003201241013a0002201241003b0000024020142d000c41e000470d0020142802084107470d0020142802002115410021020340024020024107470d0020142d000d220c4104460d022012102920112102200c41fb0171450d280c240b201220026a210c201520026a210e200241016a2102200e2d0000200c2d0000460d000b0b20121029200041edf4c2003602040c290b41021027220e450d15200e41003b0000024020142d000c41e000470d0020142802084102470d002014280200211241002102034020024102460d1e200e20026a2108201220026a210c200241016a2102200c2d000020082d0000460d000b0b200e1029200041edf4c2003602040c280b0240200241f788c500460d0041f788c5002002410d10d0040d200b4126210c41edf4c200210e20142d000c41e000470d2620142802080d262011210220142d000d4104460d230c260b02402002418489c500460d00418489c5002002410c10d0040d1f0b4126210c41edf4c200210e20142d000c41e000470d2520142802080d252011210220142d000d4104460d220c250b02402002419b89c500460d00419b89c5002002411510d0040d1e0b4126210c41edf4c200210e20142d000c41e000470d2420142802080d242011210220142d000d4104460d210c240b0240200241b089c500460d0041b089c5002002410a10d0040d1d0b41021027220e450d12200e41003b0000024020142d000c41e000470d0020142802084102470d002014280200211241002102034020024102460d03200e20026a2108201220026a210c200241016a2102200c2d000020082d0000460d000b0b200e1029200041edf4c2003602040c240b0240200241ba89c500460d0041ba89c5002002410710d0040d1c0b4126210c41edf4c200210e20142d000c41e000470d2220142802080d222011210220142d000d4104460d1f0c220b20142d000d2101200e10292011210220014104460d1e0c200b200241c189c500460d0141c189c5002002411110d004450d010240200241f289c500460d0041f289c5002002411110d0040d1a0b41041027220e450d12200e4100360000024020142d000c41e000470d0020142802084104470d002014280200211241002102034020024104460d07200e20026a2108201220026a210c200241016a2102200c2d000020082d0000460d000b0b200e1029200041edf4c2003602040c210b200241d289c500460d0141d289c5002002411010d004450d01200241e289c500460d0241e289c5002002411010d004450d020240200241b68ac500460d0041b68ac5002002411010d0040d190b4126210c41edf4c200210e20142d000c41e000470d1f20142802080d1f2011210220142d000d4104460d1c0c1f0b41021027220e450d0e200e41003b0000024020142d000c41e000470d0020142802084102470d002014280200211241002102034020024102460d16200e20026a2108201220026a210c200241016a2102200c2d000020082d0000460d000b0b200e1029200041edf4c2003602040c1f0b4126210c41edf4c200210e20142d000c41e000470d1d20142802080d1d20142d000d22014104460d1d20112102200141fb0171450d1a0c1b0b41031027220e450d0d200e41003a0002200e41003b0000024020142d000c41e000470d0020142802084103470d002014280200211241002102034020024103460d15200e20026a2108201220026a210c200241016a2102200c2d000020082d0000460d000b0b200e1029200041edf4c2003602040c1d0b0240200241838ac500460d0041838ac5002002411610d0040d150b410210272212450d0e201241003b0000024020142d000c41e000470d0020142802084102470d002014280200211541002102034020024102460d04201220026a210c201520026a210e200241016a2102200e2d0000200c2d0000460d000b0b201210290c140b20142d000d2101200e10292011210220014104460d170c190b0240200241998ac500460d0041998ac5002002411210d0040d130b4126210c41edf4c200210e20142d000c41e000470d1920142802080d192011210220142d000d4104460d160c190b20142d000d2101201210292011210220014104460d150c170b024020130d0041002116410021170c100b024020132802040d00200041daf6c200360204413221010c190b024020132802002216201341086a28020022174d0d002000418cf7c20036020441c90021010c190b201720032802644d0d0f200041d5f7c20036020441c10021010c180b41014101102a000b41044101102a000b41014101102a000b41074101102a000b41074101102a000b41024101102a000b41024101102a000b41024101102a000b41034101102a000b41044101102a000b41024101102a000b20142d000d2101200e10292011210220014104460d080c0a0b20142d000d2101200e10292011210220014104460d070c090b20142d000d2101200e10292011210220014104460d060c080b20142d000d2101200e10292011210220014104460d050c070b20092903082118200441b8036a220242003703002004418883c0003602b4032009290310211920042018a7417f2018428080808010541b3602c00320042019a7417f2019428080808010541b3602b003200441b0036a4104722201410d1081032001410c108103200141071081032001410f108103200441b0036a410c6a220128020021132002280200211120042802c003211a20042802b403210c20042802b003211b200441c0036a220820073602002001200a3602002004200b3602b803200420053602b403200420063602b003200441e0006a200441b0036a108203024002400240410110272201450d00200141003a0000200420042f01b003220d3b01a002200841e0083b01002002428180808010370300200420013602b403200441013602b0032004200d3b01c203200441e0006a200441b0036a108303210b0240410310272202450d00200241026a41002d009cb0453a0000200241002f009ab0453b00000240410310272208450d00200841026a41002d009fb0453a0000200841002f009db0453b000002400240024002400240024002400240200441f4006a280200220d200441e0006a41106a2802002201470d00200141016a220d2001490d012001410174220e200d200d200e491b220dad42287e2218422088a70d012018a7220e4100480d010240024020010d00200e102721010c010b200428026c200141286c200e102821010b2001450d072004200d3602702004200136026c2004280274210d0b200428026c200d41286c6a220141003a00182001200836020c2001428380808030370204200120023602002001411c6a200b360200200141106a4283808080303702002004200428027441016a360274200441b0036a200441e0006a418c0110ce041a200441f0016a200441b0036a108403200441f0016a41106a280200220f412c6c210120042802f801220e41586a210202400340410021082001450d01200141546a2101200241286a210d2002412c6a220b2102200d2d00004103470d000b200b41086a2802002201450d00200141286c2102200b28020041186a2101410021080340200820012d0000456a2108200141286a2101200241586a22020d000b0b200f412c6c2101200e41586a21022008417f6a210d02400340410021082001450d01200141546a2101200241286a210b2002412c6a22072102200b2d00004103470d000b200741086a2802002201450d00200141286c2102200728020041186a2101410021080340200820012d0000456a2108200141286a2101200241586a22020d000b0b200f412c6c2101200e41606a21020240034041002107024020010d00410021010c020b200141546a2101200241206a210b2002412c6a22142102200b2d00004104470d000b201428020021010b0240024002400240200f450d00200120086a211c200e200f412c6c6a211d4100211e4100211403400240200e2d000041786a220141034b0d00024002400240024020010e0403010200030b200e28020c2201450d03200e280204220b200141186c6a211f0340201421200240200b22212802144104742202450d00202128020c21010340024020012d0000410b470d00200141046a2208280200220b200d490d002008200b41016a3602000b200141106a2101200241706a22020d000b0b02400240024002400240024002400240024002400240410810272201450d002001428080808010370200410410272222450d012021410c6a21082022410036020020212802142223450d0241002102410121122023210b4101210f4101211541012114024003402002200b4f0d01200241016a210502400240024002400240024002400240200828020020024104746a2d0000220b417e6a220241044b0d0020020e050101010302010b200b1085032124200c210b201121250340200b410c6a2107200b41086a2126200b2f010621104100210202400240034020102002460d01202620026a2106200741086a2107200241016a210202404100417f410120062d00002206202441ff0171220a4b1b2006200a461b41016a0e03000301000b0b2002417f6a21100b024020250d00201b210b0c070b2025417f6a2125200b20104102746a41ec006a280200210b0c010b0b201b210b20072802000e0404100304040b200b1085032124200c210b2011212502400340200b410c6a2107200b41086a2126200b2f010621104100210202400240034020102002460d01202620026a2106200741086a2107200241016a210202404100417f410120062d00002206202441ff0171220a4b1b2006200a461b41016a0e03000301000b0b2002417f6a21100b024020250d00201b210b0c030b2025417f6a2125200b20104102746a41ec006a280200210b0c010b0b201b210b024020072802000e0401110001010b200741046a280200210b0b2014417f6a220220144f0d0f200220144b0d0f200f202220024102746a28020022024d0d0f200120024103746a22072802042202200b6a220b2002490d0f2007200b360204024002402012200f460d00201221100c010b201241016a22022012490d1e2012410174220b20022002200b491b221041ffffffff01712010470d1e201041037422024100480d1e0240024020120d002002102721010c010b200120124103742002102821010b2001450d0c0b2001200f4103746a22024101360204200220053602000240024020152014460d00201521060c010b201541016a22022015490d1e2015410174220b20022002200b491b220641ffffffff03712006470d1e200641027422024100480d1e0240024020150d002002102721220c010b202220154102742002102821220b2022450d0d0b200f41016a2102202220144102746a200f360200201441016a21140c050b2014450d0e2014417f6a21140c030b2014450d0d024002402012200f460d00201221100c010b201241016a22022012490d1c2012410174220b20022002200b491b221041ffffffff01712010470d1c201041037422024100480d1c0240024020120d002002102721010c010b200120124103742002102821010b2001450d0c0b2001200f4103746a22024101360204200220053602000240024020152014417f6a220b460d00201521060c010b20154101742202201420142002491b220641ffffffff03712006470d1c200641027422024100480d1c0240024020150d002002102721220c010b202220154102742002102821220b2022450d0d0b200f41016a21022022200b4102746a200f3602000c030b200741046a280200210b0b2014417f6a220220144f0d0b200220144b0d0b200f202220024102746a28020022024d0d0b200120024103746a22072802042202200b6a220b2002490d0b2007200b3602040b20122110200f2102201521060b20052023460d0a2021280214210b201021122002210f20062115200521020c000b0b41a0b0c5002002200b1037000b41084104102a000b41044104102a000b200141086a210741012106410121100c060b20024104102a000b20024104102a000b20024104102a000b20024104102a000b02402012450d00200110290b4101211e024020150d00202021140c080b20221029202021140c070b2002450d01200120024103746a21070b20012114410121020340200129020021182004412d3a00b003200420184220883e02b403200820022018a76a220b417f6a200441b0036a1086032004410b3a00b0032004200d3602b4032008200b200441b0036a108603200241026a21022007200141086a2201470d000b201421010b02402010450d00200110290b02402006450d00202210290b202141186a210b02400240201a450d0020212802142202450d00202128020c210120024104742102410021080340024020012d0000412c470d002001410b3a0000200141046a201c360200200841016a21080b200141106a2101200241706a22020d000b4101211420080d010b202021140b200b201f470d000c040b0b200e2802042201200d490d02200e200141016a3602040c020b200e28020c2201450d01200e280204220b2001411c6c6a21070340200b2201411c6a210b024020012802182202450d0020012802102101200241027421020340024020012802002208200d490d002001200841016a3602000b200141046a21012002417c6a22020d000b0b200b2007460d020c000b0b200e28020c2201450d00200141146c2102200e28020441106a2101034002402001417c6a2802000d0020012802002208200d490d002001200841016a3602000b200141146a21012002416c6a22020d000b0b200e412c6a220e201d470d000b201e4101710d0220144101710d01200428028002210720042802f801210e0b200441fc016a280200211220042802f401211420042802f001210f410021100c020b200441b0036a41106a200441f0016a41106a280200360200200441b0036a41086a200441f0016a41086a290300370300200420042903f0013703b003200441a0026a200441b0036a108203411010272202450d07200241063a0000410110272201450d06200141003a000041011027220b450d05200b20012d00003a000020011029411010272208450d04200841063a000041f00010272201450d03200141063a00602001412c3b01502001200d3602442001410b3a0040200141d8003a00302001201a3602242001412d3a0020200141003602142001410f3a0010200141003602042001410f3a0000024020082d00004109470d00200828020841ffffffff0371450d00200828020410290b20081029024020022d00004109470d00200228020841ffffffff0371450d00200228020410290b20021029200441d4036a4287808080f000370200200441d0036a2001360200200441cc036a4100360200200441b0036a410c6a4281808080800c370200200441b8036a4101360200200441003602dc03200442043702c4032004200b3602b403200441013602b003200441a0026a200441b0036a108703200441b0036a200441a0026a418c0110ce041a20044188026a200441b0036a10840320044188026a410c6a280200211220044198026a2802002107200428028802210f200428028c022114200428029002210e410021100c010b200441fc016a280200211220042802f801210e02402004280280022207450d002007412c6c2102200e2101034020011088032001412c6a2101200241546a22020d000b0b41012110411a211441fc8ec500210f02402012450d00200e10290b0b02402011450d000340200c28026c210c2011417f6a22110d000b0b4100210841002101024003402013450d01024002402001200c2f01064f0d00200c20014103746a41146a2902002118200141016a21010c010b02400240200c28020022010d002008ad21184100210d410021010c010b200c3301044220862008ad8421184101210d0b200c10292018a72108024002402018422088a7220b20012f01064f0d00200121020c010b034002400240200128020022020d002008ad2118410021020c010b200d41016a210d20013301044220862008ad8421180b200110292018a72108200221012018422088a7220b20022f01064f0d000b0b200b41027420026a41f0006a280200210c2002200b4103746a41146a29020021180240200d417f6a2201450d000340200c28026c210c2001417f6a22010d000b0b410021010b2013417f6a21132018a74103470d000b0b0240200c418883c000460d00200c2802002101200c10292001450d0020012802002102200110292002450d00024020022802002201450d000340200210292001210220012802002208210120080d000b0b200210290b02402010450d002000200f36020420004101360200200041086a20143602000c160b200441a0026a41106a2007360200200441a0026a410c6a20123602002004200e3602a802200420143602a4022004200f3602a002200441b0036a200441a0026a2009280260108903024020042802b0034101470d000240200441b0036a41086a280200450d0020042802b40310290b200041968fc50036020420004101360200200041086a41233602000c160b200441c4036a2802002102200441b0036a41106a2802002112200441b0036a410c6a2802002110200441b8036a280200210d20042802b4032108200328025821032004410036029002200442013703880202400240410410272201450d002004410436028c022004200428029002220b41046a3602900220042001360288022001200b6a200836000002400240200428028c02220820042802900222016b4104490d0020042802880221080c010b200141046a220b2001490d0320084101742201200b200b2001491b22014100480d030240024020080d002001102721080c010b20042802880220082001102821080b2008450d022004200136028c02200420083602880220042802900221010b2004200141046a36029002200820016a200d36000020102002412c6c22016a210d024020020d00201021010c0e0b200141546a2113200441b0036a4101722102200441b0036a41276a210b200441b0036a41206a210c200441b0036a41186a210e200441b0036a41106a2107200441b0036a41086a211120102101034020012d00002108200b200141286a280000360000200c200141216a290000370300200e200141196a2900003703002007200141116a2900003703002011200141096a2900003703002004200141016a2900003703b00302402008410f470d002001412c6a21010c0f0b200441a0026a41276a2214200b280000360000200441a0026a41206a220f200c290300370300200441a0026a41186a200e2903002218370300200441a0026a41106a20072903002219370300200441a0026a41086a20112903002227370300200420042903b00322283703a00220022028370000200241086a2027370000200241106a2019370000200241186a2018370000200241206a200f290300370000200241276a2014280000360000200420083a00b003200441e0006a200441b0036a20044188026a108a0320042d00602208411a470d0d201341546a21132001412c6a2201200d470d000b200d21010c0d0b41044101102a000b20014101102a000b102b000b41f0004108102a000b41104108102a000b41014101102a000b41014101102a000b41104108102a000b200e4104102a000b41034101102a000b41034101102a000b41014101102a000b200428026421152004280268210302402013450d002001412c6a2101200441b0036a4101722102200441b0036a41276a210c200441b0036a41206a210e200441b0036a41186a2107200441b0036a41106a2111200441b0036a41086a2113034020012d0000210b200c200141286a280000360000200e200141216a2900003703002007200141196a2900003703002011200141116a2900003703002013200141096a2900003703002004200141016a2900003703b003200b410f460d01200441a0026a41276a2214200c280000360000200441a0026a41206a220f200e290300370300200441a0026a41186a20072903002218370300200441a0026a41106a20112903002219370300200441a0026a41086a20132903002227370300200420042903b00322283703a00220022028370000200241086a2027370000200241106a2019370000200241186a2018370000200241206a200f290300370000200241276a20142800003600002004200b3a00b003200441b0036a1088032001412c6a2201200d470d000b0b02402012450d00201010290b0240200428028c02450d0020042802880210290b024020084105470d002003450d00201510290b200041d791c50036020420004101360200200041086a41253602000c0a0b02402001200d460d00200441b0036a4101722102200441b0036a41276a210b200441b0036a41206a210c200441b0036a41186a210e200441b0036a41106a2107200441b0036a41086a2111034020012d00002108200b200141286a280000360000200c200141216a290000370300200e200141196a2900003703002007200141116a2900003703002011200141096a2900003703002004200141016a2900003703b0032008410f460d01200441a0026a41276a2213200b280000360000200441a0026a41206a2214200c290300370300200441a0026a41186a200e2903002218370300200441a0026a41106a20072903002219370300200441a0026a41086a20112903002227370300200420042903b00322283703a00220022028370000200241086a2027370000200241106a2019370000200241186a2018370000200241206a2014290300370000200241276a2013280000360000200420083a00b003200441b0036a1088032001412c6a2201200d470d000b0b02402012450d00201010290b2004280288022101200429028c0221182000411c6a41003a0000200041146a2018370200200041106a20013602002000410c6a2017360200200041086a2016360200200020033602042000411d6a20042f00f0013b0000200041003602002000411f6a200441f2016a2d00003a00000c090b200020083602040c070b20121029200041edf4c2003602040c060b20121029200041edf4c2003602040c050b02400240200241ec88c500460d0041ec88c5002002410b10d0040d010b4126210c41edf4c200210e20142d000c41e000470d0420142802080d042011210220142d000d4104460d010c040b024002402002419089c500460d00419089c5002002410b10d0040d010b4126210c41edf4c200210e20142d000c41e000470d0420142802080d042011210220142d000d4104460d010c040b0240200241ab8ac500460d0041ab8ac5002002410b10d0040d020b0240024041021027220c450d00200c41003b0000024020142d000c41e000470d0020142802084102470d002014280200210e41002101034020014102460d03200c20016a2102200e20016a2108200141016a210120082d000020022d0000460d000b0b200c10290c030b41024101102a000b20142d000d2101200c10292011210220014104460d000c020b0b41262101200041edf4c2003602040c020b4126210c41edf4c200210e0b200c21012000200e3602040b20004101360200200041086a200136020002402007450d00200b2007412c6c6a2100200b210c0340200c220d412c6a210c02400240200d2d00002201410d4b0d00024002400240024002400240024002400240024002400240024020010e0e0001020304050607080e090a0b0c000b200d41086a280200450d0d200d41046a28020010290c0d0b0240200d41086a280200450d00200d41046a28020010290b200d41146a280200450d0c200d41106a28020010290c0c0b0240200d410c6a2802002202450d00200d41046a28020021012002410474210203400240200141046a280200450d00200128020010290b200141106a2101200241706a22020d000b0b200d41086a280200450d0b200d28020410290c0b0b0240200d410c6a2802002202450d00200d41046a2802002101200241286c210203400240200141046a280200450d00200128020010290b0240200141106a280200450d002001410c6a28020010290b200141286a2101200241586a22020d000b0b200d41086a280200450d0a200d28020410290c0a0b200d41086a280200450d09200d41046a28020010290c090b200d41086a280200450d08200d41046a28020010290c080b200d41086a280200450d07200d41046a28020010290c070b0240200d410c6a2802002201450d00200d41046a280200220820014104746a210e0340024020082802082202450d0020082802002101200241047421020340024020012d00004109470d00200141086a28020041ffffffff0371450d00200141046a28020010290b200141106a2101200241706a22020d000b0b200841106a21010240200841046a280200450d00200828020010290b200121082001200e470d000b0b200d41086a280200450d06200d28020410290c060b0240200d410c6a2802002202450d00200d41046a2802002101200241146c210203400240200141046a280200450d00200128020010290b200141146a21012002416c6a22020d000b0b200d41086a280200450d05200d28020410290c050b0240200d410c6a2802002201450d00200d41046a28020022082001411c6c6a210e034002402008410c6a2802002202450d0020082802042101200241047421020340024020012d00004109470d00200141086a28020041ffffffff0371450d00200141046a28020010290b200141106a2101200241706a22020d000b0b0240200841086a280200450d00200828020410290b2008411c6a21010240200841146a280200450d00200828021010290b200121082001200e470d000b0b200d41086a280200450d04200d28020410290c040b0240200d410c6a2802002201450d00200d41046a2802002208200141186c6a210e03400240200841046a280200450d00200828020010290b0240200841146a2802002202450d00200828020c2101200241047421020340024020012d00004109470d00200141086a28020041ffffffff0371450d00200141046a28020010290b200141106a2101200241706a22020d000b0b200841186a21010240200841106a280200450d00200828020c10290b200121082001200e470d000b0b200d41086a280200450d03200d28020410290c030b0240200d410c6a2802002201450d00200d41046a28020022082001411c6c6a210e034002402008410c6a2802002202450d0020082802042101200241047421020340024020012d00004109470d00200141086a28020041ffffffff0371450d00200141046a28020010290b200141106a2101200241706a22020d000b0b0240200841086a280200450d00200828020410290b2008411c6a21010240200841146a280200450d00200828021010290b200121082001200e470d000b0b200d41086a280200450d02200d28020410290c020b0240200d41046a2d0000220141024b0d0002400240024020010e03000102000b200d410c6a280200450d04200d41086a28020010290c040b0240200d41146a2802002202450d00200d410c6a28020021012002410c6c21020340024020012802002208450d00200141046a280200450d00200810290b2001410c6a2101200241746a22020d000b0b200d41106a280200450d03200d28020c10290c030b0240200d41146a2802002201450d00200d410c6a280200220720014104746a211103402007220e41106a21070240200e2802042201450d000240200e410c6a2802002202450d002002410c6c21020340024020012802002208450d00200141046a280200450d00200810290b2001410c6a2101200241746a22020d000b0b200e41086a280200450d00200e28020410290b20072011470d000b0b200d41106a280200450d02200d28020c10290c020b200d410c6a280200450d01200d41086a28020010290c010b0240200d41086a280200450d00200d41046a28020010290b0240200d41146a2802002201450d00200d41186a280200450d00200110290b200d41246a280200450d00200d41206a28020010290b200c2000470d000b0b200a450d00200b10290b200441c0046a24000bb21c05017f027e037f027e097f23004180066b220224004202210302400240024002400240024002400240024002400240200129036822044202520d00200241186a20014198016a41880110ce041a0c010b20024186026a200141036a2d00003a0000200241e8016a41086a200141146a290200370300200241e8016a410d6a200141196a290000370000200220012f00013b0184022002200129020c3703e80120012d000021052001280204210620012802082107200241c0026a200141dc006a290000370300200241b8026a200141d4006a290000370300200241b0026a200141cc006a290000370300200241a8026a200141c4006a290000370300200241a0026a2001413c6a29000037030020024188026a41106a200141346a29000037030020024188026a41086a2001412c6a2900003703002002200129002437038802200241c8026a41086a20014188016a290300370300200241c8026a41106a20014190016a290300370300200220014180016a2903003703c802200141f8006a290300210820012903702109200241086a41888dc300410d10940142002103024020044201520d002009500d022002290310420020022802081b2203200820082003541b2203200320087d2009827d21030b41101027220a450d02200a41086a41002900bf8d43370000200a41002900b78d43370000200a411041201028220a450d03200a2003370010200241e0056a41186a220b4200370300200241e0056a41106a220c4200370300200241e0056a41086a220d4200370300200242003703e005200a4118200241e0056a1000200241c0056a41186a200b290300370300200241c0056a41106a200c290300370300200241c0056a41086a200d290300370300200220022903e0053703c005200241c0056a412041b8d6c50041004100100b210b200a102902400240200b417f470d004101210a411f210b41afb8c300210c0c010b200241b8036a2003108702200241be056a20022d00ba033a0000200241e8056a200241cb036a290000370300200241ed056a200241b8036a41186a290000370000200220022f01b8033b01bc05200220022900c3033703e00520022800bb03210c20022800bf03210b4100210a0b200241b8056a41026a220d200241bc056a41026a220e2d00003a000020024190056a41086a220f200241e0056a41086a221029030037030020024190056a41106a200241e0056a41106a290300370300200220022f01bc053b01b805200220022903e005370390050240200a450d002002419c036a41026a200241b4056a41026a2d00003a000020024180036a41086a200241a0036a41086a29030037030020024180036a41106a200241a0036a41106a290300370300200220022f01b4053b019c03200220022903a00337038003200041086a200b3602002000200c3602042000410136020020014198016a103d0c0a0b200241a0036a410d6a221120024190056a410d6a290000370000200241a0036a41086a220a200f2903003703002002419c036a41026a220f200d2d00003a000020024180036a41086a220d200a29030037030020024180036a41106a200241a0036a41106a290300370300200220022f01b8053b019c03200220022903900537038003200241fc026a41026a220a200f2d00003a0000200220022f019c033b01fc02200241e0026a410d6a220f20024180036a410d6a290000370000200241e0026a41086a2212200d29030037030020022002290380033703e002200241b8036a20014198016a41880110ce041a200241b8036a4198016a2008370300200241c8046a2009370300200241f7046a200b360000200241f3046a200c360000200241d8046a220b20022903c802370300200241e0046a200241c8026a41086a290300370300200241e8046a200241c8026a41106a290300370300200241f2046a200a2d00003a0000200241fb046a20022903e00237000020024183056a201229030037000020024188056a200f290000370000200220043703c004200220022f01fc023b01f004200e20024184026a41026a2d00003a00002010200241e8016a41086a290300370300200241e0056a410d6a2201200241e8016a410d6a290000370000200220022f0184023b01bc05200220022903e8013703e005024002400240200541ff01714101470d0020024180036a200641067610cc01200228028003210a024002402002280288032006413f7122014b0d00410021010c010b200241b8056a41026a200a20014105746a220141026a2d00003a0000200241a8036a200141136a290000370300200241ad036a200141186a290000370000200220012f00003b01b8052002200129000b3703a0032001280007210720012800032106410121010b0240200228028403450d00200a10290b20010d01410121014184efc2002106411521070c020b200241b8056a41026a200241bc056a41026a2d00003a0000200241a0036a41086a200241e0056a41086a29030037030020112001290000370000200220022f01bc053b01b805200220022903e0053703a0030b20024180036a41026a200241b8056a41026a2d00003a0000200241e0056a41086a200241a0036a41086a290300370300200241e0056a410d6a200241a0036a410d6a290000370000200220022f01b8053b018003200220022903a0033703e005410021010b200241b4056a41026a220a20024180036a41026a2d00003a0000200241c0056a41086a220c200241e0056a41086a290300370300200241c0056a41106a200241e0056a41106a290300370300200220022f0180033b01b405200220022903e0053703c00502402001450d002000200636020420004101360200200041086a2007360200200241b8036a103d0c0a0b200241a3056a200c290300370000200241a8056a200241cd056a290000370000200220022f01b4053b01900520022007360097052002200636009305200220022903c00537009b052002200a2d00003a009205200241003602e805200242013703e005200241b8036a200241e0056a10320240024020022903c0044201510d000240024020022802e40520022802e8052201460d0020022802e005210a0c010b200141016a220a2001490d0a20014101742206200a200a2006491b22064100480d0a0240024020010d0020061027210a0c010b20022802e005200120061028210a0b200a450d07200220063602e4052002200a3602e00520022802e80521010b2002200141016a3602e805200a20016a41003a00000c010b20022903d00420022903c8042204420c882203420120034201561b8021030240024020022802e405220a20022802e80522016b4102490d0020022802e005210a0c010b200141026a22062001490d09200a4101742201200620062001491b22014100480d0902400240200a0d0020011027210a0c010b20022802e005200a20011028210a0b200a450d07200220013602e4052002200a3602e00520022802e80521010b2002200141026a3602e805200a20016a2003a741047420047aa7417f6a22014101200141014b1b2201410f2001410f491b723b00000b200b200241e0056a10542002200241e0046a3602c005200241c0056a200241e0056a10590240024020022802e405220c20022802e805220a6b4120490d0020022802e00521010c010b200a41206a2201200a490d08200c410174220a20012001200a491b22064100480d0802400240200c0d002006102721010c010b20022802e005200c2006102821010b2001450d07200220063602e405200220013602e00520022802e805210a2006210c0b2001200a6a2206200241f0046a220b290000370000200641186a200b41186a290000370000200641106a200b41106a290000370000200641086a200b41086a29000037000002400240200a41206a220a4180024b0d0002402001200a20024188026a20024190056a10140d004101210a0c020b2001200a20024188026a20024190056a101545210a0c010b200241e0056a41186a22064200370300200241e0056a41106a220b4200370300200241e0056a41086a220d4200370300200242003703e0052001200a200241e0056a1000200241c0056a41186a2006290300370300200241c0056a41106a200b290300370300200241c0056a41086a200d290300370300200220022903e0053703c0050240200241c0056a412020024188026a20024190056a10140d004101210a0c010b200241c0056a412020024188026a20024190056a101545210a0b0240200c450d00200110290b200a450d08200241c8016a41186a20024190056a41186a290300370300200241c8016a41106a20024190056a41106a290300370300200241c8016a41086a20024190056a41086a290300370300200241a0016a41086a200241d0046a290300370300200241a0016a41106a200241d8046a290300370300200241a0016a41186a200241e0046a290300370300200241c0016a200241e8046a29030037030020022002290390053703c8012002200241c8046a2903003703a00120022903c0042103200241186a200241b8036a41880110ce041a0b200041086a20022903c801370300200041286a2003370300200041306a20022903a001370300200041206a200241c8016a41186a290300370300200041186a200241c8016a41106a290300370300200041106a200241c8016a41086a290300370300200041386a200241a0016a41086a290300370300200041c0006a200241a0016a41106a290300370300200041c8006a200241a0016a41186a290300370300200041d0006a200241a0016a41206a290300370300200041d8006a200241186a41880110ce041a2000410036020020024180066a24000f0b41a8cec5001058000b41104101102a000b41204101102a000b20064101102a000b20014101102a000b20064101102a000b102b000b200041a981c20036020420004101360200200041086a411a360200200241b8036a103d0b20024180066a24000bfb0301067f230041e0006b22022400024002400240411010272203450d00200341086a41002900bf8d43370000200341002900b78d4337000020034110412010282203450d0120032001370010200241c0006a41186a22044200370300200241c0006a41106a22054200370300200241c0006a41086a220642003703002002420037034020034118200241c0006a1000200241186a2004290300370300200241106a2005290300370300200241086a2006290300370300200220022903403703002002410036024020024120200241c0006a100521060240024020022802402204417f460d00200241c0006a2004412020044120491b22056a41004100412020056b2005411f4b1b10cd041a200241c0006a2006200510ce041a2004411f4d0d04200241206a41186a2204200241c0006a41186a290000370300200241206a41106a2205200241c0006a41106a290000370300200241206a41086a2207200241c0006a41086a2900003703002002200229004037032020061029200041186a2004290300370000200041106a2005290300370000200041086a2007290300370000200020022903203700000c010b200041186a4200370000200041106a4200370000200041086a4200370000200042003700000b20031029200241e0006a24000f0b41104101102a000b41204101102a000b418f89c3004133104e000bf70603057f027e067f230041c0016b22022400200242003703800120024180016a2001280200220320012802042204410820044108491b220510ce041a2001200420056b22063602042001200320056a220536020002400240200441074b0d00200042003703000c010b2002290380012107200242003703800120024180016a20052006410820064108491b220410ce041a2001200620046b22033602042001200520046a22053602000240200641074d0d00200229038001210820024180016a2003412020034120491b22046a41004100412020046b2004411f4b1b10cd041a20024180016a2005200410ce041a2001200320046b22063602042001200520046a220536020002402003411f4b0d00200042003703000c020b200241e0006a41186a220320024180016a41186a2209290000370300200241e0006a41106a220a20024180016a41106a220b290000370300200241e0006a41086a220c20024180016a41086a220d290000370300200220022900800137036020024180016a200641c000200641c000491b22046a4100410041c00020046b2004413f4b1b10cd041a20024180016a2005200410ce041a2001200620046b3602042001200520046a36020002402006413f4b0d00200042003703000c020b200241386a220120024180016a41386a290000370300200241306a220420024180016a41306a290000370300200241286a220520024180016a41286a290000370300200241206a220620024180016a41206a290000370300200241186a220e2009290000370300200241106a2209200b290000370300200241086a220b200d290000370300200241c0006a41086a220d200c290300370300200241c0006a41106a220c200a290300370300200241c0006a41186a220a2003290300370300200220022900800137030020022002290360370340200041106a200837030020002007370308200041186a2002290340370300200041206a200d290300370300200041286a200c290300370300200041306a200a290300370300200041386a2002290300370300200041c0006a200b290300370300200041c8006a2009290300370300200041d0006a200e290300370300200041d8006a2006290300370300200041e0006a2005290300370300200041e8006a2004290300370300200041f0006a2001290300370300200042013703000c010b200042003703000b200241c0016a24000b860204017f017e037f017e230041c0006b2203240042002104200341206a41186a22054200370300200341206a41106a22064200370300200341206a41086a220742003703002003420037032020012002200341206a1000200341186a2005290300370300200341106a2006290300370300200341086a2007290300370300200320032903203703002003410036022020034120200341206a1005210202400240024020032802202201417f470d000c010b20034200370320200341206a20022001410820014108491b10ce041a200141074d0d012003290320210820021029420121040b2000200837030820002004370300200341c0006a24000f0b418f89c3004133104e000bc80101027f230041206b22022400200241106a41086a220342003703002002420037031020002001200241106a1004200241086a2003290300370300200220022903103703002002410036021020024110200241106a10052101024002400240024020022802102200417f470d00410221000c010b200241003a0010200241106a20012000410047220310ce041a20002003490d012000450d0220022d001021002001102920024110100c0b200241206a240020000f0b20032000103e000b418f89c3004133104e000b870802087f0a7e230041e0026b22022400200241386a2001280200200128020428020c1100000240024020022903384201520d0020024198026a4101722103200241386a41086a2104200241ab016a21050340200241a8016a41186a2206200441186a290000370300200241a8016a41106a2207200441106a290000370300200241a8016a41086a2208200441086a290000370300200220042900003703a80120024198026a200241a8016a108c02024002400240024020022d0098024101460d00200241003602e8010c010b200241c0026a41186a200341186a290000370300200241c0026a41106a200341106a290000370300200241c0026a41086a200341086a290000370300200220032900003703c002200241c8016a200241c0026a108d0220022802e80122090d010b4200210a4200210b0c010b200241c8016a41086a290300210b20022903c801210a20022802ec01450d00200910290b20024198026a41086a2008290300220c37030020024198026a41106a2007290300220d37030020024198026a41186a2006290300220e370300200220022903a801220f37039802200241c8016a41086a2207200c370300200241c8016a41106a2208200d370300200241c8016a41186a2209200e3703002002200f3703c801200241206a41b18ac0004116108601200241106a2002290328200241206a41106a290300427f420010d4042002200a200b20022903104200200228022022061b220c4201200c420156200241106a41086a290300420020061b220c420052200c501b22061b200c420020061b10d404024002402002290300220c50450d00410221060c010b200241c0026a41186a2009290300370300200241c0026a41106a2008290300370300200241c0026a41086a2007290300370300200220022903c8013703c002200220022800a8013602a001200220052800003600a3014200211041002106200c2111200a2112200b21130b20024180016a41086a200241c0026a41086a29030037030020024180016a41106a200241c0026a41106a29030037030020024180016a41186a200241c0026a41186a290300370300200220022903c00237038001200220022802a001360278200220022800a30136007b024020064102460d002000201137031020004200370308200042003703002000200229038001370320200020063a004020002002280278360041200041186a2010370300200041d0006a2013370300200041c8006a2012370300200041c4006a200228007b360000200041286a20024188016a290300370300200041306a20024190016a290300370300200041386a20024180016a41186a2903003703000c030b200241386a2001280200200128020428020c11000020022903384201510d000b0b200041023a00400b200241e0026a24000bbd0402087f047e230041e0006b22022400024002400240410e10272203450d00200341066a41002900c7a244370000200341002900c1a2443700002003410e412e10282203450d012003200129000037000e200341266a200141186a2900003700002003411e6a200141106a290000370000200341166a200141086a290000370000200241206a41186a22014200370300200241206a41106a22044200370300200241206a41086a22054200370300200242003703202003412e200241206a1000200241186a2001290300370300200241106a2004290300370300200241086a2005290300370300200220022903203703002002410036024020024120200241c0006a100521050240024020022802402201417f460d00200241206a2001412020014120491b22046a41004100412020046b2004411f4b1b10cd041a200241206a2005200410ce041a2001411f4d0d04200241c0006a41186a2201200241206a41186a2204290300370300200241c0006a41106a2206200241206a41106a2207290300370300200241c0006a41086a2208200241206a41086a2209290300370300200220022903203703402005102920042001290300220a37030020072006290300220b37030020092008290300220c37030020022002290340220d370320200041013a00002000200d370001200041096a200c370000200041116a200b370000200041196a200a3700000c010b200041003a00000b20031029200241e0006a24000f0b410e4101102a000b412e4101102a000b418f89c3004133104e000bee05010c7f230041d0016b2202240002400240024002400240410e10272203450d00200341066a410029009fa34437000020034100290099a3443700002003410e412e10282203450d012003200129000037000e200341266a200141186a2900003700002003411e6a200141106a290000370000200341166a200141086a290000370000200241f8006a41186a22014200370300200241f8006a41106a22044200370300200241f8006a41086a22054200370300200242003703782003412e200241f8006a1000200241d8006a41186a2001290300370300200241d8006a41106a2004290300370300200241d8006a41086a20052903003703002002200229037837035820024100360278200241d8006a4120200241f8006a1005210420022802782201417f460d03200220013602cc01200220043602c801200241f8006a200241c8016a10d3032002280298012205450d02200241386a41186a2206200241f8006a41186a290300370300200241386a41106a2207200241f8006a41106a290300370300200241386a41086a2208200241f8006a41086a290300370300200241086a41086a2209200241f8006a412c6a290200370300200241086a41106a220a200241f8006a41346a290200370300200241086a41186a220b200241f8006a413c6a290200370300200241286a220c200241f8006a41c4006a290200370300200241306a220d200241f8006a41cc006a280200360200200220022903783703382002200229029c0137030802402001450d00200410290b200020022903383703002000200536022020002002290308370224200041186a2006290300370300200041106a2007290300370300200041086a20082903003703002000412c6a2009290300370200200041346a200a2903003702002000413c6a200b290300370200200041c4006a200c290300370200200041cc006a200d2802003602000c040b410e4101102a000b412e4101102a000b418f89c3004133104e000b200041003602200b20031029200241d0016a24000b8e0a03077f037e047f230041d0016b22022400200241b0016a41186a22034200370300200241b0016a41106a22044200370300200241b0016a41086a22054200370300200242003703b001200241b0016a2001280200220620012802042207412020074120491b220810ce041a2001200720086b3602042001200620086a360200024002402007411f4b0d00410021070c010b20024190016a41186a2003290300220937030020024190016a41106a2004290300220a37030020024190016a41086a2005290300220b370300200241f0006a41086a200b370300200241f0006a41106a200a370300200241f0006a41186a2009370300200220022903b00122093703900120022009370370410121070b200241b0016a41186a2208200241f0006a41186a290300370300200241b0016a41106a2206200241f0006a41106a290300370300200241b0016a41086a2203200241f0006a41086a290300370300200220022903703703b0010240024020070d00200041003602080c010b200241306a41186a2008290300370300200241306a41106a2006290300370300200241306a41086a2003290300370300200220022903b00137033020022001105202402002290300a70d00200041003602080c010b20022903082109200241b0016a41186a22044200370300200241b0016a41106a22054200370300200241b0016a41086a220c4200370300200242003703b001200241b0016a2001280200220320012802042207412020074120491b220810ce041a2001200720086b22063602042001200320086a220836020002402007411f4b0d00200041003602080c010b200241d0006a41086a200c290300370300200241d0006a41106a2005290300370300200241d0006a41186a2004290300370300200220022903b001370350200241b0016a2006412020064120491b22076a41004100412020076b2007411f4b1b10cd041a200241b0016a2008200710ce041a2001200620076b3602042001200820076a36020002402006411f4b0d00200041003602080c010b200241f0006a41086a2203200241b0016a41086a2207290300370300200241f0006a41106a2204200241b0016a41106a2208290300370300200241f0006a41186a2205200241b0016a41186a2206290300370300200220022903b001370370200241106a200110430240200228021022010d00200041003602080c010b2007200241306a41086a2903003703002008200241306a41106a2903003703002006200241306a41186a29030037030020024190016a41086a220c200241d0006a41086a29030037030020024190016a41106a220d200241d0006a41106a29030037030020024190016a41186a220e200241d0006a41186a290300370300200220022903303703b00120022002290350370390012002290214210a200241106a41186a220f2005290300370300200241106a41106a22052004290300370300200241106a41086a22042003290300370300200220022903703703102000200a37020c2000200136020820002009370300200041146a20022903b0013702002000411c6a2007290300370200200041246a20082903003702002000412c6a2006290300370200200041346a2002290390013702002000413c6a200c290300370200200041c4006a200d290300370200200041cc006a200e290300370200200041ec006a200f290300370200200041e4006a2005290300370200200041dc006a2004290300370200200041d4006a20022903103702000b200241d0016a24000bcb2a04057f027e027f047e230041e0046b22022400200241003a00d402200241d4026a2001280200220320012802042204410047220510ce041a0240024002400240024002400240024002400240024020042005490d002001200420056b22063602042001200320056a2205360200024020040d00200041123a00000c0b0b024020022d00d402220441104b0d000240024002400240024002400240024002400240024002400240024002400240024020040e11000102030405060708090a0b0c0d0e0f10000b200241d8036a2001103c20022802d8032104200241d4026a200241d8036a41047241840110ce041a024020044112470d00200041123a00000c1c0b200241d0016a200241d4026a41840110ce041a41880110272205450d1220052004360200200541046a200241d0016a41840110ce041a20022001105302402002290300a70d00200041123a00002005103d200510290c1c0b200241106a290300210720022903082108200041013a0000200020022f00b0013b0001200041086a2008370300200041046a2005360200200041186a2002290358370300200041106a2007370300200041036a200241b2016a2d00003a0000200041206a200241d8006a41086a290300370300200041286a200241d8006a41106a290300370300200041306a200241d8006a41186a2903003703000c1b0b200241186a2001102e024020022802180d00200041123a00000c1b0b200228021c2101200041023a0000200020022f00d4023b0001200041046a2001360200200041086a20022903d803370300200041036a200241d4026a41026a2d00003a0000200041106a200241d8036a41086a290300370300200041186a200241d8036a41106a290300370300200041206a200241d8036a41186a290300370300200041286a200241d8036a41206a290300370300200041306a200241d8036a41286a2903003703000c1a0b200241206a2001102e024020022802200d00200041123a00000c1a0b20022802242106200241003a00d402200241d4026a2001280200220320012802042204410047220510ce041a20042005490d112001200420056b3602042001200320056a360200024002402004450d0020022d00d402220141ff007122044106490d010b200041123a00000c1a0b200041033a0000200041046a2006360200200041026a20043a0000200020014107763a0001200041086a20022903d803370300200041106a200241d8036a41086a290300370300200041186a200241d8036a41106a290300370300200041206a200241d8036a41186a290300370300200041286a200241d8036a41206a290300370300200041306a200241d8036a41286a2903003703000c190b200241286a2001102e024020022802280d00200041123a00000c190b200228022c2106200241003a00d402200241d4026a2001280200220320012802042204410047220510ce041a20042005490d112001200420056b3602042001200320056a360200024002402004450d0020022d00d402220141ff007122044106490d010b200041123a00000c190b200041043a0000200041046a2006360200200041026a20043a0000200020014107763a0001200041086a20022903d803370300200041106a200241d8036a41086a290300370300200041186a200241d8036a41106a290300370300200041206a200241d8036a41186a290300370300200041286a200241d8036a41206a290300370300200041306a200241d8036a41286a2903003703000c180b200241d8036a2001103c20022802d8032104200241d4026a200241d8036a41047241840110ce041a024020044112470d00200041123a00000c180b200241d0016a200241d4026a41840110ce041a41880110272205450d1120052004360200200541046a200241d0016a41840110ce041a200241003a00d402200241d4026a2001280200220920012802042204410047220310ce041a20042003490d122001200420036b22063602042001200920036a2203360200024002402004450d0020022d00d402220a4103490d010b200041123a00000c170b200242003703d803200241d8036a20032006410820064108491b220410ce041a2001200620046b22093602042001200320046a22043602000240200641074b0d00200041123a00000c170b20022903d8032107200242003703d803200241d8036a20042009410820094108491b220310ce041a2001200920036b3602042001200420036a3602000240200941074b0d00200041123a00000c170b200041106a20022903d803370300200041086a2007370300200041046a20053602002000200a3a0001200041053a0000200041186a2002290358370300200041206a200241d8006a41086a290300370300200041286a200241d8006a41106a290300370300200041306a200241d8006a41186a2903003703000c170b200241003602d402200241d4026a20052006410420064104491b220410ce041a2001200620046b3602042001200520046a3602000240200641034b0d00200041123a00000c170b20022802d4022101200041063a0000200020022f00d0013b0001200041046a2001360200200041086a20022903d803370300200041036a200241d2016a2d00003a0000200041106a200241d8036a41086a290300370300200041186a200241d8036a41106a290300370300200041206a200241d8036a41186a290300370300200041286a200241d8036a41206a290300370300200041306a200241d8036a41286a2903003703000c160b200241d8036a2001103c20022802d8032101200241d4026a200241d8036a41047241840110ce041a024020014112470d00200041123a00000c160b200241d0016a200241d4026a41840110ce041a41880110272204450d1120042001360200200441046a200241d0016a41840110ce041a200041073a0000200020022f00b0013b0001200041036a200241b2016a2d00003a0000200041046a2004360200200041086a2002290358370300200041106a200241d8006a41086a290300370300200041186a200241d8006a41106a290300370300200041206a200241d8006a41186a290300370300200041286a200241d8006a41206a290300370300200041306a200241d8006a41286a2903003703000c150b200241d8036a2001103c20022802d8032101200241d4026a200241d8036a41047241840110ce041a024020014112470d00200041123a00000c150b200241d0016a200241d4026a41840110ce041a41880110272204450d1120042001360200200441046a200241d0016a41840110ce041a200041083a0000200020022f00b0013b0001200041036a200241b2016a2d00003a0000200041046a2004360200200041086a2002290358370300200041106a200241d8006a41086a290300370300200041186a200241d8006a41106a290300370300200041206a200241d8006a41186a290300370300200041286a200241d8006a41206a290300370300200041306a200241d8006a41286a2903003703000c140b41002109200241d4026a2006412020064120491b22046a41004100412020046b2004411f4b1b10cd041a200241d4026a2005200410ce041a2001200620046b22033602042001200520046a220436020002402006411f4d0d00200241d0016a41186a200241d4026a41186a2900002207370300200241d0016a41106a200241d4026a41106a2900002208370300200241d0016a41086a200241d4026a41086a290000220b370300200241d8006a41086a200b370300200241d8006a41106a2008370300200241d8006a41186a2007370300200220022900d40222073703d00120022007370358410121090b200241d8036a41186a2205200241d8006a41186a290300370300200241d8036a41106a2206200241d8006a41106a290300370300200241d8036a41086a220a200241d8006a41086a290300370300200220022903583703d803024020090d00200041123a00000c140b200241b0016a41186a2005290300370300200241b0016a41106a2006290300370300200241b0016a41086a200a290300370300200220022903d8033703b001200242003703d803200241d8036a20042003410820034108491b220510ce041a2001200320056b22063602042001200420056a22043602000240200341074b0d00200041123a00000c140b20022903d8032107200242003703d803200241d8036a20042006410820064108491b220510ce041a2001200620056b3602042001200420056a3602000240200641074b0d00200041123a00000c140b20024190016a41086a200241b0016a41086a290300220837030020024190016a41106a200241b0016a41106a290300220b37030020024190016a41186a200241b0016a41186a290300220c370300200220022903b001220d3703900120022903d803210e200041093a00002000200d370001200041096a2008370000200041116a200b370000200041196a200c370000200041216a200228008901360000200041246a2002418c016a280000360000200041306a200e370300200041286a20073703000c130b41002103200241d4026a2006412020064120491b22046a41004100412020046b2004411f4b1b10cd041a200241d4026a2005200410ce041a2001200620046b3602042001200520046a36020002402006411f4d0d00200241d0016a41186a200241d4026a41186a2900002207370300200241d0016a41106a200241d4026a41106a2900002208370300200241d0016a41086a200241d4026a41086a290000220b370300200241d8006a41086a200b370300200241d8006a41106a2008370300200241d8006a41186a2007370300200220022900d40222073703d00120022007370358410121030b200241d8036a41186a2201200241d8006a41186a290300370300200241d8036a41106a2204200241d8006a41106a290300370300200241d8036a41086a2205200241d8006a41086a290300370300200220022903583703d803024020030d00200041123a00000c130b200241b0016a41186a20012903002207370300200241b0016a41106a20042903002208370300200241b0016a41086a2005290300220b370300200220022903d803220c3703b0012000410a3a00002000200c370001200041096a200b370000200041116a2008370000200041196a2007370000200041216a200229009001370000200041296a20024190016a41086a290000370000200041306a2002419f016a2900003700000c120b200241306a2001102e024020022802300d00200041123a00000c120b200228023421012000410b3a0000200020022f00d4023b0001200041046a2001360200200041086a20022903d803370300200041036a200241d6026a2d00003a0000200041106a200241d8036a41086a290300370300200041186a200241d8036a41106a290300370300200041206a200241d8036a41186a290300370300200041286a200241d8036a41206a290300370300200041306a200241d8036a41286a2903003703000c110b200241c8006a2001105202402002290348a70d00200041123a00000c110b20022903502107200241c0006a2001102e024020022802400d00200041123a00000c110b20022802442104200241386a2001102e024020022802380d00200041123a00000c110b200228023c21012000410c3a0000200020022f00d4023b0001200041106a2007370300200041086a2001360200200041046a2004360200200041186a20022903d803370300200041036a200241d6026a2d00003a0000200041206a200241d8036a41086a290300370300200041286a200241d8036a41106a290300370300200041306a200241d8036a41186a2903003703000c100b200241d4026a2006412020064120491b22046a41004100412020046b2004411f4b1b10cd041a200241d4026a2005200410ce041a2001200620046b3602042001200520046a36020002402006411f4b0d00200041123a00000c100b200241d8006a41086a200241d4026a41086a2900002208370300200241d8006a41106a200241d4026a41106a290000220b370300200241d8006a41186a200241d4026a41186a290000220c370300200220022900d40222073703d803200220073703582000410d3a000020002007370001200041096a2008370000200041116a200b370000200041196a200c370000200041216a20022900b001370000200041296a200241b0016a41086a290000370000200041306a200241bf016a2900003700000c0f0b2000410e3a00000c0e0b200241d4026a2006412020064120491b22046a41004100412020046b2004411f4b1b10cd041a200241d4026a2005200410ce041a2001200620046b3602042001200520046a36020002402006411f4b0d00200041123a00000c0e0b200241d8006a41086a200241d4026a41086a2900002208370300200241d8006a41106a200241d4026a41106a290000220b370300200241d8006a41186a200241d4026a41186a290000220c370300200220022900d40222073703d803200220073703582000410f3a000020002007370001200041096a2008370000200041116a200b370000200041196a200c370000200041216a20022900b001370000200041296a200241b0016a41086a290000370000200041306a200241b0016a410f6a2900003700000c0d0b200241d4026a2006412020064120491b22046a41004100412020046b2004411f4b1b10cd041a200241d4026a2005200410ce041a2001200620046b22033602042001200520046a220436020002402006411f4b0d00200041123a00000c0d0b200241d8006a41086a200241d4026a41086a290000370300200241d8006a41106a200241d4026a41106a290000370300200241d8006a41186a200241d4026a41186a290000370300200220022900d40222073703d80320022007370358200241003a00d402200241d4026a20042003410047220510ce041a20032005490d0a2001200320056b3602042001200420056a360200024002402003450d0020022d00d40222014106490d010b200041123a00000c0d0b200241b0016a41186a200241d8006a41186a2903002207370300200241b0016a41106a200241d8006a41106a2903002208370300200241b0016a41086a200241d8006a41086a290300220b37030020022002290358220c3703b001200041103a00002000200c370001200041096a200b370000200041116a2008370000200041196a2007370000200041216a20013a0000200041226a2002290190013701002000412a6a20024190016a41086a290100370100200041306a2002419e016a2901003701000c0c0b200041113a00000c0b0b200041123a00000c0a0b20052004103e000b4188014108102a000b20052004103e000b20052004103e000b4188014108102a000b20032004103e000b4188014108102a000b4188014108102a000b20052003103e000b2005103d200510290b200241e0046a24000b890a02057f047e230041d0036b22022400200241003a00c802200241c8026a2001280200220320012802042204410047220510ce041a02400240024002400240024020042005490d002001200420056b22063602042001200320056a2205360200024020040d00200041053a00000c060b02400240024020022d00c802220441034b0d0002400240024020040e0400010204000b200241c0016a2001102d20022802c00122010d04200041053a00000c0a0b200241c8026a2001103c20022802c8022101200241c0016a200241c8026a41047241840110ce041a024020014112470d00200041053a00000c0a0b200241386a200241c0016a41840110ce041a41880110272204450d0520042001360200200441046a200241386a41840110ce041a200041023a0000200020022f00353b0001200041036a200241356a41026a2d00003a0000200041046a2004360200200041086a2002290214370200200041106a200241146a41086a290200370200200041186a200241146a41106a290200370200200041206a200241146a41186a2902003702000c090b20022001102e024020022802000d00200041053a00000c090b20022802042105200241c8026a2001103c20022802c8022101200241c0016a200241c8026a41047241840110ce041a024020014112470d00200041053a00000c090b200241386a200241c0016a41840110ce041a41880110272204450d0520042001360200200441046a200241386a41840110ce041a200041033a0000200020022f00353b0001200041036a200241376a2d00003a0000200041086a2004360200200041046a20053602002000410c6a2002290214370200200041146a200241146a41086a2902003702002000411c6a200241246a290200370200200041246a2002412c6a2802003602000c080b200041053a00000c070b200241c8026a2006412020064120491b22046a41004100412020046b2004411f4b1b10cd041a200241c8026a2005200410ce041a2001200620046b3602042001200520046a3602002006411f4d0d05200241c0016a41186a200241c8026a41186a290000370300200241c0016a41106a200241c8026a41106a290000370300200241c0016a41086a200241c8026a41086a290000370300200220022900c8023703c001200241086a2001102e024020022802080d00200041053a00000c070b200228020c2106200241003a00c802200241c8026a2001280200220320012802042204410047220510ce041a20042005490d042001200420056b3602042001200320056a360200024020040d00200041053a00000c070b200241386a41086a200241c0016a41086a2903002207370300200241386a41106a200241c0016a41106a2903002208370300200241386a41186a200241c0016a41186a2903002209370300200220022903c001220a37033820022d00c8022101200041043a00002000200a370001200041096a2007370000200041116a2008370000200041196a2009370000200041246a2006360200200041216a20013a00000c060b20022902c4012107200041013a0000200020022f00383b0001200041086a2007370000200041046a2001360000200041106a20022902c802370200200041036a2002413a6a2d00003a0000200041186a200241c8026a41086a290200370200200041206a200241c8026a41106a2902003702000c050b20052004103e000b4188014108102a000b4188014108102a000b20052004103e000b200041053a00000b200241d0036a24000bc12308057f017e017f027e017f037e087f027e230041f0056b22022400200241003a0070200241f0006a2001280200220320012802042204410047220510ce041a02400240024002400240024020042005490d002001200420056b22063602042001200320056a2205360200024020040d00200041073a00000c060b02400240024002400240024020022d0070220441054b0d000240024002400240024020040e06000102030406000b200241d8026a200110f10220024180056a200241d8026a41f00010ce041a200220022800c9033602d0032002200241cc036a2800003600d303024020022d00c80322014102470d00200041073a00000c100b200241e8016a20024180056a41f00010ce041a200220022800d3033600e304200220022802d0033602e004200241f7006a200241e8016a41f00010ce041a200041013a0000200041016a200241f0006a41f70010ce041a200041f8006a20013a0000200041f9006a20022802e004360000200041fc006a20022800e3043600000c0f0b200241086a2001105202402002290308a70d00200041073a00000c0f0b20022903102107200241f0006a20011044200228027022010d05200041073a00000c0e0b200241f0006a2001105020024180056a41086a2204200241f9006a29000037030020024180056a41106a220520024181016a29000037030020024180056a41186a220320024189016a29000037030020024180056a411f6a220620024190016a2800003600002002200229007137038005024020022d007022084102470d00200041073a00000c0e0b200241e8016a411f6a2006280000360000200241e8016a41186a2003290300370300200241e8016a41106a2005290300370300200241e8016a41086a200429030037030020022002290380053703e801200241286a2001105302402002290328a70d00200041073a00000c0e0b200241286a41106a290300210720022903302109200241186a2001105202402002290318a70d00200041073a00000c0e0b2002290320210a200241f0006a20011044200228027022010d05200041073a00000c0d0b200241d0006a2001105302402002290350a70d00200041073a00000c0d0b200241e0006a290300210720022903582109200241c0006a2001105202402002290340a70d00200041073a00000c0d0b2002290348210a20024180056a41186a2206420037030020024180056a41106a2208420037030020024180056a41086a220b4200370300200242003703800520024180056a2001280200220320012802042204412020044120491b220510ce041a2001200420056b3602042001200320056a360200024002402004411f4b0d00410021040c010b200241e8016a41186a2006290300220c370300200241e8016a41106a2008290300220d370300200241e8016a41086a200b290300220e370300200241d0036a41086a200e370300200241d0036a41106a200d370300200241d0036a41186a200c3703002002200229038005220c3703e8012002200c3703d003410121040b200241f0006a41186a2205200241d0036a41186a290300370300200241f0006a41106a2203200241d0036a41106a290300370300200241f0006a41086a2206200241d0036a41086a290300370300200220022903d003370370024020040d00200041073a00000c0d0b200241e0046a41186a2005290300370300200241e0046a41106a2003290300370300200241e0046a41086a2006290300370300200220022903703703e004200241f0006a20011044200228027022010d05200041073a00000c0c0b20024180056a2006412020064120491b22046a41004100412020046b2004411f4b1b10cd041a20024180056a2005200410ce041a2001200620046b22033602042001200520046a220436020002402006411f4b0d00200041073a00000c0c0b200241e0046a41086a20024180056a41086a290000370300200241e0046a41106a20024180056a41106a290000370300200241e0046a41186a20024180056a41186a29000037030020022002290080052207370370200220073703e004200241003a0070200241f0006a20042003410047220510ce041a20032005490d072001200320056b22063602042001200420056a22043602002003450d0820022d0070220541014b0d08410021030240024020050e020100010b20024180056a2006412020064120491b22056a41004100412020056b2005411f4b1b10cd041a20024180056a2004200510ce041a2001200620056b3602042001200420056a3602002006411f4d0d09200241f0006a41086a20024180056a41086a2900002207370300200241d0036a41186a20024180056a41186a290000370300200241d0036a41106a20024180056a41106a290000370300200241d0036a41086a200737030020022002290080052207370370200220073703d003410121030b200241a0046a41086a2201200241d0036a41086a290300370300200241a0046a41106a2204200241d0036a41106a290300370300200241a0046a41186a2205200241d0036a41186a290300370300200241c0046a41086a2206200241e0046a41086a290300370300200241c0046a41106a2208200241e0046a41106a290300370300200241c0046a41186a220b200241e0046a41186a290300370300200220022903d0033703a004200220022903e0043703c004200041053a0000200041216a20033a0000200020022903c004370001200041096a2006290300370000200041116a2008290300370000200041196a200b290300370000200041226a20022903a0043700002000412a6a2001290300370000200041326a20042903003700002000413a6a2005290300370000200041f8006a2002418e036a290100370100200041f2006a20024188036a290100370100200041ea006a20024180036a290100370100200041e2006a200241f8026a290100370100200041da006a200241d8026a41186a290100370100200041d2006a200241d8026a41106a290100370100200041ca006a200241d8026a41086a290100370100200041c2006a20022901d8023701000c0b0b200041073a00000c0a0b20024180056a2006412020064120491b22046a41004100412020046b2004411f4b1b10cd041a20024180056a2005200410ce041a2001200620046b22033602042001200520046a22053602002006411f4d0d08200241e0046a41086a20024180056a41086a2208290000370300200241e0046a41106a20024180056a41106a220b290000370300200241e0046a41186a20024180056a41186a220f29000037030020022002290080052207370370200220073703e00420024180056a2003412020034120491b22046a41004100412020046b2004411f4b1b10cd041a20024180056a2005200410ce041a2001200320046b22063602042001200520046a220436020002402003411f4b0d00200041073a00000c0a0b200241d0036a41086a2008290000370300200241d0036a41106a200b290000370300200241d0036a41186a200f29000037030020022002290080053703d003200242003703e002200242003703d802200241d8026a20042006411020064110491b220510ce041a2001200620056b3602042001200420056a36020002402006410f4b0d00200041073a00000c0a0b200241e0026a290300210720022903d8022109200241e8006a2001102e02402002280268450d0002400240200228026c22104180012010418001491b220b0d004101210f0c010b200b41057422041027220f450d090b02402010450d00200241d8026a41186a2111200241d8026a41106a2112200241d8026a41086a21134100210841002103410021050340201142003703002012420037030020134200370300200242003703d802200241d8026a2001280200221420012802042204412020044120491b220610ce041a2001200420066b3602042001201420066a36020002402004411f4b0d00200b450d03200f10290c030b200541016a2104200241f0006a41186a22062011290300370300200241f0006a41106a22142012290300370300200241f0006a41086a22152013290300370300200220022903d80237037002402005200b470d0002402008200420042008491b220b41ffffff3f71200b470d00200b41057422164100480d000240024020050d0020161027210f0c010b200f200320161028210f0b200f0d0120164101102a000b102b000b200f20036a22052002290370370000200541186a2006290300370000200541106a2014290300370000200541086a2015290300370000200841026a2108200341206a21032004210520102004470d000b0b200f0d040b200041073a00000c090b20022902742109200041023a0000200020022f0080053b0001200041106a2007370300200041086a2009370000200041046a2001360000200041036a20024180056a41026a2d00003a0000200041186a200241d8026a41e80010ce041a0c080b200241d0036a41086a2204200241e8016a41086a290300370300200241d0036a41106a2205200241e8016a41106a290300370300200241d0036a41186a2203200241e8016a41186a290300370300200241d0036a411f6a2206200241e8016a411f6a280000360000200220022903e8013703d0032002290274210c200041033a0000200020022f00e0043b0001200041036a200241e2046a2d00003a0000200041046a20083a0000200041c0006a2007370300200041386a2009370300200041c8006a200a3703002000412c6a200c370200200041286a2001360200200041056a20022903d0033700002000410d6a2004290300370000200041156a20052903003700002000411d6a2003290300370000200041246a2006280000360000200041f8006a200241d8026a41286a290300370300200041f0006a200241f8026a290300370300200041e8006a200241d8026a41186a290300370300200041e0006a200241d8026a41106a290300370300200041d8006a200241d8026a41086a290300370300200041d0006a20022903d8023703000c070b200241c0046a41086a200241e0046a41086a290300220c370300200241c0046a41106a200241e0046a41106a290300220d370300200241c0046a41186a200241e0046a41186a290300220e370300200220022903e00422173703c00420022902742118200041386a2007370300200041306a2009370300200041043a000020002017370001200041096a200c370000200041116a200d370000200041196a200e370000200041216a20022f00a0043b0000200041236a200241a2046a2d00003a0000200041c0006a200a370300200041286a2018370000200041246a2001360000200041c8006a20022903d802370300200041d0006a200241d8026a41086a290300370300200041d8006a200241d8026a41106a290300370300200041e0006a200241d8026a41186a290300370300200041e8006a200241f8026a290300370300200041f0006a200241d8026a41286a290300370300200041f8006a200241d8026a41306a2903003703000c060b200241c0046a41186a2201200241e0046a41186a290300370300200241c0046a41106a2204200241e0046a41106a290300370300200241c0046a41086a2205200241e0046a41086a290300370300200241a0046a41086a2203200241d0036a41086a290300370300200241a0046a41106a2206200241d0036a41106a290300370300200241a0046a41186a2208200241d0036a41186a290300370300200220022903e0043703c004200220022903d0033703a004200041063a0000200020022903c004370001200041096a2005290300370000200041116a2004290300370000200041196a2001290300370000200041216a20022903a004370000200041296a2003290300370000200041316a2006290300370000200041396a2008290300370000200041c1006a20022f009d043b0000200041c3006a2002419f046a2d00003a0000200041d8006a2007370300200041d0006a2009370300200041c8006a2010ad422086200bad84370000200041c4006a200f360000200041f8006a200241f8036a41186a290300370300200041f0006a200241f8036a41106a290300370300200041e8006a200241f8036a41086a290300370300200041e0006a20022903f8033703000c050b20052004103e000b20052003103e000b200041073a00000c020b20044101102a000b200041073a00000b200241f0056a24000ba30b01077f230041106b2202240002400240024002400240024002400240024020002d0000417f6a220341034b0d00024002400240024020030e0400010203000b02400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490d0c20034101742205200420042005491b22054100480d0c0240024020030d002005102721040c010b200128020020032005102821040b2004450d0520012004360200200141046a2005360200200141086a28020021030b200141086a2205200341016a360200200420036a41003a00002000280204210320022000410c6a280200220036020c2002410c6a200110302000450d0320004105742106200141046a210703400240024020072802002204200528020022006b4120490d00200128020021040c010b200041206a22082000490d0d20044101742200200820082000491b22004100480d0d0240024020040d002000102721040c010b200128020020042000102821040b2004450d072001200436020020072000360200200528020021000b2005200041206a360200200420006a220041186a200341186a290000370000200041106a200341106a290000370000200041086a200341086a29000037000020002003290000370000200341206a2103200641606a22060d000c040b0b02400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490d0b20034101742205200420042005491b22054100480d0b0240024020030d002005102721040c010b200128020020032005102821040b2004450d0620012004360200200141046a2005360200200141086a28020021030b200141086a200341016a360200200420036a41013a00002000280204200110320c020b02400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490d0a20034101742205200420042005491b22054100480d0a0240024020030d002005102721040c010b200128020020032005102821040b2004450d0620012004360200200141046a2005360200200141086a28020021030b200141086a200341016a360200200420036a41023a0000200041046a200110302000280208200110320c010b02400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490d0920034101742205200420042005491b22054100480d090240024020030d002005102721040c010b200128020020032005102821040b2004450d0620012004360200200141046a2005360200200141086a28020021030b200141086a2205200341016a360200200420036a41033a000002400240200141046a2802002204200528020022036b4120490d00200128020021040c010b200341206a22052003490d0920044101742203200520052003491b22034100480d090240024020040d002003102721040c010b200128020020042003102821040b2004450d0720012004360200200141046a2003360200200141086a28020021030b200141086a2205200341206a360200200420036a220341186a200041196a290000370000200341106a200041116a290000370000200341086a200041096a29000037000020032000290001370000200041246a2001103002400240200141046a28020020052802002203460d00200128020021040c010b200341016a22042003490d0920034101742205200420042005491b22054100480d090240024020030d002005102721040c010b200128020020032005102821040b2004450d0820012004360200200141046a2005360200200141086a28020021030b200141086a200341016a360200200420036a20002d00213a00000b200241106a24000f0b20054101102a000b20004101102a000b20054101102a000b20054101102a000b20054101102a000b20034101102a000b20054101102a000b102b000bf71802047f017e20002802582102024002400240024002400240024002400240024002400240024002400240024002400240024002400240200141046a2802002203200141086a28020022046b4104490d00200128020021030c010b200441046a22052004490d1320034101742204200520052004491b22044100480d130240024020030d002004102721030c010b200128020020032004102821030b2003450d0120012003360200200141046a2004360200200141086a28020021040b200141086a2205200441046a360200200320046a20023600002000290300210602400240200141046a2802002203200528020022046b4108490d00200128020021030c010b200441086a22022004490d1320034101742204200220022004491b22044100480d130240024020030d002004102721030c010b200128020020032004102821030b2003450d0220012003360200200141046a2004360200200141086a28020021040b200141086a2202200441086a360200200320046a20063700002000290308210602400240200141046a2802002203200228020022046b4108490d00200128020021030c010b200441086a22022004490d1320034101742204200220022004491b22044100480d130240024020030d002004102721030c010b200128020020032004102821030b2003450d0320012003360200200141046a2004360200200141086a28020021040b200141086a2202200441086a360200200320046a20063700002000290310210602400240200141046a2802002203200228020022046b4108490d00200128020021030c010b200441086a22022004490d1320034101742204200220022004491b22044100480d130240024020030d002004102721030c010b200128020020032004102821030b2003450d0420012003360200200141046a2004360200200141086a28020021040b200141086a2202200441086a360200200320046a20063700002000290318210602400240200141046a2802002203200228020022046b4108490d00200128020021030c010b200441086a22022004490d1320034101742204200220022004491b22044100480d130240024020030d002004102721030c010b200128020020032004102821030b2003450d0520012003360200200141046a2004360200200141086a28020021040b200141086a2202200441086a360200200320046a20063700002000290320210602400240200141046a2802002203200228020022046b4108490d00200128020021030c010b200441086a22022004490d1320034101742204200220022004491b22044100480d130240024020030d002004102721030c010b200128020020032004102821030b2003450d0620012003360200200141046a2004360200200141086a28020021040b200141086a2202200441086a360200200320046a20063700002000290328210602400240200141046a2802002203200228020022046b4108490d00200128020021030c010b200441086a22022004490d1320034101742204200220022004491b22044100480d130240024020030d002004102721030c010b200128020020032004102821030b2003450d0720012003360200200141046a2004360200200141086a28020021040b200141086a2202200441086a360200200320046a20063700002000290330210602400240200141046a2802002203200228020022046b4108490d00200128020021030c010b200441086a22022004490d1320034101742204200220022004491b22044100480d130240024020030d002004102721030c010b200128020020032004102821030b2003450d0820012003360200200141046a2004360200200141086a28020021040b200141086a2202200441086a360200200320046a20063700002000290338210602400240200141046a2802002203200228020022046b4108490d00200128020021030c010b200441086a22022004490d1320034101742204200220022004491b22044100480d130240024020030d002004102721030c010b200128020020032004102821030b2003450d0920012003360200200141046a2004360200200141086a28020021040b200141086a2202200441086a360200200320046a20063700002000290340210602400240200141046a2802002203200228020022046b4108490d00200128020021030c010b200441086a22022004490d1320034101742204200220022004491b22044100480d130240024020030d002004102721030c010b200128020020032004102821030b2003450d0a20012003360200200141046a2004360200200141086a28020021040b200141086a2202200441086a360200200320046a20063700002000290348210602400240200141046a2802002203200228020022046b4108490d00200128020021030c010b200441086a22022004490d1320034101742204200220022004491b22044100480d130240024020030d002004102721030c010b200128020020032004102821030b2003450d0b20012003360200200141046a2004360200200141086a28020021040b200141086a2202200441086a360200200320046a20063700002000290350210602400240200141046a2802002203200228020022046b4108490d00200128020021030c010b200441086a22022004490d1320034101742204200220022004491b22044100480d130240024020030d002004102721030c010b200128020020032004102821030b2003450d0c20012003360200200141046a2004360200200141086a28020021040b200141086a2202200441086a360200200320046a2006370000200028025c210502400240200141046a2802002203200228020022046b4104490d00200128020021030c010b200441046a22022004490d1320034101742204200220022004491b22044100480d130240024020030d002004102721030c010b200128020020032004102821030b2003450d0d20012003360200200141046a2004360200200141086a28020021040b200141086a2202200441046a360200200320046a20053600002000280260210502400240200141046a2802002203200228020022046b4104490d00200128020021030c010b200441046a22022004490d1320034101742204200220022004491b22044100480d130240024020030d002004102721030c010b200128020020032004102821030b2003450d0e20012003360200200141046a2004360200200141086a28020021040b200141086a2202200441046a360200200320046a20053600002000280264210502400240200141046a2802002203200228020022046b4104490d00200128020021030c010b200441046a22022004490d1320034101742204200220022004491b22044100480d130240024020030d002004102721030c010b200128020020032004102821030b2003450d0f20012003360200200141046a2004360200200141086a28020021040b200141086a2202200441046a360200200320046a20053600002000280268210502400240200141046a2802002203200228020022046b4104490d00200128020021030c010b200441046a22022004490d1320034101742204200220022004491b22044100480d130240024020030d002004102721030c010b200128020020032004102821030b2003450d1020012003360200200141046a2004360200200141086a28020021040b200141086a2202200441046a360200200320046a200536000002400240200141046a28020020022802002204460d00200128020021030c010b200441016a22032004490d1320044101742202200320032002491b22024100480d130240024020040d002002102721030c010b200128020020042002102821030b2003450d1120012003360200200141046a2002360200200141086a28020021040b200141086a2202200441016a360200200320046a20002d00703a0000200028026c210302400240200141046a2802002204200228020022006b4104490d00200128020021040c010b200041046a22022000490d1320044101742200200220022000491b22004100480d130240024020040d002000102721040c010b200128020020042000102821040b2004450d1220012004360200200141046a2000360200200141086a28020021000b200141086a200041046a360200200420006a20033600000f0b20044101102a000b20044101102a000b20044101102a000b20044101102a000b20044101102a000b20044101102a000b20044101102a000b20044101102a000b20044101102a000b20044101102a000b20044101102a000b20044101102a000b20044101102a000b20044101102a000b20044101102a000b20044101102a000b20024101102a000b20004101102a000b102b000bb01405167f017e017f027e037f230041206b220224000240024020014115490d0002402001410176220341ffffff3f712003470d0020034105742204417f4c0d0041012105024002402004450d00200410272205450d010b200041606a2106200041a07f6a210741042108410021094100210a2001210b034002400240200b220c417f6a220d0d004101210e4100210b0c010b0240024002400240024002402000200d4105746a200c410574220f20006a41406a412010d0044100480d004102200c6b210d2007200f6a21044101210e03400240200d200e6a4101470d004100210b200c210e0c080b200e41016a210e200441206a2004412010d0042110200441606a21042010417f4a0d000b200c200e6b210d0c010b2007200f6a2104024003400240200d4101470d004100210d0c020b200d417f6a210d200441206a2004412010d0042110200441606a210420104100480d000b0b200c200d490d01200c20014b0d03200c200d6b220e4101762211450d002006200f6a21042000200d4105746a21100340200241186a220f201041186a2212290000370300200241106a2213201041106a2214290000370300200241086a2215201041086a221629000037030020022010290000370300200441086a22172900002118200441106a2219290000211a200441186a220b290000211b201020042900003700002012201b3700002014201a37000020162018370000200b200f290300370000201920132903003700002017201529030037000020042002290300370000200441606a2104201041206a21102011417f6a22110d000b0b0240200d0d00200d210b0c050b0240200e41094d0d00200d210b0c050b200c20014b0d01200c200d6b21112000200d4105746a210f0340200c200d417f6a220b490d040240200c200b6b220e4102490d002000200d4105746a22042000200b4105746a220d412010d004417f4a0d00200d2900002118200d2004290000370000200241186a2215200d41186a2210290000370300200241106a2216200d41106a2212290000370300200241086a2217200d41086a22132900003703002013200441086a2900003700002012200441106a2900003700002010200441186a29000037000020022018370300410121140240200e4103490d00200d41c0006a2002412010d004417f4a0d0041022110200f210402400340200441186a200441386a290000370000200441106a200441306a290000370000200441086a200441286a2900003700002004200441206a221229000037000020112010460d01200441c0006a21132010211420122104201041016a211020132002412010d004417f4a0d020c000b0b201021140b200d20144105746a22042002290300370000200441186a2015290300370000200441106a2016290300370000200441086a20172903003700000b200b450d05200f41606a210f201141016a2111200b210d200e410a4f0d050c000b0b200d200c103e000b200c200d417f6a220b490d010b200c2001107f000b200b200c103e000b0240024002402009200a470d0002400240200941016a22042009490d0020094101742210200420042010491b220441ffffffff01712004470d002004410374221041004e0d010b102b000b0240024020090d002010102721080c010b200820094103742010102821080b2008450d01200421090b2008200a4103746a2204200e3602042004200b360200200a41016a2215210a20154102490d0103400240024002400240200820152213417f6a22154103746a2204280200450d00201341037420086a221141746a280200220e200428020422104d0d004102210a201341024d0d0620082013417d6a22044103746a280204220d2010200e6a4d0d014103210a201341034d0d06201141646a280200200d200e6a4d0d012013210a0c060b20134103490d012004280204211020082013417d6a22044103746a280204210d0b200d2010490d010b2013417e6a21040b0240024002400240024002402013200441016a221c4d0d00201320044d0d01200820044103746a2216280204221d20162802006a22042008201c4103746a22172802002219490d02200420014b0d03201641046a211e200020194105746a22122017280204221441057422106a210e2004410574210d200420196b220a20146b220420144f0d042005200e2004410574221010ce04220f20106a21110240024020144101480d00200441014e0d010b200e2104200f21100c060b2006200d6a210d200e21040340200d200441606a220e201141606a220a200a200e412010d004410048220c1b2210290000370000200d41186a201041186a290000370000200d41106a201041106a290000370000200d41086a201041086a2900003700002011200a200c1b211102402012200e2004200c1b2204490d00200f21100c070b200d41606a210d200f2110200f2011490d000c060b0b41d8e3c100201c20131037000b41d8e3c100200420131037000b20192004103e000b20042001107f000b20052012201010ce04220f20106a21110240024020144101480d00200a20144a0d010b20122104200f21100c010b2000200d6a210c200f21102012210403402004200e2010200e2010412010d004410048220a1b220d290000370000200441186a200d41186a290000370000200441106a200d41106a290000370000200441086a200d41086a2900003700002010201041206a200a1b2110200441206a2104200e41206a200e200a1b220e200c4f0d01201120104b0d000b0b20042010201120106b41607110ce041a201e201d20146a360200201620193602002017201741086a201c417f7320136a41037410cf041a2015210a201541014d0d020c000b0b20104104102a000b200b0d000b02402009450d00200810290b2003450d03200510290c030b20044101102a000b1039000b20014102490d002001417f6a2110200141057420006a41206a210c410121110340024002400240024020102204417f6a221020014b0d00200120106b220d4102490d03200020044105746a2204200020104105746a220a412010d004417f4a0d03200a2900002118200a2004290000370000200241186a2212200a41186a220e290000370300200241106a2213200a41106a220f290000370300200241086a2214200a41086a22082900003703002008200441086a290000370000200f200441106a290000370000200e200441186a2900003700002002201837030041012104200d4103490d02200a41c0006a2002412010d004417f4a0d024100210f200c21040340200441406a220d200441606a220e290000370000200d41186a200e41186a290000370000200d41106a200e41106a290000370000200d41086a200e41086a2900003700002011200f220d460d02200d417f6a210f20042002412010d004210e200441206a2104200e417f4a0d020c000b0b20102001103e000b4102200d6b21040b200a20044105746a22042002290300370000200441186a2012290300370000200441106a2013290300370000200441086a20142903003700000b200c41606a210c2011417f6a211120100d000b0b200241206a24000be91a03037f027e067f230041f0016b220224000240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024020012802000e12000102030405060708090a0b0c0d0e0f1011000b200241e8006a200141086a10960220004100360200200041106a200241e8006a41086a290300370300200041086a20022903683703000c110b109702000b20004102360200200041086a200141086a2903003703000c0f0b200241e8006a200141046a1038200041033602002000410c6a200241f0006a280200360200200020022903683702040c0e0b109802000b0240024002400240200141086a280200417f6a220341014b0d0020030e020102010b41e4bdc0001058000b41012103024002402001410c6a22042d00004101460d00200241026a200441036a2d00003a0000200241f0006a2001411c6a290200370300200241e8006a41106a200141246a29020037030020024180016a2001412c6a2d00003a0000200220042f00013b01002002200141146a290200370368200141106a2802002104410021030c010b200141106a28020021040b200241246a41026a200241026a2d00003a0000200241286a41086a200241e8006a41086a290300370300200241286a41106a200241e8006a41106a290300370300200241286a41186a200241e8006a41186a280200360200200220022f01003b012420022002290368370328200141386a29030021052001290330210641012107200241106a21010c010b41012103024002402001410c6a22042d00004101460d00200241ee016a200441036a2d00003a0000200241f0006a2001411c6a290200370300200241e8006a41106a200141246a29020037030020024180016a2001412c6a2d00003a0000200220042f00013b01ec012002200141146a290200370368200141106a2802002104410021030c010b200141106a28020021040b41022107200241246a41026a200241ec016a41026a2d00003a0000200241286a41086a200241e8006a41086a290300370300200241286a41106a200241e8006a41106a290300370300200241286a41186a200241e8006a41186a280200360200200220022f01ec013b012420022002290368370328200220012903303703102002200141386a290300370318200141c8006a290300210520012903402106200221010b20012006370300200120053703082000410c6a20033a0000200041086a2007360200200020022f01243b000d2000410f6a200241266a2d00003a0000200041106a2004360200200041146a20022903283702002000411c6a200241286a41086a290300370200200041246a200241286a41106a2903003702002000412c6a200241c0006a280200360200200041386a200241106a41086a290300370300200041306a2002290310370300200041c0006a2002290300370300200041c8006a200241086a290300370300200041053602000c0c0b200241e8006a200141086a10990220004106360200200041386a200241e8006a41306a290300370300200041306a200241e8006a41286a290300370300200041286a200241e8006a41206a290300370300200041206a200241e8006a41186a290300370300200041186a200241e8006a41106a290300370300200041106a200241e8006a41086a290300370300200041086a20022903683703000c0b0b200241e8006a41186a200141286a290000370300200241e8006a41106a200141206a290000370300200241f0006a200141186a290000370300200241e8006a41286a200141386a290000370300200241e8006a41306a200141c0006a290000370300200241e8006a41386a200141c8006a2900003703002002200141106a2900003703682002200141306a290000370388012001410c6a2802002203417f4c0d0b0240024020030d00410121010c010b20012802042104200310272201450d0d20012004200310ce041a0b200241286a41386a2204200241e8006a41386a290300370300200241286a41306a2207200241e8006a41306a290300370300200241286a41286a2208200241e8006a41286a290300370300200241286a41206a2209200241e8006a41206a290300370300200241286a41186a220a200241e8006a41186a290300370300200241286a41106a220b200241e8006a41106a290300370300200241286a41086a220c200241e8006a41086a290300370300200220022903683703282000410c6a2003360200200041086a200336020020002001360204200041106a2002290328370200200041186a200c290300370200200041206a200b290300370200200041286a200a290300370200200041306a2009290300370200200041386a2008290300370200200041c0006a2007290300370200200041c8006a2004290300370200200041073602000c0a0b200241e8006a200141086a109a0220004108360200200041386a200241e8006a41306a290300370300200041306a200241e8006a41286a290300370300200041286a200241e8006a41206a290300370300200041206a200241e8006a41186a290300370300200041186a200241e8006a41106a290300370300200041106a200241e8006a41086a290300370300200041086a20022903683703000c090b200241e8006a200141046a109b0220004109360200200041246a20024188016a2903003702002000411c6a20024180016a290300370200200041146a200241f8006a2903003702002000410c6a200241f0006a290300370200200020022903683702040c080b200241e8006a200141046a109b022000410a360200200041246a20024188016a2903003702002000411c6a20024180016a290300370200200041146a200241f8006a2903003702002000410c6a200241f0006a290300370200200020022903683702040c070b200241e8006a200141086a10c8012000410b360200200041c0006a200241e8006a41386a290300370300200041386a200241e8006a41306a290300370300200041306a200241e8006a41286a290300370300200041286a200241e8006a41206a290300370300200041206a200241e8006a41186a290300370300200041186a200241e8006a41106a290300370300200041106a200241e8006a41086a290300370300200041086a20022903683703000c060b2000410c360200200041086a200141086a2903003703000c050b2001410c6a2802002203417f4c0d050240024020030d00410121010c010b20012802042104200310272201450d0820012004200310ce041a0b200020013602042000410d3602002000410c6a2003360200200041086a20033602000c040b024002400240024002400240200141086a280200417f6a220341024b0d0020030e03010203010b4190a9c1001058000b200141386a2903002105200141306a290300210641012103024002402001410c6a2d00004101460d00200241f0006a2001411c6a290200370300200241e8006a41106a200141246a29020037030020024180016a2001412c6a2d00003a00002002200141146a29020037036820012f000d2001410f6a2d0000411074722104200141106a2802002101410021030c010b200141106a28020021010b200241286a41186a200241e8006a41186a280200360200200241286a41106a200241e8006a41106a290300370300200241286a41086a200241e8006a41086a29030037030020022002290368370328410121070c030b2001410c6a28020022034108762104410221070c010b2001410c6a28020022034108762104410321070b0b2000410e360200200041386a2005370300200041306a2006370300200041106a2001360200200041086a2007360200200041146a20022903283702002000410c6a2004410874200341ff0171723602002000411c6a200241286a41086a290300370200200041246a200241286a41106a2903003702002000412c6a200241c0006a2802003602000c030b200241e8006a200141086a109c02200041086a200241e8006a41800110ce041a2000410f3602000c020b02400240024002402001280204417f6a220341014b0d0020030e020102010b41f8e2c1001058000b41880110272203450d072003200141086a280200109502410121010c010b4101210302400240200141086a2d00004101460d00200241e8006a41086a200141186a290200370300200241e8006a41106a200141206a290200370300200241e8006a41186a200141286a2d00003a00002002200141106a29020037036820012f00092001410b6a2d00004110747241087421072001410c6a2802002104410021030c010b2001410c6a2802002104410021070b200241286a41186a200241e8006a41186a280200360200200241286a41106a200241e8006a41106a290300370300200241286a41086a200241e8006a41086a2903003703002002200229036837032820032007722103410221010b20002001360204200041103602002000410c6a2004360200200041086a2003360200200041106a2002290328370200200041186a200241286a41086a290300370200200041206a200241286a41106a290300370200200041286a200241286a41186a2802003602000c010b200241e8006a200141086a10b101200041086a200241e8006a41d80010ce041a200041113602000b200241f0016a24000f0b1039000b20034101102a000b20034101102a000b4188014108102a000bac0703037f017e077f0240024002400240024002400240024002400240024002400240024002402001280200417f6a220241054b0d0020020e06010203040506010b41b48ec3001058000b200041013602000f0b2001410c6a2802002202417f4c0d040240024020020d00410121010c010b20012802042103200210272201450d0620012003200210ce041a0b20002001360204200041023602002000410c6a2002360200200041086a20023602000f0b20004103360200200041086a200141086a2903003703000f0b2001410c6a2802002202417f4c0d020240024020020d00410121010c010b20012802042103200210272201450d0520012003200210ce041a0b20002001360204200041043602002000410c6a2002360200200041086a20023602000f0b2001410c6a2802002204ad42187e2205422088a70d012005a72203417f4c0d01200128020421020240024020030d00410421060c010b200310272206450d050b0240024020040d00410021070c010b2002200441186c6a210841002107200621010340200241086a2802002203417f4c0d03200228020021090240024020030d004101210a0c010b20031027220a450d080b200a2009200310ce04210a200241146a2802002209417f4c0d032002410c6a280200210b0240024020090d004101210c0c010b20091027220c450d090b200c200b200910ce04210b200141146a2009360200200141106a20093602002001410c6a200b360200200141086a2003360200200141046a20033602002001200a360200200141186a2101200741016a2107200241186a22022008470d000b0b20002006360204200041053602002000410c6a2007360200200041086a20043602000f0b2001410c6a280200220cad420c7e2205422088a70d002005a72202417f4c0d00200128020421030240024020020d00410421080c010b200210272208450d070b02400240200c0d00410021090c010b2003200c410c6c6a210b41002109200821020340200341086a2802002201417f4c0d02200328020021070240024020010d004101210a0c010b20011027220a450d0a0b200a2007200110ce042107200241086a2001360200200241046a2001360200200220073602002002410c6a2102200941016a21092003410c6a2203200b470d000b0b20002008360204200041063602002000410c6a2009360200200041086a200c3602000f0b1039000b20024101102a000b20024101102a000b20034104102a000b20034101102a000b20094101102a000b20024104102a000b20014101102a000b0a0041dc8dc3001058000b0a004198eec2001058000bbf0c03047f017e057f230041206b2202240002400240024002400240024002400240024002400240024002400240024002400240024020012d0000417f6a2203410c4b0d0020030e0d0102030405060708090a0b0c0d010b41e8fcc4001058000b4101210302400240200141046a2d00004101460d002002411e6a200141076a2d00003a0000200241086a200141146a290000370300200241106a2001411c6a290000370300200241186a200141246a2d00003a00002002200141056a2f00003b011c20022001410c6a290000370300200141086a2800002104410021030c010b200141086a28020021040b200041286a2001290328370300200041046a20033a0000200041056a20022f011c3b0000200041086a20043602002000410c6a2002290300370200200041306a200141306a290300370300200041076a2002411e6a2d00003a0000200041146a200241086a2903003702002000411c6a200241106a290300370200200041246a200241186a28020036020020012d00012101200041013a0000200020013a00010c0c0b200041023a0000200041106a200141106a290300370300200041086a200141086a2903003703000c0b0b200041033a0000200041106a200141106a290300370300200041086a200141086a2903003703000c0a0b200041043a00000c090b200041053a0000200041106a200141106a290300370300200041086a200141086a290300370300200041186a200141186a2802003602000c080b2001410c6a2802002205ad42247e2206422088a70d082006a72204417f4c0d08200141046a28020021030240024020040d00410421070c010b200410272207450d0a0b0240024020050d00410021040c010b200541246c2108410021042002411e6a21092007210103400240024020032d00004101460d002009200341036a2d00003a0000200341046a280000210a200341016a2f0000210b200241086a200341106a290000370300200241106a200341186a290000370300200241186a200341206a2d00003a00002002200b3b011c2002200341086a2900003703004100210b0c010b200341046a280200210a4101210b0b200341246a21032001200b3a0000200141046a200a360200200141016a20022f011c3b0000200141036a20092d00003a0000200141086a2002290300370200200141106a200241086a290300370200200141186a200241106a290300370200200141206a200241186a280200360200200141246a2101200441016a21042008415c6a22080d000b0b200041063a00002000410c6a2004360200200041086a2005360200200041046a20073602000c070b200041073a00000c060b200041083a0000200020012d00013a00010c050b4101210302400240200141046a2d00004101460d002002411e6a200141076a2d00003a0000200241086a200141146a290000370300200241106a2001411c6a290000370300200241186a200141246a2d00003a00002002200141056a2f00003b011c20022001410c6a290000370300200141086a2800002101410021030c010b200141086a28020021010b200041093a0000200041046a20033a0000200041056a20022f011c3b0000200041086a20013602002000410c6a2002290300370200200041076a2002411e6a2d00003a0000200041146a200241086a2903003702002000411c6a200241106a290300370200200041246a200241186a2802003602000c040b2000410a3a0000200041046a200141046a2802003602000c030b2000410b3a00000c020b2000410c3a0000200041046a200141046a2802003602000c010b2001410c6a280200220841ffffff3f712008470d0120084105742203417f4c0d01200141046a280200210a0240024020030d004101210b0c010b20031027220b450d040b0240024020080d0041002108410021010c010b200841057421044160200a6b2109200b2101200a2103034020012003290000370000200141186a200341186a290000370000200141106a200341106a290000370000200141086a200341086a290000370000200141206a2101200341206a2103200441606a22040d000b200a20084105746a20096a41057641016a21010b2000410d3a00002000410c6a2001360200200041086a2008360200200041046a200b3602000b200241206a24000f0b1039000b20044104102a000b20034101102a000be50701017f024002400240024002400240024002400240024002400240024002400240024002400240024002400240024020012d0000417f6a220241104b0d0020020e110102030405060708090a0b0c0d0e0f1011010b41c499c4001058000b41880110272202450d102002200141046a28020010c103200041046a2002360200200041013a0000200041106a200141106a290300370300200041086a200141086a2903003703000f0b200041023a0000200041046a200141046a2802003602000f0b200041033a0000200041046a200141046a280200360200200041026a200141026a2d00003a0000200020012d00014101713a00010f0b200041043a0000200041046a200141046a280200360200200041026a200141026a2d00003a0000200020012d00014101713a00010f0b41880110272202450d0d2002200141046a28020010c103200041046a2002360200200041053a0000200041106a200141106a290300370300200041086a200141086a290300370300200020012d00013a00010f0b200041063a0000200041046a200141046a2802003602000f0b41880110272202450d0c2002200141046a28020010c103200041073a0000200041046a20023602000f0b41880110272202450d0c2002200141046a28020010c103200041083a0000200041046a20023602000f0b200041093a000020002001290001370001200041096a200141096a290000370000200041116a200141116a290000370000200041196a200141196a290000370000200041306a200141306a290300370300200041286a200141286a2903003703000f0b2000410a3a000020002001290001370001200041196a200141196a290000370000200041116a200141116a290000370000200041096a200141096a2900003700000f0b2000410b3a0000200041046a200141046a2802003602000f0b2000410c3a0000200041106a200141106a290300370300200041046a200141046a2902003702000f0b2000410d3a000020002001290001370001200041196a200141196a290000370000200041116a200141116a290000370000200041096a200141096a2900003700000f0b2000410e3a00000f0b2000410f3a000020002001290001370001200041196a200141196a290000370000200041116a200141116a290000370000200041096a200141096a2900003700000f0b200041103a000020002001290001370001200041096a200141096a290000370000200041116a200141116a290000370000200041196a200141196a290000370000200041216a200141216a2d00003a00000f0b200041113a00000f0b4188014108102a000b4188014108102a000b4188014108102a000b4188014108102a000beb0301067f024002400240024002400240024020012d0000417f6a220241034b0d0020020e0401020304010b41c893c2001058000b2001410c6a280200220341ffffff3f712003470d0320034105742202417f4c0d03200141046a28020021040240024020020d00410121050c010b200210272205450d050b0240024020030d0041002103410021010c010b20034105742106416020046b21072005210120042102034020012002290000370000200141186a200241186a290000370000200141106a200241106a290000370000200141086a200241086a290000370000200141206a2101200241206a2102200641606a22060d000b200420034105746a20076a41057641016a21010b200041013a00002000410c6a2001360200200041086a2003360200200041046a20053602000f0b200141046a10f7022101200041023a0000200041046a20013602000f0b200141046a2802002102200041086a200141086a10f702360200200041046a2002360200200041033a00000f0b200041043a000020002001290001370001200041096a200141096a290000370000200041116a200141116a290000370000200041196a200141196a290000370000200041246a200141246a280200360200200041216a200141216a2d00004100473a00000f0b1039000b20024101102a000ba60f05027f017e027f027e017f230041c0006b22022400024002400240024002400240024002400240024002400240024020012d0000417f6a220341054b0d0020030e06010203040506010b4190e1c2001058000b200041f9006a2002280020360000200041086a200141086a290300370300200041fc006a200241236a280000360000200041106a200141106a290300370300200041186a200141186a290300370300200041206a200141206a290300370300200041286a200141286a290300370300200041306a200141306a290300370300200041386a200141386a290300370300200041c0006a200141c0006a290300370300200041c8006a200141c8006a290300370300200041d0006a200141d0006a290300370300200041d8006a200141d8006a290300370300200041e0006a200141e0006a290300370300200041e8006a200141e8006a290300370300200041f0006a200141f0006a290300370300200041f8006a200141f8006a2d00004100473a0000200041013a00000c050b2001410c6a2802002203417f4c0d05200141106a29030021040240024020030d00410121010c010b200141046a2802002105200310272201450d0720012005200310ce041a0b200041023a00002000410c6a2003360200200041086a2003360200200041046a2001360200200041106a20043703000c040b4101210502400240200141046a2d00004101460d00200241026a200141076a2d00003a0000200241206a41086a200141146a290000370300200241306a2001411c6a290000370300200241386a200141246a2d00003a00002002200141056a2f00003b010020022001410c6a290000370320200141086a2800002106410021050c010b200141086a28020021060b200141306a2802002203417f4c0d04200141c0006a290300210420012903382107200129034821080240024020030d00410121010c010b20012802282109200310272201450d0720012009200310ce041a0b200041c0006a2004370300200041386a2007370300200041046a20053a0000200041056a20022f01003b0000200041086a20063602002000410c6a2002290320370200200041c8006a2008370300200041306a20033602002000412c6a2003360200200041286a2001360200200041076a200241026a2d00003a0000200041146a200241206a41086a2903003702002000411c6a200241306a290300370200200041246a200241386a280200360200200041033a00000c030b200141386a2903002104200141306a2903002107200141c0006a2903002108200241386a200141196a290000370300200241306a200141116a290000370300200241286a200141096a290000370300200220012900013703202001412c6a2802002203417f4c0d030240024020030d00410121010c010b200141246a2802002105200310272201450d0720012005200310ce041a0b20002002290320370001200041043a0000200041386a2004370300200041306a2007370300200041c0006a20083703002000412c6a2003360200200041286a2003360200200041246a2001360200200041096a200241286a290300370000200041116a200241306a290300370000200041196a200241386a2903003700000c020b200241186a2205200141196a290000370300200241106a2206200141116a290000370300200241086a2209200141096a29000037030020022001290001370300410021030240200141216a2d00004101470d00200241206a41186a2001413a6a290000370300200241206a41106a200141326a290000370300200241206a41086a2001412a6a2900003703002002200141226a290000370320410121030b20002002290300370001200041216a20033a0000200041226a2002290320370000200041196a2005290300370000200041116a2006290300370000200041096a20092903003700002000412a6a200241206a41086a290300370000200041326a200241206a41106a2903003700002000413a6a200241206a41186a290300370000200041053a00000c010b200241186a200141196a290000370300200241106a200141116a290000370300200241086a200141096a29000037030020022001290001370300200241206a41186a200141396a290000370300200241206a41106a200141316a290000370300200241206a41086a200141296a2900003703002002200141216a290000370320200141cc006a280200220341ffffff3f712003470d0120034105742205417f4c0d01200141d8006a2903002104200141d0006a2903002107200141c4006a28020021010240024020050d00410121060c010b200510272206450d060b20062001200341057410ce042101200041d8006a2004370300200041d0006a2007370300200041cc006a2003360200200041c8006a2003360200200041c4006a2001360200200041196a200241186a290300370000200041116a200241106a290300370000200041096a200241086a29030037000020002002290300370001200041216a2002290320370000200041296a200241206a41086a290300370000200041316a200241206a41106a290300370000200041396a200241206a41186a290300370000200041063a00000b200241c0006a24000f0b1039000b20034101102a000b20034101102a000b20034101102a000b20054101102a000bc9b30103047f027e057f230041106b22022400024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024020002d00002203410d4b0d000240024002400240024002400240024002400240024002400240024020030e0e000102030405060708090a0b0c0d000b02400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490d5a20034101742205200420042005491b22054100480d5a0240024020030d002005102721040c010b200128020020032005102821040b2004450d0f20012004360200200141046a2005360200200141086a28020021030b200141086a2205200341016a360200200420036a41003a0000200141046a280200210420052802002103024020002d00014101460d000240024020042003460d00200128020021000c010b200341016a22002003490d5b20034101742204200020002004491b22044100480d5b0240024020030d002004102721000c010b200128020020032004102821000b2000450d1120012000360200200141046a2004360200200141086a28020021030b200141086a200341016a360200200020036a41003a00000c0e0b0240024020042003460d00200128020021000c010b200341016a22002003490d5a20034101742204200020002004491b22044100480d5a0240024020030d002004102721000c010b200128020020032004102821000b2000450d1120012000360200200141046a2004360200200141086a28020021030b200141086a200341016a360200200020036a41013a00000c0d0b02400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490d5920034101742205200420042005491b22054100480d590240024020030d002005102721040c010b200128020020032005102821040b2004450d1120012004360200200141046a2005360200200141086a28020021030b200141086a2205200341016a360200200420036a41013a000002400240200141046a28020020052802002203460d00200128020021040c010b200341016a22042003490d5920034101742205200420042005491b22054100480d590240024020030d002005102721040c010b200128020020032005102821040b2004450d1220012004360200200141046a2005360200200141086a28020021030b200141086a2205200341016a360200200420036a41003a000002400240200141046a2802002204200528020022036b4120490d00200128020021040c010b200341206a22052003490d5920044101742203200520052003491b22034100480d590240024020040d002003102721040c010b200128020020042003102821040b2004450d1320012004360200200141046a2003360200200141086a28020021030b200141086a2205200341206a360200200420036a220341186a200041086a220441186a290000370000200341106a200441106a290000370000200341086a200441086a290000370000200320042900003700002000280204210402400240200141046a2802002203200528020022006b4104490d00200128020021030c010b200041046a22052000490d5920034101742200200520052000491b22004100480d590240024020030d002000102721030c010b200128020020032000102821030b2003450d1420012003360200200141046a2000360200200141086a28020021000b200141086a200041046a360200200320006a20043600000c0c0b02400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490d5820034101742205200420042005491b22054100480d580240024020030d002005102721040c010b200128020020032005102821040b2004450d1420012004360200200141046a2005360200200141086a28020021030b200141086a200341016a360200200420036a41023a000020002d0008220341024b0d0b02400240024020030e03000102000b02400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490d5a20034101742205200420042005491b22054100480d5a0240024020030d002005102721040c010b200128020020032005102821040b2004450d1720012004360200200141046a2005360200200141086a28020021030b200141086a2205200341016a360200200420036a41003a000002400240200141046a2802002204200528020022036b4120490d00200128020021040c010b200341206a22052003490d5a20044101742203200520052003491b22034100480d5a0240024020040d002003102721040c010b200128020020042003102821040b2004450d1820012004360200200141046a2003360200200141086a28020021030b200141086a2205200341206a360200200420036a220341186a200041096a220441186a290000370000200341106a200441106a290000370000200341086a200441086a29000037000020032004290000370000200041386a29030021062000290330210702400240200141046a2802002203200528020022006b4110490d00200128020021030c010b200041106a22042000490d5a20034101742200200420042000491b22004100480d5a0240024020030d002000102721030c010b200128020020032000102821030b2003450d1920012003360200200141046a2000360200200141086a28020021000b200141086a200041106a360200200320006a22012006370008200120073700000c0d0b02400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490d5920034101742205200420042005491b22054100480d590240024020030d002005102721040c010b200128020020032005102821040b2004450d1920012004360200200141046a2005360200200141086a28020021030b200141086a2205200341016a360200200420036a41013a000002400240200141046a2802002204200528020022036b4120490d00200128020021040c010b200341206a22052003490d5920044101742203200520052003491b22034100480d590240024020040d002003102721040c010b200128020020042003102821040b2004450d1a20012004360200200141046a2003360200200141086a28020021030b200141086a200341206a360200200420036a220141186a200041096a220041186a290000370000200141106a200041106a290000370000200141086a200041086a290000370000200120002900003700000c0c0b02400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490d5820034101742205200420042005491b22054100480d580240024020030d002005102721040c010b200128020020032005102821040b2004450d1a20012004360200200141046a2005360200200141086a28020021030b200141086a2205200341016a360200200420036a41023a000002400240200141046a2802002204200528020022036b4120490d00200128020021040c010b200341206a22052003490d5820044101742203200520052003491b22034100480d580240024020040d002003102721040c010b200128020020042003102821040b2004450d1b20012004360200200141046a2003360200200141086a28020021030b200141086a2205200341206a360200200420036a220341186a200041096a220441186a290000370000200341106a200441106a290000370000200341086a200441086a2900003700002003200429000037000002400240200141046a2802002204200528020022036b4120490d00200128020021040c010b200341206a22052003490d5820044101742203200520052003491b22034100480d580240024020040d002003102721040c010b200128020020042003102821040b2004450d1c20012004360200200141046a2003360200200141086a28020021030b200141086a2205200341206a360200200420036a220341186a200041296a220441186a290000370000200341106a200441106a290000370000200341086a200441086a29000037000020032004290000370000200041d8006a29030021062000290350210702400240200141046a2802002204200528020022036b4110490d00200128020021040c010b200341106a22052003490d5820044101742203200520052003491b22034100480d580240024020040d002003102721040c010b200128020020042003102821040b2004450d1d20012004360200200141046a2003360200200141086a28020021030b200141086a2205200341106a360200200420036a2203200637000820032007370000200041e8006a29030021062000290360210702400240200141046a2802002203200528020022006b4110490d00200128020021030c010b200041106a22042000490d5820034101742200200420042000491b22004100480d580240024020030d002000102721030c010b200128020020032000102821030b2003450d1e20012003360200200141046a2000360200200141086a28020021000b200141086a200041106a360200200320006a22012006370008200120073700000c0b0b02400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490d5720034101742205200420042005491b22054100480d570240024020030d002005102721040c010b200128020020032005102821040b2004450d1e20012004360200200141046a2005360200200141086a28020021030b200141086a200341016a360200200420036a41033a000020002d0008220341024b0d0a02400240024020030e03000102000b02400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490d5920034101742205200420042005491b22054100480d590240024020030d002005102721040c010b200128020020032005102821040b2004450d2120012004360200200141046a2005360200200141086a28020021030b200141086a2205200341016a360200200420036a41003a0000200041186a29030021062000290310210702400240200141046a2802002203200528020022006b4110490d00200128020021030c010b200041106a22042000490d5920034101742200200420042000491b22004100480d590240024020030d002000102721030c010b200128020020032000102821030b2003450d2220012003360200200141046a2000360200200141086a28020021000b200141086a200041106a360200200320006a22012006370008200120073700000c0c0b02400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490d5820034101742205200420042005491b22054100480d580240024020030d002005102721040c010b200128020020032005102821040b2004450d2220012004360200200141046a2005360200200141086a28020021030b200141086a2205200341016a360200200420036a41013a000002400240200141046a2802002204200528020022036b4120490d00200128020021040c010b200341206a22052003490d5820044101742203200520052003491b22034100480d580240024020040d002003102721040c010b200128020020042003102821040b2004450d2320012004360200200141046a2003360200200141086a28020021030b200141086a2205200341206a360200200420036a220341186a200041096a220441186a290000370000200341106a200441106a290000370000200341086a200441086a29000037000020032004290000370000200028022c210402400240200141046a2802002203200528020022006b4104490d00200128020021030c010b200041046a22052000490d5820034101742200200520052000491b22004100480d580240024020030d002000102721030c010b200128020020032000102821030b2003450d2420012003360200200141046a2000360200200141086a28020021000b200141086a200041046a360200200320006a20043600000c0b0b02400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490d5720034101742205200420042005491b22054100480d570240024020030d002005102721040c010b200128020020032005102821040b2004450d2420012004360200200141046a2005360200200141086a28020021030b200141086a2205200341016a360200200420036a41023a000002400240200141046a2802002204200528020022036b4120490d00200128020021040c010b200341206a22052003490d5720044101742203200520052003491b22034100480d570240024020040d002003102721040c010b200128020020042003102821040b2004450d2520012004360200200141046a2003360200200141086a28020021030b200141086a2205200341206a360200200420036a220341186a200041096a220441186a290000370000200341106a200441106a290000370000200341086a200441086a29000037000020032004290000370000200041386a29030021062000290330210702400240200141046a2802002203200528020022006b4110490d00200128020021030c010b200041106a22042000490d5720034101742200200420042000491b22004100480d570240024020030d002000102721030c010b200128020020032000102821030b2003450d2620012003360200200141046a2000360200200141086a28020021000b200141086a200041106a360200200320006a22012006370008200120073700000c0a0b02400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490d5620034101742205200420042005491b22054100480d560240024020030d002005102721040c010b200128020020032005102821040b2004450d2620012004360200200141046a2005360200200141086a28020021030b200141086a2205200341016a360200200420036a41043a000002400240200141046a28020020052802002203460d00200128020021040c010b200341016a22042003490d5620034101742205200420042005491b22054100480d560240024020030d002005102721040c010b200128020020032005102821040b2004450d2720012004360200200141046a2005360200200141086a28020021030b200141086a2205200341016a360200200420036a41003a00002000280204210402400240200141046a2802002203200528020022006b4104490d00200128020021030c010b200041046a22052000490d5620034101742200200520052000491b22004100480d560240024020030d002000102721030c010b200128020020032000102821030b2003450d2820012003360200200141046a2000360200200141086a28020021000b200141086a200041046a360200200320006a20043600000c090b02400240200141046a2208280200200141086a22042802002203460d00200128020021050c010b200341016a22052003490d5520034101742209200520052009491b22094100480d550240024020030d002009102721050c010b200128020020032009102821050b2005450d2820012005360200200141046a2009360200200141086a28020021030b2004200341016a360200200520036a41053a000020002d00082203410a4b0d080240024002400240024002400240024002400240024020030e0b000102030405060708090a000b02400240200828020020042802002203460d00200128020021050c010b200341016a22052003490d5f20034101742209200520052009491b22094100480d5f0240024020030d002009102721050c010b200128020020032009102821050b2005450d3320012005360200200141046a2009360200200141086a28020021030b2004200341016a360200200520036a41003a0000200028020c21090240024020082802002205200428020022036b4104490d00200128020021050c010b200341046a220a2003490d5f20054101742203200a200a2003491b22034100480d5f0240024020050d002003102721050c010b200128020020052003102821050b2005450d3420012005360200200141046a2003360200200141086a28020021030b2004200341046a360200200520036a2009360000200041186a2903002106200029031021070240024020082802002203200428020022006b4110490d00200128020021030c010b200041106a22052000490d5f20034101742200200520052000491b22004100480d5f0240024020030d002000102721030c010b200128020020032000102821030b2003450d3520012003360200200141046a2000360200200141086a28020021000b2004200041106a360200200320006a22012006370008200120073700000c120b02400240200828020020042802002203460d00200128020021050c010b200341016a22052003490d5e20034101742209200520052009491b22094100480d5e0240024020030d002009102721050c010b200128020020032009102821050b2005450d3520012005360200200141046a2009360200200141086a28020021030b2004200341016a360200200520036a41013a0000200028020c21090240024020082802002205200428020022036b4104490d00200128020021050c010b200341046a220a2003490d5e20054101742203200a200a2003491b22034100480d5e0240024020050d002003102721050c010b200128020020052003102821050b2005450d3620012005360200200141046a2003360200200141086a28020021030b2004200341046a360200200520036a2009360000200041286a2903002106200029032021070240024020082802002205200428020022036b4110490d00200128020021050c010b200341106a22092003490d5e20054101742203200920092003491b22034100480d5e0240024020050d002003102721050c010b200128020020052003102821050b2005450d3720012005360200200141046a2003360200200141086a28020021030b200141086a220b200341106a360200200520036a2203200637000820032007370000200028021021032002200041186a280200220036020c2002410c6a200110302000450d1120004105742109200141046a210c03400240024020082802002205200428020022006b4120490d00200128020021050c010b200041206a220a2000490d5f20054101742200200a200a2000491b22004100480d5f0240024020050d002000102721050c010b200128020020052000102821050b2005450d3920012005360200200c2000360200200b28020021000b2004200041206a360200200520006a220041186a200341186a290000370000200041106a200341106a290000370000200041086a200341086a29000037000020002003290000370000200341206a2103200941606a22090d000c120b0b02400240200828020020042802002200460d00200128020021030c010b200041016a22032000490d5d20004101742205200320032005491b22054100480d5d0240024020000d002005102721030c010b200128020020002005102821030b2003450d3820012003360200200141046a2005360200200141086a28020021000b2004200041016a360200200320006a41023a00000c100b02400240200828020020042802002203460d00200128020021050c010b200341016a22052003490d5c20034101742209200520052009491b22094100480d5c0240024020030d002009102721050c010b200128020020032009102821050b2005450d3820012005360200200141046a2009360200200141086a28020021030b2004200341016a360200200520036a41033a0000200028020c21090240024020082802002205200428020022036b4104490d00200128020021050c010b200341046a220a2003490d5c20054101742203200a200a2003491b22034100480d5c0240024020050d002003102721050c010b200128020020052003102821050b2005450d3920012005360200200141046a2003360200200141086a28020021030b2004200341046a360200200520036a200936000020002d0009220041024b0d0f02400240024020000e03000102000b02400240200828020020042802002200460d00200128020021030c010b200041016a22032000490d5e20004101742205200320032005491b22054100480d5e0240024020000d002005102721030c010b200128020020002005102821030b2003450d3c20012003360200200141046a2005360200200141086a28020021000b2004200041016a360200200320006a41003a00000c110b02400240200828020020042802002200460d00200128020021030c010b200041016a22032000490d5d20004101742205200320032005491b22054100480d5d0240024020000d002005102721030c010b200128020020002005102821030b2003450d3c20012003360200200141046a2005360200200141086a28020021000b2004200041016a360200200320006a41013a00000c100b02400240200828020020042802002200460d00200128020021030c010b200041016a22032000490d5c20004101742205200320032005491b22054100480d5c0240024020000d002005102721030c010b200128020020002005102821030b2003450d3c20012003360200200141046a2005360200200141086a28020021000b2004200041016a360200200320006a41023a00000c0f0b02400240200828020020042802002203460d00200128020021050c010b200341016a22052003490d5b20034101742209200520052009491b22094100480d5b0240024020030d002009102721050c010b200128020020032009102821050b2005450d3c20012005360200200141046a2009360200200141086a28020021030b2004200341016a360200200520036a41043a0000200028020c21050240024020082802002203200428020022006b4104490d00200128020021030c010b200041046a22082000490d5b20034101742200200820082000491b22004100480d5b0240024020030d002000102721030c010b200128020020032000102821030b2003450d3d20012003360200200141046a2000360200200141086a28020021000b2004200041046a360200200320006a20053600000c0e0b02400240200828020020042802002203460d00200128020021050c010b200341016a22052003490d5a20034101742209200520052009491b22094100480d5a0240024020030d002009102721050c010b200128020020032009102821050b2005450d3d20012005360200200141046a2009360200200141086a28020021030b2004200341016a360200200520036a41053a0000200028020c21050240024020082802002203200428020022006b4104490d00200128020021030c010b200041046a22082000490d5a20034101742200200820082000491b22004100480d5a0240024020030d002000102721030c010b200128020020032000102821030b2003450d3e20012003360200200141046a2000360200200141086a28020021000b2004200041046a360200200320006a20053600000c0d0b02400240200828020020042802002203460d00200128020021050c010b200341016a22052003490d5920034101742209200520052009491b22094100480d590240024020030d002009102721050c010b200128020020032009102821050b2005450d3e20012005360200200141046a2009360200200141086a28020021030b2004200341016a360200200520036a41063a0000200028020c21050240024020082802002203200428020022006b4104490d00200128020021030c010b200041046a22082000490d5920034101742200200820082000491b22004100480d590240024020030d002000102721030c010b200128020020032000102821030b2003450d3f20012003360200200141046a2000360200200141086a28020021000b2004200041046a360200200320006a20053600000c0c0b02400240200828020020042802002203460d00200128020021050c010b200341016a22052003490d5820034101742209200520052009491b22094100480d580240024020030d002009102721050c010b200128020020032009102821050b2005450d3f20012005360200200141046a2009360200200141086a28020021030b2004200341016a360200200520036a41073a0000200028020c21090240024020082802002205200428020022036b4104490d00200128020021050c010b200341046a220a2003490d5820054101742203200a200a2003491b22034100480d580240024020050d002003102721050c010b200128020020052003102821050b2005450d4020012005360200200141046a2003360200200141086a28020021030b2004200341046a360200200520036a200936000002400240200828020020042802002203460d00200128020021050c010b200341016a22052003490d5820034101742208200520052008491b22084100480d580240024020030d002008102721050c010b200128020020032008102821050b2005450d4120012005360200200141046a2008360200200141086a28020021030b2004200341016a360200200520036a20002d00093a00000c0b0b02400240200828020020042802002203460d00200128020021050c010b200341016a22052003490d5720034101742209200520052009491b22094100480d570240024020030d002009102721050c010b200128020020032009102821050b2005450d4120012005360200200141046a2009360200200141086a28020021030b2004200341016a360200200520036a41083a00000240024020082802002205200428020022036b4120490d00200128020021050c010b200341206a22092003490d5720054101742203200920092003491b22034100480d570240024020050d002003102721050c010b200128020020052003102821050b2005450d4220012005360200200141046a2003360200200141086a28020021030b2004200341206a360200200520036a220341186a200041096a220541186a290000370000200341106a200541106a290000370000200341086a200541086a290000370000200320052900003700000240024020082802002205200428020022036b4120490d00200128020021050c010b200341206a22082003490d5720054101742203200820082003491b22034100480d570240024020050d002003102721050c010b200128020020052003102821050b2005450d4320012005360200200141046a2003360200200141086a28020021030b2004200341206a360200200520036a220141186a200041296a220041186a290000370000200141106a200041106a290000370000200141086a200041086a290000370000200120002900003700000c0a0b02400240200828020020042802002203460d00200128020021050c010b200341016a22052003490d5620034101742209200520052009491b22094100480d560240024020030d002009102721050c010b200128020020032009102821050b2005450d4320012005360200200141046a2009360200200141086a28020021030b2004200341016a360200200520036a41093a00000240024020082802002205200428020022036b4120490d00200128020021050c010b200341206a22082003490d5620054101742203200820082003491b22034100480d560240024020050d002003102721050c010b200128020020052003102821050b2005450d4420012005360200200141046a2003360200200141086a28020021030b2004200341206a360200200520036a220141186a200041096a220041186a290000370000200141106a200041106a290000370000200141086a200041086a290000370000200120002900003700000c090b02400240200828020020042802002203460d00200128020021050c010b200341016a22052003490d5520034101742209200520052009491b22094100480d550240024020030d002009102721050c010b200128020020032009102821050b2005450d4420012005360200200141046a2009360200200141086a28020021030b2004200341016a360200200520036a410a3a00000240024020082802002205200428020022036b4120490d00200128020021050c010b200341206a22092003490d5520054101742203200920092003491b22034100480d550240024020050d002003102721050c010b200128020020052003102821050b2005450d4520012005360200200141046a2003360200200141086a28020021030b2004200341206a360200200520036a220341186a200041096a220541186a290000370000200341106a200541106a290000370000200341086a200541086a290000370000200320052900003700000240024020082802002205200428020022036b4120490d00200128020021050c010b200341206a22092003490d5520054101742203200920092003491b22034100480d550240024020050d002003102721050c010b200128020020052003102821050b2005450d4620012005360200200141046a2003360200200141086a28020021030b2004200341206a360200200520036a220341186a200041296a220541186a290000370000200341106a200541106a290000370000200341086a200541086a29000037000020032005290000370000200029035021060240024020082802002203200428020022006b4108490d00200128020021030c010b200041086a22052000490d5520034101742200200520052000491b22004100480d550240024020030d002000102721030c010b200128020020032000102821030b2003450d4720012003360200200141046a2000360200200141086a28020021000b2004200041086a360200200320006a20063700000c080b02400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490d5420034101742205200420042005491b22054100480d540240024020030d002005102721040c010b200128020020032005102821040b2004450d4720012004360200200141046a2005360200200141086a28020021030b200141086a200341016a360200200420036a41063a0000200041046a2001109e020c070b02400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490d5320034101742205200420042005491b22054100480d530240024020030d002005102721040c010b200128020020032005102821040b2004450d4720012004360200200141046a2005360200200141086a28020021030b200141086a200341016a360200200420036a41073a0000200041046a2001109e020c060b02400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490d5220034101742205200420042005491b22054100480d520240024020030d002005102721040c010b200128020020032005102821040b2004450d4720012004360200200141046a2005360200200141086a28020021030b200141086a2205200341016a360200200420036a41083a0000024002400240024020002d00040e0400010203000b02400240200141046a28020020052802002203460d00200128020021040c010b200341016a22042003490d5520034101742205200420042005491b22054100480d550240024020030d002005102721040c010b200128020020032005102821040b2004450d4b20012004360200200141046a2005360200200141086a28020021030b200141086a2205200341016a360200200420036a41003a000002400240200141046a2802002204200528020022036b4120490d00200128020021040c010b200341206a22052003490d5520044101742203200520052003491b22034100480d550240024020040d002003102721040c010b200128020020042003102821040b2004450d4c20012004360200200141046a2003360200200141086a28020021030b200141086a2205200341206a360200200420036a220341186a200041056a220441186a290000370000200341106a200441106a290000370000200341086a200441086a2900003700002003200429000037000002400240200141046a2802002204200528020022036b4120490d00200128020021040c010b200341206a22052003490d5520044101742203200520052003491b22034100480d550240024020040d002003102721040c010b200128020020042003102821040b2004450d4d20012004360200200141046a2003360200200141086a28020021030b200141086a200341206a360200200420036a220141186a200041256a220041186a290000370000200141106a200041106a290000370000200141086a200041086a290000370000200120002900003700000c080b02400240200141046a28020020052802002203460d00200128020021040c010b200341016a22042003490d5420034101742205200420042005491b22054100480d540240024020030d002005102721040c010b200128020020032005102821040b2004450d4d20012004360200200141046a2005360200200141086a28020021030b200141086a2205200341016a360200200420036a41013a000002400240200141046a2802002204200528020022036b4120490d00200128020021040c010b200341206a22052003490d5420044101742203200520052003491b22034100480d540240024020040d002003102721040c010b200128020020042003102821040b2004450d4e20012004360200200141046a2003360200200141086a28020021030b200141086a200341206a360200200420036a220141186a200041056a220041186a290000370000200141106a200041106a290000370000200141086a200041086a290000370000200120002900003700000c070b02400240200141046a28020020052802002203460d00200128020021040c010b200341016a22042003490d5320034101742205200420042005491b22054100480d530240024020030d002005102721040c010b200128020020032005102821040b2004450d4e20012004360200200141046a2005360200200141086a28020021030b200141086a2205200341016a360200200420036a41023a00002000280208210402400240200141046a2802002203200528020022006b4104490d00200128020021030c010b200041046a22052000490d5320034101742200200520052000491b22004100480d530240024020030d002000102721030c010b200128020020032000102821030b2003450d4f20012003360200200141046a2000360200200141086a28020021000b200141086a200041046a360200200320006a20043600000c060b02400240200141046a28020020052802002203460d00200128020021040c010b200341016a22042003490d5220034101742205200420042005491b22054100480d520240024020030d002005102721040c010b200128020020032005102821040b2004450d4f20012004360200200141046a2005360200200141086a28020021030b200141086a2208200341016a360200200420036a41033a0000200028020821032002200041106a280200220436020c2002410c6a2001103002402004450d0020044105742109200141046a210a034002400240200a2802002205200828020022046b4120490d00200128020021050c010b200441206a220b2004490d5420054101742204200b200b2004491b22044100480d540240024020050d002004102721050c010b200128020020052004102821050b2005450d5220012005360200200a2004360200200828020021040b2008200441206a360200200520046a220441186a200341186a290000370000200441106a200341106a290000370000200441086a200341086a29000037000020042003290000370000200341206a2103200941606a22090d000b0b2000280214210320022000411c6a280200220036020c2002410c6a200110302000450d0520004105742108200141086a2105200141046a210903400240024020092802002204200528020022006b4120490d00200128020021040c010b200041206a220a2000490d5320044101742200200a200a2000491b22004100480d530240024020040d002000102721040c010b200128020020042000102821040b2004450d522001200436020020092000360200200528020021000b2005200041206a360200200420006a220041186a200341186a290000370000200041106a200341106a290000370000200041086a200341086a29000037000020002003290000370000200341206a2103200841606a22080d000c060b0b02400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490d800120034101742205200420042005491b22054100480d80010240024020030d002005102721040c010b200128020020032005102821040b2004450d5220012004360200200141046a2005360200200141086a28020021030b200141086a200341016a360200200420036a41093a00002000280204220341024b0d0402400240024020030e03000102000b02400240200141046a280200200141086a2802002203460d00200128020021050c010b200341016a22042003490d820120034101742205200420042005491b22044100480d82010240024020030d002004102721050c010b200128020020032004102821050b2005450d5520012005360200200141046a2004360200200141086a28020021030b200141086a2204200341016a360200200520036a41003a0000200028020821032002200041106a280200220036020c2002410c6a200110302000450d062003200041286c6a210a200141046a210503400240024020052802002208200428020022006b4120490d00200128020021080c010b200041206a22092000490d830120084101742200200920092000491b22004100480d83010240024020080d002000102721080c010b200128020020082000102821080b2008450d572001200836020020052000360200200428020021000b2004200041206a360200200820006a220041186a200341186a290000370000200041106a200341106a290000370000200041086a200341086a29000037000020002003290000370000200341206a29030021060240024020052802002208200428020022006b4108490d00200128020021080c010b200041086a22092000490d830120084101742200200920092000491b22004100480d83010240024020080d002000102721080c010b200128020020082000102821080b2008450d582001200836020020052000360200200428020021000b2004200041086a360200200820006a2006370000200a200341286a2203470d000c070b0b02400240200141046a280200200141086a2802002200460d00200128020021030c010b200041016a22032000490d810120004101742204200320032004491b22044100480d81010240024020000d002004102721030c010b200128020020002004102821030b2003450d5720012003360200200141046a2004360200200141086a28020021000b200141086a200041016a360200200320006a41013a00000c050b02400240200141046a280200200141086a2802002200460d00200128020021030c010b200041016a22032000490d800120004101742204200320032004491b22044100480d80010240024020000d002004102721030c010b200128020020002004102821030b2003450d5720012003360200200141046a2004360200200141086a28020021000b200141086a200041016a360200200320006a41023a00000c040b02400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490d7f20034101742205200420042005491b22054100480d7f0240024020030d002005102721040c010b200128020020032005102821040b2004450d5720012004360200200141046a2005360200200141086a28020021030b200141086a200341016a360200200420036a410a3a000020002d0008220341044b0d030240024002400240024020030e050001020304000b02400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490d830120034101742205200420042005491b22054100480d83010240024020030d002005102721040c010b200128020020032005102821040b2004450d5c20012004360200200141046a2005360200200141086a28020021030b200141086a2205200341016a360200200420036a41003a0000200028020c210402400240200141046a2802002203200528020022006b4104490d00200128020021030c010b200041046a22052000490d830120034101742200200520052000491b22004100480d83010240024020030d002000102721030c010b200128020020032000102821030b2003450d5d20012003360200200141046a2000360200200141086a28020021000b200141086a200041046a360200200320006a20043600000c070b02400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490d820120034101742205200420042005491b22054100480d82010240024020030d002005102721040c010b200128020020032005102821040b2004450d5d20012004360200200141046a2005360200200141086a28020021030b200141086a2205200341016a360200200420036a41013a0000200041186a29030021062000290310210702400240200141046a2802002203200528020022006b4110490d00200128020021030c010b200041106a22042000490d820120034101742200200420042000491b22004100480d82010240024020030d002000102721030c010b200128020020032000102821030b2003450d5e20012003360200200141046a2000360200200141086a28020021000b200141086a200041106a360200200320006a22012006370008200120073700000c060b02400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490d810120034101742205200420042005491b22054100480d81010240024020030d002005102721040c010b200128020020032005102821040b2004450d5e20012004360200200141046a2005360200200141086a28020021030b200141086a2205200341016a360200200420036a41023a0000200028022c210802400240200141046a2802002204200528020022036b4104490d00200128020021040c010b200341046a22052003490d810120044101742203200520052003491b22034100480d81010240024020040d002003102721040c010b200128020020042003102821040b2004450d5f20012004360200200141046a2003360200200141086a28020021030b200141086a2205200341046a360200200420036a2008360000200041386a29030021062000290330210702400240200141046a2802002204200528020022036b4110490d00200128020021040c010b200341106a22052003490d810120044101742203200520052003491b22034100480d81010240024020040d002003102721040c010b200128020020042003102821040b2004450d6020012004360200200141046a2003360200200141086a28020021030b200141086a2205200341106a360200200420036a220320063700082003200737000002400240200141046a2802002204200528020022036b4120490d00200128020021040c010b200341206a22052003490d810120044101742203200520052003491b22034100480d81010240024020040d002003102721040c010b200128020020042003102821040b2004450d6120012004360200200141046a2003360200200141086a28020021030b200141086a200341206a360200200420036a220141186a200041096a220041186a290000370000200141106a200041106a290000370000200141086a200041086a290000370000200120002900003700000c050b02400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490d800120034101742205200420042005491b22054100480d80010240024020030d002005102721040c010b200128020020032005102821040b2004450d6120012004360200200141046a2005360200200141086a28020021030b200141086a2205200341016a360200200420036a41033a0000200041186a29030021062000290310210702400240200141046a2802002203200528020022006b4110490d00200128020021030c010b200041106a22042000490d800120034101742200200420042000491b22004100480d80010240024020030d002000102721030c010b200128020020032000102821030b2003450d6220012003360200200141046a2000360200200141086a28020021000b200141086a200041106a360200200320006a22012006370008200120073700000c040b02400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490d7f20034101742205200420042005491b22054100480d7f0240024020030d002005102721040c010b200128020020032005102821040b2004450d6220012004360200200141046a2005360200200141086a28020021030b200141086a2205200341016a360200200420036a41043a0000200041186a29030021062000290310210702400240200141046a2802002203200528020022006b4110490d00200128020021030c010b200041106a22042000490d7f20034101742200200420042000491b22004100480d7f0240024020030d002000102721030c010b200128020020032000102821030b2003450d6320012003360200200141046a2000360200200141086a28020021000b200141086a200041106a360200200320006a22012006370008200120073700000c030b02400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490d7e20034101742205200420042005491b22054100480d7e0240024020030d002005102721040c010b200128020020032005102821040b2004450d6320012004360200200141046a2005360200200141086a28020021030b200141086a200341016a360200200420036a410b3a000020002d0008220341054b0d0202400240024002400240024020030e06000102030405000b02400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490d830120034101742205200420042005491b22054100480d83010240024020030d002005102721040c010b200128020020032005102821040b2004450d6920012004360200200141046a2005360200200141086a28020021030b200141086a2205200341016a360200200420036a41003a000002400240200141046a2802002204200528020022036b4120490d00200128020021040c010b200341206a22052003490d830120044101742203200520052003491b22034100480d83010240024020040d002003102721040c010b200128020020042003102821040b2004450d6a20012004360200200141046a2003360200200141086a28020021030b200141086a2205200341206a360200200420036a220341186a200041096a220441186a290000370000200341106a200441106a290000370000200341086a200441086a2900003700002003200429000037000002400240200141046a2802002204200528020022036b4120490d00200128020021040c010b200341206a22052003490d830120044101742203200520052003491b22034100480d83010240024020040d002003102721040c010b200128020020042003102821040b2004450d6b20012004360200200141046a2003360200200141086a28020021030b200141086a2205200341206a360200200420036a220341186a200041296a220441186a290000370000200341106a200441106a290000370000200341086a200441086a29000037000020032004290000370000200041d8006a29030021062000290350210702400240200141046a2802002203200528020022006b4110490d00200128020021030c010b200041106a22042000490d830120034101742200200420042000491b22004100480d83010240024020030d002000102721030c010b200128020020032000102821030b2003450d6c20012003360200200141046a2000360200200141086a28020021000b200141086a200041106a360200200320006a22012006370008200120073700000c070b02400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490d820120034101742205200420042005491b22054100480d82010240024020030d002005102721040c010b200128020020032005102821040b2004450d6c20012004360200200141046a2005360200200141086a28020021030b200141086a2205200341016a360200200420036a41013a000002400240200141046a2802002204200528020022036b4120490d00200128020021040c010b200341206a22052003490d820120044101742203200520052003491b22034100480d82010240024020040d002003102721040c010b200128020020042003102821040b2004450d6d20012004360200200141046a2003360200200141086a28020021030b200141086a2205200341206a360200200420036a220341186a200041096a220441186a290000370000200341106a200441106a290000370000200341086a200441086a2900003700002003200429000037000002400240200141046a2802002204200528020022036b4120490d00200128020021040c010b200341206a22052003490d820120044101742203200520052003491b22034100480d82010240024020040d002003102721040c010b200128020020042003102821040b2004450d6e20012004360200200141046a2003360200200141086a28020021030b200141086a200341206a360200200420036a220141186a200041296a220041186a290000370000200141106a200041106a290000370000200141086a200041086a290000370000200120002900003700000c060b02400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490d810120034101742205200420042005491b22054100480d81010240024020030d002005102721040c010b200128020020032005102821040b2004450d6e20012004360200200141046a2005360200200141086a28020021030b200141086a2205200341016a360200200420036a41023a000002400240200141046a2802002204200528020022036b4120490d00200128020021040c010b200341206a22052003490d810120044101742203200520052003491b22034100480d81010240024020040d002003102721040c010b200128020020042003102821040b2004450d6f20012004360200200141046a2003360200200141086a28020021030b200141086a200341206a360200200420036a220141186a200041096a220041186a290000370000200141106a200041106a290000370000200141086a200041086a290000370000200120002900003700000c050b02400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490d800120034101742205200420042005491b22054100480d80010240024020030d002005102721040c010b200128020020032005102821040b2004450d6f20012004360200200141046a2005360200200141086a28020021030b200141086a2205200341016a360200200420036a41033a0000200028020c210402400240200141046a2802002203200528020022006b4104490d00200128020021030c010b200041046a22052000490d800120034101742200200520052000491b22004100480d80010240024020030d002000102721030c010b200128020020032000102821030b2003450d7020012003360200200141046a2000360200200141086a28020021000b200141086a200041046a360200200320006a20043600000c040b02400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490d7f20034101742205200420042005491b22054100480d7f0240024020030d002005102721040c010b200128020020032005102821040b2004450d7020012004360200200141046a2005360200200141086a28020021030b200141086a2205200341016a360200200420036a41043a000002400240200141046a2802002204200528020022036b4120490d00200128020021040c010b200341206a22052003490d7f20044101742203200520052003491b22034100480d7f0240024020040d002003102721040c010b200128020020042003102821040b2004450d7120012004360200200141046a2003360200200141086a28020021030b200141086a2205200341206a360200200420036a220341186a200041096a220441186a290000370000200341106a200441106a290000370000200341086a200441086a2900003700002003200429000037000002400240200141046a28020020052802002203460d00200128020021040c010b200341016a22042003490d7f20034101742205200420042005491b22054100480d7f0240024020030d002005102721040c010b200128020020032005102821040b2004450d7220012004360200200141046a2005360200200141086a28020021030b200141086a200341016a360200200420036a20002d00293a00000c030b02400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490d7e20034101742205200420042005491b22054100480d7e0240024020030d002005102721040c010b200128020020032005102821040b2004450d7220012004360200200141046a2005360200200141086a28020021030b200141086a2205200341016a360200200420036a41053a000002400240200141046a2802002204200528020022036b4120490d00200128020021040c010b200341206a22052003490d7e20044101742203200520052003491b22034100480d7e0240024020040d002003102721040c010b200128020020042003102821040b2004450d7320012004360200200141046a2003360200200141086a28020021030b200141086a2205200341206a360200200420036a220341186a200041096a220441186a290000370000200341106a200441106a290000370000200341086a200441086a29000037000020032004290000370000200028022c21082002200041346a280200220036020c2002410c6a2001103002400240200141046a2802002204200528020022036b2000490d00200128020021040c010b200320006a22052003490d7e20044101742203200520052003491b22034100480d7e0240024020040d002003102721040c010b200128020020042003102821040b2004450d7420012004360200200141046a2003360200200141086a28020021030b200141086a200320006a360200200420036a2008200010ce041a0c020b02400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490d7d20034101742205200420042005491b22054100480d7d0240024020030d002005102721040c010b200128020020032005102821040b2004450d7420012004360200200141046a2005360200200141086a28020021030b200141086a2205200341016a360200200420036a410c3a0000200041026a2104200141046a280200210820052802002103024020002d00014101460d000240024020082003460d00200128020021000c010b200341016a22002003490d7e20034101742205200020002005491b22054100480d7e0240024020030d002005102721000c010b200128020020032005102821000b2000450d7620012000360200200141046a2005360200200141086a28020021030b200141086a2205200341016a360200200020036a41003a000002400240200141046a28020020052802002200460d00200128020021030c010b200041016a22032000490d7e20004101742205200320032005491b22054100480d7e0240024020000d002005102721030c010b200128020020002005102821030b2003450d7720012003360200200141046a2005360200200141086a28020021000b200141086a200041016a360200200320006a20042d00003a00000c020b0240024020082003460d00200128020021000c010b200341016a22002003490d7d20034101742205200020002005491b22054100480d7d0240024020030d002005102721000c010b200128020020032005102821000b2000450d7720012000360200200141046a2005360200200141086a28020021030b200141086a2205200341016a360200200020036a41013a000002400240200141046a2802002203200528020022006b4120490d00200128020021030c010b200041206a22052000490d7d20034101742200200520052000491b22004100480d7d0240024020030d002000102721030c010b200128020020032000102821030b2003450d7820012003360200200141046a2000360200200141086a28020021000b200141086a200041206a360200200320006a220141186a200441186a290000370000200141106a200441106a290000370000200141086a200441086a290000370000200120042900003700000c010b02400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490d7c20034101742205200420042005491b22054100480d7c0240024020030d002005102721040c010b200128020020032005102821040b2004450d7820012004360200200141046a2005360200200141086a28020021030b200141086a2205200341016a360200200420036a410d3a000002400240200141046a28020020052802002203460d00200128020021040c010b200341016a22042003490d7c20034101742205200420042005491b22054100480d7c0240024020030d002005102721040c010b200128020020032005102821040b2004450d7920012004360200200141046a2005360200200141086a28020021030b200141086a2205200341016a360200200420036a41003a00002000290308210602400240200141046a2802002204200528020022036b4108490d00200128020021040c010b200341086a22052003490d7c20044101742203200520052003491b22034100480d7c0240024020040d002003102721040c010b200128020020042003102821040b2004450d7a20012004360200200141046a2003360200200141086a28020021030b200141086a2205200341086a360200200420036a200637000002400240200141046a2802002204200528020022036b4120490d00200128020021040c010b200341206a22052003490d7c20044101742203200520052003491b22034100480d7c0240024020040d002003102721040c010b200128020020042003102821040b2004450d7b20012004360200200141046a2003360200200141086a28020021030b200141086a200341206a360200200420036a220141186a200041106a220041186a290000370000200141106a200041106a290000370000200141086a200041086a290000370000200120002900003700000b200241106a24000f0b20054101102a000b20044101102a000b20044101102a000b20054101102a000b20054101102a000b20034101102a000b20004101102a000b20054101102a000b20054101102a000b20034101102a000b20004101102a000b20054101102a000b20034101102a000b20054101102a000b20034101102a000b20034101102a000b20034101102a000b20004101102a000b20054101102a000b20054101102a000b20004101102a000b20054101102a000b20034101102a000b20004101102a000b20054101102a000b20034101102a000b20004101102a000b20054101102a000b20054101102a000b20004101102a000b20094101102a000b20094101102a000b20034101102a000b20004101102a000b20094101102a000b20034101102a000b20034101102a000b20004101102a000b20054101102a000b20094101102a000b20034101102a000b20054101102a000b20054101102a000b20054101102a000b20094101102a000b20004101102a000b20094101102a000b20004101102a000b20094101102a000b20004101102a000b20094101102a000b20034101102a000b20084101102a000b20094101102a000b20034101102a000b20034101102a000b20094101102a000b20034101102a000b20094101102a000b20034101102a000b20034101102a000b20004101102a000b20054101102a000b20054101102a000b20054101102a000b20054101102a000b20034101102a000b20034101102a000b20054101102a000b20034101102a000b20054101102a000b20004101102a000b20054101102a000b20044101102a000b20004101102a000b102b000b20054101102a000b20044101102a000b20004101102a000b20004101102a000b20044101102a000b20044101102a000b20054101102a000b20054101102a000b20004101102a000b20054101102a000b20004101102a000b20054101102a000b20034101102a000b20034101102a000b20034101102a000b20054101102a000b20004101102a000b20054101102a000b20004101102a000b20054101102a000b20054101102a000b20034101102a000b20034101102a000b20004101102a000b20054101102a000b20034101102a000b20034101102a000b20054101102a000b20034101102a000b20054101102a000b20004101102a000b20054101102a000b20034101102a000b20054101102a000b20054101102a000b20034101102a000b20034101102a000b20054101102a000b20054101102a000b20054101102a000b20054101102a000b20004101102a000b20054101102a000b20054101102a000b20034101102a000b20034101102a000b102b000bde1f01047f0240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024020002d0000220241054b0d0002400240024002400240024020020e06000102030405000b02400240200141046a280200200141086a2802002202460d00200128020021030c010b200241016a22032002490d1c20024101742204200320032004491b22044100480d1c0240024020020d002004102721030c010b200128020020022004102821030b2003450d0720012003360200200141046a2004360200200141086a28020021020b200141086a2204200241016a360200200320026a41003a000002400240200141046a2802002203200428020022026b4120490d00200128020021030c010b200241206a22042002490d1c20034101742202200420042002491b22024100480d1c0240024020030d002002102721030c010b200128020020032002102821030b2003450d0820012003360200200141046a2002360200200141086a28020021020b200141086a2204200241206a360200200320026a220241186a200041196a290000370000200241106a200041116a290000370000200241086a200041096a290000370000200220002900013700002000280244210502400240200141046a2802002203200428020022026b4104490d00200128020021030c010b200241046a22042002490d1c20034101742202200420042002491b22024100480d1c0240024020030d002002102721030c010b200128020020032002102821030b2003450d0920012003360200200141046a2002360200200141086a28020021020b200141086a2204200241046a360200200320026a200536000002400240200141046a2802002203200428020022026b4120490d00200128020021030c010b200241206a22042002490d1c20034101742202200420042002491b22024100480d1c0240024020030d002002102721030c010b200128020020032002102821030b2003450d0a20012003360200200141046a2002360200200141086a28020021020b200141086a2204200241206a360200200320026a220241186a200041216a220341186a290000370000200241106a200341106a290000370000200241086a200341086a290000370000200220032900003700002000280248210302400240200141046a2802002202200428020022006b4104490d00200128020021020c010b200041046a22042000490d1c20024101742200200420042000491b22004100480d1c0240024020020d002000102721020c010b200128020020022000102821020b2002450d0b20012002360200200141046a2000360200200141086a28020021000b200141086a200041046a360200200220006a20033600000f0b02400240200141046a280200200141086a2802002202460d00200128020021030c010b200241016a22032002490d1b20024101742204200320032004491b22044100480d1b0240024020020d002004102721030c010b200128020020022004102821030b2003450d0b20012003360200200141046a2004360200200141086a28020021020b200141086a2204200241016a360200200320026a41013a000002400240200141046a2802002203200428020022026b4120490d00200128020021030c010b200241206a22042002490d1b20034101742202200420042002491b22024100480d1b0240024020030d002002102721030c010b200128020020032002102821030b2003450d0c20012003360200200141046a2002360200200141086a28020021020b200141086a2204200241206a360200200320026a220241186a200041196a290000370000200241106a200041116a290000370000200241086a200041096a2900003700002002200029000137000002400240200141046a2802002203200428020022026b4120490d00200128020021030c010b200241206a22042002490d1b20034101742202200420042002491b22024100480d1b0240024020030d002002102721030c010b200128020020032002102821030b2003450d0d20012003360200200141046a2002360200200141086a28020021020b200141086a2204200241206a360200200320026a220241186a200041216a220341186a290000370000200241106a200341106a290000370000200241086a200341086a2900003700002002200329000037000002400240200141046a28020020042802002202460d00200128020021030c010b200241016a22032002490d1b20024101742204200320032004491b22044100480d1b0240024020020d002004102721030c010b200128020020022004102821030b2003450d0e20012003360200200141046a2004360200200141086a28020021020b200141086a2204200241016a360200200320026a20002d00413a00002000280244210502400240200141046a2802002203200428020022026b4104490d00200128020021030c010b200241046a22042002490d1b20034101742202200420042002491b22024100480d1b0240024020030d002002102721030c010b200128020020032002102821030b2003450d0f20012003360200200141046a2002360200200141086a28020021020b200141086a2204200241046a360200200320026a20053600002000280248210302400240200141046a2802002202200428020022006b4104490d00200128020021020c010b200041046a22042000490d1b20024101742200200420042000491b22004100480d1b0240024020020d002000102721020c010b200128020020022000102821020b2002450d1020012002360200200141046a2000360200200141086a28020021000b200141086a200041046a360200200220006a20033600000f0b02400240200141046a280200200141086a2802002202460d00200128020021030c010b200241016a22032002490d1a20024101742204200320032004491b22044100480d1a0240024020020d002004102721030c010b200128020020022004102821030b2003450d1020012003360200200141046a2004360200200141086a28020021020b200141086a2204200241016a360200200320026a41023a000002400240200141046a2802002203200428020022026b4120490d00200128020021030c010b200241206a22042002490d1a20034101742202200420042002491b22024100480d1a0240024020030d002002102721030c010b200128020020032002102821030b2003450d1120012003360200200141046a2002360200200141086a28020021020b200141086a200241206a360200200320026a220141186a200041196a290000370000200141106a200041116a290000370000200141086a200041096a290000370000200120002900013700000f0b02400240200141046a280200200141086a2802002202460d00200128020021030c010b200241016a22032002490d1920024101742204200320032004491b22044100480d190240024020020d002004102721030c010b200128020020022004102821030b2003450d1120012003360200200141046a2004360200200141086a28020021020b200141086a2204200241016a360200200320026a41033a000002400240200141046a2802002203200428020022026b4120490d00200128020021030c010b200241206a22042002490d1920034101742202200420042002491b22024100480d190240024020030d002002102721030c010b200128020020032002102821030b2003450d1220012003360200200141046a2002360200200141086a28020021020b200141086a200241206a360200200320026a220141186a200041196a290000370000200141106a200041116a290000370000200141086a200041096a290000370000200120002900013700000f0b02400240200141046a280200200141086a2802002202460d00200128020021030c010b200241016a22032002490d1820024101742204200320032004491b22044100480d180240024020020d002004102721030c010b200128020020022004102821030b2003450d1220012003360200200141046a2004360200200141086a28020021020b200141086a2204200241016a360200200320026a41043a000002400240200141046a2802002203200428020022026b4120490d00200128020021030c010b200241206a22042002490d1820034101742202200420042002491b22024100480d180240024020030d002002102721030c010b200128020020032002102821030b2003450d1320012003360200200141046a2002360200200141086a28020021020b200141086a2204200241206a360200200320026a220241186a200041196a290000370000200241106a200041116a290000370000200241086a200041096a2900003700002002200029000137000002400240200141046a28020020042802002202460d00200128020021030c010b200241016a22032002490d1820024101742204200320032004491b22044100480d180240024020020d002004102721030c010b200128020020022004102821030b2003450d1420012003360200200141046a2004360200200141086a28020021020b200141086a200241016a360200200320026a20002d00213a00000f0b02400240200141046a280200200141086a2802002202460d00200128020021030c010b200241016a22032002490d1720024101742204200320032004491b22044100480d170240024020020d002004102721030c010b200128020020022004102821030b2003450d1420012003360200200141046a2004360200200141086a28020021020b200141086a2204200241016a360200200320026a41053a000002400240200141046a2802002203200428020022026b4120490d00200128020021030c010b200241206a22042002490d1720034101742202200420042002491b22024100480d170240024020030d002002102721030c010b200128020020032002102821030b2003450d1520012003360200200141046a2002360200200141086a28020021020b200141086a2204200241206a360200200320026a220241186a200041196a290000370000200241106a200041116a290000370000200241086a200041096a2900003700002002200029000137000002400240200141046a28020020042802002202460d00200128020021030c010b200241016a22032002490d1720024101742204200320032004491b22044100480d170240024020020d002004102721030c010b200128020020022004102821030b2003450d1620012003360200200141046a2004360200200141086a28020021020b200141086a200241016a360200200320026a20002d00213a00000b0f0b20044101102a000b20024101102a000b20024101102a000b20024101102a000b20004101102a000b20044101102a000b20024101102a000b20024101102a000b20044101102a000b20024101102a000b20004101102a000b20044101102a000b20024101102a000b20044101102a000b20024101102a000b20044101102a000b20024101102a000b20044101102a000b20044101102a000b20024101102a000b20044101102a000b102b000b130020004102360204200041bce4c1003602000b130020004102360204200041d0cbc5003602000b130020004101360204200041e0e7c2003602000b1300200041033602042000419085c0003602000b130020004103360204200041a89ec4003602000b130020004101360204200041ccc8c5003602000b13002000410b3602042000418ccbc3003602000b130020004106360204200041808bc2003602000b130020004104360204200041f8bec0003602000b130020004103360204200041f8c1c5003602000b130020004105360204200041dca1c1003602000b130020004106360204200041b484c2003602000b130020004101360204200041f888c0003602000bb10501027f4190ce0021024100210302400240024002400240024002400240024002400240024002400240024002400240024020012802000e1200110c0c1101020304090a0b11110d110e11000b417f2102200141086a280200417f6a220141054b0d0e41012103024002400240024020010e06140001020303140b41c0843d21020c120b4190ce0021020c120b41c09a0c21020c110b4190ce0021020c100b200141086a280200417f6a220141014b0d0d41c0843d21024100210320010e020f030f0b200141086a2d0000417f6a2201410c4b0d0c41a0c21e21024100210302400240024020010e0d111100000101111101020c0c0c110b4180b51821020c0f0b41b0e32d21020c0e0b4101210341f0930921020c0e0b41f0930921020c0c0b200141086a2d0000417f6a220141104b0d0a41c096b10221024100210320010e110c0c010100000c0c0101070702020203030c0b4101210341a0c21e21020c0b0b41c09a0c21020c090b41a08d0621020c080b41a0c21e21020c070b20012d0004417f6a220141034b0d054101210341a08d0621020240024020010e0409090001090b41c096b10221020c080b41c09a0c21020c070b20012d0004417f6a220141034b0d044101210341a08d0621020240024020010e0408080001080b41c096b10221020c070b41c09a0c21020c060b200141086a280200417f6a220141094b0d0341a0cb98012102410021030240024020010e0a07070700070102020202070b41d0a5cc0021020c050b4180ade20421020c040b410121034190ce0021020c040b200141086a280200417f6a220141024b0d0141a0c21e210241002103024020010e03040000040b4101210341a08d0621020c030b410121032001280204417f6a220141014b0d0041c0843d210220010e020200020b4190ce0021020b410021030b200020033a0004200020023602000be4910108017f017e097f017e037f017e0e7f067e230041a0076b220324000240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024020012802000e12000102030405060708090a0b0c0f10111213000b200141106a29030021042001410c6a280200210520022d0001210620022d000021020240024002400240024002400240024002400240200141086a28020022070e0700010203040607000b20034194036a41013602002003420137028403200341ccfdc40036028003200341023602dc06200341c4fdc4003602d8062003200341d8066a3602900320034180036a4190b8c3001057000b4100210841ad88c3004100200220067241ff01711b21094128210a4101210b0c4a0b2004a7210702400240200241ff01710d004101210b200641ff01714101460d010b41d588c3002109412a210a4101210b410021082007450d4a0c490b20070d020c470b4101210b0240200220067241ff0171450d0041ad88c30021094128210a410021080c490b410810272202450d192002200437000041a0b8c300410a200241081003200210290c460b2004a721070240200220067241ff0171450d0041ad88c30021094128210a4101210b4100210820070d470c480b41aab8c300410520052004422088a710034101210b2007450d450b200510290c440b2004422088a721092004a7210a0240200220067241ff0171450d0002402009450d00200941186c21082005210203400240200241046a280200450d00200228020010290b0240200241106a280200450d002002410c6a28020010290b200241186a2102200841686a22080d000b0b41ad88c30021094101210c4100210d200a0d020c430b0240200941186c2202450d00200520026a21082005210203402002280200200241086a2802002002410c6a280200200241146a2802001003200241186a22022008470d000b0b02402009450d00200941186c21082005210203400240200241046a280200450d00200228020010290b0240200241106a280200450d002002410c6a28020010290b200241186a2102200841686a22080d000b0b4101210c200a450d41200510290c410b2004422088a721092004a7210a200220067241ff0171450d0102402009450d002009410c6c21082005210203400240200241046a280200450d00200228020010290b2002410c6a2102200841746a22080d000b0b41ad88c30021094100210c4101210d200a450d410b200510290c400b02402009410c6c2202450d00200520026a21082005210203402002280200200241086a280200100c2002410c6a22022008470d000b0b02402009450d002009410c6c21082005210203400240200241046a280200450d00200228020010290b2002410c6a2102200841746a22080d000b0b4101210d200a450d3d200510290c3d0b10ae02000b418988c30021094124210a4101210820022d00000d2a20022d000141ff01714102470d2a200141086a290300210420034190056a41086a22024200370300200342003703900541bdcbc500411320034190056a100420034190046a41086a200229030037030020032003290390053703900420034190046a411041b8d6c50041004100100b417f470d12200341186a41ceecc200410d109401024002402003290320500d002003280218450d00200341086a41ceecc200410d109401200329031042b9067c42b90620032802081b2004560d010b20034190056a41086a22024200370300200342003703900541ceecc200410d20034190056a100420034190046a41086a22062002290300370300200320032903900537039004200320043703800320034190046a411020034180036a4108100341012108200341013a00800320024200370300200342003703900541bdcbc500411320034190056a10042006200229030037030020032003290390053703900420034190046a411020034180036a410110030c0b0b41e8ebc2001058000b20034188036a2001410c6a2802003602002003200129020437038003200341286a20034180036a20022d000020022d000110af02200328022c210a200328022821094100210b410121080c3f0b10b002000b200341fc026a41026a22062001410f6a2d00003a0000200341f0046a41086a2207200141206a290300370300200341f0046a410d6a2209200141256a290000370000200320012f000d3b01fc022003200141186a2903003703f004200141386a290300210e200141306a2903002104200141146a280200210f200141106a28020021082001410c6a2d0000211020022d0001211120022d0000210a024002400240200141086a2802000e03000102000b20034180036a41146a41013602002003420137028403200341ccfdc40036028003200341023602dc06200341c4fdc4003602d8062003200341d8066a3602900320034180036a41c0bec0001057000b2002411a6a2901002112200241196a2d00002113200241186a2d00002114200241166a2f01002115200241156a2d00002116200241146a2d00002117200241126a2f0100210b200241116a2d00002105200241106a2d0000210c2002410e6a2f0100210d2002410d6a2d000021182002410c6a2d000021192002410a6a2f0100211a200241096a2d0000211b200241086a2d0000211c200241066a2f0100211d200241056a2d0000211e200241046a2d0000211f200241026a2f0100212020034188046a41026a20062d00003a000020034198066a41086a200729030037030020034198066a410d6a2009290000370000200320032f01fc023b018804200320032903f004370398064101210241d588c300210941002106412a210702400240200a41ff0171450d004100210a0c010b4100210a201141ff01714101470d00201d410874201e72201c41187472210941002102201b2107201a21062019210a0b200641ffff0371410874200741ff017172200a41187472210a20020d32200320123703e805200320133a00e705200320143a00e605200320153b01e405200320163a00e305200320173a00e2052003200b3b01e005200320053a00df052003200c3a00de052003200d3b01dc05200320183a00db052003200a3600d705200320093600d3052003201f3a00d205200320203b01d005200341b8066a41026a220220034188046a41026a2d00003a0000200320032f0188043b01b80620034180036a41086a20034198066a41086a29030037030020034180036a410d6a220620034198066a410d6a2900003700002003200329039806370380030240201041ff01714101460d00200341c8066a41026a20022d00003a0000200341b0046a41086a20034180036a41086a290300370300200341b0046a410d6a2006290000370000200320032f01b8063b01c80620032003290380033703b0040c2e0b20034190046a200841067610cc012003280290042106024002402003280298042008413f7122024b0d00410021020c010b200341c8066a41026a200620024105746a220241026a2d00003a0000200341b8046a200241136a290000370300200341bd046a200241186a290000370000200320022f00003b01c8062003200229000b3703b0042002280007210f20022800032108410121020b0240200328029404450d00200610290b20020d2d410121024115210f4184efc20021080c2e0b200141c8006a2903002112200141c0006a290300212120034198066a41026a20062d00003a0000200341d8066a41086a2007290300370300200341d8066a410d6a2009290000370000200320032f01fc023b019806200320032903f0043703d80602402011200a7241ff0171450d0041ad88c30021094128210a410121084101210b0c3e0b200341b8066a41026a220220034198066a41026a2d00003a000020034180036a41086a2206200341d8066a41086a29030037030020034180036a410d6a2207200341d8066a410d6a290000370000200320032f0198063b01b806200320032903d806370380030240201041ff01714101460d00200341c8066a41026a20022d00003a0000200341b0046a41086a2006290300370300200341b0046a410d6a2007290000370000200320032f01b8063b01c80620032003290380033703b0040c2b0b200341d0056a200841067610cc0120032802d00521060240024020032802d8052008413f7122024b0d00410021020c010b200341c8066a41026a200620024105746a220241026a2d00003a0000200341b8046a200241136a290000370300200341bd046a200241186a290000370000200320022f00003b01c8062003200229000b3703b0042002280007210f20022800032108410121020b024020032802d405450d00200610290b20020d2a410121024184efc20021084115210f0c2b0b20034180036a41306a200141386a29030037030020034180036a41286a200141306a29030037030020034180036a41206a200141286a29030037030020034180036a41186a200141206a29030037030020034180036a41106a200141186a29030037030020034180036a41086a200141106a2903003703002003200141086a29030037038003200341d8066a41206a200241206a290200370300200341d8066a41186a200241186a290200370300200341d8066a41106a200241106a290200370300200341d8066a41086a200241086a290200370300200320022902003703d80620034190026a20034180036a200341d8066a10b102200328029402210a20032802900221094100210f410121084101210b0c3d0b200141086a280200210c2001280204210d200341d8066a2001410c6a41c40010ce041a2002411a6a2901002104200241196a2d00002106200241186a2d00002107200241166a2f01002111200241156a2d0000210f200241146a2d00002110200241126a2f01002113200241116a2d00002114200241106a2d000021152002410e6a2f010021162002410d6a2d000021172002410c6a2d0000210b2002410a6a2f01002105200241096a2d00002118200241086a2d00002119200241066a2f0100211a200241056a2d0000211b200241046a2d0000211c200241026a2f0100211d20022d0001210820022d00002102200341e8046a20034194076a290200370300200341e0046a2003418c076a290200370300200341d8046a20034184076a290200370300200341d0046a200341fc066a290200370300200341b0046a41186a200341f4066a290200370300200341b0046a41106a200341d8066a41146a290200370300200341b0046a41086a200341d8066a410c6a290200370300200320032902dc063703b00441d588c3002109412a210a20020d26200841ff01714101470d26200320043703a805200320063a00a705200320073a00a605200320113b01a4052003200f3a00a305200320103a00a205200320133b01a005200320143a009f05200320153a009e05200320163b019c05200320173a009b052003201c3a0092052003201d3b01900520032005410874201872200b41187472360097052003201a410874201b722019411874723600930520034180036a20034190056a108d0220032802a0032202450d0e200341d0056a41106a20034180036a41386a290300370300200341d0056a41086a20034180036a41306a290300370300200341d0056a41186a200341c0036a290300370300200341d0056a41206a200341c8036a28020036020020034190046a41086a200341dc056a29020037030020034190046a41106a2208200341e4056a29020037030020034190046a41186a200341ec056a290200370300200320034180036a41286a2903003703d005200320032902d40537039004024020032802a403450d00200210290b200341f0046a41086a20034190046a41086a290300370300200341f0046a41106a2008290300370300200341f0046a41186a20034190046a41186a29030037030020032003290390043703f00420034190056a41386a200341b0046a41386a29030037030020034190056a41306a200341b0046a41306a29030037030020034190056a41286a200341b0046a41286a29030037030020034190056a41206a200341b0046a41206a29030037030020034190056a41186a200341b0046a41186a29030037030020034190056a41106a200341b0046a41106a29030037030020034190056a41086a200341b0046a41086a290300370300200320032903b0043703900520034198066a200341f0046a108d0120034180036a200328029806220220032802a006108e010240024020032d0080034101460d00200341003a00d0050c010b200341d0056a20034180036a41c10010ce041a0b0240200328029c06450d00200210290b20034190056a41206a2105200341f1056a2118200341d0056a410172211941042109410a2107034002400240200741766a2213410a4b22160d0020034190056a21060240024020130e0b0102020202020202020200010b200521060b0240412010272208450d0020082006290000370000200841186a200641186a290000370000200841106a200641106a290000370000200841086a200641086a29000037000041202102410021150c020b41204101102a000b4101211541b8d6c500210641002102410121080b200320023602c406200320023602c006200320083602bc06200320073602b806200341c8066a200341b8066a108f0120032802d006210a20032802c806211120034100360280032011200a20034180036a1005211002400240200328028003220a417f460d0020034190046a200a4120200a4120491b220f6a410041004120200f6b200f411f4b1b10cd041a20034190046a2010200f10ce041a200a411f4d0d1220034180036a41186a220a20034190046a41186a29030037030020034180036a41106a220f20034190046a41106a29030037030020034180036a41086a221420034190046a41086a2903003703002003200329039004370380032010102920034198066a41186a2210200a29030037030020034198066a41106a2217200f29030037030020034198066a41086a220b2014290300370300200320032903800337039806024020032802cc06450d00201110290b02402002450d00200810290b200a2010290300370300200f20172903003703002014200b29030037030020032003290398063703800320034180036a200341f0046a412010d004450d0141b0e2c10021094118210a0c290b024020032802cc06450d00201110290b2002450d00200810290b0240024020032d00d0054101470d004100210841b8d6c500210a024020160d000240024020130e0b0002020202020202020201000b412021082019210a0c010b412021082018210a0b024020022008470d002006200a460d022006200a200210d004450d020b0240024020080d00410121110c010b200810272211450d142011200a200810ce041a0b2003200836028c0320032008360288032003201136028403200320073602800320034198066a20034180036a108f01200328029806220a20032802a006100c0240200328029c06450d00200a10290b2008450d00201110290b4101210a024020150d0020021027220a450d14200a2006200210ce041a0b2003200236028c0320032002360288032003200a36028403200320073602800320034198066a20034180036a108f0120032802a00621072003280298062106412010272208450d14200820032903f004370000200841186a200341f0046a41186a290300370000200841106a200341f0046a41106a290300370000200841086a200341f0046a41086a29030037000020062007200841201003200810290240200328029c06450d00200610290b2002450d00200a10290b024020094108460d00200941d0e3c1006a2802002107200941046a21090c010b0b20034180036a200341f0046a108d0120032802880321062003280280032108412010272202450d132002200329039005370000200241186a20034190056a41186a290300370000200241106a20034190056a41106a290300370000200241086a20034190056a41086a2903003700002002412041c00010282202450d14200220032903b005370020200241386a20034190056a41386a290300370000200241306a20034190056a41306a290300370000200241286a20034190056a41286a29030037000020082006200241c0001003200210290240200328028403450d00200810290b200341013a00800320034190056a41086a22024200370300200342003703900541a7c8c500410f20034190056a100420034190046a41086a200229030037030020032003290390053703900420034190046a411020034180036a41011003410021090240200c450d00200d10290b0c270b20034180036a41306a200141386a29030037030020034180036a41286a200141306a29030037030020034180036a41206a200141286a29030037030020034180036a41186a200141206a29030037030020034180036a41106a200141186a29030037030020034180036a41086a200141106a2903003703002003200141086a29030037038003200341d8066a41206a200241206a290200370300200341d8066a41186a200241186a290200370300200341d8066a41106a200241106a290200370300200341d8066a41086a200241086a290200370300200320022902003703d80620034198026a20034180036a200341d8066a10b202200328029c02210a200328029802210941002113410121084101210b4101210f410121100c3d0b200341d8066a41206a200141246a290200370300200341d8066a41186a2001411c6a290200370300200341d8066a41106a200141146a290200370300200341d8066a41086a2001410c6a290200370300200320012902043703d80620034180036a41206a200241206a29020037030020034180036a41186a200241186a29020037030020034180036a41106a200241106a29020037030020034180036a41086a200241086a2902003703002003200229020037038003200341a0026a200341d8066a20034180036a10b30220032802a402210a20032802a002210941002114410121084101210b4101210f41012110410121130c3d0b200341d8066a41206a200141246a290200370300200341d8066a41186a2001411c6a290200370300200341d8066a41106a200141146a290200370300200341d8066a41086a2001410c6a290200370300200320012902043703d80620034180036a41206a200241206a29020037030020034180036a41186a200241186a29020037030020034180036a41106a200241106a29020037030020034180036a41086a200241086a2902003703002003200229020037038003200341a8026a200341d8066a20034180036a10b40220032802ac02210a20032802a802210941002115410121084101210b4101210f4101211041012113410121140c3d0b20034180036a41386a200141c0006a29030037030020034180036a41306a200141386a29030037030020034180036a41286a200141306a29030037030020034180036a41206a200141286a29030037030020034180036a41186a200141206a29030037030020034180036a41106a200141186a29030037030020034180036a41086a200141106a2903003703002003200141086a29030037038003200341d8066a41206a200241206a290200370300200341d8066a41186a200241186a290200370300200341d8066a41106a200241106a290200370300200341d8066a41086a200241086a290200370300200320022902003703d806200341b0026a20034180036a200341d8066a10c90120032802b402210a20032802b002210941002116410121084101210b4101210f410121104101211341012114410121150c3d0b418988c30021094124210a4101210820022d00000d2020022d000141ff01714102470d20200141086a290300210420034190056a41086a22024200370300200342003703900541a18ac000411020034190056a100420034190046a41086a200229030037030020032003290390053703900420034190046a411041b8d6c50041004100100b417f470d10200341b8026a41888dc300410d10940120032903c002420020032802b8021b2004540d0120034190056a41086a22024200370300200342003703900541a18ac000411020034190056a100420034190046a41086a2002290300370300200320032903900537039004200320043703800320034190046a411020034180036a410810030b410021094101210b0c350b41f08bc0001058000b200141086a2802002106200128020421070240024020022d00000d004101210820022d000141ff01714101460d010b41d588c3002109412a210a41002117410121082006450d1d200710290c1d0b200241096a280000210a2006450d1b200710290c1b0b20034180036a41306a200141386a29030037030020034180036a41286a200141306a29030037030020034180036a41206a200141286a29030037030020034180036a41186a200141206a29030037030020034180036a41106a200141186a29030037030020034180036a41086a200141106a2903003703002003200141086a29030037038003200341d8066a41206a200241206a290200370300200341d8066a41186a200241186a290200370300200341d8066a41106a200241106a290200370300200341d8066a41086a200241086a290200370300200320022902003703d806200341c8026a20034180036a200341d8066a10f50120032802cc02210a20032802c8022109410121084101210b0c320b20034180036a200141086a41800110ce041a200341d8066a41206a200241206a290200370300200341d8066a41186a200241186a290200370300200341d8066a41106a200241106a290200370300200341d8066a41086a200241086a290200370300200320022902003703d806200341d0026a20034180036a200341d8066a10b50220032802d402210a20032802d002210941002106410121084101210b4101210f4101211041012113410121144101211541012116410121170c390b200141086a280200210820012802042106200341f0046a41086a22092001411c6a290200370300200341f0046a410d6a220a200141216a2900003700002003200141146a2902003703f0042002411a6a2901002104200241196a2d00002111200241186a2d0000210f200241166a2f01002110200241156a2d00002113200241146a2d00002114200241126a2f01002115200241116a2d00002116200241106a2d000021172002410e6a2f0100210b2002410d6a2d000021052002410c6a2d0000210c2002410a6a2f0100210d200241096a2d00002118200241086a2d00002119200241066a2f0100211a200241056a2d0000211b200241046a2d0000211c200241026a2f0100211d20022d0001210720022d0000210202400240024020060e03000201000b20034180036a41146a41013602002003420137028403200341ccfdc40036028003200341023602dc06200341c4fdc4003602d8062003200341d8066a3602900320034180036a4194e6c1001057000b200141106a28020021202001410c6a280200211f20034198066a410d6a200a29000037000020034198066a41086a2009290300370300200320032903f0043703980641012106412a210a4100211e41d588c300210902400240200241ff0171450d00410021020c010b41002102200741ff01714101470d00201a410874201b72201941187472210941002106200c211e200d21022018210a0b200241ffff0371410874201e41187472200a41ff017172210a20060d16200320043703e805200320113a00e7052003200f3a00e605200320103b01e405200320133a00e305200320143a00e205200320153b01e005200320163a00df05200320173a00de052003200b3b01dc05200320053a00db052003200a3600d705200320093600d3052003201c3a00d2052003201d3b01d00520034190056a41086a22024200370300200342003703900541a4e6c100410820034190056a1004200341d8066a41086a200229030037030020032003290390053703d8062003410036028003200341d8066a411020034180036a10052102024002402003280280032206417f460d002002450d0020034180036a2006412020064120491b22076a41004100412020076b2007411f4b1b10cd041a20034180036a2002200710ce041a2006411f4d0d0e20034190046a41186a220620034180036a41186a220729000037030020034190046a41106a220920034180036a41106a220a29000037030020034190046a41086a221120034180036a41086a220f2900003703002003200329008003370390042002102920072006290300370300200a2009290300370300200f20112903003703002003200329039004370380030c010b20034188036a420037030020034190036a420037030020034198036a420037030020034200370380030b0240200341d0056a20034180036a412010d004450d0041ace6c10021094131210a0c170b20034180036a410d6a220220034198066a410d6a29000037000020034180036a41086a220620034198066a41086a2903003703002003200329039806370380030240200841ff01714101460d0020034190056a410d6a200229000037000020034190056a41086a2006290300370300200320032903800337039005200841087621080c140b20034190046a201f41067610cc01200328029004210602400240200328029804201f413f7122024b0d00410021020c010b20034198056a200620024105746a220241136a2900003703002003419d056a200241186a2900003700002003200229000b3703900520022f0000200241026a2d0000411074722108200228000721202002280003211f410121020b0240200328029404450d00200610290b20020d1341012106411521204184efc200211f0c140b4101210641d588c30021094100210a412a211e02400240200241ff0171450d00410021020c010b41002102200741ff01714101470d00201a410874201b722019411874722109410021062018211e200d210a200c21020b200a41ffff0371410874201e41ff017172200241187472210a20060d112003201c3a00d2052003201d3b01d005200320043703e805200320113a00e7052003200f3a00e605200320103b01e405200320133a00e305200320143a00e205200320153b01e005200320163a00df05200320173a00de052003200b3b01dc05200320053a00db052003200a3600d705200320093600d30520034190056a41086a22024200370300200342003703900541a4e6c100410820034190056a1004200341d8066a41086a200229030037030020032003290390053703d8062003410036028003200341d8066a411020034180036a10052102024002402003280280032206417f460d002002450d0020034180036a2006412020064120491b22076a41004100412020076b2007411f4b1b10cd041a20034180036a2002200710ce041a2006411f4d0d0e20034190046a41186a220620034180036a41186a220729000037030020034190046a41106a220920034180036a41106a220a29000037030020034190046a41086a221120034180036a41086a220f2900003703002003200329008003370390042002102920072006290300370300200a2009290300370300200f20112903003703002003200329039004370380030c010b20034188036a420037030020034190036a420037030020034198036a420037030020034200370380030b0240200341d0056a20034180036a412010d004450d0041dde6c10021094122210a0c120b20034180036a200841880110ce041a41002109200341003b01d806200341d8026a20034180036a200341d8066a10ad020240024020032802d80222020d00410121020c010b200220032802dc021010410021020b200320023a0082032003410c3b01800341b8d6c500410020034180036a108801200810290c140b200141d4006a2802002110200141d0006a280200211320022d0001210820022d00002102200341d8066a200141086a41c80010ce041a02400240024020020d00200841ff01714102460d010b02402010450d00201310290b0240200341e4066a280200450d0020032802e00610290b200341ec066a28020021060240200341f4066a2802002202450d002002410c6c21082006210203400240200241046a280200450d00200228020010290b2002410c6a2102200841746a22080d000b0b418988c3002109200341f0066a280200450d01200610290c010b200341f0026a4193c8c500411410b50120034180036a20032802f402410020032802f0021b2214200341fc066a221510b201200328028003220820032802880341b8d6c50041004100100b21020240200328028403450d00200810290b02402002417f470d00200341e0026a41888dc300410d10940120034188036a20032903e802420020032802e0021b37030020034180036a41106a20032902fc0637030020034198036a20034184076a290200370300200341a0036a2003418c076a290200370300200341a8036a20034194076a2902003703002003410d3a00800341b8d6c500410020034180036a1088012003410036028803200342013703800320032802e00621072003200341d8066a41106a28020022023602d005200341d0056a20034180036a103002400240200328028403220620032802880322086b2002490d0020032802800321060c010b200820026a22092008490d122006410174220a20092009200a491b22094100480d120240024020060d002009102721060c010b20032802800320062009102821060b2006450d0f200320093602840320032006360280030b2003200820026a36028803200620086a2007200210ce041a200341ec066a28020021082003200341f4066a28020022023602d005200341d0056a20034180036a10300240024020020d002003280288032111200328028403210920032802800321070c010b20082002410c6c6a210f03402008280200210a2003200841086a28020022023602d005200341d0056a20034180036a103002400240200328028403220920032802880322066b2002490d0020032802800321070c010b200620026a22072006490d1420094101742211200720072011491b22114100480d140240024020090d002011102721070c010b20032802800320092011102821070b2007450d1220032011360284032003200736028003201121090b2003200620026a221136028803200720066a200a200210ce041a2008410c6a2208200f470d000b0b200341d0056a2014201510b20120032802d805210f20032802d005210a20034100360288032003420137038003200320113602900520034190056a20034180036a103002400240200328028403220620032802880322086b2011490d0020032802800321020c010b200820116a22022008490d1220064101742214200220022014491b22144100480d120240024020060d002014102721020c010b20032802800320062014102821020b2002450d1120032014360284032003200236028003201421060b200220086a2007201110ce041a200a200f2002200820116a100302402006450d00200210290b024020032802d405450d00200a10290b2009450d00200710290b02402010450d00201310290b0240200341e4066a280200450d0020032802e00610290b200341ec066a28020021060240200341f4066a2802002202450d002002410c6c21082006210203400240200241046a280200450d00200228020010290b2002410c6a2102200841746a22080d000b0b41002109200341f0066a280200450d00200610290b4124210a41002111410121084101210b4101210f41012110410121134101211441012115410121164101211741012106410121070c380b41084101102a000b41a0ebc2001058000b4189e2c10021094127210a0c170b418f89c3004133104e000b20084101102a000b20024101102a000b41204101102a000b41204101102a000b41c0004101102a000b41dc8ac0001058000b418f89c3004133104e000b418f89c3004133104e000b20094101102a000b20114101102a000b20144101102a000b102b000b2008103d200810290c030b20034180036a410d6a20034190056a410d6a29000037000020034180036a41086a20034190056a41086a290300370300200320032903900537038003410021060b200341d8066a41086a220220034180036a41086a290300370300200341d8066a41106a20034180036a41106a29030037030020032003290380033703d80602402006450d002020210a201f21090c020b200341b0046a410d6a200341d8066a410d6a290000370000200341b0046a41086a2002290300370300200320032903d8063703b00420034190056a41086a22064200370300200342003703900541a4e6c100410820034190056a10042002200629030037030020032003290390053703d8062003410036028003200341d8066a411020034180036a10052102024002402003280280032206417f460d002002450d0020034180036a2006412020064120491b22076a41004100412020076b2007411f4b1b10cd041a20034180036a2002200710ce041a2006411f4d0d0420034190046a41186a220620034180036a41186a220729000037030020034190046a41106a220920034180036a41106a220a29000037030020034190046a41086a221120034180036a41086a220f2900003703002003200329008003370390042002102920072006290300370300200a2009290300370300200f20112903003703002003200329039004370380030c010b20034188036a420037030020034190036a420037030020034198036a420037030020034200370380030b200341d8066a41186a20034180036a41186a2903002204370300200341d8066a41106a20034180036a41106a290300220e370300200341d8066a41086a220220034180036a41086a22062903002212370300200320032903800322213703d8062003418a036a201237010020034192036a200e3701002003419a036a20043701002003418c023b01800320032021370182034100210941b8d6c500410020034180036a10880120034180036a410d6a2207200341b0046a410d6a2900003700002006200341b0046a41086a290300370300200320032903b0043703800320034190056a41086a220a4200370300200342003703900541a4e6c100410820034190056a10042002200a29030037030020032003290390053703d806412010272202450d03200220083b0000200220203600072002201f360003200220032903800337000b200241026a20084110763a0000200241136a2006290300370000200241186a2007290000370000200341d8066a4110200241201003200210290b0b41002107410121084101210b4101210f41012110410121134101211441012115410121164101211741012106410121110c230b418f89c3004133104e000b41204101102a000b410021174101210b4101210f4101211041012113410121144101211541012116410121064101210741012111410021090c200b4101210b4101210f41012110410121134101211441012115410121160c1d0b4101210b0c150b200c450d00200d10290b41002110410121084101210b4101210f0c150b200341d0056a41026a200341c8066a41026a2d00003a000020034180036a41086a200341b0046a41086a29030037030020034180036a410d6a200341b0046a410d6a290000370000200320032f01c8063b01d005200320032903b00437038003410021020b2003418c046a41026a2206200341d0056a41026a2d00003a000020034190056a41086a220720034180036a41086a29030037030020034190056a41106a20034180036a41106a290300370300200320032f01d0053b018c0420032003290380033703900520020d0220034193036a200729030037000020034198036a2003419d056a290000370000200320032f018c043b0180032003200f360087032003200836008303200320032903900537008b03200320062d00003a00820302400240024002400240411410272202450d00200241106a41002800bb8c40360000200241086a41002900b38c40370000200241002900ab8c4037000020024114413410282202450d0120022003290380033700142002412c6a20034198036a290300370000200241246a20034180036a41106a2903003700002002411c6a20034180036a41086a290300370000200341f8016a20024134108401200341f8016a41106a2903002122200329038002212320032802f8012108200210292023420020081b222320045422062022420020081b2222200e542022200e5122021b0d0220232004562022200e5620021b450d04200341e0016a41b18ac0004116108601200341f0016a290300212420032903e801212520032802e001210220034190056a41086a22084200370300200342003703900541b18ac000411620034190056a100420034190046a41086a2008290300370300200320032903900537039004200342002024420020021b22242006ad200e20227d7c7c2025420020021b2222202320047d222554ad7d2223202220257d2225202256202320245620232024511b22021b3703d80520034200202520021b3703d005200341d0056a21020c030b41144101102a000b41344101102a000b200341c8016a41b18ac0004116108601200341d8016a290300212420032903d001212520032802c801210220034190056a41086a22084200370300200342003703900541b18ac000411620034190056a100420034190046a41086a20082903003703002003200329039005370390042003427f2024420020021b2224200e20227d2004202354ad7d7c2025420020021b2222200420237d7c22232022542202ad7c22222002202220245420222024511b22021b3703d8052003427f202320021b3703d005200341d0056a21020b20034190046a41102002411010030b20034180036a2004200e10890102400240024002400240411810272202450d00200241106a41002900cf8c40370000200241086a41002900c78c40370000200241002900bf8c4037000020024118413810282202450d012002200329038003370018200241306a20034198036a290300370000200241286a20034180036a41106a290300370000200241206a20034180036a41086a290300370000200341b0016a20024138108401200341b0016a41106a290300210420032903b801210e20032802b001210820021029200e420020081b220e20215422062004420020081b2204201254200420125122021b0d02200e202156200420125620021b450d0420034198016a41b18ac0004116108601200341a8016a290300212220032903a0012123200328029801210220034190056a41086a22084200370300200342003703900541b18ac000411620034190056a100420034190046a41086a2008290300370300200320032903900537039004200342002022420020021b22222006ad201220047d7c7c2023420020021b2204200e20217d222354ad7d220e200420237d2223200456200e202256200e2022511b22021b3703d80520034200202320021b3703d005200341d0056a21020c030b41184101102a000b41384101102a000b20034180016a41b18ac000411610860120034190016a29030021222003290388012123200328028001210220034190056a41086a22084200370300200342003703900541b18ac000411620034190056a100420034190046a41086a20082903003703002003200329039005370390042003427f2022420020021b2222201220047d2021200e54ad7d7c2023420020021b22042021200e7d7c220e2004542202ad7c22042002200420225420042022511b22021b3703d8052003427f200e20021b3703d005200341d0056a21020b20034190046a41102002411010030b20034180036a20212012109c010c040b20034190046a41026a200341c8066a41026a2d00003a000020034180036a41086a200341b0046a41086a29030037030020034180036a410d6a200341b0046a410d6a290000370000200320032f01c8063b019004200320032903b00437038003410021020b2003418c046a41026a220620034190046a41026a2d00003a000020034190056a41086a220720034180036a41086a29030037030020034190056a41106a20034180036a41106a290300370300200320032f0190043b018c042003200329038003370390052002450d010b200f210a20082109410121084101210b0c0e0b200341eb066a2007290300370000200341f0066a2003419d056a290000370000200320032f018c043b01d8062003200f3600df06200320083600db0620032003290390053700e306200320062d00003a00da06411410272202450d02200241106a41002800bb8c40360000200241086a41002900b38c40370000200241002900ab8c4037000020024114413410282202450d03200220032903d0053700142002412c6a200341e8056a290300370000200241246a200341d0056a41106a2903003700002002411c6a200341d0056a41086a290300370000200341e8006a20024134108401200341e8006a41106a2903002121200329037021222003280268210820021029411410272202450d04200241106a41002800bb8c40360000200241086a41002900b38c40370000200241002900ab8c4037000020024114413410282202450d05200220032903d8063700142002412c6a200341f0066a290300370000200241246a200341d8066a41106a2903003700002002411c6a200341d8066a41086a290300370000200341d0006a20024134108401200341d0006a41106a2903002124200329035821252003280250210620021029024020044280a094a58d1d7c22122004542202200e2002ad7c2223200e54201220045a1b450d004128210a41d0bec0002109410121084101210b0c0e0b02402022420020081b222220127d22262022562021420020081b222120237d2022201254ad7d221220215620122021511b450d00411d210a41e8b5c3002109410121084101210b0c0e0b2024420020061b21212025420020061b21220240200442ffffe883b1de1656200e420052200e501b0d00202220218450450d00411f210a4185b6c3002109410121084101210b0c0e0b200341c8006a200341d0056a4102202620121091010240200328024822090d000240202220047c222320225422022021200e7c2002ad7c222220215420222021511b450d00412d210a41a4b6c3002109410121084101210b0c0f0b200341d0056a200341d8066a412010d004450d01200341d0056a20262012108901411410272202450d07200241106a41002800bb8c40360000200241086a41002900b38c40370000200241002900ab8c4037000020024114413410282202450d08200220032903d8063700142002412c6a200341d8066a41186a2208290300370000200241246a200341d8066a41106a2903003700002002411c6a200341d8066a41086a29030037000020034180036a41186a2206420037030020034180036a41106a2207420037030020034180036a41086a2209420037030020034200370380032002413420034180036a100020034190046a41186a200629030037030020034190046a41106a200729030037030020034190046a41086a200929030037030020032003290380033703900420034190046a412041b8d6c50041004100100b21062002102902402006417f470d00200341d8066a108701200341b8036a2022370300200341b0036a202337030020034180036a41086a41003a000020034189036a20032903d80637000020034191036a200341d8066a41086a29030037000020034199036a200341e8066a290300370000200341a1036a2008290300370000200341023a00800341b8d6c500410020034180036a1088010b200341d8066a20232022108901200341306a41b18ac0004116108601200341306a41106a2903002112200329033821212003280230210220034190056a41086a22064200370300200342003703900541b18ac000411620034190056a100420034190046a41086a2006290300370300200320032903900537039004200342002012420020021b22222021420020021b22124280a094a58d1d54ad7d222120124280e0ebdaf2627c22232012562021202256201242ff9f94a58d1d561b22021b3703880320034200202320021b3703800320034190046a411020034180036a41101003200341e8036a4200370300200341e0036a4280a094a58d1d370300200341d8036a200e370300200341d0036a200437030020034180036a41086a41023a000020034189036a20032903d00537000020034191036a200341d0056a41086a29030037000020034199036a200341d0056a41106a290300370000200341a1036a200341d0056a41186a290300370000200341a9036a20032903d806370000200341b1036a200341d8066a41086a290300370000200341b9036a200341d8066a41106a290300370000200341c1036a2008290300370000200341023a00800341b8d6c500410020034180036a1088010c010b200328024c210a410121084101210b0c0d0b410021090b410121084101210b0c0b0b41144101102a000b41344101102a000b41144101102a000b41344101102a000b41144101102a000b41344101102a000b4100210c410021090c010b4100210d410021090b4128210a4101210b4100210802402007417f6a220241054b0d004101210f410121104101211341012114410121154101211641012117410121064101210741012111024002400240024020020e06100010010203100b4100210841000d062004a70d050c060b4100210841000d052004a70d040c050b200d450d0402402004422088a72202450d00200241186c21062005210203400240200241046a280200450d00200228020010290b0240200241106a280200450d002002410c6a28020010290b200241186a2102200641686a22060d000b0b2004a70d030c040b200c450d0302402004422088a72202450d002002410c6c21062005210203400240200241046a280200450d00200228020010290b2002410c6a2102200641746a22060d000b0b2004a70d020c030b02402004422088a72202450d002002410c6c21062005210203400240200241046a280200450d00200228020010290b2002410c6a2102200641746a22060d000b0b2004a70d010c020b410021084101210f410121104101211341012114410121154101211641012117410121064101210741012111410021090c0a0b200510290b4101210f0b410121100b410121130b410121140b410121150b410121160b410121170b410121060b41012107410121110b024002402001280200220241104b0d000240024002400240024002400240024002400240024020020e11000c0c010c0c0203040506070c080c090a000b2008450d0b0240200141086a280200220241054b0d0002400240024020020e060f0f000f01020f0b200141106a280200450d0e2001410c6a28020010290c0e0b200141106a280200450d0d2001410c6a28020010290c0d0b0240200141146a2802002208450d002001410c6a2802002102200841186c210803400240200241046a280200450d00200228020010290b0240200241106a280200450d002002410c6a28020010290b200241186a2102200841686a22080d000b0b200141106a280200450d0c200128020c10290c0c0b0240200141146a2802002208450d002001410c6a28020021022008410c6c210803400240200241046a280200450d00200228020010290b2002410c6a2102200841746a22080d000b0b200141106a280200450d0b200128020c10290c0b0b200b450d0a02402001410c6a2802002202450d0020012802042207200241f8006c6a211103400240200741106a2802002208450d0020072802082102200841246c210803400240024020022d0000220641034b0d0002400240024020060e0404000102040b2002410c6a280200450d03200241086a28020010290c030b2002410c6a280200450d02200241086a28020010290c020b2002410c6a280200450d01200241086a28020010290c010b200241086a280200450d00200241046a28020010290b200241246a21022008415c6a22080d000b0b200741f8006a210202402007410c6a280200450d00200728020810290b2002210720022011470d000b0b200141086a280200450d0a200128020410290c0a0b200f450d090240200141086a2d00002202410c4b0d0020024106470d0a200141106a280200450d0a2001410c6a28020010290c0a0b200141106a280200450d092001410c6a28020010290c090b2010450d08200141086a280200450d08200128020410290c080b2013450d07200141086a2d0000417f6a220241074b0d07024002400240024020020e08000b0b0b010b0203000b2001410c6a2202280200103d200228020010290c0a0b2001410c6a2202280200103d200228020010290c090b2001410c6a2202280200103d200228020010290c080b2001410c6a2202280200103d200228020010290c070b2014450d0620012d0004417f6a220241024b0d0602400240024020020e03000102000b2001410c6a280200450d08200141086a28020010290c080b200141086a2202280200103d200228020010290c070b2001410c6a2202280200103d200228020010290c060b2015450d0520012d0004417f6a220241024b0d0502400240024020020e03000102000b2001410c6a280200450d07200141086a28020010290c070b200141086a2202280200103d200228020010290c060b2001410c6a2202280200103d200228020010290c050b2016450d04200141086a280200417f6a220241014b0d040240024020020e020001000b200141106a280200450d052001410c6a28020010290c050b200141106a280200450d042001410c6a28020010290c040b2017450d03200141086a280200450d03200128020410290c030b2006450d020240200141086a2d0000220241054b0d0002400240024020020e06060600010206060b200141106a280200450d052001410c6a28020010290c050b200141346a280200450d04200141306a28020010290c040b200141306a280200450d032001412c6a28020010290c030b200141d0006a280200450d02200141cc006a28020010290c020b2007450d0120012802044101470d01200141086a2202280200103d200228020010290c010b2011450d000240200141146a280200450d00200141106a28020010290b0240200141246a2802002208450d002001411c6a28020021022008410c6c210803400240200241046a280200450d00200228020010290b2002410c6a2102200841746a22080d000b0b0240200141206a280200450d00200128021c10290b200141d4006a280200450d00200141d0006a28020010290b2000200a36020420002009360200200341a0076a24000b4d01017f230041206b22002400200041146a410136020020004201370204200041ccfdc4003602002000410236021c200041c4fdc4003602182000200041186a360210200041908fc3001057000be42107067f017e017f017e017f027e137f230041e0026b22042400200128020821052001280204210620012802002107418988c30021084124210902400240200241ff01710d00200341ff01714102470d0020044188016a41086a22014200370300200442003703880141fcc7c500411720044188016a1004200441186a41086a200129030037030020042004290388013703182004410036028801200441186a411020044188016a10052101024002400240024002400240024002402004280288012202417f460d002001450d00200441003a00880120044188016a20012002410047220310ce041a20022003490d042002450d0120042d00880121022001102920024102460d002002410171450d0041f086c3002108411c21090c080b200441013a00c00220044188016a41086a22014200370300200442003703880141fcc7c500411720044188016a1004200441186a41086a220220012903003703002004200429038801370318200441186a4110200441c0026a41011003200441086a41888dc300410d1094012004290310210a20042802082103200142003703002004420037038801418bf4c200411120044188016a10042002200129030037030020042004290388013703182004410036028801200441186a411020044188016a10052101024002402004280288012202417f460d002001450d00200420023602c402200420013602c00220044188016a200441c0026a1046200428028801220b450d04200429028c01210c2002450d01200110290c010b4108210b4200210c0b02400240200ca7200c422088a72201470d00200141016a22022001490d012001410174220d20022002200d491bad220e42c8007e220f422088a70d01200fa722024100480d010240024020010d0020021027210b0c010b200b200141c8006c20021028210b0b200b450d03200c42808080807083200e84210c0b200b200141c8006c6a220141003a00002001200a420020031b220e37030820012004280018360001200141046a200441186a41036a2800003600002001200429038801370310200141186a20044188016a41086a290300370300200141206a20044188016a41106a290300370300200141286a20044188016a41186a290300370300200141306a20044188016a41206a290300370300200141386a20044188016a41286a290300370300200141c0006a20044188016a41306a290300370300200c4280808080107c210a2007200541f8006c6a2110024020050d00200721110c070b200441ff016a2112200441b7016a2113200441ef006a2114200441276a2115200441dc016a211620044188016a41346a21172004419c016a211820044188016a410c6a2119200441b6026a211a200441a2026a41046a211b2007211103402011280208211c2011290300210c20044188016a2011410c6a41ec0010ce041a201141f8006a2111201c450d07200441186a20044188016a41ec0010ce041a2004201c360290012004200c370388012019200441186a41ec0010ce041a200441003602b002200442013703a80202400240024002400240412010272201450d00200442a080808080043702ac02200420013602a80220012018290000370000200141086a201841086a290000370000200141106a201841106a290000370000200141186a201841186a29000037000020044188016a200441a8026a10540240024020042802ac02220220042802b00222036b4120490d00200341206a210120042802a80221050c010b200341206a22012003490d0720024101742205200120012005491b220d4100480d070240024020020d00200d102721050c010b20042802a8022002200d102821050b2005450d022004200d3602ac02200420053602a802200d21020b200420013602b002200520036a22032017290000370000200341086a201741086a290000370000200341106a201741106a290000370000200341186a201741186a2900003700000240200220016b411f4b0d00200141206a22032001490d072002410174220d20032003200d491b22034100480d070240024020020d002003102721050c010b200520022003102821050b2005450d03200420033602ac02200420053602a8020b200520016a220541086a201641086a290000370000200541106a201641106a290000370000200541186a201641186a2900003700002004200141206a3602b002200520162900003700002004200428029801221d3602c002200441c0026a200441a8026a103002400240201d0d0020042802b002210520042802ac02210820042802a80221020c010b201d41246c210920042802ac02210820042802b0022101201c21030340200441c0026a2003104f20042802c002211e02400240200820016b20042802c802220d490d002001200d6a210520042802a80221020c010b2001200d6a22052001490d0920084101742202200520052002491b221f4100480d090240024020080d00201f102721020c010b20042802a8022008201f102821020b2002450d062004201f3602ac02200420023602a802201f21080b200420053602b002200220016a201e200d10ce041a024020042802c402450d00201e10290b200341246a2103200521012009415c6a22090d000b0b200441c0026a41186a22034200370300200441c0026a41106a220d4200370300200441c0026a41086a221e4200370300200442003703c00220022005200441c0026a100020044180026a41186a2220200329030037030020044180026a41106a2221200d29030037030020044180026a41086a2222201e290300370300200420042903c0023703800202402008450d00200210290b200c50450d04418c87c3002108411021090c0b0b41204101102a000b200d4101102a000b20034101102a000b201f4101102a000b0240200c200e580d00419c87c3002108411821090c070b200441c0026a200c427f7c1087020240200441c0026a2018412010d004450d0041b487c3002108411921090c070b0240200c200e5a0d0041cd87c3002108412621090c070b200b200a422088a7220241c8006c221f6a2105200b2101024002400240024002400240201f41d901490d00200b21010340024020012d00004101470d0020122001460d07200141016a20044180026a412010d004450d070b0240200141c8006a22082d00004101470d0020132001460d03200141c9006a20044180026a412010d004450d030b024020014190016a22082d00004101470d0020142001460d0420014191016a20044180026a412010d004450d040b0240200141d8016a22082d00004101470d0020152001460d06200141d9016a20044180026a412010d004450d060b2005200141a0026a22016b41d8014b0d000b0b20052001470d02410021010c040b200821010c030b200821010c020b0340024020012d00004101470d0020122001460d03200141016a20044180026a412010d004450d030b2005200141c8006a2201470d000b410021010c010b200821010b200441c0026a200c108702200441c0026a20044180026a412010d004210541f387c30021084116210920010d062005450d06200441c0026a109801200441c0026a410210960320034200370300200d4200370300201e4200370300200442003703c002200441c0026a4101109603201e2022290300370300200d20212903003703002003202029030037030020042004290380023703c00202400240200aa72002470d00200241016a22012002490d0320024101742205200120012005491bad220c42c8007e220f422088a70d03200fa722014100480d030240024020020d0020011027210b0c010b200b201f20011028210b0b200b450d01200a42808080807083200c84210a0b200b201f6a220141013a0000200141096a201e290300370000200120042903c0023700012003290300210c200d290300210f200141003a0021200141116a200f370000200141196a200c370000200120042900a80237002c200141346a200441a8026a41086a2900003700002001413a6a201a290000370000200120042801a202360142200141c6006a201b2f01003b01000240201d450d00201d41246c2105201c210103400240024020012d0000220241034b0d0002400240024020020e0404000102040b2001410c6a280200450d03200141086a28020010290c030b2001410c6a280200450d02200141086a28020010290c020b2001410c6a280200450d01200141086a28020010290c010b200141086a280200450d00200141046a28020010290b200141246a21012005415c6a22050d000b0b0240200428029401450d00201c10290b200a4280808080107c210a20112010470d010c090b0b20014108102a000b102b000b418f89c3004133104e000b20024108102a000b418f89c3004133104e000b20032002103e000b0240201d450d00201d41246c2105201c210103400240024020012d0000220241034b0d0002400240024020020e0404000102040b2001410c6a280200450d03200141086a28020010290c030b2001410c6a280200450d02200141086a28020010290c020b2001410c6a280200450d01200141086a28020010290c010b200141086a280200450d00200141046a28020010290b200141246a21012005415c6a22050d000b0b0240200428029401450d00201c10290b024020112010460d00034020112802082203450d012011410c6a280200210d0240201141106a2802002201450d00200141246c21052003210103400240024020012d0000220241034b0d0002400240024020020e0404000102040b2001410c6a280200450d03200141086a28020010290c030b2001410c6a280200450d02200141086a28020010290c020b2001410c6a280200450d01200141086a28020010290c010b200141086a280200450d00200141046a28020010290b200141246a21012005415c6a22050d000b0b201141f8006a21110240200d450d00200310290b20112010470d000b0b02402006450d00200710290b200aa7450d03200b10290c030b20112010460d00034020112802082203450d012011410c6a280200210d0240201141106a2802002201450d00200141246c21052003210103400240024020012d0000220241034b0d0002400240024020020e0404000102040b2001410c6a280200450d03200141086a28020010290c030b2001410c6a280200450d02200141086a28020010290c020b2001410c6a280200450d01200141086a28020010290c010b200141086a280200450d00200141046a28020010290b200141246a21012005415c6a22050d000b0b201141f8006a21110240200d450d00200310290b20112010470d000b0b02402006450d00200710290b20044188016a41086a220142003703002004420037038801418bf4c200411120044188016a1004200441186a41086a200129030037030020042004290388013703184100210820044100360290012004420137038801200b200a422088a720044188016a109203200428028c012101200441186a41102004280288012205200428029001100302402001450d00200510290b0240200aa7450d00200b10290b0c010b02402005450d002007200541f8006c6a210d2007210303400240200341106a2802002205450d0020032802082101200541246c210503400240024020012d0000220241034b0d0002400240024020020e0404000102040b2001410c6a280200450d03200141086a28020010290c030b2001410c6a280200450d02200141086a28020010290c020b2001410c6a280200450d01200141086a28020010290c010b200141086a280200450d00200141046a28020010290b200141246a21012005415c6a22050d000b0b200341f8006a210102402003410c6a280200450d00200328020810290b200121032001200d470d000b0b2006450d00200710290b2000200936020420002008360200200441e0026a24000b4d01017f230041206b22002400200041146a410136020020004201370204200041ccfdc4003602002000410236021c200041c4fdc4003602182000200041186a360210200041f4eec2001057000b83d50106017f037e0c7f017e157f057e23004190056b220324000240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024020012d00000e0e000102030405060708090a0b0c0d000b2003419c046a41013602002003420137028c04200341ccfdc40036028804200341023602fc01200341c4fdc4003602f8012003200341f8016a3602980420034188046a41d4fdc4001057000b200141306a2903002104200141286a29030021052002411a6a2901002106200241196a2d00002107200241186a2d00002108200241166a2f01002109200241156a2d0000210a200241146a2d0000210b200241126a2f0100210c200241116a2d0000210d200241106a2d0000210e2002410e6a2f0100210f2002410d6a2d00002110200241046a2d00002111200241026a2f010021122001411d6a29000021132001411c6a2d000021142001411b6a2d00002115200141196a2f00002116200141186a2d00002117200141176a2d00002118200141156a2f00002119200141146a2d0000211a200141136a2d0000211b200141116a2f0000211c200141106a2d0000211d2001410c6a280200211e200141086a280200211f200141076a2d00002120200141056a2f00002121200141046a2d0000212220012d00012123412a212441d588c30021250240024020022d0000450d004101212641002127410021280c010b41012126410021274100212820022d00014101470d002002410c6a2d000021272002410a6a2f01002128200241096a2d00002124200241066a2f0100410874200241056a2d000072200241086a2d0000411874722125410021260b202841ffff0371410874202741187472202441ff017172212420260d4f410e10272202450d3f200241066a41002900c7a244370000200241002900c1a2443700002002410e412e10282202450d3e20022006370026200220073a0025200220083a0024200220093b00222002200a3a00212002200b3a00202002200c3b001e2002200d3a001d2002200e3a001c2002200f3b001a200220103a00192002202436001520022025360011200220113a0010200220123b000e200341f0046a41186a22264200370300200341f0046a41106a22274200370300200341f0046a41086a22284200370300200342003703f0042002412e200341f0046a1000200341e8036a41186a2026290300370300200341e8036a41106a2027290300370300200341e8036a41086a2028290300370300200320032903f0043703e803200341e8036a412041b8d6c50041004100100b21262002102902402026417f460d0041aefec4002125411421240c500b0240202241ff01714101470d0020034188046a201f41067610cc01200328028804212602400240200328029004201f413f7122024b0d00410021020c010b202620024105746a2202290018211320022d0017211420022d0016211520022f0014211620022d0013211720022d0012211820022f0010211920022d000f211a20022d000e211b20022f000c211c20022d000b211d2002280007211e2002280003211f20022d0002212020022f00002121410121020b0240200328028c04450d00202610290b2002450d4f0b2003201337039002200320143a008f02200320153a008e02200320163b018c02200320173a008b02200320183a008a02200320193b0188022003201a3a0087022003201b3a0086022003201c3b0184022003201d3a0083022003201e3600ff012003201f3600fb01200320203a00fa01200320213b01f801410e10272202450d3d200241066a410029009fa34437000020024100290099a3443700002002410e412e10282202450d3c200220032903f80137000e200241266a200341f8016a41186a2903003700002002411e6a200341f8016a41106a290300370000200241166a200341f8016a41086a290300370000200341f0046a41186a22264200370300200341f0046a41106a22274200370300200341f0046a41086a22284200370300200342003703f0042002412e200341f0046a1000200341e8036a41186a2026290300370300200341e8036a41106a2027290300370300200341e8036a41086a2028290300370300200320032903f0043703e803200341e8036a412041b8d6c50041004100100b2126200210292026417f470d4d02402005428080e983b1de165441002004501b450d0041fdfdc4002125413121240c500b20034188046a41186a200341f8016a41186a29030037030020034188046a41106a200341f8016a41106a29030037030020034188046a41086a200341f8016a41086a290300370300200320032903f80137038804410e10272202450d3b200241066a41002900c7a244370000200241002900c1a2443700002002410e412e10282202450d3a20022006370026200220073a0025200220083a0024200220093b00222002200a3a00212002200b3a00202002200c3b001e2002200d3a001d2002200e3a001c2002200f3b001a200220103a00192002202436001520022025360011200220113a0010200220123b000e200341f0046a41186a22264200370300200341f0046a41106a22274200370300200341f0046a41086a22284200370300200342003703f0042002412e200341f0046a1000200341e8036a41186a2026290300370300200341e8036a41106a2027290300370300200341e8036a41086a2028290300370300200320032903f0043703e803412010272226450d392026200329038804370000202641186a20034188046a41186a290300370000202641106a20034188046a41106a290300370000202641086a20034188046a41086a290300370000200341e8036a41202026412010032026102920021029410d10272202450d38200241056a41002900aca344370000200241002900a7a3443700002002410d412d10282202450d3720022006370025200220073a0024200220083a0023200220093b00212002200a3a00202002200b3a001f2002200c3b001d2002200d3a001c2002200e3a001b2002200f3b0019200220103a00182002202436001420022025360010200220113a000f200220123b000d200341f0046a41186a22264200370300200341f0046a41106a22274200370300200341f0046a41086a22284200370300200342003703f0042002412d200341f0046a1000200341e8036a41186a2026290300370300200341e8036a41106a2027290300370300200341e8036a41086a2028290300370300200320032903f0043703e803024002400240024002400240202341037122264103460d0020260e03010203010b200341e8036a41204101410010030c040b410021270c020b410121270c010b410221270b200320273a00f004410110272226450d37202620273a0000200341e8036a4120202641011003202610290b20021029411410272202450d35200241106a41002800bb8c40360000200241086a41002900b38c40370000200241002900ab8c4037000020024114413410282202450d342002200637002c200220073a002b200220083a002a200220093b00282002200a3a00272002200b3a00262002200c3b00242002200d3a00232002200e3a00222002200f3b0020200220103a001f2002202436001b20022025360017200220113a0016200220123b0014200320024134108401200341106a2903002113200329030821292003280200212620021029200341cc046a2006370200200341cb046a20073a0000200341ca046a20083a0000200341c8046a20093b0100200341c7046a200a3a0000200341c6046a200b3a0000200341c4046a200c3b0100200341c3046a200d3a0000200341c2046a200e3a0000200341c0046a200f3b0100200341bf046a20103a0000200341bb046a2024360000200341b7046a2025360000200341b6046a20113a0000200341b0046a4100360200200341a0046a2013420020261b220620042029420020261b2213200554200620045420062004511b22021b2206370300200320123b01b404200342083703a80420032013200520021b22133703980420032006370390042003201337038804200341f8016a20034188046a10d803200341ac046a280200450d4c20032802a80410290c4c0b20022d00000d4a20022d00014101470d4a200141106a2903002106200141086a2903002113200241196a2d00002125200241186a2d00002124200241166a2f01002126200241156a2d00002127200241146a2d00002128200241126a2f01002107200241116a2d00002108200241106a2d000021092002410e6a2f0100210a2002410d6a2d0000210b2002410c6a2d0000210c2002410a6a2f0100210d200241096a2d0000210e200241086a2d0000210f200241066a2f01002110200241056a2d00002111200241046a2d00002112200241026a2f0100211f20032002411a6a29010037038004200320253a00ff03200320243a00fe03200320263b01fc03200320273a00fb03200320283a00fa03200320073b01f803200320083a00f703200320093a00f6032003200a3b01f4032003200b3a00f303200320123a00ea032003201f3b01e8032003200e200d410874200c41187472723600ef0320032011201041087472200f411874723600eb0320034188046a200341e8036a108c02024020032d0088044101460d0041d2fec4002125410b21240c4f0b2003200329028c0437006b200320032d008b043a006a200320032f0089043b01682003200341a1046a2900003703800120032003419d046a28000036027c200320034195046a290000370274200320034188046a410c6a22022d00003a007320034188046a200341e8006a108d0220032802a8042224450d49200341f0046a41086a20034188046a41346a2902002204370300200341b0016a41086a22262004370300200341b0016a41106a222720034188046a413c6a290200370300200341b0016a41186a222820034188046a41c4006a2902003703002003200341b4046a29020022043703f004200320043703b001200341d4046a280200210720034188046a41286a2802002108200235020021042003280288042102200329028c042105200329039804212920032802ac042125200341f8016a41186a20034188046a41186a290300222a370300200341f8016a410c6a20043e0200200341f8016a41286a20083602002003419c026a20253602002003202937038802200320053702fc012003202436029802200320023602f801200341f8016a41c4006a2028290300370200200341f8016a413c6a2027290300370200200341f8016a41346a2026290300370200200320032903b0013702a402200320073602c402411410272202450d32200241106a41002800bb8c40360000200241086a41002900b38c40370000200241002900ab8c4037000020024114413410282202450d31200220032903e8033700142002412c6a200341e8036a41186a290300370000200241246a200341e8036a41106a2903003700002002411c6a200341e8036a41086a290300370000200341186a20024134108401200341186a41106a29030021052003290320210420032802182124200210292004420020241b220420032903f801222b7d222c2004562005420020241b2205200341f8016a41086a290300222d7d2004202b54ad7d220420055620042005511b450d470c480b200141106a2903002113200141086a29030021042002411a6a2901002106200241196a2d00002107200241186a2d00002108200241166a2f01002109200241156a2d0000210a200241146a2d0000210b200241126a2f0100210c200241116a2d0000210d200241106a2d0000210e2002410e6a2f0100210f2002410d6a2d00002110200241046a2d00002111200241026a2f01002112412a212441d588c30021250240024020022d0000450d004101212641002127410021280c010b41012126410021274100212820022d00014101470d002002410c6a2d000021272002410a6a2f01002128200241096a2d00002124200241066a2f0100410874200241056a2d000072200241086a2d0000411874722125410021260b202841ffff0371410874202741187472202441ff017172212420260d4d2003200637038001200320073a007f200320083a007e200320093b017c2003200a3a007b2003200b3a007a2003200c3b01782003200d3a00772003200e3a00762003200f3b0174200320103a00732003202436006f2003202536006b200320113a006a200320123b016820034188046a200341e8006a108d0220032802a8042226450d48200341f0046a41086a20034188046a41346a2902002206370300200341b0016a41086a22242006370300200341c0016a222720034188046a413c6a290200370300200341b0016a41186a222820034188046a41c4006a2902003703002003200341b4046a29020022063703f004200320063703b001200341d4046a280200210720034188046a41286a280200212520034188046a410c6a35020021292003280288042108200329028c04212b200329039804210620032802ac042102200341f8016a41186a20034188046a41186a2903002205370300200341f8016a410c6a20293e0200200341f8016a41286a20253602002003419c026a200236020020032006370388022003202b3702fc012003202636029802200320083602f801200341f8016a41c4006a2028290300370200200341f8016a413c6a2027290300370200200341f8016a41346a2024290300370200200320032903b0013702a402200320073602c40202400240024002402025411f4b0d00200620042006200454200520135420052013511b22241b22042005201320241b221384500d03200341f8016a41186a4200200520137d2006200454ad7d2229200620047d222b428080e983b1de165441002029501b22241b37030020034200202b20241b37038802200341306a4189c7c500411210b501200328023421272003280230212820252002470d02200241016a22072002490d4920024101742208200720072008491b2207ad42187e2229422088a70d492029a7220841004e0d010c490b41ddfec4002125412321242002450d50202610290c500b0240024020020d002008102721260c010b2026200241186c2008102821260b2026450d312003200736029c0220032026360298020b2026202541186c6a22022005201320241b37030820022006200420241b3703002002202741a0056a41a00520281b360210200320032802a00241016a3602a002200341e8006a200341f8016a10d803200328029c0221020b2002450d4a20032802980210290c4a0b41d588c3002125412a212420022d00000d4c20022d00014101470d4c200241196a2d00002125200241186a2d00002124200241166a2f01002126200241156a2d00002127200241146a2d00002128200241126a2f01002107200241116a2d00002108200241106a2d000021092002410e6a2f0100210a2002410d6a2d0000210b2002410c6a2d0000210c2002410a6a2f0100210d200241096a2d0000210e200241086a2d0000210f200241066a2f01002110200241056a2d00002111200241046a2d00002112200241026a2f0100211f20032002411a6a2901003703c801200320253a00c701200320243a00c601200320263b01c401200320273a00c301200320283a00c201200320073b01c001200320083a00bf01200320093a00be012003200a3b01bc012003200b3a00bb01200320123a00b2012003201f3b01b0012003200e200d410874200c41187472723600b70120032011201041087472200f411874723600b30120034188046a200341b0016a108d0220032802a8042207450d47200341c8026a41086a200341bc046a290200370300200341c8026a41106a200341c4046a290200370300200341c8026a41186a200341cc046a2902003703002003200341b4046a2902003703c80220034188046a41186a2903002129200341b0046a280200210920034194046a3502002106200329039804212b20032802ac04210a2003350288042104200329028c042113200341c8006a4189c7c500411210b501410021282006422086201342208884210620042013422086842113024002400240200941186c2202450d00200328024c410020032802481b2126200720026a2127200941186c41686a2125200721020340200241086a2903002105200229030021042026200241106a2802002224490d024200200620057d2013200454ad7d2205201320047d2204201356200520065620052006511b22241b21064200200420241b2113202541686a2125200241186a22022027470d000b0b410821080240200a0d00410021240c020b20071029410021240c010b411810272208450d2e2008200437030020082024360210200820053703080240024020250d0041012128410121240c010b200241186a210b200941186c20076a41686a210c41012128410121240340200b210202400340200241086a2903002105200229030021042026200241106a2802002225490d014200200620057d2013200454ad7d2205201320047d2204201356200520065620052006511b22251b21064200200420251b2113200241186a22022027470d000c030b0b024020242028470d00202841016a22242028490d4820284101742209202420242009491b2224ad42187e222c422088a70d48202ca722094100480d480240024020280d002009102721080c010b2008202841186c2009102821080b2008450d300b200241186a210b2008202841186c6a220920053703082009200437030020092025360210202841016a2128200c2002470d000b0b200a450d00200710290b200341b0046a2028360200200341ac046a20243602002003202b3703980420034188046a41186a2029370300200341cc046a200341c8026a41186a290300370200200341c4046a200341d8026a290300370200200341bc046a200341d0026a2903003702002003201337038804200320032903c8023702b404200320083602a80420032006370390040240202b2029844200520d002028450d0a0b200341b0016a20034188046a10d8030c430b200141106a2903002113200141086a2903002104200141186a280200211f2002411a6a2901002106200241196a2d00002107200241186a2d00002108200241166a2f01002109200241156a2d0000210a200241146a2d0000210b200241126a2f0100210c200241116a2d0000210d200241106a2d0000210e2002410e6a2f0100210f2002410d6a2d00002110200241046a2d00002111200241026a2f0100211241d588c3002125412a21240240024020022d0000450d004101212641002127410021280c010b41012126410021274100212820022d00014101470d002002410c6a2d000021282002410a6a2f01002127200241096a2d00002124200241066a2f0100410874200241056a2d000072200241086a2d0000411874722125410021260b202741ffff0371410874202441ff017172202841187472212420260d4b2003200637038003200320073a00ff02200320083a00fe02200320093b01fc022003200a3a00fb022003200b3a00fa022003200c3b01f8022003200d3a00f7022003200e3a00f6022003200f3b01f402200320103a00f302200320243600ef02200320253600eb02200320113a00ea02200320123b01e80220034188046a200341e8026a108d0220032802a8042202450d46200341f0046a41086a20034188046a41346a2902002206370300200341b0016a41086a22252006370300200341b0016a41106a222420034188046a413c6a290200370300200341b0016a41186a222720034188046a41c4006a290200370300200320034188046a412c6a29020022063703f004200320063703b001200341d4046a280200212820034188046a41286a280200210720034188046a410c6a35020021062003280288042108200329028c042105200329039804212920032802ac042126200341f8016a41186a20034188046a41186a290300370300200341f8016a410c6a20063e0200200341f8016a41286a20073602002003419c026a20263602002003202937038802200320053702fc012003200236029802200320083602f801200341f8016a41c4006a2027290300370200200341f8016a413c6a2024290300370200200341f8016a41346a2025290300370200200320032903b0013702a402200320283602c4020240201f410a4b0d00200341f8016a412c6a222510ca0320032013370358200320043703502003201f360260411210272202450d2b200241106a41002f0088a3443b0000200241086a4100290080a344370000200241002900f8a24437000020024112413210282202450d2a200220252900003700122002412a6a202541186a290000370000200241226a202541106a2900003700002002411a6a202541086a290000370000200341f0046a41186a22244200370300200341f0046a41106a22264200370300200341f0046a41086a22274200370300200342003703f00420024132200341f0046a1000200341e8036a41186a2024290300370300200341e8036a41106a2026290300370300200341e8036a41086a2027290300370300200320032903f0043703e8032003410036028804200341e8036a412020034188046a10052124024002402003280288042226417f460d002024450d00200320263602f404200320243602f00420034188046a200341f0046a10af0320032d00a00422254102460d2b200341b0016a41186a2227200341b9046a290000370300200341b0016a41106a2207200341b1046a290000370300200341b0016a41086a2208200341a9046a290000370300200341e8006a41086a2209200341ca046a290100370300200341e8006a41106a220a200341d2046a290100370300200341e8006a41186a220b200341da046a290100370300200320032900a1043703b0012003200341c2046a290100370368200341c1046a2d0000212802402026450d00202410290b200341c8026a41086a2008290300370300200341c8026a41106a2007290300370300200341c8026a41186a202729030037030020034188036a41086a200929030037030020034188036a41106a200a29030037030020034188036a41186a200b290300370300200320032903b0013703c80220032003290368370388030c010b200341f0046a41186a22244200370300200341f0046a41106a22264200370300200341f0046a41086a22274200370300200342003703f00441b3a4c400411a200341f0046a1000200341e8036a41186a2024290300370300200341e8036a41106a2026290300370300200341e8036a41086a2027290300370300200320032903f0043703e8032003410036028804200341e8036a412020034188046a100521240240024002402003280288042226417f460d002024450d00200341f0046a2026412020264120491b22276a41004100412020276b2027411f4b1b10cd041a200341f0046a2024202710ce041a2026411f4d0d2c200341b0016a41186a2226200341f0046a41186a290300370300200341b0016a41106a2227200341f0046a41106a290300370300200341b0016a41086a2228200341f0046a41086a290300370300200320032903f0043703b00120241029200341a8036a41186a20262903002206370300200341a8036a41106a20272903002213370300200341a8036a41086a20282903002204370300200320032903b00122053703a803200341c8036a41186a2006370300200341c8036a41106a2013370300200341c8036a41086a2004370300200320053703c8034112102722240d0141124101102a000b200341f0046a41186a22244200370300200341f0046a41106a22264200370300200341f0046a41086a22274200370300200342003703f00441b3a4c400411a200341f0046a1000200341e8036a41186a2024290300370300200341e8036a41106a2026290300370300200341e8036a41086a2027290300370300200320032903f0043703e803412010272224450d2a20242025290000370000202441186a202541186a290000370000202441106a202541106a290000370000202441086a202541086a290000370000200341e8036a412020244120100320241029410021280c010b202441106a41002f0088a3443b0000202441086a4100290080a344370000202441002900f8a24437000020244112413210282224450d28202420032903c8033700122024412a6a200341c8036a41186a290300370000202441226a200341c8036a41106a2903003700002024411a6a200341c8036a41086a290300370000200341f0046a41186a22264200370300200341f0046a41106a22274200370300200341f0046a41086a22284200370300200342003703f00420244132200341f0046a1000200341e8036a41186a2026290300370300200341e8036a41106a2027290300370300200341e8036a41086a2028290300370300200320032903f0043703e8032003410036028804200341e8036a412020034188046a100521262003280288042227417f460d262026450d262003202736026c2003202636026820034188046a200341e8006a10af0320032d00a00422284102460d2720034188046a41086a290300210620032903880421132003280298042107200341b0016a200341a1046a41c70010ce041a02402027450d00202610290b200341e8006a200341b0016a41c10010ce041a200320283a00880420034188046a410172200341e8006a41c10010ce041a200341cc016a200341aa046a410020032d00a9044101461b360200200320063703b801200320133703b001200320253602c801200320073602c001200341f0046a41186a22264200370300200341f0046a41106a22274200370300200341f0046a41086a22284200370300200342003703f00420244132200341f0046a1000200341e8036a41186a2026290300370300200341e8036a41106a2027290300370300200341e8036a41086a2028290300370300200320032903f0043703e8032003410036027020034201370368200341b0016a41106a200341e8006a10302003200341b0016a3602f004200341f0046a200341e8006a10590240024020032802c80122070d00200341003a00f00402400240200328026c222720032802702207460d00200328026821260c010b200741016a22262007490d4920074101742227202620262027491b22274100480d490240024020070d002027102721260c010b200328026820072027102821260b2026450d282003202736026c200320263602680b2003200741016a2228360270202620076a41003a00000c010b200341013a00f00402400240200328026c20032802702227460d00200328026821260c010b202741016a22262027490d4820274101742228202620262028491b22284100480d480240024020270d002028102721260c010b200328026820272028102821260b2026450d262003202836026c200320263602680b2003202741016a360270202620276a41013a000002400240200328026c2208200328027022286b411f4d0d00200821270c010b202841206a22272028490d4820084101742209202720272009491b22274100480d480240024020080d002027102721260c010b202620082027102821260b2026450d252003202736026c200320263602680b202620286a220841086a200741086a290000370000200841106a200741106a290000370000200841186a200741186a2900003700002003202841206a2228360270200820072900003700000b0240024020032802cc0122070d00200341003a00f004024020272028470d00202741016a22072027490d4920274101742208200720072008491b22074100480d490240024020270d002007102721260c010b202620272007102821260b2026450d252003200736026c200320263602680b2003202841016a360270202620286a41003a000020032802702128200328026c2127200328026821260c010b200341013a00f004024020272028470d00202741016a22082027490d4820274101742209200820082009491b22084100480d480240024020270d002008102721260c010b202620272008102821260b2026450d232003200836026c200320263602680b2003202841016a360270202620286a41013a000002400240200328026c2227200328027022286b4120490d00200328026821260c010b202841206a22262028490d4820274101742208202620262008491b22084100480d480240024020270d002008102721260c010b200328026820272008102821260b2026450d222003200836026c20032026360268200821270b202620286a220841086a200741086a290000370000200841106a200741106a290000370000200841186a200741186a2900003700002003202841206a2228360270200820072900003700000b200341e8036a412020262028100302402027450d00202610290b20241029200341f0046a41186a22244200370300200341f0046a41106a22264200370300200341f0046a41086a22274200370300200342003703f00441b3a4c400411a200341f0046a1000200341e8036a41186a2024290300370300200341e8036a41106a2026290300370300200341e8036a41086a2027290300370300200320032903f0043703e803412010272224450d1f20242025290000370000202441186a202541186a290000370000202441106a202541106a290000370000202441086a202541086a290000370000200341e8036a41202024412010032024102920034188036a41086a200341c8036a41086a29030037030020034188036a41106a200341c8036a41106a29030037030020034188036a41186a200341c8036a41186a290300370300200320032903c80337038803410121280b410021250b20034188046a41086a200341c8026a41086a29030037030020034188046a41106a200341c8026a41106a29030037030020034188046a41186a200341c8026a41186a290300370300200341b0016a41086a20034188036a41086a290300370300200341b0016a41106a20034188036a41106a290300370300200341b0016a41186a20034188036a41186a290300370300200320032903c8023703880420032003290388033703b001200341f0046a41186a22244200370300200341f0046a41106a22264200370300200341f0046a41086a22274200370300200342003703f00420024132200341f0046a1000200341e8036a41186a2024290300370300200341e8036a41106a2026290300370300200341e8036a41086a2027290300370300200320032903f0043703e8032003410036027020034201370368200341d0006a41106a200341e8006a10302003200341d0006a3602f004200341f0046a200341e8006a10590240024020254101460d00200341003a00f00402400240200328026c222420032802702227460d00200328026821250c010b202741016a22252027490d4720274101742224202520252024491b22244100480d470240024020270d002024102721250c010b200328026820272024102821250b2025450d1f2003202436026c200320253602680b2003202741016a2226360270202520276a41003a00000c010b200341013a00f00402400240200328026c20032802702224460d00200328026821250c010b202441016a22252024490d4620244101742226202520252026491b22264100480d460240024020240d002026102721250c010b200328026820242026102821250b2025450d1d2003202636026c200320253602680b2003202441016a360270202520246a41013a000002400240200328026c2227200328027022266b411f4d0d00202721240c010b202641206a22242026490d4620274101742207202420242007491b22244100480d460240024020270d002024102721250c010b202520272024102821250b2025450d1c2003202436026c200320253602680b202520266a222741086a20034188046a41086a290300370000202741106a20034188046a41106a290300370000202741186a20034188046a41186a2903003700002003202641206a222636027020272003290388043700000b02400240202841ff01714101460d00200341003a00f004024020242026470d00202441016a22272024490d4720244101742228202720272028491b22274100480d470240024020240d002027102721250c010b202520242027102821250b2025450d1c2003202736026c200320253602680b2003202641016a360270202520266a41003a000020032802702126200328026c2124200328026821250c010b200341013a00f004024020242026470d00202441016a22272024490d4620244101742228202720272028491b22274100480d460240024020240d002027102721250c010b202520242027102821250b2025450d1a2003202736026c200320253602680b2003202641016a360270202520266a41013a000002400240200328026c2224200328027022266b4120490d00200328026821250c010b202641206a22252026490d4620244101742227202520252027491b22274100480d460240024020240d002027102721250c010b200328026820242027102821250b2025450d192003202736026c20032025360268202721240b202520266a222741086a200341b0016a41086a290300370000202741106a200341b0016a41106a290300370000202741186a200341b0016a41186a2903003700002003202641206a2226360270202720032903b0013700000b200341e8036a412020252026100302402024450d00202510290b20021029200328029c02450d4920032802980210290c490b4180ffc4002125411b21242026450d4b200210290c4b0b2001410c6a2802002109200141086a2802002108200141046a28020021282002411a6a2901002106200241196a2d0000210a200241186a2d0000210b200241166a2f0100210c200241156a2d0000210d200241146a2d0000210e200241126a2f0100210f200241116a2d00002110200241106a2d000021112002410e6a2f010021122002410d6a2d0000211f200241046a2d00002114200241026a2f0100211541d588c3002125412a21240240024020022d0000450d004101212641002127410021070c010b41012126410021274100210720022d00014101470d002002410c6a2d000021072002410a6a2f01002127200241096a2d00002124200241066a2f0100410874200241056a2d000072200241086a2d0000411874722125410021260b202741ffff0371410874202441ff017172200741187472212420260d40200320063703c0032003200a3a00bf032003200b3a00be032003200c3b01bc032003200d3a00bb032003200e3a00ba032003200f3b01b803200320103a00b703200320113a00b603200320123b01b4032003201f3a00b303200320243600af03200320253600ab03200320143a00aa03200320153b01a80320034188046a200341a8036a108d02024020032802a804220a0d004110212441c2fec40021250c410b200341f0046a41086a20034188046a41346a2902002206370300200341b0016a41086a22022006370300200341c0016a222520034188046a413c6a290200370300200341b0016a41186a222420034188046a41c4006a290200370300200320034188046a412c6a29020022063703f004200320063703b001200341d4046a280200212620034188046a41286a280200212720034188046a410c6a35020021062003280288042107200329028c042113200329039804210420032802ac04210b200341f8016a41186a20034188046a41186a290300370300200341f8016a410c6a20063e0200200341f8016a41286a2027360200200341f8016a41246a200b3602002003200437038802200320133702fc012003200a36029802200320073602f801200341f8016a41c4006a2024290300370200200341f8016a413c6a2025290300370200200341f8016a41346a2002290300370200200320032903b0013702a402200320263602c40220090d3e41ba80c500212541172124410121020c3f0b20022d00000d4520022d00014101470d45200241196a2d00002125200241186a2d00002124200241166a2f01002126200241156a2d00002127200241146a2d00002128200241126a2f01002107200241116a2d00002108200241106a2d000021092002410e6a2f0100210a2002410d6a2d0000210b2002410c6a2d0000210c2002410a6a2f0100210d200241096a2d0000210e200241086a2d0000210f200241066a2f01002110200241056a2d00002111200241046a2d00002112200241026a2f0100211f20032002411a6a29010037038001200320253a007f200320243a007e200320263b017c200320273a007b200320283a007a200320073b0178200320083a0077200320093a00762003200a3b01742003200b3a0073200320123a006a2003201f3b01682003200e200d41087472200c4118747236006f20032011201041087472200f4118747236006b20034188046a200341e8006a108d0220032802a8042202450d44200341f0046a41086a20034188046a41346a2902002206370300200341b0016a41086a22242006370300200341c0016a222620034188046a413c6a290200370300200341b0016a41186a222720034188046a41c4006a290200370300200320034188046a412c6a29020022063703f004200320063703b001200341d4046a280200212820034188046a41286a280200210720034188046a410c6a35020021062003280288042108200329028c042113200329039804210420032802ac042125200341f8016a41186a20034188046a41186a290300370300200341f8016a410c6a20063e0200200341f8016a41286a20073602002003419c026a20253602002003200437038802200320133702fc012003200236029802200320083602f801200341f8016a41c4006a2027290300370200200341f8016a413c6a2026290300370200200341f8016a41346a2024290300370200200320032903b0013702a402200320283602c402200341f8016a412c6a222410c903202410ca032025450d46200210290c460b20022d00000d4420022d00014101470d4420012d00012114200241196a2d00002125200241186a2d00002124200241166a2f01002126200241156a2d00002127200241146a2d00002128200241126a2f01002107200241116a2d00002108200241106a2d000021092002410e6a2f0100210a2002410d6a2d0000210b2002410c6a2d0000210c2002410a6a2f0100210d200241096a2d0000210e200241086a2d0000210f200241066a2f01002110200241056a2d00002111200241046a2d00002112200241026a2f0100211f20032002411a6a2901003703c801200320253a00c701200320243a00c601200320263b01c401200320273a00c301200320283a00c201200320073b01c001200320083a00bf01200320093a00be012003200a3b01bc012003200b3a00bb01200320123a00b2012003201f3b01b0012003200e200d41087472200c411874723600b70120032011201041087472200f411874723600b30120034188046a200341b0016a108d0220032802a8042226450d43200341f8016a41086a200341bc046a29020037030020034188026a200341c4046a290200370300200341f8016a41186a200341cc046a2902003703002003200341b4046a2902003703f80120032802ac042127410d10272202450d12200241056a41002900aca344370000200241002900a7a3443700002002410d412d10282202450d11200220032903f80137000d200241256a200341f8016a41186a2903003700002002411d6a200341f8016a41106a290300370000200241156a200341f8016a41086a290300370000200341f0046a41186a22254200370300200341f0046a41106a22244200370300200341f0046a41086a22284200370300200342003703f0042002412d200341f0046a1000200341e8036a41186a2025290300370300200341e8036a41106a2024290300370300200341e8036a41086a2028290300370300200320032903f0043703e803024002400240024002400240201441037122254103460d0020250e03010203010b200341e8036a41204101410010030c040b410021240c020b410121240c010b410221240b200320243a00f004410110272225450d11202520243a0000200341e8036a4120202541011003202510290b200210292027450d45202610290c450b2001411d6a29000021132001411c6a2d000021142001411b6a2d00002115200141196a2f00002116200141186a2d00002117200141176a2d00002118200141156a2f00002119200141146a2d0000211a200141136a2d0000211b200141116a2f0000211c200141106a2d0000211d2001410c6a280200211e200141086a2802002107200141076a2d00002120200141056a2f00002121200141046a2d000021222002411a6a2901002106200241196a2d00002108200241186a2d00002109200241166a2f0100210a200241156a2d0000210b200241146a2d0000210c200241126a2f0100210d200241116a2d0000210e200241106a2d0000210f2002410e6a2f010021102002410d6a2d00002111200241046a2d00002112200241026a2f0100211f41d588c3002125412a21240240024020022d0000450d004101212641002127410021280c010b41012126410021274100212820022d00014101470d002002410c6a2d000021282002410a6a2f01002127200241096a2d00002124200241066a2f0100410874200241056a2d000072200241086a2d0000411874722125410021260b202741ffff0371410874202441ff017172202841187472212420260d47200320063703e002200320083a00df02200320093a00de022003200a3b01dc022003200b3a00db022003200c3a00da022003200d3b01d8022003200e3a00d7022003200f3a00d602200320103b01d402200320113a00d302200320243600cf02200320253600cb02200320123a00ca022003201f3b01c80220034188046a200341c8026a108c0241012126024020032d0088044101460d0041d2fec4002125410b2124410121270c490b2003200329028c043700eb02200320032d008b043a00ea02200320032f0089043b01e8022003200341a1046a2900003703800320032003419d046a2800003602fc02200320034195046a2900003702f402200320034194046a2d00003a00f3020240202241ff01714101470d0020034188046a200741067610cc012003280288042125024002402003280290042007413f7122024b0d00410021020c010b202520024105746a2202290018211320022d0017211420022d0016211520022f0014211620022d0013211720022d0012211820022f0010211920022d000f211a20022d000e211b20022f000c211c20022d000b211d2002280007211e2002280003210720022d0002212020022f00002121410121020b0240200328028c04450d00202510290b2002450d470b200320133703a003200320143a009f03200320153a009e03200320163b019c03200320173a009b03200320183a009a03200320193b0198032003201a3a0097032003201b3a0096032003201c3b0194032003201d3a0093032003201e36008f032003200736008b03200320203a008a03200320213b018803410e10272202450d0e200241066a410029009fa34437000020024100290099a3443700002002410e412e10282202450d0d200220032903880337000e200241266a20034188036a41186a2903003700002002411e6a20034188036a41106a290300370000200241166a20034188036a41086a290300370000200341f0046a41186a22254200370300200341f0046a41106a22244200370300200341f0046a41086a22264200370300200342003703f0042002412e200341f0046a1000200341e8036a41186a2025290300370300200341e8036a41106a2024290300370300200341e8036a41086a2026290300370300200320032903f0043703e803200341e8036a412041b8d6c50041004100100b2125200210292025417f470d4520034188036a200341e8026a412010d004450d44410e10272202450d0c200241066a41002900c7a244370000200241002900c1a2443700002002410e412e10282202450d0b200220032903c80237000e200241266a200341c8026a41186a2903003700002002411e6a200341c8026a41106a290300370000200241166a200341c8026a41086a290300370000200341f0046a41186a22254200370300200341f0046a41106a22244200370300200341f0046a41086a22264200370300200342003703f0042002412e200341f0046a1000200341e8036a41186a2025290300370300200341e8036a41106a2024290300370300200341e8036a41086a2026290300370300200320032903f0043703e803412010272225450d0a2025200329038803370000202541186a20034188036a41186a290300370000202541106a20034188036a41106a290300370000202541086a20034188036a41086a290300370000200341e8036a41202025412010032025102920021029410e10272202450d09200241066a410029009fa34437000020024100290099a3443700002002410e412e10282202450d08200220032903e80237000e200241266a200341e8026a41186a2903003700002002411e6a200341e8026a41106a290300370000200241166a200341e8026a41086a290300370000200341f0046a41186a22254200370300200341f0046a41106a22244200370300200341f0046a41086a22264200370300200342003703f0042002412e200341f0046a1000200341e8036a41186a2025290300370300200341e8036a41106a2024290300370300200341e8036a41086a2026290300370300200320032903f0043703e8032003410036028804200341e8036a412020034188046a10052126024002402003280288042224417f470d00410021250c010b200320243602542003202636025020034188046a200341d0006a10d30320032802a8042225450d08200341f0046a41186a20034188046a41186a290300370300200341f0046a41106a20034188046a41106a290300370300200341f0046a41086a20034188046a41086a290300370300200341f8016a41086a200341b4046a290200370300200341f8016a41106a200341bc046a290200370300200341f8016a41186a200341c4046a290200370300200341f8016a41206a200341cc046a290200370300200341a0026a200341d4046a28020036020020032003290388043703f004200320032902ac043703f80102402024450d00202610290b200341e8036a4120100c0b200341c8036a41186a2224200341f0046a41186a290300370300200341c8036a41106a2226200341f0046a41106a290300370300200341c8036a41086a2227200341f0046a41086a290300370300200341b0016a41086a2228200341f8016a41086a290300370300200341b0016a41106a2207200341f8016a41106a290300370300200341b0016a41186a2208200341f8016a41186a290300370300200341b0016a41206a2209200341f8016a41206a290300370300200341b0016a41286a220a200341f8016a41286a280200360200200320032903f0043703c803200320032903f8013703b001024020250d00200210290c450b200341a8036a41186a220b2024290300370300200341a8036a41106a22242026290300370300200341a8036a41086a22262027290300370300200341e8006a41086a22272028290300370300200341e8006a41106a22282007290300370300200341e8006a41186a22072008290300370300200341e8006a41206a22082009290300370300200341e8006a41286a2209200a280200360200200320032903c8033703a803200320032903b0013703682002102920034188046a41186a200b29030037030020034188046a41106a202429030037030020034188046a41086a2026290300370300200341ac046a2003290368370200200341b4046a2027290300370200200341bc046a2028290300370200200341c4046a2007290300370200200341cc046a2008290300370200200341d4046a2009280200360200200320032903a80337038804200320253602a804410e10272202450d06200241066a410029009fa34437000020024100290099a3443700002002410e412e10282202450d05200220032903880337000e200241266a20034188036a41186a2903003700002002411e6a20034188036a41106a290300370000200241166a20034188036a41086a290300370000200341f0046a41186a22254200370300200341f0046a41106a22244200370300200341f0046a41086a22264200370300200342003703f0042002412e200341f0046a1000200341e8036a41186a2025290300370300200341e8036a41106a2024290300370300200341e8036a41086a2026290300370300200320032903f0043703e803200341203602fc012003200341e8036a3602f80120034188046a200341f8016a10c7032002102920032802ac04450d4420032802a80410290c440b4101212620022d000120022d0000720d39200141046a280200210220034188046a41086a22254200370300200342003703880441bdc6c500411620034188046a1004200341f8016a41086a202529030037030020032003290388043703f8012003200236028804200341f8016a411020034188046a410410030c380b024020022d000120022d000072450d0041ad88c3002125412821240c460b41012126200341013a00b00120034188046a41086a22024200370300200342003703880441d7c7c500411320034188046a1004200341f8016a41086a200229030037030020032003290388043703f801200341f8016a4110200341b0016a410110030c370b4101212620022d000120022d0000720d37200141046a280200210220034188046a41086a22254200370300200342003703880441f0c6c500411920034188046a1004200341f8016a41086a202529030037030020032003290388043703f8012003200236028804200341f8016a411020034188046a410410030c360b200141086a2802002108200141046a2802002109024020022d000120022d000072450d0041ad88c30021254128212441002127410121262008450d45200910290c450b2001410c6a280200210220034188046a41086a22254200370300200342003703880441d180c500411520034188046a1004200341f8016a41086a202529030037030020032003290388043703f80120034100360290042003420137038804200320023602b001200341b0016a20034188046a10300240024020020d002003280290042124200328028c04212620032802880421270c010b200241057421282003280288042127200328028c042126200328029004212520092102034002400240202620256b4120490d00202541206a21240c010b202541206a22242025490d3e20264101742207202420242007491b22074100480d3e0240024020260d002007102721270c010b202720262007102821270b02402027450d00200721260c010b20074101102a000b202720256a22252002290000370000202541186a200241186a290000370000202541106a200241106a290000370000202541086a200241086a29000037000020242125200241206a2102202841606a22280d000b2003202636028c04200320243602900420032027360288040b200341f8016a411020272024100302402026450d00202710290b410121262008450d34200910290c340b200341f8016a41186a200341b4046a220241186a290000370300200341f8016a41106a200241106a290000370300200341f8016a41086a200241086a290000370300200342f3e885db96cddbb3203703c803200320022900003703f801200341386a41888dc300410d10940120032003290340420020032802381b3703e803200341e8006a200341f8016a109301200328026c21252003280268210220032802702124200341fc006a200341c8036a36020020032002202441286c6a360274200320023602702003202536026c200320023602682003200341e8036a360278200341f0046a200341e8006a104a200341e8006a41086a200341f0046a41086a280200360200200320032903f004370368200341f8016a200341e8006a10a701200341f8016a108b010c390b412e4101102a000b410e4101102a000b418f89c3004133104e000b412e4101102a000b410e4101102a000b41204101102a000b412e4101102a000b410e4101102a000b412e4101102a000b410e4101102a000b41014101102a000b412d4101102a000b410d4101102a000b20274101102a000b20274101102a000b20274101102a000b20244101102a000b20264101102a000b20244101102a000b41204101102a000b20084101102a000b20084101102a000b20074101102a000b20274101102a000b20284101102a000b20274101102a000b419bffc400419f01104e000b418f89c3004133104e000b41324101102a000b41204101102a000b418f89c3004133104e000b418f89c3004133104e000b41324101102a000b41124101102a000b20094108102a000b41184108102a000b20084108102a000b41344101102a000b41144101102a000b41344101102a000b41144101102a000b41014101102a000b412d4101102a000b410d4101102a000b41204101102a000b412e4101102a000b410e4101102a000b412e4101102a000b410e4101102a000b412e4101102a000b410e4101102a000b41002127410021250c0f0b41002125410121270c0e0b41ad88c300212541282124410121270c0d0b0240024002400240200941246c22240d0020282102410021260c010b200341c8026a41026a2225202841036a2d00003a0000200341e8036a41086a2227202841146a290000370300200341e8036a410d6a2207202841196a290000370000200320282f00013b01c8022003202829000c3703e803202841246a2102024020282d0000220c4102470d00410021260c010b2028280008210d2028280004212620034188036a41026a20252d00003a0000200341e8006a41086a2027290300370300200341e8006a410d6a2007290000370000200320032f01c8023b018803200320032903e8033703680240200c4101460d00200341e8026a41026a20034188036a41026a2d00003a0000200341f0046a41086a200341e8006a41086a290300370300200341f0046a410d6a200341e8006a410d6a290000370000200320032f0188033b01e802200320032903683703f0040c020b200341c8036a202641067610cc0120032802c80321270240024020032802d0032026413f7122254b0d00410021250c010b200341e8026a41026a202720254105746a222541026a2d00003a0000200341f8046a202541136a290000370300200341fd046a202541186a290000370000200320252f00003b01e8022003202529000b3703f0042025280007210d20252800032126410121250b024020032802cc03450d00202710290b20250d014184efc20021260b410121254100210c410021240c010b20034188046a410d6a2225200341f0046a410d6a29000037000020034188046a41086a2227200341f0046a41086a290300370300200341d0006a41026a2207200341e8026a41026a2d00003a0000200341b0016a41086a220c2027290300370300200341b0016a410d6a22272025290000370000200320032f01e8023b0150200320032903f0043703b00102400240412010272225450d00202520032f01503b00002025200d36000720252026360003202520032903b00137000b202541026a20072d00003a0000202541136a200c290300370000202541186a2027290000370000024002400240202820246a221e2002470d00201e21020c010b200341c8026a41026a2226202841276a2d00003a0000200341e8036a41086a2227202841386a290000370300200341e8036a410d6a22072028413d6a290000370000200320282f00253b01c802200320282900303703e803202841c8006a210220282d0024220c4102470d010b200341023a0088044101210c41002126410121240c030b202828002c21152028280028212420034188036a41026a20262d00003a0000200341e8006a41086a2027290300370300200341e8006a410d6a2007290000370000200320032f01c8023b018803200320032903e8033703680240200c4101460d00200341e8026a41026a20034188036a41026a2d00003a0000200341f0046a41086a200341e8006a41086a290300370300200341f0046a410d6a200341e8006a410d6a290000370000200320032f0188033b01e802200320032903683703f0040c020b200341c8036a202441067610cc0120032802c80321260240024020032802d0032024413f7122244b0d0041002127200d21150c010b200341e8026a41026a202620244105746a222441026a2d00003a0000200341f8046a202441136a290000370300200341fd046a202441186a290000370000200320242f00003b01e8022003202429000b3703f0042024280007211520242800032124410121270b024020032802cc03450d00202610290b20270d0120034190046a41153602004184efc200212620034184efc20036028c044101210c200341013a008804410121240c020b41204101102a000b20034194046a221020032903f00437020020034188046a41086a2015360200200341a1046a2202200341f0046a410d6a22192900003700002003419c046a200341f0046a41086a2207290300370200200341b0016a41086a221120034191046a290000370300200341b0016a41186a22122002290000370300200341b0016a41106a221f20034199046a2900003703002003202436028c04200320032f01e8023b0089042003200341e8026a41026a221a2d00003a008b0420032003290089043703b001200941246c41b87f6a211d20034188046a41017221264102210f4120210e4102210c41002127410121240340200341f0046a41186a220d2012290300370300200341f0046a41106a2214201f29030037030020072011290300370300200320032903b0013703f0040240200c417f6a2024470d00200f200c200c200f491b222441ffffff3f712024470d06202441057422024100480d062025200e2002102822250d0020024101102a000b2025200e6a220220032903f004370000200241186a200d290300370000200241106a2014290300370000200241086a20072903003700000240024002400240202741f803460d00201d2027470d01201e21020c020b202820276a41c8006a21020c010b200341c8026a41026a2214202820276a220241cb006a2d00003a0000200341e8036a41086a2216200241dc006a290000370300200341e8036a410d6a2217200241e1006a2900003700002003200241c9006a2f00003b01c8022003200241d4006a2900003703e803200241c8006a2d000022184102470d01200241ec006a21020b200341023a008804410021260c020b200241d0006a280000211b200241cc006a280000210d20034188036a41026a221c20142d00003a0000200341e8006a41086a22142016290300370300200341e8006a410d6a22162017290000370000200320032f01c8023b018803200320032903e8033703680240024020184101460d00201a201c2d00003a00002007201429030037030020192016290000370000200320032f0188033b01e802200320032903683703f004201b21150c010b200341c8036a200d41067610cc01200d413f7121144100211620032802c8032117024020032802d00320144d0d00201a201720144105746a220d41026a2d00003a00002007200d41136a2900003703002019200d41186a2900003700002003200d2f00003b01e8022003200d29000b3703f004200d2800072115200d280003210d410121160b024020032802cc03450d00201710290b20160d0020034115360290044184efc200212620034184efc20036028c04200341013a008804200241ec006a21020c020b202620032f01e8023b0000201020032903f004370000202641026a201a2d00003a0000201041086a20072903003700002010410d6a201929000037000020032015360290042003200d36028c04200341003a0088042011202641086a290000370300201f202641106a2900003703002012202641186a290000370300200320262900003703b001200f41026a210f200e41206a210e200c41016a210c202741246a21270c000b0b0240024020260d004100210d0c010b4101210d02402024450d00202510290b20262125411521240b200341f8016a412c6a21072028200941246c6a21270240034020272002460d0120022d00002126200241246a210220264102470d000b0b02402008450d00202810290b0240200d450d00410021020c010b200710c9032003200c36025820032024360254200320253602500240024002400240024002400240024002400240024002400240411210272202450d00200241106a41002f00f6a2443b0000200241086a41002900eea244370000200241002900e6a24437000020024112413210282209450d01200920072900003700122009412a6a200741186a290000370000200941226a200741106a2900003700002009411a6a200741086a290000370000200341f0046a41186a22024200370300200341f0046a41106a22254200370300200341f0046a41086a22244200370300200342003703f00420094132200341f0046a1000200341e8036a41186a2002290300370300200341e8036a41106a2025290300370300200341e8036a41086a2024290300370300200320032903f0043703e8032003410036028804200341e8036a412020034188046a10052102024002402003280288042226417f460d002002450d00200320263602ec04200320023602e804200341e8026a200341e8046a102d0240024020032802e802220e450d0020032802ec02212720034188046a200341e8046a10940320032d00880422254102470d012027450d00200e10290b418f89c3004133104e000b200341b0016a41186a2228200341a1046a290000370300200341b0016a41106a220720034199046a290000370300200341b0016a41086a220820034191046a290000370300200341e8006a41086a220a200341b2046a290100370300200341e8006a41106a220b200341ba046a290100370300200341e8006a41186a220c200341c2046a29010037030020032003290089043703b0012003200341aa046a290100370368200341a9046a2d00002124200341f0046a41086a220d2008290300370300200341f0046a41106a22082007290300370300200341f0046a41186a22072028290300370300200341c8036a41086a2228200a290300370300200341c8036a41106a220a200b290300370300200341c8036a41186a220b200c290300370300200320032903b0013703f004200320032903683703c80302402026450d00200210290b200341c8026a41086a200d290300370300200341c8026a41106a2008290300370300200341c8026a41186a200729030037030020034188036a41086a202829030037030020034188036a41106a200a29030037030020034188036a41186a200b290300370300200320032903f0043703c802200320032903c803370388032027450d01200e10290c010b200341f0046a41186a22024200370300200341f0046a41106a22254200370300200341f0046a41086a22244200370300200342003703f00441c6a3c400411a200341f0046a1000200341e8036a41186a2002290300370300200341e8036a41106a2025290300370300200341e8036a41086a2024290300370300200320032903f0043703e8032003410036028804200341e8036a412020034188046a100521020240024002402003280288042225417f460d002002450d00200341f0046a2025412020254120491b22246a41004100412020246b2024411f4b1b10cd041a200341f0046a2002202410ce041a2025411f4d0d06200341b0016a41186a2225200341f0046a41186a290300370300200341b0016a41106a2224200341f0046a41106a290300370300200341b0016a41086a2226200341f0046a41086a290300370300200320032903f0043703b00120021029200341c8036a41186a20252903002206370300200341c8036a41106a20242903002213370300200341c8036a41086a20262903002204370300200320032903b00122053703c803200341e8006a41186a2006370300200341e8006a41106a2013370300200341e8006a41086a2004370300200320053703684112102722020d0141124101102a000b200341f0046a41186a22024200370300200341f0046a41106a22254200370300200341f0046a41086a22244200370300200342003703f00441c6a3c400411a200341f0046a1000200341e8036a41186a2002290300370300200341e8036a41106a2025290300370300200341e8036a41086a2024290300370300200320032903f0043703e803412010272202450d0620022007290000370000200241186a200741186a290000370000200241106a200741106a290000370000200241086a200741086a290000370000200341e8036a412020024120100320021029410021240c010b200241106a41002f00f6a2443b0000200241086a41002900eea244370000200241002900e6a2443700002002411241321028220a450d06200a2003290368370012200a412a6a200341e8006a41186a290300370000200a41226a200341e8006a41106a290300370000200a411a6a200341e8006a41086a290300370000200341f0046a41186a22024200370300200341f0046a41106a22254200370300200341f0046a41086a22244200370300200342003703f004200a4132200341f0046a1000200341e8036a41186a2002290300370300200341e8036a41106a2025290300370300200341e8036a41086a2024290300370300200320032903f0043703e8032003410036028804200341e8036a412020034188046a100521022003280288042224417f460d072002450d07200320243602ec02200320023602e802200341f0046a200341e8026a102d0240024020032802f004220b450d00200341f8046a280200212520032802f404210c200341b0016a200341e8026a10940320032d00b00122264102470d01200c450d00200b10290b418f89c3004133104e000b20034188046a200341b0016a410172222741c10010ce041a200341b0016a20034188046a41c30010ce041a02402024450d00200210290b20034188046a200341b0016a41c30010ce041a200320263a00b001202720034188046a41c10010ce041a20032d00d101210d200341f0046a41186a22024200370300200341f0046a41106a22244200370300200341f0046a41086a22264200370300200342003703f004200a4132200341f0046a1000200341e8036a41186a2002290300370300200341e8036a41106a2024290300370300200341e8036a41086a2026290300370300200320032903f0043703e80320034201370388042003410036029004200320253602f004200341f0046a20034188046a1030024002402025450d0020254105742128410020032802900422256b2126200328028c042127200b2102034002400240202720266a4120490d0020032802880421240c010b202541206a22242025490d1620274101742208202420242008491b22084100480d160240024020270d002008102721240c010b20032802880420272008102821240b2024450d0c2003200836028c042003202436028804200821270b202420256a222441086a200241086a290000370000202441106a200241106a290000370000202441186a200241186a2900003700002003202541206a22253602900420242002290000370000202641606a2126200241206a2102202841606a22280d000c020b0b20032802900421250b200341013a00f00402400240200328028c042025460d0020032802880421020c010b202541016a22022025490d1320254101742224200220022024491b22244100480d130240024020250d002024102721020c010b20032802880420252024102821020b2002450d0a2003202436028c0420032002360288040b2003202541016a36029004200220256a41013a000002400240200328028c04222620032802900422246b411f4d0d00202621250c010b202441206a22252024490d1320264101742227202520252027491b22254100480d130240024020260d002025102721020c010b200220262025102821020b2002450d0b2003202536028c0420032002360288040b200220246a222641086a200741086a290000370000202641106a200741106a290000370000202641186a200741186a2900003700002003202441206a2228360290042026200729000037000002400240200341d2016a4100200d4101461b22260d00200341003a00f0040240024020252028460d00202521080c010b202541016a22262025490d1520254101742227202620262027491b22084100480d150240024020250d002008102721020c010b200220252008102821020b2002450d0e2003200836028c0420032002360288040b2003202441216a222436029004200220286a41003a00000c010b200341013a00f0040240024020252028460d00202521270c010b202541016a22272025490d1420254101742208202720272008491b22274100480d140240024020250d002027102721020c010b200220252027102821020b2002450d0e2003202736028c0420032002360288040b2003202441216a222536029004200220286a41013a000002400240202720256b411f4d0d00202721080c010b202541206a22282025490d1420274101742208202820282008491b22084100480d140240024020270d002008102721020c010b200220272008102821020b2002450d0f2003200836028c0420032002360288040b200220256a222541086a202641086a290000370000202541106a202641106a290000370000202541186a202641186a2900003700002003202441c1006a222436029004202520262900003700000b200341e8036a412020022024100302402008450d00200210290b0240200c450d00200b10290b200a1029200341f0046a41186a22024200370300200341f0046a41106a22254200370300200341f0046a41086a22244200370300200342003703f00441c6a3c400411a200341f0046a1000200341e8036a41186a2002290300370300200341e8036a41106a2025290300370300200341e8036a41086a2024290300370300200320032903f0043703e803412010272202450d0e20022007290000370000200241186a200741186a290000370000200241106a200741106a290000370000200241086a200741086a290000370000200341e8036a41202002412010032002102920034188036a41086a200341e8006a41086a29030037030020034188036a41106a200341e8006a41106a29030037030020034188036a41186a200341e8006a41186a2903003703002003200329036837038803410121240b410021250b20034195046a200341c8026a41086a2903003700002003419d046a200341c8026a41106a290300370000200341a5046a200341c8026a41186a290300370000200341ad046a20243a0000200341ae046a200329038803370100200341b6046a20034188036a41086a290300370100200341be046a20034188036a41106a290300370100200341c6046a20034188036a41186a290300370100200320253a008c04200320032903c80237008d042003200341d0006a36028804200341f0046a41186a22024200370300200341f0046a41106a22254200370300200341f0046a41086a22244200370300200342003703f00420094132200341f0046a1000200341e8036a41186a2002290300370300200341e8036a41106a2025290300370300200341e8036a41086a2024290300370300200320032903f0043703e803200341003602b801200342013703b00120032802502102200320032802582225360268200341e8006a200341b0016a1030024002402025450d0020254105742107410020032802b80122256b212620032802b001212820032802b401212703400240202720266a411f4b0d00202541206a22242025490d1420274101742208202420242008491b22244100480d140240024020270d002024102721280c010b202820272024102821280b2028450d03202421270b202820256a22242002290000370000202441186a200241186a290000370000202441106a200241106a290000370000202441086a200241086a290000370000202641606a2126202541206a2125200241206a2102200741606a22070d000b200320273602b401200320253602b801200320283602b0010b20034188046a410472200341b0016a10c60320032802b4012102200341e8036a412020032802b001222520032802b801100302402002450d00202510290b2009102902402003280254450d00200328025010290b0240200328029c02450d0020032802980210290b4100212641012127410021250c1a0b20244101102a000b41124101102a000b41324101102a000b418f89c3004133104e000b41204101102a000b41324101102a000b419bffc400419f01104e000b20084101102a000b20244101102a000b20254101102a000b20084101102a000b20274101102a000b20084101102a000b41204101102a000b0240200b450d00200a10290b20020d0041012127410021260c0b0b41012127410021262008450d0a202810290c0a0b024020032802ac04450d0020032802a80410290b410021250c080b102b000b20032013202c202c201356200420065620042006511b22021b221320297c220537038802200341f8016a41186a2006200420021b2206202a7c2005201354ad7c37030020032013202b7c22043703f80120032006202d7c2004201354ad7c37038002200341e8006a200341f8016a10d803200328029c0221250b2025450d0220032802980210290c020b41c2fec4002125411021240c040b41d588c3002125412a21240c030b4100212541012126410121270c030b41e4fdc4002125411921240c010b4184efc2002125411521240b41012126410121270b0240024020012d00002202410d4b0d00410120027441be3f710d01024020024106460d002002410d470d012027450d02200141086a280200450d02200141046a28020010290c020b2026450d01200141086a280200450d01200141046a28020010290c010b200141086a280200450d00200141046a28020010290b200020243602042000202536020020034190056a24000bb0c90107017f027e017f017e157f017e027f230041a0086b2203240002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024020012d00000e12000102030405060708090b0c0d0e0f101112000b200341b4036a4101360200200342013702a403200341ccfdc4003602a00320034102360264200341c4fdc4003602602003200341e0006a3602b003200341a0036a41a09ac4001057000b200141106a2903002104200141086a2903002105200141046a28020021062002411a6a2901002107200241196a2d00002108200241186a2d00002109200241166a2f0100210a200241156a2d0000210b200241146a2d0000210c200241126a2f0100210d200241116a2d0000210e200241106a2d0000210f2002410e6a2f010021102002410d6a2d00002111200241046a2d00002112200241026a2f01002113024002400240024020022d0000450d002003200737028402200320083a008302200320093a0082022003200a3b018002410121020c010b2002410c6a2d000021142002410a6a2f01002115200241096a2d00002116200241086a2d00002117200241066a2f01002118200241056a2d0000211920022d0001211a200320073703800241012102201a41ff01714101460d010b412a21164100211441d588c300211a410021150c010b2018410874201972201741187472211a410021020b201541ffff0371410874201441187472201641ff017172211420020d5920032007370378200320083a0077200320093a00762003200a3b01742003200b3a00732003200c3a00722003200d3b01702003200e3a006f2003200f3a006e200320103b016c200320113a006b200320143600672003201a360063200320123a0062200320133b01600240200542808084fea6dee1115441002004501b450d0041b09ac400211a410d21140c5a0b200341106a200341e0006a2005200410ac0102402003280210450d0041bd9ac400211a411a21140c5a0b200341086a41b086c500411910b501200328020c210220032802082114200341b8076a41086a221a4200370300200342003703b80741b086c5004119200341b8076a1004200341f0066a41086a2215201a290300370300200320032903b8073703f00620032002410020141b221641016a3602a003200341f0066a4110200341a0036a41041003412010272202450d1120022003290360370000200341b4036a428180808010370200200241186a200341e0006a41186a290300370000200241106a200341e0006a41106a290300370000200241086a200341e0006a41086a290300370000200320053703a003200320023602b003200320043703a8032016200341a0036a10c203201a4200370300200342003703b80741b7d2c3004115200341b8076a10042015201a290300370300200320032903b8073703f006200341003602a003200341f0066a4110200341a0036a1005211a0240024020032802a0032208417f460d00201a450d0020032008360284022003201a36028002200341a0036a20034180026a103f20032802a0032214450d14200341a8036a280200210220032802a40321152008450d01201a10290c010b4108211441002102410021150b200341a0036a200610c103200341c0006a41186a2208200341e0006a41186a290300370300200341c0006a41106a2209200341e0006a41106a290300370300200341c0006a41086a220a200341e0006a41086a29030037030020032003290360370340024020152002470d00200241016a221a2002490d4920024101742215201a201a2015491b2215ad42b0017e2207422088a70d492007a7221a4100480d490240024020020d00201a102721140c010b2014200241b0016c201a102821140b2014450d140b2014200241b0016c220b6a200341a0036a41880110ce04221a201636028801201a200329034037028c01201a4194016a200a290300370200201a419c016a2009290300370200201a41a4016a2008290300370200200320153602a403200320143602a0032003200241016a221a3602a803200341b8076a41086a22084200370300200342003703b80741b7d2c3004115200341b8076a1004200341f0066a41086a2008290300370300200320032903b8073703f00620034110360284022003200341f0066a36028002200341a0036a20034180026a10330240201a2002490d00200b41b0016a211a2014210203402002103d200241b0016a2102201a41d07e6a221a0d000b0b02402015450d00201410290b200341b8036a2004370300200341b0036a2005370300200341ac036a201636020041002116200341a8036a41003a0000200341053a00a00341b8d6c5004100200341a0036a1088012006103d200610294101211541012106410121084100211a0c5a0b200141046a280200210a2002411a6a2901002107200241196a2d00002116200241186a2d00002108200241166a2f01002109200241156a2d0000210b200241146a2d0000210c200241126a2f0100210d200241116a2d0000210e200241106a2d0000210f2002410e6a2f010021102002410d6a2d00002111200241046a2d00002112200241026a2f01002113024002400240024020022d0000450d002003200737028402200320163a008302200320083a008202200320093b018002410121020c010b2002410c6a2d000021142002410a6a2f01002106200241096a2d00002115200241086a2d00002117200241066a2f01002118200241056a2d0000211920022d0001211a200320073703800241012102201a41ff01714101460d010b412a21154100211441d588c300211a410021060c010b2018410874201972201741187472211a410021020b200641ffff0371410874201441187472201541ff017172211420020d5520032007370378200320163a0077200320083a0076200320093b01742003200b3a00732003200c3a00722003200d3b01702003200e3a006f2003200f3a006e200320103b016c200320113a006b200320143600672003201a360063200320123a0062200320133b0160200341a0036a200a10b603024020032802b00322020d0041d79ac400211a41242114410121150c570b200341bc036a2802002116200341a0036a41186a280200211a20032802b4032106200341186a200341e0006a20032902a403220742208620033502a003842204200341ac036a350200422086200742208884220710ac0120032802180d54200341c0006a41186a200341e0006a41186a290300370300200341c0006a41106a2215200341e0006a41106a290300370300200341c0006a41086a2209200341e0006a41086a2903003703002003200329036037034002402006201a460d00200621080c520b200641016a22142006490d4720064101742208201420142008491b220841ffffff3f712008470d47200841057422144100480d470240024020060d002014102721020c010b200220064105742014102821020b20020d5120144101102a000b2002411a6a2901002107200241196a2d0000211a200241186a2d00002114200241166a2f01002106024020022d0000450d0020032007370284022003201a3a008302200320143a008202200320063b0180020c500b200241156a2d00002116200241146a2d00002108200241126a2f01002109200241116a2d0000210a200241106a2d0000210b2002410e6a2f0100210c2002410d6a2d0000210d2002410c6a2d0000210e2002410a6a2f0100210f200241096a2d00002110200241086a2d00002111200241066a2f01002112200241056a2d00002113200241046a2d00002117200241026a2f01002118200141026a2d00002119200141046a280200211b20022d0001210220012d0001211c200320073703800241012115200241ff01714101460d060c4f0b2002411a6a2901002107200241196a2d0000211a200241186a2d00002114200241166a2f01002106024020022d0000450d0020032007370284022003201a3a008302200320143a008202200320063b0180020c4f0b200141026a2d00002118200141046a280200211920012d0001211b200241156a2d00002115200241146a2d00002116200241126a2f01002108200241116a2d00002109200241106a2d0000210a2002410e6a2f0100210b2002410d6a2d0000210c2002410c6a2d0000210d2002410a6a2f0100210e200241096a2d0000210f200241086a2d00002110200241066a2f01002111200241056a2d00002112200241046a2d00002113200241026a2f0100211720022d000121022003200737038002200241ff01714101470d4e200320073703782003201a3a0077200320143a0076200320063b0174200320153a0073200320163a0072200320083b0170200320093a006f2003200a3a006e2003200b3b016c2003200c3a006b200320133a0062200320173b01602003200e410874200d41187472200f7236006720032011410874201272201041187472360063200341a0036a200341e0006a10c30320032d00a0034101470d4d200341ac036a2d00002102200341ad036a2900002107200341b5036a280000211a20032f00a103211420032d00a303210620032902a40321042003200341b9036a2900003703b8032003201a3602b403200320073702ac03200320023a00ab03200320043700a303200320063a00a203200320143b01a003200341a0036a2019201b41ff0171410047201810c403211a41222114410121150c540b2002410c6a2802002109200241086a280200210a200241046a2802002106200141106a2903002105200141086a2903002107200141046a2802002115200241036a2d0000211620012d0001211420022d0000211a20022f0001210820034180026a41086a2002411c6a2802003602002003200241146a290200370380020240024002400240201a4101470d00200641ff01710d01200a2009490d010c020b201a4103460d010b201a20082016411074727241ff01710d010b42002104200341b8076a41086a22024200370300200342003703b80741888dc300410d200341b8076a1004200341f0066a41086a2002290300370300200320032903b8073703f006200341003602a003200341f0066a4110200341a0036a1005211a024020032802a0032202417f460d00200342003703a003200341a0036a201a2002410820024108491b10ce041a200241074d0d1220032903a0032104201a10290b200341a0036a201541880110ce041a200341e0006a2004200742c0d102200742c0d102561b7c200341a0036a2014200510b503410121060240024020032802604101470d002003280264221a0d010b20151029410021150c4c0b200341e8006a28020021140c4a0b2015103d4128211441ad88c300211a0c490b41a584c200211a410e211420022d0000417f6a220941024b0d51200141046a280200210a410121154101210641012108410121160240024020090e03005701000b200241046a2d00000d5241012115410121064101210841012116200241086a28020041036c2002410c6a280200410174490d560b200341a0036a200a10a703024020032802a8034112470d0041bf9dc400211a410d2114410121150c530b20032802a003210220034180026a200341a0036a410472419c0110ce041a20032002360260200341e0006a41047220034180026a419c0110ce041a200341003602a803200342013703a003200341e0006a41086a2214200341a0036a103220032802a403211a20032802a803210620032802a003210220034180026a41186a2215420037030020034180026a41106a2216420037030020034180026a41086a2208420037030020034200370380022002200620034180026a1000200341c8056a41186a22062015290300370300200341c8056a41106a22152016290300370300200341c8056a41086a2216200829030037030020032003290380023703c8050240201a450d00200210290b200341a0036a41186a2006290300370300200341a0036a41106a2015290300370300200341a0036a41086a2016290300370300200320032903c8053703a003411710272202450d102002410f6a41002900af9b44370000200241086a41002900a89b44370000200241002900a09b4437000020024117413710282202450d11200220032903a0033700172002412f6a200341a0036a41186a2216290300370000200241276a200341a0036a41106a22082903003700002002411f6a200341a0036a41086a29030037000020034180026a41186a221a420037030020034180026a41106a2206420037030020034180026a41086a2215420037030020034200370380022002413720034180026a1000200341c0046a41186a201a290300370300200341c0046a41106a2006290300370300200341c0046a41086a201529030037030020032003290380023703c004200341c0046a412041b8d6c50041004100100b211a20021029201a417f460d472014103d41cc9dc400211a41252114410121150c520b200141046a280200210641a584c200211a410e211420022d0000417f6a221541024b0d450240024020150e03004701000b200241086a2802004101742002410c6a280200490d46200241046a28020041ff01710d460b200341b8076a41086a22024200370300200342003703b8074188d4c3004116200341b8076a1004200341f0066a41086a2002290300370300200320032903b8073703f006200341f0066a411041b8d6c50041004100100b417f460d4141d19bc400211a411521140c450b200141046a280200210641a584c200211a410e211420022d0000417f6a221541024b0d3f0240024020150e03004101000b200241046a2d00000d40200241086a28020041036c2002410c6a280200410174490d400b200341b8076a41086a22024200370300200342003703b8074188d4c3004116200341b8076a1004200341f0066a41086a2002290300370300200320032903b8073703f006200341f0066a411041b8d6c50041004100100b417f460d3e41d19bc400211a411521140c3f0b200141306a2903002104200141286a290300210720034190086a200141196a29000037030020034188086a200141116a290000370300200341f8076a41086a200141096a290000370300200320012900013703f8074101211541a584c200211a410e211420022d0000417e6a220641014b0d4f0240024020060e020001000b200241046a2d00000d50200241086a28020041036c2002410c6a280200410174490d500b200341b8076a41086a22024200370300200342003703b8074188d4c3004116200341b8076a1004200341f0066a41086a2002290300370300200320032903b8073703f006200341003602a003200341f0066a4110200341a0036a1005210220032802a003221a417f460d3c2002450d3c2003201a3602dc07200320023602d807200341a0036a200341d8076a103c20032802a0034112460d38200341e0006a200341a0036a41880110ce041a200341003a009f082003419f086a20032802d807221620032802dc072214410047220610ce041a20142006490d0f2003201420066b3602dc072003201620066a3602d807024002402014450d0020032d009f0822064103490d010b200341e0006a103d0c390b2003280260211420034180026a200341e0006a41047241840110ce041a20144112460d38200341c8056a20034180026a41840110ce041a0240201a450d00200210290b200341c0046a200341c8056a41840110ce041a20032014360260200341e0006a410472200341c0046a41840110ce041a20064102460d3941f29bc400211a412a21140c3a0b200320073703b8032003201a3a00b703200320143a00b603200320063b01b403200320163a00b303200320083a00b203200320093b01b0032003200a3a00af032003200b3a00ae032003200c3b01ac032003200d3a00ab03200320173a00a203200320183b01a0032003200f410874200e411874722010723600a703200320124108742013722011411874723600a303200341a0036a201b201c41ff0171410047201910c403211a412221140c4e0b200341f0076a200141196a290000370300200341d8076a41106a200141116a290000370300200341d8076a41086a200141096a290000370300200320012900013703d8074101211541a584c200211a410e211420022d00004101470d4d200241236a2d00002116200241216a2f000021082002411f6a2d000021092002411d6a2f0000210a2002410f6a2d0000210b2002410d6a2f0000210c2002410b6a2d0000210d200241096a2f0000210e200241076a2d0000210f200241056a2f00002110200241246a3502002105200241206a310000211d200241116a2900002107200241106a2d000021112002410c6a2d00002112200241086a2d00002113200241046a2d000021062003200241196a28000036028802200320073703800220064101470d4d200320032902840222043d018808200320113a008308200320044238883c008f08200320044230883c008e08200320044220883d018c08200320044218883c008b08200320044210883c008a08200320073d018408200320074218883c0087082003200c200b411074724108742012723600ff072003200e200d411074724108742013723600fb0720032010200f4110747222023b01f807200320024110763a00fa0720032007a74110763a0086082003201d421886200a200941107472ad42ffffff0783842008201641107472ad42ffffff07834220868420054238868437039008200341b8076a41086a22024200370300200342003703b8074188d4c3004116200341b8076a1004200341f0066a41086a2002290300370300200320032903b8073703f006200341003602a003200341f0066a4110200341a0036a100521020240024020032802a003221a417f460d002002450d002003201a3602bc07200320023602b807200341a0036a200341b8076a103c20032802a0034112460d37200341e0006a200341a0036a41880110ce041a200341003a009f082003419f086a20032802b807221620032802bc072214410047220610ce041a20142006490d102003201420066b3602bc072003201620066a3602b807024002402014450d0020032d009f084103490d010b200341e0006a103d0c380b2003280260211420034180026a200341e0006a41047241840110ce041a20144112460d37200341c8056a20034180026a41840110ce041a0240201a450d00200210290b200341c0046a200341c8056a41840110ce041a200320143602a003200341a0036a410472200341c0046a41840110ce041a2003410036026820034201370360200341a0036a200341e0006a10322003280264211a200328026821062003280260210220034180026a41186a221642003703004110211420034180026a41106a2208420037030020034180026a41086a2209420037030020034200370380022002200620034180026a1000200341e0006a41186a2016290300370300200341e0006a41106a2008290300370300200341e0006a41086a200929030037030020032003290380023703600240201a450d00200210290b200341d8076a200341e0006a412010d0042102200341a0036a103d41d39cc400211a20020d4f200341a0036a200341d8076a10c50320032802a803220b0d01410021024101210b420021070c360b4114211441bf9cc400211a0c4e0b410021020240024020032902ac032207422088a7221a41014b0d00201a0e023601360b0340201a410176221420026a22062002200b20064105746a200341f8076a412010d0044101481b2102201a20146b221a41014b0d000b0b200b20024105746a200341f8076a412010d004221a450d33201a411f7620026a21020c340b4101211520022d000120022d0000720d31200141046a28020010ab030c480b4101211520022d000120022d0000720d30200141086a2802002106200141046a2802002102200341e0006a200141106a290300220710ac03200328026021140240024002402003280268221a20024d0d00201420024190016c6a22162802004112460d01201420024190016c6a4188016a2802002006470d012016103d20164112360200200341a0036a41086a200341e0006a41086a280200360200200320032903603703a003411710272202450d102002410f6a41002900ffd143370000200241086a41002900f8d143370000200241002900f0d14337000020024117412e10282202450d112002200737001720034180026a41186a221a420037030020034180026a41106a2214420037030020034180026a41086a2206420037030020034200370380022002411f20034180026a1000200341c0046a41186a201a290300370300200341c0046a41106a2014290300370300200341c0046a41086a200629030037030020032003290380023703c00420034120360284022003200341c0046a36028002200341a0036a20034180026a10312002102920032802a0032114024020032802a8032202450d0020024190016c211a201421020340024020022802004112460d002002103d0b20024190016a2102201a41f07e6a221a0d000b0b20032802a403450d4a201410290c4a0b201a450d010b201a4190016c211a201421020340024020022802004112460d002002103d0b20024190016a2102201a41f07e6a221a0d000b0b02402003280264450d00201410290b41f19dc400211a411221140c4b0b200341e0006a41186a200141196a290000370300200341e0006a41106a200141116a290000370300200341e0006a41086a200141096a29000037030020032001290001370360200241166a2f0100211a200241186a2d00002114200241196a2d000021062002411a6a2901002107024020022d0000450d002003200737028402200320063a008302200320143a0082022003201a3b0180020c450b200241026a2f01002116200241046a2d00002108200241056a2d00002109200241066a2f0100210a200241086a2d0000210b200241096a2d0000210c2002410a6a2f0100210d2002410c6a2d0000210e2002410d6a2d0000210f2002410e6a2f01002110200241106a2d00002111200241116a2d00002112200241126a2f01002113200241146a2d00002117200241156a2d0000211820022d000121022003200737038002200241ff01714101470d44410f10272202450d0e200241076a41002900909d44370000200241002900899d443700002002410f412f10282202450d0f2002200329036037000f200241276a200341e0006a41186a221c2903003700002002411f6a200341e0006a41106a221e290300370000200241176a200341e0006a41086a221f29030037000020034180026a41186a2215420037030020034180026a41106a2219420037030020034180026a41086a221b420037030020034200370380022002412f20034180026a1000200341c0046a41186a2015290300370300200341c0046a41106a2019290300370300200341c0046a41086a201b29030037030020032003290380023703c004200341c0046a412041b8d6c50041004100100b21152002102902402015417f460d0041989dc400211a410f2114410121150c4b0b200341a0036a41186a201c290300370300200341a0036a41106a201e290300370300200341a0036a41086a201f290300370300200320032903603703a003410f10272202450d10200241076a41002900909d44370000200241002900899d443700002002410f412f10282215450d11201520032903a00337000f201541276a200341a0036a41186a2903003700002015411f6a200341a0036a41106a290300370000201541176a200341a0036a41086a29030037000020034180026a41186a2202420037030020034180026a41106a2219420037030020034180026a41086a221b420037030020034200370380022015412f20034180026a1000200341c0046a41186a2002290300370300200341c0046a41106a2019290300370300200341c0046a41086a201b29030037030020032003290380023703c004412010272202450d1220022007370018200220063a0017200220143a00162002201a3b0014200220183a0013200220173a0012200220133b0010200220123a000f200220113a000e200220103b000c2002200f3a000b2002200d410874200c72200e411874723600072002200a410874200972200b41187472360003200220083a0002200220163b0000200341c0046a412020024120100320021029201510294100211a410121150c4a0b2002411a6a2901002107200241196a2d00002114200241186a2d00002106200241166a2f01002115024020022d0000450d002003200737028402200320143a008302200320063a008202200320153b0180020c440b200241156a2d00002116200241146a2d00002108200241126a2f01002109200241116a2d0000210a200241106a2d0000210b2002410e6a2f0100210c2002410d6a2d0000210d2002410c6a2d0000210e2002410a6a2f0100210f200241096a2d00002110200241086a2d00002111200241066a2f01002112200241056a2d00002113200241046a2d00002117200241026a2f0100211820022d000121022003200737038002200241ff01714101470d43410f10272202450d124100211a200241076a41002900909d44370000200241002900899d443700002002410f412f10282202450d1320022007370027200220143a0026200220063a0025200220153b0023200220163a0022200220083a0021200220093b001f2002200a3a001e2002200b3a001d2002200c3b001b2002200d3a001a2002200f410874201072200e4118747236001620022012410874201372201141187472360012200220173a0011200220183b000f20034180026a41186a2214420037030020034180026a41106a2206420037030020034180026a41086a2215420037030020034200370380022002412f20034180026a1000200341c0046a41186a2014290300370300200341c0046a41106a2006290300370300200341c0046a41086a201529030037030020032003290380023703c004200341c0046a4120100c20021029410121150c460b200341f8076a41186a200141196a290000370300200341f8076a41106a200141116a290000370300200341f8076a41086a200141096a290000370300200320012900013703f8072002411a6a2901002107200241196a2d0000211a200241186a2d00002114200241166a2f01002106024020022d0000450d0020032007370284022003201a3a008302200320143a008202200320063b0180020c430b200241156a2d00002115200241146a2d00002116200241126a2f01002108200241116a2d00002109200241106a2d0000210a2002410e6a2f0100210b2002410d6a2d0000210c2002410c6a2d0000210d2002410a6a2f0100210e200241096a2d0000210f200241086a2d00002110200241066a2f01002111200241056a2d00002112200241046a2d00002113200241026a2f0100211720022d000121022003200737038002200241ff01714101470d42200320073703e0052003201a3a00df05200320143a00de05200320063b01dc05200320153a00db05200320163a00da05200320083b01d805200320093a00d7052003200a3a00d6052003200b3b01d4052003200c3a00d305200320133a00ca05200320173b01c8052003200e410874200f72200d411874723600cf05200320114108742012722010411874723600cb05200341a0036a200341f8076a10c30320032d00a0034101470d41200320032902a403370063200320032d00a3033a0062200320032f00a1033b01602003200341b9036a2900003703782003200341b5036a2800003602742003200341ad036a29000037026c2003200341ac036a2d00003a006b0240200341e0006a200341c8056a412010d004450d0041a79dc400211a410b2114410121150c490b200341a0036a41186a200341f8076a41186a290300370300200341a0036a41106a200341f8076a41106a290300370300200341a0036a41086a200341f8076a41086a290300370300200320032903f8073703a003410f10272202450d134100211a200241076a41002900909d44370000200241002900899d443700002002410f412f10282202450d14200220032903a00337000f200241276a200341a0036a41186a2903003700002002411f6a200341a0036a41106a290300370000200241176a200341a0036a41086a29030037000020034180026a41186a2214420037030020034180026a41106a2206420037030020034180026a41086a2215420037030020034200370380022002412f20034180026a1000200341c0046a41186a2014290300370300200341c0046a41106a2006290300370300200341c0046a41086a201529030037030020032003290380023703c004200341c0046a4120100c20021029410121150c480b200141216a2d0000210a200341206a41186a200141196a290000370300200341206a41106a200141116a290000370300200341206a41086a200141096a290000370300200320012900013703202002411a6a2901002107200241196a2d00002116200241186a2d00002108200241166a2f01002109200241156a2d0000210b200241146a2d0000210c200241126a2f0100210d200241116a2d0000210e200241106a2d0000210f2002410e6a2f010021102002410d6a2d00002111200241046a2d00002112200241026a2f01002113024002400240024020022d0000450d002003200737028402200320163a008302200320083a008202200320093b018002410121020c010b2002410c6a2d000021142002410a6a2f01002106200241096a2d00002115200241086a2d00002117200241066a2f01002118200241056a2d0000211920022d0001211a200320073703800241012102201a41ff01714101460d010b41d588c300211a41002106412a2115410021140c010b2018410874201972201741187472211a410021020b200641ffff0371410874201541ff017172201441187472211420020d46200320143600d7062003201a3600d306200320123a00d206200320133b01d0062003200e3a00df062003200f3a00de06200320103b01dc06200320113a00db06200320163a00e706200320083a00e606200320093b01e4062003200b3a00e3062003200c3a00e2062003200d3b01e006200320073703e806200341f0066a41186a2007370300200341f0066a41106a20032903e006370300200341f0066a41086a200341d0066a41086a290300370300200320032903d0063703f006200341c8056a41186a200341206a41186a290300370300200341c8056a41106a200341206a41106a290300370300200341c8056a41086a200341206a41086a2903003703002003200a3a00e805200320032903203703c805411510272202450d142002410d6a41002900bbd143370000200241086a41002900b6d143370000200241002900aed14337000020024115413510282202450d15200220032903f0063700152002412d6a200341f0066a41186a290300370000200241256a200341f0066a41106a2903003700002002411d6a200341f0066a41086a29030037000020034180026a41186a221a420037030020034180026a41106a2206420037030020034180026a41086a2215420037030020034200370380022002413520034180026a1000200341c0046a41186a201a290300370300200341c0046a41106a2006290300370300200341c0046a41086a201529030037030020032003290380023703c004200341003602a003200341c0046a4120200341a0036a1005211a0240024020032802a0032216417f460d00201a450d00200320163602fc072003201a3602f807200341a0036a200341f8076a10fc0220032d00c10322064102460d18200341e0006a41186a2208200341da036a290100370300200341e0006a41106a2209200341d2036a290100370300200341e0006a41086a220a200341ca036a29010037030020034180026a41086a220b200341eb036a29000037030020034180026a41106a220c200341f3036a29000037030020034180026a41186a220d200341fb036a290000370300200320032901c2033703602003200341e3036a29000037038002200341e2036a2d0000211502402016450d00201a10290b200341c0006a41086a200a290300370300200341c0006a41106a2009290300370300200341c0006a41186a2008290300370300200341f8076a41086a200b290300370300200341f8076a41106a200c290300370300200341f8076a41186a200d2903003703002003200329036037034020032003290380023703f8070c010b20034180026a41186a221a420037030020034180026a41106a2206420037030020034180026a41086a221542003703002003420037038002419ad2c300411d20034180026a1000200341c0046a41186a201a290300370300200341c0046a41106a2006290300370300200341c0046a41086a201529030037030020032003290380023703c004200341003602a003200341c0046a4120200341a0036a1005211a02400240024020032802a0032206417f460d00201a450d0020034180026a2006412020064120491b22156a41004100412020156b2015411f4b1b10cd041a20034180026a201a201510ce041a2006411f4d0d1b200341a0036a41186a220620034180026a41186a290300370300200341a0036a41106a221520034180026a41106a290300370300200341a0036a41086a221620034180026a41086a29030037030020032003290380023703a003201a102920034198076a41186a2006290300220737030020034198076a41106a2015290300220437030020034198076a41086a20162903002205370300200320032903a003221d37039807200341b8076a41186a2007370300200341b8076a41106a2004370300200341b8076a41086a20053703002003201d3703b80741151027221a0d0141154101102a000b20034180026a41186a221a420037030020034180026a41106a2206420037030020034180026a41086a221542003703002003420037038002419ad2c300411d20034180026a1000200341c0046a41186a201a290300370300200341c0046a41106a2006290300370300200341c0046a41086a201529030037030020032003290380023703c00441201027221a450d1b201a20032903f006370000201a41186a200341f0066a41186a290300370000201a41106a200341f0066a41106a290300370000201a41086a200341f0066a41086a290300370000200341c0046a4120201a41201003201a1029410021150c010b201a410d6a41002900bbd143370000201a41086a41002900b6d143370000201a41002900aed143370000201a4115413510282215450d1b201520032903b8073700152015412d6a200341b8076a41186a290300370000201541256a200341b8076a41106a2903003700002015411d6a200341b8076a41086a29030037000020034180026a41186a221a420037030020034180026a41106a2206420037030020034180026a41086a2216420037030020034200370380022015413520034180026a1000200341c0046a41186a201a290300370300200341c0046a41106a2006290300370300200341c0046a41086a201629030037030020032003290380023703c004200341003602a003200341c0046a4120200341a0036a1005210820032802a0032209417f460d1d2008450d1d20032009360284022003200836028002200341a0036a20034180026a10fc0220032d00c103220b4102460d1c200341f8076a41186a221a200341a0036a41186a290300370300200341f8076a41106a2206200341a0036a41106a290300370300200341f8076a41086a2216200341a0036a41086a290300370300200320032903a0033703f80720032d00c003210a200341e0006a200341c2036a220c41c10010ce041a02402009450d00200810290b200341d8076a41086a22082016290300370300200341d8076a41106a22092006290300370300200341d8076a41186a220d201a290300370300200320032903f8073703d80720034180026a200341e0006a41c10010ce041a201a200d2903003703002006200929030037030020162008290300370300200320032903d8073703f8072003200b3a00a003200341a0036a41017220034180026a41c10010ce041a200341e0006a41186a201a290300370300200341e0006a41106a2006290300370300200341e0006a41086a2016290300370300200320032903f80737036020032d00c103210920034180026a41186a221a420037030020034180026a41106a2206420037030020034180026a41086a2216420037030020034200370380022015413520034180026a1000200341c0046a41186a201a290300370300200341c0046a41106a2006290300370300200341c0046a41086a201629030037030020032003290380023703c00441201027221a450d1e201a2003290360370000201a41186a200341e0006a41186a290300370000201a41106a200341e0006a41106a290300370000201a41086a200341e0006a41086a29030037000002400240200a41054b0d000240024002400240024002400240200a0e06000102030405000b200341003a009f080c050b200341013a009f080c040b200341023a009f080c030b200341033a009f080c020b200341043a009f080c010b200341053a009f080b41c0002106201a412041c0001028221a450d21201a20032d009f083a002041012108200341013a009f08412121160c010b200341013a009f0841000d3b41c000210641202116201a412041c0001028221a450d2120032d009f0821080b201a20166a20083a000002402006201641016a22086b411f4b0d0041000d3b2006410174220a200841206a220b200b200a491b220a4100480d3b201a2006200a1028221a450d2c200a21060b201a20086a220820032903f006370000200841186a200341f0066a41186a290300370000200841106a200341f0066a41106a290300370000200841086a200341f0066a41086a290300370000201641216a210802400240200c410020094101461b22160d0041002116200341003a009f080240024020062008460d00200821060c010b41000d3d20064101742216200641016a220820082016491b22164100480d3d201a200620161028221a450d2420032d009f0821160b201a20066a20163a0000200641016a21060c010b200341013a009f080240024020062008460d004101210a20062109200821060c010b41000d3c20064101742208200641016a220920092008491b22094100480d3c201a200620091028221a450d2420032d009f08210a0b201a20066a200a3a000002402009200641016a22086b411f4b0d0041000d3c2009410174220a200841206a220b200b200a491b220a4100480d3c201a2009200a1028221a0d00200a4101102a000b201a20086a22082016290000370000200841186a201641186a290000370000200841106a201641106a290000370000200841086a201641086a290000370000200641216a21060b200341c0046a4120201a20061003201a10292015102920034180026a41186a221a420037030020034180026a41106a2206420037030020034180026a41086a221542003703002003420037038002419ad2c300411d20034180026a1000200341c0046a41186a201a290300370300200341c0046a41106a2006290300370300200341c0046a41086a201529030037030020032003290380023703c00441201027221a450d23201a20032903f006370000201a41186a200341f0066a41186a290300370000201a41106a200341f0066a41106a290300370000201a41086a200341f0066a41086a290300370000200341c0046a4120201a41201003201a1029200341f8076a41086a200341b8076a41086a290300370300200341f8076a41106a200341b8076a41106a290300370300200341f8076a41186a200341b8076a41186a290300370300200320032903b8073703f807410121150b410021060b200341ad036a200341c0006a41086a290300370000200341b5036a200341c0006a41106a290300370000200341bd036a200341c0006a41186a290300370000200341c5036a20153a0000200341c6036a20032903f807370100200341ce036a200341f8076a41086a290300370100200341d6036a200341f8076a41106a290300370100200341de036a200341f8076a41186a290300370100200320063a00a403200320032903403700a5032003200341c8056a3602a00320034180026a41186a221a420037030020034180026a41106a2206420037030020034180026a41086a2215420037030020034200370380022002413520034180026a1000200341c0046a41186a201a290300370300200341c0046a41106a2006290300370300200341c0046a41086a201529030037030020032003290380023703c004200341003602682003420137036041201027221a450d22201a20032903c805370000201a41186a200341c8056a41186a290300370000201a41106a200341c8056a41106a290300370000201a41086a200341c8056a41086a290300370000200342a080808080043702642003201a360260024020032d00e805220641054b0d00024002400240024002400240024020060e06000102030405000b200341003a009f080c050b200341013a009f080c040b200341023a009f080c030b200341033a009f080c020b200341043a009f080c010b200341053a009f080b201a412041c0001028221a450d24201a20032d009f083a00202003201a360260200342c080808090043702640b200341a0036a410472200341e0006a10c6032003280264211a200341c0046a412020032802602206200328026810030240201a450d00200610290b20021029200342e4cab5fbb6ccdcb0e3003703900720034190076a200341d0066a427f10a601200341a0036a41086a41083a0000200341a9036a20032903d006370000200341b1036a200341d0066a41086a290300370000200341b9036a200341d0066a41106a290300370000200341c1036a200341d0066a41186a290300370000200341c9036a2003290320370000200341d1036a200341206a41086a290300370000200341d9036a200341206a41106a290300370000200341e1036a200341206a41186a290300370000200341053a00a0034100211a41b8d6c5004100200341a0036a108801410121150c470b2002411a6a2901002107200241196a2d00002116200241186a2d00002108200241166a2f01002109200241156a2d0000210a200241146a2d0000210b200241126a2f0100210c200241116a2d0000210d200241106a2d0000210e2002410e6a2f0100210f2002410d6a2d00002110200241046a2d00002111200241026a2f01002112024002400240024020022d0000450d002003200737028402200320163a008302200320083a008202200320093b018002410121020c010b2002410c6a2d000021142002410a6a2f01002106200241096a2d00002115200241086a2d00002113200241066a2f01002117200241056a2d0000211820022d0001211a200320073703800241012102201a41ff01714101460d010b41d588c300211a41002106412a2115410021140c010b2017410874201872201341187472211a410021020b200641ffff0371410874201541ff017172201441187472211420020d45200320073703b007200320163a00af07200320083a00ae07200320093b01ac072003200a3a00ab072003200b3a00aa072003200c3b01a8072003200d3a00a7072003200e3a00a6072003200f3b01a407200320103a00a3072003201436009f072003201a36009b07200320113a009a07200320123b019807411510272202450d23410d21142002410d6a41002900bbd143370000200241086a41002900b6d143370000200241002900aed14337000020024115413510282202450d2420022003290398073700152002412d6a20034198076a41186a290300370000200241256a20034198076a41106a2903003700002002411d6a20034198076a41086a29030037000020034180026a41186a221a420037030020034180026a41106a2206420037030020034180026a41086a2215420037030020034200370380022002413520034180026a1000200341c0046a41186a201a290300370300200341c0046a41106a2006290300370300200341c0046a41086a201529030037030020032003290380023703c004200341c0046a412041b8d6c50041004100100b211a200210290240201a417f470d0041b29dc400211a410121150c470b411510272202450d252002410d6a41002900bbd143370000200241086a41002900b6d143370000200241002900aed14337000020024115413510282202450d2620022003290398073700152002412d6a20034198076a41186a290300370000200241256a20034198076a41106a2903003700002002411d6a20034198076a41086a29030037000020034180026a41186a221a420037030020034180026a41106a2214420037030020034180026a41086a2206420037030020034200370380022002413520034180026a1000200341c0046a41186a201a290300370300200341c0046a41106a2014290300370300200341c0046a41086a200629030037030020032003290380023703c004200341003602a003200341c0046a4120200341a0036a1005211a20032802a0032214417f460d29201a450d29200320143602cc052003201a3602c805200341a0036a200341c8056a10fc0220032d00c10322064102460d27200341e0006a41086a200341ca036a290100370300200341e0006a41106a200341d2036a290100370300200341e0006a41186a200341da036a29010037030020034180026a41086a200341eb036a29000037030020034180026a41106a200341f3036a29000037030020034180026a41186a200341fb036a290000370300200320032901c2033703602003200341e3036a29000037038002200341e2036a2d0000211520032c00c003211602402014450d00201a10290b200341c0046a4120100c0c2a0b41204101102a000b418f89c3004133104e000b201a4108102a000b418f89c3004133104e000b41174101102a000b41374101102a000b20062014103e000b20062014103e000b41174101102a000b412e4101102a000b410f4101102a000b412f4101102a000b410f4101102a000b412f4101102a000b41204101102a000b410f4101102a000b412f4101102a000b410f4101102a000b412f4101102a000b41154101102a000b41354101102a000b418f89c3004133104e000b418f89c3004133104e000b41204101102a000b41354101102a000b418f89c3004133104e000b419bffc400419f01104e000b41204101102a000b41c0004101102a000b41c0004101102a000b20164101102a000b20094101102a000b41204101102a000b41204101102a000b41c0004101102a000b41154101102a000b41354101102a000b41154101102a000b41354101102a000b418f89c3004133104e000b200a4101102a000b41022106410021160b200341d8076a41186a2208200341e0006a41186a290300370300200341d8076a41106a2209200341e0006a41106a290300370300200341d8076a41086a220a200341e0006a41086a290300370300200341b8076a41086a221a20034180026a41086a290300370300200341b8076a41106a220b20034180026a41106a290300370300200341b8076a41186a220c20034180026a41186a290300370300200320032903603703d80720032003290380023703b8072002102941002114024020064102460d00200341c8056a41086a200a290300370300200341c8056a41106a2009290300370300200341c8056a41186a2008290300370300200341f8076a41086a201a290300370300200341f8076a41106a200b290300370300200341f8076a41186a200c290300370300200320032903d8073703c805200320032903b8073703f8074100210202400240024002400240024002400240024002400240201541ff01714101470d00411510272202450d012002410d6a41002900bbd143370000200241086a41002900b6d143370000200241002900aed14337000020024115413510282202450d02200220032903f8073700152002412d6a20034190086a290300370000200241256a20034188086a2903003700002002411d6a200341f8076a41086a2903003700000b0240024020064101470d00411510272214450d042014410d6a41002900bbd143370000201441086a41002900b6d143370000201441002900aed14337000020144115413510282214450d05201420032903c8053700152014412d6a200341c8056a41186a290300370000201441256a200341c8056a41106a2903003700002014411d6a200341c8056a41086a29030037000020034180026a41186a2208420037030020034180026a41106a2209420037030020034180026a41086a220a420037030020034200370380022014413520034180026a1000200341c0046a41186a2008290300370300200341c0046a41106a2009290300370300200341c0046a41086a200a29030037030020032003290380023703c004200341003602a003200341c0046a4120200341a0036a1005210b024020032802a003220c417f460d00200b0d020b41e0a3c40041d300104e000b20034180026a41186a2214420037030020034180026a41106a2208420037030020034180026a41086a220942003703002003420037038002419ad2c300411d20034180026a1000200341c0046a41186a2014290300370300200341c0046a41106a2008290300370300200341c0046a41086a200929030037030020032003290380023703c0040240201541ff01714101460d00200341c0046a4120100c0c0a0b412010272214450d05201420032903f807370000201441186a200341f8076a41186a290300370000201441106a200341f8076a41106a290300370000201441086a200341f8076a41086a290300370000200341c0046a4120201441201003201410290c090b2003200c3602f4062003200b3602f006200341a0036a200341f0066a10fc0220032d00c103220d4102460d0520034180026a41206a220e200341a0036a41206a220f2d00003a000020034180026a41186a2208200341a0036a41186a221029030037030020034180026a41106a2209200341a0036a41106a221129030037030020034180026a41086a220a200341a0036a41086a2212290300370300200320032903a00337038002200341e0006a200341c2036a221341c10010ce041a0240200c450d00200b10290b201320032900603701002012200a2903003703002011200929030037030020102008290300370300200f200e2d00003a0000200341ca036a200341e0006a41086a290000370100200341d2036a200341e0006a41106a290000370100200341da036a200341e0006a41186a29000037010020032003290380023703a0032003200d3a00c103200341e2036a20153a0000200341e3036a20032903f807370000200341eb036a200341f8076a41086a290300370000200341f3036a200341f8076a41106a290300370000200341fb036a200341f8076a41186a2903003700002008420037030020094200370300200a420037030020034200370380022014413520034180026a1000200341c0046a41186a2008290300370300200341c0046a41106a2009290300370300200341c0046a41086a200a29030037030020032003290380023703c0042003410036026820034201370360412010272215450d06201520032903a003370000201541086a200341a0036a41086a290300370000201541106a200341a0036a41106a290300370000201541186a200341a0036a41186a290300370000200342a0808080800437026420032015360260024020032d00c003220841054b0d00024002400240024002400240024020080e06000102030405000b410021080c050b410121080c040b410221080c030b410321080c020b410421080c010b410521080b200320083a0080022015412041c00010282215450d08201520083a0020200342c08080809004370264200320153602600b200341c1036a200341e0006a10c60320032802642115200341c0046a4120200328026022082003280268100302402015450d00200810290b201410294101210b0c090b41154101102a000b41354101102a000b41154101102a000b41354101102a000b41204101102a000b418f89c3004133104e000b41204101102a000b41c0004101102a000b410021144100210b0b0240024002400240024002400240024020020d00410021060c010b20034180026a41186a2215420037030020034180026a41106a2208420037030020034180026a41086a2209420037030020034200370380022002413520034180026a1000200341c0046a41186a2015290300370300200341c0046a41106a2008290300370300200341c0046a41086a200929030037030020032003290380023703c004200341003602a003200341c0046a4120200341a0036a1005210a20032802a003220c417f460d02200a450d022003200c3602f4062003200a3602f006200341a0036a200341f0066a10fc0220032d00c1034102460d0120034180026a41206a220d200341a0036a41206a220e2d00003a000020034180026a41186a2215200341a0036a41186a220f29030037030020034180026a41106a2208200341a0036a41106a221029030037030020034180026a41086a2209200341a0036a41086a2211290300370300200320032903a00337038002200341e0006a200341c2036a221241c10010ce041a0240200c450d00200a10290b2011200929030037030020102008290300370300200f2015290300370300200e200d2d00003a000020032003290380023703a0032012200341e0006a41c10010ce0420032903c805370100200341ca036a200341c8056a41086a290300370100200341d2036a200341c8056a41106a290300370100200341da036a200341c8056a41186a290300370100200320063a00c10320154200370300200842003703002009420037030020034200370380022002413520034180026a1000200341c0046a41186a2015290300370300200341c0046a41106a2008290300370300200341c0046a41086a200929030037030020032003290380023703c0042003410036026820034201370360412010272206450d03200620032903a003370000200641086a200341a0036a41086a290300370000200641106a200341a0036a41106a290300370000200641186a200341a0036a41186a290300370000200342a0808080800437026420032006360260024020032d00c003221541054b0d00024002400240024002400240024020150e06000102030405000b410021150c050b410121150c040b410221150c030b410321150c020b410421150c010b410521150b200320153a0080022006412041c00010282206450d05200620153a0020200342c08080809004370264200320063602600b200341c1036a200341e0006a10c60320032802642106200341c0046a4120200328026022152003280268100302402006450d00201510290b20021029410121060b200b20144572450d040c050b418f89c3004133104e000b41e0a3c40041d300104e000b41204101102a000b41c0004101102a000b201410290b02402002452006720d00200210290b201621140b42002107201a4200370300200342003703b80741888dc300410d200341b8076a1004200341f0066a41086a201a290300370300200320032903b8073703f006200341003602a003200341f0066a4110200341a0036a1005211a0240024020032802a0032202417f460d00200342003703a003200341a0036a201a2002410820024108491b10ce041a200241074d0d0120032903a0032107201a10290b200342e4cab5fbb6ccdcb0e300370360200341e0006a20034198076a427f427f2014410274419886c5006a3502004280af1a7e20077c410210a801200341a0036a41086a41093a0000200341a0036a41096a200329039807370000200341b1036a20034198076a41086a290300370000200341b9036a200341a8076a290300370000200341c1036a200341b0076a290300370000200341053a00a0034100211a41b8d6c5004100200341a0036a108801410121150c1c0b418f89c3004133104e000b41ad88c300211a412821140c1a0b41e39cc400211a412621142007a7450d19200b10290c190b200341a0036a41186a200341f8076a41186a290300370300200341a0036a41106a200341f8076a41106a290300370300200341a0036a41086a200341f8076a41086a290300370300200320032903f8073703a00302400240024002400240024020022007422088a722144b0d00024020142007a7470d00201441016a221a2014490d1020144101742206201a201a2006491b221a41ffffff3f71201a470d10201a41057422064100480d100240024020140d0020061027210b0c010b200b201441057420061028210b0b200b450d02201aad21070b200b20024105746a221a41206a201a201420026b41057410cf041a201a41186a200341a0036a41186a290300370000201a41106a200341a0036a41106a290300370000201a41086a200341a0036a41086a290300370000201a20032903a003370000200341b8076a41086a22024200370300200342003703b80741888dc300410d200341b8076a1004200341f0066a41086a2002290300370300200320032903b8073703f006200341003602a003200341f0066a4110200341a0036a100521020240024020032802a003221a417f460d002002450d00200342003703a003200341a0036a2002201a4108201a4108491b10ce041a201a41074d0d0420032903a00321042002102920044280af1a7c21040c010b4280af1a21040b411310272202450d032002410f6a41002800bb9c44360000200241086a41002900b49c44370000200241002900ac9c443700002002411341331028220c450d04200c20032903d807370013200c412b6a200341d8076a41186a290300370000200c41236a200341d8076a41106a290300370000200c411b6a200341d8076a41086a29030037000020034180026a41186a2202420037030020034180026a41106a221a420037030020034180026a41086a220642003703002003420037038002200c413320034180026a1000200341c0046a41186a2002290300370300200341c0046a41106a201a290300370300200341c0046a41086a200629030037030020032003290380023703c004200341003602a803200342013703a003410810272202450d05200220043700002003428880808080013702a403200320023602a0032003201441016a2202360260200341e0006a200341a0036a103002400240024020020d0020032802a803211a20032802a403211620032802a00321080c010b410020032802a803221a6b2106201441057441206a210920032802a003210820032802a4032116200b210203400240201620066a411f4b0d00201a41206a2214201a490d132016410174220a20142014200a491b22144100480d130240024020160d002014102721080c010b200820162014102821080b2008450d03201421160b2008201a6a22142002290000370000201441186a200241186a290000370000201441106a200241106a290000370000201441086a200241086a290000370000200641606a2106201a41206a211a200241206a2102200941606a22090d000b200320163602a4032003201a3602a803200320083602a0030b2007a72102200341c0046a41202008201a100302402016450d00200810290b200c102902402002450d00200b10290b200341a0036a41086a410a3a0000200341a9036a20032903f807370000200341c9036a20032903d807370000200341b1036a200341f8076a41086a290300370000200341b9036a200341f8076a41106a290300370000200341c1036a200341f8076a41186a290300370000200341d1036a200341d8076a41086a290300370000200341d9036a200341d8076a41106a290300370000200341e1036a200341d8076a41186a290300370000200341053a00a003200341f0036a20043703004100211a41b8d6c5004100200341a0036a108801200341b8076a41086a22024200370300200342003703b8074188d4c3004116200341b8076a1004200341f0066a41086a2002290300370300200320032903b8073703f006200341f0066a4110100c0c1f0b20144101102a000b41d0b1c5001058000b20064101102a000b418f89c3004133104e000b41134101102a000b41334101102a000b41084101102a000b418f89c3004133104e000b418f89c3004133104e000b200341003602a803200342013703a003200341e0006a200341a0036a103220032802a403211a20032802a803211420032802a003210220034180026a41186a2206420037030020034180026a41106a2216420037030020034180026a41086a2208420037030020034200370380022002201420034180026a1000200341a0036a41186a2006290300370300200341a0036a41106a2016290300370300200341a0036a41086a200829030037030020032003290380023703a0030240201a450d00200210290b0240200341f8076a200341a0036a412010d004450d0041e69bc400211a410c21140c010b42002105200341b8076a41086a22024200370300200342003703b8074188d4c3004116200341b8076a1004200341f0066a41086a221a2002290300370300200320032903b8073703f006200341f0066a4110100c20024200370300200342003703b80741888dc300410d200341b8076a1004201a2002290300370300200320032903b8073703f006200341003602a003200341f0066a4110200341a0036a1005211a024020032802a0032202417f460d00200342003703a003200341a0036a201a2002410820024108491b10ce041a200241074d0d0220032903a0032105201a10290b200341a0036a200341e0006a41880110ce041a20034180026a2005200742c0d102200742c0d102561b7c200341a0036a4102200410b50302402003280280024101470d00200328028402221a450d0020034188026a28020021140c160b4100211a0c150b200341e0006a103d0c140b418f89c3004133104e000b419c9cc400211a411021140c120b200341003602a803200342013703a0032006200341a0036a103220032802a403211a20032802a803211420032802a003210220034180026a41186a2215420037030020034180026a41106a2216420037030020034180026a41086a2208420037030020034200370380022002201420034180026a1000200341e0006a41186a22142015290300370300200341e0006a41106a2016290300370300200341e0006a41086a200829030037030020032003290380023703600240201a450d00200210290b200341a0036a41186a2014290300370300200341a0036a41106a200341e0006a41106a290300370300200341a0036a41086a200341e0006a41086a290300370300200320032903603703a00320034180026a200341a0036a10c503024002400240200328028802221a450d00200329038002210442002107200341b8076a41086a22024200370300200342003703b80741888dc300410d200341b8076a1004200341f0066a41086a2002290300370300200320032903b8073703f006200341003602a003200341f0066a4110200341a0036a10052102024020032802a0032214417f460d002002450d00200342003703a003200341a0036a20022014410820144108491b10ce041a201441074d0d0220032903a0032107200210290b02402003418c026a280200450d00201a10290b200720045a0d0041b79bc400211a411a21140c030b200341a0036a200641880110cf041a200341023a00a804200341b8076a41086a22024200370300200342003703b8074188d4c3004116200341b8076a1004200341f0066a41086a2002290300370300200320032903b8073703f00620034100360288022003420137038002200341a0036a20034180026a1032024020032d00a804220241024b0d00024002400240024020020e03000102000b4100211a0c020b4101211a0c010b4102211a0b2003201a3a009f08024002402003280284022003280288022202460d0020032802800221140c010b200241016a221a2002490d0620024101742214201a201a2014491b221a4100480d060240024020020d00201a102721140c010b2003280280022002201a102821140b2014450d032003201a36028402200320143602800220032d009f08211a20032802880221020b2003200241016a36028802201420026a201a3a00000b2003280284022102200341f0066a4110200328028002221a200328028802100302402002450d00201a10290b200341a0036a103d200610294100210841012115410121060c0b0b418f89c3004133104e000b201a4101102a000b2006103d200610294100210841012115410121060c110b200341003602a803200342013703a0032006200341a0036a103220032802a403211a20032802a803211420032802a003210220034180026a41186a2215420037030020034180026a41106a2216420037030020034180026a41086a2208420037030020034200370380022002201420034180026a1000200341e0006a41186a22142015290300370300200341e0006a41106a2016290300370300200341e0006a41086a200829030037030020032003290380023703600240201a450d00200210290b200341a0036a41186a2014290300370300200341a0036a41106a200341e0006a41106a290300370300200341a0036a41086a200341e0006a41086a290300370300200320032903603703a00320034180026a200341a0036a10c5030240200328028802221a450d00200329038002210442002107200341b8076a41086a22024200370300200342003703b80741888dc300410d200341b8076a1004200341f0066a41086a2002290300370300200320032903b8073703f006200341003602a003200341f0066a4110200341a0036a10052102024020032802a0032214417f460d002002450d00200342003703a003200341a0036a20022014410820144108491b10ce041a201441074d0d0320032903a0032107200210290b02402003418c026a280200450d00201a10290b200720045a0d0041b79bc400211a411a21140c040b200341a0036a200641880110cf041a200341003a00a804200341b8076a41086a22024200370300200342003703b8074188d4c3004116200341b8076a1004200341f0066a41086a2002290300370300200320032903b8073703f00620034100360288022003420137038002200341a0036a20034180026a1032024020032d00a804220241024b0d00024002400240024020020e03000102000b4100211a0c020b4101211a0c010b4102211a0b2003201a3a009f08024002402003280284022003280288022202460d0020032802800221140c010b200241016a221a2002490d0220024101742214201a201a2014491b221a4100480d020240024020020d00201a102721140c010b2003280280022002201a102821140b2014450d042003201a36028402200320143602800220032d009f08211a20032802880221020b2003200241016a36028802201420026a201a3a00000b2003280284022102200341f0066a4110200328028002221a200328028802100302402002450d00201a10290b200341a0036a103d2006102941002106410121150c060b102b000b418f89c3004133104e000b201a4101102a000b2006103d200610294100210641012115410121080c0c0b2016200341c8056a41186a2903003703002008200341c8056a41106a290300370300200341a0036a41086a200341c8056a41086a290300370300200320032903c8053703a003200341013a00f80702400240411710272202450d004100211a2002410f6a41002900af9b44370000200241086a41002900a89b44370000200241002900a09b4437000020024117413710282202450d01200220032903a0033700172002412f6a200341a0036a41186a290300370000200241276a200341a0036a41106a2903003700002002411f6a200341a0036a41086a29030037000020034180026a41186a2206420037030020034180026a41106a2215420037030020034180026a41086a2216420037030020034200370380022002413720034180026a1000200341c0046a41186a2006290300370300200341c0046a41106a2015290300370300200341c0046a41086a201629030037030020032003290380023703c00441012115200341c0046a4120200341f8076a4101100320021029200a10ab032014103d0c090b41174101102a000b41374101102a000b201510294101210641002115410121080c0a0b410121080b410121164100211a0c0a0b41959bc400211a410b2114410121150c060b41d588c300211a412a2114410121150c050b2002201a4105746a22142003290340370000201441186a200341c0006a41186a290300370000201441106a2015290300370000201441086a200929030037000041012115200341a0036a41186a201a41016a360200200341b4036a2008360200200320073703a803200320043703a003200320163602bc03200320023602b003200a200341a0036a10c2030b4100211a0b4101210641012108410121160c050b41fb9ac400211a411a21142006450d0020021029410121150c010b410121150b41012106410121080b410121160c010b2006103d20061029410021164101211541012106410121080b0240024020012d0000417f6a2202410f4b0d00024002400240024020020e1000040404010402030404040405040505000b2016450d04200141046a2202280200103d200228020010290c040b2015450d03200141046a2202280200103d200228020010290c030b2006450d02200141046a2202280200103d200228020010290c020b2008450d01200141046a2202280200103d200228020010290c010b200241074b0d00024002400240024020020e080004040401040203000b200141046a2202280200103d200228020010290c030b200141046a2202280200103d200228020010290c020b200141046a2202280200103d200228020010290c010b200141046a2202280200103d200228020010290b200020143602042000201a360200200341a0086a24000bd75d02157f037e230041d0036b2203240002400240024002400240024002400240024002400240024002400240024002400240024020012d000022040e0500010d0302000b200341b4026a4101360200200342013702a402200341ccfdc4003602a00220034102360274200341c4fdc4003602702003200341f0006a3602b002200341a0026a41bce4c2001057000b200141086a2802002105200141046a2802002106024020022d000120022d000072450d0041ad88c300210741282108410021094101210a02402005450d00200610290b4101210b0c100b2001410c6a280200210c200341a0026a41086a22024200370300200342003703a00241d692c200411b200341a0026a1004200341f0006a41086a2002290300370300200320032903a002370370200341003602a002200341f0006a4110200341a0026a1005210202400240024020032802a0022207417f460d002002450d00200320073602fc01200320023602f801200341a0026a200341f8016a102d20032802a002220d450d02200341a8026a280200210a20032802a402210e2007450d01200210290c010b4101210d4100210a4100210e0b200d200a1094022006200c109402200d4100200a1b210920064100200c1b2108200d41206a200d200a1b2107200641206a2006200c1b21022006200c4105746a210f200d200a4105746a2110410021114100211241012113410021144100211541012116034002400240024002400240024002402009450d0003402008450d02024020092008460d0020092008412010d004220a0d040b410020072007201046220a1b2109410020022002200f46220b1b21082007200741206a200a1b21072002200241206a200b1b210220090d000b0b4100210920080d04201320112006200c10ba0102402012450d00201310290b02402015450d00201610290b02402005450d00200610290b4101210a200e450d16200d10290c160b200341a0026a41186a220a200941186a290000370300200341a0026a41106a220b200941106a290000370300200341a0026a41086a2217200941086a290000370300200320092900003703a002024020122011470d00201141016a22082011490d0a20114101742209200820082009491b221241ffffff3f712012470d0a201241057422084100480d0a0240024020110d002008102721130c010b201320114105742008102821130b2013450d020b201320114105746a220820032903a002370000200841186a200a290300370000200841106a200b290300370000200841086a20172903003700002007200741206a200720104622091b210a410021084100200720091b21090c040b200a417f4a0d02200341a0026a41186a220a200941186a290000370300200341a0026a41106a220b200941106a290000370300200341a0026a41086a2217200941086a290000370300200320092900003703a002024020122011470d00201141016a22092011490d0920114101742212200920092012491b221241ffffff3f712012470d09201241057422094100480d090240024020110d002009102721130c010b201320114105742009102821130b2013450d020b201320114105746a220920032903a002370000200941186a200a290300370000200941106a200b290300370000200941086a20172903003700002007200741206a200720104622091b210a4100200720091b21090c030b20084101102a000b20094101102a000b200341a0026a41186a220a200841186a290000370300200341a0026a41106a220b200841106a290000370300200341a0026a41086a2217200841086a290000370300200320082900003703a0020240024020152014470d00201441016a22082014490d0720144101742215200820082015491b221541ffffff3f712015470d07201541057422084100480d070240024020140d002008102721160c010b201620144105742008102821160b2016450d010b201620144105746a220820032903a002370000200841186a200a290300370000200841106a200b290300370000200841086a2017290300370000410020022002200f46220a1b2108201441016a21142002200241206a200a1b21020c020b20084101102a000b201141016a2111200a21070c000b0b418f89c3004133104e000b200141216a2d0000210e200141246a2802002105200341306a41186a200141196a290000370300200341306a41106a200141116a290000370300200341306a41086a200141096a290000370300200320012900013703302002411a6a2901002118200241196a2d0000210f200241186a2d00002110200241166a2f01002114200241156a2d00002111200241146a2d00002115200241126a2f01002116200241116a2d00002117200241106a2d000021122002410e6a2f010021132002410d6a2d00002106200241046a2d0000210d200241026a2f0100210c41d588c3002107412a21080240024020022d0000450d00410121094100210a4100210b0c010b410121094100210a4100210b20022d00014101470d002002410c6a2d0000210b2002410a6a2f0100210a200241096a2d00002108200241066a2f0100410874200241056a2d000072200241086a2d0000411874722107410021090b200a41ffff0371410874200841ff017172200b411874722108024020090d00200320183703682003200f3a0067200320103a0066200320143b0164200320113a0063200320153a0062200320163b0160200320173a005f200320123a005e200320133b015c200320063a005b20032008360057200320073600532003200d3a00522003200c3b0150200341a0026a41086a22024200370300200342003703a00241d692c200411b200341a0026a1004200341f0006a41086a2002290300370300200320032903a002370370200341003602a002200341f0006a4110200341a0026a10052102024002400240024020032802a0022207417f460d002002450d00200320073602fc01200320023602f801200341a0026a200341f8016a102d20032802a0022208450d02200341a8026a280200210920032802a402210a02402007450d00200210290b20082009200341d0006a10f90221020240200a450d00200810290b2002450d010c030b41014100200341d0006a10f9020d020b41d2e5c2002107411221080c020b418f89c3004133104e000b200341a0026a200341306a10f202024020032802a80222100d0041bfe5c2002107411321080c010b200341b8026a2802002111200341b4026a28020021144110210820032802ac02210b41e4e5c20021070240200520032802a0022217470d00200341bc026a280200210f20032802a40221122010200341a0026a41106a28020022154105746a2109201021024100210802400240024003400240200920026b41e0004b0d0020022009470d02410021160c040b200341d0006a2002460d0220082002200341d0006a412010d00422074100476a21082007450d02200241206a2207200341d0006a460d0220082007200341d0006a412010d00422074100476a21082007450d02200241c0006a2207200341d0006a460d0220082007200341d0006a412010d00422074100476a21082007450d02200241e0006a2207200341d0006a460d0220024180016a210220082007200341d0006a412010d00422074100476a210820070d000c020b0b201020154105746a21090340200341d0006a2002460d0120082002200341d0006a412010d00422074100476a21082007450d01410021162009200241206a2202470d000c020b0b410121160b2014200f4105746a210a201421024100210702400240024003400240200a20026b41e0004b0d002002200a470d02410021090c040b200341d0006a2002460d0220072002200341d0006a412010d00422094100476a21072009450d02200241206a2209200341d0006a460d0220072009200341d0006a412010d00422094100476a21072009450d02200241c0006a2209200341d0006a460d0220072009200341d0006a412010d00422094100476a21072009450d02200241e0006a2209200341d0006a460d0220024180016a210220072009200341d0006a412010d00422094100476a210720090d000c020b0b0340200341d0006a2002460d0120072002200341d0006a412010d00422094100476a21072009450d0141002109200a200241206a2202470d000c020b0b410121090b024002400240024002400240024002400240200e41ff01710d002009450d010c080b20160d07200341a0026a41186a2208200341d0006a41186a290300370300200341a0026a41106a220a200341d0006a41106a290300370300200341a0026a41086a2213200341d0006a41086a290300370300200320032903503703a0020240200b2015460d00200b21160c020b200b41016a2202200b490d0b200b4101742216200220022016491b221641ffffff3f712016470d0b201641057422024100480d0b02400240200b0d002002102721100c010b2010200b4105742002102821100b20100d0120024101102a000b200341a0026a41186a2209200341d0006a41186a290300370300200341a0026a41106a220a200341d0006a41106a290300370300200341a0026a41086a2213200341d0006a41086a290300370300200320032903503703a002024002402011200f460d00201121070c010b201141016a22022011490d0b20114101742207200220022007491b220741ffffff3f712007470d0b200741057422024100480d0b0240024020110d002002102721140c010b201420114105742002102821140b20140d0020024101102a000b2014200f4105746a220220032903a002370000200241186a2009290300370000200241106a200a290300370000200241086a2013290300370000200f41016a210f024002402016450d00201520084d0d0120102015417f6a22154105746a22022900002118200229000821192002290010211a201020084105746a220841186a200241186a2900003700002008201a37001020082019370008200820183700000b200b2116200721110c020b418ce6c200200820151037000b201020154105746a220220032903a002370000200241186a2008290300370000200241106a200a290300370000200241086a2013290300370000201541016a21152009450d00200f20074d0d012014200f417f6a220f4105746a22022900002118200229000821192002290010211a201420074105746a220741186a200241186a2900003700002007201a37001020072019370008200720183700000b200341c5026a2003290330370000200341ad026a200341d0006a41086a290300370000200341b5026a200341d0006a41106a290300370000200341bd026a200341d0006a41186a290300370000200341cd026a200341306a41086a290300370000200341d5026a200341306a41106a290300370000200341dd026a200341306a41186a290300370000200341013a00a402200341063a00a002200320032903503700a502200341ec026a200f360200200341e8026a2015360200200341e5026a200e3a000041b8d6c5004100200341a0026a108801200341a0026a41086a22024200370300200342003703a00241d692c200411b200341a0026a1004200341f0006a41086a2002290300370300200320032903a002370370200341003602a002200341f0006a4110200341a0026a1005210720032802a0022208417f460d022007450d02200320083602fc01200320073602f801200341a0026a200341f8016a102d20032802a002220a450d01200341a8026a280200210220032802a402210902402008450d00200710290b2009450d03200a10290c030b418ce6c2002007200f1037000b418f89c3004133104e000b410021020b024002400240024002400240024002400240024002400240201520124f22070d0041002002200f6b2208200820024b1b2012490d00200341bc026a200f360200200341a0026a41186a2011360200200341a0026a41106a2015360200200341ac026a2016360200200320143602b402200320103602a802200320123602a402200320173602a002411a10272202450d01200241186a41002f00cfce423b0000200241106a41002900c7ce42370000200241086a41002900bfce42370000200241002900b7ce423700002002411a413a10282202450d022002200329033037001a200241326a200341306a41186a2903003700002002412a6a200341306a41106a290300370000200241226a200341306a41086a290300370000200341f8016a41186a22074200370300200341f8016a41106a22084200370300200341f8016a41086a22094200370300200342003703f8012002413a200341f8016a1000200341a8036a41186a2007290300370300200341a8036a41106a2008290300370300200341a8036a41086a2009290300370300200320032903f8013703a803200341203602742003200341a8036a360270200341a0026a200341f0006a10db022002102902402016450d00201010290b20110d060c070b024020070d00200341ad026a200341386a290300370000200341b5026a200341c0006a290300370000200341bd026a200341c8006a290300370000200341033a00a402200341063a00a002200320032903303700a50241b8d6c5004100200341a0026a1088010c050b200341ad026a200341306a41086a290300370000200341b5026a200341306a41106a290300370000200341bd026a200341c8006a290300370000200341023a00a402200341063a00a002200320032903303700a50241b8d6c5004100200341a0026a108801411e10272207450d02200741166a4100290096e542370000200741106a4100290090e542370000200741086a4100290088e54237000020074100290080e5423700002007411e413e10282207450d032007200329033037001e200741366a200341306a41186a220b2903003700002007412e6a200341306a41106a220f290300370000200741266a200341306a41086a2215290300370000200341f8016a41186a22094200370300200341f8016a41106a220a4200370300200341f8016a41086a22084200370300200342003703f8012007413e200341f8016a1000200341a8036a41186a2009290300370300200341a8036a41106a200a290300370300200341a8036a41086a2008290300370300200320032903f8013703a803200341a0026a200341a8036a10fa02024020032802a00222094112470d00200710290c050b200341f0006a200341a0026a410472220a41840110ce041a20071029200320093602a002200a200341f0006a41840110ce041a20034184026a200236020020082012360200200341003a00fc01200341013a00f801200341286a200341a0026a200341f8016a10ad0220032802282102200341ad026a2015290300370000200341b5026a200f290300370000200341bd026a200b290300370000200341c5026a2002453a0000200341043a00a402200341063a00a002200320032903303700a50241b8d6c5004100200341a0026a1088010c040b411a4101102a000b413a4101102a000b411e4101102a000b413e4101102a000b411a10272202450d03200241186a41002f00cfce423b0000200241106a41002900c7ce42370000200241086a41002900bfce42370000200241002900b7ce423700002002411a413a10282202450d042002200329033037001a200241326a200341306a41186a2903003700002002412a6a200341306a41106a290300370000200241226a200341306a41086a290300370000200341f8016a41186a22074200370300200341f8016a41106a22084200370300200341f8016a41086a22094200370300200342003703f8012002413a200341f8016a1000200341a8036a41186a2007290300370300200341a8036a41106a2008290300370300200341a8036a41086a2009290300370300200320032903f8013703a803200341a8036a4120100c20021029200341a0026a41086a22024200370300200342003703a002419acec200411d200341a0026a1004200341f0006a41086a2002290300370300200320032903a002370370200341003602a002200341f0006a4110200341a0026a100521020240024020032802a0022207417f460d002002450d00200320073602fc01200320023602f801200341a0026a200341f8016a102d20032802a0022208450d0720032902a402211802402007450d00200210290b200320183702fc01200320083602f8010c010b2003410036028002200342013703f8010b200341f8016a200341306a1036200341a0026a41086a22024200370300200342003703a002419acec200411d200341a0026a1004200341f0006a41086a2002290300370300200320032903a002370370200341003602a802200342013703a00220032802f8012117200320032802800222023602a803200341a8036a200341a0026a10300240024020020d0020032802a802210720032802a402210a20032802a002210b0c010b2002410574210f410020032802a80222076b210920032802a002210b20032802a402210a2017210203400240200a20096a411f4b0d00200741206a22082007490d0d200a4101742215200820082015491b22084100480d0d02400240200a0d0020081027210b0c010b200b200a20081028210b0b200b450d052008210a0b200b20076a22082002290000370000200841186a200241186a290000370000200841106a200241106a290000370000200841086a200241086a290000370000200941606a2109200741206a2107200241206a2102200f41606a220f0d000b2003200a3602a402200320073602a8022003200b3602a0020b200341f0006a4110200b200710030240200a450d00200b10290b024020032802fc01450d00201710290b02402016450d00201010290b2011450d010b201410290b410021070c060b20084101102a000b411a4101102a000b413a4101102a000b418f89c3004133104e000b41f4e5c2002107411621080b0240200b450d00201010290b2011450d00201410290b4101210a4101210b410121090c0e0b200141086a2802002109200141046a280200210e2002411a6a2901002118200241196a2d00002110200241186a2d00002114200241166a2f01002111200241156a2d00002115200241146a2d00002116200241126a2f01002117200241116a2d00002112200241106a2d000021132002410e6a2f010021062002410d6a2d0000210d200241046a2d0000210c200241026a2f01002105412a210841d588c30021070240024020022d0000450d004101210a4100210b4100210f0c010b4101210a4100210b4100210f20022d00014101470d002002410c6a2d0000210b2002410a6a2f0100210f200241096a2d00002108200241066a2f0100410874200241056a2d000072200241086a2d00004118747221074100210a0b200f41ffff0371410874200b41187472200841ff0171722108200a0d0820032018370348200320103a0047200320143a0046200320113b0144200320153a0043200320163a0042200320173b0140200320123a003f200320133a003e200320063b013c2003200d3a003b20032008360037200320073600332003200c3a0032200320053b0130200341a0026a41086a22024200370300200342003703a00241d692c200411b200341a0026a1004200341f0006a41086a2002290300370300200320032903a002370370200341003602a002200341f0006a4110200341a0026a10052102024002400240024020032802a0022207417f460d002002450d00200320073602fc01200320023602f801200341a0026a200341f8016a102d20032802a0022208450d02200341a8026a280200210a20032802a402210b02402007450d00200210290b2008200a200341306a10f90221020240200b450d00200810290b2002450d010c030b41014100200341306a10f9020d020b41cce4c2002107411521080c0a0b418f89c3004133104e000b200341003602a802200342013703a0022009200341a0026a103220032802a402210720032802a802210820032802a0022102200341f8016a41186a220a4200370300200341f8016a41106a220b4200370300200341f8016a41086a220f4200370300200342003703f80120022008200341f8016a1000200341d0006a41186a2208200a290300370300200341d0006a41106a220a200b290300370300200341d0006a41086a220b200f290300370300200320032903f80137035002402007450d00200210290b200341a0026a41186a2008290300370300200341a0026a41106a200a290300370300200341a0026a41086a200b290300370300200320032903503703a002024002400240024002400240024002400240411e10272202450d00200241166a4100290096e542370000200241106a4100290090e542370000200241086a4100290088e54237000020024100290080e5423700002002411e413e10282202450d01200220032903a00237001e200241366a200341a0026a41186a2903003700002002412e6a200341a0026a41106a290300370000200241266a200341a0026a41086a290300370000200341f8016a41186a22074200370300200341f8016a41106a22084200370300200341f8016a41086a220a4200370300200342003703f8012002413e200341f8016a1000200341a8036a41186a2007290300370300200341a8036a41106a2008290300370300200341a8036a41086a200a290300370300200320032903f8013703a803200341a8036a412041b8d6c50041004100100b2107200210292007417f470d020240200e4102490d00200341206a419ee5c200412110b5012003280224211520032802202116200341186a419ee5c200412110b50120032802182107200328021c2108200341a0026a41086a22024200370300200342003703a002419ee5c2004121200341a0026a1004200341f0006a41086a220a2002290300370300200320032903a0023703702003200841016a410120071b3602a002200341f0006a4110200341a0026a4104100320024200370300200342003703a002419acec200411d200341a0026a1004200a2002290300370300200320032903a002370370200341003602a002200341f0006a4110200341a0026a1005210220032802a0022207417f460d052002450d05200320073602fc01200320023602f801200341a0026a200341f8016a102d20032802a0022211450d0420032902a402211802402007450d00200210290b200341a0026a41186a200341d0006a41186a290300370300200341a0026a41106a200341d0006a41106a290300370300200341a0026a41086a200341d0006a41086a290300370300200320032903503703a002200341a0026a21072018a72018422088a72202470d080c070b200341a0026a41086a22024200370300200342003703a00241d692c200411b200341a0026a1004200341f0006a41086a2002290300370300200320032903a00237037041002102200341003602a002200341f0006a4110200341a0026a10052108024020032802a0022207417f460d00200320073602fc01200320083602f801200341a0026a200341f8016a102d20032802a002220b450d06200341a8026a280200210220032802a402210a02402007450d00200810290b200a450d00200b10290b200341a0026a200941880110ce041a200341fc006a2002360200200341f0006a41086a4101360200200341003a0074200341013a0070200341106a200341a0026a200341f0006a10ad0220032802102102200341ad026a200341d0006a41086a290300370000200341b5026a200341e0006a290300370000200341bd026a200341e8006a290300370000200341c5026a2002453a0000200341043a00a402200341063a00a002200320032903503700a502200341a0026a21020c080b411e4101102a000b413e4101102a000b41e1e4c2002107411f21080c0e0b418f89c3004133104e000b200341a0026a41186a200341d0006a41186a290300370300200341a0026a41106a200341d0006a41106a290300370300200341a0026a41086a200341d0006a41086a290300370300200320032903503703a002420021184101211141002102200341a0026a21070c010b418f89c3004133104e000b200241016a22082002490d022002410174220a20082008200a491b220841ffffff3f712008470d022008410574220a4100480d020240024020020d00200a102721110c010b20112002410574200a102821110b2011450d032018422088a721022008ad21180b20112002410574220b6a22082007290000370000200841186a200741186a290000370000200841106a200741106a290000370000200841086a200741086a290000370000200341a0026a41086a22074200370300200342003703a002419acec200411d200341a0026a1004200341f0006a41086a2007290300370300200320032903a002370370200341003602a802200342013703a0022003200241016a22073602f801200341f8016a200341a0026a103002400240200720024f0d0020032802a802210720032802a402210b20032802a002210f0c010b410020032802a80222076b210a200b41206a211020032802a002210f20032802a402210b2011210203400240200b200a6a411f4b0d00200741206a22082007490d04200b4101742214200820082014491b22084100480d0402400240200b0d0020081027210f0c010b200f200b20081028210f0b200f450d0b2008210b0b200f20076a22082002290000370000200841186a200241186a290000370000200841106a200241106a290000370000200841086a200241086a290000370000200a41606a210a200741206a2107200241206a2102201041606a22100d000b2003200b3602a402200320073602a8022003200f3602a0020b200341f0006a4110200f200710030240200b450d00200f10290b02402018a7450d00201110290b200341f0006a41186a200341d0006a41186a290300370300200341f0006a41106a200341d0006a41106a290300370300200341f0006a41086a200341d0006a41086a29030037030020032003290350370370200341a0026a200941880110ce041a411e10272202450d03200241166a4100290096e542370000200241106a4100290090e542370000200241086a4100290088e54237000020024100290080e5423700002002411e413e10282202450d042002200329037037001e200241366a200341f0006a41186a2903003700002002412e6a200341f0006a41106a290300370000200241266a200341f0006a41086a290300370000200341f8016a41186a22074200370300200341f8016a41106a22084200370300200341f8016a41086a220a4200370300200342003703f8012002413e200341f8016a1000200341a8036a41186a2007290300370300200341a8036a41106a2008290300370300200341a8036a41086a200a290300370300200320032903f8013703a8032003410036028002200342013703f801200341a0026a200341f8016a103220032802fc012107200341a8036a412020032802f8012208200328028002100302402007450d00200810290b20021029200341a0026a103d412010272202450d0520022003290330370000200241186a200341306a41186a290300370000200241106a200341306a41106a290300370000200241086a200341306a41086a290300370000200341f0006a41186a200341d0006a41186a290300370300200341f0006a41106a200341d0006a41106a290300370300200341f0006a41086a200341d0006a41086a29030037030020032003290350370370200341bc026a4100360200200341ac026a428180808010370200200342013702b402200320023602a8022003200e3602a40220032015410020161b22083602a002411a10272207450d06200741186a41002f00cfce423b0000200741106a41002900c7ce42370000200741086a41002900bfce42370000200741002900b7ce423700002007411a413a10282207450d072007200329037037001a200741326a200341f0006a41186a2903003700002007412a6a200341f0006a41106a290300370000200741226a200341f0006a41086a290300370000200341f8016a41186a220a4200370300200341f8016a41106a220b4200370300200341f8016a41086a220f4200370300200342003703f8012007413a200341f8016a1000200341a8036a41186a200a290300370300200341a8036a41106a200b290300370300200341a8036a41086a200f290300370300200320032903f8013703a803200341203602fc012003200341a8036a3602f801200341a0026a200341f8016a10db022007102920021029200341ad026a200341306a41086a290300370000200341b5026a200341306a41106a290300370000200341bd026a200341306a41186a290300370000200341c5026a2003290350370000200341cd026a200341d0006a41086a290300370000200341d5026a200341d0006a41106a290300370000200341dd026a200341d0006a41186a290300370000200341ec026a200e360200200341e8026a2008360200200341003a00a402200341063a00a002200320032903303700a502200341a0026a21020b4100210b41b8d6c50041002002108801200910294101210a0c0a0b102b000b200a4101102a000b411e4101102a000b413e4101102a000b41204101102a000b411a4101102a000b413a4101102a000b20084101102a000b2009103d200910294100210b4101210a410121090c040b200141046a280200210941d588c3002107412a210820022d00000d0120022d00014101470d01200241196a2d00002107200241186a2d00002108200241166a2f0100210a200241156a2d0000210b200241146a2d0000210f200241126a2f01002110200241116a2d00002114200241106a2d000021112002410e6a2f010021152002410d6a2d000021162002410c6a2d000021172002410a6a2f01002112200241096a2d00002113200241086a2d00002106200241066a2f0100210d200241056a2d0000210c200241046a2d00002105200241026a2f0100210e20032002411a6a290100370368200320073a0067200320083a00662003200a3b01642003200b3a00632003200f3a0062200320103b0160200320143a005f200320113a005e200320153b015c200320163a005b200320053a00522003200e3b0150200320132012410874201741187472723600572003200c200d41087472200641187472360053200341a0026a41086a22024200370300200342003703a00241d692c200411b200341a0026a1004200341f0006a41086a2002290300370300200320032903a002370370200341003602a002200341f0006a4110200341a0026a10052107024002400240024020032802a0022202417f460d00200320023602fc01200320073602f801200341a0026a200341f8016a102d20032802a0022208450d02200341a8026a280200210a20032802a402210b02402002450d00200710290b2008200a200341d0006a10f90221020240200b450d00200810290b2002450d010c030b41014100200341d0006a10f9020d020b41cce4c2002107411521080c030b418f89c3004133104e000b4100210a200341003602a802200342013703a0022009200341a0026a103220032802a402210720032802a802210820032802a0022102200341f8016a41186a220b4200370300200341f8016a41106a220f4200370300200341f8016a41086a22104200370300200342003703f80120022008200341f8016a1000200341a8036a41186a2208200b290300370300200341a8036a41106a2214200f290300370300200341a8036a41086a220f2010290300370300200320032903f8013703a80302402007450d00200210290b200341a0026a200941880110ce041a200341f0006a410d6a200341d0006a41086a290300370000200341f0006a41156a200341d0006a41106a290300370000200341f0006a411d6a200341d0006a41186a2903003700004101210b200341013a007420032003290350370075200341013a0070200341086a200341a0026a200341f0006a10ad0220032802082102200341a0026a410d6a200f290300370000200341a0026a41156a2014290300370000200341a0026a411d6a2008290300370000200341c5026a2002453a0000200341053a00a402200341063a00a002200320032903a8033700a50241b8d6c5004100200341a0026a108801200910290b41012109410021070c020b2009103d200910294101210b4100210a410121090c010b410021094101210b410021070b02402004410771417f6a220241024b0d0002400240024020020e03000102000b2009450d02200141086a280200450d02200141046a28020010290c020b200a450d01200141046a2802002202103d200210290c010b200b450d00200141086a2802002202103d200210290b2000200836020420002007360200200341d0036a24000b9a6f03197f077e017f23002203210420034180046b4160712205240002400240024002400240024002400240024002400240024002400240024002400240024020012d000022060e0500010d0302000b200541d4026a4101360200200542013702c402200541ccfdc4003602c0022005410236028401200541c4fdc40036028001200520054180016a3602d002200541c0026a41bce4c2001057000b200141086a2802002107200141046a2802002108024020022d000120022d000072450d0041ad88c3002103412821094100210a4101210b02402007450d00200810290b4101210c0c100b2001410c6a280200210d20054180016a41086a22024200370300200542003703800141f192c200411b20054180016a1004200541c0026a41086a200229030037030020052005290380013703c0022005410036028001200541c0026a411020054180016a100521020240024002402005280280012203417f460d002002450d002005200336029c02200520023602980220054180016a20054198026a102d200528028001220e450d0220054188016a280200210b200528028401210f2003450d01200210290c010b4101210e4100210b4100210f0b200e200b1094022008200d109402200e4100200b1b210a20084100200d1b2109200e41206a200e200b1b2103200841206a2008200d1b21022008200d4105746a2110200e200b4105746a211141002112410021134100211441012115410021164100211741012118034002400240024002400240024002400240024002400240024002400240200a450d0003402009450d020240200a2009460d00200a2009412010d004220b0d040b410020032003201146220b1b210a410020022002201046220c1b21092003200341206a200b1b21032002200241206a200c1b2102200a0d000b0b4100210a20090d0b201341ffffff3f712013470d0220134105742202417f4c0d020240024020020d00410121090c010b200210272209450d040b410021034100210202402013450d00416020156b210a2009210220152103034020022003290000370000200241186a200341186a290000370000200241106a200341106a290000370000200241086a200341086a290000370000200241206a2102200341206a2103201241606a22120d000b201520134105746a200a6a41057641016a2102201321030b20052002360248200520033602442005200936024020092002410041202002676b10e00120054180016a41086a22024200370300200542003703800141e8e6c200411d20054180016a1004200541c0026a41086a200229030037030020052005290380013703c0022005410036028001200541c0026a411020054180016a10052102024002402005280280012209417f460d002002450d002005200936029c02200520023602980220054180016a20054198026a102d2005280280012219450d0620054188016a2802002103200528028401211a2009450d01200210290c010b41012119410021034100211a0b024020034105742210450d00200541c0026a4114722112200541c0026a410872211b201921030340200541e0006a41186a2211200341186a290000370300200541e0006a41106a2216200341106a290000370300200541e0006a41086a2213200341086a2900003703002005200329000037036020054180016a200541e0006a10fb02200541003602c802200529039801211c200520052903d802221d37039801200529039001211e200520052903d002221f370390012005290380012120200520052903c002370380012005290388012121200520052903c802222237038801201f422088a7210c2022422088a7210a201da7210b2022a7210902402021a72202450d00200520203703c002200520213703c8022005201e3703d0022005201c3703d80220052002201ea74105746a3602a402200520023602a00220052021422088a736029c0220052002360298022005200541c0006a3602a802200541d8036a20054198026a104b201b41086a200541d8036a41086a2223280200360200201b20052903d8033702002005201e422088a72202201c422088a74105746a3602a402200520023602a0022005201ca736029c0220052002360298022005200541c0006a3602a802200541d8036a20054198026a104b201241086a2023280200360200201220052903d80337020020052903c802212120052903c002211e20052903d802212220052903d002211c02402009450d000240200a450d00200910290b200b450d00200c10290b2005201e3703800120052021370388012021422088a7210a2005201c37039001201c422088a7210c20052022370398012021a721092022a7210b0b411a102721020240024020090d002002450d09200241186a41002f009de7423b0000200241106a4100290095e742370000200241086a410029008de74237000020024100290085e7423700002002411a413a10282202450d0a2002200529036037001a200241326a20112903003700002002412a6a2016290300370000200241226a201329030037000020054198026a41186a2209420037030020054198026a41106a220a420037030020054198026a41086a220b420037030020054200370398022002413a20054198026a1000200541d8036a41186a2009290300370300200541d8036a41106a200a290300370300200541d8036a41086a200b29030037030020052005290398023703d803200541d8036a4120100c200210290c010b2002450d0a200241186a41002f009de7423b0000200241106a4100290095e742370000200241086a410029008de74237000020024100290085e7423700002002411a413a10282202450d0b2002200529036037001a200241326a20112903003700002002412a6a2016290300370000200241226a201329030037000020054198026a41186a2211420037030020054198026a41106a2216420037030020054198026a41086a2213420037030020054200370398022002413a20054198026a1000200541d8036a41186a2011290300370300200541d8036a41106a2016290300370300200541d8036a41086a201329030037030020052005290398023703d803200541203602c4022005200541d8036a3602c00220054180016a200541c0026a10db02200210290240200a450d00200910290b200b450d00200c10290b200341206a2103201041606a22100d000b0b0240201a450d00201910290b200541003602c802200542013703c0022005200d3602800120054180016a200541c0026a10300240024002400240200d0d0020052802c802210320052802c402210b20052802c002210c0c010b200d4105742110410020052802c80222036b210a20052802c002210c20052802c402210b2008210203400240200b200a6a411f4b0d00200341206a22092003490d16200b4101742211200920092011491b22094100480d1602400240200b0d0020091027210c0c010b200c200b20091028210c0b200c450d032009210b0b200c20036a22092002290000370000200941186a200241186a290000370000200941106a200241106a290000370000200941086a200241086a290000370000200a41606a210a200341206a2103200241206a2102201041606a22100d000b2005200b3602c402200520033602c8022005200c3602c0020b20054180016a41086a22024200370300200542003703800141f192c200411b20054180016a1004200541c0026a41086a200229030037030020052005290380013703c002200541c0026a4110200c200310030240200b450d00200c10290b02402005280244450d00200528024010290b02402014450d00201510290b02402017450d00201810290b02402007450d00200810290b4101210b200f0d010c1f0b20094101102a000b200e10290c1d0b200541c0026a41186a220b200a41186a290000370300200541c0026a41106a220c200a41106a290000370300200541c0026a41086a221b200a41086a2900003703002005200a2900003703c002024020142013470d00201341016a22092013490d112013410174220a20092009200a491b221441ffffff3f712014470d11201441057422094100480d110240024020130d002009102721150c010b201520134105742009102821150b2015450d090b201520134105746a220920052903c002370000200941186a200b290300370000200941106a200c290300370000200941086a201b2903003700002003200341206a2003201146220a1b210b4100210941002003200a1b210a0c0b0b200b417f4a0d09200541c0026a41186a220b200a41186a290000370300200541c0026a41106a220c200a41106a290000370300200541c0026a41086a221b200a41086a2900003703002005200a2900003703c002024020142013470d00201341016a220a2013490d1020134101742214200a200a2014491b221441ffffff3f712014470d102014410574220a4100480d100240024020130d00200a102721150c010b20152013410574200a102821150b2015450d090b201520134105746a220a20052903c002370000200a41186a200b290300370000200a41106a200c290300370000200a41086a201b2903003700002003200341206a2003201146220a1b210b41002003200a1b210a0c0a0b1039000b20024101102a000b418f89c3004133104e000b411a4101102a000b413a4101102a000b411a4101102a000b413a4101102a000b20094101102a000b200a4101102a000b200541c0026a41186a220b200941186a290000370300200541c0026a41106a220c200941106a290000370300200541c0026a41086a221b200941086a290000370300200520092900003703c0020240024020172016470d00201641016a22092016490d0720164101742217200920092017491b221741ffffff3f712017470d07201741057422094100480d070240024020160d002009102721180c010b201820164105742009102821180b2018450d010b201820164105746a220920052903c002370000200941186a200b290300370000200941106a200c290300370000200941086a201b290300370000410020022002201046220b1b2109201641016a21162002200241206a200b1b21020c020b20094101102a000b201241206a2112201341016a2113200b21030c000b0b418f89c3004133104e000b200141216a2d0000210e200141246a280200210d200541c0006a41186a200141196a290000370300200541c0006a41106a200141116a290000370300200541c0006a41086a200141096a290000370300200520012900013703402002411a6a2901002121200241196a2d00002110200241186a2d00002111200241166a2f01002116200241156a2d00002113200241146a2d00002117200241126a2f01002118200241116a2d00002112200241106a2d0000211b2002410e6a2f010021142002410d6a2d00002115200241046a2d00002123200241026a2f0100210841d588c3002103412a21090240024020022d0000450d004101210a4100210b4100210c0c010b4101210a4100210b4100210c20022d00014101470d002002410c6a2d0000210c2002410a6a2f0100210b200241096a2d00002109200241066a2f0100410874200241056a2d000072200241086a2d00004118747221034100210a0b200b41ffff0371410874200941ff017172200c4118747221090240200a0d0020052021370378200520103a0077200520113a0076200520163b0174200520133a0073200520173a0072200520183b0170200520123a006f2005201b3a006e200520143b016c200520153a006b2005200936006720052003360063200520233a0062200520083b016020054180016a41086a22024200370300200542003703800141f192c200411b20054180016a1004200541c0026a41086a200229030037030020052005290380013703c0022005410036028001200541c0026a411020054180016a1005210202400240024002402005280280012203417f460d002002450d002005200336029c02200520023602980220054180016a20054198026a102d2005280280012209450d0220054188016a280200210a200528028401210b02402003450d00200210290b2009200a200541e0006a10f90221020240200b450d00200910290b2002450d010c030b41014100200541e0006a10f9020d020b41d2e5c2002103411221090c020b418f89c3004133104e000b200541c0026a200541c0006a10fb02024020052802c80222110d0041bfe5c2002103411321090c010b200541d8026a2802002113200541d4026a28020021164110210920052802cc02210c41e4e5c20021030240200d20052802c0022212470d00200541dc026a280200211020052802c402211b2011200541c0026a41106a28020022174105746a210a201121024100210902400240024003400240200a20026b41e0004b0d002002200a470d02410021180c040b200541e0006a2002460d0220092002200541e0006a412010d00422034100476a21092003450d02200241206a2203200541e0006a460d0220092003200541e0006a412010d00422034100476a21092003450d02200241c0006a2203200541e0006a460d0220092003200541e0006a412010d00422034100476a21092003450d02200241e0006a2203200541e0006a460d0220024180016a210220092003200541e0006a412010d00422034100476a210920030d000c020b0b201120174105746a210a0340200541e0006a2002460d0120092002200541e0006a412010d00422034100476a21092003450d0141002118200a200241206a2202470d000c020b0b410121180b201620104105746a210b201621024100210302400240024003400240200b20026b41e0004b0d002002200b470d024100210a0c040b200541e0006a2002460d0220032002200541e0006a412010d004220a4100476a2103200a450d02200241206a220a200541e0006a460d022003200a200541e0006a412010d004220a4100476a2103200a450d02200241c0006a220a200541e0006a460d022003200a200541e0006a412010d004220a4100476a2103200a450d02200241e0006a220a200541e0006a460d0220024180016a21022003200a200541e0006a412010d004220a4100476a2103200a0d000c020b0b0340200541e0006a2002460d0120032002200541e0006a412010d004220a4100476a2103200a450d014100210a200b200241206a2202470d000c020b0b4101210a0b024002400240024002400240024002400240200e41ff01710d00200a450d010c080b20180d07200541c0026a41186a2209200541e0006a41186a290300370300200541c0026a41106a220b200541e0006a41106a290300370300200541c0026a41086a2214200541e0006a41086a290300370300200520052903603703c0020240200c2017460d00200c21180c020b200c41016a2202200c490d0b200c4101742218200220022018491b221841ffffff3f712018470d0b201841057422024100480d0b02400240200c0d002002102721110c010b2011200c4105742002102821110b20110d0120024101102a000b200541c0026a41186a220a200541e0006a41186a290300370300200541c0026a41106a220b200541e0006a41106a290300370300200541c0026a41086a2214200541e0006a41086a290300370300200520052903603703c0020240024020132010460d00201321030c010b201341016a22022013490d0b20134101742203200220022003491b220341ffffff3f712003470d0b200341057422024100480d0b0240024020130d002002102721160c010b201620134105742002102821160b20160d0020024101102a000b201620104105746a220220052903c002370000200241186a200a290300370000200241106a200b290300370000200241086a2014290300370000201041016a2110024002402018450d00201720094d0d0120112017417f6a22174105746a22022900002121200229000821222002290010211c201120094105746a220941186a200241186a2900003700002009201c37001020092022370008200920213700000b200c2118200321130c020b418ce6c200200920171037000b201120174105746a220220052903c002370000200241186a2009290300370000200241106a200b290300370000200241086a2014290300370000201741016a2117200a450d00201020034d0d0120162010417f6a22104105746a22022900002121200229000821222002290010211c201620034105746a220341186a200241186a2900003700002003201c37001020032022370008200320213700000b200541e5026a2005290340370000200541cd026a200541e0006a41086a290300370000200541d5026a200541e0006a41106a290300370000200541dd026a200541e0006a41186a290300370000200541ed026a200541c0006a41086a290300370000200541f5026a200541c0006a41106a290300370000200541fd026a200541c0006a41186a290300370000200541013a00c402200541073a00c002200520052903603700c5022005418c036a201036020020054188036a201736020020054185036a200e3a000041b8d6c5004100200541c0026a10880120054180016a41086a22024200370300200542003703800141f192c200411b20054180016a1004200541c0026a41086a200229030037030020052005290380013703c0022005410036028001200541c0026a411020054180016a100521032005280280012209417f460d022003450d022005200936029c02200520033602980220054180016a20054198026a102d200528028001220b450d0120054188016a2802002102200528028401210a02402009450d00200310290b200a450d03200b10290c030b418ce6c200200320101037000b418f89c3004133104e000b410021020b0240024002400240024002400240024002400240024002402017201b4f22030d004100200220106b2209200920024b1b201b490d00200541dc026a2010360200200541c0026a41186a2013360200200541c0026a41106a2017360200200541cc026a2018360200200520163602d402200520113602c8022005201b3602c402200520123602c002411a10272202450d01200241186a41002f009de7423b0000200241106a4100290095e742370000200241086a410029008de74237000020024100290085e7423700002002411a413a10282202450d022002200529034037001a200241326a200541c0006a41186a2903003700002002412a6a200541c0006a41106a290300370000200241226a200541c0006a41086a29030037000020054198026a41186a2203420037030020054198026a41106a2209420037030020054198026a41086a220a420037030020054200370398022002413a20054198026a1000200541d8036a41186a2003290300370300200541d8036a41106a2009290300370300200541d8036a41086a200a29030037030020052005290398023703d80320054120360284012005200541d8036a36028001200541c0026a20054180016a10db022002102902402018450d00201110290b20130d060c070b024020030d00200541cd026a200541c8006a290300370000200541d5026a200541d0006a290300370000200541dd026a200541d8006a290300370000200541033a00c402200541073a00c002200520052903403700c50241b8d6c5004100200541c0026a1088010c050b200541cd026a200541c0006a41086a290300370000200541d5026a200541c0006a41106a290300370000200541dd026a200541d8006a290300370000200541023a00c402200541073a00c002200520052903403700c50241b8d6c5004100200541c0026a108801411e10272203450d02200341166a41002900b5e742370000200341106a41002900afe742370000200341086a41002900a7e7423700002003410029009fe7423700002003411e413e10282203450d032003200529034037001e200341366a200541c0006a41186a220c2903003700002003412e6a200541c0006a41106a2210290300370000200341266a200541c0006a41086a221729030037000020054198026a41186a220a420037030020054198026a41106a220b420037030020054198026a41086a2209420037030020054200370398022003413e20054198026a1000200541d8036a41186a200a290300370300200541d8036a41106a200b290300370300200541d8036a41086a200929030037030020052005290398023703d803200541c0026a200541d8036a10fa02024020052802c002220a4112470d00200310290c050b20054180016a200541c0026a410472220b41840110ce041a200310292005200a3602c002200b20054180016a41840110ce041a200541a4026a20023602002009201b360200200541003a009c02200541023a009802200541386a200541c0026a20054198026a10ad0220052802382102200541cd026a2017290300370000200541d5026a2010290300370000200541dd026a200c290300370000200541e5026a2002453a0000200541043a00c402200541073a00c002200520052903403700c50241b8d6c5004100200541c0026a1088010c040b411a4101102a000b413a4101102a000b411e4101102a000b413e4101102a000b411a10272202450d03200241186a41002f009de7423b0000200241106a4100290095e742370000200241086a410029008de74237000020024100290085e7423700002002411a413a10282202450d042002200529034037001a200241326a200541c0006a41186a2903003700002002412a6a200541c0006a41106a290300370000200241226a200541c0006a41086a29030037000020054198026a41186a2203420037030020054198026a41106a2209420037030020054198026a41086a220a420037030020054200370398022002413a20054198026a1000200541d8036a41186a2003290300370300200541d8036a41106a2009290300370300200541d8036a41086a200a29030037030020052005290398023703d803200541d8036a4120100c2002102920054180016a41086a22024200370300200542003703800141e8e6c200411d20054180016a1004200541c0026a41086a200229030037030020052005290380013703c0022005410036028001200541c0026a411020054180016a10052102024002402005280280012203417f460d002002450d002005200336029c02200520023602980220054180016a20054198026a102d2005280280012209450d07200529028401212102402003450d00200210290b2005202137029c0220052009360298020c010b200541003602a00220054201370398020b20054198026a200541c0006a103620054180016a41086a22024200370300200542003703800141e8e6c200411d20054180016a1004200541c0026a41086a200229030037030020052005290380013703c002200541003602880120054201370380012005280298022112200520052802a00222023602d803200541d8036a20054180016a10300240024020020d002005280288012103200528028401210b200528028001210c0c010b20024105742110410020052802880122036b210a200528028001210c200528028401210b2012210203400240200b200a6a411f4b0d00200341206a22092003490d0d200b4101742217200920092017491b22094100480d0d02400240200b0d0020091027210c0c010b200c200b20091028210c0b200c450d052009210b0b200c20036a22092002290000370000200941186a200241186a290000370000200941106a200241106a290000370000200941086a200241086a290000370000200a41606a210a200341206a2103200241206a2102201041606a22100d000b2005200b3602840120052003360288012005200c360280010b200541c0026a4110200c200310030240200b450d00200c10290b0240200528029c02450d00201210290b02402018450d00201110290b2013450d010b201610290b410021030c060b20094101102a000b411a4101102a000b413a4101102a000b418f89c3004133104e000b41f4e5c2002103411621090b0240200c450d00201110290b2013450d00201610290b4101210b4101210c4101210a0c0e0b200141086a280200210a200141046a280200210e2002411a6a2901002121200241196a2d00002111200241186a2d00002116200241166a2f01002113200241156a2d00002117200241146a2d00002118200241126a2f01002112200241116a2d0000211b200241106a2d000021142002410e6a2f010021152002410d6a2d00002123200241046a2d00002108200241026a2f0100210d41d588c3002103412a21090240024020022d0000450d004101210b4100210c410021100c010b4101210b4100210c4100211020022d00014101470d002002410c6a2d000021102002410a6a2f0100210c200241096a2d00002109200241066a2f0100410874200241056a2d000072200241086a2d00004118747221034100210b0b200c41ffff0371410874200941ff0171722010411874722109200b0d0820052021370358200520113a0057200520163a0056200520133b0154200520173a0053200520183a0052200520123b01502005201b3a004f200520143a004e200520153b014c200520233a004b2005200936004720052003360043200520083a00422005200d3b014020054180016a41086a22024200370300200542003703800141f192c200411b20054180016a1004200541c0026a41086a200229030037030020052005290380013703c0022005410036028001200541c0026a411020054180016a1005210202400240024002402005280280012203417f460d002002450d002005200336029c02200520023602980220054180016a20054198026a102d2005280280012209450d0220054188016a280200210b200528028401210c02402003450d00200210290b2009200b200541c0006a10f90221020240200c450d00200910290b2002450d010c030b41014100200541c0006a10f9020d020b41cce4c2002103411521090c0a0b418f89c3004133104e000b200541003602c802200542013703c002200a200541c0026a103220052802c402210320052802c802210920052802c002210220054198026a41186a220b420037030020054198026a41106a220c420037030020054198026a41086a2210420037030020054200370398022002200920054198026a1000200541e0006a41186a2209200b290300370300200541e0006a41106a220b200c290300370300200541e0006a41086a220c2010290300370300200520052903980237036002402003450d00200210290b200541c0026a41186a2009290300370300200541c0026a41106a200b290300370300200541c0026a41086a200c290300370300200520052903603703c002024002400240024002400240024002400240411e10272202450d00200241166a41002900b5e742370000200241106a41002900afe742370000200241086a41002900a7e7423700002002410029009fe7423700002002411e413e10282202450d01200220052903c00237001e200241366a200541c0026a41186a2903003700002002412e6a200541c0026a41106a290300370000200241266a200541c0026a41086a29030037000020054198026a41186a2203420037030020054198026a41106a2209420037030020054198026a41086a220b420037030020054200370398022002413e20054198026a1000200541d8036a41186a2003290300370300200541d8036a41106a2009290300370300200541d8036a41086a200b29030037030020052005290398023703d803200541d8036a412041b8d6c50041004100100b2103200210292003417f470d020240200e4102490d00200541306a41bde7c200412110b5012005280234211720052802302118200541286a41bde7c200412110b50120052802282103200528022c210920054180016a41086a22024200370300200542003703800141bde7c200412120054180016a1004200541c0026a41086a220b200229030037030020052005290380013703c0022005200941016a410120031b36028001200541c0026a411020054180016a4104100320024200370300200542003703800141e8e6c200411d20054180016a1004200b200229030037030020052005290380013703c0022005410036028001200541c0026a411020054180016a100521022005280280012203417f460d052002450d052005200336029c02200520023602980220054180016a20054198026a102d2005280280012213450d04200529028401212102402003450d00200210290b200541c0026a41186a200541e0006a41186a290300370300200541c0026a41106a200541e0006a41106a290300370300200541c0026a41086a200541e0006a41086a290300370300200520052903603703c002200541c0026a21032021a72021422088a72202470d080c070b20054180016a41086a22024200370300200542003703800141f192c200411b20054180016a1004200541c0026a41086a200229030037030020052005290380013703c002410021022005410036028001200541c0026a411020054180016a1005210902402005280280012203417f460d002005200336029c02200520093602980220054180016a20054198026a102d200528028001220c450d0620054188016a2802002102200528028401210b02402003450d00200910290b200b450d00200c10290b200541c0026a200a41880110ce041a2005418c016a200236020020054180016a41086a4101360200200541003a008401200541023a008001200541206a200541c0026a20054180016a10ad0220052802202102200541cd026a200541e0006a41086a290300370000200541d5026a200541f0006a290300370000200541dd026a200541f8006a290300370000200541e5026a2002453a0000200541043a00c402200541073a00c002200520052903603700c502200541c0026a21020c080b411e4101102a000b413e4101102a000b41e1e4c2002103411f21090c0e0b418f89c3004133104e000b200541c0026a41186a200541e0006a41186a290300370300200541c0026a41106a200541e0006a41106a290300370300200541c0026a41086a200541e0006a41086a290300370300200520052903603703c002420021214101211341002102200541c0026a21030c010b418f89c3004133104e000b200241016a22092002490d022002410174220b20092009200b491b220941ffffff3f712009470d022009410574220b4100480d020240024020020d00200b102721130c010b20132002410574200b102821130b2013450d032021422088a721022009ad21210b20132002410574220c6a22092003290000370000200941186a200341186a290000370000200941106a200341106a290000370000200941086a200341086a29000037000020054180016a41086a22034200370300200542003703800141e8e6c200411d20054180016a1004200541c0026a41086a200329030037030020052005290380013703c002200541003602880120054201370380012005200241016a22033602980220054198026a20054180016a103002400240200320024f0d002005280288012103200528028401210c20052802800121100c010b410020052802880122036b210b200c41206a21112005280280012110200528028401210c2013210203400240200c200b6a411f4b0d00200341206a22092003490d04200c4101742216200920092016491b22094100480d0402400240200c0d002009102721100c010b2010200c2009102821100b2010450d0b2009210c0b201020036a22092002290000370000200941186a200241186a290000370000200941106a200241106a290000370000200941086a200241086a290000370000200b41606a210b200341206a2103200241206a2102201141606a22110d000b2005200c36028401200520033602880120052010360280010b200541c0026a41102010200310030240200c450d00201010290b02402021a7450d00201310290b20054180016a41186a200541e0006a41186a29030037030020054180016a41106a200541e0006a41106a29030037030020054180016a41086a200541e0006a41086a2903003703002005200529036037038001200541c0026a200a41880110ce041a411e10272202450d03200241166a41002900b5e742370000200241106a41002900afe742370000200241086a41002900a7e7423700002002410029009fe7423700002002411e413e10282202450d04200220052903800137001e200241366a20054180016a41186a2903003700002002412e6a20054180016a41106a290300370000200241266a20054180016a41086a29030037000020054198026a41186a2203420037030020054198026a41106a2209420037030020054198026a41086a220b420037030020054200370398022002413e20054198026a1000200541d8036a41186a2003290300370300200541d8036a41106a2009290300370300200541d8036a41086a200b29030037030020052005290398023703d803200541003602a0022005420137039802200541c0026a20054198026a1032200528029c022103200541d8036a4120200528029802220920052802a002100302402003450d00200910290b20021029200541c0026a103d412010272202450d0520022005290340370000200241186a200541c0006a41186a290300370000200241106a200541c0006a41106a290300370000200241086a200541c0006a41086a29030037000020054180016a41186a200541e0006a41186a29030037030020054180016a41106a200541e0006a41106a29030037030020054180016a41086a200541e0006a41086a2903003703002005200529036037038001200541dc026a4100360200200541cc026a428180808010370200200542013702d402200520023602c8022005200e3602c40220052017410020181b22093602c002411a10272203450d06200341186a41002f009de7423b0000200341106a4100290095e742370000200341086a410029008de74237000020034100290085e7423700002003411a413a10282203450d07200320052903800137001a200341326a20054180016a41186a2903003700002003412a6a20054180016a41106a290300370000200341226a20054180016a41086a29030037000020054198026a41186a220b420037030020054198026a41106a220c420037030020054198026a41086a2210420037030020054200370398022003413a20054198026a1000200541d8036a41186a200b290300370300200541d8036a41106a200c290300370300200541d8036a41086a201029030037030020052005290398023703d8032005412036029c022005200541d8036a36029802200541c0026a20054198026a10db022003102920021029200541cd026a200541c0006a41086a290300370000200541d5026a200541c0006a41106a290300370000200541dd026a200541c0006a41186a290300370000200541e5026a2005290360370000200541ed026a200541e0006a41086a290300370000200541f5026a200541e0006a41106a290300370000200541fd026a200541e0006a41186a2903003700002005418c036a200e36020020054188036a2009360200200541003a00c402200541073a00c002200520052903403700c502200541c0026a21020b4100210c41b8d6c50041002002108801200a10294101210b0c0a0b102b000b200b4101102a000b411e4101102a000b413e4101102a000b41204101102a000b411a4101102a000b413a4101102a000b20094101102a000b200a103d200a10294100210c4101210b4101210a0c040b200141046a280200210a41d588c3002103412a210920022d00000d0120022d00014101470d01200241196a2d00002103200241186a2d00002109200241166a2f0100210b200241156a2d0000210c200241146a2d00002110200241126a2f01002111200241116a2d00002116200241106a2d000021132002410e6a2f010021172002410d6a2d000021182002410c6a2d000021122002410a6a2f0100211b200241096a2d00002114200241086a2d00002115200241066a2f01002123200241056a2d00002108200241046a2d0000210d200241026a2f0100210e20052002411a6a290100370378200520033a0077200520093a00762005200b3b01742005200c3a0073200520103a0072200520113b0170200520163a006f200520133a006e200520173b016c200520183a006b2005200d3a00622005200e3b016020052014201b410874201241187472723600672005200820234108747220154118747236006320054180016a41086a22024200370300200542003703800141f192c200411b20054180016a1004200541c0026a41086a200229030037030020052005290380013703c0022005410036028001200541c0026a411020054180016a1005210302400240024002402005280280012202417f460d002005200236029c02200520033602980220054180016a20054198026a102d2005280280012209450d0220054188016a280200210b200528028401210c02402002450d00200310290b2009200b200541e0006a10f90221020240200c450d00200910290b2002450d010c030b41014100200541e0006a10f9020d020b41cce4c2002103411521090c030b418f89c3004133104e000b4100210b200541003602c802200542013703c002200a200541c0026a103220052802c402210320052802c802210920052802c002210220054198026a41186a220c420037030020054198026a41106a2210420037030020054198026a41086a2211420037030020054200370398022002200920054198026a1000200541d8036a41186a2209200c290300370300200541d8036a41106a22162010290300370300200541d8036a41086a2210201129030037030020052005290398023703d80302402003450d00200210290b200541c0026a200a41880110ce041a20054180016a410d6a200541e0006a41086a29030037000020054180016a41156a200541e0006a41106a29030037000020054180016a411d6a200541e0006a41186a2903003700004101210c200541013a0084012005200529036037008501200541023a008001200541186a200541c0026a20054180016a10ad0220052802182102200541c0026a410d6a2010290300370000200541c0026a41156a2016290300370000200541c0026a411d6a2009290300370000200541e5026a2002453a0000200541053a00c402200541073a00c002200520052903d8033700c50241b8d6c5004100200541c0026a108801200a10290b4101210a410021030c020b200a103d200a10294101210c4100210b4101210a0c010b4100210a4101210c410021030b02402006410771417f6a220241024b0d0002400240024020020e03000102000b200a450d02200141086a280200450d02200141046a28020010290c020b200b450d01200141046a2802002202103d200210290c010b200c450d00200141086a2802002202103d200210290b2000200936020420002003360200200424000bc08c0108077f027e0e7f027e027f017e0d7f0b7e230041e00a6b220324000240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024020012d00000e0700010203040506000b200341e4046a4101360200200342013702d404200341ccfdc4003602d004200341023602b409200341c4fdc4003602b0092003200341b0096a3602e004200341d0046a41ece1c2001057000b200141e0006a2802002104200341b0096a200141086a41d80010ce041a20034188086a41186a200141fc006a28020036020020034188086a41106a200141f4006a29020037030020034188086a41086a200141ec006a2902003703002003200141e4006a29020037038808024020022d000120022d000072450d0041ad88c3002105412821020c220b200341b8076a41086a22024200370300200342003703b80741f987c5004118200341b8076a100420034190046a41086a2002290300370300200320032903b8073703900441002102200341003602d00420034190046a4110200341d0046a10052106024020032802d0042205417f460d002003200536029c062003200636029806200341d0046a20034198066a10f10220032d00c0054102460d0620032802a80521022005450d00200610290b024020022004490d0041fce1c2002105413521020c220b200341dc046a2004360200200341d0046a41086a41033a00002003410b3a00d0044100210541b8d6c5004100200341d0046a108801200341d0046a200341b0096a41d80010ce041a200341b4056a20034188086a41086a290300370200200341bc056a20034188086a41106a290300370200200341c4056a20034188086a41186a280200360200200320043602a80520032003290388083702ac05200341b8076a41086a22024200370300200342003703b80741f987c5004118200341b8076a100420034190046a41086a2002290300370300200320032903b80737039004200341003602a0062003420137039806200341d0046a20034198066a109302200328029c06210220034190046a4110200328029806220420032802a00610032002450d20200410290c200b2001410c6a2802002107200141086a2802002108200141046a2802002109200141106a290300210a2002411a6a290100210b200241196a2d0000210c200241186a2d0000210d200241166a2f0100210e200241156a2d0000210f200241146a2d00002110200241126a2f01002111200241116a2d00002112200241106a2d000021132002410e6a2f010021142002410d6a2d00002115200241046a2d00002116200241026a2f01002117412a210441d588c30021050240024020022d0000450d004101210641002118410021190c010b41012106410021184100211920022d00014101470d002002410c6a2d000021182002410a6a2f01002119200241096a2d00002104200241066a2f0100410874200241056a2d000072200241086a2d0000411874722105410021060b201941ffff0371410874201841187472200441ff017172210220060d1e2003200b3703b0062003200c3a00af062003200d3a00ae062003200e3b01ac062003200f3a00ab06200320103a00aa06200320113b01a806200320123a00a706200320133a00a606200320143b01a406200320153a00a3062003200236009f062003200536009b06200320163a009a06200320173b019806200341b8076a41086a22024200370300200342003703b80741f987c5004118200341b8076a100420034190046a41086a2002290300370300200320032903b80737039004200341003602d00420034190046a4110200341d0046a1005210220032802d0042205417f460d062002450d06200320053602bc07200320023602b807200341d0046a200341b8076a10f10220032d00c00522044102460d0520034188086a200341d0046a41f00010ce041a2003200341d0046a41f4006a28000036009309200320032800c1053602900902402005450d00200210290b200341b0096a20034188086a41f00010ce041a200341b0096a41f4006a200328009309360000200320043a00a00a20032003280290093600a10a0c150b200141c0006a290300211a200141386a290300211b2002411a6a290100210b200241196a2d0000210d200241186a2d0000210f200241166a2f01002110200241156a2d00002111200241146a2d00002112200241126a2f01002113200241116a2d00002114200241106a2d000021152002410e6a2f010021162002410d6a2d00002117200241046a2d00002107200241026a2f0100211c200141306a280200211d2001412c6a2802002108200141286a280200210e2001411d6a290000211e2001411c6a2d0000211f2001411b6a2d00002120200141196a2f00002121200141186a2d00002122200141176a2d00002123200141156a2f00002124200141146a2d00002125200141136a2d00002126200141116a2f00002127200141106a2d000021282001410c6a2802002129200141086a2802002109200141076a2d0000212a200141056a2f0000212b200141046a2d0000210c200141c8006a290300210a412a210441d588c30021050240024020022d0000450d004101210641002118410021190c010b41012106410021184100211920022d00014101470d002002410c6a2d000021182002410a6a2f01002119200241096a2d00002104200241066a2f0100410874200241056a2d000072200241086a2d0000411874722105410021060b201941ffff0371410874201841187472200441ff017172210220060d130240200c41ff01714101470d00200341d0046a200941067610cc0120032802d00421060240024020032802d8042009413f7122044b0d00410021040c010b200620044105746a2204290018211e20042d0017211f20042d0016212020042f0014212120042d0013212220042d0012212320042f0010212420042d000f212520042d000e212620042f000c212720042d000b2128200428000721292004280003210920042d0002212a20042f0000212b410121040b024020032802d404450d00200610290b20040d004184efc2002105411521020c140b2003200b3703c8042003200d3a00c7042003200f3a00c604200320103b01c404200320113a00c304200320123a00c204200320133b01c004200320143a00bf04200320153a00be04200320163b01bc04200320173a00bb04200320023600b704200320053600b304200320073a00b2042003201c3b01b004200341e0016a41e887c500411110940102404280ade20420032903e8017d4280ade20420032802e0011b200a5a0d0041dbeac2002105411b21020c140b200341c8016a41b793c20041111086014200212c0240024020032903d001420120032802c80122021b220b200341d8016a290300420020021b222d8450450d004200212e0c010b200341a8016a202d4200200a420010d304200341b8016a200b4200200a420010d30420034198016a42004200200b420010d304024020032903b00120032903a00184420052200341c0016a290300222c20032903a8012003290398017c7c222e202c5472450d0041f6eac2002105412721020c150b20032903b801212c0b200341d0046a200341b0046a202c202e4108109001024020032802d0044101470d0020032802d804210220032802d40421050c140b200341d0046a41106a290300212e20032903d804212c20034198076a41186a202d3703002003200b3703a8072003200a3703a0072003200a37039807200341b8076a41086a22024200370300200342003703b80741f987c5004118200341b8076a1004200341b0096a41086a2002290300370300200320032903b8073703b009200341003602d004200341b0096a4110200341d0046a1005210220032802d004220f417f460d072002450d072003200f36028c082003200236028808200341d0046a20034188086a10f10220032d00c00522054102460d0620032802bc05210420032802b805210620032802b405211820032802b005211920032802ac05210c20032802a805210d20032903a005210a200329039805210b200329039005212d200329038805212f200329038005213020032903f804213120032903f004213220032903e804213320032903e004213420032903d804213520032903d0042136200320032800c105360298062003200341c4056a28000036009b060240200f450d00200210290b2003200328029806360288082003200328009b0636008b080c120b200141386a290300211e200141306a290300211a200141c0006a290300210a200341f0036a41186a200141196a290000370300200341f0036a41106a200141116a290000370300200341f0036a41086a200141096a290000370300200320012900013703f0032002411a6a290100210b200241196a2d00002108200241186a2d00002109200241166a2f0100210c200241156a2d0000210e200241146a2d00002110200241126a2f01002111200241116a2d00002112200241106a2d000021132002410e6a2f010021142002410d6a2d00002115200241046a2d00002116200241026a2f010021172001412c6a2802002107200141286a280200210d200141246a280200210f41d588c3002105412a21040240024020022d0000450d004101210641002118410021190c010b41012106410021184100211920022d00014101470d002002410c6a2d000021192002410a6a2f01002118200241096a2d00002104200241066a2f0100410874200241056a2d000072200241086a2d0000411874722105410021060b201841ffff0371410874200441ff017172201941187472210202402006450d00200d0d100c110b2003200b3703c804200320083a00c704200320093a00c6042003200c3b01c4042003200e3a00c304200320103a00c204200320113b01c004200320123a00bf04200320133a00be04200320143b01bc04200320153a00bb04200320023600b704200320053600b304200320163a00b204200320173b01b004200341e0026a41e887c500411110940102404280ade20420032903e8027d4280ade20420032802e0021b200a5a0d0041dbeac2002105411b21020c0f0b200341c8026a41b793c20041111086014200211b0240024020032903d002420120032802c80222021b220b200341d8026a290300420020021b222c8450450d004200212d0c010b200341a8026a202c4200200a420010d304200341b8026a200b4200200a420010d30420034198026a42004200200b420010d304024020032903b00220032903a00284420052200341c0026a290300221b20032903a8022003290398027c7c222d201b5472450d0041f6eac2002105412721020c100b20032903b802211b0b200341d0046a200341b0046a201b202d4108109001024020032802d0044101470d0020032802d804210220032802d40421050c0f0b200341d0046a41106a290300212d20032903d804211b20034198076a41186a202c3703002003200b3703a8072003200a3703a0072003200a37039807200341b8076a41086a22024200370300200342003703b80741f987c5004118200341b8076a1004200341b0096a41086a2002290300370300200320032903b8073703b009200341003602d004200341b0096a4110200341d0046a1005210220032802d004220c417f460d082002450d082003200c36028c082003200236028808200341d0046a20034188086a10f10220032d00c00522054102460d0720032802bc05210420032802b805210620032802b405211820032802b005211920032802ac05210820032802a805210920032903a005210a200329039805210b200329039005212c200329038805212e200329038005212f20032903f804213020032903f004213120032903e804213220032903e004213320032903d804213420032903d0042135200320032800c105360298062003200341c4056a28000036009b060240200c450d00200210290b2003200328029806360288082003200328009b0636008b080c0d0b20034198066a41186a200141196a29000037030020034198066a41106a200141116a29000037030020034198066a41086a200141096a290000370300200320012900013703980620034188086a41206a200141c1006a2d00003a000020034188086a41186a200141396a29000037030020034188086a41106a200141316a29000037030020034188086a41086a200141296a2900003703002003200141216a29000037038808200341d0046a41086a2205200241096a290000370300200341d0046a41106a2204200241116a290000370300200341d0046a41186a2206200241196a290000370300200341d0046a41206a2218200241216a2d00003a0000200341bc076a2219200241266a2f01003b0100200320022900013703d0042003200241226a2801003602b807024020022d00002202450d00200341b0096a41266a20032802b807360100200341bd096a2005290300370000200341c5096a2004290300370000200341cd096a2006290300370000200341d5096a20182d00003a0000200341da096a20192f01003b0100200320023a00b409200320032903d0043700b509200341013a00b00941b1e2c200210541e90021020c1e0b200341b0096a41216a20182d00003a0000200341b0096a41196a2006290300370000200341b0096a41116a2004290300370000200341b0096a41096a2005290300370000200320032903d004220a3700b109200341003a00b00941b1e2c200210541e9002102200aa741ff0171417f6a220441014b0d1d02400240024020040e020100010b20032d0088084101470d1f20034188086a41017221044200210a0c010b20032d0088084101460d1e200341b0096a41027221044202210a0b41002105200341d0046a20034198066a200a410010a00120032d00d0042102024020032d00d8040d002003418c056a280200450d0020034188056a28020010290b200241ff01714101470d1c200341d0046a20044296014200109f01024020032802d0044101470d0020032802d804210220032802d40421050c1e0b200341d0046a41106a290300210b20032903d804211e200341f0026a41b18ac0004116108601200341f0026a41106a290300210a20032903f802211a20032802f0022102200341b8076a41086a22044200370300200342003703b80741b18ac0004116200341b8076a100420034190046a41086a2004290300370300200320032903b807370390042003427f200b200a420020021b220a7c201e201a420020021b220b7c221e200b542202ad7c220b2002200b200a54200b200a511b22021b3703c0072003427f201e20021b3703b80720034190046a4110200341b8076a411010030c1c0b200141d8006a290300210b200141d0006a290300211e200341f0036a41186a200141196a290000370300200341f0036a41106a200141116a290000370300200341f0036a41086a200141096a290000370300200320012900013703f003200341b0046a41186a200141396a290000370300200341b0046a41106a200141316a290000370300200341b0046a41086a200141296a2900003703002003200141216a2900003703b004200141c4006a2802002109200141c8006a2802002108200141cc006a28020021072002411a6a290100210a200241196a2d0000210c200241186a2d0000210d200241166a2f0100210e200241156a2d0000210f200241146a2d00002110200241126a2f01002111200241116a2d00002112200241106a2d000021132002410e6a2f010021142002410d6a2d00002115200241046a2d00002116200241026a2f0100211741d588c3002105412a21040240024020022d0000450d004101210641002118410021190c010b41012106410021184100211920022d00014101470d002002410c6a2d000021192002410a6a2f01002118200241096a2d00002104200241066a2f0100410874200241056a2d000072200241086a2d0000411874722105410021060b201841ffff0371410874200441ff017172201941187472210220060d092003200a3703b0072003200c3a00af072003200d3a00ae072003200e3b01ac072003200f3a00ab07200320103a00aa07200320113b01a807200320123a00a707200320133a00a607200320143b01a407200320153a00a3072003200236009f072003200536009b07200320163a009a07200320173b019807200341d0046a20034198076a108c010240024020032d00d00422054102470d0041012105413421024202210a0c010b20034190096a41086a2204200341e4046a29020037030020034190096a41106a2206200341ec046a28020036020020034188086a41086a2218200341d0046a41306a29030037030020034188086a41106a221920034188056a29030037030020034188086a41186a220c20034190056a29030037030020034188086a41206a220d20034198056a29030037030020034188086a41286a220e200341a0056a29030037030020034188086a41306a220f200341a8056a2903003703002003200341dc046a290200370390092003200341d0046a41286a29030037038808200341d0046a41086a28020021024202210a4202211a024020050d00200341d0046a41206a290300211a20034190046a41106a200628020036020020034190046a41086a200429030037030020034198066a41086a201829030037030020034198066a41106a201929030037030020034198066a41186a200c29030037030020034198066a41206a200d29030037030020034198066a41286a200e29030037030020034198066a41306a200f2903003703002003200329039009370390042003200329038808370398060b0240201a4202520d0041012105413421020c010b20034188086a41106a20034190046a41106a28020036020020034188086a41086a20034190046a41086a290300370300200341d0046a41086a20034198066a41086a290300370300200341d0046a41106a20034198066a41106a290300370300200341d0046a41186a20034198066a41186a290300370300200341d0046a41206a20034198066a41206a290300370300200341d0046a41286a20034198066a41286a290300370300200341d0046a41306a20034198066a41306a29030037030020032003290390043703880820032003290398063703d00441002105201a210a0b200341f0076a41086a220420034188086a41086a290300370300200341f0076a41106a220620034188086a41106a280200360200200341b8076a41086a2218200341d0046a41086a290300370300200341b8076a41106a2219200341d0046a41106a290300370300200341b8076a41186a220c200341d0046a41186a290300370300200341b8076a41206a220d200341d0046a41206a290300370300200341b8076a41286a220e200341d0046a41286a290300370300200341b8076a41306a220f200341d0046a41306a29030037030020032003290388083703f007200320032903d0043703b80702402005450d00419ae3c20021050c0a0b200341b0096a41206a220520032903b807370300200341bc096a2004290300370200200341c4096a2006280200360200200341b0096a41286a2018290300370300200341b0096a41306a2019290300370300200341e8096a200c290300370300200341f0096a200d290300370300200341f8096a200e290300370300200341800a6a200f290300370300200320023602b009200320032903f0073702b4092003200a3703c809200341e0036a41888dc300410d10940120032903e803420020032802e0031b211a200aa74101470d072005290300201a520d0741cee3c2002105412a21020c080b418f89c3004133104e000b418f89c3004133104e000b200341003602880a200341003a00a00a200342908080808080103702940a200342848080808080c00037028c0a200342013703800a200342013703f809200342af013703f00920034287013703e809200342013703e009200342013703d809200342013703d009200342013703c809200342013703c009200342013703b809200342013703b0092003412036029c0a0c0e0b418f89c3004133104e000b4100210d428701212f42af01212d4201210a4104210c41808004211941102118418080012106412021044201210b42012130420121314201213242012133420121344201213542012136410021050c0a0b418f89c3004133104e000b4100210941202104418080012106411021184180800421194104210842af01212c428701212e4201213542012134420121334201213242012131420121304201212f4201210b4201210a410021050c040b200341d0046a200341f0036a108c010240024020032d00d00422024102460d0020020d0120034184056a280200450d0020034180056a28020010290b418ee4c2002105412e21020c010b200320032902d40437009309200320032d00d3043a009209200320032f00d1043b0190092003200341e9046a2900003703a8092003200341e5046a2800003602a4092003200341dd046a29000037029c092003200341dc046a2d00003a009b0920032903c809210a20032903d009211b200320093602b8072003200920074105746a3602bc072003200341b0096a3602c00720034188086a200341b8076a102502400240024002400240024002400240024002400240024002402003280288080d004104210441002105410021060c010b200341d0046a41086a220220034188086a41086a29030037030020032003290388083703d004411010272204450d01200420032903d004370200200441086a200229030037020020034198066a41086a200341b8076a41086a280200360200200320032903b8073703980620034188086a20034198066a102502402003280288080d0041012105410121060c010b41012102410121060340200341d0046a41086a221820034188086a41086a29030037030020032003290388083703d0040240024020062002460d00200241016a21050c010b200241016a22052002490d1820024101742206200520052006491b220641ffffffff00712006470d18200641047422194100480d180240024020020d002019102721040c010b200420024104742019102821040b2004450d040b200420024104746a220220032903d004370200200241086a201829030037020020034188086a20034198066a1025200521022003280288080d000b0b200341e0096a280200210220032802d8092118200341003602d00420182002200341d0046a100f210d20032802d0042218417f460d0220034188086a41186a200341b0046a41186a29030037030020034188086a41106a200341b0046a41106a29030037030020034188086a41086a200341b0046a41086a290300370300200320032903b00437038808200341003602d804200342013703d004200320183602b807200341b8076a200341d0046a10300240024020032802d404220c20032802d80422026b2018490d0020032802d00421190c010b200220186a22192002490d16200c410174220e20192019200e491b220e4100480d1602400240200c0d00200e102721190c010b20032802d004200c200e102821190b2019450d042003200e3602d404200320193602d004200e210c0b201920026a200d201810ce041a02400240200220186a22020d004101210e0c010b20024100480d1620021027220e450d09200e2019200210ce041a0b0240200c450d00201910290b20024101742219200241206a220c200c2019491b220f4100480d150240024020020d00200f102721190c010b200e2002200f102821190b024020190d00200f4101102a000b201920026a2202200329038808370000200241186a20034188086a41186a290300370000200241106a20034188086a41106a290300370000200241086a20034188086a41086a290300370000200341d0046a41186a22024200370300200341d0046a41106a220e4200370300200341d0046a41086a220f4200370300200342003703d0042019200c200341d0046a100020034198066a41186a200229030037030020034198066a41106a200e29030037030020034198066a41086a200f290300370300200320032903d004370398062019102902402018450d00200d10290b024020034198066a20034190096a412010d0040d000240024020050d00410021180c010b200541047421192004410c6a2102410021180340200228020020186a2118200241106a2102201941706a22190d000b0b200320032802e40920186b3602e409411710272202450d052002410f6a41002900af9342370000200241086a41002900a89342370000200241002900a0934237000020024117413710282202450d0620022003290398073700172002412f6a20034198076a41186a290300370000200241276a20034198076a41106a2903003700002002411f6a20034198076a41086a290300370000200341d0046a41186a22184200370300200341d0046a41106a22194200370300200341d0046a41086a220c4200370300200342003703d00420024137200341d0046a1000200341b8076a41186a2018290300370300200341b8076a41106a2019290300370300200341b8076a41086a200c290300370300200320032903d0043703b807200341b8076a4120100c200210292019200b370300200341f8046a201a201b20071b370300200341d0046a41206a4201200a20071b3703002018201a3703002003418c056a20032802e40936020020034190056a20032903b00437030020034198056a200341b0046a41086a290300370300200341a0056a200341b0046a41106a290300370300200341a8056a200341b0046a41186a29030037030020034180056a200341d8096a220229030037030020034188056a200241086a2802003602002003201e3703d804200341003a00d004200341f0036a200341d0046a10d801411410272202450d07200241106a41002800bb8c40360000200241086a41002900b38c40370000200241002900ab8c4037000020024114413410282202450d0820022003290398073700142002412c6a200341b0076a290300370000200241246a20034198076a41106a2903003700002002411c6a20034198076a41086a290300370000200341c8036a20024134108401200341c8036a41106a290300210a20032903d003210b20032802c803211820021029200341d0046a20034198076a4200420010850120032903d004211a200341b0036a41b18ac0004116108601200a420020181b211b200b420020181b212c200341b0036a41106a290300420020032802b00322021b210a20032903b803420020021b210b200341d0046a41106a290300212d20032903d804211e02400240201a4200520d00200341b8076a41086a22024200370300200342003703b80741b18ac0004116200341b8076a100420034190046a41086a2002290300370300200320032903b807370390042003427f200a202d7c200b201e7c221e200b542202ad7c220b2002200b200a54200b200a511b22021b370390082003427f201e20021b3703880820034188086a21020c010b200341b8076a41086a22024200370300200342003703b80741b18ac0004116200341b8076a100420034190046a41086a2002290300370300200320032903b8073703900420034200200a202d7d200b201e54ad7d221a200b201e7d221e200b56201a200a56201a200a511b22021b3703900820034200201e20021b3703880820034188086a21020b20034190046a4110200241101003200341a0036a200341f0036a202c201b108301200341a0036a41086a290300210b20032903a003211e20034188036a41b18ac000411610860120034188036a41106a290300210a200329039003211a2003280288032102200341b8076a41086a22184200370300200342003703b80741b18ac0004116200341b8076a100420034190046a41086a2018290300370300200320032903b807370390042003427f200b200a420020021b220a7c201e201a420020021b220b7c221e200b542202ad7c220b2002200b200a54200b200a511b22021b3703d8042003427f201e20021b3703d00420034190046a4110200341d0046a4110100302402005450d0020054104742105200441046a210203400240200241046a280200450d00200228020010290b200241106a2102200541706a22050d000b0b02402006450d00200410290b4100210502402008450d00200910290b0c0e0b200420054104746a2112024020050d00200421020c0a0b2004210203400240200228020022180d00200241106a21020c0b0b200241046a2802002105200241086a28020021192002410c6a280200210c20032802e009210d20032802d809210e200341d0046a41186a220f4200370300200341d0046a41106a22104200370300200341d0046a41086a22114200370300200342003703d00420184120200341d0046a100020034190046a41186a200f29030037030020034190046a41106a201029030037030020034190046a41086a2011290300370300200320032903d00437039004200e200d20034190046a41202005200c101102402019450d00200510290b200241106a22022012470d000c0b0b0b41104104102a000b20194104102a000b41b0cfc5004138104e000b200e4101102a000b41174101102a000b41374101102a000b41144101102a000b41344101102a000b20024101102a000b20022012460d0003402002280200450d010240200241086a280200450d00200241046a28020010290b200241106a22022012470d000b0b02402006450d00200410290b41f8e3c2002105411621020b200341dc096a280200450d0020032802d80910290b2008450d00200910290b410021084101210641012118410121190c130b200320053a00c005200320043602bc05200320063602b805200320183602b405200320193602b005200320083602ac05200320093602a8052003200a3703a0052003200b370398052003202c370390052003202e370388052003202f37038005200320303703f804200320313703f004200320323703e804200320333703e004200320343703d804200320353703d004200341d0056a420037030020034180066a4200370300200341f0056a4200370300200341e0056a4200370300200341d0046a41f4006a200328008b0836000020034280888080808010370388062003428080e983b1de163703c80520034280a094a58d1d3703f80520034280a094a58d1d3703e80520034280a094a58d1d3703d80520032003280288083600c1052003200341d0046a360294062003200341d0046a3602f00720034188026a41ceecc200410d109401200329039002210a2003280288022102200341f8016a41888dc300410d109401200341e4066a4100360200200341d4066a4200370200200341c8066a41e48cc300360200200341c4066a41b8d6c500360200200341bc066a22044200370200200341b8066a418883c000360200200341fc066a200341b0046a41086a29030037020020034184076a200341c0046a29030037020020034198066a41f4006a200341b0046a41186a290300370200200342083702dc062003428080808080013702cc06200341003602b406200341003602a806200320032903b0043702f40620032802f8012105200329038002210b2003200341f0076a3602f006200320034194066a3602ec062003200341d0046a3602e8062003200b420020051b3703a0062003200a420020021b37039806200341b0096a20034198066a201a201e20034198076a200341f0036a200f200710da0141012112200341b0096a41086a22062802002102024020032802b409410020032d00b0094101461b22050d002006200429020037030020034188086a41086a200341bc096a280200360200200320032902b4063703b009200320032902b40937038808200341d80a6a20034188086a10d40120032802d006220e20032802d806220641e8006c6a210920032802d4062110200e2104024002402006450d00200341b9096a210c200e21040240034020042d0000210620034188086a200441016a41d70010ce041a20064106460d01200441d8006a2800002118200441dc006a2800002119200441e0006a2800002108200320063a00b8092003410b3a00b009200c20034188086a41d70010ce041a20182008200341b0096a10880102402019450d00201810290b200441e8006a22042009470d000c030b0b200441e8006a21040b20042009460d00034020042d000022064106460d01200441286a2800002118200441246a28000021190240200441dc006a280000450d00200441d8006a28000010290b024020064105490d002018450d00201910290b200441e8006a22042009470d000b0b410021122010450d00200e10290b200341b0046a20032903980720032903a00720032903a80720034198076a41186a290300201b202d10f80220032802dc06221120032802e406220641a8016c6a210e20032802e00621132011210402402006450d00200341b9096a2106200341b8076a4102722118200341b0096a4104722110201121040240034020034190046a41186a2208200441186a29030037030020034190046a41106a2209200441106a29030037030020034190046a41086a220c200441086a2903003703002003200429030037039004200441206a280200211920034188086a200441246a41840110ce041a20194112460d01200320193602b009201020034188086a41840110ce041a2018200329039004370000201841086a200c290300370000201841106a2009290300370000201841186a200829030037000020034180023b01b807200341f0016a200341b0096a200341b8076a10ad0220032802f00121192006200329039004370000200641086a200c290300370000200641106a2009290300370000200641186a2008290300370000200341043a00b8092003410b3a00b00920032019453a00d90941b8d6c5004100200341b0096a108801200441a8016a2204200e470d000b200e21040c010b200441a8016a21040b02402004200e460d00200341b0096a41206a210c200341b0096a41246a21100340200341b8076a41186a2218200441186a290300370300200341b8076a41106a2219200441106a290300370300200341b8076a41086a2208200441086a290300370300200320042903003703b807200441206a2802002106200341b0096a200441246a41840110ce041a20064112460d0120034190096a41186a2209201829030037030020034190096a41106a2218201929030037030020034190096a41086a22192008290300370300200320032903b8073703900920034188086a200341b0096a41840110ce041a200341b0096a41186a2009290300370300200341b0096a41106a2018290300370300200341b0096a41086a201929030037030020032003290390093703b009200320063602d009201020034188086a41840110ce041a200c103d200441a8016a2204200e470d000b0b02402013450d00201110290b024020032802a8062204450d00200341ac066a280200450d00200410290b2012450d00200341b8066a280200210420032802c00621080240024020032802bc0622180d00200421060c010b2018211920042106034020062802880b21062019417f6a22190d000b0340200420042f01064102746a41880b6a28020021042018417f6a22180d000b0b200341cc096a20042f0106360200200341c8096a4100360200200341c4096a2004360200200320083602d009200341003602c009200342003703b809200320063602b409200341003602b009200341b0096a10d901024020032802d8062206450d0020032802d0062104200641e8006c210603400240200441dc006a280200450d00200441d8006a28020010290b024020042d00004105490d00200441286a280200450d00200441246a28020010290b200441e8006a2104200641987f6a22060d000b0b20032802d406450d0020032802d00610290b200d450d010b200f10290b410021194101210641012118410121080c0f0b200320053a00c005200320043602bc05200320063602b805200320183602b405200320193602b0052003200c3602ac052003200d3602a8052003200a3703a0052003200b370398052003202d370390052003202f370388052003203037038005200320313703f804200320323703f004200320333703e804200320343703e004200320353703d804200320363703d004200341d0056a420037030020034180066a4200370300200341f0056a4200370300200341e0056a4200370300200341d0046a41f4006a200328008b0836000020034280888080808010370388062003428080e983b1de163703c80520034280a094a58d1d3703f80520034280a094a58d1d3703e80520034280a094a58d1d3703d80520032003280288083600c1052003200341d0046a3602f0072003200341d0046a3602f00320034188016a41ceecc200410d109401200329039001210a2003280288012102200341f8006a41888dc300410d109401200341e4066a4100360200200341d4066a4200370200200341c8066a41e48cc300360200200341c4066a41b8d6c500360200200341bc066a4200370200200341b8066a418883c000360200200341fc066a200341b0046a41086a29030037020020034184076a200341c0046a29030037020020034198066a41f4006a200341c8046a290300370200200342083702dc062003428080808080013702cc06200341003602b406200341003602a806200320032903b0043702f40620032802782105200329038001210b2003200341f0036a3602f0062003200341f0076a3602ec062003200341d0046a3602e8062003200b420020051b3703a0062003200a420020021b370398062003201e3703c8092003201f3a00c709200320203a00c609200320213b01c409200320223a00c309200320233a00c209200320243b01c009200320253a00bf09200320263a00be09200320273b01bc09200320283a00bb09200320293600b709200320093600b3092003202a3a00b2092003202b3b01b009200341003602c007200342013703b80720034188086a20034198066a200341b0096a201b201a20034198076a200e201d200341b8076a10e1014101211220034188086a41086a2802002102200328028c08210502402003280288084101460d0002402002450d00200510290b200341b0096a41086a200341bc066a29020037030020034188086a41086a200341bc096a280200360200200320032902b4063703b009200320032902b40937038808200341d80a6a20034188086a10d40120032802d006220d20032802d806220441e8006c6a210920032802d406210f200d2105024002402004450d00200341b9096a210c200d21050240034020052d0000210420034188086a200541016a41d70010ce041a20044106460d01200541d8006a2800002106200541dc006a2800002118200541e0006a2800002119200320043a00b8092003410b3a00b009200c20034188086a41d70010ce041a20062019200341b0096a10880102402018450d00200610290b200541e8006a22052009470d000c030b0b200541e8006a21050b20052009460d00034020052d000022044106460d01200541286a2800002106200541246a28000021180240200541dc006a280000450d00200541d8006a28000010290b024020044105490d002006450d00201810290b200541e8006a22052009470d000b0b0240200f450d00200d10290b41002105410021120b200341b0046a20032903980720032903a00720032903a80720034198076a41186a290300202c202e10f80220032802dc06221120032802e406220641a8016c6a210f20032802e00621132011210402402006450d00200341b9096a2106200341b8076a4102722118200341b0096a4104722110201121040240034020034190046a41186a2209200441186a29030037030020034190046a41106a220c200441106a29030037030020034190046a41086a220d200441086a2903003703002003200429030037039004200441206a280200211920034188086a200441246a41840110ce041a20194112460d01200320193602b009201020034188086a41840110ce041a2018200329039004370000201841086a200d290300370000201841106a200c290300370000201841186a200929030037000020034180023b01b807200341f0006a200341b0096a200341b8076a10ad02200328027021192006200329039004370000200641086a200d290300370000200641106a200c290300370000200641186a2009290300370000200341043a00b8092003410b3a00b00920032019453a00d90941b8d6c5004100200341b0096a108801200441a8016a2204200f470d000b200f21040c010b200441a8016a21040b02402004200f460d00200341b0096a41206a210d200341b0096a41246a21100340200341b8076a41186a2218200441186a290300370300200341b8076a41106a2219200441106a290300370300200341b8076a41086a2209200441086a290300370300200320042903003703b807200441206a2802002106200341b0096a200441246a41840110ce041a20064112460d0120034190096a41186a220c201829030037030020034190096a41106a2218201929030037030020034190096a41086a22192009290300370300200320032903b8073703900920034188086a200341b0096a41840110ce041a200341b0096a41186a200c290300370300200341b0096a41106a2018290300370300200341b0096a41086a201929030037030020032003290390093703b009200320063602d009201020034188086a41840110ce041a200d103d200441a8016a2204200f470d000b0b02402013450d00201110290b024020032802a8062204450d00200341ac066a280200450d00200410290b2012450d00200341b8066a280200210420032802c00621090240024020032802bc0622180d00200421060c010b2018211920042106034020062802880b21062019417f6a22190d000b0340200420042f01064102746a41880b6a28020021042018417f6a22180d000b0b200341cc096a20042f0106360200200341c8096a4100360200200341c4096a2004360200200320093602d009200341003602c009200342003703b809200320063602b409200341003602b009200341b0096a10d901024020032802d8062206450d0020032802d0062104200641e8006c210603400240200441dc006a280200450d00200441d8006a28020010290b024020042d00004105490d00200441286a280200450d00200441246a28020010290b200441e8006a2104200641987f6a22060d000b0b20032802d406450d0020032802d00610290b41002118410121062008450d0c200e10290c0c0b200341e0006a41e887c500411110940102404280ade20420032903687d4280ade20420032802601b200a5a0d0041dbeac2002105411b21020c090b200341c8006a41b793c20041111086014200211e0240024020032903504201200328024822021b220b200341d8006a290300420020021b221a8450450d004200211b0c010b200341286a201a4200200a420010d304200341386a200b4200200a420010d304200341186a42004200200b420010d30402402003290330200329032084420052200341c0006a290300221e200329032820032903187c7c221b201e5472450d0041f6eac2002105412721020c0a0b2003290338211e0b200341d0046a20034198066a201e201b4108109001024020032802d0044101470d0020032802d804210220032802d40421050c090b200341086a20032903b00942002007ad420010d3044200200a427f200329030820032903104200521b7d221e201e200a5622021b212c200341e0046a290300211b20032903d804211e02402002450d0041cde1c1002105412c21020c070b200341d0046a20092007200341b0096a108502024020032802d0044101470d00200341d8046a280200210220032802d40421050c070b20034190096a41186a2205200341d0046a410472220241186a28020036020020034190096a41106a2204200241106a29020037030020034190096a41086a2218200241086a2902003703002003200229020037039009200341d0046a41186a22024200370300200341d0046a41106a4200370300200341d0046a41086a4200370300200342003703d00420092007200341d0046a1000200341f0036a41026a20032d00d20422193a0000200341b0046a41086a220c200341e3046a290000370300200341b0046a410d6a220d2002290000370000200320032f01d004220e3b01f003200320032900db04222d3703b00420032800d304210620032800d704210220034190046a41026a20193a000020034198076a41086a200c29030037030020034198076a410d6a200d2900003700002003200e3b0190042003202d37039807200341b8076a41186a2005280200360200200341b8076a41106a2004290300370300200341b8076a41086a201829030037030020032003290390093703b807411410272205450d01200541106a410028009c9342360000200541086a410029009493423700002005410029008c934237000020054114413410282205450d02200520032f0190043b00142005200236001b20052006360017200520032903980737001f200541166a20034190046a41026a22042d00003a0000200541276a20034198076a41086a2903003700002005412c6a20034198076a410d6a290000370000200341d0046a41186a22184200370300200341d0046a41106a22194200370300200341d0046a41086a220c4200370300200342003703d00420054134200341d0046a100020034188086a41186a201829030037030020034188086a41106a201929030037030020034188086a41086a200c290300370300200320032903d00437038808200341203602d404200320034188086a3602d004200341b8076a200341d0046a105b200510290240200341b8076a41106a280200450d0020032802c40710290b2004200341f0036a41026a2d00003a0000200341b8076a41086a200341b0046a41086a290300370300200341b8076a410d6a200341b0046a410d6a290000370000200320032f01f0033b019004200320032903b0043703b807411510272205450d032005410d6a41002900ce9242370000200541086a41002900c99242370000200541002900c1924237000020054115413510282205450d04200520032f0190043b00152005200236001c20052006360018200520032903b807370020200541176a20034192046a2d00003a0000200541286a200341b8076a41086a2903003700002005412d6a200341b8076a410d6a290000370000200341d0046a41186a22044200370300200341d0046a41106a22184200370300200341d0046a41086a22194200370300200342003703d00420054135200341d0046a100020034188086a41186a200429030037030020034188086a41106a201829030037030020034188086a41086a2019290300370300200320032903d00437038808200341003602d804200342013703d004200320073602980720034198076a200341d0046a10300240024020032802d404221920032802d80422186b2007490d0020032802d00421040c010b201820076a22042018490d012019410174220c20042004200c491b220c4100480d010240024020190d00200c102721040c010b20032802d0042019200c102821040b2004450d062003200c3602d404200320043602d004200c21190b200420186a2009200710ce041a20034188086a41202004201820076a100302402019450d00200410290b2005102902402008450d00200910290b20034198076a41026a2205200341f0036a41026a2d00003a000020034188086a41086a2204200341b0046a41086a29030037030020034188086a410d6a2218200341b0046a410d6a290000370000200320032f01f0033b019807200320032903b00437038808200341d0046a41086a41023a0000200341e0046a2002360200200341dc046a20063602002003410b3a00d004200341d9046a20032f0198073b0000200341d0046a410b6a20052d00003a0000200341e4046a200329038808370200200341ec046a2004290300370200200341f1046a20182900003700004100210541b8d6c5004100200341d0046a10880120034198066a200a202c200b201a201e201b10f8020c070b102b000b41144101102a000b41344101102a000b41154101102a000b41354101102a000b200c4101102a000b02402008450d00200910290b20034198066a200a202c200b201a201e201b10f8020b41012118410021060c030b41012118410021062008450d02200910290c020b0b41012106410121180b41012119410121080b02400240024020012d0000220441064b0d00024002400240024020040e0706060001020603060b2006450d05200141086a280200450d05200141046a28020010290c050b2018450d042001412c6a280200450d04200141286a28020010290c040b2019450d03200141286a280200450d03200141246a28020010290c030b20080d010c020b200141c8006a280200450d01200141c4006a28020010290c010b200141c8006a280200450d00200141c4006a28020010290b2000200236020420002005360200200341e00a6a24000b3400200041d0f4c10036020420004100360200200041146a4101360200200041106a4180f9c100360200200041086a42043702000b130020004102360204200041dcf4c1003602000b950101057f230041206b22022400200241186a22034200370300200241106a22044200370300200241086a220542003703002002420037030002404120102722060d0041204101102a000b20062002290300370000200042a0808080800437020420002006360200200641186a2003290300370000200641106a2004290300370000200641086a2005290300370000200241206a24000bb014030c7f017e017f230041e0006b2201240020014100360208200142043703000240024002400240024002400240024002400240024002400240024002400240200041106a28020041246c22020d004104210341002104410021050c010b20002802082106410421034100210441002107410021050340024020062d00004101470d00200641106a2802002208417f4c0d03200641016a28000021090240024020080d004101210a0c010b200641086a280200210b20081027220a450d05200a200b200810ce041a0b200141c0006a41086a220c200141206a41086a29020037030020012001290220370340024020052007470d00024020042007460d00200421070c010b200441016a220b2004490d1020044101742207200b200b2007491b2207ad42247e220d422088a70d10200da7220b4100480d100240024020040d00200b102721030c010b2003200441246c200b102821030b2003450d062001200736020420012003360200200721040b2003200541246c6a220b2008360210200b200836020c200b200a360208200b2009360001200b41013a0000200b2001290340370214200b411c6a200c2903003702002001200541016a22053602080b200641246a21062002415c6a22020d000b0b2001410036024041ff88c3004110200141c0006a41041003200141c0006a41086a220642003703002001420037034041888dc300410d200141c0006a1004200141206a41086a220b20062903003703002001200129034037032020012000290300220d370340200141206a4110200141c0006a41081003200642003703002001420037034041aa8dc300410d200141c0006a1004200b200629030037030020012001290340370320200141103602442001200141206a3602402001200141c0006a105c200642003703002001420037034041d18fc3004111200141c0006a1004200b200629030037030020012001290340370320200141206a4110200041146a220241201003411010272206450d03200641086a41002900bf8d43370000200641002900b78d433700002006411041201028220b450d04200b200d427f7c370010200141c0006a41186a22084200370300200141c0006a41106a220a4200370300200141c0006a41086a2206420037030020014200370340200b4118200141c0006a1000200141206a41186a2008290300370300200141206a41106a200a290300370300200141206a41086a2208200629030037030020012001290340370320200141206a4120200241201003200b1029200642003703002001420037034041958dc3004115200141c0006a10042008200629030037030020012001290340370320200141206a4110200041d4006a41201003200642003703002001420037034041e28fc3004115200141c0006a10042008200629030037030020012001290340370320200141106a200141206a10ba020240200128021422060d002001410136020c4100210b4100210e410021080c070b2001200636020c20012c001021082001280218210e2001411c6a280200220b41d100490d06200141c0006a41186a220a2000412c6a290000370300200141c0006a41106a2207200041246a290000370300200141c0006a41086a22092000411c6a29000037030020012000290014370340200b20084d0d05200620084105746a22022001290340370000200241186a200a290300370000200241106a2007290300370000200241086a2009290300370000200841187441808080086a41187541d1006f21080c070b1039000b20084101102a000b200b4104102a000b41104101102a000b41204101102a000b41f88fc3002008200b1037000b200141d8006a2000412c6a290000370300200141d0006a200041246a290000370300200141c8006a2000411c6a2900003703002001200029001437034002400240200b200e460d00200128020c21060c010b200b41016a2206200b490d06200b4101742202200620062002491b220e41ffffff3f71200e470d06200e41057422024100480d0602400240200b0d002002102721060c010b200128020c200b4105742002102821060b2006450d022001200636020c0b2006200b4105746a22022001290340370000200241186a200141c0006a41186a290300370000200241106a200141c0006a41106a290300370000200241086a200141c0006a41086a290300370000200b41016a210b0b200141c0006a41086a220242003703002001420037034041e28fc3004115200141c0006a1004200141206a41086a2002290300370300200120012903403703202001410036024820014201370340410110272202450d01200220083a00002001428180808010370244200120023602402001200b360210200b4105742109200141106a200141c0006a103041002001280248220b6b2102200128024021072001280244210a03400240200a20026a411f4b0d00200b41206a2208200b490d06200a410174220c20082008200c491b22084100480d0602400240200a0d002008102721070c010b2007200a2008102821070b2007450d072008210a0b2007200b6a22082006290000370000200841186a200641186a290000370000200841106a200641106a290000370000200841086a200641086a290000370000200241606a2102200b41206a210b200641206a2106200941606a22090d000b200141206a41102007200b10030240200a450d00200710290b0240200e450d00200128020c10290b200141c0006a41086a2206420037030020014200370340418890c300410d200141c0006a1004200141206a41086a2208200629030037030020012001290340370320200141206a4110100c20064200370300200142003703404187cec5004111200141c0006a10042008200629030037030020012001290340370320200141206a4110100c41121027220b450d02200b41106a41002f00a590433b0000200b41086a410029009d9043370000200b41002900959043370000200141c0006a41186a22024200370300200141c0006a41106a220a42003703002006420037030020014200370340200b4112200141c0006a1000200141206a41186a22072002290300370300200141206a41106a200a2903003703002008200629030037030020012001290340370320412010272206450d0320062001290320370000200641186a2007290300370000200641106a200141206a41106a290300370000200641086a200141206a41086a290300370000200b102920064120100e20061029200029030010bb0202402005450d00200541246c210b2003210603400240024020062d0000220841034b0d0002400240024020080e0404000102040b2006410c6a280200450d03200641086a28020010290c030b2006410c6a280200450d02200641086a28020010290c020b2006410c6a280200450d01200641086a28020010290c010b200641086a280200450d00200641046a28020010290b200641246a2106200b415c6a220b0d000b0b02402004450d00200310290b200141e0006a24000f0b20024101102a000b41014101102a000b41124101102a000b41204101102a000b102b000b20084101102a000b9d0202057f017e230041306b220224002002410036022020014110200241206a100521010240024002400240024020022802202203417f460d0020010d010b200041003602040c010b2002200136021020022003360214200241003a0020200241206a20012003410047220410ce041a20032004490d012002200320046b3602142002200120046a3602102003450d0220022d00202103200241206a200241106a102d20022802202204450d022002410c6a41026a2002411d6a41026a2d000022053a0000200220022f001d22063b010c20022902242107200020033a0000200020063b0001200041036a20053a00002000200737020820002004360204200110290b200241306a24000f0b20042003103e000b418f89c3004133104e000b93b10108047f017e207f017e057f037e127f0c7e230041c00c6b2201240020014198056a41086a22024200370300200142003703980541aa8dc300410d20014198056a1004200141d8076a41086a200229030037030020012001290398053703d807200141003602980b200141d8076a4110200141980b6a100521020240024002400240024002400240024002400240024020012802980b2203417f460d002002450d00200120033602bc06200120023602b806200141980b6a200141b8066a104320012802980b2204450d02200129029c0b210502402003450d00200210290b20042005422088a7220641246c22076a2103200421020240200741ed00490d00200141980b6a41086a2108200421020340024020022d00004101470d00200241016a2800002107200241086a28020021092001200241106a2802003602840a200120093602800a0240200741c28289aa04460d00200142003703980b0c010b200141980b6a200141800a6a10880220012903980b4201520d00200141d8076a200841f00010ce041a200141b8066a200141d8076a41f00010ce041a200141b8066a21020c060b0240200241246a2d00004101470d00200241256a28000021072002412c6a28020021092001200241346a2802003602840a200120093602800a0240200741c28289aa04460d00200142003703980b0c010b200141980b6a200141800a6a10880220012903980b4201520d00200141d8076a200841f00010ce041a200141b8066a200141d8076a41f00010ce041a200141b8066a21020c060b0240200241c8006a2d00004101470d00200241c9006a2800002107200241d0006a28020021092001200241d8006a2802003602840a200120093602800a0240200741c28289aa04460d00200142003703980b0c010b200141980b6a200141800a6a10880220012903980b4201520d00200141d8076a200841f00010ce041a200141b8066a200141d8076a41f00010ce041a200141b8066a21020c060b0240200241ec006a2d00004101470d00200241ed006a2800002107200241f4006a28020021092001200241fc006a2802003602840a200120093602800a0240200741c28289aa04460d00200142003703980b0c010b200141980b6a200141800a6a10880220012903980b4201520d00200141d8076a200841f00010ce041a200141b8066a200141d8076a41f00010ce041a200141b8066a21020c060b200320024190016a22026b41ec004b0d000b0b20022003460d012004200641246c6a2103200141980b6a41086a21060340024020022d00004101470d00200241016a2800002107200241086a28020021092001200241106a2802003602840a200120093602800a0240200741c28289aa04460d00200142003703980b0c010b200141980b6a200141800a6a10880220012903980b4201520d00200141d8076a200641f00010ce041a200141b8066a200141d8076a41f00010ce041a200141b8066a21020c050b2003200241246a2202470d000c020b0b42002105410421040b02402005422088a72202450d00200241246c21032004210203400240024020022d0000220741034d0d00200241086a280200450d01200241046a28020010290c010b02400240024020070e0403000102030b2002410c6a280200450d02200241086a28020010290c020b2002410c6a280200450d01200241086a28020010290c010b2002410c6a280200450d00200241086a28020010290b200241246a21022003415c6a22030d000b0b2005a70d020c030b418f89c3004133104e000b20022d002f210720022d002e210920022d002d210620022d002c210820022d002b210a20022d002a210b20022d0029210c20022d0028210d20022d0027210e20022d0026210f20022d0025211020022d0024211120022d0023211220022d0022211320022d0021211420022d0020211520022d001f211620022d001e211720022d001d211820022d001c211920022d001b211a20022d001a211b20022d0019211c20022d0018211d20022d0017211e20022d0016211f20022d0015212020022d0014212120022d0013212220022d0012212320022d0011212420022d0010212520022903002126200141b8046a41e2c5c50041131094010240024020012903c004500d0020012802b8040d010b20014198056a41086a22024200370300200142003703980541e2c5c500411320014198056a1004200141d8076a41086a200229030037030020012001290398053703d807200120263703980b200141d8076a4110200141980b6a410810030b20014198056a41086a22024200370300200142003703980541f5c5c500411020014198056a1004200141d8076a41086a200229030037030020012001290398053703d807200120263703980b200141d8076a4110200141980b6a4108100320024200370300200142003703980541a7c6c500411620014198056a1004200141b8066a41086a200229030037030020012001290398053703b806200141003602980b200141b8066a4110200141980b6a100521020240024020012802980b2203417f460d002002450d00200141980b6a2003412020034120491b22276a41004100412020276b2027411f4b1b10cd041a200141980b6a2002202710ce041a2003411f4d0d04200141d8076a41186a2203200141980b6a41186a2227290000370300200141d8076a41106a2228200141980b6a41106a2229290000370300200141d8076a41086a222a200141980b6a41086a222b290000370300200120012900980b3703d8072002102920272003290300222637030020292028290300222c370300202b202a290300222d370300200120012903d807222e3703980b2026a72102202ca72103202da72127202ea7212820012d00af0b212920012d00ae0b212a20012d00ad0b212b20012d00ac0b212f20012d00ab0b213020012d00aa0b213120012d00a90b213220012d00a70b213320012d00a60b213420012d00a50b213520012d00a40b213620012d00a30b213720012d00a20b213820012d00a10b213920012d009f0b213a20012d009e0b213b20012d009d0b213c20012d009c0b213d20012d009b0b213e20012d009a0b213f20012d00990b21400c010b200141a00b6a4200370300200141a80b6a4200370300200141b00b6a4200370300200142003703980b41002102410021294100212a4100212b4100212f4100213041002131410021324100210341002133410021344100213541002136410021374100213841002139410021274100213a4100213b4100213c4100213d4100213e4100213f41002140410021280b20012002200d733a00b00b20012029200e733a00af0b2001202a200f733a00ae0b2001202b2010733a00ad0b2001202f2011733a00ac0b200120302012733a00ab0b200120312013733a00aa0b200120322014733a00a90b200120032015733a00a80b200120332016733a00a70b200120342017733a00a60b200120352018733a00a50b200120362019733a00a40b20012037201a733a00a30b20012038201b733a00a20b20012039201c733a00a10b20012027201d733a00a00b2001203a201e733a009f0b2001203b201f733a009e0b2001203c2020733a009d0b2001203d2021733a009c0b2001203e2022733a009b0b2001203f2023733a009a0b200120402024733a00990b200120282025733a00980b200120012d00b10b200c733a00b10b200120012d00b20b200b733a00b20b200120012d00b30b200a733a00b30b200120012d00b40b2008733a00b40b200120012d00b50b2006733a00b50b200120012d00b60b2009733a00b60b200120012d00b70b2007733a00b70b20014198056a41086a22024200370300200142003703980541a7c6c500411620014198056a1004200141d8076a41086a200229030037030020012001290398053703d807200141d8076a4110200141980b6a4120100302402005422088a72202450d00200241246c21032004210203400240024020022d0000220741034b0d0002400240024020070e0404000102040b2002410c6a280200450d03200241086a28020010290c030b2002410c6a280200450d02200241086a28020010290c020b2002410c6a280200450d01200241086a28020010290c010b200241086a280200450d00200241046a28020010290b200241246a21022003415c6a22030d000b0b2005a7450d010b200410290b20014198056a41086a220242003703002001420037039805418bf4c200411120014198056a100420014188066a41086a2002290300370300200120012903980537038806200141003602980b20014188066a4110200141980b6a100521020240024020012802980b2203417f460d002002450d00200120033602dc07200120023602d807200141980b6a200141d8076a104620012802980b2204450d03200129029c0b21052003450d01200210290c010b41082104420021050b20042005422088a7220641c8006c22026a21090240200241d9014f0d0041002102200421030c040b200441e0016a21034100210203400240200341a07e6a22072d00004101460d00200341a87e6a29030020005a0d060b0240200741c8006a2d00004101460d00200341f07e6a2903002000540d00200241016a21020c060b024020074190016a2d00004101460d00200341b87f6a2903002000540d00200241026a21020c060b02400240200741d8016a2d00004101460d00200329030020005a0d010b200341a0026a2103200241046a21022009200741a0026a6b41d8014d0d040c010b0b200241036a21020c040b418f89c3004133104e000b418f89c3004133104e000b200341a07e6a21030b20032009460d002004200641c8006c6a21070340024020032d00004101460d00200341086a29030020005a0d020b200241016a21022007200341c8006a2203470d000b0b02400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240200220064b0d000240200620026b2203450d002002450d0020042004200241c8006c6a200341c8006c10cf041a0b200141003a00980b20014198056a41086a22024200370300200142003703980541fcc7c500411720014198056a100420014188066a41086a200229030037030020012001290398053703880620014188066a4110200141980b6a41011003200141d8076a109801200141980b6a41186a200141d8076a41186a290300370300200141980b6a41106a200141d8076a41106a290300370300200141980b6a41086a2202200141d8076a41086a290300370300200120012903d8073703980b200141980b6a411410960302402005a7450d00200410290b20024200370300200142003703980b41f5c5c5004110200141980b6a1004200141e8056a41086a2002290300370300200120012903980b3703e805200141003602980b200141e8056a4110200141980b6a1005210202400240024020012802980b2203417f470d00420021050c010b024020020d00420021050c010b200142003703980b200141980b6a20022003410820034108491b10ce041a200341074d0d0120012903980b2105200210290b42002126200141980b6a41086a22024200370300200142003703980b41e2c5c5004113200141980b6a1004200141e8056a41086a2002290300370300200120012903980b3703e805200141003602980b200141e8056a4110200141980b6a100521020240024020012802980b2203417f460d002002450d00200142003703980b200141980b6a20022003410820034108491b10ce041a200341074d0d0120012903980b2126200210290b4200200520267d222620262005561b42eb02540d07200141b0046a4193c8c500411410b50120012802b404211c20012802b004211d200141980b6a41086a22024200370300200142003703980b41b6c8c5004115200141980b6a1004200141e8056a41086a2002290300370300200120012903980b3703e805200141003602980b200141e8056a4110200141980b6a10052102024002400240024020012802980b2203417f470d00410221190c010b024020020d00410221190c010b200141003a00980b200141980b6a20022003410047220710ce041a20032007490d022003450d0120012d00980b2119200210290b41a7c8c500410f108a02211f200141980b6a41086a22024200370300200142003703980b4190e1c1004112200141980b6a1004200141e8056a41086a2002290300370300200120012903980b3703e805200141003602980b200141e8056a4110200141980b6a1005211a0240024002400240024002400240024002400240024002400240024020012802980b221b417f460d00201a450d002001201b3602dc052001201a3602d805200141a8046a200141d8056a102e20012802a804450d2b0240024020012802ac042218412a2018412a491b22170d004101210e0c010b201741e0006c22021027220e450d0e0b02402018450d00200141980b6a41206a2102200141b8066a41206a210920012802d805210420012802dc0521074100210b4100210a410021080340200141f8046a2007412020074120491b22036a41004100412020036b2003411f4b1b10cd041a200141f8046a2004200310ce041a2001200420036a22063602d805200720036b21040240024002402007411f4b0d00200120043602dc050c010b200141d8046a41186a2210200141f8046a41186a220c290000370300200141d8046a41106a2211200141f8046a41106a220d290000370300200141d8046a41086a2212200141f8046a41086a220f290000370300200120012900f8043703d804200141f8046a2004412020044120491b22036a41004100412020036b2003411f4b1b10cd041a200141f8046a2006200310ce041a2001200620036a22073602d805200420036b210602402004411f4b0d00200120063602dc050c010b20014198056a41086a2213200f29000037030020014198056a41106a2214200d29000037030020014198056a41186a2215200c290000370300200120012900f80422053703b8052001200537039805200141f8046a2006412020064120491b22036a41004100412020036b2003411f4b1b10cd041a200141f8046a2007200310ce041a2001200720036a22043602d805200620036b21072006411f4b0d01200120073602dc050b2017450d2e200e10290c2e0b200841016a2103200141f8086a41086a2206200f290000370300200141f8086a41106a220f200d290000370300200141f8086a41186a220d200c290000370300200141b8066a41186a220c2015290300370300200141b8066a41106a22152014290300370300200141b8066a41086a22142013290300370300200120012900f80422053703b805200120053703f80820012001290398053703b806200920012903f808370000200941086a2006290300370000200941106a200f290300370000200941186a200d290300370000200141800a6a41386a2206200141b8066a41386a290300370300200141800a6a41306a220d200141b8066a41306a290300370300200141800a6a41286a220f200141b8066a41286a290300370300200141800a6a41206a22132009290300370300200141800a6a41186a2216200c290300370300200141800a6a41106a220c2015290300370300200141800a6a41086a22152014290300370300200120012903b8063703800a200141980b6a41186a2010290300370300200141980b6a41106a2011290300370300200141980b6a41086a2012290300370300200120012903d8043703980b200220012903800a370000200241086a2015290300370000200241106a200c290300370000200241186a2016290300370000200241206a2013290300370000200241286a200f290300370000200241306a200d290300370000200241386a2006290300370000200141d8076a200141980b6a41e00010ce041a024020082017470d00200b20032003200b491b2217ad42e0007e2205422088a70d2d2005a722064100480d2d0240024020080d0020061027210e0c010b200e200a20061028210e0b200e450d050b200e200a6a200141d8076a41e00010ce041a200b41026a210b200a41e0006a210a2003210820182003470d000b200120073602dc050b200e450d2b201b450d01201a10290c010b4101210e41002118410021170b4100210702400240201841e0006c22020d004101211b4100211e0c010b200241e0006e221e41057422031027221b450d0b0b0240200e200e20026a22164622140d00201841e0006c210941002107201b2102200e2103034020022003290000370000200241186a200341186a290000370000200241106a200341106a290000370000200241086a200341086a290000370000200741016a2107200241206a2102200341e0006a2103200941a07f6a22090d000b0b200141980b6a41086a22024200370300200142003703980b41abccc1004112200141980b6a1004200141e8056a41086a2002290300370300200120012903980b3703e805200141003602a00b200142013703980b200120073602d807200141d8076a200141980b6a10300240024020070d0020012802a00b2103200128029c0b210420012802980b21060c010b20074105742108410020012802a00b22036b210920012802980b2106200128029c0b2104201b210203400240200420096a411f4b0d00200341206a22072003490d2b2004410174220a20072007200a491b22074100480d2b0240024020040d002007102721060c010b200620042007102821060b2006450d04200721040b200620036a22072002290000370000200741186a200241186a290000370000200741106a200241106a290000370000200741086a200241086a290000370000200941606a2109200341206a2103200241206a2102200841606a22080d000b2001200436029c0b200120033602a00b200120063602980b0b201c4100201d1b2102200141e8056a411020062003100302402004450d00200610290b200141c8046a200241026a10a4030240024020012802c804221a0d00200141980b6a41086a22034200370300200142003703980b41abccc1004112200141980b6a1004200141e8056a41086a2003290300370300200120012903980b3703e805200141003602980b200141e8056a4110200141980b6a100521070240024020012802980b2209417f460d002007450d00200120093602dc07200120073602d807200141980b6a200141d8076a102d20012802980b220f450d0d200141a00b6a2802002103200128029c0b21102009450d01200710290c010b4101210f41002103410021100b201f201f41ff01714102477121114100211c0c010b200141d0046a28020021034101211c20012802cc042110201a210f410121110b200141980b6a41086a22074200370300200142003703980b4193c8c5004114200141980b6a1004200141e8056a41086a2007290300370300200120012903980b3703e805410121122001200241016a22133602980b200141e8056a4110200141980b6a410410034100210b02400240200341057422020d004100211d0c010b2002410575221dad42e0007e2205422088a70d292005a722074100480d29200710272212450d090b0240200f20026a200f460d0020034105742104200141d8076a4101722107200141980b6a41206a21024100210b20122106200f21030340200341086a2900002105200341106a29000021262003290000212c200141b8066a41186a2208200341186a290000370300200141b8066a41106a220a2026370300200141b8066a41086a220c20053703002001202c3703b806200141f8086a200141b8066a108d01200141d8076a20012802f808220d200128028009108e0141002109024020012d00d8074101470d00200141800a6a41386a200741386a290000370300200141800a6a41306a200741306a290000370300200141800a6a41286a200741286a290000370300200141800a6a41206a200741206a290000370300200141800a6a41186a200741186a290000370300200141800a6a41106a200741106a290000370300200141800a6a41086a200741086a290000370300200120072900003703800a410121090b024020012802fc08450d00200d10290b0240024020090d00200141d8076a41386a4200370300200141d8076a41306a4200370300200141d8076a41286a4200370300200141d8076a41206a4200370300200141d8076a41186a4200370300200141d8076a41106a4200370300200141d8076a41086a4200370300200142003703d8070c010b200141d8076a41386a200141800a6a41386a290300370300200141d8076a41306a200141800a6a41306a290300370300200141d8076a41286a200141800a6a41286a290300370300200141d8076a41206a200141800a6a41206a290300370300200141d8076a41186a200141800a6a41186a290300370300200141d8076a41106a200141800a6a41106a290300370300200141d8076a41086a200141800a6a41086a290300370300200120012903800a3703d8070b200341206a2103200220012903d807370000200141980b6a41086a200c290300370300200141980b6a41106a200a290300370300200141980b6a41186a2008290300370300200241086a200141d8076a41086a290300370000200241106a200141d8076a41106a290300370000200241186a200141d8076a41186a290300370000200241206a200141d8076a41206a290300370000200241286a200141d8076a41286a290300370000200241306a200141d8076a41306a290300370000200241386a200141d8076a41386a290300370000200120012903b8063703980b200b41016a210b2006200141980b6a41e00010ce0441e0006a2106200441606a22040d000b0b02402010450d00200f10290b200bad42e0007e2205422088a70d072005a72202417f4c0d070240024020020d004101210c0c010b20021027220c450d070b410021090240200b450d002012200b41e0006c6a2106200141980b6a41c0006a2103200141980b6a41206a210741002109200c2104201221020340200141980b6a41186a200241186a290000370300200141980b6a41106a200241106a290000370300200141980b6a41086a200241086a290000370300200120022900003703980b2007200241206a290000370000200741086a200241286a290000370000200741106a200241306a290000370000200741186a200241386a2900003700002003200241c0006a290000370000200341086a200241c8006a290000370000200341106a200241d0006a290000370000200341186a200241d8006a290000370000200941016a21092004200141980b6a41e00010ce0441e0006a2104200241e0006a22022006470d000b0b200141980b6a41086a22024200370300200142003703980b4190e1c1004112200141980b6a1004200141e8056a41086a2002290300370300200120012903980b3703e805200141003602a00b200142013703980b200120093602d807200141d8076a200141980b6a10300240024020090d0020012802a00b2102200128029c0b210320012802980b21070c010b200c200941e0006c6a210d410020012802a00b22066b210420012802980b2107200128029c0b2103410021090340200620096a210a0240024002400240200320046a411f4b0d00200a41206a2202200a490d2e20034101742208200220022008491b22024100480d2e0240024020030d002002102721070c010b200720032002102821070b2007450d01200221030b200720066a20096a2208200c20096a2202290000370000200841186a200241186a290000370000200841106a200241106a290000370000200841086a200241086a290000370000200320046a41606a411f4b0d02200a41206a220f41206a2208200f490d2d2003410174220f20082008200f491b220841004e0d010c2d0b20024101102a000b0240024020030d002008102721070c010b200720032008102821070b2007450d05200821030b200720066a20096a220841386a200241386a290000370000200841306a200241306a290000370000200841286a200241286a290000370000200841206a200241206a2900003700000240200320046a41406a411f4b0d00200a41c0006a220a41206a2208200a490d2b2003410174220a20082008200a491b22084100480d2b0240024020030d002008102721070c010b200720032008102821070b2007450d06200821030b200720066a20096a220841d8006a200241d8006a290000370000200841d0006a200241d0006a290000370000200841c8006a200241c8006a290000370000200841c0006a200241c0006a290000370000200441a07f6a2104200941e0006a2109200241e0006a200d470d000b2001200336029c0b200120073602980b2001200620096a22023602a00b0b200141e8056a411020072002100302402003450d00200710290b0240200b450d00200c10290b200120113a00d807200141980b6a41086a22024200370300200142003703980b41b6c8c5004115200141980b6a1004200141e8056a41086a2002290300370300200120012903980b3703e805200141e8056a4110200141d8076a410110032001201336029c0b200141043a00980b41b8d6c5004100200141980b6a108801410810272203450d05200320163602042003200e3602002019201941ff017141024771450d110240024020140d002003200e41e0006a360200200141980b6a41186a2202200e41386a290000370300200141980b6a41106a2207200e41306a290000370300200141980b6a41086a2209200e41286a2900003703002001200e290020220537039805200120053703980b200e0d010b2003102941002102410821044108210f410021070c140b200141d8076a41186a2002290300370300200141d8076a41106a2007290300370300200141d8076a41086a2009290300370300200120012903980b3703d807200328020420032802006b41e0006e41016a2202ad42287e2205422088a70d072005a7220710272204450d04200420012903d80737030020044201370320200441186a200141d8076a41186a2213290300370300200441106a200141d8076a41106a2214290300370300200441086a200141d8076a41086a22152903003703000240200328020022072003280204470d00410121072004210f0c130b2003200741e0006a36020020014198056a41086a2218200741286a2900002205370300200141980b6a41186a2206200741386a290000370300200141980b6a41106a2208200741306a290000370300200141980b6a41086a220a200537030020012007290020220537039805200120053703980b4102210741c800210903402013200629030022053703002014200829030022263703002015200a290300222c370300200120012903980b222d3703d807200141f8046a41186a220c2005370300200141f8046a41106a220d2026370300200141f8046a41086a220f202c3703002001202d3703f80402400240024002402007417f6a2002460d00200221100c010b200328020420032802006b41e0006e20026a41016a22102002490d2c20024101742211201020102011491b2210ad42287e2205422088a70d2c2005a722114100480d2c0240024020020d002011102721040c010b2004200241286c2011102821040b2004450d010b200420096a221141606a220220012903f804370300200f2903002105200d2903002126200c290300212c20114201370300200241186a202c370300200241106a2026370300200241086a2005370300200328020022022003280204470d012004210f201021020c150b20114108102a000b2003200241e0006a3602002018200241286a29000022053703002006200241386a2900003703002008200241306a290000370300200a200537030020012002290020220537039805200120053703980b200941286a2109200741016a2107201021020c000b0b20064101102a000b20074101102a000b20084101102a000b20084101102a000b20074108102a000b41084104102a000b20024101102a000b1039000b20074101102a000b418f89c3004133104e000b20034101102a000b20024101102a000b418f89c3004133104e000b20072003103e000b418f89c3004133104e000b418f89c3004133104e000b419cb1c5001058000b200310290c020b200310290b200141b8056a41086a22034200370300200142003703b80541c6c4c500411b200141b8056a1004200141980b6a41086a2003290300370300200120012903b8053703980b200141003602d807200141980b6a4110200141d8076a100521030240024020012802d8072206417f460d002003450d00200120063602bc06200120033602b806200141d8076a200141b8066a104120012802d807220d450d14200141e0076a280200210920012802dc0721102006450d01200310290c010b4108210d41002109410021100b0240024020072009470d00200f200d460d01200741286c41286e22032007200720034b1b210c417f2106200f2103200d21090340200641016a2206200c4f0d02024020032009460d0020032009412010d0040d020b200941206a2108200341206a210a200341286a2103200941286a2109200a2903002008290300510d000b0b200141b8056a41086a22034200370300200142003703b8054199a7c1004117200141b8056a1004200141980b6a41086a2003290300370300200120012903b8053703980b200141003602d807200141980b6a4110200141d8076a1005210302400240024020012802d8072209417f460d002003450d00200142003703d807200141d8076a200320094108200941084922061b220410ce041a024020060d0020012903d8072105200142003703d807200141d8076a200320046a200920046b2209410820094108491b10ce041a200941074b0d020b418f89c3004133104e000b200120073602a00b2001200236029c0b200120043602980b200141980b6a42004200200510f6010c010b20012903d807212620031029200141980b6a4110100c200120073602a00b2001200236029c0b2001200f3602980b200141980b6a20054201202610f6010b2010450d01200d10290c010b02402010450d00200d10290b2002450d00200410290b410810272202450d10200220163602042002200e360200410810272203450d0f20032012200b41e0006c6a220f3602042003201236020020014198046a41c3c5c500410f10940120012903a00442002001280298041b220542017c222d2005540d0e200141b8056a41086a22074200370300200142003703b80541c3c5c500410f200141b8056a1004200141b8066a41086a22092007290300370300200120012903b8053703b8062001202d3703980b200141b8066a4110200141980b6a4108100320014184cac10036029c0b200120023602980b2001200141800a6a3602a00b200141d8056a200141980b6a104c200141980b6a41086a200141d8056a41086a280200360200200120012903d8053703980b20074200370300200142003703b80541d2c5c5004110200141b8056a100420092007290300370300200120012903b8053703b806200141103602dc072001200141b8066a3602d807200141980b6a200141d8076a102f0240200128029c0b450d0020012802980b10290b20014188046a41f5c5c500411010940120012903900421052001280288042102200141f8036a41e2c5c5004113109401024042002005420020021b2226200129038004420020012802f8031b22057d222c202c2026561b42eb02540d00034042002026427f200542eb027c222c202c2005541b22057d222c202c2026561b42ea02560d000b0b200141b8056a41086a22024200370300200142003703b80541e2c5c5004113200141b8056a1004200141b8066a41086a2002290300370300200120012903b8053703b806200120053703980b200141b8066a4110200141980b6a41081003202d42017c2205202d540d0d20024200370300200142003703b8054194c6c5004113200141b8056a100420014188066a41086a2002290300370300200120012903b80537038806200141003602980b20014188066a4110200141980b6a100521020240024020012802980b2207417f460d002002450d00200141f8086a2007412020074120491b22096a41004100412020096b2009411f4b1b10cd041a200141f8086a2002200910ce041a2007411f4d0d0e20014198056a41186a2207200141f8086a41186a29030037030020014198056a41106a2209200141f8086a41106a29030037030020014198056a41086a2204200141f8086a41086a290300370300200120012903f8083703980520021029200141d8076a41186a2007290300370300200141d8076a41106a2009290300370300200141d8076a41086a200429030037030020012001290398053703d8070c010b200141e0076a4200370300200141e8076a4200370300200141f0076a4200370300200142003703d8070b200141d8046a41186a200141d8076a41186a290300370300200141d8046a41106a200141d8076a41106a290300370300200141d8046a41086a200141d8076a41086a290300370300200120012903d8073703d804200141b8056a41086a22024200370300200142003703b80541a7c6c5004116200141b8056a100420014198056a41086a2002290300370300200120012903b80537039805200141003602980b20014198056a4110200141980b6a100521020240024020012802980b2207417f460d002002450d0020014188066a2007412020074120491b22096a41004100412020096b2009411f4b1b10cd041a20014188066a2002200910ce041a2007411f4d0d0d200141b8056a41186a220720014188066a41186a290300370300200141b8056a41106a220920014188066a41106a290300370300200141b8056a41086a220420014188066a41086a29030037030020012001290388063703b80520021029200141f8046a41186a2007290300370300200141f8046a41106a2009290300370300200141f8046a41086a2004290300370300200120012903b8053703f8040c010b20014180056a420037030020014188056a420037030020014190056a4200370300200142003703f8040b200141980b6a41186a200141d8046a41186a290300370300200141980b6a41106a200141d8046a41106a290300370300200141980b6a41086a2209200141d8046a41086a290300370300200141c80b6a200141f8046a41086a290300370300200141d00b6a200141f8046a41106a290300370300200141d80b6a200141f8046a41186a290300370300200120012903d8043703980b200120053703b80b200120012903f8043703c00b200141b8056a41186a22074200370300200141b8056a41106a22044200370300200141b8056a41086a22024200370300200142003703b805200141980b6a41c800200141b8056a1000200141f8086a41186a2007290300370300200141f8086a41106a2004290300370300200141f8086a41086a2002290300370300200120012903b8053703f80820024200370300200142003703b80541a7c6c5004116200141b8056a1004200141b8066a41086a22072002290300370300200120012903b8053703b806200141b8066a411041b3b4c3004120100320024200370300200142003703b8054194c6c5004113200141b8056a100420072002290300370300200120012903b8053703b806200141b8066a4110200141f8086a41201003200141e8056a41186a200141d8076a41186a2903002226370300200141e8056a41106a200141d8076a41106a290300222c370300200141e8056a41086a200141d8076a41086a290300222d370300200120012903d807222e3703e80520014188066a41186a202637030020014188066a41106a202c37030020014188066a41086a202d3703002001202e3703880620024200370300200142003703b8054185c6c500410f200141b8056a100420072002290300370300200120012903b8053703b806200141b8066a411020014188066a4120100320014184cac10036029c0b200120033602980b2001200141800a6a3602a00b200141800a6a200141980b6a104c200141e8036a41e2c5c500411310940120012903f003212620012802e803210420024200370300200142003703b8054194c6c5004113200141b8056a100420092002290300370300200120012903b8053703980b200141003602d807200141980b6a4110200141d8076a100521020240024020012802d8072203417f460d002002450d0020014198056a2003412020034120491b22076a41004100412020076b2007411f4b1b10cd041a20014198056a2002200710ce041a2003411f4d0d0c200141f8046a41186a220320014198056a41186a290300370300200141f8046a41106a220720014198056a41106a290300370300200141f8046a41086a220920014198056a41086a29030037030020012001290398053703f80420021029200141f8086a41186a2003290300370300200141f8086a41106a2007290300370300200141f8086a41086a2009290300370300200120012903f8043703f8080c010b20014180096a420037030020014188096a420037030020014190096a4200370300200142003703f8080b200141d8076a41086a200141f8086a41086a290300370300200141d8076a41106a200141f8086a41106a290300370300200141d8076a41186a200141f8086a41186a290300370300200120012903f8083703d80720012802800a210c20012802840a211020012802880a2107200141003602a00b200142013703980b410110272202450d09200142818080801037029c0b200120023602980b200241013a000020024101410910282202450d0820014289808080900137029c0b200120023602980b200220053700010240200128029c0b220920012802a00b22036b41074b0d00200341086a22062003490d1420094101742208200620062008491b22064100480d140240024020090d002006102721020c010b200220092006102821020b2002450d082001200636029c0b200120023602980b0b2001200341086a3602a00b200220036a427f2026420020041b220542eb027c222620262005541b3700000240200128029c0b220920012802a00b22036b41074b0d00200341086a22042003490d1420094101742206200420042006491b22044100480d140240024020090d002004102721020c010b200220092004102821020b2002450d072001200436029c0b200120023602980b0b2001200341086a3602a00b200220036a42eb02370000200120073602b806200141b8066a200141980b6a10300240024020070d00200128029c0b210920012802a00b21020c010b200c200741286c6a210d410020012802a00b220a6b2104200128029c0b2109410021020340200a20026a210602400240200920046a4120490d0020012802980b21070c010b200641206a22032006490d1620094101742207200320032007491b22034100480d160240024020090d002003102721070c010b20012802980b20092003102821070b2007450d082001200336029c0b200120073602980b200321090b2007200a6a20026a220841186a200c20026a220341186a290000370000200841106a200341106a290000370000200841086a200341086a2900003700002001200641206a220b3602a00b20082003290000370000200341206a29030021050240200920046a41606a41074b0d00200b41086a2208200b490d162009410174220b20082008200b491b22084100480d160240024020090d002008102721070c010b200720092008102821070b2007450d072001200836029c0b200120073602980b200821090b2001200641286a3602a00b2007200a6a20026a41206a2005370000200441586a2104200241286a2102200d200341286a470d000b200a20026a21020b02400240200920026b4120490d0020012802980b21030c010b200241206a22032002490d1420094101742207200320032007491b22074100480d140240024020090d002007102721030c010b20012802980b20092007102821030b2003450d042001200736029c0b200120033602980b0b200320026a220341086a200141d8076a41086a2903003700002001200241206a3602a00b200320012903d807370000200341106a200141d8076a41106a290300370000200341186a200141d8076a41186a290300370000200141c3066a20012802a00b360000200120012903980b3700bb06200141a40b6a200141bf066a290000370000200141c28289aa043600990b200141023a00980b200120012900b80637009d0b200141980b6a10970302402010450d00200c10290b410810272203450d02200320163602042003200e360200410810272207450d012007200f36020420072012360200200141d8036a41888dc300410d10940120012903e003210520012802d8032102200141b8056a41086a22094200370300200142003703b80541d9b0c0004111200141b8056a1004200141980b6a41086a2009290300370300200120012903b8053703980b20012005420020021b3703d807200141980b6a4110200141d8076a41081003200141d0036a4193c8c500411410b50120012802d403210220012802d0032109200141c8036a41d685c500411810b5012002410020091b21020240024020012802c8030d00200141b8056a41086a22094200370300200142003703b80541d685c5004118200141b8056a1004200141980b6a41086a2009290300370300200120012903b8053703980b200120023602d807200141980b6a4110200141d8076a410410030c010b200220012802cc036b4107490d00200141b8056a41086a22094200370300200142003703b80541d685c5004118200141b8056a1004200141980b6a41086a2009290300370300200120012903b8053703980b200120023602d807200141980b6a4110200141d8076a41041003200141c0036a4193c8c500411410b50120012802c403210220012802c0032109200141b8036a41d685c500411810b5012002410020091b2109024020012802b8030d002009109e010c010b20012802bc03220220094f0d0003402002109e012009200241016a2202470d000b0b20071029200310290240201d450d00201210290b0240201a45201c720d0020012802cc04450d00201a10290b0240201e450d00201b10290b2017450d00200e10290b024020004280ce18824200520d000240024041f586c500411f108a02220241ff01714102460d0020024101710d010b200010a503450d01200010a6031a0c010b200010a603450d00200010a5031a0b200141b0036a41e286c500411310b50120012802b403210220012802b0032103200141a8036a41c986c500411910b501024002400240024002402002410020031b220220012802ac03410020012802a8031b22034f0d00200141a40b6a210902400340200141980b6a200210a70320012802a00b22074112470d012003200241016a2202470d000c020b0b20012903980b2105200141b8066a200941940110ce041a200141800a6a200141b8066a41940110ce041a200141a80b6a22092007360200200120053703a00b200120023602980b200141ac0b6a200141800a6a41940110ce04210420052000510d012009103d0b4100212941082128410021070c010b200141f8086a41086a2209200141980b6a41086a290300370300200120012903980b3703f808200141d8076a200441940110ce041a200141b8066a41086a22042009290300370300200120012903f8083703b806200141980b6a200141d8076a41940110ce041a41a80110272228450d02202820012903b80637030020282007360210202841086a2004290300370300202841146a200141980b6a41940110ce041a0240200241016a22022003490d0041012107410121290c010b200141980b6a41106a210c200141980b6a41146a2106200141a40b6a210841012129410121070340200141980b6a200210a703024020012802a00b22094112470d002003200241016a2202470d010c020b20012903980b2105200141b8066a200841940110ce041a200141800a6a200141b8066a41940110ce041a200120093602a80b200120053703a00b200120023602980b2006200141800a6a41940110ce042104024020052000510d00200c103d0c020b20014188066a41086a220a200141980b6a41086a290300370300200120012903980b37038806200141d8076a200441940110ce041a20014198056a41086a220b200a290300370300200120012903880637039805200141980b6a200141d8076a41940110ce041a024020292007470d00202941016a22042029490d172029410174220a20042004200a491b2204ad42a8017e2205422088a70d172005a7220a4100480d170240024020290d00200a102721280c010b2028202941a8016c200a102821280b2028450d03200421290b2028200741a8016c6a2204200129039805370300200441086a200b290300370300200441106a2009360200200441146a200141980b6a41940110ce041a200741016a2107200241016a22022003490d000b0b2028200741a8016c6a2123024020070d002028211e0c140b200141b8066a41086a2127200141980b6a41086a2111200141980b6a4104722102200141c4066a21252028211e0340201e41106a2802002103201e2902082105201e2802002109200141980b6a201e41146a41940110ce041a201e41a8016a211e20034112460d14200141800a6a200141980b6a41940110ce041a200120033602c006200120053703b8062025200141800a6a41940110ce041a200141d8076a200910a80320012802d80721080240024020012802e00722030d00420021414200214242002143420021444200212e420021450c010b200341057421044200212e200821034200214542002143420021444200214142002142034020014198036a200310950120014198036a41086a2903002126200129039803210520022003290000370000200241086a200341086a290000370000200241106a200341106a290000370000200241186a200341186a290000370000200120093602980b20014190036a200141980b6a10a90320012d00900341017121070240024020012d00910322060d00200141d0026a20052026420a420010d40420012903d002222c2105200141d0026a41086a290300222d21260c010b200141f0026a202642002006ad222c420010d30420014180036a20054200202c420010d304200141e0026a420042002005420010d304427f20014180036a41086a290300222c20012903f00220012903e0027c7c222d20012903f80220012903e80284420052202d202c547222061b212d427f20012903800320061b212c0b200341206a21034200202d20071b20447c4200202c20071b224620437c2243204654ad7c2144202d420020071b20427c202c420020071b222c20417c2241202c54ad7c2142202620457c2005202e7c222e200554ad7c2145200441606a22040d000b0b024020012802dc07450d00200810290b200141d8076a200910a80320012802d807210c0240024020012802e00722030d00420021464200214742002148420021494200212d4200214a0c010b200341057421044200212d200c21034200214a42002148420021494200214642002147034020022003290000370000200241086a200341086a2207290000370000200241106a200341106a2206290000370000200241186a200341186a2208290000370000200120093602980b200141c8026a200141980b6a10a90320012d00c802210a20012d00c902210b200141980b6a41186a2008290000370300200141980b6a41106a200629000037030020112007290000370300200120032900003703980b200141a8026a2009200141980b6a200b411010aa03200141a8026a41186a290300204a7c20012903b8022205202d7c222d200554ad7c214a4200200141a8026a41086a2903002205200a41017122071b20497c420020012903a802222620071b222c20487c2248202c54ad7c21492005420020071b20477c2026420020071b220520467c2246200554ad7c2147200341206a2103200441606a22040d000b0b024020012802dc07450d00200c10290b20014198056a41086a22214200370300200142003703980541b18ac000411620014198056a1004200141b8056a41086a2210202129030037030020012001290398053703b805200141003602980b200141b8056a4110200141980b6a100521030240024020012802980b2207417f460d002003450d00200142003703a00b200142003703980b200141980b6a20032007411020074110491b10ce041a02402007410f4d0d002011290300210520012903980b2126200310290c020b418f89c3004133104e000b42002126420021050b02400240202d202e7c222c420288204a20457c202c202d54ad7c222d423e8684222e202c85202d4202882245202d8584500d00202e204584500d00410021030240034020014198026a202c202d200341046a41fe007110d204200341026a2103200129039802222e202c8520014198026a41086a2903002245202d8584500d01202e2045844200520d000b0b20014188026a202c202d200341fe007110d20420012903880220014188026a41086a29030084212e42002145024020030d00202e420052ad212e0c020b202e420052ad212e0340200141e8016a202c202d41002003417e6a2207200720034b1b220341ff007110d204200141f8016a202e420186224b420184224a2045420186202e423f88842245204a204510d304204b204a20012903f80120012903e80156200141f8016a41086a290300222e200141e8016a41086a290300224c56202e204c511b1b212e20030d000c020b0b42002145202c202d84420052ad212e0b0240024020264202882005423e8684222c2026852005420288222d20058584500d00202c202d84500d004100210302400340200141d8016a20262005200341046a41fe007110d204200341026a210320012903d801222c202685200141d8016a41086a290300222d20058584500d01202c202d844200520d000b0b200141c8016a20262005200341fe007110d20420012903c801200141c8016a41086a29030084212c4200212d024020030d00202c420052ad212c0c020b202c420052ad212c0340200141a8016a2026200541002003417e6a2207200720034b1b220341ff007110d204200141b8016a202c420186224b420184224a202d420186202c423f8884222d204a202d10d304204b204a20012903b80120012903a80156200141b8016a41086a290300222c200141a8016a41086a290300224c56202c204c511b1b212c20030d000c020b0b4200212d2026200584420052ad212c0b02400240024002400240202e20458450450d004100210c0c010b204920447c204820437c2226204854ad7c2148204720427c204620417c2205204654ad7c214602400240024020012d00d0070e03010200010b2005202656204620485620462048511b210c0c020b0340200141d8006a20262048202e204510d404202c2241202d2242844200510d04200141d8006a41086a290300212c2001290358212d200141c8006a200520462041204210d4044101210c202d2001290348224354202c200141c8006a41086a290300224a54202c204a5122031b0d0202402043202d54204a202c5420031b450d004100210c0c030b200141386a202d202c202e204510d304200141286a2043204a2041204210d304024020052001290328222c7d222d2046200141286a41086a2903007d2005202c54ad7d224a84500d002048200141386a41086a2903007d2143202620012903382205542103202620057d212c202e210520452146202d212e204a21452041212620422148202c20432003ad7d222d84500d030c010b0b4100210c0c010b03402045214a202e2141202c202d844200510d0220014188016a200520462041204a10d40420014198016a20262048202c202d10d4044101210c200129039801224220012903880122435420014198016a41086a290300222e20014188016a41086a290300224554202e20455122031b0d01024020432042542045202e5420031b450d004100210c0c020b200141f8006a2042202e202c202d10d304200141e8006a204320452041204a10d304024020052001290368222e7d22452046200141e8006a41086a2903007d2005202e54ad7d22428450450d004100210c0c020b2048200141f8006a41086a2903007d2143202620012903782205542103202620057d212e202c2105202d21462045212c2042212d20412126204a2148202e20432003ad7d2245844200520d000b0b200141980b6a200910a80320012802980b2122200128029c0b212420012802a00b2203450d022022200341057422156a2120202221030340200141f8086a41186a2216200341186a22072900002205370300200141f8086a41106a2217200341106a22042900002226370300200141f8086a41086a2218200341086a2206290000222c37030020012003290000222d3703f808200141d8076a41086a2208202c370300200141d8076a41106a220a2026370300200141d8076a41186a220b2005370300200141b8056a41186a22192007290000370300200141b8056a41106a221a2004290000370300201020062900003703002001202d3703d807200120032900003703b80520032900002105200241186a221b200729000037000020022005370000200241086a221c2006290000370000200241106a221d2004290000370000200120093602980b200141206a200141980b6a10a903410221070240200c20012d0020410171220445734101470d0020012d0021211f20014188066a41186a200b29030037030020014188066a41106a200a29030037030020014188066a41086a2008290300370300200120012903d80737038806200421070b200141e8056a41086a221220014188066a41086a220d290300370300200141e8056a41106a221320014188066a41106a220e290300370300200141e8056a41186a221420014188066a41186a220f29030037030020012001290388063703e8050240024020074102460d00200341206a21030c010b200341206a2103201541606a22150d010c040b0b0340200141f8046a41086a20122903002205370300200141f8046a41106a20132903002226370300200141f8046a41186a2014290300222c370300200120012903e805222d3703f804200141980b6a41186a202c370300200141980b6a41106a2026370300201120053703002001202d3703980b200142e4cab5fbb6ccdcb0e3003703d804200141d8046a200141980b6a201f411874411875410274419886c5006a3502004280af1a7e20007c10a60120032020460d0303402016200341186a220729000022053703002017200341106a220429000022263703002018200341086a2206290000222c37030020012003290000222d3703f80820192007290000370300201a2004290000370300201020062900003703002003290000212e2008202c370300200a2026370300200b20053703002001202e3703b8052001202d3703d807200120093602980b20062900002105200429000021262003290000212c201b2007290000370000201d2026370000201c20053700002002202c370000200141186a200141980b6a10a903410221070240200c20012d0018410171220445734101470d0020012d0019211f200f200b290300370300200e200a290300370300200d2008290300370300200120012903d80737038806200421070b2012200d2903003703002013200e2903003703002014200f29030037030020012001290388063703e805024020074102470d002020200341206a2203470d010c050b0b200341206a21030c000b0b41c4a7c1001058000b41c4a7c1001058000b02402024450d00202210290b200910ab0302400240200c0d00200141053a00a00b200141053a00980b200120093602a40b41b8d6c5004100200141980b6a10880120214200370300200142003703980541e286c500411320014198056a10042010202129030037030020012001290398053703b8052001200941016a3602980b200141b8056a4110200141980b6a410410032027103d0c010b200120093602a40b200141043a00a00b200141053a00980b41b8d6c5004100200141980b6a108801024020012903c8072205500d00200141d8076a200141b8066a41a00110ce041a20014188066a200520007c220510ac03200141980b6a200141d8076a41a00110ce041a200141f8086a201141880110ce041a02400240024002400240200128028c0622062001280290062203460d0020012802880621040c010b200341016a22072003490d1b20034101742204200720072004491b2206ad4290017e2226422088a70d1b2026a722074100480d1b0240024020030d002007102721040c010b20012802880620034190016c2007102821040b2004450d012001200636028c0620012004360288060b200420034190016c220c6a200141f8086a41880110ce044188016a20093602002001200341016a220736029006411710272203450d012003410f6a41002900ffd143370000200341086a41002900f8d143370000200341002900f0d14337000020034117412e10282203450d0220032005370017200141f8086a41186a22084200370300200141f8086a41106a220a4200370300200141f8086a41086a220b4200370300200142003703f8082003411f200141f8086a1000200141b8056a41186a2008290300370300200141b8056a41106a200a2903003703002010200b290300370300200120012903f8083703b8052001412036029c0b2001200141b8056a3602980b20014188066a200141980b6a10312003102902402007450d00200c4190016a2107200421030340024020032802004112460d002003103d0b20034190016a2103200741f07e6a22070d000b0b02402006450d00200410290b20214200370300200142003703980541e286c500411320014198056a10042010202129030037030020012001290398053703b8052001200941016a3602980b200141b8056a4110200141980b6a410410030c040b20074108102a000b41174101102a000b412e4101102a000b200141980b6a202741880110ce041a200141003b01d807200141106a200141980b6a200141d8076a10ad0220012001280210453a00a10b200141073a00a00b200141053a00980b200120093602a40b41b8d6c5004100200141980b6a10880120214200370300200142003703980541e286c500411320014198056a10042010202129030037030020012001290398053703b8052001200941016a3602980b200141b8056a4110200141980b6a410410030b201e2023470d000b2023211e0c130b200a4108102a000b41a8014108102a000b41084104102a000b41084104102a000b20074101102a000b20084101102a000b20034101102a000b20044101102a000b20064101102a000b41094101102a000b41014101102a000b418f89c3004133104e000b418f89c3004133104e000b418f89c3004133104e000b41eab3c30041c900104e000b41eab3c30041c900104e000b41084104102a000b41084104102a000b418f89c3004133104e000b0240201e2023460d00200141980b6a41106a2109200141980b6a41146a21040340200141b8056a41086a2203201e41086a2903003703002001201e2903003703b805201e41106a2802002102200141980b6a201e41146a41940110ce041a20024112460d01200141b8066a41086a22072003290300370300200120012903b8053703b806200141d8076a200141980b6a41940110ce041a200141980b6a41086a2007290300370300200120012903b8063703980b200120023602a80b2004200141d8076a41940110ce041a2009103d201e41a8016a221e2023470d000b0b02402029450d00202810290b02400240411710272202450d002002410f6a41002900ffd143370000200241086a41002900f8d143370000200241002900f0d143370000024020024117412e10282202450d0020022000370017200141f8086a41186a22034200370300200141f8086a41106a22074200370300200141f8086a41086a22094200370300200142003703f8082002411f200141f8086a1000200141b8056a41186a2003290300370300200141b8056a41106a2007290300370300200141b8056a41086a2009290300370300200120012903f8083703b805200141003602980b200141b8056a4120200141980b6a1005210702400240024020012802980b2203417f460d00200120033602dc07200120073602d807200141980b6a200141d8076a103b20012802980b22080d01418f89c3004133104e000b4100210a41082108410021030c010b200129029c0b210502402003450d00200710290b200141b8056a4120100c2005422088a721032005a7210a0b20021029200820034190016c22026a2109024020030d00200821020c030b200241f07e6a2107200141980b6a410472210620082102034020022802002103200141d8076a200241046a41840110ce041a0240024020034113460d00200141980b6a200141d8076a41840110ce041a024020034112470d0020070d02200921020c060b20024188016a2802002104200141b8066a200141980b6a41840110ce041a200120033602980b2006200141b8066a41840110ce041a200141003b01d807200141086a200141980b6a200141d8076a10ad0220012802082103200120043602a40b20012003453a00a10b200141073a00a00b200141053a00980b41b8d6c5004100200141980b6a10880120070d01200921020c050b20024190016a21020c040b20024190016a2102200741f07e6a21070c000b0b412e4101102a000b41174101102a000b024020022009460d00200141980b6a4104722107034020022802002103200141980b6a200241046a418c0110ce041a20034113460d01200141d8076a200141980b6a418c0110ce041a200120033602980b2007200141d8076a418c0110ce041a024020034112460d00200141980b6a103d0b20024190016a22022009470d000b0b0240200a450d00200810290b200010b401200141c00c6a24000f0b102b000b418f89c3004133104e000bf31605027f017e067f037e017f230041c0086b22042400200441c0056a200141a00210ce041a200441e0036a200441c0056a1086024101210502400240024002400240024002400240024002400240024002400240024020042802e0034101460d00200441e0036a41086a290300210620044190026a200441e0036a41106a41d00110ce041a20042006370338200441386a41086a20044190026a41d00110ce041a024020032802002201450d00200341086a28020021072003280204210841002109200441003602c00541ff88c3004110200441c0056a10052105024020042802c005220a417f460d002005450d00200441003602c005200441c0056a2005200a4104200a4104491b10ce041a200a41034d0d0520042802c0052109200510290b411410272205450d05200541106a4100280083ce45360000200541086a41002900fbcd45370000200541002900f3cd453700002005411441281028220a450d06200a2009360014200441e0036a41186a22054200370300200441e0036a41106a22094200370300200441e0036a41086a220b4200370300200442003703e003200a4118200441e0036a100020044190026a41186a200529030037030020044190026a41106a200929030037030020044190026a41086a200b290300370300200420042903e00337039002200441003602c805200442013703c005200420073602e003200441e0036a200441c0056a10300240024020042802c405220b20042802c80522096b2007490d0020042802c00521050c010b200920076a22052009490d09200b410174220c20052005200c491b220c4100480d0902400240200b0d00200c102721050c010b20042802c005200b200c102821050b2005450d082004200c3602c405200420053602c005200c210b0b200520096a2001200710ce041a20044190026a41202005200920076a10030240200b450d00200510290b200a1029410021052008450d00200110290b200441306a200441386a41d0006a10ac0220042d003421092004280230210a200441c0056a200441386a41d80110ce041a41002107024002400240024002400240024002400240024020042903e0054202510d00200441a0086a41186a200441c0056a41186a290300370300200441a0086a41106a200441c0056a41106a290300370300200441a0086a41086a200441c0056a41086a290300370300200420042903c0053703a00820044188066a290300210d20044180066a290300210e200441f8056a2903002106411310272207450d122007410f6a41002800d68d43360000200741086a41002900cf8d43370000200741002900c78d4337000020074113413310282207450d13200720042903a0083700132007412b6a200441b8086a290300370000200741236a200441b0086a2903003700002007411b6a200441a8086a290300370000200441206a200741331089022004290328210f2004280220210b20071029200f4200200b1b220f2006520d04411310272207450d142007410f6a41002800d68d43360000200741086a41002900cf8d43370000200741002900c78d4337000020074113413310282207450d15200720042903a0083700132007412b6a200441a0086a41186a290300370000200741236a200441a0086a41106a2903003700002007411b6a200441a0086a41086a290300370000200441e0036a41186a220b4200370300200441e0036a41106a22084200370300200441e0036a41086a220c4200370300200442003703e00320074133200441e0036a100020044190026a41186a200b29030037030020044190026a41106a200829030037030020044190026a41086a200c290300370300200420042903e003370390022004200642017c3703e00320044190026a4120200441e0036a4108100320071029200441186a41c1cdc500411710b501417f200428021c410020042802181b220720026a220b200b2007491b220b418080c002418080f001200941017122071b4b0d02200441e0036a41086a22094200370300200442003703e00341c1cdc5004117200441e0036a100420044190026a41086a22102009290300370300200420042903e003370390022004200b3602e00320044190026a4110200441e0036a41041003200441106a41a7cdc500411a10b501417f2004280214410020042802101b2208418094ebdc034180afd0e50220071b220b200a200b200a491b6a220c200c2008491b2208200b4b0d0220094200370300200442003703e00341a7cdc500411a200441e0036a100420102009290300370300200420042903e00337039002200420083602e00320044190026a4110200441e0036a41041003200441e0036a200e200d200441a0086a200a2007200210960120042d00e0034101460d012004418c046a280200210920044188046a280200210820044184046a280200210b200441fc036a280200210c200441f8036a2802002102024020044180046a2802002207450d002007410c6c210a2002210703400240200741046a280200450d00200728020010290b2007410c6a2107200a41746a220a0d000b0b0240200c450d00200210290b02402009450d002009410c6c210a200b210703400240200741046a280200450d00200728020010290b2007410c6a2107200a41746a220a0d000b0b02402008450d00200b10290b200441e0076a41086a200441a0086a41086a290300370300200441e0076a41106a200441a0086a41106a290300370300200441e0076a41186a200441a0086a41186a290300370300200420042903a0083703e007410121070b200441e0036a200441c0056a41d0006a41880110ce041a200441a0086a41186a2209200441e0076a41186a290300370300200441a0086a41106a220b200441e0076a41106a290300370300200441a0086a41086a2202200441e0076a41086a290300370300200420042903e0073703a0084102210a02402007450d0020044180086a41186a200929030037030020044180086a41106a200b29030037030020044180086a41086a2002290300370300200420042903a008370380084101210a0b2004419a026a20044180086a41086a290300370100200441a2026a20044180086a41106a290300370100200441aa026a20044180086a41186a2903003701002004200a3a009102200420042903800837019202200441003a009002200441086a200441e0036a20044190026a10ad02200428020c21092004200428020822074100473a00c105200441003a00c00541b8d6c5004100200441c0056a108801200441003602c00541ff88c3004110200441c0056a1005210b20042802c005220a417f470d074101210a0c080b20042d00e103210a20044190066a103d410321070240200a0e0706020606040500060b410021070c050b20044190066a103d0b410421070c030b20044190066a103d200f2006580d010b410121070c010b410221070b20002007360204200041013602002000410c6a4100360200200041086a41b8d6c50036020020054521000c030b200441003602c005200441c0056a200b200a4104200a4104491b10ce041a200a41034d0d0d20042802c005210a200b1029200a41016a210a0b2004200a3602c00541ff88c3004110200441c0056a410410030240024020070d004100210720004100360204200041086a20093602000c010b02402009411b470d000240200741dbeac200460d00200741dbeac200411b10d0040d010b20004104360204410121070c010b20002007360204200041086a2009360200410021070b200020073602002001450d0e20050d020c0e0b200041086a20042902e4033702002000420137020020032802002101410021000b20000d0c20010d0b0c0c0b200341046a280200450d0b200110290c0b0b418f89c3004133104e000b41144101102a000b41284101102a000b200c4101102a000b102b000b41134101102a000b41334101102a000b41134101102a000b41334101102a000b418f89c3004133104e000b200341046a280200450d00200110290b200441c0086a24000b950901087f230041106b2202240020024100360208200242013703002002410436020c2002410c6a20021030024002400240024002400240024002400240024020022802042203200228020822046b4104490d00200441046a2105200228020021030c010b200441046a22052004490d0820034101742206200520052006491b22064100480d080240024020030d002006102721030c010b200228020020032006102821030b2003450d0120022006360204200220033602000b20022005360208200320046a41eede91ab063600002002410e36020c2002410c6a200210300240024020022802042203200228020822066b410e490d002006410e6a2105200228020021040c010b2006410e6a22052006490d0820034101742204200520052004491b22074100480d080240024020030d002007102721040c010b200228020020032007102821040b2004450d022002200736020420022004360200200721030b20022005360208200420066a220641002900a8fb41370000200641066a41002900aefb413700000240200320056b41034b0d00200541046a22062005490d0820034101742207200620062007491b22064100480d080240024020030d002006102721040c010b200420032006102821040b2004450d0320022006360204200220043602000b2002200541046a360208200420056a410a360000024020022802042203200228020822056b41034b0d00200541046a22062005490d0820034101742207200620062007491b22064100480d080240024020030d002006102721040c010b200420032006102821040b2004450d0420022006360204200220043602000b2002200541046a360208200420056a41fb003600000240024020022802042205200228020822046b4104490d00200228020021050c010b200441046a22032004490d0820054101742206200320032006491b22034100480d080240024020050d002003102721050c010b200228020020052003102821050b2005450d0520022003360204200220053602000b2002200441046a360208200520046a41fd003600002002410836020c2002410c6a2002103041b8fbc10021072002280204210320022802082106034002400240200320066b4108490d00200641086a2104200228020021050c010b200641086a22042006490d0920034101742205200420042005491b22084100480d090240024020030d002008102721050c010b200228020020032008102821050b2005450d072002200836020420022005360200200821030b20022004360208200520066a2007290000370000200741086a28020021080240200320046b41034b0d00200441046a22062004490d0920034101742209200620062009491b22064100480d090240024020030d002006102721050c010b200520032006102821050b2005450d082002200636020420022005360200200621030b2002200441046a2206360208200520046a20083600002007410c6a22074198fcc100470d000b200241106a24002006ad4220862005ad840f0b20064101102a000b20074101102a000b20064101102a000b20064101102a000b20034101102a000b20084101102a000b20064101102a000b102b000bc91b05017f017e037f017e057f230041800a6b22022400024002402001450d00200220003602100c010b200241b8d6c5003602100b20022001360214200241e0076a200241106a108e02200241f0076a280200210120022903e007210320022802e807210420022802ec072105200241b0046a200241f4076a41e40010ce041a024002402004450d0020024180036a200241b0046a41e40010ce041a200241e0076a200241106a104820022802e00722000d0102402001450d00200141246c21002004210103400240024020012d0000220641034b0d0002400240024020060e0404000102040b2001410c6a280200450d03200141086a28020010290c030b2001410c6a280200450d02200141086a28020010290c020b2001410c6a280200450d01200141086a28020010290c010b200141086a280200450d00200141046a28020010290b200141246a21012000415c6a22000d000b0b2005450d00200410290b200241f4076a4101360200200242013702e407200241cc81c2003602e007200241023602b404200241c481c2003602b0042002200241b0046a3602f007200241e0076a41d481c2001057000b20022902e40721072002411c6a20024180036a41e40010ce041a20024190016a20013602002002418c016a20053602002002200436028801200220033703800120024194016a2002411c6a41e40010ce042101200241fc016a2007370200200220003602f80120024180016a10b902024002400240024002400240024002402002290380012203500d00200241e0076a2003427f7c108702200241e0076a2001412010d0040d004100210820022802f80121000240024020024180026a280200220141a0026c0d00410421094100210a0c010b2001410c6c220610272209450d042001210a0b02402001450d00200141a0026c2106200141057441606a2104200921010340200220003602b004200241e0076a200241b0046a10bf02200141086a200241e0076a41086a280200360200200120022903e0073702002001410c6a2101200041a0026a2100200641e07d6a22060d000b200441057641016a21080b41002106024002402008410c6c22010d004104210b4100210c0c010b2001410c6e220c41037422004100480d0220001027220b450d030b0240200920016a22052009460d0041002106200b210120092100034020002802002104200141046a200041086a28020036020020012004360200200141086a2101200641016a21062000410c6a22002005470d000b0b200241e0076a200b200610c0020240200c450d00200b10290b02402008450d002008410c6c21002009210103400240200141046a280200450d00200128020010290b2001410c6a2101200041746a22000d000b0b0240200a450d00200910290b0240200241d4016a2201200241e0076a412010d004450d004198cec500410e1010200141201016200241e0076a412010160b02402001200241e0076a412010d0040d0020022802fc01210920022802f8012105200228028002210620024188026a20024180016a41f80010ce041a2005200641a0026c6a210020022903880221072005210102402006450d00200241b0046a41f0006a210420052101024002400340200241f8066a200141e80010ce041a200141e8006a290300210320024180036a200141f0006a41b00110ce041a20034203510d02200241b0046a200241f8066a41e80010ce041a2002200337039805200420024180036a41b00110ce041a2002200241b0046a3602d006200241e0076a200241d0066a10bf0220022802e8072106024020022802e407450d0020022802e00710290b200241e0076a200241b0046a41a00210ce041a200241003602e006200241d0066a200241e0076a2006200241e0066a10bc0220022802d0064101460d01024020022802d4062206450d00200620022802d80610100b200141a0026a22012000470d000b200021010c020b024020022802d4060e050a00000b090a0b4190fdc1001058000b200141a0026a21010b20012000460d05200241f8086a2106200241e0076a41f0006a2104034020024180036a200141e80010ce041a200141e8006a2903002103200241e0076a200141f0006a41b00110ce041a20034203510d06200241f8066a20024180036a41e80010ce041a200241b0046a200241e0076a41b00110ce041a200241e0076a200241f8066a41e80010ce041a200220033703c8082004200241b0046a41b00110ce041a2006103d200141a0026a22012000470d000c060b0b41b0fcc1001058000b4198fcc1001058000b102b000b20004104102a000b20064104102a000b02402009450d00200510290b200241086a41ff88c300411010c102200228020c210120022802082100200241e0076a41086a22064200370300200242003703e0074192cdc5004115200241e0076a1004200241b0046a41086a2006290300370300200220022903e0073703b00420022001410020001b3602e007200241b0046a4110200241e0076a41041003200710c202200241e0076a10c302200220024188026a41106a28020022093602f00620022802900221042002200241e0076a41106a28020022013602f406024020092001470d0002402009450d0020022802e807210541002106034002400240024002400240024002400240200420066a22012d00002208200520066a22002d0000470d000240024002400240024020080e050400010203040b024020042005460d00200141016a280000200041016a280000470d050b200141106a2802002208200041106a280200470d04200141086a280200220b200041086a280200220a460d09200b200a200810d0040d040c090b024020042005460d00200141016a280000200041016a280000470d040b200141106a2802002208200041106a280200470d03200141086a280200220b200041086a280200220a460d07200b200a200810d0040d030c070b024020042005460d00200141016a280000200041016a280000470d030b200141106a2802002208200041106a280200470d02200141086a280200220b200041086a280200220a460d05200b200a200810d0040d020c050b2001410c6a28020022082000410c6a280200470d01200141046a280200220b200041046a280200220a460d03200b200a200810d0040d010c030b20042005460d07200141016a200041016a412010d004450d010b41a481c00041141010200241b0046a2001104f20022802b004220820022802b8041016024020022802b404450d00200810290b200241b0046a2000104f20022802b004220820022802b8041016024020022802b404450d00200810290b20012d000020002d00002208470d05024020080e050005040302000b20042005460d060b200141016a200041016a412010d0040d040c050b2001410c6a28020022082000410c6a280200470d03200141046a2802002201200041046a2802002200460d0420012000200810d004450d040c030b024020042005460d00200141016a280000200041016a280000470d030b200141106a2802002208200041106a280200470d02200141086a2802002201200041086a2802002200460d0320012000200810d0040d020c030b024020042005460d00200141016a280000200041016a280000470d020b200141106a2802002208200041106a280200470d01200141086a2802002201200041086a2802002200460d0220012000200810d0040d010c020b024020042005460d00200141016a280000200041016a280000470d010b200141106a2802002208200041106a280200470d00200141086a2802002201200041086a2802002200460d0120012000200810d004450d010b41c0fdc1001058000b200641246a21062009417f6a22090d000b0b024020024188026a41346a2201200241e0076a41346a2200412010d004450d004198cec500410e10102001412010162000412010160b024020012000412010d004450d0041d8fdc1001058000b024020022802f0072200450d0020022802e8072101200041246c210003400240024020012d0000220641034b0d0002400240024020060e0404000102040b2001410c6a280200450d03200141086a28020010290c030b2001410c6a280200450d02200141086a28020010290c020b2001410c6a280200450d01200141086a28020010290c010b200141086a280200450d00200141046a28020010290b200141246a21012000415c6a22000d000b0b0240200241ec076a280200450d0020022802e80710290b02402002280298022200450d002002280290022101200041246c210003400240024020012d0000220641034b0d0002400240024020060e0404000102040b2001410c6a280200450d03200141086a28020010290c030b2001410c6a280200450d02200141086a28020010290c020b2001410c6a280200450d01200141086a28020010290c010b200141086a280200450d00200141046a28020010290b200141246a21012000415c6a22000d000b0b024020024194026a280200450d0020022802900210290b200241800a6a240042010f0b20024180036a41146a41033602002002418c036a411d360200200241f8066a41146a41033602002002200241f0066a3602e0062002200241f4066a3602d006200241b0046a41146a4100360200200242033702fc0620024190d1c5003602f8062002411d36028403200241b8d6c5003602c004200242013702b404200241a8fdc1003602b004200220024180036a360288072002200241b0046a360290032002200241d0066a360288032002200241e0066a36028003200241f8066a41b0fdc1001057000b41f8fcc1001058000b41e0fcc1001058000b41c8fcc1001058000bb51003067f027e067f230041206b2202240002400240024002400240024002400240024002400240024002400240024041a20210272203450d00200242a20237020420022003360200200341003b000020024102360208200228020021042002280204210502400240200128020022032903684202520d00024020054102470d0020044102410410282204450d0420024104360204200220043602000b200441023a00022002200228020841016a3602080c010b024020054102470d0020044102410410282204450d0420024104360204200220043602000b20044182013a00022002200228020841016a3602082003200210510240024020022802042206200228020822046b41c000490d00200441c0006a2101200228020021050c010b200441c0006a22012004490d1020064101742205200120012005491b22074100480d100240024020060d002007102721050c010b200228020020062007102821050b2005450d052002200736020420022005360200200721060b20022001360208200520046a22042003290024370000200441386a200341dc006a290000370000200441306a200341d4006a290000370000200441286a200341cc006a290000370000200441206a200341c4006a290000370000200441186a2003413c6a290000370000200441106a200341346a290000370000200441086a2003412c6a2900003700000240024020032903684201510d00024020062001470d00200141016a22042001490d1220014101742206200420042006491b22044100480d120240024020010d002004102721050c010b200520012004102821050b2005450d0820022004360204200220053602000b2002200141016a360208200520016a41003a00000c010b200341f8006a29030020032903702208420c882209420120094201561b8021090240200620016b41014b0d00200141026a22042001490d1120064101742207200420042007491b22044100480d110240024020060d002004102721050c010b200520062004102821050b2005450d0820022004360204200220053602000b2002200141026a360208200520016a2009a741047420087aa7417f6a22044101200441014b1b2204410f2004410f491b723b00000b20034180016a20021054200220034188016a360210200241106a200210590b20034198016a2002103220022802082103200241003602182002420137031020022003417e6a36021c2002411c6a200241106a10302002280208220441014d0d0620022802182105200228021021062002280214210a20024100360208200228020021030240024002402004417e6a2207450d004102210b2005450d0e200320062d00003a00004101210c2002200228020841016a36020820054101460d0e200620056a210d200320062d00013a00012002200228020841016a3602084102210b200641026a21014100210e2005417e6a2203450d0c2002280204220b20046b2003490d01200228020021040c020b0240024002402002280204220420054f0d0020044101742201200520052001491b22014100480d130240024020040d002001102721030c010b200320042001102821030b2003450d0c20022001360204200220033602002002280208210b0c010b4100210b2005450d010b2003200b6a220420062d00003a0000024020054101470d00200b41016a210b0c010b2005417f6a2101200641016a2103200441016a21040340200420032d00003a0000200441016a2104200341016a21032001417f6a22010d000b200b20056a210b0b2002200b3602084102210b0c0c0b200420036a220c2004490d0f200b4101742204200c200c2004491b220c4100480d0f02400240200b0d00200c102721040c010b2002280200200b200c102821040b2004450d092002200c360204200220043602000b200420056a200441026a200710cf041a024020052002280208220b460d002002280200200b6a2104200521030340024020034102470d002005210b0c0d0b200420012d00003a00002002200228020841016a360208200441016a2104200141016a2101200b2003417f6a2203470d000b200d20016b22030d004101210c2005210b0c0a0b20034100480d0e024020031027220c450d002005210b2003210e0c0a0b20034101102a000b41a2024101102a000b41044101102a000b41044101102a000b20074101102a000b20044101102a000b20044101102a000b419cb1c5001058000b20014101102a000b200c4101102a000b0240200d2001460d00200c20012d00003a00004101210f0240200141016a2203200d460d00200c41016a2104200520016b21010340200420032d00003a0000200441016a2104200d200341016a2203470d000b200620016a220f450d010b200c200f6a21050240024020022802042203200b20076a22046b200f490d00200228020021030c010b2004200f6a22012004490d0620034101742204200120012004491b22044100480d060240024020030d002004102721030c010b200228020020032004102821030b2003450d0520022004360204200220033602000b2003200f200b6a220d6a2003200b6a200710cf041a0240200d20022802082203460d00200228020020036a2104200f200b6a20036b2101200c2103034020052003460d01200420032d00003a00002002200228020841016a360208200341016a2103200441016a21042001417f6a22010d000b0b200d210b0b200e450d00200c10290b2007450d010b0240200b20022802082203460d002002280200220420036a2004200b6a200710cf041a0b2002200320076a3602080b0240200a450d00200610290b20002002290300370200200041086a200241086a280200360200200241206a24000f0b20044101102a000b102b000bd203010b7f230041206b22032400024002400240024020020d00410421040c010b2002410274220510272204450d010b0240200120024103746a22062001470d004101210741002108410021090c020b2002410374210a200141046a21052004210b0340200b2005280200360200200541086a2105200b41046a210b200a41786a220a0d000b200620016b41786a41037641016a210841012107410021094100210503402001280200210c02400240200920056b200141046a280200220b490d00200b20056a210a0c010b02402005200b6a220a2005490d002009410174220d200a200a200d491b220d4100480d000240024020090d00200d102721070c010b20072009200d102821070b02402007450d00200d21090c020b200d4101102a000b102b000b200720056a200c200b10ce041a200a2105200141086a22012006460d020c000b0b20054104102a000b200341186a22054200370300200341106a22014200370300200341086a220b42003703002003420037030020072004200820031021200041186a2005290300370000200041106a2001290300370000200041086a200b2903003700002000200329030037000002402009450d00200710290b02402002450d00200410290b200341206a24000b940101047f230041106b22032400410021042003410036020c200120022003410c6a10052105024002400240200328020c2206417f470d000c010b20034100360208200341086a20052006410420064104491b10ce041a200641034d0d01200328020821062005102920012002100c410121040b2000200436020020002006360204200341106a24000f0b418f89c3004133104e000bb15108067f027e027f017e077f027e027f037e230041a0046b2201240020014190036a41086a22024200370300200142003703900341e887c500411120014190036a1004200141b0036a41086a200229030037030020012001290390033703b003200141b0036a4110100c0240024002400240024002400240024002400240024002400240024002400240024002400240024002400240200042c0f000824200520d00200141b0036a109701411410272203450d09200341106a41002800bb8c40360000200341086a41002900b38c40370000200341002900ab8c4037000020034114413410282203450d08200320012903b0033700142003412c6a200141c8036a2204290300370000200341246a200141b0036a41106a22052903003700002003411c6a200141b0036a41086a220629030037000020014188016a2003413410840120014188016a41106a2903002107200129039001210820012802880121092003102920012007420020091b22073703a80120012008420020091b22083703a0012004200737030020052008370300200641013a00002001410a3a00b00341b8d6c5004100200141b0036a108801200141003a00b701200142003703c001200142003703b801200141b0026a41086a22034200370300200142003703b002418486c5004112200141b0026a100420014190036a41086a2003290300370300200120012903b00237039003200141003602b00320014190036a4110200141b0036a100521030240024020012802b0032209417f460d002003450d00200120093602cc01200120033602c801200141b0036a200141c8016a104520012802b003220a450d0920012902b403210b2009450d01200310290c010b4104210a4200210b0b4100210c0240200b422088a72209450d00200141b9036a210d200141f0026a210e200141b0026a41206a210f200141c8016a41086a2110200141e8036a2111410021124100210c41002103024003400240024002400240200c450d00200a20034102746a2104200a200320126a4102746a21050340200320094f0d02200141c8016a2004280200220610f20120012903c8014201520d04200141b0026a201041e00010ce041a20012903a001221320012903b002221454200141a0016a41086a2903002208200141b0026a41086a29030022075420082007511b450d03200141013a00b7010240201220036a220620094f0d0020052004280200360200200441046a2104200541046a2105200341016a22032009490d010c070b0b419481c000200620091037000b200a20034102746a21040340200320094f0d01200141c8016a2004280200220610f20120012903c8014201520d03200141b0026a201041e00010ce041a20012903a001221320012903b00222145a200141a0016a41086a2903002208200141b0026a41086a29030022075a20082007511b0d02200441046a2104200141013a00b701200341016a22032009490d000b4100210c0c050b41b880c000200320091037000b2001201320147d3703a0012001200820077d2013201454ad7d3703a801411210272204450d05200441106a41002f00c0a7413b0000200441086a41002900b8a741370000200441002900b0a74137000020044112412410282204450d0620042006360012200141b0036a41186a22054200370300200141b0036a41106a22154200370300200141b0036a41086a22164200370300200142003703b00320044116200141b0036a100020014190036a41186a200529030037030020014190036a41106a201529030037030020014190036a41086a2016290300370300200120012903b0033703900320014190036a4120100c20041029200f20012903c002200141b0026a41186a29030010ad01200141f8006a200e20142007108301200141b8016a41086a2204427f20042903002208200141f8006a41086a2903007c20012903b801221320012903787c22172013542204ad7c22132004201320085420132008511b22041b3703002001427f201720041b3703b80120112007370300200d200e290000370000200d41086a200e41086a290000370000200d41106a200e41106a290000370000200d41186a200e41186a290000370000200120143703e003200141023a00b8032001410a3a00b003200120063602dc0341b8d6c5004100200141b0036a1088010b2012417f6a2112200c41016a210c200341016a22032009490d000b0b200c450d00200320094f0d00200a20034102746a2204200c4102746b2004200920036b41027410cf041a0b200141b0026a41086a22034200370300200142003703b002418486c5004112200141b0026a100420014190036a41086a2003290300370300200120012903b00237039003200141003602b803200142013703b00320012009200c6b22033602c801200141c8016a200141b0036a10300240024020030d0020012802b803210920012802b403210620012802b00321040c010b2009410274200c4102746b211020012802b403210620012802b8032103200a210503402005280200210c02400240200620036b4104490d00200341046a210920012802b00321040c010b200341046a22092003490d1820064101742204200920092004491b22124100480d180240024020060d002012102721040c010b20012802b00320062012102821040b2004450d06200120123602b403200120043602b003201221060b200541046a2105200120093602b803200420036a200c360000200921032010417c6a22100d000b0b20014190036a411020042009100302402006450d00200410290b0240200ba7450d00200a10290b024020012d00b7010d0042002107200141e8006a20012903a0012208200141a0016a41086a2203290300221442c0843d420010d404200141d8006a20012903682213200141e8006a41086a290300220b42c0fb42427f10d304200141c8006a2013200b42a0c21e420010d304200320142014200141c8006a41086a29030020012903482213200820012903587c42018842ffffffff0f837c220b201354ad7c2213200b200856201320145620132014511b22091b22137d20082008200b20091b221454ad7d3703002001200820147d3703a001200141b0026a41086a22034200370300200142003703b00241b18ac0004116200141b0026a100420014190036a41086a2003290300370300200120012903b00237039003200141003602b00320014190036a4110200141b0036a100521030240024020012802b0032209417f470d0042002107420021080c010b024020030d00420021080c010b200142003703b803200142003703b003200141b0036a20032009411020094110491b10ce041a2009410f4d0d06200141b8036a290300210820012903b0032107200310290b200141b0026a41086a22034200370300200142003703b00241b18ac0004116200141b0026a100420014190036a41086a2003290300370300200120012903b00237039003200120073703b003200120083703b80320014190036a4110200141b0036a41101003200141b8016a41086a2203427f2003290300220b20082013200720147d200756200820137d2007201454ad7d221720085620172008511b22031b7c20012903b80122082007201420031b7c22172008542203ad7c220720032007200b542007200b511b22031b3703002001427f201720031b3703b801200141c8036a2013370300200141b0036a41106a2014370300200141b0036a41086a41033a00002001410a3a00b00341b8d6c5004100200141b0036a1088010b200141b0036a109701200141c8016a200141b0036a20012903b8012207200141b8016a41086a29030022084102109001024002400240024020012802c8010d00200141c8016a41106a290300211320012903d0012114200141306a41b18ac0004116108601200820137d2007201454ad7d201320087d2014200754ad7d20142007582013200858201320085122031b22091b2118200720147d201420077d20091b2119200141306a41106a2903004200200128023022091b210b2001290338420020091b21172014200756201320085620031b0d01200141b0026a41086a22034200370300200142003703b00241b18ac0004116200141b0026a100420014190036a41086a2003290300370300200120012903b002370390032001427f200b20187c201720197c22082017542203ad7c220720032007200b542007200b511b22031b3703b8022001427f200820031b3703b002200141b0026a21030c020b41f3c8c10041ca00101042002113200141b0026a41086a22034200370300200142003703b00241b18ac0004116200141b0026a100420014190036a41086a2003290300370300200120012903b00237039003200141003602c80120014190036a4110200141c8016a100521030240024020012802c8012209417f470d0042002113420021140c010b024020030d00420021140c010b200142003703d001200142003703c801200141c8016a20032009411020094110491b10ce041a2009410f4d0d09200141d0016a290300211420012903c8012113200310290b200141b0026a41086a22034200370300200142003703b00241b18ac0004116200141b0026a100420014190036a41086a2003290300370300200120012903b002370390032001427f201420087c201320077c22082013542203ad7c22072003200720145420072014511b22031b3703d0012001427f200820031b3703c80120014190036a4110200141c8016a411010030c020b200141b0026a41086a22034200370300200142003703b00241b18ac0004116200141b0026a100420014190036a41086a2003290300370300200120012903b0023703900320014200200b20187d2017201954ad7d2207201720197d22082017562007200b562007200b511b22031b3703b80220014200200820031b3703b002200141b0026a21030b20014190036a41102003411010030b20012903a0012107200141c8036a200141a0016a41086a290300370300200141c0036a2007370300200141b0036a41086a41043a00002001410a3a00b00341b8d6c5004100200141b0036a1088010b20024200370300200142003703900341c1c8c100411d20014190036a1004200141b0026a41086a200229030037030020012001290390033703b002200141003602b003200141b0026a4110200141b0036a1005210920012802b0032203417f460d0c2009450d0c200120093602c801200120033602cc01200142003703b003200141b0036a20092003410820034108491b220510ce041a2001200320056b22043602cc012001200920056a22053602c8010240200341074d0d0020012903b003210b200142003703b003200141b0036a20052004410820044108491b220310ce041a2001200420036b3602cc012001200520036a3602c801200441074d0d0020012903b0032117200141b0036a200141c8016a104120012802b0032203450d0020012902b4032108200141003a00b003200141b0036a20012802c801220620012802cc012204410047220510ce041a20042005490d062001200420056b22103602cc012001200620056a22053602c8012004450d0a20012d00b0034101470d0a42002107200142003703b003200141b0036a200520104108201041084922061b220410ce041a2001201020046b3602cc012001200520046a3602c80120060d0b20012903b0032119420121070c0c0b418f89c3004133104e000b41124101102a000b41244101102a000b20124101102a000b418f89c3004133104e000b418f89c3004133104e000b20052004103e000b418f89c3004133104e000b41344101102a000b41144101102a000b420021070b0b20091029200141ec016a2008370200200141e0016a2019370300200120033602e801200120073703d801200120173703d0012001200b3703c8010240200b2000520d002008422088a72106024020074200520d002006ad42287e2207422088a70d032007a72209417f4c0d030240024020090d00410821100c010b200910272210450d050b0240024020060d00410021040c010b200641286c210541002104201021090340200341086a2903002107200341106a2903002108200341186a290300211420032903002113200941206a200341206a290300370300200941186a2014370300200941106a2008370300200941086a200737030020092013370300200941286a2109200441016a2104200341286a2103200541586a22050d000b0b200141c8036a2004360200200141c4036a2006360200200141c0036a2010360200200120173703b803200142003703b003200141b0026a200141b0036a105d2001419b036a200141b8026a280200360000200120012903b00237009303200141bc026a20014197036a290000370000200141c6a4b9da043600b102200141023a00b00220012001290090033700b502200141b0026a1097032006450d01201010290c010b2006ad42287e2207422088a70d022007a72209417f4c0d020240024020090d00410821100c010b200910272210450d050b0240024020060d00410021040c010b200641286c210541002104201021090340200341086a2903002107200341106a2903002108200341186a290300211420032903002113200941206a200341206a290300370300200941186a2014370300200941106a2008370300200941086a200737030020092013370300200941286a2109200441016a2104200341286a2103200541586a22050d000b0b200141d0036a2004360200200141cc036a2006360200200141c8036a2010360200200141c0036a2017370300200120193703b803200142013703b003200141b0026a200141b0036a105d2001419b036a200141b8026a280200360000200120012903b00237009303200141bc026a20014197036a290000370000200141c6a4b9da043600b102200141023a00b00220012001290090033700b502200141b0026a1097032006450d00201010290b02402017200b7c2000520d0020014190036a41086a22034200370300200142003703900341c6c4c500411b20014190036a1004200141b0026a41086a2204200329030037030020012001290390033703b002200141103602b4032001200141b0026a3602b003200141e8016a2209200141b0036a102f200141b0036a41086a2009290000370300200141b0036a41106a200941086a280000360200200141003602b403200141093a00b00341b8d6c5004100200141b0036a10880120034200370300200142003703900341c1c8c100411d20014190036a10042004200329030037030020012001290390033703b002200141b0026a4110100c0c010b20012802ec01450d0020012802e80110290b20014190036a41086a22034200370300200142003703900341dec8c100411520014190036a1004200141b0026a41086a200329030037030020012001290390033703b002200141003602b003200141b0026a4110200141b0036a1005210320012802b0032209417f460d062003450d06200141003a00b003200141b0036a20032009410047220410ce041a20092004490d03024002402009450d0020012d00b003220541034b0d00200920046b2109200320046a21040240024020050e0403000301030b200142003703b003200141b0036a20042009410820094108491b220510ce041a200941074d0d0120012903b0032107200142003703b003200141b0036a200420056a200920056b2209410820094108491b10ce041a200941074b0d080c010b200142003703b003200141b0036a20042009410820094108491b220510ce041a200941074d0d0020012903b0032107200142003703b003200141b0036a200420056a200920056b2209410820094108491b10ce041a200941074b0d060b418f89c3004133104e000b200310290c060b1039000b20094108102a000b20094108102a000b20042009103e000b20012903b003210820031029024020072000520d00200142043703b003200120083703b803200141c8016a200141b0036a105d2001419b036a200141d0016a280200360000200120012903c80137009303200141d4016a20014197036a290000370000200141c6a4b9da043600c901200141023a00c80120012001290090033700cd01200141c8016a1097030b200820077c2000520d01200142003703b00320014190036a41086a22034200370300200142003703900341dec8c100411520014190036a1004200141b0026a41086a200329030037030020012001290390033703b002200141c8016a200141b0036a10e701200141b0026a411020012802c801220320012802d0011003024020012802cc01450d00200310290b200141023602b403200141093a00b00341b8d6c5004100200141b0036a1088010c010b20012903b003210820031029024020072000520d00200142033703b003200120083703b803200141c8016a200141b0036a105d2001419b036a200141d0016a280200360000200120012903c80137009303200141d4016a20014197036a290000370000200141c6a4b9da043600c901200141023a00c80120012001290090033700cd01200141c8016a1097030b200820077c2000520d00200142023703b00320014190036a41086a22034200370300200142003703900341dec8c100411520014190036a1004200141b0026a41086a200329030037030020012001290390033703b002200141c8016a200141b0036a10e701200141b0026a411020012802c801220320012802d0011003024020012802cc01450d00200310290b200141013602b403200141093a00b00341b8d6c5004100200141b0036a1088010b20014190036a41086a22034200370300200142003703900341a18ac000411020014190036a1004200141b0026a41086a2209200329030037030020012001290390033703b002200141206a200141b0026a109f03200129032821002001280220211020034200370300200142003703900341e1c4c500411520014190036a10042009200329030037030020012001290390033703b002200141003602b003200141b0026a4110200141b0036a100521030240024002400240024002400240024002400240024002400240024020012802b0032209417f460d002003450d00200141003a00b003200141b0036a20032009410047220410ce041a20092004490d022009450d0c20012d00b00321092003102920094102460d0020094101710d010b410810272209450d022009420037030020014190036a41086a22034200370300200142003703900341c78ac000411520014190036a1004200141b0026a41086a200329030037030020012001290390033703b002200141003602b803200142013703b003200141013602c801200141c8016a200141b0036a1030200929030021070240024020012802b403220520012802b80322046b4108490d0020012802b00321030c010b200441086a22032004490d0e20054101742206200320032006491b22064100480d0e0240024020050d002006102721030c010b20012802b00320052006102821030b2003450d04200120063602b403200120033602b003200621050b2001200441086a22063602b803200320046a2007370000200141b0026a411020032006100302402005450d00200310290b20091029410810272209450d042009420037030020014190036a41086a2203420037030020014200370390034188b7c000411620014190036a1004200141b0026a41086a200329030037030020012001290390033703b002200141003602b803200142013703b003200141013602c801200141c8016a200141b0036a1030200929030021070240024020012802b403220520012802b80322046b4108490d0020012802b00321030c010b200441086a22032004490d0e20054101742206200320032006491b22064100480d0e0240024020050d002006102721030c010b20012802b00320052006102821030b2003450d06200120063602b403200120033602b003200621050b2001200441086a22063602b803200320046a2007370000200141b0026a411020032006100302402005450d00200310290b2009102920014190036a41086a220342003703002001420037039003419eb7c000411020014190036a1004200141b0026a41086a2209200329030037030020012001290390033703b002200142003703b003200141b0026a4110200141b0036a41081003200141013a00b00320034200370300200142003703900341e1c4c500411520014190036a10042009200329030037030020012001290390033703b002200141b0026a4110200141b0036a410110030b20014190036a41086a22034200370300200142003703900341c78ac000411520014190036a1004200141b0026a41086a200329030037030020012001290390033703b002200141003602b003200141b0026a4110200141b0036a100521030240024020012802b0032209417f460d002003450d00200120093602cc01200120033602c801200141b0036a200141c8016a104020012802b0032202450d0720012902b403210b2009450d01200310290c010b410821024200210b0b20014190036a41086a2203420037030020014200370390034188b7c000411620014190036a1004200141b0026a41086a200329030037030020012001290390033703b002200141003602b003200141b0026a4110200141b0036a100521030240024020012802b0032209417f460d002003450d00200120093602cc01200120033602c801200141b0036a200141c8016a104020012802b0032206450d0820012902b403211402402009450d00200310290b2014422088a721030c010b4108210641002103420021140b200b422088a7210a024020100d00200a417f6a2209200a4b0d082009200a4f0d08200220094103746a2209450d08200929030021000b4100200a419c7f6a22092009200a41016a4b1b220e200a4b0d082002200e4103746a210c200e450d0b2003ad21082002211203402012290300210741002103024002400240024002402008a7221041014b0d0020100e020201020b20102109034020032009410176220420036a22052007200620054103746a290300541b2103200920046b220941014b0d000b0b20072006200341037422096a2903002213510d02200320072013566a21030c010b410021030b200120033602b00341d4b7c000412e200141b0036a4184b8c00010a201000b20082003ad580d0a200620096a2209200941086a2003417f7320106a41037410cf041a201442ffffffff0f832010417f6a2203ad422086842114201241086a2212200c460d0c2008427f7c21080c000b0b20042009103e000b41084108102a000b20064101102a000b41084108102a000b20064101102a000b418f89c3004133104e000b418f89c3004133104e000b41aeb7c0004126104e000b419cb1c5001058000b418080c0001058000b418f89c3004133104e000b200b42ffffffff0f8321080240200a200e6b2209450d000240200e450d002002200c200941037410cf041a2014422088a721030b2009ad42208620088421080b41002109024002400240200341014b0d00024020030e020002000b20144220882207a72103410021090c020b034020092003410176220420096a22052000200620054103746a290300541b2109200320046b220341014b0d000b0b02402000200620094103746a2903002207510d00200920002007566a21090b200920144220882207a722034d0d0041d0b1c5001058000b024002400240024002400240024002400240024020032014a7470d00200341016a22042003490d0a2007a722104101742205200420042005491b220441ffffffff01712004470d0a200441037422054100480d0a0240024020030d002005102721060c010b200620104103742005102821060b2006450d012004ad21140b200620094103746a220441086a2004200320096b41037410cf041a2004200037030002402008a72008422088220ba72203470d00200341016a22092003490d0a20034101742204200920092004491b220941ffffffff01712009470d0a200941037422044100480d0a0240024020030d002004102721020c010b200220034103742004102821020b2002450d022009ad21080b200220034103746a200037030002402007a7220d41016a220a200d4f0d004194b8c0001058000b200a4101762203200a4f0d02200620034103746a29030021130240200a4101710d002003417f6a2203200a4f0d04200620034103746a29030020137c42018821130b20014190036a41086a22034200370300200142003703900341c78ac000411520014190036a1004200141b0026a41086a200329030037030020012001290390033703b002200141003602b803200142013703b0032001200b42017ca7220e3602c801200141c8016a200141b0036a103002400240200e0d0020012802b803211220012802b403211020012802b00321090c010b200e410374210c410020012802b80322036b210420012802b40321102002210503402005290300210702400240201020046a4108490d0020012802b00321090c010b200341086a22092003490d0c20104101742212200920092012491b22124100480d0c0240024020100d002012102721090c010b20012802b00320102012102821090b2009450d07200120123602b403200120093602b003201221100b200541086a21052001200341086a22123602b803200920036a2007370000200441786a210420122103200c41786a220c0d000b0b200141b0026a411020092012100302402010450d00200910290b02402008a7450d00200210290b20014190036a41086a2203420037030020014200370390034188b7c000411620014190036a1004200141b0026a41086a200329030037030020012001290390033703b002200142013703b003200141003602b8032001200a3602c801200d41037441086a2112200141c8016a200141b0036a1030410020012802b80322036b210420012802b40321102006210503402005290300210702400240201020046a4108490d0020012802b00321090c010b200341086a22092003490d0b2010410174220c20092009200c491b220c4100480d0b0240024020100d00200c102721090c010b20012802b0032010200c102821090b2009450d072001200c3602b403200120093602b003200c21100b200541086a21052001200341086a220c3602b803200920036a2007370000200441786a2104200c2103201241786a22120d000b200141b0026a41102009200c100302402010450d00200910290b02402014a7450d00200610290b20014190036a41086a220342003703002001420037039003419eb7c000411020014190036a1004200141b0026a41086a200329030037030020012001290390033703b002200120133703b003200141b0026a4110200141b0036a410810030240200e41e500470d00200141106a41888dc300410d1094012013429a087c2001290318420020012802101b560d0020014190036a41086a2209420037030020014200370390034199a7c100411720014190036a1004200141b0026a41086a200929030037030020012001290390033703b002410810272209450d07200942e40037000020094108411010282209450d0820092013370008200141b0026a4110200941101003200910290b20034200370300200142003703900341cfa2c400411720014190036a1004200141b0036a41086a200329030037030020012001290390033703b0030240200141b0036a411041b8d6c50041004100100b417f470d00200141ceecc200410d109401200129030821072001280200210320014190036a41086a22094200370300200142003703900341cfa2c400411720014190036a1004200141b0036a41086a200929030037030020012001290390033703b00320012007420020031b3703c801200141b0036a4110200141c8016a410810030b20014190036a41086a22034200370300200142003703900341dbecc200411120014190036a1004200141b0036a41086a2209200329030037030020012001290390033703b003200141b0036a4110100c20034200370300200142003703900341fcc7c500411720014190036a10042009200329030037030020012001290390033703b003200141b0036a4110100c41bdcbc5004113108a02220341ff01714102460d082003410171450d08200141a0046a24000f0b20054108102a000b20044108102a000b41acb8c0002003200a1037000b41acb8c0002003200a1037000b20124101102a000b200c4101102a000b41084101102a000b41104101102a000b41d4e9c2001058000b102b000bd91a08017f017e047f027e047f017e037f017e23004190026b2201240042002102200141d0016a41086a22034200370300200142003703d0014192cdc5004115200141d0016a100420014190016a41086a2003290300370300200120012903d0013703900120014190016a4110100c200141286a41a7cdc500411a10b501200128022c21042001280228210520034200370300200142003703d00141d8cdc500411b200141d0016a1004200141f0016a41086a2003290300370300200120012903d0013703f001200141003602d001200141f0016a4110200141d0016a10052103024002400240024002400240024002400240024020012802d0012206417f460d002003450d00200142003703d001200141d0016a20032006410820064108491b10ce041a200641074d0d0120012903d0012102200310290b200141186a4180e59af7002004410020051b220320034180e59af7004922061b20034180e59af70020061b6b2206ad220742002007420010d304200742a8c30180210742ffffffffffffffffff00428080808080808080807f20061b2001290318220820012903202008423f87521b42808090bbbad6adf00d7f210802400240200341ffe49af7004b0d0042ffffffffffffffffff00428080808080808080807f2002200720087d22087d22074200531b20072002427f5522032008427f554720032007427f5547711b22024280ec94a37c20024280ec94a37c551b21020c010b42ffffffffffffffffff00428080808080808080807f2002200720087c22087c22074200531b20072002427f5522032008427f554620032007427f5547711b21020b200141d0016a41086a22034200370300200142003703d00141d8cdc500411b200141d0016a100420014190016a41086a22062003290300370300200120012903d00137039001410810272204450d012004200237000020014190016a41102004410810032004102920034200370300200142003703d00141a7cdc500411a200141d0016a100420062003290300370300200120012903d0013703900120014190016a4110100c20034200370300200142003703d00141c1cdc5004117200141d0016a100420062003290300370300200120012903d0013703900120014190016a4110100c20034200370300200142003703d00141888dc300410d200141d0016a100420062003290300370300200120012903d00137039001200141086a20014190016a109f03200129031021022001280208210920034200370300200142003703d00141d18fc3004111200141d0016a100420062003290300370300200120012903d00137039001200141003602f00120014190016a4110200141f0016a100521030240024020012802f0012206417f460d002003450d00200141f0016a2006412020064120491b22046a41004100412020046b2004411f4b1b10cd041a200141f0016a2003200410ce041a2006411f4d0d04200141d0016a41186a2206200141f0016a41186a2204290000370300200141d0016a41106a2205200141f0016a41106a220a290000370300200141d0016a41086a220b200141f0016a41086a220c290000370300200120012900f0013703d00120031029200141b0016a41186a22032006290300370300200141b0016a41106a22062005290300370300200141b0016a41086a2205200b290300370300200120012903d0013703b00120014190016a4110100c200420032903002207370300200a20062903002208370300200c2005290300220d370300200141306a41086a200d370300200141306a41106a2008370300200141306a41186a2007370300200120012903b00122073703f001200120073703300c010b200141f0016a41186a200141b0016a41186a290300370300200141f0016a41106a200141b0016a41106a290300370300200141f0016a41086a200141b0016a41086a290300370300200141306a41086a4200370300200141306a41106a4200370300200141306a41186a4200370300200120012903b0013703f001200142003703300b200141d0016a41086a22034200370300200142003703d00141aa8dc300410d200141d0016a1004200141f0016a41086a2003290300370300200120012903d0013703f001200141003602d001200141f0016a4110200141d0016a100521030240024020012802d0012206417f460d002003450d00200120063602b401200120033602b001200141d0016a200141b0016a104320012802d001220a450d0520012902d401210702402006450d00200310290b200141f0016a4110100c2007422088a721032007a7210b0c010b4104210a410021034100210b0b200141d0016a41086a22064200370300200142003703d00141958dc3004115200141d0016a100420014190016a41086a2006290300370300200120012903d00137039001200141003602d00120014190016a4110200141d0016a100521050240024020012802d0012206417f460d00200141f0016a2006412020064120491b22046a41004100412020046b2004411f4b1b10cd041a200141f0016a2005200410ce041a2006411f4d0d06200141d0016a41186a2206200141f0016a41186a2204290000370300200141d0016a41106a220c200141f0016a41106a220e290000370300200141d0016a41086a220f200141f0016a41086a2210290000370300200120012900f0013703d00120051029200141b0016a41186a22052006290300370300200141b0016a41106a2206200c290300370300200141b0016a41086a220c200f290300370300200120012903d0013703b00120014190016a4110100c200420052903002207370300200e200629030022083703002010200c290300220d370300200141d0006a41086a200d370300200141d0006a41106a2008370300200141d0006a41186a2007370300200120012903b00122073703f001200120073703500c010b200141f0016a41086a200141b0016a41086a290300370300200141f0016a41106a200141b0016a41106a290300370300200141f0016a41186a200141b0016a41186a290300370300200141d0006a41086a4200370300200141d0006a41106a4200370300200141d0006a41186a4200370300200120012903b0013703f001200142003703500b02402002420020091b220242fb01540d00200242857e7c2207500d00411010272206450d06200641086a41002900bf8d43370000200641002900b78d4337000020064110412010282206450d0720062007370010200141b0016a41186a22044200370300200141b0016a41106a22054200370300200141b0016a41086a22094200370300200142003703b00120064118200141b0016a1000200141f0016a41186a2004290300370300200141f0016a41106a2005290300370300200141f0016a41086a2009290300370300200120012903b0013703f001200141f0016a4120100c200610290b200141b0016a41186a22064200370300200141b0016a41106a22044200370300200141b0016a41086a22054200370300200142003703b001200141b0016a101e200141f0006a41186a2006290300370300200141f0006a41106a2004290300370300200141f0006a41086a2005290300370300200120012903b001370370200141f0016a41186a2209200141306a41186a290300370300200141f0016a41106a220c200141306a41106a290300370300200141f0016a41086a220e200141306a41086a290300370300200120012903303703f001200642003703002004420037030020054200370300200142003703b0010240200141f0016a4120200141b0016a101f450d0020014190016a41086a2005290300220737030020014190016a41106a2004290300220837030020014190016a41186a2006290300220d370300200120012903b001221137039001200e2007370300200c20083703002009200d370300200120113703f00102402003200b470d00200341016a22062003490d0a20034101742204200620062004491b220bad42247e2207422088a70d0a2007a722064100480d0a0240024020030d0020061027210a0c010b200a200341246c20061028210a0b200a450d090b200a200341246c6a220641003a0000200620012903f001370001200641096a200141f8016a290300370000200641116a20014180026a290300370000200641196a20014188026a290300370000200620012f00d0013b0021200641236a200141d2016a2d00003a0000200341016a21030b2000200129033037001420002002370300200020012903703700342000412c6a200141306a41186a290300370000200041246a200141306a41106a2903003700002000411c6a200141306a41086a2903003700002000413c6a200141f0006a41086a290300370000200041c4006a200141f0006a41106a290300370000200041cc006a200141f0006a41186a290300370000200041106a20033602002000410c6a200b3602002000200a360208200041ec006a200141d0006a41186a290300370000200041e4006a200141d0006a41106a290300370000200041dc006a200141d0006a41086a2903003700002000200129035037005420014190026a24000f0b418f89c3004133104e000b41084101102a000b418f89c3004133104e000b418f89c3004133104e000b418f89c3004133104e000b41104101102a000b41204101102a000b20064104102a000b102b000bf90201027f23004180026b22022400024002402001450d00200220003602000c010b200241b8d6c5003602000b2002200136020420024180016a2002108e020240200228028801450d00200241086a20024180016a41f80010ce041a200241086a10b9020240200241186a2802002200450d0020022802102101200041246c210003400240024020012d0000220341034b0d0002400240024020030e0404000102040b2001410c6a280200450d03200141086a28020010290c030b2001410c6a280200450d02200141086a28020010290c020b2001410c6a280200450d01200141086a28020010290c010b200141086a280200450d00200141046a28020010290b200141246a21012000415c6a22000d000b0b0240200241146a280200450d00200228021010290b20024180026a240042010f0b2002411c6a41013602002002420137020c200241cc81c200360208200241023602fc01200241d082c2003602f8012002200241f8016a360218200241086a41d481c2001057000be40b01087f230041206b2202240020024100360218200242013703100240024002400240024002400240024002400240410410272203450d0020024284808080c00037021420022003360210200341edcad18b0636000002400240200228021420022802182203460d00200228021021040c010b200341016a22042003490d0a20034101742205200420042005491b22054100480d0a0240024020030d002005102721040c010b200228021020032005102821040b2004450d0220022005360214200220043602100b2002200341016a360218200420036a41073a00004112200241106a10c60241002103034020034184e7c1006a28020020034188e7c1006a280200200241106a10c702024002402003418ce7c1006a22052802004102470d0002400240200228021420022802182204460d00200228021021050c010b200441016a22052004490d0d20044101742206200520052006491b22064100480d0d0240024020040d002006102721050c010b200228021020042006102821050b2005450d0620022006360214200220053602100b2002200441016a360218200520046a41003a00000c010b02400240200228021420022802182204460d00200228021021060c010b200441016a22062004490d0c20044101742207200620062007491b22074100480d0c0240024020040d002007102721060c010b200228021020042007102821060b2006450d0620022007360214200220063602100b2002200441016a360218200620046a41013a00002005200241106a10c8020b02400240200341ace7c1006a22052802004102470d0002400240200228021420022802182204460d00200228021021050c010b200441016a22052004490d0d20044101742206200520052006491b22064100480d0d0240024020040d002006102721050c010b200228021020042006102821050b2005450d0820022006360214200220053602100b2002200441016a360218200520046a41003a00000c010b02400240200228021420022802182204460d00200228021021060c010b200441016a22062004490d0c20044101742207200620062007491b22074100480d0c0240024020040d002007102721060c010b200228021020042007102821060b2006450d0820022007360214200220063602100b2002200441016a360218200620046a41013a00002005200241106a10c9020b02400240200341bce7c1006a22052802004102470d0002400240200228021420022802182204460d00200228021021050c010b200441016a22052004490d0d20044101742206200520052006491b22064100480d0d0240024020040d002006102721050c010b200228021020042006102821050b2005450d0a20022006360214200220053602100b2002200441016a360218200520046a41003a00000c010b02400240200228021420022802182204460d00200228021021060c010b200441016a22062004490d0c20044101742207200620062007491b22074100480d0c0240024020040d002007102721060c010b200228021020042007102821060b2006450d0a20022007360214200220063602100b2002200441016a360218200620046a41013a00002005200241106a10ca020b200341cce7c1006a200241106a10cb02200341dc006a220341f80c470d000b20022802142107200228021021062002280218210320024100360218200242013703102002200336020c2002410c6a200241106a10300240024020022802142205200228021822046b2003490d00200228021021050c010b200420036a22082004490d0a20054101742209200820082009491b22084100480d0a0240024020050d002008102721050c010b200228021020052008102821050b2005450d0920022008360214200220053602100b200520046a2006200310ce041a200420036a210302402007450d00200610290b200241206a24002003ad4220862005ad840f0b41044101102a000b20054101102a000b20064101102a000b20074101102a000b20064101102a000b20074101102a000b20064101102a000b20074101102a000b20084101102a000b102b000b920701037f0240024002400240024002402000413f4b0d0002400240200141046a280200200141086a2802002202460d00200128020021030c010b200241016a22032002490d0620024101742204200320032004491b22044100480d060240024020020d002004102721030c010b200128020020022004102821030b2003450d0220012003360200200141046a2004360200200141086a28020021020b200141086a200241016a360200200320026a20004102743a00000f0b200041808001490d032000418080808004490d020c010b20044101102a000b0240024002400240200141046a280200200141086a2802002202460d00200128020021030c010b200241016a22032002490d0520024101742204200320032004491b22044100480d050240024020020d002004102721030c010b200128020020022004102821030b2003450d0120012003360200200141046a2004360200200141086a28020021020b200141086a2204200241016a360200200320026a41033a000002400240200141046a2802002203200428020022026b4104490d00200128020021030c010b200241046a22042002490d0520034101742202200420042002491b22024100480d050240024020030d002002102721030c010b200128020020032002102821030b2003450d0220012003360200200141046a2002360200200141086a28020021020b200141086a200241046a360200200320026a20003600000f0b20044101102a000b20024101102a000b024002400240200141046a2802002203200141086a28020022026b4104490d00200128020021030c010b200241046a22042002490d0320034101742202200420042002491b22024100480d030240024020030d002002102721030c010b200128020020032002102821030b2003450d0120012003360200200141046a2002360200200141086a28020021020b200141086a200241046a360200200320026a20004102744102723600000f0b20024101102a000b024002400240200141046a2802002203200141086a28020022026b4102490d00200128020021030c010b200241026a22042002490d0220034101742202200420042002491b22024100480d020240024020030d002002102721030c010b200128020020032002102821030b2003450d0120012003360200200141046a2002360200200141086a28020021020b200141086a200241026a360200200320026a20004102744101723b00000f0b20024101102a000b102b000bc60801037f0240024002400240024002400240024002402001413f4b0d0002400240200241046a280200200241086a2802002203460d00200228020021040c010b200341016a22042003490d0920034101742205200420042005491b22054100480d090240024020030d002005102721040c010b200228020020032005102821040b2004450d0220022004360200200241046a2005360200200241086a28020021030b200241086a200341016a360200200420036a20014102743a00000c050b200141808001490d032001418080808004490d020c010b20054101102a000b0240024002400240200241046a280200200241086a2802002203460d00200228020021040c010b200341016a22042003490d0820034101742205200420042005491b22054100480d080240024020030d002005102721040c010b200228020020032005102821040b2004450d0120022004360200200241046a2005360200200241086a28020021030b200241086a2205200341016a360200200420036a41033a000002400240200241046a2802002204200528020022036b4104490d00200228020021040c010b200341046a22052003490d0820044101742203200520052003491b22034100480d080240024020040d002003102721040c010b200228020020042003102821040b2004450d0220022004360200200241046a2003360200200241086a28020021030b200241086a200341046a360200200420036a20013600000c040b20054101102a000b20034101102a000b024002400240200241046a2802002204200241086a28020022036b4104490d00200228020021040c010b200341046a22052003490d0620044101742203200520052003491b22034100480d060240024020040d002003102721040c010b200228020020042003102821040b2004450d0120022004360200200241046a2003360200200241086a28020021030b200241086a200341046a360200200420036a20014102744102723600000c020b20034101102a000b02400240200241046a2802002204200241086a28020022036b4102490d00200228020021040c010b200341026a22052003490d0420044101742203200520052003491b22034100480d040240024020040d002003102721040c010b200228020020042003102821040b2004450d0220022004360200200241046a2003360200200241086a28020021030b200241086a200341026a360200200420036a20014102744101723b00000b02400240200241046a2802002204200241086a28020022036b2001490d00200228020021040c010b200320016a22052003490d0320044101742203200520052003491b22034100480d030240024020040d002003102721040c010b200228020020042003102821040b2004450d0220022004360200200241046a2003360200200241086a28020021030b200241086a200320016a360200200420036a2000200110ce041a0f0b20034101102a000b20034101102a000b102b000b860201037f230041206b220224000240024020002802004101460d00200220002802041101002002280204200241086a280200200110c7022002410c6a200110b004200228020c450d01200241106a28020021030240200241186a2802002200450d00200041d8006c21044100210103400240200320016a220041346a280200450d002000413c6a280200450d00200041386a28020010290b0240200041c4006a280200450d00200041cc006a280200450d00200041c8006a28020010290b2004200141d8006a2201470d000b0b200241146a280200450d01200310290c010b200041086a2802002000410c6a280200200110c702200041106a200110b0040b200241206a24000bae0201047f230041106b220224000240024020002802004101460d00200241086a200028020411010020022802082103200228020c2200200110c6022000450d012000412c6c2104410021050340200320056a220041046a280200200041086a280200200110c7022000410c6a200110af04200041206a28020020032005412841242000411c6a2802004101461b6a6a280200200110ad0420042005412c6a2205470d000c020b0b200028020421032000410c6a2802002200200110c6022000450d002000412c6c2104410021050340200320056a220041046a280200200041086a280200200110c7022000410c6a200110af04200041206a28020020032005412841242000411c6a2802004101461b6a6a280200200110ad0420042005412c6a2205470d000b0b200241106a24000be60201047f230041106b220224000240024020002802004101460d00200241086a200028020411010020022802082103200228020c2200200110c6022000450d012000412c6c2104410021050340200320056a220041046a280200200041086a280200200110c702200041106a28020020032005411841142000410c6a2802004101461b6a6a280200200110ad04200041206a28020020032005412841242000411c6a2802004101461b6a6a280200200110ad0420042005412c6a2205470d000c020b0b200028020421032000410c6a2802002200200110c6022000450d002000412c6c2104410021050340200320056a220041046a280200200041086a280200200110c702200041106a28020020032005411841142000410c6a2802004101461b6a6a280200200110ad04200041206a28020020032005412841242000411c6a2802004101461b6a6a280200200110ad0420042005412c6a2205470d000b0b200241106a24000b880401057f230041206b220224000240024020002802004101460d00200241086a200028020411010020022802082103200228020c2200200110c6022000450d01200041386c2104410021050340200320056a220041046a280200200041086a280200200110c702200041106a280200200041146a280200200110c70202400240200041186a2802004101460d00200241106a2000411c6a280200200041206a28020028020c110000200228021022062002280218200110c7022002280214450d01200610290c010b2000411c6a280200200041246a280200200110c7020b2000412c6a2802002003200541344130200041286a2802004101461b6a6a280200200110ad042004200541386a2205470d000c020b0b200028020421032000410c6a2802002200200110c6022000450d00200041386c2104410021050340200320056a220041046a280200200041086a280200200110c702200041106a280200200041146a280200200110c70202400240200041186a2802004101460d00200241106a2000411c6a280200200041206a28020028020c110000200228021022062002280218200110c7022002280214450d01200610290c010b2000411c6a280200200041246a280200200110c7020b2000412c6a2802002003200541344130200041286a2802004101461b6a6a280200200110ad042004200541386a2205470d000b0b200241206a24000ba80301027f230041a0076b22022400024002402001450d00200220003602080c010b200241b8d6c5003602080b2002200136020c200241f0046a200241086a104902400240024020022903d8054203510d00200241106a200241f0046a41a00210ce041a200241b0026a200241106a41a00210ce041a2002200241b0026a3602f004200241d0046a200241f0046a10bf0220022802d8042101200241f0046a200241b0026a41a00210ce041a20024198076a20022802d804360200200220022903d00437039007200241e0046a200241f0046a200120024190076a10bc02410121000240024020022802e0044101460d004100210020022802e40441004721030c010b4280828898f01f20022802e404410374ad88a721030b410110272201450d01200120003a000020014101410210282201450d02200120033a0001200241a0076a24002001ad428080808020840f0b200241c4026a4101360200200242013702b402200241cc81c2003602b00220024102360214200241e882c2003602102002200241106a3602c002200241b0026a41d481c2001057000b41014101102a000b41024101102a000bee1003097f017e037f230041e0016b22022400200241206a41ff88c300411010c1022002280224210320022802202104200241a0016a41086a22054200370300200242003703a0014192cdc5004115200241a0016a1004200241286a41086a2005290300370300200220022903a0013703284100210620022003410020041b3602c00141042107200241286a4110200241c0016a41041003200241106a41888dc300410d1094012002290318420020022802101b10c202200241086a4192cdc500411510b5014104210841002109024002400240200228020c410020022802081b220a450d00200aad420c7e220b422088a70d01200ba722034100480d01200310272208450d02200821034100210c034002400240024002400240411410272204450d00200441106a4100280083ce45360000200441086a41002900fbcd45370000200441002900f3cd4537000020044114412810282205450d012005200c360014200241286a41186a22044200370300200241286a41106a220d4200370300200241286a41086a220942003703002002420037032820054118200241286a1000200241c0016a41186a2004290300370300200241c0016a41106a200d290300370300200241c0016a41086a2009290300370300200220022903283703c00120024100360228200241c0016a4120200241286a1005210d20022802282209417f460d03200d450d03200220093602b4012002200d3602b001200241286a200241b0016a104420022802282204450d02200229022c210b02402009450d00200d10290b200241c0016a4120100c0c040b41144101102a000b41284101102a000b418f89c3004133104e000b410021040b2005102920032004410120041b360200200341046a200ba7410020041b360200200341086a200b422088a7410020041b3602002003410c6a2103200a200c41016a220c470d000b200a21090b0240024002400240024002402009410c6c2203450d002003410c6e220641037422044100480d06200410272207450d010b410021050240200820036a220d2008460d00200721032008210403402004280200210c200341046a200441086a2802003602002003200c360200200341086a2103200541016a21052004410c6a2204200d470d000b0b200241c0016a2007200510c00202402006450d00200710290b02402009450d002009410c6c21042008210303400240200341046a280200450d00200328020010290b2003410c6a2103200441746a22040d000b0b0240200a450d00200810290b200241286a41186a200241c0016a41186a290300370300200241286a41106a200241c0016a41106a290300370300200241286a41086a200241c0016a41086a290300370300200220022903c001370328200241a0016a41086a22034200370300200242003703a00141958dc3004115200241a0016a1004200241b0016a41086a2003290300370300200220022903a0013703b001200241b0016a4110200241286a41201003200241286a10c302200241003602b801200242013703b001412010272203450d01200242a080808080043702b401200220033602b0012003200229023c370000200341086a200241c4006a290200370000200341106a200241cc006a290200370000200341186a200241d4006a290200370000200241286a200241b0016a10540240024020022802b401220520022802b801220c6b4120490d00200c41206a210320022802b00121040c010b200c41206a2203200c490d0620054101742204200320032004491b220d4100480d060240024020050d00200d102721040c010b20022802b0012005200d102821040b2004450d032002200d3602b401200220043602b001200d21050b200220033602b8012004200c6a220c200229025c370000200c41086a200241e4006a290200370000200c41106a200241ec006a290200370000200c41186a200241f4006a2902003700000240200520036b411f4b0d00200341206a220c2003490d062005410174220d200c200c200d491b220c4100480d060240024020050d00200c102721040c010b20042005200c102821040b2004450d042002200c3602b401200220043602b0010b200420036a220441086a20024184016a290200370000200441106a2002418c016a290200370000200441186a20024194016a2902003700002002200341206a3602b8012004200229027c3700002002280230210e2002200241286a41106a28020022063602c001200241c0016a200241b0016a10300240024020060d0020022802b801210420022802b00121050c010b200641246c210820022802b401210920022802b8012103200e210c0340200241c0016a200c104f20022802c001210a02400240200920036b20022802c801220d490d002003200d6a210420022802b00121050c010b2003200d6a22042003490d0820094101742205200420042005491b22074100480d080240024020090d002007102721050c010b20022802b00120092007102821050b2005450d07200220073602b401200220053602b001200721090b200220043602b801200520036a200a200d10ce041a024020022802c401450d00200a10290b200c41246a210c200421032008415c6a22080d000b2006450d00200641246c210c200e210303400240024020032d0000220d41034b0d00024002400240200d0e0404000102040b2003410c6a280200450d03200341086a28020010290c030b2003410c6a280200450d02200341086a28020010290c020b2003410c6a280200450d01200341086a28020010290c010b200341086a280200450d00200341046a28020010290b200341246a2103200c415c6a220c0d000b0b0240200241346a280200450d00200e10290b200241e0016a24002004ad4220862005ad840f0b20044104102a000b41204101102a000b200d4101102a000b200c4101102a000b20074101102a000b102b000b20034104102a000b900c03017f027e097f230041b0026b22022400024002402001450d00200220003602100c010b200241b8d6c5003602100b20022001360214200241286a200241106a10fb010240024020022802282201450d002002200229022c37021c20022001360218200241286a200241186a10cf02024020022802284101470d002002200229022c3703c80141beefc2004128200241c8016a4188eec20010a201000b200241286a41086a2903002103200241ceecc200410d109401200229030821042002280200210141a002102722050d0141a0024108102a000b2002413c6a41013602002002420137022c200241cc81c200360228200241023602cc012002418083c2003602c8012002200241c8016a360238200241286a41d481c2001057000b2005200241c8016a41e80010ce04220642023703682006410236029801200620022903a001370370200641f8006a200241a0016a41086a29030037030020064180016a200241b0016a29030037030020064188016a200241b8016a29030037030020064190016a200241c0016a29030037030020062003200442b9067c42b90620011b220420042003541b3703a001200641a8016a200241286a41f80010ce041a200241186a2101200228021c21070240024003402001280200220841086a210020082f0106220941037421014100210a0240024003402001450d0141c8e2c1002000410810d004220b450d02200141786a2101200a41016a210a200041086a2100200b417f4a0d000b200a417f6a21090b024020070d0041d0e2c1002101412821000c030b2007417f6a2107200820094102746a41e4016a21010c010b0b2008200a410c6c6a220141e0006a2802002100200141e8006a280200210120024200370328200241286a20002001410820014108491b10ce041a200141074b0d0141fec4c5002101412921000b2002200036022c2002200136022841f88cc000412b200241286a41e88cc00010a201000b20022903282103200241286a41086a220142003703002002420037032841c78ac0004115200241286a1004200241c8016a41086a2001290300370300200220022903283703c8014100210120024100360228200241c8016a4110200241286a1005210a02400240024002400240024020022802282200417f460d00200220003602a4012002200a3602a001200241286a200241a0016a10402002280228220b450d02200241306a2802002101200228022c21082000450d01200a10290c010b4108210b410021080b4100210002402001417f6a220a20014b0d00200a20014f0d00200b200a4103746a2201450d00200129030020035221000b02402008450d00200b10290b0240024020000d004101210c0c010b200641a00241c00410282205450d02200541a0026a200241c8016a41e80010ce041a2005420237038803200520033703c0032005410c3602b803200520022903a0013703900320054198036a200241a8016a290300370300200541a0036a200241b0016a290300370300200541a8036a200241b8016a290300370300200541b0036a200241c0016a290300370300200541c8036a200241286a41f80010ce041a4102210c0b2002280218200228021c200228022010fc01200241003602d001200242013703c8012002200c360228200c41a0026c210d200241286a200241c8016a103020022802cc01210820022802d00121014100210a034020022005200a6a3602a001200241286a200241a0016a10bf022002280228210702400240200820016b20022802302206490d00200120066a210020022802c801210b0c010b200120066a22002001490d052008410174220b20002000200b491b22094100480d050240024020080d0020091027210b0c010b20022802c801200820091028210b0b200b450d04200220093602cc012002200b3602c801200921080b200220003602d001200b20016a2007200610ce041a0240200228022c450d00200710290b20002101200d200a41a0026a220a470d000b200c41a0026c210a410021010340200520016a4198016a103d200a200141a0026a2201470d000b20051029200241b0026a24002000ad422086200bad840f0b418f89c3004133104e000b41c0044108102a000b20094101102a000b102b000bad0201077f230041106b2202240020012802042103024002400240024003402001280200220441086a210520042f01062206410374210141002107024003402001450d0141e4cac5002005410810d0042208450d03200141786a2101200741016a2107200541086a21052008417f4a0d000b2007417f6a21060b02402003450d002003417f6a2103200420064102746a41e4016a21010c010b0b200041eccac500360204200041086a41283602000c010b20042007410c6c6a220141e0006a2802002105200141e8006a280200210120024200370308200241086a20052001410820014108491b10ce041a200141074b0d0120004194cbc500360204200041086a41293602000b410121010c010b200041086a2002290308370300410021010b20002001360200200241106a24000bb91e08067f017e057f017e047f027e027f017e230041b0026b22022400024002402001450d00200220003602100c010b200241b8d6c5003602100b20022001360214200241c8006a200241106a108e020240024020022802502203450d00200241d8006a280200210420022802542105200241c8006a200241106a1048200228024822060d0102402004450d00200441246c21002003210103400240024020012d0000220741034b0d0002400240024020070e0404000102040b2001410c6a280200450d03200141086a28020010290c030b2001410c6a280200450d02200141086a28020010290c020b2001410c6a280200450d01200141086a28020010290c010b200141086a280200450d00200141046a28020010290b200141246a21012000415c6a22000d000b0b2005450d00200310290b200241dc006a41013602002002420137024c200241cc81c200360248200241023602d4012002419c83c2003602d0012002200241d0016a360258200241c8006a41d481c2001057000b200229024c2108200241c8006a200241106a10fb01024020022802482201450d002002200229024c37021c20022001360218200241013b01342002420037022c2002418883c000360228200241286a41086a21090240024002400240024002402008422088a7220a450d002006200a41a0026c6a210b200241d0016a410272210c2006210d0340200d41e8006a2903004202520d010240024002400240024002400240024002400240024002400240200d2802980122014102470d00200d2903a001210e200241186a2101200228021c210f024002400240024003402001280200221041086a210020102f010622114103742101410021070240024003402001450d0141f6c4c5002000410810d0042212450d02200141786a2101200741016a2107200041086a21002012417f4a0d000b2007417f6a21110b200f450d02200f417f6a210f201020114102746a41e4016a21010c010b0b20102007410c6c6a220141e0006a2802002100200141e8006a280200210120024200370348200241c8006a20002001410820014108491b10ce041a0240200141074b0d00201342808080807083422984210e41fec4c50021110c020b200e42f20c8020022903482213510d0341a08fc30021114131210f0c020b201342808080807083421c84210e41a7c5c50021110b200ea7210f0b024002400240024020022d0035450d00413121014195fac10021000c010b2002280228200228022c200228023010fc012002420037022c2002418883c000360228200242e2c289abb68edbb7f400370338200241d0016a410272410041da0010cd041a200241c8006a410041840110cd041a41e40110272212450d0520124100360200201241046a200241d0016a41dc0010ce041a201241e0006a200241c8006a41840110ce041a2002410036022c2002201236022820122f0106220d4103742110417f210041002101024002400340024020102001470d00200d21000c020b200241386a201220016a41086a410810d0042207450d02200141086a2101200041016a2100200741004e0d000b0b200242e2c289abb68edbb7f40037025c20022009360258200220003602542002201236024c200241003602482002200241286a360250200241003602d801200242013703d0012002200f360238200241386a200241d0016a103020022802d401220020022802d80122016b200f490d0220022802d00121000c030b412d210141c6fac10021000b2002200136024c2002200036024841f3fac1004122200241c8006a4198fbc10010a201000b2001200f6a22072001490d1220004101742212200720072012491b22074100480d120240024020000d002007102721000c010b20022802d00120002007102821000b2000450d04200220073602d401200220003602d0010b20022001200f6a3602d801200020016a2011200f10ce041a200241386a41086a20022802d801360200200220022903d001370338200241c8006a200241386a10fd0120024180023b0134200241d0016a41086a200241286a41086a290300370300200220022903283703d0010c100b200d2802980121010b20014102470d0b200d2903a0012114200241c8006a200241186a10cf020240024020022802484101470d002002350250210e200228024c2115410121160c010b2002290350210e200241ceecc200410d10940102402014200e423c7c560d00410021162014200229030842b9067c42b90620022802001b220e540d010c0d0b201742808080807083422584210e410121164199efc20021150b024020022d0035450d00413121014195fac10021000c050b02402016450d002002280228200228022c200228023010fc012002420037022c2002418883c000360228200242f4d2b59bc7ae98b8303703380c030b20022802282112200242f4d2b59bc7ae98b8303703382012418883c000460d02200228022c210f0c030b41e4014104102a000b20074101102a000b200c410041da0010cd041a200241c8006a410041840110cd041a41e40110272212450d034100210f20124100360200201241046a200241d0016a41dc0010ce041a201241e0006a200241c8006a41840110ce041a2002410036022c200220123602280b034020122f010622114103742110417f210041002101024002400340024020102001470d00201121000c020b200241386a201220016a41086a410810d0042207450d02200141086a2101200041016a21002007417f4a0d000b0b200f450d03200f417f6a210f201220004102746a41e4016a28020021120c010b0b412d210141c6fac10021000b2002200136024c2002200036024841f3fac1004122200241c8006a4198fbc10010a201000b200242f4d2b59bc7ae98b83037025c20022009360258200220003602542002201236024c200241003602482002200241286a360250200241003602d801200242013703d0014101102721010240024020160d002001450d03200141003a000020024281808080103702d401200220013602d00120014101410910282201450d042001200e3700012002428980808090013702d401200220013602d0010c010b2001450d04200141013a000020024281808080103702d401200220013602d0012002200ea72201360238200241386a200241d0016a10300240024020022802d401220720022802d80122006b2001490d0020022802d00121070c010b200020016a22122000490d0b20074101742210201220122010491b22124100480d0b0240024020070d002012102721070c010b20022802d00120072012102821070b2007450d06200220123602d401200220073602d0010b2002200020016a3602d801200720006a2015200110ce041a0b200241386a41086a200241d0016a41086a280200360200200220022903d001370338200241c8006a200241386a10fd01200220163a0035200241003a0034200e21172016450d05200241d0016a41086a200241286a41086a290300370300200220022903283703d0010c080b41e4014104102a000b41014101102a000b41094101102a000b41014101102a000b20124101102a000b200d41a0026a220d200b470d000b0b200241d0016a41086a2009290300370300200220022903283703d0010b2002280218200228021c200228022010fc0102402004450d00200441246c21002003210103400240024020012d0000220741034b0d0002400240024020070e0404000102040b2001410c6a280200450d03200141086a28020010290c030b2001410c6a280200450d02200141086a28020010290c020b2001410c6a280200450d01200141086a28020010290c010b200141086a280200450d00200141046a28020010290b200141246a21012000415c6a22000d000b0b02402005450d00200310290b2008a721070240200a450d00200a41a0026c210020064198016a210103402001103d200141a0026a2101200041e07d6a22000d000b0b02402007450d00200610290b2002410036025020024201370348410110272201450d03200242818080801037024c20022001360248200120022d00dc013a000020014101410210282201450d02200242828080802037024c20022001360248200120022d00dd013a000120022802d801210d20014102410610282212450d0120024286808080e00037024c200220123602482012200d36000220022802d00122072100024020022802d4012210450d002010210120072100034020002802e40121002001417f6a22010d000b0b0240024002400240200d0d004280808080e000210e0c010b41062110200241d0016a210b4106210f41002111034002400240201120002f01064f0d0020002011410c6c6a41e0006a2101200020114103746a41086a2107201141016a21110c010b02400240200028020022010d00201742808080807083200bad84211741002107410021010c010b2000330104422086200bad842117410121070b201721142017210e02402017422088a7220020012f0106490d000340200e221442ffffffff0f83210e200741016a210720012f01042200200128020022012f01064f0d000b0b20012000410c6c6a2111200120004103746a2116200041027420016a41e8016a28020021002014a7210b02402007417f6a2201450d00034020002802e40121002001417f6a22010d000b0b201141e0006a2101201641086a2107410021110b02402010200f6b41074b0d00200f41086a2216200f490d0520104101742204201620162004491b22164100480d050240024020100d002016102721120c010b201220102016102821120b2012450d032002201636024c200220123602480b2002200f41086a3602502012200f6a200729000037000020012802002116200220012802082201360228200241286a200241c8006a103002400240200228024c2210200228025022076b2001490d00200228024821120c010b200720016a22122007490d052010410174220f20122012200f491b220f4100480d050240024020100d00200f102721120c010b20022802482010200f102821120b2012450d042002200f36024c20022012360248200f21100b2002200720016a220f360250201220076a2016200110ce041a200d417f6a220d0d000b200fad422086210e20022802d401211020022802d00121070b2007201020022802d80110fc01200241b0026a2400200e2012ad840f0b20164101102a000b200f4101102a000b102b000b41064101102a000b41024101102a000b41014101102a000b200241dc006a41013602002002420137024c200241cc81c200360248200241023602d4012002419c83c2003602d0012002200241d0016a360258200241c8006a41d481c2001057000b7701027f230041206b22022400200241b8d6c500410010db0102404120102722030d0041204101102a000b20032002290300370000200341186a200241186a290300370000200341106a200241106a290300370000200341086a200241086a290300370000200241206a24002003ad42808080808004840bcf4c040b7f027e127f067e230041c00a6b22022400024002402001450d00200220003602400c010b200241b8d6c5003602400b20022001360244200241e8066a200241c0006a104902400240024002400240024002400240024002400240024002400240024002400240024020022903d0074203510d00200241c8006a200241e8066a41a00210ce041a200241e8026a200241c8006a41a00210ce041a2002200241e8026a36028805200241e8066a20024188056a10bf0220022802f0062100024020022802ec06450d0020022802e80610290b200241e8066a200241e8026a41a00210ce041a20024188056a200241e8066a10860202402002280288054101470d00200228029005416b6a220141054b0d10200228028c05210002400240024020010e06001313131301000b4102210341f601210120004184efc200460d0120004184efc200411510d004450d010c120b410021010240200041a981c200470d00410021030c130b41002103200041a981c200411a10d0040d110b0c110b200241e8066a20024190056a41d80110ce041a200241386a200241b8076a220410ac020240024002402002290388074202520d0041c00110272201450d04200141013a00b801200142003703b00120014280808080c0003703a801200142043703a0012001427f3703980120014200370390012001420137038801200142003703800120014280808080c000370378200142043703702001427f37036820014200370360200142013703582001420037035020014280808080c000370348200142043703402001427f37033820014200370330200142013703282001420037032020014280808080c000370318200142043703102001427f37030820014200370300200141bc016a20024188056a41036a28000036000020012002280088053600b9012002200141c0016a36028c0a200220013602880a200241043602840a200220013602800a200241900a6a41206a22054200370300200241900a6a41186a22064280808080c000370300200241013a00b80a200242043703a00a2002427f3703980a200242003703900a200241c8096a41086a22072001290308370300200241c8096a41106a22082001290310370300200241c8096a41186a22032001290318370300200241c8096a41206a22092001290320370300200220012903003703c809200220012800293602f80920022001412c6a2800003600fb09200141306a210020012d0028220a4102460d1020024188096a41286a220b200241900a6a41286a220c29030037030020024188096a41206a200529030037030020024188096a41186a200629030037030020024188096a41106a200241900a6a41106a29030037030020024188096a41086a200241900a6a41086a290300370300200220022903900a3703880920024188056a41206a200929030037030020024188056a41186a200329030037030020024188056a41106a200829030037030020024188056a41086a2007290300370300200220022903c809370388052002200a3a00b005200241b1056a220a20022802f809360000200a41036a20022800fb09360000200241900a6a20024188096a20024188056a10d3022007200041086a2903003703002008200041106a2903003703002003200041186a2903003703002009200041206a290300370300200220002903003703c809200220012800593602f8092002200141dc006a2800003600fb09200141e0006a210020012d005822074102470d010c100b20022d003c21032002280238210841c00110272205450d0420022903a007210d411310272201450d052001410f6a41002800d68d43360000200141086a41002900cf8d43370000200141002900c78d4337000020014113413310282201450d06200120022903e8063700132001412b6a20024180076a290300370000200141236a200241f8066a2903003700002001411b6a200241e8066a41086a290300370000200241286a200141331089022002290330210e20022802282106200110290240024002400240200e420020061b220e200d560d00410c10272206450d0b412010272201450d0c200120022903e806370000200141186a200241e8066a41186a290300370000200141106a200241e8066a41106a290300370000200141086a200241e8066a41086a2903003700002001412041c00010282201450d0d2001200d37002041042107200641046a42c0808080800537020020062001360200410021010240200e200d5a0d00410c10272207450d0f412010272201450d10200120022903e806370000200141186a200241e8066a41186a290300370000200141106a200241e8066a41106a290300370000200141086a200241e8066a41086a2903003700002001412041c00010282201450d112001200d427f7c370020200742c0808080800537020420072001360200410121010b20022002280088053602800a20022002418b056a220b2800003600830a200220022802800a3602f809200220022800830a3600fb09200241206a41c1cdc500411710b501417f2002280224410020022802201b220920006a220a200a2009491b418080c002418080f001200341017122031b4b0d01200241186a41a7cdc500411a10b501417f200228021c410020022802181b220a418094ebdc034180afd0e50220031b2209200820092008491b6a220c200c200a491b20094b0d0120022002280088053602900a20022002418b056a2800003600930a200220022802900a3602c809200220022800930a3600cb0920024188056a20022903a807200241b0076a290300200241e8066a20082003200010960120022d0088054101460d02200541013a005820054281808080103703502005200636024c2005200136024820052001360244200520073602402005427f37033820052008ad220d370330200542013703282005420037032020054280808080c000370318200542043703102005427f37030820054200370300200520022802f809360059200541dc006a220f20022800fb09360000200541013a008801200542003703800120054280808080c000370378200542043703702005427f3703682005427f200d20031b370360200520022802c809360089012005418c016a20022800cb0936000020052002290390053703900120054198016a20024188056a41106a2200290300370300200541a0016a20024188056a41186a2206290300370300200541a8016a20024188056a41206a2207290300370300200541b0016a20024188056a41286a2208290300370300200541b8016a20024188056a41306a2903003703002002200541c0016a36028c0a200220053602880a200241043602840a200220053602800a200241900a6a41206a22034200370300200241900a6a41186a22094280808080c000370300200241013a00b80a200242043703a00a2002427f3703980a200242003703900a200241c8096a41086a220a2005290308370300200241c8096a41106a220b2005290310370300200241c8096a41186a220c2005290318370300200241c8096a41206a22102005290320370300200220052903003703c809200220052800293602f80920022005412c6a2800003600fb09200541306a210120052d002822114102460d1120024188096a41286a200241900a6a41286a29030037030020024188096a41206a200329030037030020024188096a41186a200929030037030020024188096a41106a200241900a6a41106a29030037030020024188096a41086a200241900a6a41086a290300370300200220022903900a37038809200720102903003703002006200c2903003703002000200b29030037030020024188056a41086a200a290300370300200220022903c80937038805200220113a00b005200241b1056a221120022802f809360000201141036a221220022800fb09360000200241900a6a20024188096a20024188056a10d302200a200141086a290300370300200b200141106a290300370300200c200141186a2903003703002010200141206a290300370300200220012903003703c809200220052800593602f8092002200f2800003600fb09200541e0006a210120052d0058220a4102470d050c110b20022002280088053602800a20022002418b056a2800003600830a20024181083b0188092005102941012101410421080c020b20022002280088053602900a2002200b2800003600930a20024181023b01880902402001450d002001410c6c21002007210103400240200141046a280200450d00200128020010290b2001410c6a2101200041746a22000d000b200710290b0240200641046a280200450d00200628020010290b200610292005102941012108410121010c100b200220022d00890522083a008909200241013a00880902402001450d002001410c6c21002007210103400240200141046a280200450d00200128020010290b2001410c6a2101200041746a22000d000b200710290b0240200641046a280200450d00200628020010290b2006102920051029410121010b0c0e0b200b200c29030037030020024188096a41206a220c200241900a6a41206a221029030037030020024188096a41186a2211200241900a6a41186a220f29030037030020024188096a41106a2212200241900a6a41106a221329030037030020024188096a41086a2214200241900a6a41086a2215290300370300200220022903900a3703880920024188056a41206a2216200241c8096a41206a220829030037030020024188056a41186a2217200241c8096a41186a220329030037030020024188056a41106a2218200241c8096a41106a220929030037030020024188056a41086a2219200241c8096a41086a220b290300370300200220022903c80937038805200220073a00b005200a20022802f809360000200a41036a220720022800fb09360000200241900a6a20024188096a20024188056a10d302200b200041086a2903003703002009200041106a2903003703002003200041186a2903003703002008200041206a290300370300200220002903003703c80920022001280089013602f80920022001418c016a2800003600fb0920014190016a210020012d008801221a4102460d0e20024188096a41286a221b200241900a6a41286a221c290300370300200c20102903003703002011200f2903003703002012201329030037030020142015290300370300200220022903900a370388092016200829030037030020172003290300370300201820092903003703002019200b290300370300200220022903c809370388052002201a3a00b005200a20022802f809360000200720022800fb09360000200241900a6a20024188096a20024188056a10d302200b200041086a2903003703002009200041106a2903003703002003200041186a2903003703002008200041206a290300370300200220002903003703c809200220012800b9013602f8092002200141bc016a2800003600fb09200141c0016a210020012d00b80122014102460d0e201b201c29030037030020024188096a41206a200241900a6a41206a29030037030020024188096a41186a200241900a6a41186a29030037030020024188096a41106a200241900a6a41106a29030037030020024188096a41086a200241900a6a41086a290300370300200220022903900a3703880920024188056a41206a200241c8096a41206a29030037030020024188056a41186a200241c8096a41186a29030037030020024188056a41106a200241c8096a41106a29030037030020024188056a41086a200241c8096a41086a290300370300200220022903c80937038805200220013a00b005200a20022802f809360000200a41036a20022800fb09360000200241900a6a20024188096a20024188056a10d3020c0e0b20024188096a41286a2213200241900a6a41286a221429030037030020024188096a41206a2215200241900a6a41206a221629030037030020024188096a41186a2217200241900a6a41186a221829030037030020024188096a41106a2219200241900a6a41106a221a29030037030020024188096a41086a221b200241900a6a41086a221c290300370300200220022903900a3703880920024188056a41206a221d200241c8096a41206a220b29030037030020024188056a41186a221e200241c8096a41186a220c29030037030020024188056a41106a221f200241c8096a41106a221029030037030020024188056a41086a2220200241c8096a41086a220f290300370300200220022903c809370388052002200a3a00b005201120022802f809360000201220022800fb09360000200241900a6a20024188096a20024188056a10d302200f200141086a2903003703002010200141106a290300370300200c200141186a290300370300200b200141206a290300370300200220012903003703c80920022005280089013602f80920022005418c016a2800003600fb0920054190016a210120052d008801220a4102460d0b2013201429030037030020152016290300370300201720182903003703002019201a290300370300201b201c290300370300200220022903900a37038809201d200b290300370300201e200c290300370300201f20102903003703002020200f290300370300200220022903c809370388052002200a3a00b005201120022802f809360000201141036a220a20022800fb09360000200241900a6a20024188096a20024188056a10d302200f200141086a2903003703002010200141106a290300370300200c200141186a290300370300200b200141206a290300370300200220012903003703c809200220052800b9013602f8092002200541bc016a2800003600fb09200541c0016a210120052d00b80122054102460d0b20024188096a41286a200241900a6a41286a29030037030020024188096a41206a200241900a6a41206a29030037030020024188096a41186a200241900a6a41186a29030037030020024188096a41106a200241900a6a41106a29030037030020024188096a41086a200241900a6a41086a290300370300200220022903900a3703880920024188056a41206a200241c8096a41206a29030037030020024188056a41186a200241c8096a41186a29030037030020024188056a41106a200241c8096a41106a29030037030020024188056a41086a200241c8096a41086a290300370300200220022903c80937038805200220053a00b005201120022802f809360000200a20022800fb09360000200241900a6a20024188096a20024188056a10d3020c0b0b200241fc026a4101360200200242013702ec02200241cc81c2003602e8022002410236024c200241b483c2003602482002200241c8006a3602f802200241e8026a41d481c2001057000b41c0014108102a000b41c0014108102a000b41134101102a000b41334101102a000b410c4104102a000b41204101102a000b41c0004101102a000b410c4104102a000b41204101102a000b41c0004101102a000b20024188056a41086a2205200241900a6a41086a2903003703002000200241900a6a41106a29030037030020062009290300370300200720032903003703002008200241900a6a41286a290300370300200220013602880a200220022903900a37038805200241800a6a103a20024188096a41086a200229038805222137030020024188096a41106a2005290300220e37030020024188096a41186a2000290300220d37030020024188096a41206a200629030037030020024188096a41286a200729030037030020024188096a41306a200829030037030041002101200241003a008809200da7210c20022d00890921080b200241b8096a2d0000210f200241b4096a2802002109200241b0096a2802002110200241ac096a280200210b200241a8096a280200210a200241a4096a2802002111024020010d00410121030c020b42bcf7ea858cf8afdfbd7f2008410473ad42078342038688a72101410021030c010b20024188056a41086a2201200241900a6a41086a29030037030020024188056a41106a2207200241900a6a41106a29030037030020024188056a41186a2208200629030037030020024188056a41206a2206200529030037030020024188056a41286a2205200241900a6a41286a290300370300200220003602880a200220022903900a37038805200241800a6a103a20024188096a41106a2001290300220d37030020024188096a41186a2201200729030037030020024188096a41206a2200200829030037030020024188096a41286a2208200629030037030020024188096a41306a220620052903003703002002200229038805220e37039009200241003a008809200241800a6a41086a200d3703002002200e3703800a20024188096a412c6a28020021072008280200210b200241ac096a280200210920002802002108200241a4096a280200210c2001280200210a024002400240024002400240024020022802b8074111470d002006290300210d20024188056a41086a22014200370300200242003703880541d2c5c500411020024188056a1004200241900a6a41086a200129030037030020022002290388053703900a2002410036028805200241900a6a411020024188056a10052101024002402002280288052200417f460d002001450d00200220003602cc09200220013602c80920024188056a200241c8096a10412002280288052210450d0320024190056a2802002111200228028c05210f2000450d01200110290c010b41082110410021114100210f0b200241e4076a21002010201141286c6a210320102101024003400240200320016b41f8004b0d00024020032001460d002010201141286c6a2103200241e4076a210503404101210620052001460d0420012000412010d004450d042003200141286a2201470d000b0b410021060c020b4101210620012000460d0120012000412010d004450d01200141286a22052000460d0120052000412010d004450d01200141d0006a22052000460d0120052000412010d004450d01200141f8006a22052000460d01200141a0016a210120052000412010d0040d000b0b0240200f450d00201010290b2006450d00200241106a4193c8c500411410b50120024188056a2002280214410020022802101b200010b201200228028805220520022802900541b8d6c50041004100100b21010240200228028c05450d00200510290b2001417f470d0020024190086a28020041c000470d00200228028808220141086a290000210e200141106a2900002121200141186a2900002122200141206a2900002123200141286a2900002124200141306a29000021252001290000212620024188056a41386a200141386a29000037030020024188056a41306a202537030020024188056a41286a202437030020024188056a41206a202337030020024188056a41186a202237030020024188056a41106a202137030020024188056a41086a200e3703002002202637038805200241003602980a200242013703900a20022903c007210e410810272201450d022001200e3700002002428880808080013702940a200220013602900a200241c8076a200241900a6a1061200241e0076a28020021100240024020022802940a220520022802980a22066b4104490d0020022802900a21010c010b200641046a22012006490d0b20054101742203200120012003491b22034100480d0b0240024020050d002003102721010c010b20022802900a20052003102821010b2001450d04200220033602940a200220013602900a200321050b2002200641046a22033602980a200120066a201036000002400240200520036b411f4d0d00200521100c010b200341206a22102003490d0b20054101742211201020102011491b22104100480d0b0240024020050d002010102721010c010b200120052010102821010b2001450d05200220103602940a200220013602900a0b200120036a22052000290000370000200541186a200041186a290000370000200541106a200041106a290000370000200541086a200041086a29000037000002402001200641246a220520024188056a200010140d00200241086a4193c8c500411410b50120022802e007200228020c410020022802081b490d00410c102722000d06410c4104102a000b2010450d00200110290b02402008450d002008410c6c2100200a210103400240200141046a280200450d00200128020010290b2001410c6a2101200041746a22000d000b0b0240200c450d00200a10290b02402007450d002007410c6c21002009210103400240200141046a280200450d00200128020010290b2001410c6a2101200041746a22000d000b0b42002121427f210e4104210c0240200b450d00200910290b4100210a4101210f410121094101211041002111410021030c050b418f89c3004133104e000b41084101102a000b20034101102a000b20104101102a000b200020053602082000201036020420002001360200200220022802f8093602c009200220022800fb093600c309200241900a6a41206a428180808010370300200241900a6a41186a4100360200200241bc0a6a20022800c30936000041012103200241013a00b80a200220003602ac0a200242043703a00a2002427f3703980a200242003703900a200220022802c0093600b90a20024188056a41246a200736020020024188056a41206a200b36020020024188056a41186a200836020020024188056a41146a200c36020020024188056a41086a200241800a6a41086a2903003703002002200d3703b005200220093602a4052002200a36029805200220022903800a37038805200241c8096a200241900a6a20024188056a10d302200241c8096a41146a2802002111200241c8096a41186a280200210a200241c8096a41206a2802002110200241c8096a41246a280200210920022903c809212120022903d009210e20022802d809210c20022802e409210b20022d00f009210f0b410021010b2004103d0c010b4100210341810121010b200241003602f0064201210d200242013703e806024002400240024002400240024002400240024002400240200341024d0d004200210e0c010b024002400240024020030e03000102000b410110272200450d04200241013602ec06200220022802f006220541016a3602f006200220003602e806200020056a41003a00000240024020022802ec0620022802f0062200460d0020022802e80621050c010b200041016a22052000490d0f20004101742204200520052004491b22044100480d0f0240024020000d002004102721050c010b20022802e80620002004102821050b2005450d06200220043602ec06200220053602e80620022802f00621000b2002200041016a3602f006200520006a20013a00000c020b410110272201450d05200241013602ec06200220022802f006220041016a3602f006200220013602e806200120006a41013a00000240024020022802ec06220020022802f00622016b4108490d0020022802e80621000c010b200141086a22052001490d0e20004101742201200520052001491b22014100480d0e0240024020000d002001102721000c010b20022802e80620002001102821000b2000450d07200220013602ec06200220003602e80620022802f00621010b2002200141086a3602f006200020016a20213700002002200a3602e802200241e8026a200241e8066a10300240200a450d00200c200a410c6c6a2108200c21050340200528020021062002200541086a28020022013602e802200241e8026a200241e8066a10300240024020022802ec06220420022802f00622006b2001490d0020022802e80621040c010b200020016a22072000490d1020044101742200200720072000491b22004100480d100240024020040d002000102721040c010b20022802e80620042000102821040b2004450d0a200220003602ec06200220043602e80620022802f00621000b2002200020016a3602f006200420006a2006200110ce041a2005410c6a22052008470d000b0b200220093602e802200241e8026a200241e8066a103002402009450d00200b2009410c6c6a2108200b21050340200528020021062002200541086a28020022013602e802200241e8026a200241e8066a10300240024020022802ec06220420022802f00622006b2001490d0020022802e80621040c010b200020016a22072000490d1020044101742200200720072000491b22004100480d100240024020040d002000102721040c010b20022802e80620042000102821040b2004450d0b200220003602ec06200220043602e80620022802f00621000b2002200020016a3602f006200420006a2006200110ce041a2005410c6a22052008470d000b0b0240024020022802ec06220020022802f00622016b4108490d0020022802e80621000c010b200141086a22052001490d0e20004101742201200520052001491b22014100480d0e0240024020000d002001102721000c010b20022802e80620002001102821000b2000450d0a200220013602ec06200220003602e80620022802f00621010b2002200141086a3602f006200020016a200e3700000240024020022802ec0620022802f0062201460d0020022802e80621000c010b200141016a22002001490d0e20014101742205200020002005491b22054100480d0e0240024020010d002005102721000c010b20022802e80620012005102821000b2000450d0b200220053602ec06200220003602e80620022802f00621010b2002200141016a3602f006200020016a200f3a00000c010b410110272200450d0a200241013602ec06200220022802f006220541016a3602f006200220003602e806200020056a41023a00000240024020022802ec0620022802f0062200460d0020022802e80621050c010b200041016a22052000490d0d20004101742204200520052004491b22044100480d0d0240024020000d002004102721050c010b20022802e80620002004102821050b2005450d0c200220043602ec06200220053602e80620022802f00621000b2002200041016a3602f006200520006a20013a00000b20023502f006422086210e20023502e806210d0b024020034101470d000240200a450d00200a410c6c2100200c210103400240200141046a280200450d00200128020010290b2001410c6a2101200041746a22000d000b0b02402011450d00200c10290b02402009450d002009410c6c2100200b210103400240200141046a280200450d00200128020010290b2001410c6a2101200041746a22000d000b0b2010450d00200b10290b200241c00a6a2400200e200d840f0b41014101102a000b20044101102a000b41014101102a000b20014101102a000b20004101102a000b20004101102a000b20014101102a000b20054101102a000b41014101102a000b20044101102a000b102b000b980505017f027e077f017e017f230041106b220324002002290300210420012903002105200141106a21062002280210210702400240024002400240200141146a2802002208200141186a28020022096b200241186a280200220a490d00200628020021080c010b2009200a6a220b2009490d032008410174220c200b200b200c491b220bad420c7e220d422088a70d03200da7220c4100480d030240024020080d00200c102721080c010b20062802002008410c6c200c102821080b2008450d0120012008360210200141146a200b3602000b20082009410c6c6a2007200a410c6c10ce041a200141186a2009200a6a36020020024100360218200341086a200641086a280200360200200320062902003703002001411c6a2106200228021c210b02400240200141206a2802002208200141246a28020022096b200241246a280200220a490d00200628020021080c010b2009200a6a220c2009490d032008410174220e200c200c200e491b220cad420c7e220d422088a70d03200da7220e4100480d030240024020080d00200e102721080c010b20062802002008410c6c200e102821080b2008450d022001200836021c200141206a200c3602000b20082009410c6c6a200b200a410c6c10ce041a200141246a2009200a6a360200200241003602242000427f200520047c220420042005541b37030020002003290300370210200041186a200341086a2802003602002000200629020037021c200041246a200641086a280200360200200020022d0028410020012d00281b3a00282000200229030822052001290308220420042005561b3703080240200241146a280200450d00200710290b0240200241206a280200450d00200b10290b200341106a24000f0b200c4104102a000b200e4104102a000b102b000be41807017f027e027f017e017f017e0e7f23004180046b2202240020024200370368200241e8006a200041b8d6c50020011b2001410820014108491b10ce041a0240024002400240024002400240024002400240024002400240024002400240024002400240200141074d0d0020022903682103200241186a41d9b0c0004111109401200229032021042002280218210041002105200241003602684101210641014185b1c000411c200241e8006a101721012004420020001b2107024002400240024020022802682200417f470d0041012100410121060c010b2000ad2204422086200484210420014521002001450d00200241003a0068200241e8006a20012004422088a72206410047220510ce041a20062005490d042006450d0120022d0068210820024200370368200241e8006a200120056a200620056b2206410820064108491b10ce041a200641074d0d01200229036822092007542009200354200841ff01711b2106200121050b0240200720035a0d0020060d020b20002004a745720d14200510290c140b02402004a7450d00200110290b41b284c500412d10100c130b410110272201450d02200141003a000020014101410910282201450d032001200337000141014185b1c000411c4100200520001b22062004422088a7417f20061b200141091018210620011029024020002004a745720d00200510290b20060d12200241003602484201200241c8006a1019210020022802482201417f460d1220022000360288032002200136028c03200241003a0068200241e8006a20002001410047220610ce041a20012006490d042002200120066b36028c032002200020066a360288032001450d124100210a0240024020022d0068450d000c010b200241e8006a20024188036a10440240200228026822010d000c010b200229026c21042001210a0b20001029200a450d1241002106200241e8006a2004422088a72200412020004120491b22016a41004100412020016b2001411f4b1b10cd041a200241e8006a200a200110ce041a2004a7210b2000411f4d0d11200241306a200241f1006a290000370300200241386a200241f9006a2900003703002002413f6a20024180016a2900003700002002200229006937032820022d0068210c20024100360248200241c8006a101a210020022802482201417f460d1020022000360288032002200136028c03200241003a0068200241e8006a20002001410047220610ce041a20012006490d052002200120066b36028c032002200020066a3602880302400240024002402001450d0020022d0068220641014b0d004100210d024020060e020003000b200241e8006a20024188036a10442002280268220d450d00200229026c2109200241106a20024188036a102e2009a7210e02402002280210450d00024002402002280214220f41d502200f41d502491b22100d00410421110c010b2010410c6c220610272211450d0c0b0240200f450d004100211241002106410021080340200241e8006a20024188036a10440240200228026822130d0002402008450d002011210503400240200541046a280200450d00200528020010290b2005410c6a2105200641746a22060d000b0b2010450d03201110290c030b200841016a2105200229026c2104024020082010470d002012200520052012491b2210ad420c7e2207422088a70d152007a722144100480d150240024020080d002014102721110c010b201120062014102821110b2011450d0f0b201120066a22082013360200200841046a2004370200201241026a21122006410c6a210620052108200f2005470d000b0b20110d020b200e450d00200d10290b4100210d0c020b200fad4220862010ad8421042009422088a7210f0b2004422088a721142004a721150b02402001450d00200010290b200d450d10200241086a4193c8c500411410b501200241c8006a41086a200241286a41086a290300370300200241c8006a41106a200241286a41106a290300370300200241c8006a41176a200241286a41176a29000037000020022002290328370348200228020c2116200228020821172002420137036820024100360270410810272201450d0820024288808080800137026c20022001360268200120033700002002200f3602880320024188036a200241e8006a103002400240200228026c2200200228027022016b200f490d00200228026821000c010b2001200f6a22062001490d0e20004101742205200620062005491b22064100480d0e0240024020000d002006102721000c010b200228026820002006102821000b2000450d0a2002200636026c200220003602680b20022001200f6a360270200020016a200d200f10ce041a200220143602880320024188036a200241e8006a10300240024020140d00200228026c2105200228027021130c010b20112014410c6c6a2110201121000340200028020021122002200041086a28020022013602880320024188036a200241e8006a103002400240200228026c2205200228027022066b2001490d00200228026821080c010b200620016a22082006490d1020054101742213200820082013491b22134100480d100240024020050d002013102721080c010b200228026820052013102821080b2008450d0d2002201336026c20022008360268201321050b2002200620016a2213360270200820066a2012200110ce041a2000410c6a22002010470d000b0b02400240200520136b4104490d00200228026821010c010b201341046a22012013490d0e20054101742200200120012000491b22004100480d0e0240024020050d002000102721010c010b200228026820052000102821010b2001450d0c2002200036026c20022001360268200021050b2002201341046a2200360270200120136a2016410020171b220836000002400240200520006b411f4d0d00200521060c010b200041206a22062000490d0e20054101742212200620062012491b22064100480d0e0240024020050d002006102721010c010b200120052006102821010b2001450d0d2002200636026c200220013602680b200120006a2200200c3a000020002002290348370001200041096a200241d0006a290300370000200041116a200241d8006a290300370000200041186a200241df006a2900003700002002410036026842012001201341246a200241e8006a101b2100024002400240024020022802682205417f470d0020060d010c020b02402000450d0002402006450d00200110290b200241e8006a2002418e036a41e80010ce041a200241ac026a200c3a0000200241a8026a2008360200200241a4026a2014360200200241a0026a20153602002002419c026a201136020020024198026a200f36020020024194026a200e36020020024190026a200d36020020024188026a2003370300200241b5026a200241d0006a290300370000200241bd026a200241d8006a290300370000200241c4026a200241df006a2900003700002002411136028002200242023703d001200220022903483700ad02200241d8026a2005360200200241d4026a2005360200200241d0026a20003602002002200241e8006a3602fc0320024188036a200241fc036a10bf022002280288032200200228029003101c21010240200228028c03450d00200010290b2001450d0320024180026a103d410521060c150b2006450d010b200110290b0240200e450d00200d10290b02402014450d002014410c6c21002011210103400240200141046a280200450d00200128020010290b2001410c6a2101200041746a22000d000b0b410321062015450d12201110290c120b410110272201450d0e200141013a000020014101410910282201450d0f2001200337000141014185b1c000411c20014109101d2001102920024180026a103d200b450d12200a10290c120b200241fc006a41013602002002420137026c200241cc81c2003602682002410236028c03200241d083c20036028803200220024188036a360278200241e8006a41d481c2001057000b20052006103e000b41014101102a000b41094101102a000b20062001103e000b20062001103e000b20064104102a000b20144104102a000b41084101102a000b20064101102a000b20134101102a000b20004101102a000b20064101102a000b102b000b41014101102a000b41094101102a000b410421060b0240200b450d00200a10290b02400240024002400240024020060e06010203040500010b41d883c500412e10100c050b418684c500412c10100c040b41b284c500412d10100c030b41df84c500412a10100c020b418985c500411f10100c010b41a885c500412e10100b20024180046a240042010be60905027f027e027f017e067f230041d0006b22022400024002402001450d00200220003602080c010b200241b8d6c5003602080b2002200136020c200241206a200241086a1043024002400240024002400240024020022802202203450d002002200229022422043702142002200336021020024101360248200241d6a1c10036024c200241206a200241106a200241c8006a105f02400240200229032022054205510d00200241386a2802002101200241306a280200210620022802342107024020054200520d0020022903282108200621090c020b2005a7220041014b0d000240024020000e020001000b2007450d01200610290c010b200228023c450d00200110290b41002106410021090b200241003602282002420137032041011027210a0240024020090d00200a450d0320024281808080103702242002200a360220200a41003a000042808080801021050c010b200a450d0320024281808080103702242002200a360220200a41013a000020022001360248200241c8006a200241206a10300240024020010d002002280224210b200228022821000c010b2009200141286c6a210c2002280224210b2002280228210020092101034002400240200b20006b4120490d00200041206a210d2002280220210a0c010b200041206a220d2000490d0a200b410174220a200d200d200a491b220e4100480d0a02400240200b0d00200e1027210a0c010b2002280220200b200e1028210a0b200a450d072002200e3602242002200a360220200e210b0b200a20006a220041186a200141186a290000370000200041106a200141106a290000370000200041086a200141086a2900003700002002200d36022820002001290000370000200141206a290300210502400240200b200d6b4108490d00200d41086a21000c010b200d41086a2200200d490d0a200b410174220e20002000200e491b220e4100480d0a02400240200b0d00200e1027210a0c010b200a200b200e1028210a0b200a450d082002200e3602242002200a360220200e210b0b20022000360228200a200d6a2005370000200c200141286a2201470d000b0b02400240200b20006b4108490d002002280220210a0c010b200041086a22012000490d08200b410174220d20012001200d491b22014100480d0802400240200b0d0020011027210a0c010b2002280220200b20011028210a0b200a450d07200220013602242002200a3602200b2002200041086a2201360228200a20006a20083700002001ad42208621052009450d002007450d00200610290b2004a7210b02402004422088a72201450d00200141246c21002003210103400240024020012d0000220d41034b0d00024002400240200d0e0404000102040b2001410c6a280200450d03200141086a28020010290c030b2001410c6a280200450d02200141086a28020010290c020b2001410c6a280200450d01200141086a28020010290c010b200141086a280200450d00200141046a28020010290b200141246a21012000415c6a22000d000b0b0240200b450d00200310290b200241d0006a24002005200aad840f0b200241346a410136020020024201370224200241cc81c20036022020024102360214200241e883c2003602102002200241106a360230200241206a41d481c2001057000b41014101102a000b41014101102a000b200e4101102a000b200e4101102a000b20014101102a000b102b000ba90a03027f047e077f230041d0006b22022400024002402001450d00200220003602080c010b200241b8d6c5003602080b2002200136020c200241206a200241086a10430240024002400240024002400240024020022802202203450d002002200229022422043702142002200336021020024101360248200241d6a1c10036024c200241206a200241106a200241c8006a105f42002105024002400240200229032022064205520d0042002107410021080c010b200241386a2802002108200241306a2802002100200228023c210920022802342101024020064201520d002001ad42208621052000ad2107200241c0006a280200210020022903282106200821010c020b02402006a7220a41014b0d0002400240200a0e020001000b2001450d01200010290c010b2009450d00200810290b41002108420021070b410021010b200241003602282002420137032041011027210b0240024020010d00200b450d034101210c200241013602242002200b360220200b41003a00000c010b200b450d0320024281808080103702242002200b360220200b41013a0000200b410141091028220a450d042002428980808090013702242002200a360220200a200637000120022000360248200241c8006a200241206a10300240024020000d002002280224210b2002280228210c0c010b2001200041286c6a210d2002280224210b2002280228210c034002400240200b200c6b4120490d00200c41206a21002002280220210a0c010b200c41206a2200200c490d0b200b410174220a20002000200a491b220e4100480d0b02400240200b0d00200e1027210a0c010b2002280220200b200e1028210a0b200a450d082002200e3602242002200a360220200e210b0b200a200c6a220c41186a200141186a290000370000200c41106a200141106a290000370000200c41086a200141086a29000037000020022000360228200c2001290000370000200141206a29030021060240200b20006b41074b0d00200041086a220c2000490d0b200b410174220e200c200c200e491b220c4100480d0b02400240200b0d00200c1027210a0c010b200a200b200c1028210a0b200a450d092002200c3602242002200a360220200c210b0b2002200041086a220c360228200a20006a2006370000200d200141286a2201470d000b0b02400240200b200c6b4108490d002002280220210b0c010b200c41086a2201200c490d09200b4101742200200120012000491b22014100480d0902400240200b0d0020011027210b0c010b2002280220200b20011028210b0b200b450d08200220013602242002200b3602200b200b200c6a2005200784370000200c41086a210c2009450d00200810290b2004a7210e02402004422088a72201450d00200141246c21002003210103400240024020012d0000220a41034b0d00024002400240200a0e0404000102040b2001410c6a280200450d03200141086a28020010290c030b2001410c6a280200450d02200141086a28020010290c020b2001410c6a280200450d01200141086a28020010290c010b200141086a280200450d00200141046a28020010290b200141246a21012000415c6a22000d000b0b0240200e450d00200310290b200241d0006a2400200cad422086200bad840f0b200241346a410136020020024201370224200241cc81c200360220200241023602142002418884c2003602102002200241106a360230200241206a41d481c2001057000b41014101102a000b41014101102a000b41094101102a000b200e4101102a000b200c4101102a000b20014101102a000b102b000bb405020a7f017e230041306b2202240041082103200241186a41086a220442003703002002420037031841c6c4c500411b200241186a1004200241086a41086a2004290300370300200220022903183703084100210520024100360218200241086a4110200241186a100521060240024020022802182207417f460d002002200736022c20022006360228200241186a200241286a1041024020022802182203450d00200241206a2802002104200228021c21052007450d02200610290c020b418f89c3004133104e000b410021040b200241003602202002420137031820022004360208200241086a200241186a10300240024002400240024020040d0020022802202107200228021821080c010b2003200441286c6a2109200228021c210a2002280220210720032104034002400240200a20076b4120490d00200741206a2106200228021821080c010b200741206a22062007490d05200a4101742208200620062008491b220b4100480d0502400240200a0d00200b102721080c010b2002280218200a200b102821080b2008450d032002200b36021c20022008360218200b210a0b200820076a220741186a200441186a290000370000200741106a200441106a290000370000200741086a200441086a2900003700002002200636022020072004290000370000200441206a290300210c02400240200a20066b4108490d00200641086a21070c010b200641086a22072006490d05200a410174220b20072007200b491b220b4100480d0502400240200a0d00200b102721080c010b2008200a200b102821080b2008450d042002200b36021c20022008360218200b210a0b20022007360220200820066a200c3700002009200441286a2204470d000b0b02402005450d00200310290b200241306a24002007ad4220862008ad840f0b200b4101102a000b200b4101102a000b102b000b7101017f024002400240410810272202450d00200242f20c37000020024108411010282202450d01200242960237000820024110412010282202450d02200242e807370018200242e8073700102002ad42808080808004840f0b41084101102a000b41104101102a000b41204101102a000b870d05017f017e067f017e077f230041f0006b22022400200241106a41e2c5c50041131094012002290318210320022802102104200241d0006a41086a220542003703002002420037035041d2c5c5004110200241d0006a1004200241206a41086a2005290300370300200220022903503703204100210620024100360250200241206a4110200241d0006a100521050240024020022802502207417f460d002005450d002002200736023420022005360230200241d0006a200241306a1041024020022802502206450d00200241d8006a2802002108200228025421092007450d02200510290c020b418f89c3004133104e000b0b200241c3c5c500410f1094012002290308210a2002280200210b200241d0006a41086a22054200370300200242003703504185c6c500410f200241d0006a1004200241206a41086a20052903003703002002200229035037032020024100360250200241206a4110200241d0006a10052105024002400240024002400240024002400240024020022802502207417f460d002005450d00200241d0006a2007412020074120491b220c6a410041004120200c6b200c411f4b1b10cd041a200241d0006a2005200c10ce041a2007411f4d0d02200241306a41186a2207200241d0006a41186a220c290000370300200241306a41106a220d200241d0006a41106a220e290000370300200241306a41086a220f200241d0006a41086a22102900003703002002200229005037033020051029200c2007290300370300200e200d2903003703002010200f290300370300200220022903303703500c010b200241d8006a4200370300200241e0006a4200370300200241e8006a4200370300200242003703500b200241306a41186a200241d0006a41186a290300370300200241306a41106a200241d0006a41106a290300370300200241306a41086a200241d0006a41086a290300370300200220022903503703302002410036025820024201370350410810272205450d01200242888080808001370254200220053602502005200a4200200b1b37000020054108411010282205450d0220024290808080800237025420052003420020041b3700082002200536025002404110200228025822076b41074b0d00200741086a22042007490d084110410174220b20042004200b491b22044100480d080240024041100d002004102721050c010b200541102004102821050b2005450d0420022004360254200220053602500b2006410820061b21102002200741086a360258200520076a42eb0237000020022008410020061b2205360220200241206a200241d0006a1030200228025421082002280258210e02402005450d002010200541286c6a21114100200e6b210b410021050340200e20056a210c024002402008200b6a4120490d00200228025021040c010b200c41206a2207200c490d0a20084101742204200720072004491b22074100480d0a0240024020080d002007102721040c010b200228025020082007102821040b2004450d072002200736025420022004360250200721080b2004200e6a20056a220d41186a201020056a220741186a290000370000200d41106a200741106a290000370000200d41086a200741086a2900003700002002200c41206a220f360258200d2007290000370000200741206a290300210302402008200b6a41606a41074b0d00200f41086a220d200f490d0a2008410174220f200d200d200f491b220d4100480d0a0240024020080d00200d102721040c010b20042008200d102821040b2004450d082002200d36025420022004360250200d21080b2002200c41286a3602582004200e6a20056a41206a2003370000200b41586a210b200541286a21052011200741286a470d000b200e20056a210e0b024002402008200e6b4120490d00200228025021050c010b200e41206a2205200e490d0820084101742207200520052007491b22074100480d080240024020080d002007102721050c010b200228025020082007102821050b2005450d0720022007360254200220053602500b2005200e6a22072002290330370000200741186a200241306a41186a290300370000200741106a200241306a41106a290300370000200741086a200241306a41086a290300370000200e41206a210702402006450d002009450d00201010290b200241f0006a24002007ad4220862005ad840f0b418f89c3004133104e000b41084101102a000b41104101102a000b20044101102a000b20074101102a000b200d4101102a000b20074101102a000b102b000b800603097f037e027f230041306b22022400200241186a41086a220342003703002002420037031841d2c5c5004110200241186a1004200241086a41086a2003290300370300200220022903183703084100210420024100360218200241086a4110200241186a100521050240024002400240024020022802182206417f460d002002200636022c20022005360228200241186a200241286a104120022802182207450d01200241206a2802002103200228021c210802402006450d00200510290b410021040240200341286c22060d00410121094100210a0c030b200641286d220a41ffffff3f71200a470d04200a41057422064100480d042006102722090d0220064101102a000b410121094100210a0c020b418f89c3004133104e000b02402003450d00200341286c21054100210420092103200721060340200641086a290000210b200641106a290000210c2006290000210d200341186a200641186a290000370000200341106a200c370000200341086a200b3700002003200d370000200441016a2104200341206a2103200641286a2106200541586a22050d000b0b2008450d00200710290b200241003602202002420137031820022004360208200241086a200241186a103002400240024020040d0020022802202106200228021821080c010b2004410574210e4100200228022022066b210520022802182108200228021c21072009210303400240200720056a411f4b0d00200641206a22042006490d042007410174220f20042004200f491b22044100480d040240024020070d002004102721080c010b200820072004102821080b2008450d03200421070b200820066a22042003290000370000200441186a200341186a290000370000200441106a200341106a290000370000200441086a200341086a290000370000200541606a2105200641206a2106200341206a2103200e41606a220e0d000b2002200736021c20022006360220200220083602180b0240200a450d00200910290b200241306a24002006ad4220862008ad840f0b20044101102a000b102b000b860601087f230041106b2202240020024100360208200242013703002000280200210302400240024002400240410410272204450d0020024284808080c00037020420022004360200200420033600002000280204210320044104410810282204450d012002428880808080013702042004200336000420022004360200200028020821042002200041106a280200220336020c2002410c6a2002103002402003450d00200341057421052002280204210620022802082103034002400240200620036b4120490d00200341206a2107200228020021080c010b200341206a22072003490d0720064101742208200720072008491b22094100480d070240024020060d002009102721080c010b200228020020062009102821080b2008450d052002200936020420022008360200200921060b200820036a220341086a200441086a290000370000200341106a200441106a290000370000200341186a200441186a290000370000200220073602082003200429000037000020072103200441206a2104200541606a22050d000b0b2000280214210420022000411c6a280200220336020c2002410c6a200210300240024020030d002002280208210320022802042105200228020021080c010b200341057421094100200228020822036b210620022802042105034002400240200520066a4120490d00200228020021080c010b200341206a22072003490d0720054101742208200720072008491b22074100480d070240024020050d002007102721080c010b200228020020052007102821080b2008450d062002200736020420022008360200200721050b200820036a220741086a200441086a290000370000200741106a200441106a290000370000200741186a200441186a2900003700002002200341206a220336020820072004290000370000200641606a2106200441206a2104200941606a22090d000b0b2001280200200128020420082003100302402005450d00200810290b200241106a24000f0b41044101102a000b41084101102a000b20094101102a000b20074101102a000b102b000bb60201037f230041106b22022400200241003602082002420137030020002d000021034101102721040240024002400240024020034101460d002004450d02200441003a0000200242818080801037020420022004360200200041086a200210dd02200228020445210020022802082103200228020021040c010b2004450d02200441013a00002002428180808010370204200220043602004121210320044101412110282204450d0320042000290001370001200441096a200041096a290000370000200441116a200041116a290000370000200441196a200041196a290000370000200242a1808080900437020420022004360200410021000b20012802002001280204200420031003024020000d00200410290b200241106a24000f0b41014101102a000b41014101102a000b41214101102a000bfd0b02067f027e230041106b22022400200028022821032002200041306a280200220436020c2002410c6a2001103002400240024002400240024002400240024002400240200141046a2802002205200141086a28020022066b2004490d00200128020021050c010b200620046a22072006490d0920054101742206200720072006491b22064100480d090240024020050d002006102721050c010b200128020020052006102821050b2005450d0120012005360200200141046a2006360200200141086a28020021060b200141086a2207200620046a360200200520066a2003200410ce041a2000280234210502400240200141046a2802002206200728020022046b4104490d00200128020021060c010b200441046a22032004490d0920064101742204200320032004491b22044100480d090240024020060d002004102721060c010b200128020020062004102821060b2006450d0220012006360200200141046a2004360200200141086a28020021040b200141086a2203200441046a360200200620046a200536000002400240200141046a2802002206200328020022046b4120490d00200128020021060c010b200441206a22052004490d0920064101742204200520052004491b22044100480d090240024020060d002004102721060c010b200128020020062004102821060b2006450d0320012006360200200141046a2004360200200141086a28020021040b200141086a2205200441206a360200200620046a220441186a200041d0006a290000370000200441106a200041c8006a290000370000200441086a200041c0006a29000037000020042000290038370000200041086a29030021082000290300210902400240200141046a2802002206200528020022046b4110490d00200128020021060c010b200441106a22052004490d0920064101742204200520052004491b22044100480d090240024020060d002004102721060c010b200128020020062004102821060b2006450d0420012006360200200141046a2004360200200141086a28020021040b200141086a2205200441106a360200200620046a22042008370008200420093700002000290310210802400240200141046a2802002206200528020022046b4108490d00200128020021060c010b200441086a22052004490d0920064101742204200520052004491b22044100480d090240024020060d002004102721060c010b200128020020062004102821060b2006450d0520012006360200200141046a2004360200200141086a28020021040b200141086a2205200441086a360200200620046a20083700000240024020002903184201510d0002400240200141046a28020020052802002200460d00200128020021040c010b200041016a22042000490d0b20004101742206200420042006491b22064100480d0b0240024020000d002006102721040c010b200128020020002006102821040b2004450d0820012004360200200141046a2006360200200141086a28020021000b200141086a200041016a360200200420006a41003a00000c010b02400240200141046a28020020052802002204460d00200128020021060c010b200441016a22062004490d0a20044101742205200620062005491b22054100480d0a0240024020040d002005102721060c010b200128020020042005102821060b2006450d0820012006360200200141046a2005360200200141086a28020021040b200141086a2205200441016a360200200620046a41013a00002000290320210802400240200141046a2802002204200528020022006b4108490d00200128020021040c010b200041086a22062000490d0a20044101742200200620062000491b22004100480d0a0240024020040d002000102721040c010b200128020020042000102821040b2004450d0920012004360200200141046a2000360200200141086a28020021000b200141086a200041086a360200200420006a20083700000b200241106a24000f0b20064101102a000b20044101102a000b20044101102a000b20044101102a000b20044101102a000b20064101102a000b20054101102a000b20004101102a000b102b000b130020004106360204200041a894c2003602000b3400200041e087c20036020420004100360200200041146a4107360200200041106a418cacc200360200200041086a42083702000b02000b3701017f02404110102722020d0041104101102a000b2002420037000820024201370000200042908080808002370204200020023602000b5d01027f230041106b22022400200241003602082002420137030002404101102722030d0041014101102a000b200341003a0000200041086a4101360200200241013602042002200336020020002002290300370200200241106a24000bc70101017f23004190016b22022400200241003a00782002428080848080023703682002420137035820024201370350200242af0137034820024287013703402002420137033820024201370330200242013703282002420137032020024201370318200242013703102002420137030820024280808080c00037036020024280808180800437037020024100360288012002420137038001200241086a20024180016a109302200041086a200228028801360200200020022903800137020020024190016a24000b130020004110360204200041c4b5c2003602000b3301017f02404108102722020d0041084101102a000b2000428880808080013702042000200236020020024280ade2043700000b3201017f02404104102722020d0041044101102a000b20004284808080c000370204200020023602002002418080013600000b3101017f02404104102722020d0041044101102a000b20004284808080c0003702042000200236020020024180083600000b3101017f02404108102722020d0041084101102a000b20004288808080800137020420002002360200200242e8073700000b3c01017f02404110102722020d0041104101102a000b2002420037000820024280a094a58d1d370000200042908080808002370204200020023602000b3b01017f02404110102722020d0041104101102a000b2002420037000820024280c8afa025370000200042908080808002370204200020023602000b3801017f02404110102722020d0041104101102a000b200242003700082002429601370000200042908080808002370204200020023602000b3801017f02404110102722020d0041104101102a000b20024200370008200242e807370000200042908080808002370204200020023602000b3701017f02404110102722020d0041104101102a000b2002420037000820024204370000200042908080808002370204200020023602000b3001017f02404104102722020d0041044101102a000b20004284808080c00037020420002002360200200241083600000b3701017f02404110102722020d0041104101102a000b2002420037000820024210370000200042908080808002370204200020023602000b3001017f02404108102722020d0041084101102a000b20004288808080800137020420002002360200200242023700000be80c03067f0b7e047f230041106b2202240020024100360208200241086a2001280200220320012802042204410420044104491b220510ce041a2001200420056b22063602042001200320056a220536020002400240200441034b0d00200041023a00700c010b2002280208210720024200370308200241086a20052006410820064108491b220410ce041a2001200620046b22033602042001200520046a22043602000240200641074b0d00200041023a00700c010b2002290308210820024200370308200241086a20042003410820034108491b220510ce041a2001200320056b22063602042001200420056a22043602000240200341074b0d00200041023a00700c010b2002290308210920024200370308200241086a20042006410820064108491b220510ce041a2001200620056b22033602042001200420056a22043602000240200641074b0d00200041023a00700c010b2002290308210a20024200370308200241086a20042003410820034108491b220510ce041a2001200320056b22063602042001200420056a22043602000240200341074b0d00200041023a00700c010b2002290308210b20024200370308200241086a20042006410820064108491b220510ce041a2001200620056b22033602042001200420056a22043602000240200641074b0d00200041023a00700c010b2002290308210c20024200370308200241086a20042003410820034108491b220510ce041a2001200320056b22063602042001200420056a22043602000240200341074b0d00200041023a00700c010b2002290308210d20024200370308200241086a20042006410820064108491b220510ce041a2001200620056b22033602042001200420056a22043602000240200641074b0d00200041023a00700c010b2002290308210e20024200370308200241086a20042003410820034108491b220510ce041a2001200320056b22063602042001200420056a22043602000240200341074b0d00200041023a00700c010b2002290308210f20024200370308200241086a20042006410820064108491b220510ce041a2001200620056b22033602042001200420056a22043602000240200641074b0d00200041023a00700c010b2002290308211020024200370308200241086a20042003410820034108491b220510ce041a2001200320056b22063602042001200420056a22043602000240200341074b0d00200041023a00700c010b2002290308211120024200370308200241086a20042006410820064108491b220510ce041a2001200620056b22033602042001200420056a22043602000240200641074b0d00200041023a00700c010b2002290308211220024100360208200241086a20042003410420034104491b220510ce041a2001200320056b22063602042001200420056a22043602000240200341034b0d00200041023a00700c010b2002280208211320024100360208200241086a20042006410420064104491b220510ce041a2001200620056b22033602042001200420056a22043602000240200641034b0d00200041023a00700c010b2002280208211420024100360208200241086a20042003410420034104491b220510ce041a2001200320056b22063602042001200420056a22043602000240200341034b0d00200041023a00700c010b2002280208211520024100360208200241086a20042006410420064104491b220510ce041a2001200620056b22033602042001200420056a22043602000240200641034b0d00200041023a00700c010b20022802082116200241003a0008200241086a20042003410047220510ce041a024020032005490d002001200320056b22063602042001200420056a2204360200024020030d00200041023a00700c020b20022d0008210320024100360208200241086a20042006410420064104491b220510ce041a2001200620056b3602042001200420056a3602000240200641034b0d00200041023a00700c020b20022802082101200020033a00702000200136026c2000201636026820002015360264200020143602602000201336025c200020073602582000201237035020002011370348200020103703402000200f3703382000200e3703302000200d3703282000200c3703202000200b3703182000200a370310200020093703082000200837030020002002280008360071200041f4006a200241086a41036a2800003600000c010b20052003103e000b200241106a24000b970402067f017e230041e0006b2202240002400240024002400240411a10272203450d00200341186a41002f00cfce423b0000200341106a41002900c7ce42370000200341086a41002900bfce42370000200341002900b7ce423700002003411a413a10282203450d012003200129000037001a200341326a200141186a2900003700002003412a6a200141106a290000370000200341226a200141086a290000370000200241c0006a41186a22014200370300200241c0006a41106a22044200370300200241c0006a41086a22054200370300200242003703402003413a200241c0006a1000200241186a41186a2001290300370300200241186a41106a2004290300370300200241186a41086a20052903003703002002200229034037031820024100360240200241186a4120200241c0006a1005210420022802402201417f460d032002200136023c20022004360238200241c0006a200241386a10f30220022802482205450d02200241086a2206200241c0006a41146a290200370300200241106a2207200241c0006a411c6a2802003602002002200229024c3703002002290340210802402001450d00200410290b20002005360208200020083702002000200229030037020c200041146a20062903003702002000411c6a20072802003602000c040b411a4101102a000b413a4101102a000b418f89c3004133104e000b200041003602080b20031029200241e0006a24000bc60202067f017e230041106b220224002002410036020020022001280200220320012802042204410420044104491b220510ce0421022001200420056b22063602042001200320056a220536020002400240200441034b0d00200041003602080c010b2002280200210720024100360200200220052006410420064104491b220310ce0421042001200620036b3602042001200520036a3602000240200641034b0d00200041003602080c010b2004280200210620042001102d0240200428020022050d00200041003602080c010b2004290204210820042001102d2008a721010240200428020022030d00200041003602082001450d01200510290c010b200041186a2004290204370200200041146a2003360200200041106a20084220883e02002000200136020c2000200536020820002006360204200020073602000b200241106a24000b130020004104360204200041d4cec2003602000b3400200041cad6c20036020420004100360200200041146a4105360200200041106a41e0d6c200360200200041086a42133702000b340020004194ddc20036020420004100360200200041146a4105360200200041106a41a8ddc200360200200041086a42133702000bf02105027f017e027f017e067f230041f0016b22012400024002400240024002400240024041880110272202450d000240024002400240024002400240024002400240024002400240024002400240024002400240200028020022002802000e12000102030405060708090a0b0c0d0e0f1011000b200141e8006a200041086a10960220024100360200200241106a200141e8006a41086a290300370300200220012903683703080c110b109702000b200041086a290300210320024102360200200220033703080c0f0b200141e8006a200041046a1038200241033602002002410c6a200141f0006a280200360200200220012903683702040c0e0b109802000b0240024002400240200041086a280200417f6a220441014b0d0020040e020102010b41e4bdc0001058000b41012104024002402000410c6a22052d00004101460d00200141026a200541036a2d00003a0000200141f0006a2000411c6a290200370300200141e8006a41106a200041246a29020037030020014180016a2000412c6a2d00003a0000200120052f00013b01002001200041146a290200370368200041106a2802002105410021040c010b200041106a28020021050b200141246a41026a200141026a2d00003a0000200141286a41086a200141e8006a41086a290300370300200141286a41106a200141e8006a41106a290300370300200141286a41186a200141e8006a41186a280200360200200120012f01003b012420012001290368370328200041386a29030021032000290330210641012107200141106a21000c010b41012104024002402000410c6a22052d00004101460d00200141ee016a200541036a2d00003a0000200141f0006a2000411c6a290200370300200141e8006a41106a200041246a29020037030020014180016a2000412c6a2d00003a0000200120052f00013b01ec012001200041146a290200370368200041106a2802002105410021040c010b200041106a28020021050b41022107200141246a41026a200141ec016a41026a2d00003a0000200141286a41086a200141e8006a41086a290300370300200141286a41106a200141e8006a41106a290300370300200141286a41186a200141e8006a41186a280200360200200120012f01ec013b012420012001290368370328200120002903303703102001200041386a290300370318200041c8006a290300210320002903402106200121000b2000200637030020002003370308200220043a000c20022007360208200220012f01243b000d2002410f6a200141266a2d00003a000020022005360210200220012903283702142002411c6a200141286a41086a290300370200200241246a200141386a2903003702002002412c6a200141c0006a280200360200200241386a200141106a41086a2903003703002002200129031037033020022001290300370340200241c8006a200141086a290300370300200241053602000c0c0b200141e8006a200041086a10990220024106360200200241386a200141e8006a41306a290300370300200241306a200141e8006a41286a290300370300200241286a200141e8006a41206a290300370300200241206a200141e8006a41186a290300370300200241186a200141e8006a41106a290300370300200241106a200141e8006a41086a290300370300200220012903683703080c0b0b200141e8006a41186a200041286a290000370300200141e8006a41106a200041206a290000370300200141f0006a200041186a290000370300200141e8006a41286a200041386a290000370300200141e8006a41306a200041c0006a290000370300200141e8006a41386a200041c8006a2900003703002001200041106a2900003703682001200041306a290000370388012000410c6a2802002204417f4c0d0c0240024020040d00410121000c010b20002802042105200410272200450d0e20002005200410ce041a0b200141286a41386a2205200141e8006a41386a290300370300200141286a41306a2207200141e8006a41306a290300370300200141286a41286a2208200141e8006a41286a290300370300200141286a41206a2209200141e8006a41206a290300370300200141286a41186a220a200141e8006a41186a290300370300200141286a41106a220b200141e8006a41106a290300370300200141286a41086a220c200141e8006a41086a290300370300200120012903683703282002200436020c200220043602082002200036020420022001290328370210200241186a200c290300370200200241206a200b290300370200200241286a200a290300370200200241306a2009290300370200200241386a2008290300370200200241c0006a2007290300370200200241c8006a2005290300370200200241073602000c0a0b200141e8006a200041086a109a0220024108360200200241386a200141e8006a41306a290300370300200241306a200141e8006a41286a290300370300200241286a200141e8006a41206a290300370300200241206a200141e8006a41186a290300370300200241186a200141e8006a41106a290300370300200241106a200141e8006a41086a290300370300200220012903683703080c090b02400240024002400240024020002d0004417f6a220441034b0d0020040e0401020304010b41c893c2001058000b200041106a280200220741ffffff3f712007470d0e20074105742204417f4c0d0e200041086a2802002109410121004101210802402004450d00200410272208450d110b024020070d0041002104410021070c040b20074105742105416020096b210a2008210020092104034020002004290000370000200041186a200441186a290000370000200041106a200441106a290000370000200041086a200441086a290000370000200041206a2100200441206a2104200541606a22050d000b41012100200920074105746a200a6a41057641016a21040c030b200041086a10f7022108410221000c020b200041086a28020021082000410c6a10f7022107410321000c010b2001412a6a200041046a220441036a2d00003a0000200141e8006a41086a2000411c6a290000370300200141e8006a41106a200041246a2d00003a0000200120042f00013b01282001200041146a29000037036820002d00254100472109200041286a2802002105200041106a28000021042000410c6a2800002107200041086a2800002108410421000b200220003a0004200220012f01283b0005200220043602102002200736020c200220083602082002200129036837021420022005360228200220093a002520024109360200200241076a2001412a6a2d00003a00002002411c6a200141f0006a290300370200200241246a200141f8006a2d00003a00000c080b02400240024002400240024020002d0004417f6a220441034b0d0020040e0401020304010b41c893c2001058000b200041106a280200220741ffffff3f712007470d0d20074105742204417f4c0d0d200041086a2802002109410121004101210802402004450d00200410272208450d110b024020070d0041002104410021070c040b20074105742105416020096b210a2008210020092104034020002004290000370000200041186a200441186a290000370000200041106a200441106a290000370000200041086a200441086a290000370000200041206a2100200441206a2104200541606a22050d000b41012100200920074105746a200a6a41057641016a21040c030b200041086a10f7022108410221000c020b200041086a28020021082000410c6a10f7022107410321000c010b2001412a6a200041046a220441036a2d00003a0000200141e8006a41086a2000411c6a290000370300200141e8006a41106a200041246a2d00003a0000200120042f00013b01282001200041146a29000037036820002d00254100472109200041286a2802002105200041106a28000021042000410c6a2800002107200041086a2800002108410421000b200220003a0004200220012f01283b0005200220043602102002200736020c200220083602082002200129036837021420022005360228200220093a00252002410a360200200241076a2001412a6a2d00003a00002002411c6a200141f0006a290300370200200241246a200141f8006a2d00003a00000c070b200141e8006a200041086a10c8012002410b360200200241c0006a200141e8006a41386a290300370300200241386a200141e8006a41306a290300370300200241306a200141e8006a41286a290300370300200241286a200141e8006a41206a290300370300200241206a200141e8006a41186a290300370300200241186a200141e8006a41106a290300370300200241106a200141e8006a41086a290300370300200220012903683703080c060b200041086a29030021032002410c360200200220033703080c050b2000410c6a2802002204417f4c0d060240024020040d00410121000c010b20002802042105200410272200450d0b20002005200410ce041a0b2002200436020c20022004360208200220003602042002410d3602000c040b024002400240024002400240200041086a280200417f6a220441024b0d0020040e03010203010b4190a9c1001058000b200041386a2903002103200041306a290300210641012104024002402000410c6a2d00004101460d00200141f0006a2000411c6a290200370300200141e8006a41106a200041246a29020037030020014180016a2000412c6a2d00003a00002001200041146a29020037036820002f000d2000410f6a2d0000411074722105200041106a2802002100410021040c010b200041106a28020021000b200141286a41186a200141e8006a41186a280200360200200141286a41106a200141e8006a41106a290300370300200141286a41086a200141e8006a41086a29030037030020012001290368370328410121070c030b2000410c6a28020022044108762105410221070c010b2000410c6a28020022044108762105410321070b0b200220063703302002200036021020022007360208200220012903283702142002410e360200200241386a200337030020022005410874200441ff01717236020c2002411c6a200141286a41086a290300370200200241246a200141386a2903003702002002412c6a200141c0006a2802003602000c030b200141e8006a200041086a109c02200241086a200141e8006a41800110ce041a2002410f3602000c020b02400240024002402000280204417f6a220441014b0d0020040e020102010b41f8e2c1001058000b41880110272204450d0a2004200041086a280200109502410121000c010b4101210402400240200041086a2d00004101460d00200141e8006a41086a200041186a290200370300200141e8006a41106a200041206a290200370300200141e8006a41186a200041286a2d00003a00002001200041106a29020037036820002f00092000410b6a2d00004110747221072000410c6a2802002105410021040c010b2000410c6a28020021050b200141286a41186a200141e8006a41186a280200360200200141286a41106a200141e8006a41106a290300370300200141286a41086a200141e8006a41086a2903003703002001200129036837032820042007410874722104410221000b2002200536020c20022004360208200220003602042002200129032837021020024110360200200241186a200141306a290300370200200241206a200141286a41106a290300370200200241286a200141286a41186a2802003602000c010b200141e8006a200041086a10b101200241086a200141e8006a41d80010ce041a200241113602000b200141f0016a240020020f0b4188014108102a000b1039000b20044101102a000b20044101102a000b20044101102a000b20044101102a000b4188014108102a000bc50401047f230041f0006b22072400200741086a200242002003200410d304200741c0006a41e887c50041111094012007290348210320072802402108200741e0006a41086a220942003703002007420037036041e887c5004111200741e0006a1004200741d0006a41086a220a2009290300370300200720072903603703502007200120027d2003420020081b7c370360200741d0006a4110200741e0006a41081003200741306a20002007290308200741086a41086a290300108301200741306a41086a290300210120072903302102200741186a41b18ac0004116108601200520027d200220057d2002200558200120065820012006511b22001b2103200620017d2005200254ad7d200120067d2002200554ad7d20001b2106200741186a41106a2903004200200728021822081b21052007290320420020081b2102024002402000450d00200942003703002007420037036041b18ac0004116200741e0006a1004200a20092903003703002007200729036037035020074200200520067d2002200354ad7d2206200220037d2201200256200620055620062005511b22091b37036820074200200120091b370360200741e0006a21090c010b200942003703002007420037036041b18ac0004116200741e0006a1004200a2009290300370300200720072903603703502007427f200520067c200220037c22062002542209ad7c22022009200220055420022005511b22091b3703682007427f200620091b370360200741e0006a21090b200741d0006a4110200941101003200741f0006a24000bcd0101047f200020014105746a210320002104024003400240200320046b41e0004b0d00024020042003460d00200020014105746a210503404101210620022004460d0420042002412010d004450d042005200441206a2204470d000b0b41000f0b4101210620042002460d0120042002412010d004450d01200441206a22052002460d0120052002412010d004450d01200441c0006a22052002460d0120052002412010d004450d01200441e0006a22052002460d0120044180016a210420052002412010d0040d000b0b20060bbd0101047f230041a0026b2202240020024100360290012001412020024190016a100521030240024002402002280290012204417f470d00411221050c010b2002200436029c02200220033602980220024190016a20024198026a103c20022802900122054112460d012002410c6a20024190016a41047241840110ce041a02402004450d00200310290b20014120100c0b20002005360200200041046a2002410c6a41840110ce041a200241a0026a24000f0b418f89c3004133104e000b970402067f017e230041e0006b2202240002400240024002400240411a10272203450d00200341186a41002f009de7423b0000200341106a4100290095e742370000200341086a410029008de74237000020034100290085e7423700002003411a413a10282203450d012003200129000037001a200341326a200141186a2900003700002003412a6a200141106a290000370000200341226a200141086a290000370000200241c0006a41186a22014200370300200241c0006a41106a22044200370300200241c0006a41086a22054200370300200242003703402003413a200241c0006a1000200241186a41186a2001290300370300200241186a41106a2004290300370300200241186a41086a20052903003703002002200229034037031820024100360240200241186a4120200241c0006a1005210420022802402201417f460d032002200136023c20022004360238200241c0006a200241386a10f30220022802482205450d02200241086a2206200241c0006a41146a290200370300200241106a2207200241c0006a411c6a2802003602002002200229024c3703002002290340210802402001450d00200410290b20002005360208200020083702002000200229030037020c200041146a20062903003702002000411c6a20072802003602000c040b411a4101102a000b413a4101102a000b418f89c3004133104e000b200041003602080b20031029200241e0006a24000ba40b03087f017e017f23004180026b22022400200241e0016a41186a22034200370300200241e0016a41106a22044200370300200241e0016a41086a22054200370300200242003703e001200241e0016a2001280200220620012802042207412020074120491b220810ce041a2001200720086b22093602042001200620086a22083602000240024002400240024002402007411f4d0d00200241c0016a41186a2003290300370300200241c0016a41106a2004290300370300200241c0016a41086a2005290300370300200220022903e0013703c001200241003a00e001200241e0016a20082009410047220710ce041a20092007490d022001200920076b22063602042001200820076a22073602002009450d0020022d00e00122034106490d010b200041023a00210c040b200241186a200241c0016a41186a290300370300200241106a200241c0016a41106a290300370300200241086a200241c0016a41086a290300370300200220022903c001370300200241003a00e001200241e0016a20072006410047220810ce041a20062008490d012001200620086b22093602042001200720086a220736020002402006450d0020022d00e001220841014b0d00410021060240024020080e020100010b200241e0016a2009412020094120491b22086a41004100412020086b2008411f4b1b10cd041a200241e0016a2007200810ce041a2001200920086b22043602042001200720086a22073602002009411f4d0d01200241a0016a41086a200241e0016a41086a290000220a37030020024180016a41186a200241e0016a41186a29000037030020024180016a41106a200241e0016a41106a29000037030020024180016a41086a200a370300200220022900e001220a3703a0012002200a3703800141012106200421090b200241e0006a41186a20024180016a41186a290300370300200241e0006a41106a20024180016a41106a290300370300200241e0006a41086a20024180016a41086a2903003703002002200229038001370360200241003a00e001200241e0016a20072009410047220810ce041a20092008490d032001200920086b22043602042001200720086a22073602002009450d0020022d00e001220841014b0d00410021090240024020080e020100010b200241e0016a2004412020044120491b22086a41004100412020086b2008411f4b1b10cd041a200241e0016a2007200810ce041a2001200420086b3602042001200720086a3602002004411f4d0d01200241a0016a41086a200241e0016a41086a290000220a37030020024180016a41186a200241e0016a41186a29000037030020024180016a41106a200241e0016a41106a29000037030020024180016a41086a200a370300200220022900e001220a3703a0012002200a37038001410121090b200241206a41186a220120024180016a41186a290300370300200241206a41106a220720024180016a41106a290300370300200241206a41086a220820024180016a41086a290300370300200241c0006a41086a2204200241e0006a41086a290300370300200241c0006a41106a2205200241e0006a41106a290300370300200241c0006a41186a220b200241e0006a41186a290300370300200220022903800137032020022002290360370340200041186a200241186a290300370000200041106a200241106a290300370000200041086a200241086a29030037000020002002290300370000200020063a0021200020033a0020200041c2006a20093a0000200020022903403700222000412a6a2004290300370000200041326a20052903003700002000413a6a200b290300370000200041c3006a2002290320370000200041cb006a2008290300370000200041d3006a2007290300370000200041db006a20012903003700000c040b200041023a00210c030b20072009103e000b20082006103e000b20082009103e000b20024180026a24000b3400200041e6efc20036020420004100360200200041146a4102360200200041106a41f0efc200360200200041086a42073702000bd60401097f230041d0006b220224000240410f10272203450d00200341076a41002900f3ec42370000200341002900ecec4237000002402003410f411e10282204450d002004200036000f200241306a41186a22034200370300200241306a41106a22004200370300200241306a41086a220542003703002002420037033020044113200241306a1000200241086a41186a2003290300370300200241086a41106a2000290300370300200241086a41086a20052903003703002002200229033037030820024100360238200242013703302001280200210620022001280208220336022c2002412c6a200241306a10300240024020030d002002280238210520022802342107200228023021080c010b2003410574210920022802302108200228023421072002280238210020062103034002400240200720006b4120490d00200041206a21050c010b0240200041206a22052000490d002007410174220a20052005200a491b220a4100480d000240024020070d00200a102721080c010b20082007200a102821080b02402008450d00200a21070c020b200a4101102a000b102b000b200820006a22002003290000370000200041186a200341186a290000370000200041106a200341106a290000370000200041086a200341086a29000037000020052100200341206a2103200941606a22090d000b2002200736023420022005360238200220083602300b200241086a412020082005100302402007450d00200810290b200410290240200141046a280200450d00200610290b200241d0006a24000f0b411e4101102a000b410f4101102a000bd06704167f017e087f017e23004180036b2204240041002105200441003602f002200420023602ec02200420013602e8020240024002400240024002400240200241034b0d0041012106200441013a00d002200441ec016a4101360200200442013702dc0120044180c0c5003602d8012004411f3602b4022004200441b0026a3602e8012004200441d0026a3602b00220044180016a200441d8016a10e6032004280280012107200428028401210820042802880121094105210a4100210b0c010b200441043602f002024020012800004180c2cdeb06460d004101210a410121060c010b024002402002417c714104460d00200241074b0d0141082002107f000b41012106200441013a00d002200441ec016a4101360200200442013702dc0120044180c0c5003602d8012004411f3602b4022004200441b0026a3602e8012004200441d0026a3602b00220044180016a200441d8016a10e6032004280280012107200428028401210820042802880121094105210a410021054100210b0c010b200441083602f002410121060240200128000422074101460d004102210a0c010b200441d8016a200441e8026a10f20302400240024020042802d8014101470d00410421084100210c410021090c010b200441d8016a410572210d410421084128210a410021054100210c410021094100210b02400340200441d0026a41026a2201200d41026a2d00003a00002004200d2f00003b01d002200428028402210e200428028002210f20042802fc01211020042802f801211120042802f401211220042802f001211320042802ec01211420042802e801211520042802e401211620042802e0012117024020042d00dc012206417e6a41ff0171410a4b0d004100211802400240024002400240024002400240024002400240024020060e0f0b0b000102030405060708090a0b0b0b0b410121180c0a0b410221180c090b410321180c080b410421180c070b410521180c060b410621180c050b410721180c040b410821180c030b410921180c020b410a21180c010b410b21180b0240200b41ff0171221920184d0d004113210a0c030b4100211802400240024002400240024002400240024002400240024020060e0f0b0b000102030405060708090a0b0b0b0b410121180c0a0b410221180c090b410321180c080b410421180c070b410521180c060b410621180c050b410721180c040b410821180c030b410921180c020b410a21180c010b410b21180b024020192018470d004114210a0c030b4100210b0240024002400240024002400240024002400240024020060e0f0b0b000102030405060708090a0b0b0b0b4101210b0c0a0b4102210b0c090b4103210b0c080b4104210b0c070b4105210b0c060b4106210b0c050b4107210b0c040b4108210b0c030b4109210b0c020b410a210b0c010b410b210b0b20044180016a41026a221820012d00003a0000200420042f01d0023b01800102400240200c2009470d00200c41016a2201200c490d072005200120012005491b2209ad422c7e221a422088a70d07201aa722014100480d0702400240200c0d002001102721080c010b2008200a41586a2001102821080b2008450d010b2008200a6a220141586a20063a00002001200e3602002001417c6a200f360200200141786a2010360200200141746a2011360200200141706a20123602002001416c6a2013360200200141686a2014360200200141646a2015360200200141606a20163602002001415c6a2017360200200141596a220120042f0180013b0000200141026a20182d00003a0000200541026a2105200a412c6a210a200c41016a210c200441d8016a200441e8026a10f20320042802d8014101460d030c010b0b20014104102a000b024002402006410d4b0d00024002400240024002400240024002400240024002400240024020060e0e0001020304050607080e090a0b0c000b2016450d0d201710290c0d0b02402016450d00201710290b2013450d0c201410290c0c0b02402015450d00201541047421062017210103400240200141046a280200450d00200128020010290b200141106a2101200641706a22060d000b0b2016450d0b201710290c0b0b02402015450d00201541286c21062017210103400240200141046a280200450d00200128020010290b0240200141106a280200450d002001410c6a28020010290b200141286a2101200641586a22060d000b0b2016450d0a201710290c0a0b2016450d09201710290c090b2016450d08201710290c080b2016450d07201710290c070b02402015450d00201720154104746a210d201721050340024020052802082206450d0020052802002101200641047421060340024020012d00004109470d00200141086a28020041ffffffff0371450d00200141046a28020010290b200141106a2101200641706a22060d000b0b200541106a21010240200541046a280200450d00200528020010290b200121052001200d470d000b0b2016450d06201710290c060b02402015450d00201541146c21062017210103400240200141046a280200450d00200128020010290b200141146a21012006416c6a22060d000b0b2016450d05201710290c050b02402015450d0020172015411c6c6a210d20172105034002402005410c6a2802002206450d0020052802042101200641047421060340024020012d00004109470d00200141086a28020041ffffffff0371450d00200141046a28020010290b200141106a2101200641706a22060d000b0b0240200541086a280200450d00200528020410290b2005411c6a21010240200541146a280200450d00200528021010290b200121052001200d470d000b0b2016450d04201710290c040b02402015450d002017201541186c6a210d2017210503400240200541046a280200450d00200528020010290b0240200541146a2802002206450d00200528020c2101200641047421060340024020012d00004109470d00200141086a28020041ffffffff0371450d00200141046a28020010290b200141106a2101200641706a22060d000b0b200541186a21010240200541106a280200450d00200528020c10290b200121052001200d470d000b0b2016450d03201710290c030b02402015450d0020172015411c6c6a210d20172105034002402005410c6a2802002206450d0020052802042101200641047421060340024020012d00004109470d00200141086a28020041ffffffff0371450d00200141046a28020010290b200141106a2101200641706a22060d000b0b0240200541086a280200450d00200528020410290b2005411c6a21010240200541146a280200450d00200528021010290b200121052001200d470d000b0b2016450d02201710290c020b0240201741ff0171220141024b0d0002400240024020010e03000102000b2015450d04201610290c040b02402013450d002013410c6c2106201521010340024020012802002205450d00200141046a280200450d00200510290b2001410c6a2101200641746a22060d000b0b2014450d03201510290c030b02402013450d00201520134104746a21162015211703402017220d41106a21170240200d2802042201450d000240200d410c6a2802002206450d002006410c6c21060340024020012802002205450d00200141046a280200450d00200510290b2001410c6a2101200641746a22060d000b0b200d41086a280200450d00200d28020410290b20172016470d000b0b2014450d02201510290c020b2015450d01201610290c010b02402016450d00201710290b02402013450d002012450d00201310290b200f450d00201010290b0c010b024020042d00dc010d00200c412c6c210641002105410021010240034020062001460d01200820016a210a2001412c6a220b2101200a2d0000410b470d000b2008200b6a41606a28020021050b200c412c6c21064100210d410021010240034020062001460d01200820016a210a2001412c6a220b2101200a2d00004104470d000b200441f8006a2008200b6a41586a108003200428027c210d0b02402005200d470d004100210a4101210741e100210b41f3da012105410021060c030b0240200c450d00200c412c6c210a20082101034020011088032001412c6a2101200a41546a220a0d000b0b410121064119210a024020090d000c030b200810290c020b20042802dc01220a4110762105200a410876210b200441d8016a41106a280200210d200441e4016a2802002117200441d8016a41086a28020021070b0240200c450d00200c412c6c210620082101034020011088032001412c6a2101200641546a22060d000b0b4101210602402009450d00200810290b200d2109201721080b02402006450d00200821060c040b20042802f0022002470d022005411074200b41ff017141087472200a41ff017172211b2008200c412c6c6a210a20082101024002400340200a2001460d0120012d000021022001412c6a2206210120024102470d000b200441f0006a200641586a1080034104211c200428027021024100211002400240024002400240200428027422010d004100211d0c010b2001410474220a4100480d06200a1027221c450d012001211d0b02402001450d002001410474210641002110201c21010340200241086a280200220a417f4c0d032002410c6a2d0000210b2002280200210502400240200a0d004101210d0c010b200a1027220d450d050b200d2005200a10ce0421052001410d6a2002410d6a2d00003a00002001410c6a200b3a0000200141086a200a360200200141046a200a36020020012005360200200141106a2101201041016a2110200241106a2102200641706a22060d000b0b201c450d030c040b200a4104102a000b1039000b200a4101102a000b4100211d4104211c410021100b2008200c412c6c6a210a20082101024003404100210641b8d6c500210b0240200a2001470d00410021010c020b20012d000021022001412c6a2205210120024103470d000b200441e8006a200541586a1080034100210120042802682202450d00200428026c21012002210b0b0240024020010d0041012112410021134100210a4100210e410421154100210b4100211e41042114410421174100210241002105410021164100211f410121190c010b200141286c210d200b411c6a2101410421154100210641002113410121124100210a4100210e4100210b4100211e41042114410421174100210241002105410021164100211f41012119024002400240024002400340024002400240024002402001417c6a2d00000e0400010203000b2001280200210f0240024020052002460d00200521110c010b200241016a22112002490d0c20024101742218201120112018491b221841ffffffff03712018470d0c201841027422114100480d0c0240024020020d002011102721170c010b201720024102742011102821170b2017450d0620022111201821020b201720114102746a200f360200200541016a21050c030b200441d8016a41086a220f200141086a280200360200200420012902003703d8010240200a200e470d00200a41016a220e200a490d0b200a4101742211200e200e2011491b220ead420c7e221a422088a70d0b201aa722114100480d0b02400240200a0d002011102721150c010b2015200a410c6c2011102821150b2015450d060b2015200a410c6c6a221120042903d801370200201141086a200f280200360200200a41016a210a0c020b200441d8016a41086a220f200141086a280200360200200420012902003703d8010240200b201e470d00200b41016a2211200b490d0a200b4101742218201120112018491b221ead420c7e221a422088a70d0a201aa722114100480d0a02400240200b0d002011102721140c010b2014200b410c6c2011102821140b2014450d060b2014200b410c6c6a221120042903d801370200201141086a200f280200360200200b41016a210b0c010b2001417e6a220f2d000021112001417d6a22182d00002120024020062013470d00200641016a22132006490d0920064101742221201320132021491b221320136a22222013490d0920224100480d090240024020060d002022102721120c010b201220212022102821120b2012450d060b201220064101746a222220114101713a0001202220203a0000200f2d0000210f20182d000021110240201f2016470d00201641016a22182016490d0920164101742220201820182020491b221f201f6a2218201f490d0920184100480d090240024020160d002018102721190c010b201920202018102821190b2019450d070b200641016a2106201920164101746a2218200f4101713a0001201820113a0000201641016a21160b200141286a2101200d41586a220d450d060c000b0b20114104102a000b20114104102a000b20114104102a000b20224101102a000b20184101102a000b2008200c412c6c6a210f200821010240024002400240024002400240024002400240024002400240024003400240200f2001470d002002210d0c020b20012d0000210d2001412c6a22112101200d4104470d000b200441e0006a201141586a10800302402004280264220d0d002002210d0c010b20042802602101200d410274210f0340200128020021110240024020052002460d002002210d200521180c010b200241016a220d2002490d1020024101742218200d200d2018491b220d41ffffffff0371200d470d10200d41027422184100480d100240024020020d002018102721170c010b201720024102742018102821170b2017450d0320022118200d21020b200141046a2101201720184102746a2011360200200541016a2105200f417c6a220f0d000b0b2008200c412c6c6a210f20082101024002400340200f2001460d0120012d000021022001412c6a2211210120024105470d000b200441d8006a201141586a108003200428025c410c6c2218450d0020042802582101200a410174210f200a410c6c21020340200141086a2111024002400240200141046a2802004101470d002004201128020022203602c0022001280200222220204b0d010b20044100360280010c010b200441023602ec01200442023702dc01200441dc9cc5003602d801200441013602f402200441013602ec02200420223602d0022004200441e8026a3602e8012004200441d0026a3602f0022004200441c0026a3602e80220044180016a200441d8016a10e603200428028001450d0020044180016a21010c0e0b2001290200211a200441d8016a41086a222020112802003602002004201a3703d8010240200a200e470d00200a41016a220e200a490d11200f200e200e200f491b220ead420c7e221a422088a70d11201aa722114100480d1102400240200a0d002011102721150c010b201520022011102821150b2015450d030b2001410c6a2101201520026a221120042903d801370200201141086a2020280200360200200f41026a210f2002410c6a2102200a41016a210a201841746a22180d000b0b2008200c412c6c6a210f20082101024002400340200f2001460d0120012d000021022001412c6a2211210120024106470d000b200441d0006a201141586a10800320042802542202450d00200428025021012002410c6c2111200b410174210f200b410c6c21020340200441d8016a200110f503024020042802d801450d00200441d8016a21010c0f0b2001290200211a200441d8016a41086a2218200141086a2802003602002004201a3703d8010240200b201e470d00200b41016a221e200b490d12200f201e201e200f491b221ead420c7e221a422088a70d12201aa722204100480d1202400240200b0d002020102721140c010b201420022020102821140b2014450d030b2001410c6a2101201420026a222020042903d801370200202041086a2018280200360200200f41026a210f2002410c6a2102200b41016a210b201141746a22110d000b0b2008200c412c6c6a210f20082101024002400240024002400340200f2001460d0120012d000021022001412c6a2211210120024107470d000b200441c8006a201141586a108003200428024c2202450d002004280248220120024104746a212220064101742102200441d8016a41047221200340200441d8016a20012019201610f60302400240024020042d00d8014101460d00200420042d00d901220f3a00c0020240200f2001410c6a2d00002211470d0020044100360280010c030b200441023602ec01200442023702dc01200441f09dc5003602d801200441203602f402200441203602ec02200420113a00d0022004200441e8026a3602e8012004200441c0026a3602f0022004200441d0026a3602e80220044180016a200441d8016a10e6030c010b20044180016a41086a202041086a28020036020020042020290200370380010b0240200428028001450d0020044180016a21010c140b2001410c6a2d0000210f0b2001410d6a2d00002111024020062013470d00200641016a22132006490d162002201320132002491b221320136a22182013490d1620184100480d160240024020060d002018102721120c010b201220022018102821120b2012450d030b201220026a2218200f3a0000201841016a20114101713a0000200241026a2102200641016a2106200141106a22012022470d000b0b200441b8016a2005360200200441b4016a200d36020020044180016a412c6a2010360200200441a8016a201d360200200441a0016a20063602002004419c016a201336020020044194016a200a36020020044190016a200e360200200420173602b0012004201c3602a40120042012360298012004201536028c012004200b360288012004201e3602840120042014360280012008200c412c6c6a210a20082101024003400240200a2001470d004100210b0c020b20012d000021022001412c6a2206210120024104470d000b200441c0006a200641586a1080032004280244210b0b2004200b3602bc012008200c412c6c6a210a20082101024003400240200a2001470d00410021010c020b20012d000021022001412c6a220621012002410b470d000b200641606a28020021010b200420013602c001200b2001470d0d0240200b450d002008200c412c6c6a210a200821010340200a2001460d0520012d000021022001412c6a2206210120024104470d000b2008200c412c6c6a210b200821010340200b2001460d0420012d000021022001412c6a220a21012002410b470d000b200441386a200641586a108003200428023c2201450d002004280238220d20014102746a2115200a41606a2117200a41586a211620044191026a2111410021050340200420053602c4012017280200210120162802002102200442013702dc01200441f492c5003602d801200441013602d402200441013602ec012004200441d0026a3602e8012004200441c4016a3602d002200441e8026a200441d8016a10e60320042802e802210a20042902ec02211a200120054d0d110240201aa7450d00200a10290b2004200d28020022013602d002024002400240024020042802ac0120014b0d00200441013602ec01200442023702dc01200441e8a0c5003602d801200441013602c4022004200441c0026a3602e8012004200441d0026a3602c002200441e8026a200441d8016a10e60320042902ec02221a422088a7210120042802e802210a201aa721020c010b0240024002402002200541186c6a22022802142210450d0020042802a40120014104746a220a2d000d2113200a280200210e200228020c210120022802002114200a280208220f2106024020022802082212450d002012410374210b200f21022014210a034002402002200a2802006a220620024f0d00024041201027220a0d0041204101102a000b200a41186a41002900b8a345370000200a41106a41002900b0a345370000200a41086a41002900a8a345370000200a41002900a0a3453700000c040b200a41086a210a20062102200b41786a220b0d000b0b0240410810272202450d0020022013ad42ff0183422886370200200441d0026a41026a220a200441e8026a41026a2d00003a0000200420042f00e8023b01d002200420133a00900220044180800136028c022004428180808010370284022004200236028002200442808080808080103703f801200442013703f001200420063602ec01200420123602e801200420143602e4012004200f3602e0012004200e3602dc01200420044180016a3602d801201120042f01d0023b0000201141026a200a2d00003a0000201041047441706a41047641016a210641002102034020042002360298022004200136029c02200441b0026a200441d8016a200110f803024020042802b002450d00200441c0026a41086a200441b0026a41086a280200360200200420042903b0023703c002200441033602e402200442033702d402200441e88ac5003602d002200441213602fc02200441013602f402200441223602ec022004200441e8026a3602e0022004200441c0026a3602f802200420044198026a3602f00220042004419c026a3602e802200441a0026a200441d0026a10e603024020042802c402450d0020042802c00210290b20042802a002220a450d0020042902a402211a024020042802f401450d0020042802f00110290b201a42208821230240200428028402450d0020042802800210290b2023a72101201aa721020c070b200141106a21012006200241016a2202470d000b02402004280288020d00024020042802f401450d0020042802f00110290b200428028402450d0720042802800210290c070b41808bc5001058000b41084104102a000b41201027220a450d01200a41186a41002900de8a45370000200a41106a41002900d68a45370000200a41086a41002900ce8a45370000200a41002900c68a453700000b41202102412021010c010b41204101102a000b200a450d010b2004200a3602d00220042001ad4220862002ad843702d4022004200441d0026a3602c002200441023602ec01200442023702dc01200441fc92c5003602d801200441233602f402200441013602ec022004200441e8026a3602e8012004200441c0026a3602f0022004200441c4016a3602e802200441c8016a200441d8016a10e603024020042802d402450d0020042802d00210290b20042802c801220a450d0020042902cc01211a0c120b200541016a2105200d41046a220d2015470d000b0b2008200c412c6c6a210a2008210102400340200a2001460d0120012d000021022001412c6a2206210120024109470d000b2004200641586a28020022013602b002024020042802b80120014b0d00200441ec016a4101360200200442023702dc01200441d8a0c5003602d801200441013602c4022004200441c0026a3602e8012004200441b0026a3602c002200441e8026a200441d8016a10e6030c0d0b200420042802b00120014102746a28020022013602d002024020042802ac0120014b0d00200441ec016a4101360200200442023702dc01200441e8a0c5003602d801200441013602c4022004200441c0026a3602e8012004200441d0026a3602c002200441e8026a200441d8016a10e6030c0d0b024020042802a40120014104746a22013502084200520d00200131000d4220864280808080f000834280808080c000510d010b412d1027220a450d02200a41256a41002900b19345370000200a41206a41002900ac9345370000200a41186a41002900a49345370000200a41106a410029009c9345370000200a41086a41002900949345370000200a410029008c934537000042ad808080d005211a0c100b2008200c412c6c6a210a200821010340200a2001460d0b20012d000021022001412c6a2206210120024108470d000b200441306a200641586a2201108003200441d8016a200428023410fb03200441e8026a41086a200441e4016a290200370300200441e8026a41106a200441d8016a41146a280200360200200420042902dc013703e802200441286a2001108003200428022c2201450d0920042802282215200141146c6a210e034020152217450d0a410021022017280208220d210120172802002216210a0240200d4104490d004100210220162101200d210a0340200128000020024105777341b9f3ddf1796c2102200141046a2101200a417c6a220a41034b0d000b200d417c6a22012001417c71220a6b2101200a20166a41046a210a0b02400240200141014b0d00200a21060c010b200a41026a21062001417e6a21012002410577200a2f00007341b9f3ddf1796c21020b02402001450d00200241057720062d00007341b9f3ddf1796c21020b201741146a2115200241057741ff017341b9f3ddf1796c22024119762213410874201372220141107420017221054100210f20042802f002211220042802e802210b20042802ec0221062002210103400240200b200120067122016a2800002214200573220a417f73200a41fffdfb776a7141808182847871220a450d00024003400240200d2012200a6841037620016a2006714103746a221041046a280200470d00201620102802002210460d0220162010200d10d004450d020b200a417f6a200a71220a450d020c000b0b200441ec016a4101360200200442013702dc01200441bc93c5003602d801200441023602b4022004200d3602c402200420163602c0022004200441b0026a3602e8012004200441c0026a3602b002200441d0026a200441d8016a10e6030c0a0b200f41046a220f20016a2101201420144101747141808182847871450d000b024020042802f8020d00200441e8026a10fc0320042802e802210b20042802ec0221060b200620027121024104210103402002220a20016a2006712102200141046a2101200b200a6a280000418081828478712205450d000b0240200b200568410376200a6a20067122016a2c000022024100480d00200b200b280200418081828478716841037622016a2d000021020b200b20016a20133a00002001417c6a200671200b6a41046a20133a000020042802f00220014103746a200dad4220862016ad84370200200420042802f40241016a3602f402200420042802f80220024101716b3602f802024002400240024002400240201728020c0e0400030201000b2004201728021022013602a002024020042802b80120014b0d00200441ec016a4101360200200442023702dc01200441d8a0c5003602d801200441013602c4022004200441c0026a3602e8012004200441a0026a3602c002200441d0026a200441d8016a10e6030c0e0b200420042802b00120014102746a28020022013602b00220042802ac0120014b0d03200441013602ec01200442023702dc01200441e8a0c5003602d801200441013602c4022004200441c0026a3602e8012004200441b0026a3602c002200441d0026a200441d8016a10e6030c0d0b2004201728021022013602a002024020042802a00120014b0d00200441ec016a4101360200200442023702dc0120044188a1c5003602d801200441013602c4022004200441c0026a3602e8012004200441a0026a3602c002200441d0026a200441d8016a10e6030c0d0b20042802980120014101746a2d0001450d02200441ec016a4101360200200442023702dc01200441a8a1c5003602d801200441013602c4022004200441c0026a3602e8012004200441a0026a3602c002200441d0026a200441d8016a10e6030c0c0b2004201728021022013602b00220042802880120014b0d01200441013602ec01200442023702dc0120044188a0c5003602d801200441013602c4022004200441c0026a3602e8012004200441b0026a3602c002200441d0026a200441d8016a10e60320042802d002220a0d0c0c010b2004201728021022013602b00220042802940120014d0d010b2015200e470d010c0b0b0b200441ec016a4101360200200442023702dc01200441b8a0c5003602d801200441013602c4022004200441c0026a3602e8012004200441b0026a3602c002200441d0026a200441d8016a10e6030c070b20184101102a000b412d4101102a000b41aa92c50041c800104e000b418c92c500411e104e000b20204104102a000b20114104102a000b20184104102a000b20042802d002210a0b20042902d402211a2006450d060240200641016a220141ffffffff01712001470d00200641086a417c712202200641056a490d00200220014103746a2002491a0b200b10290c060b20042802ec022201450d000240200141016a220241ffffffff01712002470d00200141086a417c71220a200141056a490d00200a20024103746a200a491a0b20042802e80210290b2008200c412c6c6a210a2008210102400340200a2001460d0120012d000021022001412c6a2206210120024103470d000b200441206a200641586a10800320042802242201450d0020042802202106200141286c210b41002101034002400240024002400240200620016a220241186a2d00000e0400030201000b20042002411c6a28020022023602d00220042802ac0120024b0d03200441ec016a4101360200200442023702dc01200441e8a0c5003602d801200441013602c4022004200441c0026a3602e8012004200441d0026a3602c002200441e8026a200441d8016a10e6030c060b2002411a6a2d0000450d022002410c6a2802002101200241146a2802002102200441d8016a41146a4101360200200420023602d402200420013602d002200441023602c402200442013702dc01200441c493c5003602d8012004200441d0026a3602c0022004200441c0026a3602e801200441e8026a200441d8016a10e6030c050b200441d8016a2002411c6a10f50320042802d801220a450d0120042902dc01211a0c080b200241206a2802004101470d002002411c6a280200210a2004200241246a28020022023602b002200a20024d0d00200441023602ec01200442023702dc01200441dc9cc5003602d801200441013602f402200441013602ec022004200a3602c0022004200441e8026a3602e8012004200441c0026a3602f0022004200441b0026a3602e802200441d0026a200441d8016a10e60320042802d002220a0d060b200b200141286a2201470d000b0b024002400240200428029401220141014b0d00200428028801220141014b0d012008200c412c6c6a210a2008210102400240024002400340200a2001460d0120012d000021022001412c6a220621012002410c470d000b200441186a200641586a10800320042802182201200428021c411c6c6a2106034020012006460d012004200128020022023602d002024020042802880120024b0d00200441013602ec01200442023702dc0120044188a0c5003602d801200441013602c4022004200441c0026a3602e8012004200441d0026a3602c002200441e8026a200441d8016a10e60320042802e802220a450d0020042902ec02211a0c0d0b200441d8016a200141046a220120042802980120042802a00110f60320042d00d8014101460d02200141186a210120042d00d901450d000b41201027220a450d06200a41186a41002900f49345370000200a41106a41002900ec9345370000200a41086a41002900e49345370000200a41002900dc934537000042a08080808004211a0c0b0b2008200c412c6c6a210a2008210102400340200a2001460d0120012d000021022001412c6a220621012002410a470d000b200441106a200641586a10800320042802142201450d002004280210220b2001411c6c6a21050340200b450d012004200b28020022013602d00220042802940120014d0d03200441d8016a200b41046a20042802980120042802a00110f60320042d00d8014101460d0420042d00d9010d09200441086a200b10fd0302400240200428020c2201450d00200428020821022001410274210a20042802b801210603402004200228020022013602b0020240200620014b0d00200441ec016a4101360200200442023702dc01200441d8a0c5003602d801200441013602c4022004200441c0026a3602e8012004200441b0026a3602c002200441e8026a200441d8016a10e6030c0c0b200420042802b00120014102746a28020022013602d00220042802ac0120014d0d02200241046a2102200a417c6a220a0d000b0b200b411c6a220b2005460d020c010b0b200441013602ec01200442023702dc01200441e8a0c5003602d801200441013602c4022004200441c0026a3602e8012004200441d0026a3602c002200441e8026a200441d8016a10e6030c070b0240200428028401450d0020042802800110290b0240200428029001450d00200428028c0110290b0240200428029c01450d0020042802980110290b024020042802ac012202450d0020042802a40121012002410474210203400240200141046a280200450d00200128020010290b200141106a2101200241706a22020d000b0b024020042802a801450d0020042802a40110290b024020042802b401450d0020042802b00110290b201f450d0d201910290c0d0b200441e0016a290300211a20042802dc01210a0c090b200441ec016a4101360200200442023702dc01200441b8a0c5003602d801200441013602c4022004200441c0026a3602e8012004200441d0026a3602c002200441e8026a200441d8016a10e6030c040b200441e0016a290300211a20042802dc01210a0c070b200441ec016a4101360200200442013702dc01200441cc93c5003602d801200441013602d402200420013602c0022004200441d0026a3602e8012004200441c0026a3602d002200441e8026a200441d8016a10e6030c020b200441ec016a4101360200200442013702dc01200441d493c5003602d801200441013602d402200420013602c0022004200441d0026a3602e8012004200441c0026a3602d002200441e8026a200441d8016a10e6030c010b41204101102a000b20042802e802210a20042902ec02211a0c030b024041201027220a450d00200a41186a41002900f49345370000200a41106a41002900ec9345370000200a41086a41002900e49345370000200a41002900dc934537000042a08080808004211a0c030b41204101102a000b200441ec016a4102360200200441f4026a4101360200200442023702dc01200441fc91c5003602d801200441013602ec022004200441e8026a3602e8012004200441c0016a3602f0022004200441bc016a3602e802200441d0026a200441d8016a10e60320042802d002210a0b20042902d402211a0b0240200428028401450d0020042802800110290b0240200428029001450d00200428028c0110290b0240200428029c01450d0020042802980110290b024020042802ac012202450d0020042802a40121012002410474210203400240200141046a280200450d00200128020010290b200141106a2101200241706a22020d000b0b024020042802a801450d0020042802a40110290b024020042802b401450d0020042802b00110290b201f450d0120191029200a0d040c020b2001290204211a2001280200210a0240201f450d00201910290b0240201e450d00201410290b0240200e450d00201510290b02402013450d00201210290b02402010450d0020104104742102201c210103400240200141046a280200450d00200128020010290b200141106a2101200241706a22020d000b0b0240201d450d00201c10290b200d450d00201710290b200a0d020b2000201b36020420004100360200200041186a2003360200200041146a200c360200200041106a20093602002000410c6a2008360200200041086a20073602000c040b102b000b0240201aa7450d00200a10290b200041f48cc50036020420004101360200200041086a41133602000240200c450d00200c412c6c210220082101034020011088032001412c6a2101200241546a22020d000b0b2009450d02200810290c020b200441003a00d002200441ec016a4101360200200442013702dc0120044180c0c5003602d8012004411f3602b4022004200441b0026a3602e8012004200441d0026a3602b00220044180016a200441d8016a10e603200428028001210720042802840121060240200c450d00200c412c6c210220082101034020011088032001412c6a2101200241546a22020d000b0b4105210a2009450d00200810290b02402006450d00200a41ff01714105470d00200710290b200041de8cc50036020420004101360200200041086a41163602000b20044180036a24000b160020002001280208360204200020012802003602000bd41301177f23004190026b2202240002400240024002400240024020002802002203418883c000460d00200028020421040c010b41002104200241b8016a410041d80010cd041a2002411f6a220542003700002002420037011a41ec0010272203450d0120034100360200200320022902183702042003410b6a2005290000370000200341136a200241b7016a41d90010ce041a20004100360204200020033602000b200141ff01712106024003402003410c6a2107200341086a210820032f010621094100210502400240034020092005460d01200820056a210a200741086a2107200541016a210502404100417f4101200a2d0000220a20064b1b200a2006461b41016a0e03000301000b0b2005417f6a21090b2004450d022004417f6a2104200320094102746a41ec006a28020021030c010b0b200742013702000c030b2000200028020841016a360208024002400240024020032f01062205410b490d00200241276a41016a410041d80010cd041a200241003a001941ec0010272204450d03200441003602002004410036000f20044200370007200420022f01183b0005200441136a200241276a41d90010ce041a2003410e6a2d0000210b2003280248210c2003280244210d200441086a2003410f6a20032f010641796a220510ce042107200441146a200341cc006a200541037410ce042106200341063b0106200420053b010620094107490d0120072009417a6a220a6a2007200941796a22096a2207200541ffff037120096b10cf041a200720013a00002006200a4103746a200620094103746a2207200441066a22052f010020096b41037410cf041a2007410136020020052f010021070c020b200341086a2207200941016a22066a200720096a2207200520096b220a10cf041a200720013a0000200341146a220720064103746a200720094103746a2207200a41037410cf041a200741013602002003200541016a3b01060c050b200341086a2205200941016a22066a200520096a220a200341066a22052f0100220720096b220810cf041a200a20013a0000200341146a220a20064103746a200a20094103746a2209200841037410cf041a200941013602000b2005200741016a3b01002003280200220a450d02200341046a2105200241276a41016a210e200241a8016a210f200241a0016a211020024198016a211120024190016a211220024180016a41086a2113034020052f0100210602400240024002400240200a2f01062205410b490d00200e410041d80010cd041a200241003a0019200220022f01183b0108200241b7016a200241276a41d90010ce041a200f4200370300201042003703002011420037030020124200370300201342003703002002420037038001419c0110272207450d03200741003602002007410036000f20074200370007200720022f01083b0005200741136a200241b7016a41d90010ce041a20074194016a200f2903003702002007418c016a201029030037020020074184016a2011290300370200200741fc006a2012290300370200200741f4006a2013290300370200200720022903800137026c200a41c8006a2802002114200a41c4006a2802002115200a410e6a2d00002116200741086a200a410f6a200a2f0106220341796a220510ce042117200741146a200a41cc006a200541037410ce042118200741ec006a200a4188016a2003417a6a220841027410ce042101200a41063b0106200720053b010602402008450d00410021052001210303402003280200220920053b010420092007360200200341046a21032008200541016a2205470d000b0b20064107490d0120172006417a6a22036a2017200641796a22056a220920072f010620056b10cf041a2009200b3a0000201820034103746a201820054103746a220920072f010620056b41037410cf041a2009200d3602002009200c360204200720072f010641016a22093b01062006410274220b20016a416c6a200120034102746a2208200941ffff0371220620036b41027410cf041a2008200436020020062003490d022007200b6a41d4006a2103034020032802002209200541016a22053b010420092007360200200341046a210320052006490d000c030b0b200a41086a2207200641016a22036a200720066a2207200520066b220910cf041a2007200b3a0000200a41146a220720034103746a200720064103746a2207200941037410cf041a2007200d3602002007200c360204200a200541016a22053b01062006410274200a41ec006a22076a41086a200720034102746a2207200541ffff0371220920036b41027410cf041a20072004360200200620094f0d08200a2003417f6a22054102746a41f0006a2103034020032802002207200541016a22053b01042007200a360200200341046a210320052009490d000c090b0b200a41086a2203200641016a22056a200320066a2203200a2f0106220920066b220810cf041a2003200b3a0000200a41146a220320054103746a200320064103746a2203200841037410cf041a2003200d3602002003200c360204200a200941016a22033b010620064102742201200a41ec006a22096a41086a200920054102746a2208200341ffff0371220920056b41027410cf041a20082004360200200620094f0d00200a20016a41f0006a2105034020052802002203200641016a22063b01042003200a360200200541046a210520092006470d000b0b200a28020022030d01200721042014210c2015210d2016210b0c050b419c014104102a000b200a41046a21052003210a2016210b2015210d2014210c200721040c000b0b41ec004104102a000b41ec004104102a000b200241b7016a41016a410041d80010cd041a2002411f6a220542003700002002420037011a200220022902183703082002200529000037000f200241276a200241b7016a41d90010ce041a200241a8016a22034200370300200241a0016a2207420037030020024180016a41186a2209420037030020024190016a2206420037030020024180016a41086a220a42003703002002420037038001419c0110272205450d0120054100360200200520022903083702042005410b6a200229000f370000200541136a200241276a41d90010ce041a20054194016a20032903003702002005418c016a200729030037020020054184016a2009290300370200200541fc006a2006290300370200200541f4006a200a290300370200200520022903800137026c20052000280200220336026c200020053602002000200028020441016a360204200341003b010420032005360200200520052f010622034103746a220741186a200c360200200741146a200d360200200520036a41086a200b3a0000200541ec006a200341016a22034102746a2004360200200520033b0106200420033b0104200420053602000b20024190026a24000f0b419c014104102a000bd11e01387f23004190016b2202240020024184016a4200370200200241fc006a4280808080c000370200200241ec006a4200370200200241e4006a4280808080c000370200200241d0006a4200370300200241c0006a4200370300200241386a4280808080c000370300200241286a4200370300200241206a4280808080c000370300200241106a4200370300200242043702742002420437025c20024204370348200242043703302002420437031820024280808080c000370308200242043703002001410c6a280200210320024180016a210420012802082105024002400240200141106a28020022060d00410421014100210741002108410021094100210a4104210b4100210c4100210d4104210e4100210f41002110410421114100211241002113410421144100210641002115410421164100211741002118410421194100211a4100211b4104211c4100211d4100211e4104211f41002120410021210c010b410021224100211f41002123410021244100211c410021254100212641002127410021284100212941002107024003402001212a2007211520052006417f6a2206412c6c6a2201280024211720012800202119200128001821182001280014211420012800102116200128000c210c2001280008210b200128000421094101210741012112024002400240024002400240024020012d0000220a417e6a2208410d4d0d00410121130c010b4101211341012110410121114101210f4101210d4101210e20092101024002400240024002400240024002400240024020080e0e000102030405060f0708090e0e11000b02402029450d000240202b450d00202b41047421072029210103400240200141046a280200450d00200128020010290b200141106a2101200741706a22070d000b0b202c450d00202910290b4101211341002112200c212b200b212c200921290c090b02402028450d000240202d450d00202d41286c21072028210103400240200141046a280200450d00200128020010290b0240200141106a280200450d002001410c6a28020010290b200141286a2101200741586a22070d000b0b202e450d00202810290b4100211341012112200c212d200b212e200921280c080b0240202f450d002027450d00202710290b20152107202a210120092127200b212f200c21300c0c0b02402031450d002026450d00202610290b20152107202a210120092126200b2131200c21320c0b0b02402033450d002025450d00202510290b20152107202a210120092125200b2133200c21340c0a0b0240201c450d000240201a450d00201c201a4104746a210d201c21080340024020082802082207450d0020082802002101200741047421070340024020012d00004109470d00200141086a28020041ffffffff0371450d00200141046a28020010290b200141106a2101200741706a22070d000b0b200841106a21010240200841046a280200450d00200828020010290b200121082001200d470d000b0b2035450d00201c10290b4100211041012112200c211a200b21352009211c410121130c050b02402024450d000240201e450d00201e41146c21072024210103400240200141046a280200450d00200128020010290b200141146a21012007416c6a22070d000b0b2036450d00202410290b4100211141012112200c211e200b21362009212441012113410121100c050b02402023450d000240201d450d002023201d411c6c6a210d20232108034002402008410c6a2802002207450d0020082802042101200741047421070340024020012d00004109470d00200141086a28020041ffffffff0371450d00200141046a28020010290b200141106a2101200741706a22070d000b0b0240200841086a280200450d00200828020410290b2008411c6a21010240200841146a280200450d00200828021010290b200121082001200d470d000b0b2037450d00202310290b4100210f41012112200c211d200b2137200921234101211341012110410121110c050b0240201f450d000240201b450d00201f201b41186c6a210d201f210803400240200841046a280200450d00200828020010290b0240200841146a2802002207450d00200828020c2101200741047421070340024020012d00004109470d00200141086a28020041ffffffff0371450d00200141046a28020010290b200141106a2101200741706a22070d000b0b200841186a21010240200841106a280200450d00200828020c10290b200121082001200d470d000b0b2020450d00201f10290b4100210d41012112200c211b200b21202009211f4101211341012110410121114101210f4101210e0c050b02402022450d0002402038450d0020222038411c6c6a210d20222108034002402008410c6a2802002207450d0020082802042101200741047421070340024020012d00004109470d00200141086a28020041ffffffff0371450d00200141046a28020010290b200141106a2101200741706a22070d000b0b0240200841086a280200450d00200828020410290b2008411c6a21010240200841146a280200450d00200828021010290b200121082001200d470d000b0b2039450d00202210290b4100210e41012112200c2138200b2139200921224101211341012110410121114101210f4101210d0c040b410121100b410121110b4101210f0b4101210d4101210e0b02400240024002400240200a410d4b0d0020152107202a210102400240024002400240024002400240024002400240200a0e0e080900010202020304100506070a080b2012450d0e0240200c450d00200c41047421072009210103400240200141046a280200450d00200128020010290b200141106a2101200741706a22070d000b0b200b450d0e0c0d0b2013450d0d200c450d00200c41286c21072009210103400240200141046a280200450d00200128020010290b0240200141106a280200450d002001410c6a28020010290b200141286a2101200741586a22070d000b0b200b0d0b0c0c0b2010450d0b0240200c450d002009200c4104746a210a200921080340024020082802082207450d0020082802002101200741047421070340024020012d00004109470d00200141086a28020041ffffffff0371450d00200141046a28020010290b200141106a2101200741706a22070d000b0b200841106a21010240200841046a280200450d00200828020010290b200121082001200a470d000b0b200b0d0a0c0b0b2011450d0a0240200c450d00200c41146c21072009210103400240200141046a280200450d00200128020010290b200141146a21012007416c6a22070d000b0b200b0d090c0a0b200f450d090240200c450d002009200c411c6c6a210a20092108034002402008410c6a2802002207450d0020082802042101200741047421070340024020012d00004109470d00200141086a28020041ffffffff0371450d00200141046a28020010290b200141106a2101200741706a22070d000b0b0240200841086a280200450d00200828020410290b2008411c6a21010240200841146a280200450d00200828021010290b200121082001200a470d000b0b200b0d080c090b200d450d080240200c450d002009200c41186c6a210a2009210803400240200841046a280200450d00200828020010290b0240200841146a2802002207450d00200828020c2101200741047421070340024020012d00004109470d00200141086a28020041ffffffff0371450d00200141046a28020010290b200141106a2101200741706a22070d000b0b200841186a21010240200841106a280200450d00200828020c10290b200121082001200a470d000b0b200b0d070c080b200e450d07200c450d002009200c411c6c6a210a20092108034002402008410c6a2802002207450d0020082802042101200741047421070340024020012d00004109470d00200141086a28020041ffffffff0371450d00200141046a28020010290b200141106a2101200741706a22070d000b0b0240200841086a280200450d00200828020410290b2008411c6a21010240200841146a280200450d00200828021010290b200121082001200a470d000b0b200b0d050c060b0240200b450d00200910290b2014450d05201610290c050b0240200941ff0171220141024b0d0002400240024020010e03000102000b200c450d070c050b02402014450d002014410c6c2107200c21010340024020012802002208450d00200141046a280200450d00200810290b2001410c6a2101200741746a22070d000b0b2016450d060c030b02402014450d00200c20144104746a210b200c210a0340200a220941106a210a024020092802042201450d0002402009410c6a2802002207450d002007410c6c21070340024020012802002208450d00200141046a280200450d00200810290b2001410c6a2101200741746a22070d000b0b200941086a280200450d00200928020410290b200a200b470d000b0b20160d020c050b200c0d020c040b0240200b450d00200910290b02402014450d002018450d00201410290b2017450d03201910290c030b200c10290c020b200b10290c010b200910290b20152107202a21010b20060d000b410021062001212a200721150b201b4100201f1b210720204100201f1b2108201d410020231b21212037410020231b2120201e410020241b21092036410020241b210a201a4100201c1b211e20354100201c1b211d2034410020251b210c2033410020251b210d2032410020261b211b2031410020261b211a2030410020271b210f202f410020271b2110202d410020281b2118202e410020281b2117202b410020291b2112202c410020291b2113201f4104201f1b21012023410420231b211f2024410420241b210b201c4104201c1b211c2025410420251b210e2026410420261b21192027410420271b21112028410420281b21162029410420291b211420220d010b4104212241002139410021380b200410a4040240200228028401450d0020022802800110290b200241d8006a202a3602002002200636028801200220033602840120022005360280012002203836027c2002203936027820022022360274200220073602702002200836026c2002200136026820022021360264200220203602602002201f36025c20022015360254200220093602502002200a36024c2002200b3602482002201e3602442002201d3602402002201c36023c2002200c3602382002200d3602342002200e3602302002201b36022c2002201a360228200220193602242002200f3602202002201036021c2002201136021820022018360214200220173602102002201636020c20022012360208200220133602042002201436020020002002418c0110ce041a20024190016a24000bc30a01107f230041106b220224000240024002400240024020012802004101470d00200141106a2d000021032001410c6a2802002104200141086a280200210520012f0112210620012d0011210720012802042108200241086a200010800320022802082201200228020c22094104746a210a4100210b20094104490d01200341ff0171210c024002400340024020012d000c200c470d0020012802082004470d002001280200210d200421092008210e024003402009450d012009417f6a2109200e2d0000210f200d2d00002110200e41016a210e200d41016a210d2010200f460d000c020b0b20012d000d2209410446220f200741ff0171220d410446220e470d002009200d460d06200e0d06200f0d060b024002402001411c6a2d0000200c470d00200141186a2802002004470d002001280210210d200421092008210e024003402009450d012009417f6a2109200e2d0000210f200d2d00002110200e41016a210e200d41016a210d2010200f460d000c020b0b20012d001d2209410446220f200741ff0171220d410446220e470d002009200d460d01200e0d01200f0d010b02402001412c6a2d0000200c470d00200141286a2802002004470d002001280220210d200421092008210e024003402009450d012009417f6a2109200e2d0000210f200d2d00002110200e41016a210e200d41016a210d2010200f460d000c020b0b20012d002d2209410446220f200741ff0171220d410446220e470d002009200d460d03200e0d03200f0d030b02402001413c6a2d0000200c470d00200141386a2802002004470d002001280230210d200421092008210e024003402009450d012009417f6a2109200e2d0000210f200d2d00002110200e41016a210e200d41016a210d2010200f460d000c020b0b20012d003d2209410446220f200741ff0171220d410446220e470d002009200d460d04200e0d04200f0d040b200b41046a210b200a200141c0006a22016b41304d0d050c010b0b200b410172210b0c040b200b410272210b0c030b200b410372210b0c020b2001280204210b0c030b2001200a460d0102400240200741ff017122114104460d00200341ff0171210c0c010b200341ff0171210c0340024020012d000c200c470d0020012802082004470d002001280200210d200421092008210e024003402009450d012009417f6a2109200e2d0000210f200d2d00002110200e41016a210e200d41016a210d2010200f460d000c020b0b20012d000d4104460d030b200b41016a210b200141106a2201200a470d000c030b0b0340024020012d000c200c470d0020012802082004470d002001280200210e200421092008210d024003402009450d012009417f6a2109200d2d0000210f200e2d00002110200d41016a210d200e41016a210e2010200f460d000c020b0b20012d000d22092011470d0020094104470d020b200b41016a210b200141106a2201200a460d020c000b0b2005450d01200810290c010b02400240200041046a28020020002802082201460d00200028020021090c010b02400240200141016a22092001490d002001410174220d20092009200d491b220d41ffffffff0071200d470d00200d410474220e4100480d000240024020010d00200e102721090c010b20002802002001410474200e102821090b2009450d0120002009360200200041046a200d360200200028020821010c020b102b000b200e4104102a000b200920014104746a220120063b010e200120073a000d200120033a000c2001200436020820012005360204200120083602002000200028020841016a360208200220001080032002280204417f6a210b0b200241106a2400200b0bcc21032d7f017e017f230041306b2202240020012802042103200128020021044101210502400240024002400240024002400240024002400240024002400240024002400240200128020822060d004104210741002108410121090c010b412c10272207450d01200741023a0000200720022f002d3b00012007200636000c200720033600082007200436000420072002290208370210200741036a2002412d6a41026a2d00003a0000200741186a200241106a290200370200200741206a200241186a290200370200200741286a200241086a41186a28020036020041002109410121080b200141106a280200210a200128020c210b02400240200141146a280200220c0d002008210d0c010b2008410174220d200841016a220e200e200d491b220d412c6c210e0240024020080d00200e102721070c010b20072008412c6c200e102821070b2007450d0220072008412c6c6a220e41033a0000200e20022f002d3b0001200e200c36000c200e200a360008200e200b360004200e2002290208370210200e41036a2002412f6a2d00003a0000200e41186a200241106a290200370200200e41206a200241186a290200370200200e41286a200241086a41186a280200360200200841016a2108410021050b2001411c6a280200210f200128021821104100211102400240200141206a28020022120d00410021130c010b0240200d2008470d0041000d0e41000d0e200d410174220e200d41016a22142014200e491b220ead422c7ea722144100480d0e02400240200d0d002014102721070c010b2007200d412c6c2014102821070b2007450d04200e210d0b20072008412c6c6a220e41043a0000200e201236000c200e200f360008200e2010360004200e20022f002d3b0001200e41036a2002412f6a2d00003a0000200e2002290208370210200e41186a200241106a290200370200200e41206a200241186a290200370200200e41286a200241086a41186a28020036020041012113200841016a21080b200141286a28020021122001280224211502402001412c6a2802002214450d000240200d2008470d0041000d0e41000d0e200d410174220e200d41016a22112011200e491b220ead422c7ea722114100480d0e02400240200d0d002011102721070c010b2007200d412c6c2011102821070b2007450d05200e210d0b20072008412c6c6a220e41053a0000200e201436000c200e2012360008200e2015360004200e20022f002d3b0001200e41036a2002412f6a2d00003a0000200e2002290208370210200e41186a200241106a290200370200200e41206a200241186a290200370200200e41286a200241086a41186a28020036020041012111200841016a21080b200141346a28020021142001280230211602400240200141386a28020022170d00410021180c010b0240200d2008470d0041000d0e41000d0e200d410174220e200d41016a22192019200e491b220ead422c7ea722194100480d0e02400240200d0d002019102721070c010b2007200d412c6c2019102821070b2007450d06200e210d0b20072008412c6c6a220e41063a0000200e201736000c200e2014360008200e2016360004200e20022f002d3b0001200e41036a2002412f6a2d00003a0000200e2002290208370210200e41186a200241106a290200370200200e41206a200241186a290200370200200e41286a200241086a41186a28020036020041012118200841016a21080b200141c0006a280200211a200128023c211b4101211702400240200141c4006a280200221c0d004101211d0c010b0240200d2008470d0041000d0e41000d0e200d410174220e200d41016a22192019200e491b220ead422c7ea722194100480d0e02400240200d0d002019102721070c010b2007200d412c6c2019102821070b2007450d07200e210d0b20072008412c6c6a220e41073a0000200e201c36000c200e201a360008200e201b360004200e20022f002d3b0001200e41036a2002412f6a2d00003a0000200e2002290208370210200e41186a200241106a290200370200200e41206a200241186a290200370200200e41286a200241086a41186a280200360200200841016a21084100211d0b200141cc006a280200211e2001280248211f0240200141d0006a2802002220450d000240200d2008470d0041000d0e41000d0e200d410174220e200d41016a22172017200e491b220ead422c7ea722174100480d0e02400240200d0d002017102721070c010b2007200d412c6c2017102821070b2007450d08200e210d0b20072008412c6c6a220e41083a0000200e202036000c200e201e360008200e201f360004200e20022f002d3b0001200e41036a2002412f6a2d00003a0000200e2002290208370210200e41186a200241086a41086a290200370200200e41206a200241186a290200370200200e41286a200241086a41186a280200360200200841016a2108410021170b41012119024020012802544101470d00200141d8006a28020021210240200d2008470d0041000d0e41000d0e200d410174220e200d41016a22222022200e491b220ead422c7ea722224100480d0e02400240200d0d002022102721070c010b2007200d412c6c2022102821070b2007450d09200e210d0b20072008412c6c6a220e41093a0000200e2021360204200e20022f002d3b0001200e41036a2002412f6a2d00003a0000200e2002290208370208200e41106a200241106a290200370200200e41186a200241086a41106a290200370200200e41206a200241086a41186a290200370200200e41286a200241086a41206a280200360200200841016a21080b200141e0006a2802002123200128025c21220240200141e4006a2802002224450d000240200d2008470d0041000d0e41000d0e200d410174220e200d41016a22192019200e491b220ead422c7ea722194100480d0e02400240200d0d002019102721070c010b2007200d412c6c2019102821070b2007450d0a200e210d0b20072008412c6c6a220e410a3a0000200e202436000c200e2023360008200e2022360004200e20022f002d3b0001200e41036a2002412f6a2d00003a0000200e2002290208370210200e41186a200241106a290200370200200e41206a200241186a290200370200200e41286a200241086a41186a280200360200200841016a2108410021190b200141ec006a2802002125200128026821264101212102400240200141f0006a28020022270d00410121280c010b0240200d2008470d0041000d0e41000d0e200d410174220e200d41016a22292029200e491b220ead422c7ea722294100480d0e02400240200d0d002029102721070c010b2007200d412c6c2029102821070b2007450d0b200e210d0b20072008412c6c6a220e410b3a0000200e202736000c200e2025360008200e2026360004200e20022f002d3b0001200e41036a2002412f6a2d00003a0000200e2002290208370210200e41186a200241106a290200370200200e41206a200241186a290200370200200e41286a200241086a41186a280200360200200841016a2108410021280b200141f8006a280200212a200128027421290240200141fc006a280200222b450d000240200d2008470d0041000d0e41000d0e200d410174220e200d41016a22212021200e491b220ead422c7ea722214100480d0e02400240200d0d002021102721070c010b2007200d412c6c2021102821070b2007450d0c200e210d0b20072008412c6c6a220e410c3a0000200e202b36000c200e202a360008200e2029360004200e20022f002d3b0001200e41036a2002412f6a2d00003a0000200e2002290208370210200e41186a200241106a290200370200200e41206a200241186a290200370200200e41286a200241086a41186a280200360200200841016a2108410021210b20014184016a280200212c200128028001210e02400240200d20086b20014188016a280200412c6c222d412c6d2201490d00200820016a21010c010b200820016a22012008490d0d200d410174222e20012001202e491b222ead422c7e222f422088a70d0d202fa722304100480d0d02400240200d0d002030102721070c010b2007200d412c6c2030102821070b2007450d0c202e210d0b20072008412c6c6a200e202d10ce041a0240202c450d00200e10290b41c00510272208450d0d2000200736020820004280c2cdeb16370200200241086a410c6a4210370200200041106a20013602002000410c6a200d3602002002200836021020024280c2cdeb16370308200241106a10a404200810292021450d0e0240202b450d002029202b411c6c6a210d20292107034002402007410c6a2802002208450d0020072802042101200841047421080340024020012d00004109470d00200141086a28020041ffffffff0371450d00200141046a28020010290b200141106a2101200841706a22080d000b0b0240200741086a280200450d00200728020410290b2007411c6a21010240200741146a280200450d00200728021010290b200121072001200d470d000b0b202a450d0e202910290c0e0b412c4104102a000b200e4104102a000b20144104102a000b20114104102a000b20194104102a000b20194104102a000b20174104102a000b20224104102a000b20194104102a000b20294104102a000b20214104102a000b20304104102a000b102b000b41c0054104102a000b02402028450d0002402027450d002026202741186c6a210d2026210703400240200741046a280200450d00200728020010290b0240200741146a2802002208450d00200728020c2101200841047421080340024020012d00004109470d00200141086a28020041ffffffff0371450d00200141046a28020010290b200141106a2101200841706a22080d000b0b200741186a21010240200741106a280200450d00200728020c10290b200121072001200d470d000b0b2025450d00202610290b02402019450d0002402024450d0020222024411c6c6a210d20222107034002402007410c6a2802002208450d0020072802042101200841047421080340024020012d00004109470d00200141086a28020041ffffffff0371450d00200141046a28020010290b200141106a2101200841706a22080d000b0b0240200741086a280200450d00200728020410290b2007411c6a21010240200741146a280200450d00200728021010290b200121072001200d470d000b0b2023450d00202210290b02402017450d0002402020450d00202041146c2108201f210103400240200141046a280200450d00200128020010290b200141146a21012008416c6a22080d000b0b201e450d00201f10290b0240201d450d000240201c450d00201b201c4104746a210d201b21070340024020072802082208450d0020072802002101200841047421080340024020012d00004109470d00200141086a28020041ffffffff0371450d00200141046a28020010290b200141106a2101200841706a22080d000b0b200741106a21010240200741046a280200450d00200728020010290b200121072001200d470d000b0b201a450d00201b10290b02402014410047201841017371450d00201610290b02402012410047201141017371450d00201510290b0240200f410047201341017371450d00201010290b02402005450d000240200c450d00200c41286c2108200b210103400240200141046a280200450d00200128020010290b0240200141106a280200450d002001410c6a28020010290b200141286a2101200841586a22080d000b0b200a450d00200b10290b02402009450d0002402006450d00200641047421082004210103400240200141046a280200450d00200128020010290b200141106a2101200841706a22080d000b0b2003450d00200410290b200241306a24000b860501017f411021010240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240200041ff01710eac010001020202020202020202020202020303030404050506060707080809090a0a0b0b0c0d0d0e0e0f0f1010111213131414151516161717181819191a1a1b1b1c1c1d1d1e1e1f1f2020212122222323242425252627272828292a2a2b2b2c2d2d2e2e2f2f303031313232333434353536363737383839393a3a3b3b3c3c3d3d3e3e3f3f40404141424243434444454546464747484a4a4a4a49494a4a4a4a4a4a4a4a4a4a4a4a4a4a4b4b4b4b000b41110f0b41120f0b410a0f0b41080f0b41080f0b41040f0b41040f0b41040f0b41040f0b41040f0b41040f0b41040f0b41050f0b41050f0b41050f0b41050f0b41050f0b41130f0b41140f0b41060f0b41070f0b410b0f0b410b0f0b410b0f0b410b0f0b410b0f0b410b0f0b410b0f0b410b0f0b410b0f0b410b0f0b410b0f0b410c0f0b410c0f0b410c0f0b410c0f0b410c0f0b410c0f0b41000f0b41000f0b41010f0b41020f0b41030f0b41030f0b41000f0b41000f0b41000f0b41000f0b41000f0b41000f0b41010f0b41020f0b41030f0b41030f0b41000f0b41000f0b41000f0b41000f0b410d0f0b410d0f0b410d0f0b410d0f0b410d0f0b410d0f0b410d0f0b410d0f0b410d0f0b410d0f0b410d0f0b410d0f0b410d0f0b410d0f0b410e0f0b410e0f0b410f21010b20010bfe0101057f02400240024002400240200041086a28020022032001490d002003200041046a280200460d01200341016a2104200028020021050c020b41d0b1c5001058000b200341016a22042003490d0220034101742205200420042005491b220641ffffffff00712006470d02200641047422074100480d020240024020030d002007102721050c010b200028020020034104742007102821050b2005450d0120002005360200200041046a20063602000b200520014104746a220541106a2005200320016b41047410cf041a200541086a200241086a29030037030020052002290300370300200041086a20043602000f0b20074108102a000b102b000b800502067f017e230041306b22022400200241106a200141246a290200370300200241086a2001411c6a29020037030020022001290214370300200241186a41106a200141106a280200360200200241186a41086a200141086a290200370300200220012902003703182000200241186a1083032103024002400240024002402000411c6a280200200041206a2802002204460d00200028021821050c010b200441016a22052004490d0320044101742206200520052006491b220641ffffffff03712006470d03200641027422074100480d030240024020040d002007102721050c010b200028021820044102742007102821050b2005450d01200020053602182000411c6a2006360200200028022021040b200520044102746a20033602002000200028022041016a360220200241186a41106a200241106a290300370300200241186a41086a200241086a2903003703002002200229030037031802400240200041ec006a280200200041f0006a2802002204460d00200028026821050c010b200441016a22052004490d0320044101742203200520052003491b2203ad42187e2208422088a70d032008a722064100480d030240024020040d002006102721050c010b2000280268200441186c2006102821050b2005450d0220002005360268200041ec006a2003360200200041f0006a28020021040b2005200441186c6a22042002290318370200200441106a200241186a41106a290300370200200441086a200241186a41086a290300370200200041f0006a22042004280200220441016a360200024020012d002c450d0020004101360254200041d8006a20043602000b200241306a24000f0b20074104102a000b20064104102a000b102b000bcf0d01067f0240024020002d00002201410d4b0d00024002400240024002400240024002400240024002400240024020010e0e0001020304050607080e090a0b0c000b200041086a280200450d0d200041046a28020010290f0b0240200041086a280200450d00200041046a28020010290b200041146a280200450d0c200041106a28020010290f0b02402000410c6a2802002202450d00200041046a28020021012002410474210203400240200141046a280200450d00200128020010290b200141106a2101200241706a22020d000b0b200041086a280200450d0b200028020410290f0b02402000410c6a2802002202450d00200041046a2802002101200241286c210203400240200141046a280200450d00200128020010290b0240200141106a280200450d002001410c6a28020010290b200141286a2101200241586a22020d000b0b200041086a280200450d0a200028020410290f0b200041086a280200450d09200041046a28020010290f0b200041086a280200450d08200041046a28020010290f0b200041086a280200450d07200041046a28020010290f0b02402000410c6a2802002201450d00200041046a280200220320014104746a21040340024020032802082202450d0020032802002101200241047421020340024020012d00004109470d00200141086a28020041ffffffff0371450d00200141046a28020010290b200141106a2101200241706a22020d000b0b200341106a21010240200341046a280200450d00200328020010290b2001210320012004470d000b0b200041086a280200450d06200028020410290f0b02402000410c6a2802002202450d00200041046a2802002101200241146c210203400240200141046a280200450d00200128020010290b200141146a21012002416c6a22020d000b0b200041086a280200450d05200028020410290f0b02402000410c6a2802002201450d00200041046a28020022032001411c6c6a2104034002402003410c6a2802002202450d0020032802042101200241047421020340024020012d00004109470d00200141086a28020041ffffffff0371450d00200141046a28020010290b200141106a2101200241706a22020d000b0b0240200341086a280200450d00200328020410290b2003411c6a21010240200341146a280200450d00200328021010290b2001210320012004470d000b0b200041086a280200450d04200028020410290f0b02402000410c6a2802002201450d00200041046a2802002203200141186c6a210403400240200341046a280200450d00200328020010290b0240200341146a2802002202450d00200328020c2101200241047421020340024020012d00004109470d00200141086a28020041ffffffff0371450d00200141046a28020010290b200141106a2101200241706a22020d000b0b200341186a21010240200341106a280200450d00200328020c10290b2001210320012004470d000b0b200041086a280200450d03200028020410290f0b02402000410c6a2802002201450d00200041046a28020022032001411c6c6a2104034002402003410c6a2802002202450d0020032802042101200241047421020340024020012d00004109470d00200141086a28020041ffffffff0371450d00200141046a28020010290b200141106a2101200241706a22020d000b0b0240200341086a280200450d00200328020410290b2003411c6a21010240200341146a280200450d00200328021010290b2001210320012004470d000b0b200041086a280200450d02200028020410290f0b0240200041046a2d0000220141024b0d0002400240024020010e03000102000b2000410c6a280200450d04200041086a28020010290f0b0240200041146a2802002202450d002000410c6a28020021012002410c6c21020340024020012802002203450d00200141046a280200450d00200310290b2001410c6a2101200241746a22020d000b0b200041106a280200450d03200028020c10290f0b0240200041146a2802002201450d002000410c6a280200220520014104746a210603402005220441106a2105024020042802042201450d0002402004410c6a2802002202450d002002410c6c21020340024020012802002203450d00200141046a280200450d00200310290b2001410c6a2101200241746a22020d000b0b200441086a280200450d00200428020410290b20052006470d000b0b200041106a280200450d02200028020c10290c020b2000410c6a280200450d01200041086a28020010290f0b0240200041086a280200450d00200041046a28020010290b0240200041146a2802002201450d00200041186a280200450d00200110290b200041246a280200450d00200041206a28020010290f0b0b907f05087f017e1d7f037e187f23002203210420034180096b41607122032400024002400240024002400240024002400240024002400240024002400240411010272205450d00200541063a0000412010272206450d01200641063a00104100210720064100360204200620032f00f0053b00012006412d3a0000200641036a200341f2056a2d00003a0000024020052d00004109470d00200528020841ffffffff0371450d00200528020410290b20051029200141106a2802002208412c6c21092001280208210a02400340024020092007470d00411010272205450d0520054180023b010c200542828080802037020420052006360200200520032f01d0033b010e02402001410c6a2802002008470d00200841016a22072008490d0f20084101742209200720072009491b2207ad422c7e220b422088a70d0f200ba722094100480d0f0240024020080d0020091027210a0c010b200a2008412c6c20091028210a0b200a450d072001200a3602082001410c6a20073602000b2001200841016a220c360210200a2008412c6c6a220741073a0000200720032f00e0043b0001200742818080801037000820072005360004200720032902f005370210200741036a200341e2046a2d00003a0000200741186a200341f8056a290200370200200741206a20034180066a290200370200200741286a200341f0056a41186a2802003602004100210d0c020b200a20076a21052007412c6a220e210720052d00004107470d000b200320032f01d0033b01f005200a200e6a220541586a210a024002402005415c6a220c280200200541606a22092802002207460d00200a280200210e0c010b200741016a220e2007490d0d20074101742208200e200e2008491b220841ffffffff00712008470d0d2008410474220d4100480d0d0240024020070d00200d1027210e0c010b200541586a2802002007410474200d1028210e0b200e450d06200c2008360200200541586a200e360200200928020021070b200e20074104746a22074180023b010c200742828080802037020420072006360200200720032f01f0053b010e2009200928020041016a360200200341c0006a200a1080032003280244417f6a210d2001280210210c2001280208210a0b200c412c6c2107200a41586a210502400340410021062007450d01200741546a2107200541286a21092005412c6a220e210520092d00004103470d000b200e41086a2802002207450d00200741286c2105200e28020041186a2107410021060340200620072d0000456a2106200741286a2107200541586a22050d000b0b200c412c6c2107200a41586a210502400340410021092007450d01200741546a2107200541286a210e2005412c6a22082105200e2d00004103470d000b200841086a2802002207450d00200741286c2105200828020041186a2107410021090340200920072d0000456a2109200741286a2107200541586a22050d000b0b200c412c6c2107200a41606a210502400340024020070d00410021070c020b200741546a2107200541206a210e2005412c6a220a2105200e2d00004104470d000b200a28020021070b200720096a220f41ffffffff0371200f470d0c200f4102742207417f4c0d0c0240024020070d00410421100c010b2007107c2210450d060b024002400240024002400240200f450d002010200f4102746a211141002112201021130340024020122006490d0020012802102214412c6c220921072001280208221541586a220e2105024003404100210a2007450d01200741546a2107200541286a21082005412c6a220c210520082d00004103470d000b200c41086a2802002207450d00200741286c2105200c28020041186a21074100210a0340200a20072d0000456a210a200741286a2107200541586a22050d000b0b2012200a6b220a20124b0d0303402009450d05200941546a2109200e41286a2107200e412c6a2205210e20072d0000410b470d000b200541086a280200200a4d0d052005280200200a41186c6a2802082105200341f0056a200a200110960420032802f405210720032802f0054101460d072013200720056a3602000b201241016a2112201341046a22132011470d000b0b20012802102114200128020821150c0f0b412c10272207450d0a200741286a4100280092ac45360000200741206a410029008aac45370000200741186a4100290082ac45370000200741106a41002900faab45370000200741086a41002900f2ab45370000200741002900eaab4537000042ac808080c005210b0c020b412c10272207450d0a200741286a41002800beac45360000200741206a41002900b6ac45370000200741186a41002900aeac45370000200741106a41002900a6ac45370000200741086a410029009eac4537000020074100290096ac4537000042ac808080c005210b0c010b411e10272207450d0a200741166a41002900d8ac45370000200741106a41002900d2ac45370000200741086a41002900caac45370000200741002900c2ac45370000429e808080e003210b0b201010290c0a0b20032903f805210b2010102920070d09410021100c0a0b41104108102a000b41204108102a000b41104104102a000b20094104102a000b200d4104102a000b20074104102a000b412c4101102a000b412c4101102a000b411e4101102a000b410021100c030b02402014450d0020152014412c6c6a2116200341e0046a41146a2117200341e0076a2118200341f0056a41017221190340024020152d0000410b470d00201528020c2207450d002015280204220a200741186c6a211a03400240200a41146a220c2802002207450d00200a410c6a21124100210e0240024002400240024002400340200e20074f0d014101210702402012280200200e41047422136a22052d0000410b470d002003200541046a22053602c0022010450d04200f200528020022054d0d03201020054102746a2802002209450d00201920032f00e0043b0000201941026a200341e0046a41026a2d00003a0000200341123a00f0052003200d3602d407200341133a00d007200341d7003a00c007200320093602b4072003412d3a00b0072003200d3602a407200341123a00a00720032005360294072003410b3a009007200341063a008007200341003a00f00620034184083b01e006200341373a00d006200320023602c4062003412d3a00c0062003200d3602b406200341123a00b0062003200d3602a406200341133a00a006200341d6003a00900620032009360284062003412d3a0080062003200d3602f405200c2802002211200e4d0d05200c200e360200200a28020c2107200320183602f804200320123602f0042003200720136a220841106a22063602e8042003200e41016a22143602e0042003201120146b221b3602e404200320072014410474221c6a221d3602ec042003200341f0056a3602f40420062107024020082d0000220941ac01460d004100210702400340200820076a21050240200941ff01714109470d00200541086a28020041ffffffff0371450d00200541046a28020010290b2007450d012003200541206a3602e804200741106a2107200541106a2d0000220941ac01470d000b200820076a41106a21070c010b200541106a21070b02402007201d460d00034020032007220541106a22073602e8040240024020052d000022094109460d00200941ac01470d010c030b200541086a28020041ffffffff0371450d00200541046a28020010290b20062007470d000b0b0240024002400240201b450d0002402014200a2802142207470d00200341f0056a2107201821080c030b2013200741047422076b2109200a28020c20076a2105200341f0056a21072018210603400240024020072006470d00410021070c010b2003200741106a3602f4040b200341d0036a2007109c0420032d00d00341ac01460d04200520032903d003370300200541086a200341d0036a41086a290300370300200a200a28021441016a3602142009450d02200541106a2105200941706a210920032802f804210620032802f40421070c000b0b20122017109d040c020b20032802f804210820032802f40421070b0240200820076b2205450d000240024020032802f004220641046a221d280200221320116b20054104762209490d00200628020021050c010b201120096a22052011490d1020134101742211200520052011491b221141ffffffff00712011470d102011410474221e4100480d100240024020130d00201e102721050c010b20062802002013410474201e102821050b2005450d0920062005360200201d20113602000b2005201420096a22134104746a2005201c6a201b41047410cf041a200320133602e004201320062802082205460d00200e20096a410474200541047422056b2109200628020020056a210503400240024020072008470d00410021070c010b2003200741106a3602f4040b200341d0036a2007109c0420032d00d00341ac01460d02200520032903d003370300200541086a200341d0036a41086a2903003703002006200628020841016a3602082009450d01200541106a2105200941706a210920032802f804210820032802f40421070c000b0b200341003602d803200342083703d003200341d0036a2017109d0420032802d003221b20032802d803220541047422086a210620032802d403211c201b210702402005450d000240024020032802f004221341046a221d280200220720032802e404221420032802e00422056a22116b20084104752209490d00201328020021070c010b201120096a221e2011490d1020074101742211201e201e2011491b221141ffffffff00712011470d102011410474221e4100480d100240024020070d00201e102721070c010b20132802002007410474201e102821070b2007450d0a20132007360200201d20113602000b2007200520096a220941047422116a200720054104746a201441047410cf041a200320093602e004201b2107200920132802082205460d002013280200220720116a211d200720054104746a2109201b21050340024020080d00200621070c020b200341d0036a41026a2207200541036a2d00003a0000200320052f00013b01d003024020052d0000221441ac01470d00200541106a21070c020b200541046a290200210b2005410c6a2802002111200920143a00002009410c6a2011360200200941046a200b37020020032f01d0032114200941036a20072d00003a0000200941016a20143b00002013201328020841016a360208200841706a2108200541106a22072105200941106a2209201d470d000b0b024020072006460d0003400240024020072d000022054109460d00200541ac01470d010c030b200741086a28020041ffffffff0371450d00200741046a28020010290b200741106a22072006470d000b0b201c450d00201b10290b024020032802e804220720032802ec042206460d00034020032007220541106a22073602e8040240024020052d000022094109460d00200941ac01470d010c030b200541086a28020041ffffffff0371450d00200541046a28020010290b20062007470d000b0b024020032802e4042207450d00024020032802e004220620032802f004220841086a22092802002205460d002008280200220820054104746a200820064104746a200741047410cf041a0b2009200720056a3602000b024020032d00f0054109470d0020032802f80541ffffffff0371450d0020032802f40510290b024020032d0080064109470d0020032802880641ffffffff0371450d0020032802840610290b024020032d0090064109470d0020032802980641ffffffff0371450d0020032802940610290b024020032d00a0064109470d0020032802a80641ffffffff0371450d0020032802a40610290b024020032d00b0064109470d0020032802b80641ffffffff0371450d0020032802b40610290b024020032d00c0064109470d0020032802c80641ffffffff0371450d0020032802c40610290b024020032d00d0064109470d0020032802d80641ffffffff0371450d0020032802d40610290b024020032d00e0064109470d0020032802e80641ffffffff0371450d0020032802e40610290b024020032d00f0064109470d0020032802f80641ffffffff0371450d0020032802f40610290b024020032d0080074109470d0020032802880741ffffffff0371450d0020032802840710290b024020032d0090074109470d0020032802980741ffffffff0371450d0020032802940710290b024020032d00a0074109470d0020032802a80741ffffffff0371450d0020032802a40710290b024020032d00b0074109470d0020032802b80741ffffffff0371450d0020032802b40710290b024020032d00c0074109470d0020032802c80741ffffffff0371450d0020032802c40710290b024020032d00d0074109470d0020032802d80741ffffffff0371450d0020032802d40710290b410f21070b2007200e6a220e200c2802002207490d000c070b0b41e0acc500200e20071037000b2003410136028406200342013702f405200341f0acc5003602f005200341243602d4032003200341d0036a360280062003200341c0026a3602d003200341e0046a200341f0056a10e60320032802e0042207450d0420032902e404210b0c0b0b419eabc50041cc00104e000b419cb1c5001058000b201e4108102a000b201e4108102a000b200a41186a220a201a470d000b0b2015412c6a22152016470d000b0b200341c8006a41106a200141106a280200221f360200200341c8006a41086a200141086a290200220b37030020032001290200370348201f412c6c2107200ba7222041586a210502400340024020070d00410021090c020b200741546a2107200541286a21092005412c6a220e210520092d00004108470d000b200341386a200e10800320032802382109200328023c21070b2007410020091b2106201f412c6c2107202041586a2105200941b8d6c50020091b210e02400340024020070d00410021090c020b200741546a2107200541286a21092005412c6a220a210520092d0000410a470d000b200341306a200a10800320032802302109200328023421070b2007410020091b2108201f412c6c2107202041586a2105200941b8d6c50020091b211e02400340024020070d00410021210c020b200741546a2107200541286a21092005412c6a220a210520092d00004109470d000b200a2802002105410121210b200342003702742003418883c000360270201e2008411c6c6a2122200e200641146c6a2106200341e0046a410272222341266a2124202341186a2125202341086a21264100211741002127410021284100210c4100211c4104211a410421110240024002400240410041ff01710e03000102000b410021070c020b410221070c010b410121070b03400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024020070e03000104040b0240201741ff01710e03020300020b20284101470d05410021070c080b2021450d0e41022119410021214100211d200521070c1b0b0340024002400240024002402006200e22076b413c4b0d0020072006470d012007210e0c020b200728020c0d03200741146a210e200741106a28020021070c1e0b200741106a21090340200728020c450d02200941146a2109200741146a22072006470d000b2006210e0b20284101470d05410021070c0a0b200941046a210e200928020021070c1b0b200741206a280200450d19200741346a280200450d18200741d0006a210e200741c8006a280200450d170c000b0b03400240024002402006200e22076b413c4b0d004101211720072006470d012007210e0c1f0b200728020c0d01200741146a210e200741106a28020021070c170b200741106a210902400340200728020c450d01200941146a2109200741146a22072006470d000b2006210e0c1e0b200941046a210e200928020021070c160b200741206a280200450d14200741346a280200450d13200741d0006a210e200741c8006a280200450d120c000b0b0240024002400240201741ff01710e03010200010b20284101470d02410021070c090b0340024002400240024002402006200e22076b413c4b0d0020072006470d012007210e0c020b200728020c0d03200741146a210e200741106a28020021070c160b200741106a21090340200728020c450d02200941146a2109200741146a22072006470d000b2006210e0b20284101470d07410021070c080b200941046a210e200928020021070c130b200741206a280200450d11200741346a280200450d10200741d0006a210e200741c8006a280200450d0f0c000b0b03400240024002402006200e22076b413c4b0d0020072006460d10200741106a21090340200728020c450d02200941146a2109200741146a22072006470d000c110b0b200728020c0d01200741146a210e200741106a28020021070c0e0b200941046a210e200928020021070c0d0b200741206a280200450d0b200741346a280200450d0a200741d0006a210e200741c8006a280200450d090c000b0b410121070c060b410121070c040b410121070c020b410121070b0340024002400240024020070e020001010b20182027470d01410121070c030b201e2022460d0a200341206a201e10fd0320032802202218450d0a201e411c6a211e201820032802244102746a21270c010b2018450d092018280200210741012119410221172005211d201841046a2118410121280c160b410021070c000b0b0340024002400240024020070e020001010b20182027470d014101212820272118410121070c030b41022117201e2022460d17200341186a201e10fd03201e411c6a211e20032802182207450d182007200328021c4102746a2127200721180c010b201841046a2109024020180d004101212841022117200921180c180b201828020021074101212841022117410021192005211d200921180c150b410021070c000b0b0340024002400240024020070e020001010b20182027470d014101212820272118410121070c030b41022117201e2022460d16200341106a201e10fd03201e411c6a211e20032802102207450d17200720032802144102746a2127200721180c010b201841046a2109024020180d004101212841022117200921180c170b201828020021074101212841022117410021192005211d200921180c140b410021070c000b0b0340024002400240024020070e020001010b20182027470d01410121070c030b201e2022460d07200341286a201e10fd0320032802282218450d07201e411c6a211e2018200328022c4102746a21270c010b2018450d062018280200210741012119410221172005211d201841046a2118410121280c130b410021070c000b0b200741cc006a28020021070c020b2007413c6a210e200741386a28020021070c010b200741286a210e200741246a28020021070b410121192005211d410121170c0d0b200341e0006a41086a200341f0006a41086a28020036020020032003290370370360201f412c6c2107202041586a210502400340410021092007450d01200741546a2107200541286a210e2005412c6a220a2105200e2d00004103470d000b200a41086a2802002207450d00200741286c2105200a28020041186a2107410021090340200920072d0000456a2109200741286a2107200541586a22050d000b0b201f412c6c2107202041606a210502400340024020070d00410021070c020b200741546a2107200541206a210e2005412c6a220a2105200e2d00004104470d000b200a28020021070b200341f0056a41106a200341c8006a41106a280200360200200341f0056a41086a200341c8006a41086a290300370300200320032903483703f005200341b0016a200341f0056a1082030240200c450d002011200c4102746a2118200720096a211b200341e0076a2112200341e7046a211703402011220741046a21112007280200210a200341e0006a21072003280264210803402007280200220641086a210520062f0106220c4102742107417f210902400340024020070d00200c21090c020b2005280200210e2007417c6a2107200941016a2109200541046a210502404100417f4101200e200a4b1b200e200a461b41016a0e03020001020b0b200641346a20094105746a22132802182105201328021c21072003200d3602d407200341133a00d007200341d7003a00c007200320073602b4072003412d3a00b0072003200d3602a407200341123a00a00720032005360294072003410b3a009007200341063a008007200341003a00f00620034184083b01e006200341373a00d006200320023602c4062003412d3a00c0062003200d3602b406200341123a00b0062003200d3602a406200341133a00a006200341d6003a00900620032007360284062003412d3a0080062003200d3602f405200341123a00f0052013280208220a41106a220e41ffffffff0071200e470d15200e4104742207417f4c0d15201341086a21190240024002400240024020070d004108210c0c010b20071027220c450d012019280200210a0b0240200a0d00410021050c030b4100210941002107034002402007200e470d00200e41016a2205200e490d19200e4101742206200520052006491b220541ffffffff00712005470d19200541047422064100480d1902400240200e0d0020061027210c0c010b200c200e41047420061028210c0b200c450d032005210e0b200c20096a2205410f3a0000200541046a2007360200200541016a20032f01d0033b0000200541036a200341d0036a41026a2d00003a0000200941106a2109200741016a22052107200a2005460d030c000b0b20074108102a000b20064108102a000b02400240024002400240024002400240200e20056b410f4f0d002005410f6a22072005490d1c200e4101742209200720072009491b220741ffffffff00712007470d1c200741047422094100480d1c02400240200e0d0020091027210c0c010b200c200e41047420091028210c0b200c450d012007210e0b200c20054104746a2107200341f0056a2109034020052108024002400240024020092d00002205414f6a41fb004f0d000c010b02400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024020050e312c2c0001022c2c0304052c06072c2c08090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292c0b20092d00012106410221050c2b0b20092d00012106410321050c2a0b20092d00012106410421050c290b200941046a280200210a410721050c270b200941046a280200210a410821050c260b2009280208221d41ffffffff0371201d470d44201d4102742205417f4c0d440240024020050d004104210a0c010b20051027220a450d2a0b0240201d450d0020092802042105201d4102742114200a2106034020062005280200360200200641046a2106200541046a21052014417c6a22140d000b0b200935020c422086201dad84210b410921050c250b200941046a280200210a410b21050c240b200941046a280200210a20092d00012106410c21050c240b200941046a280200210a410f21050c220b200941046a280200210a411021050c210b200941046a280200210a411121050c200b200941046a280200210a411221050c1f0b200941046a280200210a411321050c1e0b200941046a280200210a2009350208210b411421050c1d0b200941046a280200210a2009350208210b411521050c1c0b200941046a280200210a2009350208210b411621050c1b0b200941046a280200210a2009350208210b411721050c1a0b200941046a280200210a2009350208210b411821050c190b200941046a280200210a2009350208210b411921050c180b200941046a280200210a2009350208210b411a21050c170b200941046a280200210a2009350208210b411b21050c160b200941046a280200210a2009350208210b411c21050c150b200941046a280200210a2009350208210b411d21050c140b200941046a280200210a2009350208210b411e21050c130b200941046a280200210a2009350208210b411f21050c120b200941046a280200210a2009350208210b412021050c110b200941046a280200210a2009350208210b412121050c100b200941046a280200210a2009350208210b412221050c0f0b200941046a280200210a2009350208210b412321050c0e0b200941046a280200210a2009350208210b412421050c0d0b200941046a280200210a2009350208210b412521050c0c0b200941046a280200210a2009350208210b412621050c0b0b200941046a280200210a2009350208210b412721050c0a0b200941046a280200210a2009350208210b412821050c090b200941046a280200210a2009350208210b412921050c080b200941046a280200210a2009350208210b412a21050c070b20092d00012106412b21050c070b20092d00012106412c21050c060b200941046a280200210a412d21050c040b2009290308210b412e21050c020b200941046a280200210a412f21050c020b2009290308210b413021050b0b0b200720063a0001200720053a0000200741086a200b370300200741046a200a360200200841016a2105200741106a2107200941106a22092012470d000b02400240200e2005460d00200e21090c010b200e41016a2207200e490d1c200e4101742205200720072005491b220941ffffffff00712009470d1c200941047422074100480d1c02400240200e0d0020071027210c0c010b200c200e41047420071028210c0b200c450d03200e21050b200c20054104746a220741063a0000200720032900e004370001200741086a2017290000370000200341e0046a200341b0016a418c0110ce041a411010272205450d03200541063a0000200341d0036a200341e0046a418c0110ce041a20192802002207417f4c0d1c0240024020070d004101210a41014101200710ce041a2007ad210b410021070c010b2013280200210e20071027220a450d05200a200e200710ce04210e20071027220a450d06200a200e200710ce041a200e10292007ad210b0b200341e0046a200341d0036a418c0110ce041a201331000d2129200341d0036a200341e0046a418c0110ce041a200341e0046a200341d0036a418c0110ce041a200341c0026a200341e0046a418c0110ce041a41101027220e450d06200841026a2106202a428080808080804083222a200b842029422886844280808080800c84210b200e41063a0000200e1029200341d0036a200341c0026a418c0110ce041a200341e0046a200341d0036a418c0110ce041a024020052d00004109470d00200528020841ffffffff0371450d00200528020410290b20051029200341c0026a200341e0046a418c0110ce041a200341e0046a200341c0026a418c0110ce041a200341003602fc03200320063602f803200320093602f4032003200c3602f003200341003602ec03200342043702e4032003200b3702dc03200320073602d8032003200a3602d403200341013602d003200341e0046a200341d0036a108703200341b0016a200341e0046a418c0110ce041a201341013602102013201b360214024020032d00f0054109470d0020032802f80541ffffffff0371450d0020032802f40510290b024020032d0080064109470d0020032802880641ffffffff0371450d0020032802840610290b024020032d0090064109470d0020032802980641ffffffff0371450d0020032802940610290b024020032d00a0064109470d0020032802a80641ffffffff0371450d0020032802a40610290b024020032d00b0064109470d0020032802b80641ffffffff0371450d0020032802b40610290b024020032d00c0064109470d0020032802c80641ffffffff0371450d0020032802c40610290b024020032d00d0064109470d0020032802d80641ffffffff0371450d0020032802d40610290b024020032d00e0064109470d0020032802e80641ffffffff0371450d0020032802e40610290b024020032d00f0064109470d0020032802f80641ffffffff0371450d0020032802f40610290b024020032d0080074109470d0020032802880741ffffffff0371450d0020032802840710290b024020032d0090074109470d0020032802980741ffffffff0371450d0020032802940710290b024020032d00a0074109470d0020032802a80741ffffffff0371450d0020032802a40710290b024020032d00b0074109470d0020032802b80741ffffffff0371450d0020032802b40710290b024020032d00c0074109470d0020032802c80741ffffffff0371450d0020032802c40710290b024020032d00d0074109470d0020032802d80741ffffffff0371450d0020032802d40710290b202a4280808080808c0184212a201b41016a211b20112018470d090c0a0b20094108102a000b20054104102a000b20074108102a000b41104108102a000b20074101102a000b20074101102a000b41104108102a000b02402008450d002008417f6a2108200620094102746a4194036a21070c010b0b0b41b0b2c500418001104e000b0240201c450d00201a10290b200341f0056a200341b0016a418c0110ce041a200341e0046a200341f0056a1084030240200341e0046a41106a2802002207450d0020032802e80422192007412c6c6a211d0340024020192d000041786a220741024b0d0002400240024020070e03000102000b201928020c2207450d0220192802042209200741146c6a211203400240200928020c0d002009280210210c2003280264210d200341e0006a210703402007280200220841286a210e200841086a210520082f010622134102742107417f210a02400340024020070d002013210a0c020b200528020021062007417c6a2107200a41016a210a200e41206a210e200541046a210502404100417f41012006200c4b1b2006200c461b41016a0e03020001020b0b0240200e417c6a280200450d002009200e2802003602100c030b41b0b3c5004135104e000b200d450d01200d417f6a210d2008200a4102746a4194036a21070c000b0b200941146a22092012470d000c030b0b201928020421082003280264210c200341e0006a210703402007280200220641286a2109200641086a210520062f0106220d4102742107417f210e02400340024020070d00200d210e0c020b2005280200210a2007417c6a2107200e41016a210e200941206a2109200541046a210502404100417f4101200a20084b1b200a2008461b41016a0e03020001020b0b02402009417c6a280200450d00201920092802003602040c040b41b0b3c5004135104e000b200c450d02200c417f6a210c2006200e4102746a4194036a21070c000b0b201928020c2207450d00201928020422112007411c6c6a211b0340024020112802182207450d002011280210220d20074102746a21140340200d221241046a210d201228020021082003280264210c200341e0006a210703402007280200220641286a2109200641086a210520062f010622134102742107417f210e024002400340024020070d002013210e0c020b2005280200210a2007417c6a2107200e41016a210e200941206a2109200541046a210502404100417f4101200a20084b1b200a2008461b41016a0e03020001020b0b02402009417c6a280200450d00201220092802003602000c020b41b0b3c5004135104e000b200c450d00200c417f6a210c2006200e4102746a4194036a21070c010b0b200d2014470d000b0b2011411c6a2211201b470d000b0b2019412c6a2219201d470d000b0b200341ec046a290200210b20032802e004210720032902e404212a200328026020032802642003280268109f04200041106a200b370200200041086a202a37020020002007360204200041003602002010450d13200f450d1320101029200424000f0b200741cc006a28020021070c020b2007413c6a210e200741386a28020021070c010b200741286a210e200741246a28020021070b41002117410121192005211d0c080b200741cc006a28020021070c020b2007413c6a210e200741386a28020021070c010b200741286a210e200741246a28020021070b41012117410021192005211d0c040b200741cc006a28020021070c020b2007413c6a210e200741386a28020021070c010b200741286a210e200741246a28020021070b410021192005211d410021170b2003200736027c0240024002400240024002400240024002402010450d000240200f20074b0d002003410136028406200342023702f405200341a0b2c5003602f005200341013602d4032003200341d0036a360280062003200341fc006a3602d003200341e0046a200341f0056a10e60320032902e404220b422088a7210920032802e0042113200ba721160c090b201020074102746a2802002205450d0402400240201c200c470d00200c41016a2209200c490d0e200c410174220a20092009200a491b221c41ffffffff0371201c470d0e201c41027422094100480d0e02400240200c0d0020091027211a0c010b201a200c41027420091028211a0b201a450d01201a21110b2011200c4102746a2007360200200341f0056a200328027c2208200341c8006a109b0420032802f805211620032802f4052113024020032802f00522014101470d0020032802fc0521090c0a0b20132802082207417f4c0d0e20132d000c210a02400240024020070d00410121090c010b20132802002112200710272209450d0120092012200710ce041a0b2003200a3a008c0120032007360288012003200736028401200320093602800120132d000d21072003200536029c012003200328027c360298012003410036029001200320073a008d0102400240024020032802702207418883c000460d002003280274211b0c010b20244200370100202341206a420037010020254200370100202341106a42003701002026420037010020234200370100200341f0056a410041e00210cd041a41940310272207450d014100211b20074100360200200720032903e0043702042007410c6a200341e0046a41086a290300370200200741146a200341e0046a41106a2903003702002007411c6a200341e0046a41186a290300370200200741246a200341e0046a41206a2903003702002007412c6a200341e0046a41286a290300370200200741346a200341f0056a41e00210ce041a20034100360274200320073602700b200c41016a210c0340200741146a210920072f010622154102742114417f210a4100210502400340024020142005470d002015210a0c020b200720056a2112200541046a2105200a41016a210a200941206a210902404100417f4101201241086a280200221220084b1b20122008461b41016a0e03020001020b0b2009290200210b2009200329038001370200200941186a200329039801370200200941106a2207290200212a2007200329039001370200200941086a200329038801370200202a42ffffffff0f83420285500d08200b42808080807083500d08200ba710290c080b0240201b450d00201b417f6a211b2007200a4102746a4194036a28020021070c010b0b2003200328027841016a360278200329039801210b200329039001212a2003290388012129200329038001212b20072f01062209410b490d0420244200370100202341206a222c420037010020254200370100202341106a222d42003701002026420037010020234200370100200341f0056a410041e00210cd041a024041940310272205450d0020054100360200200520032903e0043702042005410c6a200341e0046a41086a222e290300370200200541146a200341e0046a41106a222f2903003702002005411c6a200341e0046a41186a2230290300370200200541246a200341e0046a41206a22312903003702002005412c6a200341e0046a41286a2232290300370200200541346a200341f0056a41e00210ce042112200341f0056a41086a221b200741fc016a290200370300200341f0056a41106a221520074184026a290200370300200341f0056a41186a22332007418c026a290200370300200320072902f4013703f00520072802202134200541086a200741246a20072f010641796a220941027410ce042114201220074194026a200941057410ce042112200741063b0106200520093b010620302033290300370300202f2015290300370300202e201b290300370300200320032903f0053703e00402400240200a4107490d002014200a417a6a22354102746a2014200a41796a220a4102746a2214200941ffff0371200a6b41027410cf041a20142008360200201220354105746a2012200a4105746a2209200541066a22122f0100200a6b41057410cf041a200941186a200b3702002009202a370210200920293702082009202b37020020122f010021140c010b200741086a2209200a41016a22354102746a2009200a4102746a2209200741066a22122f01002214200a6b223641027410cf041a20092008360200200741346a220920354105746a2009200a4105746a2209203641057410cf041a200941186a200b3702002009202a370210200920293702082009202b3702000b2012201441016a3b0100200341d0036a41186a22372030290300220b370300200341d0036a41106a2238202f290300222a370300200341d0036a41086a2239202e2903002229370300200341b0016a41186a223a200b370300200341b0016a41106a223b202a370300200341b0016a41086a223c2029370300200320032903e004220b3703d0032003200b3703b0010240200728020022120d00200521090c070b20072f010421352005213d0340200341c0026a41186a223e203a290300370300200341c0026a41106a223f203b290300370300200341c0026a41086a2240203c290300370300200320032903b0013703c002203541ffff037121080240024002400240024020122f01062207410b490d0020244200370100202c420037010020254200370100202d420037010020264200370100202342003701002039202e2903003703002038202f29030037030020372030290300370300200341d0036a41206a22072031290300370300200341d0036a41286a22052032290300370300200320032903e0043703d003200341f0056a410041900310cd041a41c40310272209450d0320094100360200200920032903d0033702042009410c6a2039290300370200200941146a20382903003702002009411c6a2037290300370200200941246a20072903003702002009412c6a2005290300370200200941346a200341f0056a41900310ce042105201241206a280200214120332012418c026a290200370300201520124184026a290200370300201b201241fc016a2902003703002003201241f4016a2902003703f005200941086a201241246a20122f0106220a41796a220741027410ce042142200520124194026a200741057410ce04214320094194036a201241b0036a200a417a6a221441027410ce042136201241063b0106200920073b010602402014450d00410021072036210503402005280200220a20073b0104200a2009360200200541046a21052014200741016a2207470d000b0b20302033290300220b370300202f2015290300222a370300202e201b2903002229370300200320032903f005222b3703e0042033200b3703002015202a370300201b20293703002003202b3703f005203541ffff037122054107490d0120422008417a6a220a41027422146a2042200841796a22074102746a220520092f010620076b41027410cf041a200520343602002043200a4105746a204320074105746a220520092f010620076b41057410cf041a200541186a203e290300370200200541106a203f290300370200200541086a2040290300370200200520032903c002370200200920092f010641016a22053b01062008410274223520366a416c6a203620146a2214200541ffff03712208200a6b41027410cf041a2014203d3602002008200a490d02200920356a41fc026a210503402005280200220a200741016a22073b0104200a2009360200200541046a210520072008490d000c030b0b201241086a2205200841016a2209410274220a6a2005200841027422146a2205200720086b221b41027410cf041a20052034360200201241346a220520094105746a200520084105746a2205201b41057410cf041a200541186a203e290300370200200541106a203f290300370200200541086a2040290300370200200520032903c0023702002012200741016a22073b0106201420124194036a22056a41086a2005200a6a2205200741ffff0371220a20096b41027410cf041a2005203d3602002008200a4f0d0c20122009417f6a22074102746a4198036a2105034020052802002209200741016a22073b010420092012360200200541046a21052007200a490d000c0d0b0b201241086a2207200841016a2214410274220a6a2007200841027422356a220720122f0106223620086b224241027410cf041a20072034360200201241346a220720144105746a200720084105746a2207204241057410cf041a200741186a203e290300370200200741106a203f290300370200200741086a2040290300370200200720032903c0023702002012203641016a22073b0106203520124194036a22366a41086a2036200a6a2236200741ffff0371220a20146b41027410cf041a2036203d3602002005200a4f0d00201220356a4198036a2107034020072802002205200841016a22083b010420052012360200200741046a2107200a2008470d000b0b203a2033290300370300203b2015290300370300203c201b290300370300200320032903f0053703b001201228020022070d01204121340c090b41c4034104102a000b20122f0104213520072112204121342009213d0c000b0b4194034104102a000b4194034104102a000b20074101102a000b20094104102a000b419eabc50041cc00104e000b200741086a2205200a41016a22124102746a2005200a4102746a22052009200a6b221441027410cf041a20052008360200200741346a220520124105746a2005200a4105746a2205201441057410cf041a200541186a200b3702002005202a370210200520293702082005202b3702002007200941016a3b01060c010b20244200370100202c420037010020254200370100202d420037010020264200370100202342003701002039202e2903003703002038202f29030037030020372030290300370300200341d0036a41206a22052031290300370300200341d0036a41286a220a2032290300370300200320032903e0043703d003200341f0056a410041900310cd041a41c40310272207450d0220074100360200200720032903d0033702042007410c6a2039290300370200200741146a20382903003702002007411c6a2037290300370200200741246a20052903003702002007412c6a200a290300370200200741346a200341f0056a41900310ce04210820072003280270220536029403200320073602702003200328027441016a36027420052007360200200541003b0104200820072f0106220a4105746a220520032903b001370200200541186a203a290300370200200541106a203b290300370200200541086a203c2903003702002007200a4102746a41086a203436020020074194036a200a41016a22054102746a2009360200200720053b0106200920053b0104200920073602000b2001450d002016450d00201310290b201d2105201941ff01710e03010205010b41c4034104102a000b410021070c040b410221070c030b200328027020032802742003280278109f040240201c450d00201a10290b0240201f450d00201f412c6c210520202107034020071088032007412c6a2107200541546a22050d000b0b0240200341d4006a280200450d00202010290b2000201336020420004101360200200041086a2009ad4220862016ad843702002010450d06200f450d0620101029200424000f0b2022211e0b410121070c000b0b102b000b1039000b2000200736020420004101360200200041086a200b37020002402010450d00200f450d00201010290b20012802082105024020012802102203450d002003412c6c210720052103034020031088032003412c6a2103200741546a22070d000b0b2001410c6a280200450d00200510290b200424000ba6810204117f017e037f017e230041e0006b220324000240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024020012d00000e0f0100021211100f0e0d0c0b0a080706010b200141186a2802002104200141146a2802002105200141106a28020021062001410c6a2802002107200141086a2802002108200141046a28020021090240200241046a280200200241086a280200220a460d002002280200210b0c180b200a41016a220c200a490d14200a410174220d200c200c200d491b220c4100480d1402400240200a0d00200c1027210b0c010b2002280200200a200c1028210b0b200b450d042002200b360200200241046a200c360200200241086a280200210a0c170b2001410c6a280200210c200141086a2802002104200141046a280200210b20012d0001210502400240200241046a280200200241086a280200220a460d002002280200210d0c010b200a41016a220d200a490d14200a4101742206200d200d2006491b22064100480d1402400240200a0d0020061027210d0c010b2002280200200a20061028210d0b200d450d032002200d360200200241046a2006360200200241086a280200210a0b200241086a2206200a41016a360200200d200a6a20053a000002400240200241046a280200220d2006280200220a6b200c490d002002280200210d0c010b200a200c6a2205200a490d14200d410174220a20052005200a491b220a4100480d1402400240200d0d00200a1027210d0c010b2002280200200d200a1028210d0b200d450d022002200d360200200241046a200a360200200241086a280200210a0b200241086a200a200c6a360200200d200a6a200b200c10ce041a4100210c41012107024020040d004101210d0c220b200b10294101210d0c210b2001410c6a2802002106200141086a280200210e200141046a280200210f024002400240200241046a280200200241086a280200220a460d002002280200210c0c010b200a41016a220c200a490d14200a410174220d200c200c200d491b220d4100480d1402400240200a0d00200d1027210c0c010b2002280200200a200d1028210c0b200c450d012002200c360200200241046a200d360200200241086a280200210a0b200241086a200a41016a360200200c200a6a41013a0000200f20064104746a21104100210d4100210c41002105410121042006210a024003400240200c2005470d00200d200c41016a220b200b200d491b22054100480d1602400240200d0d002005102721040c010b2004200c2005102821040b2004450d020b2004200c6a200a41807f72200a41ff0071200a410776220b1b3a0000200d41026a210d200c41016a210c200b210a200b0d000b024020060d00200f21080c130b200f210a02400340200a41106a2108200a2d000d22114105460d14200a2d000c210d200a2802082109200a2802042112200a28020021130240024002400240024002402005200c470d00200c41016a220a200c490d1c200c410174220b200a200a200b491b22054100480d1c02400240200c0d002005102721040c010b2004200c2005102821040b2004450d010b2004200c6a200d3a0000200c41016a210a200c410174220c41046a2107200c41026a210d2009210c0340200721060240200a2005470d00200a41016a220b200a490d1d200d200b200b200d491b22054100480d1d02400240200a0d002005102721040c010b2004200a2005102821040b2004450d030b2004200a6a200c41807f72200c41ff0071200c410776220b1b3a0000200641026a2107200d41026a210d200a41016a210a200b210c200b0d000b0240024020090d00200a210c0c010b4100210d0340200a200d6a210c41fc00210b02400240024002402013200d6a2d00000e050200010305020b41fe00210b0c020b41fd00210b0c010b41ff00210b0b0240200c2005470d00200c41016a2205200c490d1e2006200520052006491b22054100480d1e02400240200c0d002005102721040c010b2004200c2005102821040b2004450d050b2004200a6a200d6a200b3a0000200641026a21062009200d41016a220d470d000b200a200d6a210c0b20120d030c040b20054101102a000b20054101102a000b20054101102a000b201310290b4100210a024020114104460d0002402005200c470d00200c41016a220a200c490d18200c410174220d200a200a200d491b22054100480d1802400240200c0d002005102721040c010b2004200c2005102821040b2004450d030b2004200c6a41013a0000200c41016a210c201141077141ff0073210a0b024002402005200c470d00200c41016a220d200c490d18200c410174220b200d200d200b491b22054100480d1802400240200c0d002005102721040c010b2004200c2005102821040b2004450d010b2004200c6a200a3a0000200c41016a210c2008210a20082010470d010c160b0b20054101102a000b20054101102a000b20054101102a000b200d4101102a000b200a4101102a000b20064101102a000b200c4101102a000b200141286a2802002104200141246a2802002111200141206a28020021092001411c6a2802002106200141186a2802002113200141146a28020021082001410c6a2902002114200141086a280200210d200141046a280200210b024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240200241046a280200200241086a280200220a460d002002280200210c0c010b200a41016a220c200a490d22200a4101742205200c200c2005491b22054100480d2202400240200a0d0020051027210c0c010b2002280200200a20051028210c0b200c450d012002200c360200200241046a2005360200200241086a280200210a0b200241086a200a41016a36020041002105200c200a6a41003a0000200341dc006a41003602002003420137025420032002360250200320143e02482003200d3602442003200b360240200341086a200341c0006a200341d0006a10ed03024020032d0008220a411a460d0020032f000920032d000b41107472210c200341086a41086a2903002114200328020c21044100210d0c1e0b2014422088a7210c0340024002402003280258200328025c220a460d002003280254210d0c010b200a41016a220d200a490d23200a410174220b200d200d200b491b220b4100480d2302400240200a0d00200b1027210d0c010b2003280254200a200b1028210d0b200d450d032003200b3602582003200d3602540b2003200a41016a36025c200d200a6a200c41807f72200c41ff0071200c410776220a1b3a0000200a210c200a0d000b4101211202402008450d00200320063602482003201336024420032008360240200341086a200341c0006a200341d0006a10ed03024020032d0008220a411a460d0020032f000920032d000b41107472210c200341106a2903002114200328020c21044100210d410121050c1f0b410021120b200920044104746a21062004210c0340024002402003280258200328025c220a460d002003280254210d0c010b200a41016a220d200a490d23200a410174220b200d200d200b491b220b4100480d2302400240200a0d00200b1027210d0c010b2003280254200a200b1028210d0b200d450d042003200b3602582003200d3602540b2003200a41016a36025c200d200a6a200c41807f72200c41ff0071200c410776220a1b3a0000200a210c200a0d000b024020040d002009210b0c1d0b200441047441706a21072009210d0340200d41106a210b200d410c6a2802002102200d41086a280200210a200d280204210c0240024002400240024002400240024002400240200d2802000e09000102030405060727000b024002402003280258200328025c220d460d00200328025421040c010b200d41016a2204200d490d2c200d4101742205200420042005491b22054100480d2c02400240200d0d002005102721040c010b2003280254200d2005102821040b2004450d0e20032005360258200320043602540b2003200d41016a36025c2004200d6a41003a00000340024002402003280258200328025c220d460d00200328025421040c010b200d41016a2204200d490d2d200d4101742205200420042005491b22054100480d2d02400240200d0d002005102721040c010b2003280254200d2005102821040b2004450d1020032005360258200320043602540b2003200d41016a36025c2004200d6a200c41807f72200c41ff0071200c410776220d1b3a0000200d210c200d0d000b0340024002402003280258200328025c220c460d002003280254210d0c010b200c41016a220d200c490d2d200c4101742204200d200d2004491b22044100480d2d02400240200c0d0020041027210d0c010b2003280254200c20041028210d0b200d450d11200320043602582003200d3602540b2003200c41016a36025c200d200c6a200a41807f72200a41ff0071200a410776220c1b3a0000200c210a200c0d000c080b0b024002402003280258200328025c220d460d00200328025421040c010b200d41016a2204200d490d2b200d4101742205200420042005491b22054100480d2b02400240200d0d002005102721040c010b2003280254200d2005102821040b2004450d1020032005360258200320043602540b2003200d41016a36025c2004200d6a41013a00000340024002402003280258200328025c220d460d00200328025421040c010b200d41016a2204200d490d2c200d4101742205200420042005491b22054100480d2c02400240200d0d002005102721040c010b2003280254200d2005102821040b2004450d1220032005360258200320043602540b2003200d41016a36025c2004200d6a200c41807f72200c41ff0071200c410776220d1b3a0000200d210c200d0d000b0340024002402003280258200328025c220c460d002003280254210d0c010b200c41016a220d200c490d2c200c4101742204200d200d2004491b22044100480d2c02400240200c0d0020041027210d0c010b2003280254200c20041028210d0b200d450d13200320043602582003200d3602540b2003200c41016a36025c200d200c6a200a41807f72200a41ff0071200a410776220c1b3a0000200c210a200c0d000c070b0b024002402003280258200328025c220d460d00200328025421040c010b200d41016a2204200d490d2a200d4101742205200420042005491b22054100480d2a02400240200d0d002005102721040c010b2003280254200d2005102821040b2004450d1220032005360258200320043602540b2003200d41016a36025c2004200d6a41023a00000340024002402003280258200328025c220d460d00200328025421040c010b200d41016a2204200d490d2b200d4101742205200420042005491b22054100480d2b02400240200d0d002005102721040c010b2003280254200d2005102821040b2004450d1420032005360258200320043602540b2003200d41016a36025c2004200d6a200c41807f72200c41ff0071200c410776220d1b3a0000200d210c200d0d000b0340024002402003280258200328025c220c460d002003280254210d0c010b200c41016a220d200c490d2b200c4101742204200d200d2004491b22044100480d2b02400240200c0d0020041027210d0c010b2003280254200c20041028210d0b200d450d15200320043602582003200d3602540b2003200c41016a36025c200d200c6a200a41807f72200a41ff0071200a410776220c1b3a0000200c210a200c0d000c060b0b024002402003280258200328025c220d460d00200328025421040c010b200d41016a2204200d490d29200d4101742205200420042005491b22054100480d2902400240200d0d002005102721040c010b2003280254200d2005102821040b2004450d1420032005360258200320043602540b2003200d41016a36025c2004200d6a41033a00000340024002402003280258200328025c220d460d00200328025421040c010b200d41016a2204200d490d2a200d4101742205200420042005491b22054100480d2a02400240200d0d002005102721040c010b2003280254200d2005102821040b2004450d1620032005360258200320043602540b2003200d41016a36025c2004200d6a200c41807f72200c41ff0071200c410776220d1b3a0000200d210c200d0d000b0340024002402003280258200328025c220c460d002003280254210d0c010b200c41016a220d200c490d2a200c4101742204200d200d2004491b22044100480d2a02400240200c0d0020041027210d0c010b2003280254200c20041028210d0b200d450d17200320043602582003200d3602540b2003200c41016a36025c200d200c6a200a41807f72200a41ff0071200a410776220c1b3a0000200c210a200c0d000b200341086a2002200341d0006a10e10320032d0008220a411a460d0520032f000920032d000b41107472210c0c220b024002402003280258200328025c220d460d00200328025421040c010b200d41016a2204200d490d28200d4101742205200420042005491b22054100480d2802400240200d0d002005102721040c010b2003280254200d2005102821040b2004450d1620032005360258200320043602540b2003200d41016a36025c2004200d6a41043a00000340024002402003280258200328025c220d460d00200328025421040c010b200d41016a2204200d490d29200d4101742205200420042005491b22054100480d2902400240200d0d002005102721040c010b2003280254200d2005102821040b2004450d1820032005360258200320043602540b2003200d41016a36025c2004200d6a200c41807f72200c41ff0071200c410776220d1b3a0000200d210c200d0d000b0340024002402003280258200328025c220c460d002003280254210d0c010b200c41016a220d200c490d29200c4101742204200d200d2004491b22044100480d2902400240200c0d0020041027210d0c010b2003280254200c20041028210d0b200d450d19200320043602582003200d3602540b2003200c41016a36025c200d200c6a200a41807f72200a41ff0071200a410776220c1b3a0000200c210a200c0d000b200341086a2002200341d0006a10e10320032d0008220a411a460d0420032f000920032d000b41107472210c0c210b024002402003280258200328025c220d460d00200328025421040c010b200d41016a2204200d490d27200d4101742205200420042005491b22054100480d2702400240200d0d002005102721040c010b2003280254200d2005102821040b2004450d1820032005360258200320043602540b2003200d41016a36025c2004200d6a41053a00000340024002402003280258200328025c220d460d00200328025421040c010b200d41016a2204200d490d28200d4101742205200420042005491b22054100480d2802400240200d0d002005102721040c010b2003280254200d2005102821040b2004450d1a20032005360258200320043602540b2003200d41016a36025c2004200d6a200c41807f72200c41ff0071200c410776220d1b3a0000200d210c200d0d000b0340024002402003280258200328025c220c460d002003280254210d0c010b200c41016a220d200c490d28200c4101742204200d200d2004491b22044100480d2802400240200c0d0020041027210d0c010b2003280254200c20041028210d0b200d450d1b200320043602582003200d3602540b2003200c41016a36025c200d200c6a200a41807f72200a41ff0071200a410776220c1b3a0000200c210a200c0d000b200341086a2002200341d0006a10e10320032d0008220a411a460d0320032f000920032d000b41107472210c0c200b024002402003280258200328025c220d460d00200328025421040c010b200d41016a2204200d490d26200d4101742205200420042005491b22054100480d2602400240200d0d002005102721040c010b2003280254200d2005102821040b2004450d1a20032005360258200320043602540b2003200d41016a36025c2004200d6a41063a00000340024002402003280258200328025c220d460d00200328025421040c010b200d41016a2204200d490d27200d4101742205200420042005491b22054100480d2702400240200d0d002005102721040c010b2003280254200d2005102821040b2004450d1c20032005360258200320043602540b2003200d41016a36025c2004200d6a200c41807f72200c41ff0071200c410776220d1b3a0000200d210c200d0d000b0340024002402003280258200328025c220c460d002003280254210d0c010b200c41016a220d200c490d27200c4101742204200d200d2004491b22044100480d2702400240200c0d0020041027210d0c010b2003280254200c20041028210d0b200d450d1d200320043602582003200d3602540b2003200c41016a36025c200d200c6a200a41807f72200a41ff0071200a410776220c1b3a0000200c210a200c0d000c020b0b024002402003280258200328025c220d460d00200328025421040c010b200d41016a2204200d490d25200d4101742205200420042005491b22054100480d2502400240200d0d002005102721040c010b2003280254200d2005102821040b2004450d1c20032005360258200320043602540b2003200d41016a36025c2004200d6a41073a00000340024002402003280258200328025c220d460d00200328025421040c010b200d41016a2204200d490d26200d4101742205200420042005491b22054100480d2602400240200d0d002005102721040c010b2003280254200d2005102821040b2004450d1e20032005360258200320043602540b2003200d41016a36025c2004200d6a200c41807f72200c41ff0071200c410776220d1b3a0000200d210c200d0d000b0340024002402003280258200328025c220c460d002003280254210d0c010b200c41016a220d200c490d26200c4101742204200d200d2004491b22044100480d2602400240200c0d0020041027210d0c010b2003280254200c20041028210d0b200d450d1f200320043602582003200d3602540b2003200c41016a36025c200d200c6a200a41807f72200a41ff0071200a410776220c1b3a0000200c210a200c0d000b0b2003411a3a00080b200741706a2107200b210d200b2006470d000b2006210b0c1c0b20054101102a000b200b4101102a000b200b4101102a000b20054101102a000b20054101102a000b20044101102a000b20054101102a000b20054101102a000b20044101102a000b20054101102a000b20054101102a000b20044101102a000b20054101102a000b20054101102a000b20044101102a000b20054101102a000b20054101102a000b20044101102a000b20054101102a000b20054101102a000b20044101102a000b20054101102a000b20054101102a000b20044101102a000b20054101102a000b20054101102a000b20044101102a000b20032903102114200328020c2104024003402007450d01200741706a2107200b280200210d200b41106a210b200d4108470d000b0b02402011450d00200910290b20124521054101210d0c010b024003402006200b460d01200b280200210a200b41106a210b200a4108470d000b0b02402011450d00200910290b20032802582109200328025421022003280250220441086a210b200441046a2105200328025c2207210c024002400340024002402005280200200b280200220a460d002004280200210d0c010b200a41016a220d200a490d08200a4101742206200d200d2006491b22064100480d0802400240200a0d0020061027210d0c010b2004280200200a20061028210d0b200d450d022004200d36020020052006360200200b280200210a0b200b200a41016a360200200d200a6a200c41807f72200c41ff0071200c410776220a1b3a0000200a210c200a0d000b02400240200441046a280200220c200441086a280200220a6b2007490d002004280200210c0c010b200a20076a220d200a490d07200c410174220a200d200d200a491b220a4100480d0702400240200c0d00200a1027210c0c010b2004280200200c200a1028210c0b200c450d022004200c360200200441046a200a360200200441086a280200210a0b200441086a200a20076a360200200c200a6a2002200710ce041a02402009450d00200210290b41002110410121072008450d032012450d032013450d03200810290c030b20064101102a000b200a4101102a000b02402003280258450d00200328025410290b02402008452005720d002013450d00200810290b0240200d201145720d00200910290b200a411a470d1141002110410121070b4101210c4101210d4101210b4101210841012109410121044101210541012113410121064101210241012111410121120c350b200141146a280200210f200141106a28020021112001410c6a2802002113200141086a2802002110200141056a2d0000210d200141046a2d00002109024002400240024002400240024002400240024002400240200241046a280200200241086a280200220a460d002002280200210c0c010b200a41016a220c200a490d0c200a410174220b200c200c200b491b220b4100480d0c02400240200a0d00200b1027210c0c010b2002280200200a200b1028210c0b200c450d012002200c360200200241046a200b360200200241086a280200210a0b200241086a200a41016a360200200c200a6a41003a00000240410410272212450d00201241eec2b5ab06360000024020090e0400050403000b410121064100210a4100210c2011210d034002400240200a200c460d00200a21070c010b200a41016a220c200a490d0e200a410174220b200c200c200b491b22074100480d0e02400240200a0d002007102721060c010b2006200a2007102821060b02402006450d00200a210c2007210a0c010b20074101102a000b2006200c6a200d41807f72200d41ff0071200d410776220b1b3a0000200c41016a210c200b210d200b0d000b0240024002402007200c6b20114f0d00200c20116a220a200c490d0f2007410174220d200a200a200d491b220a4100480d0f0240024020070d00200a102721060c010b20062007200a102821060b2006450d01200a21070b2006200c6a2010201110ce041a200c20116a21084101210e20130d010c080b200a4101102a000b201010290c060b41044101102a000b200b4101102a000b410021154101210e20102106201321072011210841012116410121170c040b2003410036024820034201370340410121044100210d4100210a2010210c02400240024002400240024003400240200a200d470d00200d41016a220b200d490d10200d4101742205200b200b2005491b220b4100480d1002400240200d0d00200b102721040c010b2004200d200b102821040b2004450d022003200b36024420032004360240200b210d0b2003200a41016a22053602482004200a6a200c41807f72200c41ff0071200c410776220b1b3a00002005210a200b210c200b0d000b2013200f4104746a21060240200f0d002013210b0c040b2013210b2010450d03200641706a21162010210e4100210a2013210803402008210b02400340200b41046a28020022070d01200a41016a210a2006200b41106a220b470d000c070b0b200b41106a2108200a41016a2115200e417f6a210e200b41086a2902002114200b28020021172003280244210d2003280248210c02400240034002400240200c200d460d00200328024021040c010b200d41016a2204200d490d13200d4101742205200420042005491b22054100480d1302400240200d0d002005102721040c010b2003280240200d2005102821040b2004450d0220032005360244200320043602402005210d0b2003200c41016a22053602482004200c6a200a41807f72200a41ff0071200a41077622041b3a00002005210c2004210a20040d000b200320143703102003200736020c20032017360208200341d0006a200341086a200341c0006a10ea0320032d00502204411a460d010c040b20054101102a000b2016200b460d032015210a200e0d000c030b0b200b4101102a000b20032d0053210e20032f0051211720032802542105200329035821140240200641706a200b460d00200b41106a210b0340200b220a41106a210b0240200a2802042207450d00200a28020821080240200a410c6a280200220a450d00200a410c6c210c2007210a03400240200a280200220d450d00200a41046a280200450d00200d10290b200a410c6a210a200c41746a220c0d000b0b2008450d00200710290b200b2006470d000b0b02402011450d00201310290b2004411a460d03200e411074210a02402003280244450d00200328024010290b2017200a72210a02400240200941024b0d000240024020090e03000109000b2013450d080c020b0240200f450d00200f410c6c210d2013210c03400240200c280200220b450d00200c41046a280200450d00200b10290b200c410c6a210c200d41746a220d0d000b0b02402011450d00201310290b2004411a470d074100210541012104410021080c0a0b2013450d060b201010290c050b200b41106a210b0b200b2006460d000340200b220a41106a210b0240200a2802042204450d00200a28020821050240200a410c6a280200220a450d00200a410c6c210c2004210a03400240200a280200220d450d00200a41046a280200450d00200d10290b200a410c6a210a200c41746a220c0d000b0b2005450d00200410290b200b2006470d000b0b2011450d00201310290b2003280248210820032802442107200328024021064102210d410021164101210e41002117410021150c030b4100210e2003410036024820034201370340200341146a200f360200200341086a41086a20113602002003201336020c20032010360208200341d0006a200341086a200341c0006a10ea03024020032d00502204411a460d0020032d0053411074210a20032f0051210c200341d0006a41086a29030021142003280254210502402003280244450d00200328024010290b200c200a72210a0c010b2003280248210820032802442107200328024021064101211641002117410021154101210d0c020b200041086a2014370200200041046a20053602002000200a410874200472360200201210290c030b4100211741012116410121154100210d0b024002400240410110272204450d002004200d3a00004102210d4101210a410121052008210c03400240200a2005470d00200d200a41016a220b200b200d491b22054100480d092004200a200510282204450d030b2004200a6a200c41807f72200c41ff0071200c410776220b1b3a0000200d41026a210d200a41016a210a200b210c200b0d000b02402005200a6b20084f0d00200a20086a220c200a490d082005410174220d200c200c200d491b220c4100480d080240024020050d00200c102721040c010b20042005200c102821040b2004450d03200c21050b2004200a6a2006200810ce041a02402007450d00200610290b2008200a6a21080240200941024b0d00024002400240024020090e03000102000b2015201345720d07201010290c070b200e450d060240200f450d00200f410c6c210c2013210a03400240200a280200220d450d00200a41046a280200450d00200d10290b200a410c6a210a200c41746a220c0d000b0b20110d010c060b2016450d050240200f450d002013200f4104746a21072013210603402006220b41106a21060240200b280204220a450d000240200b410c6a280200220c450d00200c410c6c210c03400240200a280200220d450d00200a41046a280200450d00200d10290b200a410c6a210a200c41746a220c0d000b0b200b41086a280200450d00200b28020410290b20062007470d000b0b2011450d050b201310290c040b2017201345720d03201010290c030b41014101102a000b20054101102a000b200c4101102a000b2003411c6a2008360200200341186a20053602002003200436021420034284808080c00037020c20032012360208200341d0006a200341086a200210f103200320032900513703402003200341d0006a41086a29000037004720032d0050220a411a460d012000200a3a000020002003290340370001200041086a20032900473700000b410021094101210d4101210c4101210b410121044101210541012106410121074101210241012108410121130c1a0b41002112410121074101210c4101210d4101210b41012108410121094101210441012105410121134101210641012102410121110c330b2001410c6a2802002105200141086a2802002113200141046a28020021090240024002400240024002400240024002400240200241046a280200200241086a280200220a460d002002280200210c0c010b200a41016a220c200a490d15200a410174220d200c200c200d491b220d4100480d1502400240200a0d00200d1027210c0c010b2002280200200a200d1028210c0b200c450d012002200c360200200241046a200d360200200241086a280200210a0b200241086a200a41016a360200200c200a6a410b3a0000200341dc006a4100360200200342013702542003200236025020092005411c6c6a21074100210a4100210c2005210d034002400240200a200c460d002003280254210a0c010b200a41016a220b200a490d16200a4101742204200b200b2004491b220b4100480d1602400240200a0d00200b1027210a0c010b2003280254200a200b1028210a0b200a450d032003200b3602582003200a3602540b2003200c41016a36025c200a200c6a200d41807f72200d41ff0071200d410776220d1b3a00000240200d450d002003280258210a200328025c210c200d210d0c010b0b200921042005450d062009210a0340200a411c6a2104200a2802042202450d07200a41186a2802002105200a41146a2802002108200a41086a2902002114200a280200210c200a28021021060340024002402003280258200328025c220a460d002003280254210d0c010b200a41016a220d200a490d17200a410174220b200d200d200b491b220b4100480d1702400240200a0d00200b1027210d0c010b2003280254200a200b1028210d0b200d450d052003200b3602582003200d360254200328025c210a0b2003200a41016a36025c200d200a6a200c41807f72200c41ff0071200c410776220a1b3a0000200a210c200a0d000b2003201437024420032002360240200341086a200341c0006a200341d0006a10de03024020032d0008220d411a470d002005210c0340024002402003280258200328025c220a460d002003280254210d0c010b200a41016a220d200a490d18200a410174220b200d200d200b491b220b4100480d1802400240200a0d00200b1027210d0c010b2003280254200a200b1028210d0b200d450d072003200b3602582003200d360254200328025c210a0b2003200a41016a36025c200d200a6a200c41807f72200c41ff0071200c410776220a1b3a0000200a210c200a0d000b024002402003280258220c200328025c220a6b2005490d002003280254210c0c010b200a20056a220d200a490d0b200c410174220a200d200d200a491b220a4100480d0b02400240200c0d00200a1027210c0c010b2003280254200c200a1028210c0b200c450d072003200a3602582003200c360254200328025c210a0b2003200a20056a36025c200c200a6a2006200510ce041a02402008450d00200610290b2004210a20042007470d010c090b0b20032d000b211220032f0009211020032903102114200328020c21112008450d05200610290c050b200d4101102a000b200b4101102a000b200b4101102a000b200b4101102a000b200a4101102a000b024020042007460d0003402004280204220b450d01200441146a2802002105200441086a28020021062004280210210202402004410c6a280200220a450d00200a410474210c200b210a03400240200a2d00004109470d00200a41086a28020041ffffffff0371450d00200a41046a28020010290b200a41106a210a200c41706a220c0d000b0b02402006450d00200b10290b2004411c6a210402402005450d00200210290b20042007470d000b0b2012411074210a02402013450d00200910290b2010200a72210a02402003280258450d00200328025410290b2000200a3b00012000200d3a0000200041036a200a4110763a0000200041086a2014370000200041046a2011360000410021084101210d4101210c4101210b41012104410121054101210641012107410121020c190b20042007460d0003402004280204220d450d01200441146a280200210b200441086a28020021052004280210210602402004410c6a280200220a450d00200a410474210c200d210a03400240200a2d00004109470d00200a41086a28020041ffffffff0371450d00200a41046a28020010290b200a41106a210a200c41706a220c0d000b0b02402005450d00200d10290b2004411c6a21040240200b450d00200610290b20042007470d000b0b02402013450d00200910290b20032802582108200328025421022003280250220441086a210b200441046a2105200328025c2207210c024002400340024002402005280200200b280200220a460d002004280200210d0c010b200a41016a220d200a490d04200a4101742206200d200d2006491b22064100480d0402400240200a0d0020061027210d0c010b2004280200200a20061028210d0b200d450d022004200d36020020052006360200200b280200210a0b200b200a41016a360200200d200a6a200c41807f72200c41ff0071200c410776220a1b3a0000200a210c200a0d000b02400240200441046a280200220c200441086a280200220a6b2007490d002004280200210c0c010b200a20076a220d200a490d03200c410174220a200d200d200a491b220a4100480d0302400240200c0d00200a1027210c0c010b2004280200200c200a1028210c0b200c450d022004200c360200200441046a200a360200200441086a280200210a0b200441086a200a20076a360200200c200a6a2002200710ce041a02402008450d00200210290b41002111410121074101210c4101210d4101210b41012108410121094101210441012105410121134101210641012102410121120c340b20064101102a000b200a4101102a000b102b000b2001410c6a2802002105200141086a2802002117200141046a280200210e024002400240024002400240200241046a280200200241086a280200220a460d002002280200210c0c010b200a41016a220c200a490d0f200a410174220d200c200c200d491b220d4100480d0f02400240200a0d00200d1027210c0c010b2002280200200a200d1028210c0b200c450d012002200c360200200241046a200d360200200241086a280200210a0b200241086a200a41016a360200200c200a6a410a3a00002003412c6a41003602002003420137022420032002360220200e200541186c6a210f4100210a4100210c2005210d0240034002400240200a200c460d002003280224210a0c010b200a41016a220b200a490d11200a4101742204200b200b2004491b220b4100480d1102400240200a0d00200b1027210a0c010b2003280224200a200b1028210a0b200a450d022003200b3602282003200a3602240b2003200c41016a36022c200a200c6a200d41807f72200d41ff0071200d410776220d1b3a00000240200d450d002003280228210a200328022c210c200d210d0c010b0b200e21092005450d03200341086a4101722102200341086a41026a2107200e210a02400340200a41186a2109200a2802002208450d05200a41146a2802002111200a41106a2802002112200a28020c2113200a29020421144100210c2003410036024c2003420137024420082014422088a7220d4103746a21062003200341206a3602402014a721104100210a024002400240024002400240034002400240200c200a460d002003280244210c0c010b200c41016a220a200c490d19200c410174220b200a200a200b491b220a4100480d1902400240200c0d00200a1027210c0c010b2003280244200c200a1028210c0b200c450d022003200a3602482003200c360244200328024c210a0b2003200a41016a36024c200c200a6a200d41807f72200d41ff0071200d410776220d1b3a00000240200d450d002003280248210c200328024c210a200d210d0c010b0b0240024020062008470d00200821040c010b2008210a0340200a41086a2104200a2902002214422088a7220a41ff01714104460d01200a41187441187521052014a7210c0340024002402003280248200328024c220a460d002003280244210d0c010b200a41016a220d200a490d1b200a410174220b200d200d200b491b220b4100480d1b02400240200a0d00200b1027210d0c010b2003280244200a200b1028210d0b200d450d052003200b3602482003200d360244200328024c210a0b2003200a41016a36024c200d200a6a200c41807f72200c41ff0071200c410776220a1b3a0000200a210c200a0d000b024002402003280248200328024c220a460d002003280244210c0c010b200a41016a220c200a490d1a200a410174220d200c200c200d491b220d4100480d1a02400240200a0d00200d1027210c0c010b2003280244200a200d1028210c0b200c450d052003200d3602482003200c360244200328024c210a0b2003200a41016a36024c200c200a6a2005417f73220a413f7141c00072200a2005417f4a1b3a00002004210a20042006470d000b200621040b0240034020062004460d0120042d0004210a200441086a2104200a4104470d000b0b02402010450d00200810290b20132011410474220a6a210b024020110d002013210a0c050b201341186a210c200a41706a21042013210a0340200a2d0000210d2007200a41036a2d00003a00002003200a41016a2f00003b01080240200d41ac01470d00200a41106a210a0c060b200341306a41026a20072d000022053a0000200320032f010822063b0130200a41046a2902002114200a410c6a2802002108200220063b0000200241026a20053a00002003200d3a0008200320083602142003201437020c200341d0006a200341086a200341c0006a10e80320032d00502205411a46220d450d04200c41106a210c200441706a2104200a41106a220a200b470d000c060b0b200a4101102a000b200b4101102a000b200d4101102a000b20032d0053210820032f00512111200328025421062003290358211402402004450d00034002400240200c41786a220a2d000022044109460d00200441ac01470d010c030b200c28020041ffffffff0371450d00200a41046a28020010290b200c41106a210c200a41106a200b470d000b0b02402012450d00201310290b02402003280248450d00200328024410290b200d450d062009210a2009200f470d020c080b200a200b460d00034002400240200a2d0000220c4109460d00200c41ac01470d010c030b200a41086a28020041ffffffff0371450d00200a41046a28020010290b200a41106a220a200b470d000b0b02402012450d00201310290b20032802482111200328024421132003280240210d200328024c2208210c0240034002400240200d41086a2205280200200d410c6a2204280200220a460d00200d280204210b0c010b200a41016a220b200a490d14200a4101742206200b200b2006491b22064100480d1402400240200a0d0020061027210b0c010b200d280204200a20061028210b0b200b450d02200d200b360204200520063602002004280200210a0b2004200a41016a360200200b200a6a200c41807f72200c41ff0071200c410776220a1b3a0000200a210c200a0d000b024002402005280200220c2004280200220a6b2008490d00200d280204210c0c010b200a20086a220b200a490d13200c410174220a200b200b200a491b220a4100480d1302400240200c0d00200a1027210c0c010b200d280204200c200a1028210c0b200c450d03200d200c3602042005200a3602002004280200210a0b2004200a20086a360200200c200a6a2013200810ce041a02402011450d00201310290b2009210a2009200f470d010c070b0b20064101102a000b200a4101102a000b200b4101102a000b200d4101102a000b02402009200f460d0003402009280200220c450d01200941146a280200210a200941106a280200210b200928020c210d02402009280204450d00200c10290b0240200a450d00200a410474210c200d210a03400240200a2d00004109470d00200a41086a28020041ffffffff0371450d00200a41046a28020010290b200a41106a210a200c41706a220c0d000b0b200941186a21090240200b450d00200d10290b2009200f470d000b0b2008411074210a02402017450d00200e10290b2011200a72210a02402003280228450d00200328022410290b2000200a3b0001200020053a0000200041036a200a4110763a0000200041086a2014370000200041046a2006360000410021024101210d4101210c4101210b410121044101210541012106410121070c160b2009200f460d0003402009280200220c450d01200941146a280200210a200941106a280200210b200928020c210d02402009280204450d00200c10290b0240200a450d00200a410474210c200d210a03400240200a2d00004109470d00200a41086a28020041ffffffff0371450d00200a41046a28020010290b200a41106a210a200c41706a220c0d000b0b200941186a21090240200b450d00200d10290b2009200f470d000b0b02402017450d00200e10290b20032802282108200328022421022003280220220441086a210b200441046a2105200328022c2207210c024002400340024002402005280200200b280200220a460d002004280200210d0c010b200a41016a220d200a490d0e200a4101742206200d200d2006491b22064100480d0e02400240200a0d0020061027210d0c010b2004280200200a20061028210d0b200d450d022004200d36020020052006360200200b280200210a0b200b200a41016a360200200d200a6a200c41807f72200c41ff0071200c410776220a1b3a0000200a210c200a0d000b02400240200441046a280200220c200441086a280200220a6b2007490d002004280200210c0c010b200a20076a220d200a490d0d200c410174220a200d200d200a491b220a4100480d0d02400240200c0d00200a1027210c0c010b2004280200200c200a1028210c0b200c450d022004200c360200200441046a200a360200200441086a280200210a0b200441086a200a20076a360200200c200a6a2002200710ce041a02402008450d00200210290b41002102410121074101210c4101210d4101210b4101210841012109410121044101210541012113410121060c220b20064101102a000b200a4101102a000b2001410c6a2802002105200141086a2802002113200141046a28020021090240024002400240024002400240024002400240200241046a280200200241086a280200220a460d002002280200210c0c010b200a41016a220c200a490d12200a410174220d200c200c200d491b220d4100480d1202400240200a0d00200d1027210c0c010b2002280200200a200d1028210c0b200c450d012002200c360200200241046a200d360200200241086a280200210a0b200241086a200a41016a360200200c200a6a41093a0000200341dc006a4100360200200342013702542003200236025020092005411c6c6a21024100210a4100210c2005210d034002400240200a200c460d002003280254210a0c010b200a41016a220b200a490d13200a4101742204200b200b2004491b220b4100480d1302400240200a0d00200b1027210a0c010b2003280254200a200b1028210a0b200a450d032003200b3602582003200a3602540b2003200c41016a36025c200a200c6a200d41807f72200d41ff0071200d410776220d1b3a00000240200d450d002003280258210a200328025c210c200d210d0c010b0b200921062005450d062009210a0340200a411c6a2106200a2802042205450d07200a41186a2802002104200a41146a2802002108200a41086a2902002114200a2802102107200a280200210c0340024002402003280258200328025c220a460d002003280254210d0c010b200a41016a220d200a490d14200a410174220b200d200d200b491b220b4100480d1402400240200a0d00200b1027210d0c010b2003280254200a200b1028210d0b200d450d052003200b3602582003200d360254200328025c210a0b2003200a41016a36025c200d200a6a200c41807f72200c41ff0071200c410776220a1b3a0000200a210c200a0d000b2003201437024420032005360240200341086a200341c0006a200341d0006a10de03024020032d0008220d411a470d00200720044102746a21052004210c0340024002402003280258200328025c220a460d002003280254210d0c010b200a41016a220d200a490d15200a410174220b200d200d200b491b220b4100480d1502400240200a0d00200b1027210d0c010b2003280254200a200b1028210d0b200d450d072003200b3602582003200d360254200328025c210a0b2003200a41016a36025c200d200a6a200c41807f72200c41ff0071200c410776220a1b3a0000200a210c200a0d000b02402004450d002007210403402004280200210c0340024002402003280258200328025c220a460d002003280254210d0c010b200a41016a220d200a490d17200a410174220b200d200d200b491b220b4100480d1702400240200a0d00200b1027210d0c010b2003280254200a200b1028210d0b200d450d0a2003200b3602582003200d360254200328025c210a0b2003200a41016a36025c200d200a6a200c41807f72200c41ff0071200c410776220a1b3a0000200a210c200a0d000b200441046a22042005470d000b0b02402008450d00200710290b2006210a20062002470d010c090b0b20032d000b211220032f0009211020032903102114200328020c21112008450d05200710290c050b200d4101102a000b200b4101102a000b200b4101102a000b200b4101102a000b200b4101102a000b024020062002460d0003402006280204220b450d01200641146a2802002104200641086a28020021052006280210210702402006410c6a280200220a450d00200a410474210c200b210a03400240200a2d00004109470d00200a41086a28020041ffffffff0371450d00200a41046a28020010290b200a41106a210a200c41706a220c0d000b0b02402005450d00200b10290b2006411c6a210602402004450d00200710290b20062002470d000b0b2012411074210a02402013450d00200910290b2010200a72210a02402003280258450d00200328025410290b2000200a3b00012000200d3a0000200041036a200a4110763a0000200041086a2014370000200041046a2011360000410021074101210d4101210c4101210b4101210441012105410121060c140b20062002460d0003402006280204220d450d01200641146a280200210b200641086a28020021042006280210210502402006410c6a280200220a450d00200a410474210c200d210a03400240200a2d00004109470d00200a41086a28020041ffffffff0371450d00200a41046a28020010290b200a41106a210a200c41706a220c0d000b0b02402004450d00200d10290b2006411c6a21060240200b450d00200510290b20062002470d000b0b02402013450d00200910290b20032802582108200328025421022003280250220441086a210b200441046a2105200328025c2207210c024002400340024002402005280200200b280200220a460d002004280200210d0c010b200a41016a220d200a490d0d200a4101742206200d200d2006491b22064100480d0d02400240200a0d0020061027210d0c010b2004280200200a20061028210d0b200d450d022004200d36020020052006360200200b280200210a0b200b200a41016a360200200d200a6a200c41807f72200c41ff0071200c410776220a1b3a0000200a210c200a0d000b02400240200441046a280200220c200441086a280200220a6b2007490d002004280200210c0c010b200a20076a220d200a490d0c200c410174220a200d200d200a491b220a4100480d0c02400240200c0d00200a1027210c0c010b2004280200200c200a1028210c0b200c450d022004200c360200200441046a200a360200200441086a280200210a0b200441086a200a20076a360200200c200a6a2002200710ce041a02402008450d00200210290b41002106410121074101210c4101210d4101210b41012108410121094101210441012105410121130c200b20064101102a000b200a4101102a000b200141046a280200210a0240024002400240024002400240200241046a280200200241086a280200220c460d002002280200210d0c010b200c41016a220d200c490d0e200c410174220b200d200d200b491b220b4100480d0e02400240200c0d00200b1027210d0c010b2002280200200c200b1028210d0b200d450d012002200d360200200241046a200b360200200241086a280200210c0b200241086a200c41016a360200200d200c6a41083a0000410121064100210b4100210c03400240200c200b470d00200b410174220d200b41016a22042004200d491b220d4100480d0f02400240200b0d00200d102721060c010b2006200b200d102821060b2006450d05200d210b0b2006200c6a200a41807f72200a41ff0071200a410776220d1b3a0000200c41016a210c200d210a200d0d000b200c417f6a2109200241086a2105200241046a2107200c210d03400240024020072802002005280200220a460d00200228020021040c010b200a41016a2204200a490d0f200a4101742208200420042008491b22084100480d0f02400240200a0d002008102721040c010b2002280200200a2008102821040b2004450d0320022004360200200720083602002005280200210a0b2005200a41016a3602002004200a6a200d41807f72200d41ff0071200d410776220a1b3a0000200a210d200a0d000b02400240200241046a280200220d200241086a280200220a6b20094d0d002002280200210d0c010b200a200c6a2204200a490d0e200d410174220a20042004200a491b220a4100480d0e02400240200d0d00200a1027210d0c010b2002280200200d200a1028210d0b200d450d032002200d360200200241046a200a360200200241086a280200210a0b200241086a200a200c6a360200200d200a6a2006200c10ce041a41012107200b450d04200610290c040b200b4101102a000b20084101102a000b200a4101102a000b200d4101102a000b4101210c4101210d0c160b2001410c6a2802002109200141086a2802002113200141046a280200210802400240024002400240024002400240200241046a280200200241086a280200220a460d002002280200210c0c010b200a41016a220c200a490d0e200a410174220d200c200c200d491b220d4100480d0e02400240200a0d00200d1027210c0c010b2002280200200a200d1028210c0b200c450d012002200c360200200241046a200d360200200241086a280200210a0b200241086a200a41016a360200200c200a6a41073a0000200341dc006a410036020020034201370254200320023602502008200941146c6a2107410121044100210d4100210a2009210c03400240200a200d470d00200d41016a220b200d490d0f200d4101742205200b200b2005491b220b4100480d0f02400240200d0d00200b102721040c010b2004200d200b102821040b2004450d032003200b36025820032004360254200b210d0b2003200a41016a220536025c2004200a6a200c41807f72200c41ff0071200c410776220b1b3a00002005210a200b210c200b0d000b200821062009450d042008210a0340200a41146a2106200a28020c22054104460d05200a41106a280200210c200a29020021142003200a28020836024820032014370340200341086a200341c0006a200341d0006a10ed0320032d0008220a411a470d04024002402003280258220d200328025c220b460d00200328025421040c010b200b41016a220a200b490d0f200b410174220d200a200a200d491b220d4100480d0f02400240200b0d00200d102721040c010b2003280254200b200d102821040b2004450d042003200d360258200320043602540b2003200b41016a220a36025c2004200b6a20053a0000024003400240200a200d470d00200d41016a220b200d490d11200d4101742205200b200b2005491b220b4100480d1102400240200d0d00200b102721040c010b2004200d200b102821040b2004450d02200b210d0b2004200a6a200c41807f72200c41ff0071200c410776220b1b3a0000200a41016a210a200b210c200b0d000b2003200d3602582003200a36025c200320043602542006210a20062007470d010c070b0b200b4101102a000b200d4101102a000b200b4101102a000b200d4101102a000b20032d000b210c20032f0009210d20032903102114200328020c210b024020062007460d0003402006410c6a2802004104460d010240200641046a280200450d00200628020010290b200641146a22062007470d000b0b200c411074210c02402013450d00200810290b200d200c72210c02402003280258450d00200328025410290b2000200c3b00012000200a3a0000200041036a200c4110763a0000200041086a2014370000200041046a200b360000410021064101210d4101210c4101210b41012104410121050c110b20062007460d0003402006410c6a2802004104460d010240200641046a280200450d00200628020010290b200641146a22062007470d000b0b02402013450d00200810290b20032802582108200328025421022003280250220441086a210b200441046a2105200328025c2207210c024002400340024002402005280200200b280200220a460d002004280200210d0c010b200a41016a220d200a490d0b200a4101742206200d200d2006491b22064100480d0b02400240200a0d0020061027210d0c010b2004280200200a20061028210d0b200d450d022004200d36020020052006360200200b280200210a0b200b200a41016a360200200d200a6a200c41807f72200c41ff0071200c410776220a1b3a0000200a210c200a0d000b02400240200441046a280200220c200441086a280200220a6b2007490d002004280200210c0c010b200a20076a220d200a490d0a200c410174220a200d200d200a491b220a4100480d0a02400240200c0d00200a1027210c0c010b2004280200200c200a1028210c0b200c450d022004200c360200200441046a200a360200200441086a280200210a0b200441086a200a20076a360200200c200a6a2002200710ce041a02402008450d00200210290b41002113410121074101210c4101210d4101210b410121084101210941012104410121050c1d0b20064101102a000b200a4101102a000b2001410c6a2802002109200141086a2802002113200141046a2802002108024002400240024002400240024002400240200241046a280200200241086a280200220a460d002002280200210c0c010b200a41016a220c200a490d0e200a410174220d200c200c200d491b220d4100480d0e02400240200a0d00200d1027210c0c010b2002280200200a200d1028210c0b200c450d012002200c360200200241046a200d360200200241086a280200210a0b200241086a200a41016a360200200c200a6a41063a0000200341dc006a41003602002003420137025420032002360250200820094104746a21054100210a4100210c2009210d034002400240200a200c460d002003280254210a0c010b200a41016a220b200a490d0f200a4101742204200b200b2004491b220b4100480d0f02400240200a0d00200b1027210a0c010b2003280254200a200b1028210a0b200a450d032003200b3602582003200a3602540b2003200c41016a36025c200a200c6a200d41807f72200d41ff0071200d410776220d1b3a00000240200d450d002003280258210a200328025c210c200d210d0c010b0b2008210d2009450d054100210d0340200341086a41086a220a2008200d6a220c41086a2802003602002003200c2902003703080240200c410d6a2d000022044102470d00200c41106a210d0c070b200341306a41086a200a280200220a360200200320032903082214370330200c410c6a2d00002106200341206a41086a2207200a36020020032014370320024002402003280258200328025c220a460d002003280254210b0c010b200a41016a220b200a490d0f200a4101742202200b200b2002491b22024100480d0f02400240200a0d0020021027210b0c010b2003280254200a20021028210b0b200b450d04200320023602582003200b360254200328025c210a0b2003200a41016a36025c200b200a6a41fdf9ff77200641037441187141107376413f7141c000723a0000024002402003280258200328025c220a460d002003280254210b0c010b200a41016a220b200a490d0f200a4101742206200b200b2006491b22064100480d0f02400240200a0d0020061027210b0c010b2003280254200a20061028210b0b200b450d05200320063602582003200b360254200328025c210a0b2003200a41016a36025c200b200a6a20044100473a0000200341c0006a41086a200728020036020020032003290320370340200341086a200341c0006a200341d0006a10de0320032d0008220b411a470d05200d41106a210d200c41106a2005470d000c070b0b200d4101102a000b200b4101102a000b20024101102a000b20064101102a000b20032d000b210720032f00092102200328020c2111200329031021140240200941047441706a200d460d00200c41106a210d0340200d410d6a2d00004102460d01200d2802042106200d28020021040240200d280208220a450d00200a410474210c2004210a03400240200a2d00004109470d00200a41086a28020041ffffffff0371450d00200a41046a28020010290b200a41106a210a200c41706a220c0d000b0b200d41106a210d02402006450d00200410290b200d2005470d000b0b2007411074210a02402013450d00200810290b2002200a72210a02402003280258450d00200328025410290b2000200a3b00012000200b3a0000200041036a200a4110763a0000200041086a2014370000200041046a2011360000410021054101210d4101210c4101210b410121040c0f0b200d2005460d000340200d410d6a2d00004102460d01200d2802042104200d280200210b0240200d280208220a450d00200a410474210c200b210a03400240200a2d00004109470d00200a41086a28020041ffffffff0371450d00200a41046a28020010290b200a41106a210a200c41706a220c0d000b0b200d41106a210d02402004450d00200b10290b200d2005470d000b0b02402013450d00200810290b20032802582108200328025421022003280250220441086a210b200441046a2105200328025c2207210c024002400340024002402005280200200b280200220a460d002004280200210d0c010b200a41016a220d200a490d0a200a4101742206200d200d2006491b22064100480d0a02400240200a0d0020061027210d0c010b2004280200200a20061028210d0b200d450d022004200d36020020052006360200200b280200210a0b200b200a41016a360200200d200a6a200c41807f72200c41ff0071200c410776220a1b3a0000200a210c200a0d000b02400240200441046a280200220c200441086a280200220a6b2007490d002004280200210c0c010b200a20076a220d200a490d09200c410174220a200d200d200a491b220a4100480d0902400240200c0d00200a1027210c0c010b2004280200200c200a1028210c0b200c450d022004200c360200200441046a200a360200200441086a280200210a0b200441086a200a20076a360200200c200a6a2002200710ce041a02402008450d00200210290b41002105410121074101210c4101210d4101210b4101210841012109410121040c1b0b20064101102a000b200a4101102a000b2001410c6a2802002107200141086a2802002108200141046a280200210602400240024002400240200241046a280200200241086a280200220a460d002002280200210c0c010b200a41016a220c200a490d09200a410174220d200c200c200d491b220d4100480d0902400240200a0d00200d1027210c0c010b2002280200200a200d1028210c0b200c450d012002200c360200200241046a200d360200200241086a280200210a0b200241086a200a41016a360200200c200a6a41053a0000200341d0006a410c6a4100360200200342013702542003200236025020062007410c6c6a2102410121044100210d4100210a2007210c03400240200a200d470d00200d41016a220b200d490d0a200d4101742205200b200b2005491b220b4100480d0a02400240200d0d00200b102721040c010b2004200d200b102821040b2004450d032003200b36025820032004360254200b210d0b2003200a41016a220536025c2004200a6a200c41807f72200c41ff0071200c410776220b1b3a00002005210a200b210c200b0d000b2006210a2007450d022007410c6c210b4100210c034002402006200c6a220a41046a280200220d4102470d00200a410c6a210a0c040b200341086a200a280200200d200a41086a280200200341d0006a10eb03024020032d00082204411a460d0020032f000920032d000b41107472210520032903102114200328020c2107200a410c6a210d200b200c6b41746a210a02400340200a450d01200a41746a210a200d280204210c200d410c6a210d200c4102470d000b0b02402008450d00200610290b02402003280258450d00200328025410290b200020053b0001200020043a0000200041036a20054110763a0000200041086a2014370000200041046a2007360000410021044101210d4101210c4101210b0c100b200b200c410c6a220c470d000b2002210a0c020b200d4101102a000b200b4101102a000b200a410020076b410c6c6a210c024003402006200c460d01200c410c6a210c200a280204210d200a410c6a210a200d4102470d000b0b02402008450d00200610290b20032802582108200328025421022003280250220441086a210b200441046a2105200328025c2207210c024002400340024002402005280200200b280200220a460d002004280200210d0c010b200a41016a220d200a490d09200a4101742206200d200d2006491b22064100480d0902400240200a0d0020061027210d0c010b2004280200200a20061028210d0b200d450d022004200d36020020052006360200200b280200210a0b200b200a41016a360200200d200a6a200c41807f72200c41ff0071200c410776220a1b3a0000200a210c200a0d000b02400240200441046a280200220c200441086a280200220a6b2007490d002004280200210c0c010b200a20076a220d200a490d08200c410174220a200d200d200a491b220a4100480d0802400240200c0d00200a1027210c0c010b2004280200200c200a1028210c0b200c450d022004200c360200200441046a200a360200200441086a280200210a0b200441086a200a20076a360200200c200a6a2002200710ce041a02402008450d00200210290b41002104410121074101210c4101210d4101210b41012108410121090c190b20064101102a000b200a4101102a000b2001410c6a2802002109200141086a2802002113200141046a2802002106024002400240024002400240200241046a280200200241086a280200220a460d002002280200210c0c010b200a41016a220c200a490d09200a410174220d200c200c200d491b220d4100480d0902400240200a0d00200d1027210c0c010b2002280200200a200d1028210c0b200c450d012002200c360200200241046a200d360200200241086a280200210a0b200241086a200a41016a360200200c200a6a41043a0000200341d0006a410c6a4100360200200342013702542003200236025020062009410c6c6a2111410121044100210d4100210a2009210c03400240200a200d470d00200d41016a220b200d490d0a200d4101742205200b200b2005491b220b4100480d0a02400240200d0d00200b102721040c010b2004200d200b102821040b2004450d032003200b36025820032004360254200b210d0b2003200a41016a220536025c2004200a6a200c41807f72200c41ff0071200c410776220b1b3a00002005210a200b210c200b0d000b2006210a2009450d032009410c6c21084100210d034002402006200d6a220c41046a28020022044102470d00200c410c6a210a0c050b200c2802002105200c41086a2802002107024002402003280258200328025c220a460d002003280254210b0c010b200a41016a220b200a490d0a200a4101742202200b200b2002491b22024100480d0a02400240200a0d0020021027210b0c010b2003280254200a20021028210b0b200b450d04200320023602582003200b3602540b2003200a41016a36025c200b200a6a41f0003a0000200341086a200520042007200341d0006a10eb03024020032d0008220b411a460d0020032f000920032d000b41107472210420032903102114200328020c2105200c410c6a210c2008200d6b41746a210a02400340200a450d01200a41746a210a200c280204210d200c410c6a210c200d4102470d000b0b02402013450d00200610290b02402003280258450d00200328025410290b200020043b00012000200b3a0000200041036a20044110763a0000200041086a2014370000200041046a20053600004100210b4101210d4101210c0c0f0b2008200d410c6a220d470d000b2011210a0c030b200d4101102a000b200b4101102a000b20024101102a000b200a410020096b410c6c6a210c024003402006200c460d01200c410c6a210c200a280204210d200a410c6a210a200d4102470d000b0b02402013450d00200610290b20032802582108200328025421022003280250220441086a210b200441046a2105200328025c2207210c024002400340024002402005280200200b280200220a460d002004280200210d0c010b200a41016a220d200a490d08200a4101742206200d200d2006491b22064100480d0802400240200a0d0020061027210d0c010b2004280200200a20061028210d0b200d450d022004200d36020020052006360200200b280200210a0b200b200a41016a360200200d200a6a200c41807f72200c41ff0071200c410776220a1b3a0000200a210c200a0d000b02400240200441046a280200220c200441086a280200220a6b2007490d002004280200210c0c010b200a20076a220d200a490d07200c410174220a200d200d200a491b220a4100480d0702400240200c0d00200a1027210c0c010b2004280200200c200a1028210c0b200c450d022004200c360200200441046a200a360200200441086a280200210a0b200441086a200a20076a360200200c200a6a2002200710ce041a02402008450d00200210290b41002109410121074101210c4101210d4101210b410121080c170b20064101102a000b200a4101102a000b2001410c6a2802002106200141086a2802002109200141046a280200210802400240024002400240024002400240200241046a280200200241086a280200220a460d002002280200210c0c010b200a41016a220c200a490d0a200a410174220d200c200c200d491b220d4100480d0a02400240200a0d00200d1027210c0c010b2002280200200a200d1028210c0b200c450d012002200c360200200241046a200d360200200241086a280200210a0b200241086a200a41016a360200200c200a6a41033a0000200820064102746a21074100210d4100210a41002105410121042006210c03400240200a2005470d00200d200a41016a220b200b200d491b22054100480d0b02400240200d0d002005102721040c010b2004200a2005102821040b2004450d050b2004200a6a200c41807f72200c41ff0071200c410776220b1b3a0000200d41026a210d200a41016a210a200b210c200b0d000b02402006450d00200821060340200a410174210d2006280200210c03400240200a2005470d00200a41016a220b200a490d0d200d200b200b200d491b22054100480d0d02400240200a0d002005102721040c010b2004200a2005102821040b2004450d080b2004200a6a200c41807f72200c41ff0071200c410776220b1b3a0000200d41026a210d200a41016a210a200b210c200b0d000b200641046a22062007470d000b0b02402009450d00200810290b200241086a2106200241046a2107200a210d03400240024020072802002006280200220c460d002002280200210b0c010b200c41016a220b200c490d0b200c4101742208200b200b2008491b22084100480d0b02400240200c0d0020081027210b0c010b2002280200200c20081028210b0b200b450d032002200b360200200720083602002006280200210c0b2006200c41016a360200200b200c6a200d41807f72200d41ff0071200d410776220c1b3a0000200c210d200c0d000b02400240200241046a280200220d200241086a280200220c6b200a490d002002280200210d0c010b200c200a6a220b200c490d0a200d410174220c200b200b200c491b220c4100480d0a02400240200d0d00200c1027210d0c010b2002280200200d200c1028210d0b200d450d032002200d360200200241046a200c360200200241086a280200210c0b200241086a200c200a6a360200200d200c6a2004200a10ce041a41002108410121072005450d05200410290c050b200d4101102a000b20084101102a000b200c4101102a000b20054101102a000b20054101102a000b4101210c4101210d4101210b0c130b2001410c6a2802002106200141086a2802002111200141046a28020021130240024002400240024002400240024002400240024002400240024002400240200241046a280200200241086a280200220a460d002002280200210c0c010b200a41016a220c200a490d11200a410174220d200c200c200d491b220d4100480d1102400240200a0d00200d1027210c0c010b2002280200200a200d1028210c0b200c450d012002200c360200200241046a200d360200200241086a280200210a0b200241086a200a41016a360200200c200a6a41023a0000200341dc006a410036020020034201370254200320023602502013200641286c6a21054100210a4100210c2006210d034002400240200a200c460d002003280254210a0c010b200a41016a220b200a490d12200a4101742204200b200b2004491b220b4100480d1202400240200a0d00200b1027210a0c010b2003280254200a200b1028210a0b200a450d032003200b3602582003200a3602540b2003200c41016a36025c200a200c6a200d41807f72200d41ff0071200d410776220d1b3a00000240200d450d002003280258210a200328025c210c200d210d0c010b0b2013210b2006450d0c2013210b0340200341086a41086a220d200b220a41086a2802003602002003200a290200370308200a41286a210b200a2d001822074104460d0d200a411b6a2d00002108200a41196a2f00002109200a41206a2900002114200a411c6a280000210c200a41146a2802002102200a41106a2802002104200a28020c2106200341206a41086a200d280200220a360200200320032903082218370320200341c0006a41086a200a36020020032018370340200341086a200341c0006a200341d0006a10ed03024020032d0008220a411a460d0020032f000920032d000b41107472210720032903102114200328020c21022004450d0d200610290c0d0b200320023602482003200436024420032006360240200341086a200341c0006a200341d0006a10ed03024020032d0008220a411a460d0020032f000920032d000b411074722107200328020c2102200329031021140c0d0b2014422088a7210a2014a7210d0240024002400240024020070e0400010203000b024002402003280258200328025c220a460d002003280254210d0c010b200a41016a220d200a490d16200a4101742204200d200d2004491b22044100480d1602400240200a0d0020041027210d0c010b2003280254200a20041028210d0b200d450d08200320043602582003200d3602540b2003200a41016a36025c200d200a6a41003a00000340024002402003280258200328025c220a460d002003280254210d0c010b200a41016a220d200a490d17200a4101742204200d200d2004491b22044100480d1702400240200a0d0020041027210d0c010b2003280254200a20041028210d0b200d450d0a200320043602582003200d3602540b2003200a41016a36025c200d200a6a200c41807f72200c41ff0071200c410776220a1b3a0000200a210c200a0d000c040b0b024002402003280258200328025c2204460d00200328025421060c010b200441016a22062004490d1520044101742207200620062007491b22074100480d150240024020040d002007102721060c010b200328025420042007102821060b2006450d0920032007360258200320063602540b2003200441016a36025c200620046a41013a0000024002402003280258200328025c2204460d00200328025421060c010b200441016a22062004490d1520044101742207200620062007491b22074100480d150240024020040d002007102721060c010b200328025420042007102821060b2006450d0a20032007360258200320063602540b2003200441016a36025c200620046a41f0003a0000200341086a200c200d200a200341d0006a10eb0320032d0008220a411a460d0220032f000920032d000b4110747221070c0e0b024002402003280258200328025c2204460d00200328025421060c010b200441016a22062004490d1420044101742207200620062007491b22074100480d140240024020040d002007102721060c010b200328025420042007102821060b2006450d0a20032007360258200320063602540b2003200441016a36025c200620046a41023a0000200341086a200c200d200a200341d0006a10eb0320032d0008220a411a460d0120032f000920032d000b4110747221070c0d0b024002402003280258200328025c220a460d002003280254210c0c010b200a41016a220c200a490d13200a410174220d200c200c200d491b220d4100480d1302400240200a0d00200d1027210c0c010b2003280254200a200d1028210c0b200c450d0a2003200d3602582003200c3602540b2003200a41016a36025c200c200a6a41033a0000024002402003280258200328025c220a460d002003280254210c0c010b200a41016a220c200a490d13200a410174220d200c200c200d491b220d4100480d1302400240200a0d00200d1027210c0c010b2003280254200a200d1028210c0b200c450d0b2003200d3602582003200c3602540b2003200a41016a36025c200c200a6a2009200841107472220c417f73220a413f7141c00072200a200c411874411875417f4a1b3a0000024002402003280258200328025c220a460d002003280254210d0c010b200a41016a220d200a490d13200a4101742204200d200d2004491b22044100480d1302400240200a0d0020041027210d0c010b2003280254200a20041028210d0b200d450d0c200320043602582003200d3602540b2003200a41016a36025c200d200a6a200c4180fe03714100473a00000b200b2005470d000c0e0b0b200d4101102a000b200b4101102a000b20044101102a000b20044101102a000b20074101102a000b20074101102a000b20074101102a000b200d4101102a000b200d4101102a000b20044101102a000b20032903102114200328020c21020b0240200b2005460d000340200b41186a2d00004104460d01200b41106a280200210c200b410c6a280200210d0240200b41046a280200450d00200b28020010290b0240200c450d00200d10290b200b41286a220b2005470d000b0b02402011450d00201310290b02402003280258450d00200328025410290b200020073b00012000200a3a0000200041036a20074110763a0000200041086a2014370000200041046a20023600004100210c4101210d0c080b200b2005460d000340200b41186a2d00004104460d01200b41106a280200210a200b410c6a280200210c0240200b41046a280200450d00200b28020010290b0240200a450d00200c10290b200b41286a220b2005470d000b0b02402011450d00201310290b20032802582108200328025421022003280250220441086a210b200441046a2105200328025c2207210c024002400340024002402005280200200b280200220a460d002004280200210d0c010b200a41016a220d200a490d06200a4101742206200d200d2006491b22064100480d0602400240200a0d0020061027210d0c010b2004280200200a20061028210d0b200d450d022004200d36020020052006360200200b280200210a0b200b200a41016a360200200d200a6a200c41807f72200c41ff0071200c410776220a1b3a0000200a210c200a0d000b02400240200441046a280200220c200441086a280200220a6b2007490d002004280200210c0c010b200a20076a220d200a490d05200c410174220a200d200d200a491b220a4100480d0502400240200c0d00200a1027210c0c010b2004280200200c200a1028210c0b200c450d022004200c360200200441046a200a360200200441086a280200210a0b200441086a200a20076a360200200c200a6a2002200710ce041a02402008450d00200210290b4100210b410121074101210c4101210d0c130b20064101102a000b200a4101102a000b20082010460d0003402008410d6a2d00004105460d010240200841046a280200450d00200828020010290b200841106a22082010470d000b0b0240200e450d00200f10290b200241086a2106200241046a2107200c210d0240024003400240024020072802002006280200220a460d002002280200210b0c010b200a41016a220b200a490d04200a4101742208200b200b2008491b22084100480d0402400240200a0d0020081027210b0c010b2002280200200a20081028210b0b200b450d022002200b360200200720083602002006280200210a0b2006200a41016a360200200b200a6a200d41807f72200d41ff0071200d410776220a1b3a0000200a210d200a0d000b02400240200241046a280200220d200241086a280200220a6b200c490d002002280200210d0c010b200a200c6a220b200a490d03200d410174220a200b200b200a491b220a4100480d0302400240200d0d00200a1027210d0c010b2002280200200d200a1028210d0b200d450d022002200d360200200241046a200a360200200241086a280200210a0b200241086a200a200c6a360200200d200a6a2004200c10ce041a4100210d410121072005450d03200410290c030b20084101102a000b200a4101102a000b102b000b4101210c0c0c0b2000200c3b00012000200a3a0000200041036a200c4110763a0000200041086a2014370000200041046a2004360000410021134101210d4101210c4101210b410121044101210541012106410121074101210241012108410121090c090b4101210c200241086a200a41016a3602004100210d200b200a6a41003a00002003411c6a2004360200200341186a200536020020032006360214200320073602102003200836020c20032009360208200341d0006a200341086a200210f103200320032900513703402003200341d0006a41086a29000037004720032d0050220a411a460d092000200a3a000020002003290340370001200041086a20032900473700000b4101210b0b410121040b410121050b410121060b410121070b410121020b410121080b41012109410121130b20012d0000220a410e4b0d18200a0e0f0a0b0c0d0e0f1011121813141516170a0b4101210c410021074101210d0b4101210b0b410121080b410121090b410121040b410121050b410121130b410121060b410121020b41012111410121120c0f0b200141086a280200450d10200141046a28020010290c100b200d450d0f0240200141086a280200450d00200141046a28020010290b200141146a280200450d0f200141106a28020010290c0f0b02402001410c6a280200220c450d00200141046a280200210a200c410474210c03400240200a41046a280200450d00200a28020010290b200a41106a210a200c41706a220c0d000b0b200141086a280200450d0e200128020410290c0e0b200c450d0d02402001410c6a280200220c450d00200141046a280200210a200c41286c210c03400240200a41046a280200450d00200a28020010290b0240200a41106a280200450d00200a410c6a28020010290b200a41286a210a200c41586a220c0d000b0b200141086a280200450d0d200128020410290c0d0b200141086a280200450d0c200141046a28020010290c0c0b200b450d0b200141086a280200450d0b200141046a28020010290c0b0b2004450d0a200141086a280200450d0a200141046a28020010290c0a0b2005450d0902402001410c6a280200220a450d00200141046a280200220d200a4104746a210b03400240200d280208220c450d00200d280200210a200c410474210c03400240200a2d00004109470d00200a41086a28020041ffffffff0371450d00200a41046a28020010290b200a41106a210a200c41706a220c0d000b0b200d41106a210a0240200d41046a280200450d00200d28020010290b200a210d200a200b470d000b0b200141086a280200450d09200128020410290c090b2006450d0802402001410c6a280200220c450d00200141046a280200210a200c41146c210c03400240200a41046a280200450d00200a28020010290b200a41146a210a200c416c6a220c0d000b0b200141086a280200450d08200128020410290c080b2007450d0702402001410c6a280200220a450d00200141046a280200220d200a411c6c6a210b03400240200d410c6a280200220c450d00200d280204210a200c410474210c03400240200a2d00004109470d00200a41086a28020041ffffffff0371450d00200a41046a28020010290b200a41106a210a200c41706a220c0d000b0b0240200d41086a280200450d00200d28020410290b200d411c6a210a0240200d41146a280200450d00200d28021010290b200a210d200a200b470d000b0b200141086a280200450d07200128020410290c070b2002450d0602402001410c6a280200220a450d00200141046a280200220d200a41186c6a210b03400240200d41046a280200450d00200d28020010290b0240200d41146a280200220c450d00200d28020c210a200c410474210c03400240200a2d00004109470d00200a41086a28020041ffffffff0371450d00200a41046a28020010290b200a41106a210a200c41706a220c0d000b0b200d41186a210a0240200d41106a280200450d00200d28020c10290b200a210d200a200b470d000b0b200141086a280200450d06200128020410290c060b2008450d0502402001410c6a280200220a450d00200141046a280200220d200a411c6c6a210b03400240200d410c6a280200220c450d00200d280204210a200c410474210c03400240200a2d00004109470d00200a41086a28020041ffffffff0371450d00200a41046a28020010290b200a41106a210a200c41706a220c0d000b0b0240200d41086a280200450d00200d28020410290b200d411c6a210a0240200d41146a280200450d00200d28021010290b200a210d200a200b470d000b0b200141086a280200450d05200128020410290c050b2009450d040240200141046a2d0000220a41024b0d00024002400240200a0e03000102000b2001410c6a280200450d07200141086a28020010290c070b0240200141146a280200220c450d002001410c6a280200210a200c410c6c210c03400240200a280200220d450d00200a41046a280200450d00200d10290b200a410c6a210a200c41746a220c0d000b0b200141106a280200450d06200128020c10290c060b0240200141146a280200220a450d002001410c6a2802002204200a4104746a210503402004220b41106a21040240200b280204220a450d000240200b410c6a280200220c450d00200c410c6c210c03400240200a280200220d450d00200a41046a280200450d00200d10290b200a410c6a210a200c41746a220c0d000b0b200b41086a280200450d00200b28020410290b20042005470d000b0b200141106a280200450d05200128020c10290c050b2001410c6a280200450d04200141086a28020010290c040b2013450d030240200141086a280200450d00200141046a28020010290b0240200141146a280200220a450d00200141186a280200450d00200a10290b200141246a280200450d03200141206a28020010290c030b20011088030c020b410121100b2000411a3a0000024020012d0000220a410e4b0d0002400240024002400240024002400240024002400240024002400240200a0e0f0001020304050607080e090a0b0c0d000b200c450d0e200141086a280200450d0e200141046a28020010290c0e0b2007450d0d0240200141086a280200450d00200141046a28020010290b200141146a280200450d0d200141106a28020010290c0d0b200d450d0c02402001410c6a280200220c450d00200141046a280200210a200c410474210c03400240200a41046a280200450d00200a28020010290b200a41106a210a200c41706a220c0d000b0b200141086a280200450d0c200128020410290c0c0b200b450d0b02402001410c6a280200220c450d00200141046a280200210a200c41286c210c03400240200a41046a280200450d00200a28020010290b0240200a41106a280200450d00200a410c6a28020010290b200a41286a210a200c41586a220c0d000b0b200141086a280200450d0b200128020410290c0b0b2008450d0a200141086a280200450d0a200141046a28020010290c0a0b2009450d09200141086a280200450d09200141046a28020010290c090b2004450d08200141086a280200450d08200141046a28020010290c080b2005450d0702402001410c6a280200220a450d00200141046a280200220d200a4104746a210b03400240200d280208220c450d00200d280200210a200c410474210c03400240200a2d00004109470d00200a41086a28020041ffffffff0371450d00200a41046a28020010290b200a41106a210a200c41706a220c0d000b0b200d41106a210a0240200d41046a280200450d00200d28020010290b200a210d200a200b470d000b0b200141086a280200450d07200128020410290c070b2013450d0602402001410c6a280200220c450d00200141046a280200210a200c41146c210c03400240200a41046a280200450d00200a28020010290b200a41146a210a200c416c6a220c0d000b0b200141086a280200450d06200128020410290c060b2006450d0502402001410c6a280200220a450d00200141046a280200220d200a411c6c6a210b03400240200d410c6a280200220c450d00200d280204210a200c410474210c03400240200a2d00004109470d00200a41086a28020041ffffffff0371450d00200a41046a28020010290b200a41106a210a200c41706a220c0d000b0b0240200d41086a280200450d00200d28020410290b200d411c6a210a0240200d41146a280200450d00200d28021010290b200a210d200a200b470d000b0b200141086a280200450d05200128020410290c050b2002450d0402402001410c6a280200220a450d00200141046a280200220d200a41186c6a210b03400240200d41046a280200450d00200d28020010290b0240200d41146a280200220c450d00200d28020c210a200c410474210c03400240200a2d00004109470d00200a41086a28020041ffffffff0371450d00200a41046a28020010290b200a41106a210a200c41706a220c0d000b0b200d41186a210a0240200d41106a280200450d00200d28020c10290b200a210d200a200b470d000b0b200141086a280200450d04200128020410290c040b2011450d0302402001410c6a280200220a450d00200141046a280200220d200a411c6c6a210b03400240200d410c6a280200220c450d00200d280204210a200c410474210c03400240200a2d00004109470d00200a41086a28020041ffffffff0371450d00200a41046a28020010290b200a41106a210a200c41706a220c0d000b0b0240200d41086a280200450d00200d28020410290b200d411c6a210a0240200d41146a280200450d00200d28021010290b200a210d200a200b470d000b0b200141086a280200450d03200128020410290c030b2012450d020240200141046a2d0000220a41024b0d00024002400240200a0e03000102000b2001410c6a280200450d05200141086a28020010290c050b0240200141146a280200220c450d002001410c6a280200210a200c410c6c210c03400240200a280200220d450d00200a41046a280200450d00200d10290b200a410c6a210a200c41746a220c0d000b0b200141106a280200450d04200128020c10290c040b0240200141146a280200220a450d002001410c6a2802002204200a4104746a210503402004220b41106a21040240200b280204220a450d000240200b410c6a280200220c450d00200c410c6c210c03400240200a280200220d450d00200a41046a280200450d00200d10290b200a410c6a210a200c41746a220c0d000b0b200b41086a280200450d00200b28020410290b20042005470d000b0b200141106a280200450d03200128020c10290c030b2001410c6a280200450d02200141086a28020010290c020b2010450d010240200141086a280200450d00200141046a28020010290b0240200141146a280200220a450d00200141186a280200450d00200a10290b200141246a280200450d01200141206a28020010290c010b20011088030b200341e0006a24000b13002000410136020420004198f8c2003602000b3400200041f7fbc20036020420004100360200200041146a4102360200200041106a4180fcc200360200200041086a42093702000b2f01017f02404101102722020d0041014101102a000b200042818080801037020420002002360200200241003a00000b130020004101360204200041b4fec2003602000b3101017f02404108102722020d0041084101102a000b20004288808080800137020420002002360200200242b9063700000b130020004101360204200041d881c3003602000b3400200041e182c30036020420004100360200200041146a4103360200200041106a41ec82c300360200200041086a420a3702000bb00a02067f017e230041106b220324002003200136020c2003410c6a200210300240024002400240024002400240024002402001450d00200141c8006c2104200241086a2101200241046a210503400240024020002d00004101460d0002400240200528020020012802002206460d00200228020021070c010b200641016a22072006490d0c20064101742208200720072008491b22084100480d0c0240024020060d002008102721070c010b200228020020062008102821070b2007450d052002200736020020052008360200200128020021060b2001200641016a360200200720066a41003a0000200041086a29030021090240024020052802002207200128020022066b4108490d00200228020021070c010b200641086a22082006490d0c20074101742206200820082006491b22064100480d0c0240024020070d002006102721070c010b200228020020072006102821070b2007450d062002200736020020052006360200200128020021060b2001200641086a360200200720066a20093700000c010b02400240200528020020012802002206460d00200228020021070c010b200641016a22072006490d0b20064101742208200720072008491b22084100480d0b0240024020060d002008102721070c010b200228020020062008102821070b2007450d062002200736020020052008360200200128020021060b2001200641016a360200200720066a41013a00000240024020052802002207200128020022066b4120490d00200228020021070c010b200641206a22082006490d0b20074101742206200820082006491b22064100480d0b0240024020070d002006102721070c010b200228020020072006102821070b2007450d072002200736020020052006360200200128020021060b2001200641206a360200200720066a220641186a200041196a290000370000200641106a200041116a290000370000200641086a200041096a2900003700002006200041016a2900003700000240200041216a2d00004101460d0002400240200528020020012802002206460d00200228020021070c010b200641016a22072006490d0c20064101742208200720072008491b22084100480d0c0240024020060d002008102721070c010b200228020020062008102821070b2007450d092002200736020020052008360200200128020021060b2001200641016a360200200720066a41003a00000c010b02400240200528020020012802002206460d00200228020021070c010b200641016a22072006490d0b20064101742208200720072008491b22084100480d0b0240024020060d002008102721070c010b200228020020062008102821070b2007450d092002200736020020052008360200200128020021060b2001200641016a360200200720066a41013a00000240024020052802002207200128020022066b4120490d00200228020021070c010b200641206a22082006490d0b20074101742206200820082006491b22064100480d0b0240024020070d002006102721070c010b200228020020072006102821070b2007450d0a2002200736020020052006360200200128020021060b2001200641206a360200200720066a220641186a200041226a220741186a290000370000200641106a200741106a290000370000200641086a200741086a290000370000200620072900003700000b200041c8006a2100200441b87f6a22040d000b0b200341106a24000f0b20084101102a000b20064101102a000b20084101102a000b20064101102a000b20084101102a000b20084101102a000b20064101102a000b102b000bf10703037f047e067f23002202210320024180026b416071220224002001411c6a22042902002105200420022903b801370200200141146a22042902002106200420022903b0013702002001410c6a22042902002107200420022903a801370200200241003a00a00120012902042108200120022903a00137020420022005370338200220063703302002200737032820022008370320200141246a2d00002109200241a0016a41176a22042005370000200241a0016a41106a220a2002290031370300200241a0016a41086a220b2002290029370300200220022900213703a00102402008a741ff01714101460d0020004100360220200324000f0b200241176a2004290000370000200241106a200a290300370300200241086a200b290300370300200220022903a001370300024002400240411210272204450d00200441106a41002f00f6a2443b0000200441086a41002900eea244370000200441002900e6a24437000020044112413210282204450d0120042002290300370012200420093a0031200441296a200241176a290000370000200441226a200241106a2903003700002004411a6a200241086a290300370000200241a0016a41186a220a4200370300200241a0016a41106a220b4200370300200241a0016a41086a220c4200370300200242003703a00120044132200241a0016a100020024180016a41186a200a29030037030020024180016a41106a200b29030037030020024180016a41086a200c290300370300200220022903a00137038001200241003602a00120024180016a4120200241a0016a1005210b20022802a001220a417f460d022002200a3602ec012002200b3602e801200241f0016a200241e8016a102d0240024020022802f001220c450d00200241f8016a280200210d20022802f401210e200241206a200241e8016a10940320022d00204102470d01200e450d00200c10290b418f89c3004133104e000b200241a0016a200241206a41017241c10010ce041a200241206a200241a0016a41c30010ce041a0240200a450d00200b10290b200241a0016a200241206a41c30010ce041a200241206a200241a0016a41c10010ce041a200141246a200241e0006a2d00003a00002001411c6a200241d8006a290000370000200141146a200241d0006a2900003700002001410c6a200241206a41286a2900003700002001200229004037000420002002290300370000200041086a200241086a290300370000200041106a200241106a290300370000200041176a200241176a290000370000200041286a200d3602002000200e3602242000200c360220200020093a001f20041029200324000f0b41124101102a000b41324101102a000b41b6b7c30041d700104e000be90703067f017e027f230041a0016b22022400200241003a00800120024180016a2001280200220320012802042204410047220510ce041a024002400240024020042005490d002001200420056b22063602042001200320056a22053602000240024002402004450d0020022d008001220441014b0d00410021030240024020040e020100010b20024180016a2006412020064120491b22046a41004100412020046b2004411f4b1b10cd041a20024180016a2005200410ce041a2001200620046b22073602042001200520046a22053602002006411f4d0d01200241c0006a41086a20024180016a41086a2900002208370300200241206a41186a20024180016a41186a290000370300200241206a41106a20024180016a41106a290000370300200241206a41086a2008370300200220022900800122083703402002200837032041012103200721060b200241186a200241206a41186a290300370300200241106a200241206a41106a290300370300200241086a200241206a41086a29030037030020022002290320370300200241003a00800120024180016a20052006410047220410ce041a20062004490d042001200620046b22073602042001200520046a22043602002006450d0520022d008001220541014b0d054100210620050e020201020b200041023a00000c050b20024180016a2007412020074120491b22056a41004100412020056b2005411f4b1b10cd041a20024180016a2004200510ce041a2001200720056b3602042001200420056a3602002007411f4d0d03200241c0006a41086a20024180016a41086a2900002208370300200241206a41186a20024180016a41186a290000370300200241206a41106a20024180016a41106a290000370300200241206a41086a20083703002002200229008001220837034020022008370320410121060b200241e0006a41186a2201200241206a41186a290300370300200241e0006a41106a2204200241206a41106a290300370300200241e0006a41086a2205200241206a41086a29030037030020024180016a41086a2207200241086a29030037030020024180016a41106a2209200241106a29030037030020024180016a41186a220a200241186a290300370300200220022903203703602002200229030037038001200020033a0000200041216a20063a00002000200229038001370001200041096a2007290300370000200041116a2009290300370000200041196a200a290300370000200041226a20022903603700002000412a6a2005290300370000200041326a20042903003700002000413a6a20012903003700000c030b20052004103e000b20042006103e000b200041023a00000b200241a0016a24000ba72207017f027e077f017e017f017e107f230041d0066b22032400200241d8006a2903002104200241d0006a290300210520022802002106200341c4006a200241046a41cc0010ce041a20034190016a200341c4006a41046a41c80010ce041a2001280200210720034190036a41186a2208200341c8016a29030037030020034190036a41106a2209200341c0016a29030037030020034190036a41086a220a200341b8016a290300370300200320032903b00137039003024002400240024041c80010272202450d002002420037030020022006360220200241186a4200370300200241106a4200370300200241086a42003703002002200341b0016a220b2902003702242002412c6a200b41086a290200370200200241346a200b41106a2902003702002002413c6a200b41186a290200370200200341286a41b18ac0004116108601200341186a2003290330200341286a41106a290300427f420010d404200341086a20052004200329031842002003280228220c1b220d4201200d420156200341186a41086a2903004200200c1b220d420052200d501b220c1b200d4200200c1b10d404200341e0026a41086a200a290300370300200341e0026a41106a2009290300370300200341e0026a41186a200829030037030020032003290390033703e0022003290308210d0240024002400240200741046a28020020072802082208460d00200728020021090c010b200841016a22092008490d012008410174220a20092009200a491b220aad42d0007e2204422088a70d012004a7220c4100480d010240024020080d00200c102721090c010b2007280200200841d0006c200c102821090b2009450d0220072009360200200741046a200a360200200728020821080b2009200841d0006c6a22084200370310200842003703082008200d37030020082002360220200820032903e00237022c200841186a4200370300200841246a428180808010370200200841346a200341e0026a41086a22022903003702002008413c6a200341e0026a41106a220a290300370200200841c4006a200341e0026a41186a22082903003702002007200728020841016a3602082001280208210c200341a0026a41186a200b41186a290000370300200341a0026a41106a200b41106a290000370300200341a0026a41086a200b41086a2900003703002003200b2900003703a002024002400240200c2802002201418883c000460d00200c28020421090c010b4100210920034190036a410041e00210cd041a20034188036a220b410036020020034180036a2207420037030020084200370300200a420037030020024200370300200342003703e00241940310272201450d01200141003b010620014100360200200141086a20034190036a41e00210ce041a20014190036a200b28020036020020014188036a200729030037020020014180036a200341f8026a290300370200200141f8026a200341f0026a290300370200200141f0026a200341e0026a41086a290300370200200120032903e0023702e802200c4100360204200c20013602000b02400340200141086a2108200141066a210e20012f0106220a41057421024100210b0240024003402002450d01200341a0026a2008412010d0042207450d02200241606a2102200b41016a210b200841206a21082007417f4a0d000b200b417f6a210a0b2009450d022009417f6a21092001200a4102746a4194036a28020021010c010b0b2001200b4102746a41e8026a20063602000c060b200341d8016a41186a200341a0026a41186a2202290300220d370300200341d8016a41106a200341a0026a41106a22082903002204370300200341d8016a41086a200341a0026a41086a220b2903002205370300200320032903a002220f3703d801200c200c28020841016a3602082002200d37030020082004370300200b20053703002003200f3703a0020240024002400240200e2f01002209410b490d0020034190036a410041e00210cd041a20034188036a2202410036020020034180036a22084200370300200341e0026a41186a4200370300200341e0026a41106a4200370300200341e0026a41086a4200370300200342003703e00241940310272210450d03201041003b010620104100360200201041086a20034190036a41e00210ce04210b20104190036a200228020036020020104188036a200829030037020020104180036a200341e0026a41186a290300370200201041f8026a200341e0026a41106a290300370200201041f0026a200341e0026a41086a290300370200201020032903e0023702e802200320012f00c8013b01dc022003200141ca016a2d00003a00de02200141cb016a2800002111200141cf016a2800002112200141d3016a2800002113200141d7016a28000021142003200141e0016a2900003700cd02200320012900db013703c8022001280280032115200b200141e8016a20012f010641796a220241057410ce04210b201041e8026a20014184036a200241027410ce042107200141063b0106201020023b0106200320032f01dc023b01c402200320032d00de023a00c602200320032903c8023703e002200320032900cd023700e502200a4107490d01201041066a210e200b200a417a6a22094105746a200b200a41796a22084105746a220b200241ffff037120086b41057410cf041a200b41186a200341a0026a41186a290300370000200b41106a200341a0026a41106a290300370000200b41086a200341a0026a41086a290300370000200b20032903a002370000200720094102746a210b200720084102746a21020c020b200141086a2207200a41016a220c4105746a2007200a4105746a22072009200a6b41057410cf041a200741186a2002290300370000200741106a2008290300370000200741086a200b290300370000200720032903a002370000200141e8026a2202200c4102746a2002200a4102746a220220012f0106200a6b41027410cf041a20022006360200200120012f010641016a3b01060c080b200141086a2202200a41016a22084105746a2002200a4105746a2202200e2f0100200a6b41057410cf041a200241186a200341a0026a41186a290300370000200241106a200341a0026a41106a290300370000200241086a200341a0026a41086a290300370000200220032903a002370000200141e8026a220b200a4102746a2102200b20084102746a210b200a21080b200b2002200e2f010020086b41027410cf041a20022006360200200e200e2f010041016a3b0100200341c0026a41026a221620032d00c60222023a00002003418c026a41026a221720023a0000200320032900e50237009502200320032903e00237039002200320032f01c40222023b01c00220032003290095023700fd0120032003290390023703f801200320023b018c0220012802002209450d0520012f0104210e20034190036a41027221180340201620172d00003a0000200320032f018c023b01c002200320032903f8013703a002200320032900fd013700a502200e41ffff037121010240024002400240024020092f01062202410b490d002018410041be0310cd041a41c40310272207450d0320074100360200200741046a20034190036a41c00310ce041a200320092f00c8013b01dc022003200941ca016a2d00003a00de022003200941db016a2900003703c8022003200941e0016a2900003700cd02200941cb016a2800002119200941cf016a280000211a200941d3016a280000211b200941d7016a280000211c20094180036a280200211d200741086a200941e8016a20092f0106220841796a220241057410ce04211e200741e8026a20094184036a200241027410ce04211f20074194036a200941b0036a2008417a6a220a41027410ce042106200941063b0106200720023b01060240200a450d00410021022006210803402008280200220b20023b0104200b2007360200200841046a2108200a200241016a2202470d000b0b200320032d00de0222023a00c602200320032f01dc0222083b01c402200320032903c8023703e002200320032900cd023700e50220034190026a41026a220a20023a0000200320083b019002200320032903e00237039003200320032900e50237009503200e41ffff037122084107490d01201e2001417a6a220b4105746a201e200141796a22024105746a220820072f010620026b41057410cf041a200841186a20032900a5023700002008201436000f2008201336000b2008201236000720082011360003200841026a20162d00003a0000200820032f01c0023b0000200820032903a002370013201f200b41027422086a201f20024102746a220e20072f0106221120026b41027410cf041a200e20153602002007201141016a220e3b01062001410274221120066a416c6a200620086a2208200e41ffff03712201200b6b41027410cf041a200820103602002001200b490d02200720116a41fc026a210803402008280200220b200241016a22023b0104200b2007360200200841046a210820022001490d000c030b0b200941086a2208200141016a220b4105746a200820014105746a2208200220016b41057410cf041a200841186a20032900a5023700002008201436000f2008201336000b2008201236000720082011360003200841026a200341c0026a41026a2d00003a0000200820032f01c0023b0000200820032903a002370013200941e8026a2202200b41027422086a2002200141027422076a220220092f0106220a20016b41027410cf041a200220153602002009200a41016a22023b0106200720094194036a22016a41086a200120086a2208200241ffff03712207200b6b41027410cf041a20082010360200200e41ffff037120074f0d0b2009200b417f6a22024102746a4198036a210803402008280200220b200241016a22023b0104200b2009360200200841046a210820022007490d000c0c0b0b200941086a2202200141016a220e4105746a200220014105746a220220092f010620016b41057410cf041a200241186a20032900a5023700002002201436000f2002201336000b2002201236000720022011360003200241026a20162d00003a0000200220032f01c0023b0000200220032903a002370013200941e8026a220b200e41027422066a200b200141027422026a220b20092f0106221120016b41027410cf041a200b20153602002009201141016a220b3b0106200220094194036a22116a41086a201120066a2206200b41ffff0371220b200e6b41027410cf041a200620103602002008200b4f0d00200920026a4198036a2102034020022802002208200141016a22013b010420082009360200200241046a2102200b2001470d000b0b2017200a2d00003a0000200320032f0190023b018c0220032003290390033703f80120032003290095033700fd01200928020022020d0120192111201c2114201b2113201a211220072110201d21150c080b41c4034104102a000b20092f0104210e20192111201c2114201b2113201a211220022109201d2115200721100c000b0b4194034104102a000b4194034104102a000b102b000b200c4108102a000b41c8004108102a000b20034190036a410272410041be0310cd041a41c40310272202450d0120024100360200200241046a20034190036a41c00310ce041a2002200c280200220836029403200c2002360200200c200c28020441016a360204200841003b010420082002360200200220022f0106220b4105746a220841086a20032f018c023b00002008410a6a2003418c026a41026a2d00003a0000200841176a2014360000200841136a20133600002008410f6a20123600002008410b6a20113600002008411b6a20032903f801370000200841206a20032900fd0137000020024194036a200b41016a22084102746a20103602002002200b4102746a41e8026a2015360200200220083b0106201020083b0104201020023602000b200020034190016a41c80010ce041a200341d0066a24000f0b41c4034104102a000bcc0b03087f017e037f230041306b22022400200241186a41086a220342003703002002420037031841cdf8c4004116200241186a1004200241086a41086a20032903003703002002200229031837030820024100360218200241086a4110200241186a100521030240024002400240024002400240024020022802182204417f460d002003450d002002200436022c20022003360228200241186a200241286a102d20022802182205450d02200241206a2802002106200228021c21072004450d01200310290c010b4101210541002106410021070b200520064105746a210820052103410021060240024003400240200820036b41e0004b0d0020032008460d03034020002003460d03200620032000412010d00422044100476a21062004450d032008200341206a2203470d000c040b0b20032000460d01200620032000412010d00422044100476a21062004450d01200341206a22042000460d01200620042000412010d00422044100476a21062004450d01200341c0006a22042000460d01200620042000412010d00422044100476a21062004450d01200341e0006a22042000460d01200620042000412010d00422044100476a210620034180016a210320040d000b0b200241186a41086a220342003703002002420037031841bec7c5004119200241186a1004200241086a41086a20032903003703002002200229031837030820024100360218200241086a4110200241186a1005210002400240024020022802182203417f460d002000450d00200220003602282002200336022c20024100360218200241186a20002003410420034104491b220410ce041a2002200320046b36022c2002200020046a3602280240200341034d0d0020022802182103200241186a200241286a1045200228021822090d020b418f89c3004133104e000b410421094100210041002108410021030c010b200229021c210a20001029200a422088a72100200aa721080b02400240200320016a220420034f0d002008210b200321040c010b02400240200020064d0d002008210b0c010b02400240200820006b200641016a2000200020064d1b220c20006b220d490d002008210b0c010b2000200d6a22032000490d092008410174220b20032003200b491b220b41ffffffff0371200b470d09200b41027422034100480d090240024020080d002003102721090c010b200920084102742003102821090b2009450d050b200920004102746a210302400240200d4102490d002000417f73200c6a2100034020034100360200200341046a21032000417f6a22000d000b200c417f6a21000c010b200d450d010b20034100360200200041016a21000b200020064d0d04200920064102746a2203200328020020016a3602000b200241186a41086a220342003703002002420037031841bec7c5004119200241186a1004200241086a41086a2003290300370300200220022903183703082002410036022020024201370318410410272203450d042003200436000020024284808080c00037021c2002200336021820022000360228200241286a200241186a10300240024020000d0020022802202101200228021c2108200228021821060c010b2000410274210d4100200228022022036b2100200228021c21082009210403402004280200210c02400240200820006a4104490d00200228021821060c010b200341046a22062003490d0920084101742201200620062001491b22014100480d090240024020080d002001102721060c010b200228021820082001102821060b2006450d082002200136021c20022006360218200121080b200441046a21042002200341046a2201360220200620036a200c3600002000417c6a210020012103200d417c6a220d0d000b0b200241086a411020062001100302402008450d00200610290b200b450d00200910290b02402007450d00200510290b200241306a24000f0b418f89c3004133104e000b20034104102a000b41e4f8c400200620001037000b41044101102a000b20014101102a000b102b000bde0605017f017e047f027e017f230041d0006b2201240042002102200141286a41086a220342003703002001420037032841aa8dc300410d200141286a1004200141186a41086a2003290300370300200120012903283703184100210320014100360228200141186a4110200141286a100521040240024002400240024020012802282205417f460d002001200536020c20012004360208200141286a200141086a104320012802282206450d02200129022c210202402005450d00200410290b2002422088a721032002a721050c010b41042106410021050b200141286a41206a200041206a280200360200200141286a41186a200041186a290200370300200141286a41106a200041106a290200370300200141286a41086a200041086a29020037030020012000290200370328024020032005470d00024020032002a7470d00200341016a22002003490d0420034101742205200020002005491bad220742247e2208422088a70d042008a722004100480d040240024020030d002000102721060c010b2006200341246c2000102821060b2006450d0320024280808080708320078421020b2002422088a721030b2006200341246c22096a22002001290328370200200041206a200141286a41206a280200360200200041186a200141286a41186a290300370200200041106a200141286a41106a290300370200200041086a200141286a41086a22002903003702002001200242ffffffff0f83200341016a2205ad4220868437020c20012006360208200042003703002001420037032841aa8dc300410d200141286a1004200141186a41086a2000290300370300200120012903283703182001411036022c2001200141186a360228200141086a200141286a105c2002a72104024020052003490d00200941246a21002006210303400240024020032d0000220541034b0d0002400240024020050e0404000102040b2003410c6a280200450d03200341086a28020010290c030b2003410c6a280200450d02200341086a28020010290c020b2003410c6a280200450d01200341086a28020010290c010b200341086a280200450d00200341046a28020010290b200341246a21032000415c6a22000d000b0b02402004450d00200610290b200141d0006a24000f0b418f89c3004133104e000b20004104102a000b102b000bd20601077f230041106b22022400024002400240024002400240024020002802704101460d0002400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490d0720034101742205200420042005491b22054100480d070240024020030d002005102721040c010b200128020020032005102821040b2004450d0320012004360200200141046a2005360200200141086a28020021030b200141086a2205200341016a360200200420036a41003a00002000280274210602400240200141046a2802002204200528020022036b4104490d00200128020021040c010b200341046a22052003490d0720044101742203200520052003491b22034100480d070240024020040d002003102721040c010b200128020020042003102821040b2004450d0420012004360200200141046a2003360200200141086a28020021030b200141086a200341046a360200200420036a20063600000c010b02400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490d0620034101742205200420042005491b22054100480d060240024020030d002005102721040c010b200128020020032005102821040b2004450d0420012004360200200141046a2005360200200141086a28020021030b200141086a200341016a360200200420036a41013a00000b20002001109d0220002802782103200220004180016a280200220036020c2002410c6a2001103002402000450d0020004105742106200141086a2105200141046a210703400240024020072802002204200528020022006b4120490d00200128020021040c010b200041206a22082000490d0720044101742200200820082000491b22004100480d070240024020040d002000102721040c010b200128020020042000102821040b2004450d062001200436020020072000360200200528020021000b2005200041206a360200200420006a220041186a200341186a290000370000200041106a200341106a290000370000200041086a200341086a29000037000020002003290000370000200341206a2103200641606a22060d000b0b200241106a24000f0b20054101102a000b20034101102a000b20054101102a000b20004101102a000b102b000be70101017f024020002d0000417b6a220141064b0d00024002400240024020010e0700040401020403000b200041086a2d00004101470d03200041146a280200450d03200041106a28020010290c030b200041046a2d00004103470d0202402000410c6a280200450d00200041086a28020010290b200041186a280200450d02200041146a28020010290c020b200041046a2802000d012000410c6a280200450d01200041086a28020010290c010b200041086a2d00004105490d00200041306a280200450d002000412c6a28020010290b0240200041fc006a280200450d00200028027810290b0b130020004106360204200041f890c3003602000b34002000418d97c30036020420004100360200200041146a410f360200200041106a419497c300360200200041086a42063702000b950101057f230041206b22022400200241186a22034200370300200241106a22044200370300200241086a220542003703002002420037030002404120102722060d0041204101102a000b20062002290300370000200042a0808080800437020420002006360200200641186a2003290300370000200641106a2004290300370000200641086a2005290300370000200241206a24000b7401027f230041106b22022400200241003602082002420137030002404101102722030d0041014101102a000b200341003a00002002428180808010370204200220033602002002410036020c2002410c6a20021030200041086a200228020836020020002002290300370200200241106a24000b130020004100360204200041b8d6c5003602000b980104037f017e017f017e230041106b220224002002410036020c200141102002410c6a10052103024002400240200228020c2204417f470d00420021050c010b20024200370300200220032004410820044108491b10ce042106200441074d0d01200629030021072003102920014110100c420121050b2000200537030020002007370308200241106a24000f0b418f89c3004133104e000b0a0041c88ac3001058000b0a0041b88bc3001058000bf30c020b7f067e23004180016b22082400024002400240024002400240200728021c41016a220941004c0d002007411c6a210a2007200936021c200741246a280200210b200741206a220c210d024002400340200d280200220e41086a210f200e2f01062210410574210d41002111024002400340200d450d012004200f412010d0042212450d02200d41606a210d201141016a2111200f41206a210f2012417f4a0d000b2011417f6a21100b200b450d02200b417f6a210b200e20104102746a41880b6a210d0c010b0b200e201141e0006c6a220d41e8026a280200450d00200d41f8026a2903002113200d41f0026a29030021140c010b200841286a2007412c6a2802002004200741306a28020028021c110200200841306a2903002113200728021c2109200829032821140b20072009417f6a36021c200141186a29030021152007280250210d20012903102116024002400240024041004101410220142013842217501b20021b0e03010200010b200d41a8016a210d0c020b200d4188016a210d0c010b200d4198016a210d0b20162015844200510d01200841186a200d290300200d41086a2903002016201510d40420014200200129030822152008290318427f200841186a41086a290300501b7d22162016201556220d1b3703080240200d450d0041c6b5c300210d4122210f0c060b200a28020041016a220141004c0d022007200136021c2007280224210b024002400340200c280200220e41086a210f200e2f01062210410574210d41002111024002400340200d450d012003200f412010d0042212450d02200d41606a210d201141016a2111200f41206a210f2012417f4a0d000b2011417f6a21100b200b450d02200b417f6a210b200e20104102746a41880b6a210c0c010b0b200e201141e0006c6a220d41e8026a280200450d00200d41f8026a2903002115200d41f0026a29030021160c010b200841086a2007412c6a2802002003200741306a28020028021c110200200841106a2903002115200728021c2101200829030821160b200a2001417f6a3602000240201620057d2218201656201520067d2016200554ad7d221620155620162015511b4101470d0041e8b5c300210d411d210f0c060b024020174200520d002007280250220d290378200556200d4180016a290300221520065620152006511b450d004185b6c300210d411f210f0c060b2008200341022018201610910102402008280200220d450d002008280204210f0c060b0240201420057c2217201454220d201320067c200dad7c221520135420152013511b450d0041a4b6c300210d412d210f0c060b4100210d024020032004470d000c060b024020032004412010d0040d000c060b200a20032018201610f401200a20042017201510f401200841e0006a41086a200341086a290000370300200841e0006a41106a200341106a290000370300200841e0006a41186a200341186a290000370300200841c0006a41086a200441086a290000370300200841c0006a41106a200441106a290000370300200841c0006a41186a200441186a290000370300200820032900003703602008200429000037034002400240200741c0006a280200220f2007413c6a280200460d00200728023821110c010b200f41016a220d200f490d05200f4101742211200d200d2011491b220dad42e8007e2215422088a70d052015a722124100480d0502400240200f0d002012102721110c010b2007280238200f41e8006c2012102821110b2011450d04200720113602382007413c6a200d3602002007280240210f0b4100210d2011200f41e8006c6a220f41003a0000200f2008290360370001200f41096a200841e0006a41086a290300370000200f41116a200841e0006a41106a290300370000200f41196a200841e0006a41186a290300370000200f41216a2008290340370000200f41296a200841c0006a41086a290300370000200f41316a200841c0006a41106a290300370000200f41396a200841c0006a41186a290300370000200f41c4006a2008413c6a280000360000200f41c1006a2008280039360000200f41e0006a4100360200200f4201370358200f41d0006a2006370300200f41c8006a20053703002007200728024041016a3602400c050b41d8a8c1004118200841e0006a4180a9c10010a201000b41fcecc2001058000b41d8a8c1004118200841e0006a4180a9c10010a201000b20124108102a000b102b000b2000200f3602042000200d36020020084180016a24000bc50101057f230041306b220124002000410c6a28020021022000280204210302400240200041086a28020022040d00200321000c010b2004210520032100034020002802880b21002005417f6a22050d000b0340200320032f01064102746a41880b6a28020021032004417f6a22040d000b0b200141246a20032f0106360200200141206a41003602002001411c6a20033602002001200236022820014100360218200142003703102001200036020c20014100360208200141086a10d901200141306a24000b85e3010b047f017e037f017e097f017e037f097e027f0a7e2e7f230041c0176b2202240041d7c7c5004113108a02210302400240024002400240024002402001417f6a2204410670450d002003200341ff017141024771450d010b200241f80b6a41086a22034200370300200242003703f80b41abccc1004112200241f80b6a100420024198106a41086a2003290300370300200220022903f80b37039810200241003602b80d20024198106a4110200241b80d6a100521030240024002400240024020022802b80d2201417f460d002003450d00200220013602b40b200220033602b00b200241b80d6a200241b00b6a102d20022802b80d2205450d0220022902bc0d21062001450d01200310290c010b41012105420021060b410021070240024002402006422088a7220141057422030d0041082108410021090c010b20034105752209ad42d0007e220a422088a70d09200aa7220b4100480d09200b10272208450d010b2006a7210c0240200520036a2005460d002001410574210b20024198106a41206a2103410021072008210d200521010340200241b00b6a41086a220e200141086a290000370300200241b00b6a41106a220f200141106a290000370300200241b00b6a41186a2210200141186a290000370300200220012900003703b00b200241b80d6a200241b00b6a104d20024198106a41186a201029030037030020024198106a41106a200f29030037030020024198106a41086a200e290300370300200320022903b80d370300200341086a200241b80d6a41086a290300370300200341106a200241b80d6a41106a290300370300200341186a200241b80d6a41186a290300370300200341206a200241b80d6a41206a290300370300200341286a200241b80d6a41286a290300370300200220022903b00b37039810200741016a2107200d20024198106a41d00010ce0441d0006a210d200141206a2101200b41606a220b0d000b0b0240200c450d00200510290b200241f80b6a41086a22034200370300200242003703f80b41bec7c5004119200241f80b6a1004200241b80d6a41086a2003290300370300200220022903f80b3703b80d2002410036029810200241b80d6a411020024198106a100521030240024002402002280298102201417f460d002003450d00200220033602b00b200220013602b40b200241003602981020024198106a20032001410420014104491b220b10ce041a20022001200b6b3602b40b20022003200b6a3602b00b0240200141034d0d00200228029810210f20024198106a200241b00b6a104520022802981022110d020b418f89c3004133104e000b410421114100210e410021124100210f0c010b200229029c10210620031029200241b80d6a4110100c2006422088a7210e2006a721120b200241800a6a41ceecc200410d10940120022903880a210620022802800a2103200241f0096a41cfa2c400411710940120022903f809210a20022802f0092101200241f80b6a41086a220c4200370300200242003703f80b41cfa2c4004117200241f80b6a1004200241b80d6a41086a2213200c290300370300200220022903f80b3703b80d20022006420020031b220637039810200241b80d6a411020024198106a4108100302402006200a420020011b7d221450450d00410021150c040b200c4200370300200242003703f80b41cdf8c4004116200241f80b6a10042013200c290300370300200220022903f80b3703b80d2002410036029810200241b80d6a411020024198106a100521030240024002402002280298102201417f460d002003450d00200220013602b40b200220033602b00b20024198106a200241b00b6a102d2002280298102216450d02200241a0106a280200210d200228029c1021172001450d01200310290c010b410121164100210d410021170b200241d8096a41c8f9c4004111108601200241d8096a41106a290300211820022903e009211920022802d8092103200241c0096a41b18ac0004116108601200241b0096a20022903c809420020022802c00922011b221a200241c0096a41106a290300420020011b428094ebdc03420010d404200241a0096a20022903b0092206200241b0096a41086a290300220a4280ec94a37c427f10d30420024190096a2019420020031b2018420020031b200dad420010d304201442ffffffff0f8342ffffffff0f2014428080808010541b211b20022903a009201a7c211420024190096a41086a290300211c4100210b41d0dec1002101200229039009211d02400240034002404190e1c100200122036b41304b0d0020034190e1c100460d03200220032802002201360298102002418094ebdc0336029c1020024180096a2006200a20024198106a2001418094ebdc034b4102746a3502002218420010d3042002290380092219201820147e428094ebdc038042ffffffff0f837c2218201d5a20024180096a41086a2903002018201954ad7c2218201c5a2018201c511b0d03200241f0086a41086a21100c020b200220032802002201360298102002418094ebdc0336029c10200241e0086a2006200a20024198106a2001418094ebdc034b4102746a3502002218420010d30420022903e0082219201820147e428094ebdc038042ffffffff0f837c2218201d5a200241e0086a41086a2903002018201954ad7c2218201c5a2018201c511b0d02200220032802102201360298102002418094ebdc0336029c10200241d0086a2006200a20024198106a2001418094ebdc034b4102746a3502002218420010d304024020022903d0082219201820147e428094ebdc038042ffffffff0f837c2218201d5a200241d0086a41086a2903002018201954ad7c2218201c5a2018201c511b450d002003210b0c030b200220032802202201360298102002418094ebdc0336029c10200241c0086a2006200a20024198106a2001418094ebdc034b4102746a3502002218420010d304024020022903c0082219201820147e428094ebdc038042ffffffff0f837c2218201d5a200241c0086a41086a2903002018201954ad7c2218201c5a2018201c511b450d00200341106a210b0c030b200220032802302201360298102002418094ebdc0336029c10200241b0086a2006200a20024198106a2001418094ebdc034b4102746a3502002218420010d304200341c0006a2101200341306a210b20022903b0082219201820147e428094ebdc038042ffffffff0f837c2218201d54200241b0086a41086a2903002018201954ad7c2218201c542018201c511b0d000b200341206a210b0c010b03404180e1c1002003220b460d01200b41106a21032002200b41106a2802002201360298102002418094ebdc0336029c10200241f0086a2006200a20024198106a2001418094ebdc034b4102746a3502002218420010d30420022903f0082219201820147e428094ebdc038042ffffffff0f837c2218201d5a20102903002018201954ad7c2218201c5a2018201c511b450d000b0b4200211e20024190086a201d201c428094ebdc03420010d40420024180086a200229039008221920024190086a41086a290300221a4280ec94a37c427f10d304200b41d0dec100200b1b2203410c6a2d00002101200341046a280200210b200341086a28020021032002418094ebdc0336029c10200220033602981020024198106a2003418094ebdc034b4102746a35020021182002418094ebdc0336029c102002200b36029810200241f0076a2019201a20024198106a200b418094ebdc034b4102746a350200221f420010d304200241a0086a2006200a2018420010d304200241e0076a420020022903a008220a201820147e428094ebdc038042ffffffff0f837c220620022903f0072218201f200229038008201d7c7e428094ebdc038042ffffffff0f837c22147d22192019200656200241a0086a41086a2903002006200a54ad7c220a200241f0076a41086a2903002014201854ad7c22197d2006201454ad7d2218200a562018200a511b22031b427f200620147c22142014200654220b200a20197c200bad7c2206200a542006200a511b220b1b20011b4200201820031b427f2006200b1b20011b201b420010d304200241d0076a20022903e007200241e0076a41086a29030042e08f860f420010d4040240200d41057422030d00420021200c040b2011200e4102746a2121201620036a2122200241d0076a41086a290300212320022903d0072124200fad21252011210e4200211e420021202016210d024002400340200e2021460d0602400240200e2802002203450d00024002400240024002400240200f450d00200241c0076a202420232025420010d404200241b0076a20022903c0072206200241c0076a41086a290300220a2025420010d304200241a0076a2006200a200f20032003200f4b1bad2214420010d304202420022903b0077d20147e202580210620022903a0072114200241a0076a41086a290300211a411210272203450d01200341106a41002f0088a3443b0000200341086a4100290080a344370000200341002900f8a24437000020034112413210282203450d022003200d2900003700122003412a6a200d41186a290000370000200341226a200d41106a2900003700002003411a6a200d41086a290000370000200241c00a6a41186a22014200370300200241c00a6a41106a220b4200370300200241c00a6a41086a22104200370300200242003703c00a20034132200241c00a6a1000200241b80d6a41186a2001290300370300200241b80d6a41106a200b290300370300200241b80d6a41086a22052010290300370300200220022903c00a3703b80d2002410036029810200241b80d6a412020024198106a10052101200228029810220b417f460d042001450d042002200b36029c10200220013602981020024198076a20024198106a102e200228029807450d0320024180076a20024198106a1053200229038007a7450d0320024180076a41106a290300210a2002290388072119200b450d05200110290c050b41dcf9c4001058000b41124101102a000b41324101102a000b418f89c3004133104e000b420021194200210a0b2003102942002118200242003703c00d200242003703b80d024002402014200642ffffffff0f837c2206201920062019200654200a201a2006201454ad7c221454200a2014511b22031b22267d22272014200a201420031b22287d2006202654ad7d22298450450d00420021060c010b20024198106a200d104d20024198106a41086a29030022064200200229039810220a42015620064200522006501b22031b2106200a420120031b210a20022802b81021100240024020022802c01022030d00200241f8056a200a2006428094ebdc03420010d404200241f8056a41086a290300212a20022903f805212b0c010b2010200341306c6a210b200241f0066a200a2006428094ebdc03420010d404200241d0066a20272029428094ebdc03420010d404200241e0066a20272029428094ebdc03420010d504200241f0066a41086a290300222a420020022903f006222b420156202a420052202a501b22031b2118202b420120031b2119200241d0066a41086a290300211b20022903d006211f20022903e006212c201021030340200241c0066a200a200329030022142014200a56200341086a290300221420065620142006511b22011b2006201420011b2019201810d40420022903c006221a428080808010544100200241c0066a41086a290300501b450d04200241b0066a200a20062019201810d40420022903b0062214428080808010544100200241b0066a41086a290300501b450d0602402014a7450d0020024188066a201f201b201a42ffffffff0f83428094ebdc037e201442ffffffff0f838042ffffffff0f832214420010d30420024198066a200341106a200229038806221a2014202c7e428094ebdc038042ffffffff0f837c221420024188066a41086a2903002014201a54ad7c10d603200241b80d6a20022903980620022903a00620024198066a41106a29030010eb01200341306a2203200b460d020c010b0b41c489c3001058000b200241e8056a200a20022903a81022142014200a5620024198106a41186a290300221420065620142006511b22031b2006201420031b202b4201202b420156202a420052202a501b22031b2214202a420020031b221810d40420022903e8052219428080808010544100200241e8056a41086a290300501b450d02200241d8056a200a20062014201810d40420022903d8052206428080808010544100200241d8056a41086a290300501b450d042006a7450d05200241c8056a20272029428094ebdc03420010d404200241b8056a20022903c805220a200241c8056a41086a29030022144280ec94a37c427f10d304200241a8056a200a2014201942ffffffff0f83428094ebdc037e200642ffffffff0f838042ffffffff0f832206420010d30420022903a805220a2006202720022903b8057c7e428094ebdc038042ffffffff0f837c2218200a54ad2106200241a8056a41086a290300210a024020022802bc10450d00201010290b200a20067c21060b20024190056a200d201820267c220a200620287c200a201854ad7c10d603200241b80d6a20022903900520022903980520024190056a41106a29030010eb01427f202020052903007c201e20022903b80d7c220a201e542203ad7c22062003200620205420062020511b22031b2120427f200a20031b211e0b200e41046a210e200d41206a220d2022470d010c070b0b10a003000b10a103000b41c489c3001058000b418f89c3004133104e000b200b4108102a000b418f89c3004133104e000b02402012450d00201110290b200241b0106a202037030020024198106a41106a201e37030020024198106a41086a41003a0000200241033a00981041b8d6c500410020024198106a108801200241f8046a41b18ac0004116108601200241f8046a41106a2903002106200229038005210a20022802f8042103200241f80b6a41086a22014200370300200242003703f80b41b18ac0004116200241f80b6a1004200241b80d6a41086a2001290300370300200220022903f80b3703b80d2002427f2006420020031b220620207c200a420020031b220a201e7c2214200a542203ad7c220a2003200a200654200a2006511b22031b3703a0102002427f201420031b37039810200241b80d6a411020024198106a411010030240201e202084500d00201d201c84500d0042002106200241b00b6a41086a22034200370300200242003703b00b41b18ac0004116200241b00b6a1004200241b80d6a41086a2003290300370300200220022903b00b3703b80d2002410036029810200241b80d6a411020024198106a100521030240024002400240024002402002280298102201417f470d00420021064200210a0c010b024020030d004200210a0c010b200242003703a010200242003703981020024198106a20032001411020014110491b10ce041a2001410f4d0d01200241a0106a290300210a2002290398102106200310290b2006201d7d2214200656200a201c7d2006201d54ad7d2206200a562006200a511b0d04200241e8046a20142006201d201c10d404200241b8046a200241e8046a41086a29030022064200201e420010d304200241c8046a2020420020022903e804220a420010d304200241d8046a200a4200201e420010d304200642005220204200527120022903c0044200527220022903d00442005272200241d8046a41086a290300220620022903b80420022903c8047c7c2214200654720d0420022903d8042118200241b00b6a41086a22034200370300200242003703b00b41b18ac0004116200241b00b6a1004200241b80d6a41086a2003290300370300200220022903b00b3703b80d2002410036029810200241b80d6a411020024198106a100521032002280298102201417f460d022003450d02200242003703a010200242003703981020024198106a20032001411020014110491b10ce041a2001410f4d0d01200241a0106a290300210a2002290398102106200310290c030b418f89c3004133104e000b418f89c3004133104e000b420021064200210a0b200241b00b6a41086a22014200370300200242003703b00b41b18ac0004116200241b00b6a1004200241b80d6a41086a220b2001290300370300200220022903b00b3703b80d2002427f200a20147c200620187c221a2006542203ad7c221920032019200a542019200a511b22031b3703a0102002427f201a20031b37039810200241b80d6a411020024198106a4110100320024198106a109701200241a8046a20024198106a2006427f85201820031b2206200a427f85201420031b2214108301200241a8046a41086a290300211820022903a804210a20024190046a41b18ac00041161086012006200a7d200a20067d200a2006582018201458201820145122031b220d1b211b201420187d2006200a54ad7d201820147d200a200654ad7d200d1b211f20024190046a41106a2903004200200228029004220d1b21192002290398044200200d1b211a02400240200a200656201820145620031b0d00200b4200370300200242003703b80d41b18ac0004116200241b80d6a10042001200b290300370300200220022903b80d3703b00b200242002019201f7d201a201b54ad7d2206201a201b7d220a201a56200620195620062019511b22031b3703c00d20024200200a20031b3703b80d200241b80d6a21030c010b200241f80b6a41086a22034200370300200242003703f80b41b18ac0004116200241f80b6a100420012003290300370300200220022903f80b3703b00b2002427f2019201f7c201a201b7c220a201a542203ad7c22062003200620195420062019511b22031b3703c00d2002427f200a20031b3703b80d200241b80d6a21030b200241b00b6a41102003411010030b410121152017450d00201610290b20024188046a4189c7c500411210b5012002280288042103200228028c042101200c4200370300200242003703f80b4189c7c5004112200241f80b6a10042013200c290300370300200220022903f80b3703b80d2002200141016a410120031b221636029810200241b80d6a411020024198106a4104100320024180046a419bc7c500412310b501200c4200370300200242003703f80b419bc7c5004123200241f80b6a10042013200c290300370300200220022903f80b3703b80d2002200436029810200241b80d6a411020024198106a41041003024002400240024002400240024002400240024002400240024002400240201641a105490d00200241f80b6a41086a22034200370300200242003703f80b41eac7c5004112200241f80b6a1004200241b80d6a41086a2003290300370300200220022903f80b3703b80d2002410036029810200241b80d6a411020024198106a1005212d024002400240024002400240200228029810222e417f460d00202d450d002002202e36029c102002202d36029810200241f8036a20024198106a102e20022802f803450d1a024002400240024020022802fc0322224180042022418004491b220c0d00410421050c010b200c410374220310272205450d010b02402022450d00200228029810210e200228029c1021014100210f4100210d4100210b0340200241003602b00b200241b00b6a200e20014104200141044922211b221010ce041a2002200120106b220336029c102002200e20106a220e360298100240024020210d0020022802b00b2121200241003602b00b200241b00b6a200e2003410420034104491b221010ce041a2002200320106b220136029c102002200e20106a220e36029810200341034b0d010b200c450d1f200510290c1f0b200b41016a210320022802b00b21100240200b200c470d00200f20032003200f491b220c41ffffffff0171200c470d1e200c41037422134100480d1e02400240200b0d002013102721050c010b2005200d2013102821050b2005450d040b2005200d6a220b2021360200200b41046a2010360200200f41026a210f200d41086a210d2003210b20222003470d000b0b2005450d1c2022ad422086200cad842206422088a721032006a721170240202e450d00202d10290b20172003470d040c030b20034104102a000b20134104102a000b41042105410021170b2017220341016a22012003490d172003410174220b20012001200b491b221741ffffffff01712017470d17201741037422014100480d170240024020030d002001102721050c010b200520034103742001102821050b2005450d010b201641e07a6a2101200520034103746a220b2004360204200b20163602002005200341016a220f4103746a210d410021030240200f41044f0d002005210b0c020b2005210e02400340200e220b28020020014f0d040240200b41086a2802002001490d00200341016a21030c050b0240200b41106a2802002001490d00200341026a21030c050b200b41186a28020020014f0d01200341046a2103200d200b41206a220e6b41184b0d000b200b41206a210b0c020b200341036a21030c020b20014104102a000b200b200d460d000340200b28020020014f0d01200341016a2103200d200b41086a220b470d000b0b024002400240024002400240200f2003490d0041002101200f20036b2210450d0502402003450d002005200520034103746a201041037410cf041a0b2005280204210c200241f80b6a41086a22034200370300200242003703f80b419fcac5004113200241f80b6a1004200241b80d6a41086a2003290300370300200220022903f80b3703b80d20024198106a200241b80d6a411010bb0102402002280298104101470d00024020024198106a41086a2802002221200c2021200c491b220f200228029c1022014f0d002001210f0c050b02402001200f4f0d000340411a10272203450d04200341186a41002f00e8b3433b0000200341106a41002900e0b343370000200341086a41002900d8b343370000200341002900d0b3433700002003411a413410282203450d052003200136001a200241c00a6a41186a220b4200370300200241c00a6a41106a220d4200370300200241c00a6a41086a220e4200370300200242003703c00a2003411e200241c00a6a1000200241e00a6a41186a200b290300370300200241e00a6a41106a200d290300370300200241e00a6a41086a200e290300370300200220022903c00a3703e00a200241e00a6a4120100c20031029200141016a22032101200f2003470d000b0b2021200c4b0d040b200241f80b6a41086a22034200370300200242003703f80b419fcac5004113200241f80b6a1004200241b80d6a41086a2003290300370300200220022903f80b3703b80d200241b80d6a4110100c0c040b419cb1c5001058000b411a4101102a000b41344101102a000b200241f80b6a41086a22034200370300200242003703f80b419fcac5004113200241f80b6a1004200241b80d6a41086a2003290300370300200220022903f80b3703b80d410410272203450d032003200f36000020034104410810282203450d0420032021360004200241b80d6a4110200341081003200310290b201021010b200241f80b6a41086a22034200370300200242003703f80b41eac7c5004112200241f80b6a1004200241b80d6a41086a2003290300370300200220022903f80b3703b80d200241003602a0102002420137039810200220013602b00b200241b00b6a20024198106a10300240024020010d0020022802a0102103200228029c10210b20022802981021010c010b200520014103746a2113410020022802a010220f6b210d200228029c10210b410021030340200f20036a210e200520036a2210280200210c02400240200b200d6a4104490d0020022802981021010c010b200e41046a2201200e490d16200b4101742221200120012021491b22214100480d1602400240200b0d002021102721010c010b200228029810200b2021102821010b2001450d062002202136029c1020022001360298102021210b0b2002200e41046a22213602a0102001200f6a20036a200c360000201041046a280200210c0240200b200d6a417c6a41034b0d00202141046a22222021490d16200b4101742221202220222021491b22214100480d1602400240200b0d002021102721010c010b2001200b2021102821010b2001450d072002202136029c1020022001360298102021210b0b2002200e41086a3602a0102001200f6a20036a41046a200c360000200d41786a210d200341086a2103201041086a2013470d000b200f20036a21030b200241b80d6a41102001200310030240200b450d00200110290b2017450d00200510290b200241f0036a41bdc6c500411610b50120022802f403212f20022802f0032130200241e8036a41d3c6c500411d10b50120022802ec03213120022802e8032132200241c00a6a41186a22034200370300200241c00a6a41106a22014200370300200241c00a6a41086a220b4200370300200242003703c00a41b3a4c400411a200241c00a6a1000200241b80d6a41186a2003290300370300200241b80d6a41106a2001290300370300200241b80d6a41086a200b290300370300200220022903c00a3703b80d2002410036029810200241b80d6a412020024198106a1005210302400240200228029810220b417f470d00410021010c010b410021012003450d00200241c00a6a200b4120200b4120491b22016a41004100412020016b2001411f4b1b10cd041a200241c00a6a2003200110ce041a200b411f4d0d05200241e00a6a41186a2201200241c00a6a41186a290300370300200241e00a6a41106a220b200241c00a6a41106a290300370300200241e00a6a41086a220d200241c00a6a41086a290300370300200220022903c00a3703e00a2003102920024198106a41186a200129030037030020024198106a41106a200b29030037030020024198106a41086a200d290300370300200220022903e00a37039810410121010b412810272203450d05200320013a0004200341b8d6c5003602002003200229039810370005200320022f00b00b3b00252003410d6a20024198106a41086a290300370000200341156a20024198106a41106a2903003700002003411d6a20024198106a41186a290300370000200341276a200241b20b6a2d00003a0000200241c00a6a41186a22014200370300200241c00a6a41106a220b4200370300200241c00a6a41086a220d4200370300200242003703c00a41c6a3c400411a200241c00a6a1000200241b80d6a41186a2001290300370300200241b80d6a41106a200b290300370300200241b80d6a41086a200d290300370300200220022903c00a3703b80d4100210b2002410036029810200241b80d6a412020024198106a100521010240200228029810220d417f460d002001450d00200241c00a6a200d4120200d4120491b220b6a410041004120200b6b200b411f4b1b10cd041a200241c00a6a2001200b10ce041a200d411f4d0d07200241e00a6a41186a220b200241c00a6a41186a290300370300200241e00a6a41106a220d200241c00a6a41106a290300370300200241e00a6a41086a220e200241c00a6a41086a290300370300200220022903c00a3703e00a2001102920024198106a41186a200b29030037030020024198106a41106a200d29030037030020024198106a41086a200e290300370300200220022903e00a370398104101210b0b412810272233450d072033200b3a0004203341b8d6c5003602002033200229039810370005203320022f00b00b3b00252033410d6a20024198106a41086a2201290300370000203341156a20024198106a41106a220b2903003700002033411d6a20024198106a41186a220d290300370000203341276a200241b00b6a41026a2d00003a00002002420037028c0d2002418883c0003602880d200241003602a80d200242083703a00d200241b80c6a411c6a200241880d6a360200200241b80c6a41186a200241b00d6a360200200241003602c80c200241f4f9c4003602bc0c200220033602b80c2002200241a00d6a3602cc0c2002200241b00d6a3602c40c2002200241b00d6a3602c00c20024198106a200241b80c6a108b0202400240024020022d00d810220e4102470d00200241023a00f80d0c010b200241f80b6a41386a220f20024198106a41386a290300370300200241f80b6a41306a221020024198106a41306a290300370300200241f80b6a41286a220520024198106a41286a290300370300200241f80b6a41206a220c20024198106a41206a290300370300200241f80b6a41186a2221200d290300370300200241f80b6a41106a220d200b290300370300200241f80b6a41086a220b2001290300370300200241e00a6a41086a2201200241e1106a2222290000370300200241ef0a6a2213200241e8106a29000037000020022002290398103703f80b200220022900d9103703e00a200241d4106a200f290300370200200241cc106a2010290300370200200241c4106a2005290300370200200241bc106a200c29030037020020024198106a411c6a202129030037020020024198106a41146a200d290300370200200241a4106a200b290300370200200241013602c80c200220022903f80b37029c10200241b00b6a20024198106a41c40010ce041a200241003602981020024198106a410472200241b00b6a41c40010ce041a20024198106a41c8006a200e3a0000202220022903e00a370000200241e9106a2001290300370000200241f0106a2013290000370000200241b80d6a200241b80c6a41146a20024198106a10950320022d00f80d4102470d010b20031029410821344100213541082105410821174100210c0c0e0b20024198106a200310d70341c80010272234450d082034200241b80d6a41c80010ce041a200241d80c6a41186a200241b80c6a41186a290300370300200241d80c6a41106a200241b80c6a41106a290300370300200241d80c6a41086a200241b80c6a41086a290300370300200220022903b80c3703d80c20024198106a200241d80c6a108b02024020022d00d81022054102470d004101210c410121350c0c0b20024198106a41046a2103200241e1106a210d20024198106a410472212e200241ec0c6a2136200241d9106a210e20022802e80c21374102210f41c800210b410021014101213502400340200241f80b6a41386a221020024198106a41386a290300370300200241f80b6a41306a220c20024198106a41306a290300370300200241f80b6a41286a222120024198106a41286a290300370300200241f80b6a41206a222220024198106a41206a290300370300200241f80b6a41186a221320024198106a41186a290300370300200241f80b6a41106a220420024198106a41106a290300370300200241f80b6a41086a221620024198106a41086a290300370300200241e00a6a41086a2217200e41086a290000370300200241e00a6a410f6a222d200e410f6a29000037000020022002290398103703f80b2002200e2900003703e00a200341386a2010290300370200200341306a200c290300370200200341286a2021290300370200200341206a2022290300370200200341186a2013290300370200200341106a2004290300370200200341086a2016290300370200200320022903f80b3702002002203720016a221041016a3602e80c200241b00b6a20024198106a41c40010ce041a2002201036029810202e200241b00b6a41c40010ce041a200d20022903e00a370000200d41086a2017290300370000200d410f6a202d290000370000200220053a00e010200241b80d6a203620024198106a10950320022d00f80d4102460d0120024198106a200241b80d6a41c80010ce041a0240200141016a22102035470d00200241b00b6a20022802d80c20022802dc0c280210110000201041016a22052010490d15200f20052005200f491b2235ad42c8007e2206422088a70d152006a722054100480d15024002402001417f470d002005102721340c010b2034200b2005102821340b2034450d0c0b2034200b6a20024198106a41c80010ce041a200f41026a210f200b41c8006a210b20024198106a200241d80c6a108b022010210120022d00d81022054102460d0c0c000b0b200141016a210c203421050c0c0b41044101102a000b41084101102a000b20214101102a000b20214101102a000b418f89c3004133104e000b41284104102a000b418f89c3004133104e000b41284104102a000b41c8004108102a000b20054108102a000b201041016a210c0b20342105200241023a00f80d0b20022802d80c220120022802dc0c220328020011010002402003280204450d00200110290b200521170b200241b80d6a2033109303024002400240024020022802d80d222e450d00200241b00b6a41017221360240024002400240034020022802e00d211320022802dc0d2137200241d80c6a41186a2238200241b80d6a41186a290300370300200241d80c6a41106a2239200241b80d6a41106a290300370300200241d80c6a41086a223a200241b80d6a41086a290300370300200220022903b80d3703d80c200241b00b6a200241d80c6a108c02024002400240024020022d00b00b4101460d00200241003602b8100c010b200241f80b6a41186a203641186a290000370300200241f80b6a41106a203641106a290000370300200241f80b6a41086a203641086a290000370300200220362900003703f80b20024198106a200241f80b6a108d0220022802b81022030d010b420021194200211a0c010b20024198106a41086a290300211a200229039810211920022802bc10450d00200310290b2013ad42c8007e2206422088a70d062006a72203417f4c0d0602400240024020030d00410821160c010b200310272216450d010b02400240201341057422030d00410021220c010b202e20036a212d41002122202e210403402004220e41206a2104200241880d6a2103200228028c0d2110024003402003280200220f41086a2101200f2f0106222141057421034100210b0240024003402003450d01200e2001412010d004220d450d02200341606a2103200b41016a210b200141206a2101200d417f4a0d000b200b417f6a21210b2010450d022010417f6a2110200f20214102746a4194036a21030c010b0b200c200f200b4102746a41e8026a220328020022014d0d052005200141c8006c6a22012903102106200141186a290300210a200241d0036a41b18ac0004116108601200241c0036a20022903d803200241d0036a41106a290300427f420010d404200c200328020022014d0d06200241b0036a2019201a20022903c003420020022802d003220b1b221442012014420156200241c0036a41086a2903004200200b1b22144200522014501b220b1b20144200200b1b10d4042005200141c8006c6a220141186a427f200a200620022903b0037c2214200654220bad7c2218200b2018200a54201420065a1b220b1b3703002001427f2014200b1b370310200241e00a6a41186a2201200e41186a290000370300200241e00a6a41106a220b200e41106a290000370300200241e00a6a41086a220d200e41086a2900003703002002200e2900003703e00a2003280200210e024020132022470d00201341016a22032013490d122013410174220f20032003200f491b2203ad42c8007e2206422088a70d122006a7220f4100480d120240024020130d00200f102721160c010b2016201341c8006c200f102821160b2016450d08200321130b2016202241c8006c6a220342003703002003200e360220200341186a4200370300200341106a4200370300200341086a4200370300200320022903e00a3702242003412c6a200d290300370200200341346a200b2903003702002003413c6a2001290300370200202241016a21220b2004202d470d000b0b200241c00a6a41186a22032038290300370300200241c00a6a41106a22012039290300370300200241c00a6a41086a220b203a290300370300200220022903d80c3703c00a20024198036a41b18ac000411610860120024188036a20022903a00320024198036a41106a290300427f420010d404200241f8026a2019201a2002290388034200200228029803220d1b22064201200642015620024188036a41086a2903004200200d1b22064200522006501b220d1b20064200200d1b10d404200241b80c6a41086a220d200b290300370300200241b80c6a41106a220b2001290300370300200241b80c6a41186a22012003290300370300200220022903c00a3703b80c20022903f802210602402037450d00202e10290b2016450d0620024198106a41186a220e200129030037030020024198106a41106a220f200b29030037030020024198106a41086a220b200d290300370300200220022903b80c37039810024020022802a80d220120022802a40d470d00200241b80d6a203310d70320022802a40d220320022802a80d220d6b417f20022802b80d221041016a222120212010491b22104f0d00200d20106a2210200d490d0f2003410174220d20102010200d491b220dad42d0007e220a422088a70d0f200aa722104100480d0f0240024020030d002010102721030c010b20022802a00d200341d0006c2010102821030b2003450d062002200d3602a40d200220033602a00d0b20022802a00d200141d0006c6a22032016360220200320022903981037022c200341286a2022360200200341246a2013360200200342003703102003420037030820032006370300200341186a4200370300200341346a200b2903003702002003413c6a200f290300370200200341c4006a200e2903003702002002200141016a3602a80d200241b80d6a203310930320022802d80d222e0d010c060b0b20034108102a000b41e086c3002001200c1037000b41acf2c2002001200c1037000b200f4108102a000b20104108102a000b2033102902400240200c2031410420321b22034101200341014b1b4f0d0002402035450d00203410290b024020022802a80d2203450d00200341d0006c210120022802a00d41206a210303400240200341046a280200450d00200328020010290b200341d0006a2103200141b07f6a22010d000b0b024020022802a40d0d00410021130c020b20022802a00d1029410021130c010b200c202f410020301b2203200c2003491b223341ffffff3f712033470d0120334105742203417f4c0d01024002400240024020030d00410121130c010b200310272213450d010b2033ad422c7e2206422088a70d032006a72203417f4c0d0302400240024020030d00410421320c010b200310272232450d010b024020330d004100213a4100213b0c030b2005200c41c8006c22386a211620024198106a41186a212e20024198106a41106a213620024198106a41086a21374100212d2033213b03400240200c450d002038210303400240201741c0006a2d00000d00200241e8026a427f427f201741106a290300220642012006420156201741186a29030022064200522006501b22011b2006420020011b10d4042017200241e8026a41086a290300370308201720022903e8023703000b201741c8006a2117200341b87f6a22030d000b0b20022802a00d220d20022802a80d222141d0006c6a21040240024002400240024002402021450d00200d210e03400240200e2802282203450d00200341c8006c210b200e28022041206a21030340200c200328020022014d0d0402402005200141c8006c6a22012d00400d002001290310220a200141186a290300221484500d00200241d8026a200e29030022064200428080808010420010d304200241a8026a420042002006420010d304200241c8026a427f20022903d802200e41086a290300220642ffffffff0f8320065220022903b00242005272200241d8026a41086a2903002218200642208620022903a8027c7c220620185472220f1b427f2006200f1b200a201410d404200241b8026a200e41146a350200200e41186a290300220642208684200642208820022903c802200241c8026a41086a29030010d3042001427f2001290300220620022903b8027c220a200a200654220f200141086a22102903002206200241b8026a41086a2903007c200fad7c220a200654200a2006511b220f1b3703002010427f200a200f1b3703000b200341c8006a2103200b41b87f6a220b0d000b0b200e41d0006a220e2004470d000b0b202d41016a213a2005200c41c8006c6a210e203821012005210303402003210b02400240200e20036b41d8014d0d00200b41c0006a2d00000d01200b41c8006a21030c070b0340024020010d00202d213a0c0c0b200141b87f6a2101200b41c0006a210f200b41c8006a2203210b200f2d00000d000b200341b87f6a210b0c060b200b4188016a2d0000450d03200b41d0016a2d0000450d02200141e07d6a2101200b41a0026a2103200b4198026a2d00000d000b410321010c030b41acf2c2002001200c1037000b200b41d8016a2103410221010c010b200b4190016a2103410121010b200b200141c8006c6a210b0b02402003200e460d00200b41086a2903002106200b290300210a0340200341c8006a21010240200341c0006a2d00000d00200341086a2903002214200620032903002218200a54201420065420142006511b220e1b21062018200a200e1b210a2003200b200e1b210b0b2001210320162001470d000b0b200b41013a004002402021450d00200b417c6a2110200b41206a21210340200d41d0006a21220240200d2802282201450d00200d2802202103200141c8006c210103400240024020102003460d00200341246a2021412010d0040d010b200d41186a220e2903002106200b41086a220f290300210a2003200b2903002214200d29031022187d3703002003200a20067d2014201854ad7d370308200b2903002106200e200f290300370300200d20063703100b200341c8006a2103200141b87f6a22010d000b0b2022210d20222004470d000b0b202e200b41386a2900003703002036200b41306a2900003703002037200b41286a2900003703002002200b2900203703981002400240203b202d470d00202d4101742203203a203a2003491b223b41ffffff3f71203b470d0e203b41057422034100480d0e02400240202d0d002003102721130c010b2013202d4105742003102821130b2013450d010b2013202d4105746a2203200229039810370000200341186a202e290300370000200341106a2036290300370000200341086a203729030037000020052117203a212d203a20334f0d040c010b0b20034101102a000b20034104102a000b20034101102a000b0240024020022802a80d22030d00410021360c010b20022802a00d2222200341d0006c6a212e2013203a4105746a210e410021360340200220222f002c3b01b80d20022022412e6a2d00003a00ba0d20022022413f6a290000370398102002202241c4006a29000037009d10024020222802282203450d002022280220220f200341c8006c6a21042022413b6a2800002137202241376a2800002138202241336a28000021392022412f6a28000021312022412c6a21054100210c4108212141002110024002400340200f220d41246a2101200d41c8006a210f201321030240024003400240200e20036b41e0004b0d002003200e460d030340024020012003470d002003210b0c040b024020032001412010d0040d002003210b0c040b200e200341206a2203470d000c040b0b024020032001470d002003210b0c020b024020032001412010d0040d002003210b0c020b200341206a220b2001460d01200b2001412010d004450d01200341c0006a220b2001460d01200b2001412010d004450d01200341e0006a220b2001460d0120034180016a2103200b2001412010d0040d000b0b2005200b460d00200b2005412010d004450d000240024020222903102218200d290300220a85202241186a2903002214200d41086a2903002206858450450d0042002106428080808010210a0c010b20024198026a200a4200428080808010420010d30420024188026a42004200200a420010d3040240200642ffffffff0f832006522002290390024200527220024198026a41086a290300221920064220862002290388027c7c221a201954724101470d000240201842208820144220868422182014422088221484500d00200241e8016a200a20062018201410d404200241e8016a41086a290300210620022903e801210a0c020b41bcf2c2001058000b200241f8016a200229039802201a20184201201842015620144200522014501b22031b2014420020031b10d404200241f8016a41086a290300210620022903f801210a0b200d200a370310200d41186a20063703002002200d2f00243b01900b2002200d41266a2d00003a00920b2002200d41376a2900003703800b2002200d413c6a2900003700850b200d41336a2800002101200d412f6a280000210b200d412b6a2800002116200d41276a280000210d0240200c2010470d00200c41016a2203200c490d10200c4101742217200320032017491b2203ad42307e2214422088a70d102014a722174100480d1002400240200c0d002017102721210c010b2021200c41306c2017102821210b2021450d032003210c0b20022d00920b211720022f01900b212d2021201041306c6a2203200136000f2003200b36000b200320163600072003200d3600032003202d3b0100200341026a20173a00002003200a370320200341286a2006370300200320022903800b370013200341186a20022900850b370000201041016a21100b200f2004470d000b02402010450d0002400240201041306c22010d00420021064200210a0c010b202141206a2103420021064200210a0340200341086a290300200a7c2003290300220a20067c2206200a54ad7c210a200341306a2103200141506a22010d000b0b200241d8016a420042808080801020067d22142014428080808010564200200a200642808080801056ad7c7d22064200522006501b22031b22194200200620031b22062010ad221a420010d40420022903d801211402402019201a5441002006501b0d00200241d8016a41086a2903002118202141206a21032010210103402003427f2003290300220620147c220a200a200654220b200341086a220d290300220620187c200bad7c220a200654200a2006511b220b1b370300200d427f200a200b1b370300200341306a21032001417f6a22010d000b0b200241c8016a20142006201a200610d3040240201920022903c8017da7220d450d004100210303402021200320107041306c6a2201427f2001290320220642017c220a200a200654220b200141286a22012903002214200bad7c2218201454200a20065a1b220b1b3703202001427f2018200b1b370300200341016a2203200d490d000b0b200220022f01b80d3b01ac0b200220022d00ba0d3a00ae0b20022002290398103703980b2002200229009d1037009d0b024020332036470d00203341016a22032033490d0f20334101742201200320032001491b2203ad422c7e2206422088a70d0f2006a722014100480d0f0240024020330d002001102721320c010b20322033412c6c2001102821320b2032450d03200321330b20022d00ae0b210120022f01ac0b210b20322036412c6c6a2203203736000f2003203836000b20032039360007200320313600032003200b3b0100200341026a20013a0000200320022903980b370013200341186a200229009d0b370000200320103602282003200c36022420032021360220203641016a21360c030b200c450d02202110290c020b20174108102a000b20014104102a000b202241d0006a2222202e470d000b0b02402035450d00203410290b024020022802a80d2203450d00200341d0006c210120022802a00d41206a210303400240200341046a280200450d00200328020010290b200341d0006a2103200141b07f6a22010d000b0b20022802a40d450d0020022802a00d10290b20022802900d210f20022802880d21010240200228028c0d2203450d00034020012802940321012003417f6a22030d000b0b0240200f450d004100210b410021030340200f417f6a210f02400240200320012f01064f0d00200341016a21030c010b02400240200128020022030d00200bad21064100210d410021030c010b2001330104422086200bad8421064101210d0b200110292006a7210b024002402006422088a7220e20032f01064f0d00200321010c010b034002400240200328020022010d00200bad2106410021010c010b200d41016a210d2003330104422086200bad8421060b200310292006a7210b200121032006422088a7220e20012f01064f0d000b0b200e41027420016a4198036a28020021010240200d417f6a2203450d00034020012802940321012003417f6a22030d000b0b410021030b200f0d000b0b02402001418883c000460d0020012802002103200110292003450d0020032802002101200310292001450d00024020012802002203450d00034020011029200321012003280200220b2103200b0d000b0b200110290b024020130d00200241086a41c8f9c4004111108601410021130c030b2036412c6c2203412c6e213c41002117024002400240024020030d004108213d4100213c0c010b203c41ffffff1f71203c470d0a203c41067422014100480d0a20011027223d450d010b024002402032203220036a2237460d00200241b80d6a410172210e41002117203d210c203221050340200241c00a6a41186a2216200541186a290200370300200241c00a6a41106a222d200541106a290200370300200241c00a6a41086a222e200541086a290200370300200220052902003703c00a200241b80d6a2005108c02024002400240024020022d00b80d4101460d00200241003602b8100c010b200241b00b6a41186a200e41186a290000370300200241b00b6a41106a200e41106a290000370300200241b00b6a41086a200e41086a2900003703002002200e2900003703b00b20024198106a200241b00b6a108d0220022802b81022030d010b4200211a4200211b0c010b20024198106a41086a290300211b200229039810211a20022802bc10450d00200310290b2005280220210b4100210d024002402005280228222141306c220f0d0041082104410021210c010b202141ffffff1f712021470d0d202141067422034100480d0d200310272204450d030b2005412c6a21220240200b200b200f6a460d004100210d200421030340200b220141286a290300210a200141206a2903002106200241b80d6a2005108c02024002400240024020022d00b80d4101460d00200241003602b8100c010b200241b00b6a41186a200e41186a290000370300200241b00b6a41106a200e41106a290000370300200241b00b6a41086a200e41086a2900003703002002200e2900003703b00b20024198106a200241b00b6a108d0220022802b810220b0d010b42002118420021190c010b20024198106a41086a2903002119200229039810211820022802bc10450d00200b10290b200141306a210b200241b0016a41b18ac000411610860120024188016a20022903b801200241b0016a41106a290300427f420010d404200241e8006a20182019200229038801420020022802b00122101b22144201201442015620024188016a41086a290300420020101b22144200522014501b22101b2014420020101b10d40420024198016a41b18ac0004116108601200241f8006a20022903a00120024198016a41106a290300427f420010d404200241386a200a420020022903682214420010d304200241d8006a200642002014420010d304200241286a420042002006420010d304200241c8006a2002290378420020022802980122101b221442012014420156200241f8006a41086a290300420020101b22144200522014501b22101b2014420020101b427f200235025c200241d8006a41086a2903002218200229033820022903287c7c221442208684200229034020022903308442005220142018547222101b42ffffffff0f201442208820101b10d304200320063703002003200a370308200341286a200141186a290300370300200341206a200141106a290300370300200341186a200141086a290300370300200341106a2001290300370300200341386a200241c8006a41086a290300370300200341306a2002290348370300200341c0006a2103200d41016a210d200f41506a220f0d000b0b200c201a370300200c201b370308200c2004360230200c41386a200d360200200c41346a2021360200200c20022903c00a370310200c41186a202e290300370300200c41206a202d290300370300200c41286a2016290300370300201741016a2117200c41c0006a210c2022210520222037470d000b0b200242003702940a2002418883c0003602900a024002400240203a450d002013203a4105746a213120024198106a410272213e200241c00a6a41136a2134200241e00a6a41136a213f200241b80d6a4101722121201321050340200241b80d6a2005108c02024002400240024020022d00b80d4101460d00200241003602b8100c010b200241b00b6a41186a202141186a290000370300200241b00b6a41106a202141106a290000370300200241b00b6a41086a202141086a290000370300200220212900003703b00b20024198106a200241b00b6a108d0220022802b81022030d010b420021064200210a0c010b20024198106a41086a290300210a200229039810210620022802bc10450d00200310290b200241b00b6a41186a2222200541186a290000370300200241b00b6a41106a2204200541106a290000370300200241b00b6a41086a2216200541086a290000370300200220052900003703b00b0240024002400240024002400240024020022802900a220e418883c000460d0020022802940a210f0c010b200241b80d6a410041e00210cd041a20024198106a410041900410cd041a41f8061027220e450d014100210f200e41003b0106200e4100360200200e41086a200241b80d6a41e00210ce041a200e41e8026a20024198106a41900410ce041a200241003602940a2002200e3602900a0b200541206a210502400340200e41086a2101200e41066a210c200e2f0106221041057421034100210b024003402003450d01200241b00b6a2001412010d004220d450d03200341606a2103200b41016a210b200141206a2101200d417f4a0d000b200b417f6a21100b0240200f450d00200f417f6a210f200e20104102746a41f8066a280200210e0c010b0b200241b80c6a41186a22032022290300370300200241b80c6a41106a20042903002214370300200241b80c6a41086a20162903002218370300200220022903b00b22193703b80c200220022802980a41016a3602980a200241f80b6a41106a22302014370300200241f80b6a41086a22402018370300200241f80b6a41186a22412003290300370300200220193703f80b200c2f01002201410b490d04200241b80d6a410041e00210cd041a20024198106a410041900410cd041a41f80610272203450d02200341003b010620034100360200200341086a200241b80d6a41e00210ce04210b200341e8026a20024198106a41900410ce04210d200241e00a6a41086a2242200e41d0016a290000370300200241e00a6a41106a2243200e41d8016a290000370300200241e00a6a41186a2244200e41e0016a29000037030020024198106a41086a222d200e4190056a29030037030020024198106a41106a222e200e4198056a29030037030020024198106a41186a2237200e41a0056a29030037030020024198106a41206a2238200e41a8056a29030037030020024198106a41286a2239200e41b0056a2903003703002002200e2900c8013703e00a2002200e2903880537039810200b200e41e8016a200e2f010641796a220141057410ce04210b200d200e41b8056a200141306c10ce04210d200e41063b0106200320013b0106200220022f01e00a3b01ac0b200220022d00e20a3a00ae0b2002203f2900003703980b2002203f41056a224529000037009d0b20022800e30a214620022800e70a214720022800eb0a214820022800ef0a2149200241b80d6a41286a224a2039290300370300200241b80d6a41206a224b2038290300370300200241b80d6a41186a224c2037290300370300200241b80d6a41106a224d202e290300370300200241b80d6a41086a224e202d29030037030020022002290398103703b80d0240024020104107490d002010410574200b6a41c07e6a200b201041796a220f4105746a220b200141ffff0371200f6b41057410cf041a200b41186a2041290300370000200b41106a2030290300370000200b41086a2040290300370000200b20022903f80b370000201041306c200d6a220141e07d6a200141b07d6a2201200341066a220c2f0100200f6b41306c10cf041a200141186a200a370300200120063703102001200a37030820012006370300200141286a4100360200200142083703200c010b200e41086a20104105746a220141206a2001200c2f010020106b41057410cf041a200141186a2041290300370000200141106a2030290300370000200141086a2040290300370000200120022903f80b370000200e41e8026a201041306c6a220141306a2001200c2f010020106b41306c10cf041a200141186a200a370300200120063703102001200a37030820012006370300200141286a4100360200200142083703200b200c200c2f010041016a3b0100200241a00d6a41026a220120022d00ae0b3a00002016204e2903003703002004204d2903003703002022204c290300370300200241b00b6a41206a224f204b290300370300200241b00b6a41286a2250204a290300370300200220022f01ac0b3b01a00d200220022903980b3703c00a2002200229009d0b3700c50a200220022903b80d3703b00b200241d80c6a41286a22512050290300370300200241d80c6a41206a2252204f290300370300200241d80c6a41186a22532022290300370300200241d80c6a41106a22542004290300370300200241d80c6a41086a22552016290300370300200220022903b00b3703d80c200220022f01a00d3b01900b200220012d00003a00920b200220022903c00a3703800b200220022900c50a3700850b0240200e280200220f0d00200241900a6a21012003210b0c060b200e2f0104213541002156200321570340200241b00d6a41026a225820022d00920b3a0000200220022f01900b3b01b00d200220022903800b3703a00d200220022900850b3700a50d20502051290300370300204f2052290300370300202220532903003703002004205429030037030020162055290300370300200220022903d80c3703b00b203541ffff03712110024002400240200f2f01062203410b490d00203e410041a20710cd041a41a8071027220d450d07200d4100360200200d41046a20024198106a41a40710ce041a2044200f41e0016a2900003703002043200f41d8016a2900003703002042200f41d0016a2900003703002002200f2900c8013703e00a2039200f41b0056a2903003703002038200f41a8056a2903003703002037200f41a0056a290300370300202e200f4198056a290300370300202d200f4190056a2903003703002002200f2903880537039810200d41086a200f41e8016a200f2f0106220141796a220341057410ce042159200d41e8026a200f41b8056a200341306c10ce04215a200d41f8066a200f4194076a2001417a6a220c41027410ce04212f200f41063b0106200d20033b01060240200c450d0041002103202f210103402001280200220b20033b0104200b200d360200200141046a2101200c200341016a2203470d000b0b204a2039290300370300204b2038290300370300204c2037290300370300204d202e290300370300204e202d29030037030020022002290398103703b80d200220022f01e00a3b01ac0b200220022d00e20a3a00ae0b20022900e30a210620022900eb0a210a2002204529000037009d0b2002203f2900003703980b203420022903980b370000203441056a220c200229009d0b370000200220022d00ae0b3a00c20a200220022f01ac0b3b01c00a2002200a3700cb0a200220063700c30a2039204a2903003703002038204b2903003703002037204c290300370300202e204d290300370300202d204e290300370300200220022903b80d37039810203541ffff037122014107490d0120592010417a6a220b4105746a2059201041796a22034105746a2201200d2f010620036b41057410cf041a200141186a20022900a50d3700002001204936000f2001204836000b2001204736000720012046360003200141026a20582d00003a0000200120022f01b00d3b0000200120022903a00d370013201041306c205a6a220141e07d6a200141b07d6a2201200d2f0106223520036b41306c10cf041a200141286a2050290300370300200141206a204f290300370300200141186a2022290300370300200141106a2004290300370300200141086a2016290300370300200120022903b00b370300200d203541016a22013b010620104102742235202f6a416c6a202f200b4102746a2210200141ffff0371200b6b41027410cf041a20102057360200200b200d2f010622104b0d02200d20356a41e0066a210103402001280200220b200341016a22033b0104200b200d360200200141046a210120032010490d000c030b0b200f41086a2201201041016a220b4105746a200120104105746a2201200320106b220d41057410cf041a2001204936000f2001204836000b2001204736000720012046360003200141026a20582d00003a0000200120022f01b00d3b0000200120022903a00d370013200141186a20022900a50d370000200f201041306c6a22014198036a200141e8026a220c200d41306c10cf041a20014190036a205029030037030020014188036a204f29030037030020014180036a2022290300370300200141f8026a2004290300370300200141f0026a2016290300370300200c20022903b00b370300200f200341016a22033b01062010410274200f41f8066a22016a41086a2001200b4102746a2201200341ffff0371200b6b41027410cf041a2001205736020002402010200f2f010622034f0d002057200b3b01042057200f360200200b20034f0d002003417f6a210d200f200b417f6a22034102746a4180076a210103402001280200220b200341026a3b0104200b200f360200200141046a2101200d200341016a2203470d000b0b41001a200241900a6a1a200e1a0c090b200f41086a2203201041016a220b4105746a200320104105746a2203200f2f0106223520106b222f41057410cf041a2003204936000f2003204836000b2003204736000720032046360003200341026a20582d00003a0000200320022f01b00d3b0000200320022903a00d370013200341186a20022900a50d370000200f41e8026a201041306c6a220341306a2003202f41306c10cf041a200341286a2050290300370300200341206a204f290300370300200341186a2022290300370300200341106a2004290300370300200341086a2016290300370300200320022903b00b370300200f203541016a22033b01062010410274222f200f41f8066a22356a41086a2035200b4102746a2235200341ffff0371200b6b41027410cf041a203520573602002001200f2f0106220b4f0d00200f202f6a41fc066a2103034020032802002201201041016a22103b01042001200f360200200341046a2103200b2010470d000b0b205641016a21102002419c0d6a41026a220320022d00c20a3a00002040202d2903003703002030202e29030037030020412037290300370300200241f80b6a41206a22012038290300370300200241f80b6a41286a220b2039290300370300200220022f01c00a3b019c0d20022002290398103703f80b200220342900003703880d2002200c29000037008d0d20022800c30a214620022800c70a214720022800cb0a214820022800cf0a21492051200b29030037030020522001290300370300205320412903003703002054203029030037030020552040290300370300200220022903f80b3703d80c200220022f019c0d3b01900b200220032d00003a00920b200220022903880d3703800b2002200229008d0d3700850b0240200f28020022030d00200f1a200241900a6a22011a200d210b0c070b200f2f01042135200241900a6a1a200f1a2003210f200d2157201021560c000b0b200e200b41306c6a22034180036a200a370300200341f8026a2006370300200341f0026a200a370300200341e8026a200637030020034190036a410036020020034188036a220b28020021012003418c036a2802002103200b42083703002001450d052003450d05200110290c050b41f8064108102a000b41f8064108102a000b41a8074108102a000b200e20104105746a220341286a200341086a220b200120106b41057410cf041a200341206a2041290300370000200341186a2030290300370000200341106a2040290300370000200b20022903f80b370000200e201041306c6a22034198036a200341e8026a2201200e2f010620106b41306c10cf041a20034190036a410036020020034188036a420837030020034180036a200a370300200341f8026a2006370300200341f0026a200a37030020012006370300200e200e2f010641016a3b01060c010b203e410041a20710cd041a41a80710272203450d0320034100360200200341046a20024198106a41a40710ce041a20032001280200220d3602f806200120033602002001200128020441016a360204200d41003b0104200d2003360200200320032f0106220d4105746a220141086a20022f01900b3b00002001410a6a20022d00920b3a0000200141176a2049360000200141136a20483600002001410f6a20473600002001410b6a20463600002001411b6a20022903800b370000200141206a20022900850b3700002003200d41306c6a220141e8026a20022903d80c370300200141f0026a2055290300370300200141f8026a205429030037030020014180036a205329030037030020014188036a205229030037030020014190036a2051290300370300200341f8066a200d41016a22014102746a200b360200200320013b0106200b20013b0104200b2003360200200e1a0b20052031470d000b0b20174106742203450d04203d20036a212d203d211603402016450d05024020162802382203450d002016280230222220034106746a2104201641106a212103402022220c41106a210e200c41c0006a2122200241900a6a210320022802940a2110024003402003280200220f41086a2101200f2f0106220541057421034100210b0240024003402003450d01200e2001412010d004220d450d02200341606a2103200b41016a210b200141206a2101200d417f4a0d000b200b417f6a21050b2010450d022010417f6a2110200f20054102746a41f8066a21030c010b0b200f200b41306c6a220341e8026a2201427f20012903002206200c2903307c220a200a2006542201200341f0026a220b2903002206200c41386a220d2903007c2001ad7c220a200654200a2006511b22011b370300200b427f200a20011b37030020024198106a41086a220e202141086a2900003703002021290000210620024198106a41106a220f202141106a29000037030020024198106a41186a2210202141186a2900003703002002200637039810200d2903002106200c290330210a20034188036a210d0240024020034190036a220b28020022012003418c036a280200460d00200d28020021030c010b200141016a22032001490d1120014101742205200320032005491b2205ad42307e2214422088a70d112014a7220c4100480d110240024020010d00200c102721030c010b200d280200200141306c200c102821030b2003450d06200d2003360200200d41046a2005360200200b28020021010b2003200141306c6a220320063703082003200a3703002003200229039810370310200341186a200e290300370300200341206a200f290300370300200341286a2010290300370300200b200b28020041016a3602000b20222004470d000b0b201641c0006a2216202d470d000c050b0b41a8074108102a000b200c4108102a000b20034108102a000b20014108102a000b200241f80b6a41086a22034200370300200242003703f80b41cdf8c4004116200241f80b6a1004200241b80d6a41086a2003290300370300200220022903f80b3703b80d2002410036029810200241b80d6a411020024198106a10052103024002400240200228029810220b417f460d002003450d002002200b3602b40b200220033602b00b20024198106a200241b00b6a102d2002280298102237450d02200241a0106a2802002101200228029c102138200b450d01200310290c010b4100213841012137410021010b024002400240024002400240024020014105742204450d00203721030340410f10272201450d07200141076a4100290091a3443700002001410029008aa3443700002001410f412f10282201450d062001200329000037000f200141276a200341186a220f2900003700002001411f6a200341106a2210290000370000200141176a200341086a2205290000370000200241c00a6a41186a220b4200370300200241c00a6a41106a220d4200370300200241c00a6a41086a220e4200370300200242003703c00a2001412f200241c00a6a1000200241b80d6a41186a220c200b290300370300200241b80d6a41106a2221200d290300370300200241b80d6a41086a2222200e290300370300200220022903c00a3703b80d200241b80d6a4120100c20011029411210272201450d05200141106a41002f00c4a344222e3b0000200141086a41002900bca3442206370000200141002900b4a344220a37000020014112413210282201450d04200120032900003700122001412a6a200f290000370000200141226a20102900003700002001411a6a2005290000370000200b4200370300200d4200370300200e4200370300200242003703c00a20014132200241c00a6a1000200c200b2903003703002021200d2903003703002022200e290300370300200220022903c00a3703b80d200241206a200241b80d6a412010c102200228022421162002280220212d20011029024020164100202d1b22164102490d00411210272201450d04200141106a202e3b0000200141086a20063700002001200a37000020014112413210282201450d03200120032900003700122001412a6a200f290000370000200141226a20102900003700002001411a6a2005290000370000200b4200370300200d4200370300200e4200370300200242003703c00a20014132200241c00a6a1000200c200b2903003703002021200d2903003703002022200e290300370300200220022903c00a3703b80d20022016417f6a36029810200241b80d6a412020024198106a41041003200110290b200341206a2103200441606a22040d000b0b02402038450d00203710290b20022802900a210f024020022802940a2203450d00200321010340200f2802f806210f2001417f6a22010d000b03402003417f6a22030d000b0b024020022802980a22210d00427f2114427f21060c090b02400240200f2f0106450d00200f41e8026a210d200f41086a210e4101210c0c010b02400240200f28020022030d004100210b41002101410021030c010b200f2f0104210b410121010b0240200b20032f0106490d000340200141016a210120032f0104220b200328020022032f01064f0d000b0b2003200b41306c6a41e8026a210d2003200b4105746a41086a210e200b41027420036a41fc066a280200210f4100210c2001417f6a2203450d000340200f2802f806210f2003417f6a22030d000b0b20024198106a41106a212d427f2114427f21060340200d41086a2203290300210a200d2903002118200241b00b6a41186a2222200e41186a290000370300200241b00b6a41106a2204200e41106a290000370300200241b00b6a41086a2216200e41086a2900003703002002200e2900003703b00b200d280228220ead42307e2219422088a70d082019a72201417f4c0d08200d41186a29030021192003290300211a200d290310211b200d290300211f200d2802202103024002400240024002400240024020010d00410821100c010b200110272210450d010b02400240200e0d004100210b0c010b2003200e41306c6a210d4100210b201021010340200120032903003703002001200341086a290300370308200141106a200341106a290300370300200141186a200341186a290300370300200141206a200341206a290300370300200141286a200341286a290300370300200141306a2101200b41016a210b200341306a2203200d470d000b0b20024198106a41186a20193703002002201b3703a8102002201f370398102002200b3602c0102002200e3602bc10200220103602b8102002201a3703a010410f10272203450d01200341076a4100290091a3443700002003410029008aa3443700002003410f412f10282205450d02200520022903b00b37000f200541276a20222903003700002005411f6a2004290300370000200541176a2016290300370000200241c00a6a41186a22034200370300200241c00a6a41106a22014200370300200241c00a6a41086a220b4200370300200242003703c00a2005412f200241c00a6a1000200241b80d6a41186a2003290300370300200241b80d6a41106a2001290300370300200241b80d6a41086a200b290300370300200220022903c00a3703b80d200241003602800c200242013703f80b200220024198106a3602d80c200241d80c6a200241f80b6a10592002202d3602d80c200241d80c6a200241f80b6a105920022802b8102103200220022802c01022013602d80c200241d80c6a200241f80b6a103002402001450d00200141306c210d03400240024020022802fc0b220b20022802800c22016b4120490d0020022802f80b210b0c010b200141206a220e2001490d17200b4101742210200e200e2010491b220e4100480d1702400240200b0d00200e1027210b0c010b20022802f80b200b200e1028210b0b200b450d062002200e3602fc0b2002200b3602f80b0b200b20016a220b41086a200341186a290000370000200b41106a200341206a290000370000200b41186a200341286a2900003700002002200141206a3602800c200b200341106a290000370000200220033602d80c200241d80c6a200241f80b6a1059200341306a2103200d41506a220d0d000b0b20182014542103200a2006512101200a200654210b20022802fc0b210d200241b80d6a412020022802f80b220e20022802800c10030240200d450d00200e10290b2003200b20011b21032021417f6a212120051029024020022802bc10450d0020022802b81010290b200a200620031b21062018201420031b21142021450d0e0240200c200f2f01064f0d00200f200c41306c6a41e8026a210d200f200c4105746a41086a210e200c41016a210c0c060b02400240200f28020022030d004100210b41002101410021030c010b200f2f0104210b410121010b200b20032f0106490d040340200141016a210120032f0104220b200328020022032f01064f0d000c050b0b20014108102a000b410f4101102a000b412f4101102a000b200e4101102a000b2003200b41306c6a41e8026a210d2003200b4105746a41086a210e200b41027420036a41fc066a280200210f4100210c2001417f6a2203450d000340200f2802f806210f2003417f6a22030d000c010b0b0b41324101102a000b41124101102a000b41324101102a000b41124101102a000b412f4101102a000b410f4101102a000b418f89c3004133104e000b1039000b200241f80b6a41086a22034200370300200242003703f80b41c8f9c4004111200241f80b6a1004200241b80d6a41086a22012003290300370300200220022903f80b3703b80d200220063703a0102002201437039810200241b80d6a411020024198106a4110100320034200370300200242003703f80b41cdf8c4004116200241f80b6a100420012003290300370300200220022903f80b3703b80d200241003602a01020024201370398102002203a3602b00b200241b00b6a20024198106a103002400240203a0d0020022802a0102101200228029c10210e200228029810210f0c010b203a4105742110410020022802a01022016b210d200228029810210f200228029c10210e2013210303400240200e200d6a411f4b0d00200141206a220b2001490d08200e4101742205200b200b2005491b220b4100480d0802400240200e0d00200b1027210f0c010b200f200e200b1028210f0b200f450d07200b210e0b200f20016a220b2003290000370000200b41186a200341186a290000370000200b41106a200341106a290000370000200b41086a200341086a290000370000200d41606a210d200141206a2101200341206a2103201041606a22100d000b2002200e36029c10200220013602a0102002200f360298100b200241b80d6a4110200f200110030240200e450d00200f10290b20022802980a211020022802900a210b024020022802940a2203450d000340200b2802f806210b2003417f6a22030d000b0b02402010450d004100210d410021030340024002402003200b2f01064f0d00200b200341306c6a2201418c036a280200210f20014188036a2802002101200341016a21030c010b02400240200b28020022030d00200dad21064100210e410021030c010b200b330104422086200dad8421064101210e0b200b10292006a7210d024002402006422088a7220f20032f01064f0d00200321010c010b034002400240200328020022010d00200dad2106410021010c010b200e41016a210e2003330104422086200dad8421060b200310292006a7210d200121032006422088a7220f20012f01064f0d000b0b200f41027420016a41fc066a280200210b2001200f41306c6a2203418c036a280200210f20034188036a28020021010240200e417f6a2203450d000340200b2802f806210b2003417f6a22030d000b0b410021030b2001450d012010417f6a21100240200f450d00200110290b20100d000b0b0240200b418883c000460d00200b2802002103200b10292003450d0020032802002101200310292001450d00024020012802002203450d00034020011029200321012003280200220b2103200b0d000b0b200110290b02402017450d0020174106742101203d41306a210303400240200341046a280200450d00200328020010290b200341c0006a2103200141406a22010d000b0b203aad21060240203c450d00203d10290b20064220862106203bad210a02402036450d002036412c6c2101203241206a210303400240200341046a280200450d00200328020010290b2003412c6a2103200141546a22010d000b0b2006200a8421062033450d00203210290b02402012452015720d00201110290b20130d0102402007450d00200741d0006c2101200841c0006a210303400240200341046a280200450d00200328020010290b200341d0006a2103200141b07f6a22010d000b0b2009450d00200810290b200041003602000c010b200020063702042000201336020002402007450d00200741d0006c2101200841c0006a210303400240200341046a280200450d00200328020010290b200341d0006a2103200141b07f6a22010d000b0b2009450d00200810290b200241c0176a24000f0b200b4101102a000b102b000b418f89c3004133104e000b9f0501067f230041c0046b22012400200141b8036a41086a22024200370300200142003703b8034188d4c3004116200141b8036a100420014190016a41086a2002290300370300200120012903b80337039001200141003602b80320014190016a4110200141b8036a10052103024002400240024020012802b8032204417f470d00411221020c010b200120043602ac02200120033602a802200141b8036a200141a8026a103c20012802b8034112460d02200141b0026a200141b8036a41880110ce041a200141003a00a001200141a0016a20012802a802220520012802ac022202410047220610ce041a20022006490d012001200220066b3602ac022001200520066a3602a802024002402002450d0020012d00a00122054103490d010b200141b0026a103d0c030b20012802b0022102200141a0016a200141b0026a41047241840110ce041a20024112460d02200141b8036a200141a0016a41840110ce041a02402004450d00200310290b20014190016a4110100c0b2001410c6a200141b8036a41840110ce041a0240024020024112470d00419ed4c30021060c010b200141b0026a2001410c6a41840110ce041a200141013a00a001200141b8036a41086a22064200370300200142003703b80341f586c500411f200141b8036a100420014190016a41086a2006290300370300200120012903b8033703900120014190016a4110200141a0016a41011003200641023a0000200141053a00b8034100210641b8d6c5004100200141b8036a108801200120023602b803200141b8036a410472200141b0026a41840110ce041a200141a0016a20004280ce187c200141b8036a20054280af1a10b50320012802a0014101470d0020012802a40121060b200141c0046a240020060f0b20062002103e000b418f89c3004133104e000bb81304077f137e017f047e23004180036b22012400200141c0016a41086a22024200370300200142003703c00141b7d2c3004115200141c0016a1004200141d8026a41086a2002290300370300200120012903c0013703d802200141003602c001200141d8026a4110200141c0016a100521020240024002400240024002400240024002400240024020012802c0012203417f460d002002450d002001200336022c20012002360228200141c0016a200141286a103f20012802c0012204450d02200141c8016a280200210520012802c40121062003450d01200210290c010b4108210441002105410021060b0240200541b0016c22020d00200141003602302001200436022c200120043602282001200141f8026a3602340c080b200420026a2103200141c0016a20042802880110b603200441b0016a21020240024020012802d00122070d0042002108420021090c010b200141186a20012903c001200141c0016a41086a290300200141d8016a350200420010d304200141186a41086a29030021092001290318210820012802d401450d00200710290b200141013602302001200336022c200120023602282001200141f8026a3602342004450d072004ad422086210a024020022003460d00200541b0016c41d07e6a21034201210b0340200141c0016a20024188016a28020010b6030240024020012802d00122070d004200210c4200210d0c010b200141086a20012903c001200141c0016a41086a29030020013502d801420010d304200141086a41086a290300210d2001290308210c20012802d401450d00200710290b02402008200c562009200d562009200d511b0d002002ad422086200b84210a200c2108200d21090b200241b0016a2102200b42017c210b200341d07e6a22030d000b0b200a428080808010540d072005200aa722024d0d0120042005417f6a220741b0016c6a22034180016a290300210d20034188016a290300210920034190016a290300210b20034198016a290300210c200341e0006a2903002108200341e8006a290300210a200341f0006a290300210e200341f8006a290300210f200341c0006a2903002110200341c8006a2903002111200341d0006a2903002112200341d8006a2903002113200341206a2903002114200341286a2903002115200341306a2903002116200341386a290300211720032903002118200329030821192003290310211a2004200241b0016c6a220241186a221b290300211c200341a8016a290300211d200341a0016a290300211e201b200341186a2903003703002002290310211f2002201a3703102002290308211a200220193703082002290300211920022018370300200241386a2203290200211820032017370200200241306a2203290200211720032016370200200241286a2203290200211620032015370200200241206a2203290200211520032014370200200241d8006a2203290200211420032013370200200241d0006a2203290200211320032012370200200241c8006a2203290200211220032011370200200241c0006a2203290200211120032010370200200241f8006a220329020021102003200f370200200241f0006a2203290200210f2003200e370200200241e8006a2203290200210e2003200a370200200241e0006a2203290200210a2003200837020020024198016a200c37020020024190016a200b37020020024188016a2203280200211b2003200937020020024180016a220329020021092003200d370200200241a0016a201e370200200241a8016a201d370200200141286a41f8006a2010370300200141286a41f0006a200f370300200141286a41e8006a200e370300200141286a41e0006a200a370300200141286a41d8006a2014370300200141286a41d0006a2013370300200141286a41c8006a2012370300200141286a41c0006a2011370300200141286a41386a2018370300200141286a41306a2017370300200141286a41286a2016370300200141286a41206a2015370300200141286a41186a201c370300200141286a4180016a20093703002001201f3703382001201a37033020012019370328200120073602b801200120063602b401200120043602b001200141c0016a41086a22024200370300200142003703c00141b7d2c3004115200141c0016a1004200141d8026a41086a2002290300370300200120012903c0013703d802200141103602c4012001200141d8026a3602c001200141b0016a200141c0016a103302402007450d00200541b0016c41d07e6a21032004210203402002103d200241b0016a2102200341d07e6a22030d000b0b02402006450d00200410290b411310272202450d022002410f6a41002800ecd143360000200241086a41002900e5d143370000200241002900ddd14337000020024113412610282202450d032002201b360013200141c0016a41186a22034200370300200141c0016a41106a22074200370300200141c0016a41086a22044200370300200142003703c00120024117200141c0016a1000200141d8026a41186a2003290300370300200141d8026a41106a2007290300370300200141d8026a41086a2004290300370300200120012903c0013703d802200141003602c001200141d8026a4120200141c0016a1005210320012802c0012207417f460d052003450d05200120033602b001200120073602b401200142003703c801200142003703c001200141c0016a20032007411020074110491b220410ce041a2001200720046b3602b4012001200320046a3602b0012007410f4d0d04200141c8016a290300210920012903c001210d200141c0016a200141b0016a102d20012802c0012207450d0420012902c401210b20031029200141d8026a4120100c200b422088a72104200ba721050c060b418f89c3004133104e000b41ccd2c300200220051037000b41134101102a000b41264101102a000b418f89c3004133104e000b410021070b200210290240024020070d00200141286a103d0c010b024020044105742203450d002007210203402002200d200910ad01200241206a2102200341606a22030d000b0b200141e8016a2009370300200141e0016a200d370300200141d8016a2004360200200141d4016a2005360200200141d0016a2007360200200141cc016a201b360200200141c8016a41013a0000200141053a00c00141b8d6c5004100200141c0016a108801200141c0016a200141286a41880110ce041a200141d8026a20004280ce187c200141c0016a41004280af1a10b50320012802d8024101470d0020012802dc0221020c020b410021020c010b02402005450d00200541b0016c21032004210203402002103d200241b0016a2102200341d07e6a22030d000b0b41dcd2c30021022006450d00200410290b20014180036a240020020bda0604047f017e047f017e230041d0046b22022400024002400240411a10272203450d00200341186a41002f00dbd1433b0000200341106a41002900d3d143370000200341086a41002900cbd143370000200341002900c3d1433700002003411a413410282203450d012003200136001a200241c0026a41186a22014200370300200241c0026a41106a22044200370300200241c0026a41086a22054200370300200242003703c0022003411e200241c0026a1000200241186a2001290300370300200241106a2004290300370300200241086a2005290300370300200220022903c002370300200241003602c00220024120200241c0026a1005210102400240024020022802c0022204417f460d002001450d002002200136022020022004360224200242003703c002200241c0026a20012004410820044108491b220510ce041a2002200420056b3602242002200120056a3602200240200441074d0d0020022903c0022106200241c0026a200241206a103c20022802c0022105200241cc036a200241c0026a41047241840110ce041a20054112460d00200241bc016a200241cc036a41840110ce041a20022005360230200241306a410472200241bc016a41840110ce042107200241003a00c002200241c0026a2002280220220820022802242209410047220a10ce041a2009200a490d0620022009200a6b220436022420022008200a6a220a360220024002402009450d0020022d00c00222084103490d010b200241306a103d0c010b200242003703c002200241c0026a200a2004410820044108491b220910ce041a2002200420096b3602242002200a20096a360220200441074b0d02200241306a103d0b418f89c3004133104e000b200041123602080c010b20022903c002210b200241c0026a200741840110ce041a200220022800293602cc0320022002412c6a2800003600cf03200241306a200241c0026a41840110ce041a200220022800cf033600bf01200220022802cc033602bc012001102920002005360208200020063703002000410c6a200241306a41840110ce041a20004198016a20083a000020004190016a200b370200200020022802bc01360099012000419c016a20022800bf013600000b20031029200241d0046a24000f0b411a4101102a000b41344101102a000b200a2009103e000bfc0202047f017e230041d0006b22022400024002400240411310272203450d002003410f6a4100280096d243360000200341086a410029008fd24337000020034100290087d24337000020034113412610282203450d0120032001360013200241306a41186a22014200370300200241306a41106a22044200370300200241306a41086a220542003703002002420037033020034117200241306a1000200241086a41186a2001290300370300200241086a41106a2004290300370300200241086a41086a20052903003703002002200229033037030820024100360230200241086a4120200241306a100521040240024020022802302201417f460d002002200136022c20022004360228200241306a200241286a102d20022802302205450d042002290234210602402001450d00200410290b20002006370204200020053602000c010b20004100360208200042013702000b20031029200241d0006a24000f0b41134101102a000b41264101102a000b418f89c3004133104e000bc80301047f230041c0006b2202240002400240024002400240411010272203450d00200341086a41002900a6d1433700002003410029009ed1433700002001280200210420034110412010282203450d01200320043600102003412041c00010282203450d02200320012900043700142003412c6a2001411c6a290000370000200341246a200141146a2900003700002003411c6a2001410c6a290000370000200241206a41186a22014200370300200241206a41106a22044200370300200241206a41086a220542003703002002420037032020034134200241206a1000200241186a2001290300370300200241106a2004290300370300200241086a200529030037030020022002290320370300410021042002410036022020024120200241206a100521050240024020022802202201417f460d00200241003a0020200241206a20052001410047220410ce041a20012004490d052001450d0620022d0020220141ff0071220441064f0d0620051029200141077621010c010b410021010b20031029200020043a0001200020013a0000200241c0006a24000f0b41104101102a000b41204101102a000b41c0004101102a000b20042001103e000b418f89c3004133104e000b8f0e04017f047e117f087e230041a0036b22052400024002400240024002400240024020040d00420021064200210742002108420021090c010b20054180036a41186a220a420037030020054180036a41106a220b420037030020054180036a41086a220c42003703002005420037038003419ad2c300411d20054180036a1000200541c0026a41186a200a290300370300200541c0026a41106a200b290300370300200541c0026a41086a200c29030037030020052005290380033703c0024100210c200541003602d801200541c0026a4120200541d8016a1005210d024020052802d801220a417f460d0020054180036a200a4120200a4120491b220b6a410041004120200b6b200b411f4b1b10cd041a20054180036a200d200b10ce041a200a411f4d0d02200541d8016a41186a220a20054180036a41186a290300370300200541d8016a41106a220b20054180036a41106a290300370300200541d8016a41086a220c20054180036a41086a29030037030020052005290380033703d801200d102920054190016a41186a200a29030037030020054190016a41106a200b29030037030020054190016a41086a200c290300370300200520052903d801370390014101210c0b41281027220b450d02200b200c3a0004200b41b8d6c500360200200b200529039001370005200b20052f00d8013b0025200b410d6a20054190016a41086a290300370000200b41156a20054190016a41106a290300370000200b411d6a20054190016a41186a290300370000200b41276a200541da016a2d00003a000020054190016a200b10ad0342002108420021094200210642002107024020052d00d0014106460d002004417f6a210e200541d8016a41c0006a210f200541d8016a41206a2110200541d8016a41186a2111200341ff0171211242002106420021074200210842002109034020112007370300200520063703e801200520083703d801200520093703e001201020054190016a41c10010ce04210a02400240200f2002460d00200f2002412010d0040d010b200541e0026a41186a220c200a41186a2213290200370300200541e0026a41106a220d200a41106a2214290200370300200541e0026a41086a2215200a41086a22162902003703002005200a2902003703e002411010272204450d06200441086a41002900a6d1433700002004410029009ed14337000020044110412010282204450d07200420013600102004412041c00010282204450d08200420052903e0023700142004412c6a200c290300370000200441246a200d2903003700002004411c6a201529030037000020054180036a41186a2217420037030020054180036a41106a2218420037030020054180036a41086a2219420037030020054200370380032004413420054180036a1000200541c0026a41186a2017290300370300200541c0026a41106a2018290300370300200541c0026a41086a201929030037030020052005290380033703c002200541c0026a412041b8d6c50041004100100b211a20041029201a417f470d0020052d00b8022104200c2013290000370300200d2014290000370300201520162900003703002005200a2900003703e00202404100417f4101200420124b1b20042012461b41016a41014b0d00200321040b20054180016a200541e0026a10950120054180016a41086a290300211b200529038001211c02400240200441ff01710d002005201c201b420a420010d4042017200c2903003703002018200d29030037030020192015290300370300200520052903e00237038003200541106a200120054180036a4100200e10aa03200541106a41186a290300211d200541106a41086a290300211e2005290320211f2005290310212020052903002221211c200541086a2903002222211b0c010b200541c0006a201b42002004ad42ff01832221420010d304200541d0006a201c42002021420010d3042017200c2903003703002018200d29030037030020192015290300370300200520052903e00237038003200541e0006a200120054180036a2004200e10aa03200541306a42004200201c420010d304427f200541d0006a41086a2903002221200529034020052903307c7c221d2005290348200529033884420052201d2021547222041b2122427f200529035020041b2121200541e0006a41186a290300211d200541e0006a41086a290300211e2005290370211f200529036021200b201b20077c201c20067c2207201c54ad7c201d7c2007201f7c2206200754ad7c2107202220097c202120087c2209202154ad7c201e7c200920207c2208200954ad7c21090b20054190016a200b10ad0320052d00d0014106470d000b0b200b10290b2000200637031020002008370300200041186a200737030020002009370308200541a0036a24000f0b418f89c3004133104e000b41284104102a000b41104101102a000b41204101102a000b41c0004101102a000b8607010d7f230041e0006b220124000240024002400240024002400240411a10272202450d00200241186a41002f00dbd1433b0000200241106a41002900d3d143370000200241086a41002900cbd143370000200241002900c3d1433700002002411a413410282202450d012002200036001a200141c0006a41186a22034200370300200141c0006a41106a22044200370300200141c0006a41086a22054200370300200142003703402002411e200141c0006a1000200141206a41186a2003290300370300200141206a41106a2004290300370300200141206a41086a200529030037030020012001290340370320200141206a4120100c20021029411310272202450d022002410f6a4100280096d243360000200241086a410029008fd24337000020024100290087d24337000020024113412610282202450d0320022000360013200141c0006a41186a22044200370300200141c0006a41106a22054200370300200141c0006a41086a220342003703002001420037034020024117200141c0006a1000200141206a41186a22062004290300370300200141206a41106a22072005290300370300200141206a41086a200329030037030020012001290340370320200141206a4120100c20021029200141c0006a200010a8032001280244210820012802402109024020012802482202450d002002410574210a200921030340200141186a220b200341186a290000370300200141106a220c200341106a290000370300200141086a220d200341086a29000037030020012003290000370300411010272202450d06200241086a41002900a6d1433700002002410029009ed14337000020024110412010282202450d07200220003600102002412041c00010282202450d08200341206a2103200220012903003700142002412c6a200b290300370000200241246a200c2903003700002002411c6a200d2903003700002004420037030020054200370300200141c0006a41086a220b42003703002001420037034020024134200141c0006a10002006200429030037030020072005290300370300200141206a41086a200b29030037030020012001290340370320200141206a4120100c20021029200a41606a220a0d000b0b02402008450d00200910290b200141e0006a24000f0b411a4101102a000b41344101102a000b41134101102a000b41264101102a000b41104101102a000b41204101102a000b41c0004101102a000bfa0201057f230041d0006b22022400024002400240411710272203450d002003410f6a41002900ffd143370000200341086a41002900f8d143370000200341002900f0d14337000020034117412e10282203450d0120032001370017200241306a41186a22044200370300200241306a41106a22054200370300200241306a41086a22064200370300200242003703302003411f200241306a1000200241086a41186a2004290300370300200241086a41106a2005290300370300200241086a41086a20062903003703002002200229033037030820024100360230200241086a4120200241306a100521050240024020022802302204417f460d002002200436022c20022005360228200241306a200241286a103b20022802302206450d042002290234210102402004450d00200510290b20002001370204200020063602000c010b20004100360208200042083702000b20031029200241d0006a24000f0b41174101102a000b412e4101102a000b418f89c3004133104e000bec0903037f047e097f23002202210320024180036b416071220224002001411c6a220429020021052004200229039802370200200141146a2204290200210620042002290390023702002001410c6a220429020021072004200229038802370200200241003a00800220012902042108200120022903800237020420022005370378200220063703702002200737036820022008370360200141246a2d0000210920024180026a41176a2204200537000020024180026a41106a220a200229007137030020024180026a41086a220b2002290069370300200220022900613703800202402008a741ff01714101460d00200041063a0040200324000f0b200241186a41176a2004290000370000200241186a41106a200a290300370300200241186a41086a200b29030037030020022002290380023703180240024002400240411510272204450d002004410d6a41002900bbd143370000200441086a41002900b6d143370000200441002900aed14337000020044115413510282204450d0120042002290318370015200420093a00342004412c6a2002412f6a290000370000200441256a200241186a41106a2903003700002004411d6a200241186a41086a29030037000020024180026a41186a220a420037030020024180026a41106a220b420037030020024180026a41086a220c420037030020024200370380022004413520024180026a1000200241e0016a41186a200a290300370300200241e0016a41106a200b290300370300200241e0016a41086a200c29030037030020022002290380023703e0012002410036028002200241e0016a412020024180026a1005210d200228028002220e417f460d032002200e36023c2002200d36023820024180026a200241386a10fc0220022d00a1024102460d02200241b8016a41206a220a20024180026a41206a2d00003a0000200241b8016a41186a220b20024180026a41186a290300370300200241b8016a41106a220c20024180026a41106a290300370300200241b8016a41086a220f20024180026a41086a29030037030020022002290380023703b801200241e0006a200241a2026a41c10010ce041a0240200e450d00200d10290b200241386a41086a220e200f290300370300200241386a41106a220d200c290300370300200241386a41186a2210200b290300370300200241386a41206a2211200a2d00003a0000200220022903b80137033820024180026a200241e0006a41c10010ce041a200a20112d00003a0000200b2010290300370300200c200d290300370300200f200e290300370300200220022903383703b801200241e0006a20024180026a41c10010ce041a200141246a200241e0006a41c0006a2d00003a00002001411c6a200241e0006a41386a290000370000200141146a200241e0006a41306a2900003700002001410c6a200241e0006a41286a290000370000200120022900800137000420002002290318370000200041086a200241186a41086a290300370000200041106a200241186a41106a290300370000200041176a200241186a41176a290000370000200020093a001f200020022903b801370020200041286a200f290300370000200041306a200c290300370000200041386a200b290300370000200041c0006a200a2d00003a000020041029200324000f0b41154101102a000b41354101102a000b418f89c3004133104e000b41b6b7c30041d700104e000bd50703037f047e047f230022022103200241a0026b416071220224002001411c6a22042902002105200420022903b801370200200141146a22042902002106200420022903b0013702002001410c6a22042902002107200420022903a801370200200241003a00a00120012902042108200120022903a00137020420022005370338200220063703302002200737032820022008370320200141246a2d00002109200241a0016a41176a22042005370000200241a0016a41106a220a2002290031370300200241a0016a41086a220b2002290029370300200220022900213703a00102402008a741ff01714101460d0020004200370300200324000f0b200241176a2004290000370000200241106a200a290300370300200241086a200b290300370300200220022903a0013703000240024002400240411210272204450d00200441106a41002f0088a3443b0000200441086a4100290080a344370000200441002900f8a24437000020044112413210282204450d0120042002290300370012200420093a0031200441296a200241176a290000370000200441226a200241106a2903003700002004411a6a200241086a290300370000200241a0016a41186a220a4200370300200241a0016a41106a220b4200370300200241a0016a41086a220c4200370300200242003703a00120044132200241a0016a100020024180016a41186a200a29030037030020024180016a41106a200b29030037030020024180016a41086a200c290300370300200220022903a00137038001200241003602a00120024180016a4120200241a0016a1005210b20022802a001220a417f460d032002200a36029c022002200b36029802200241a0016a20024198026a10af0320022d00b8014102460d02200241a0016a41086a290300210520022903a001210820022802b001210c200241206a200241b9016a41c70010ce041a0240200a450d00200b10290b200241a0016a200241206a41c10010ce041a200241206a200241a0016a41c10010ce041a200141246a200241e0006a2d00003a00002001411c6a200241206a41386a290000370000200141146a200241206a41306a2900003700002001410c6a200241206a41286a2900003700002001200229004037000420002002290300370008200041106a200241086a290300370000200041186a200241106a2903003700002000411f6a200241176a290000370000200041306a2005370300200041286a2008370300200041386a200c360200200020093a00272000420137030020041029200324000f0b41124101102a000b41324101102a000b418f89c3004133104e000b41b6b7c30041d700104e000b860905027f027e057f017e027f23004190026b22022400200241206a2001102e0240024002402002280220450d0020022802242103200241086a200110532002290308a70d010b200041023a00180c010b200241186a290300210420022903102105200241003a00f001200241f0016a2001280200220620012802042207410047220810ce041a02400240024020072008490d002001200720086b22093602042001200620086a22083602002007450d0220022d00f001220741014b0d02410021060240024020070e020100010b200241f0016a2009412020094120491b22076a41004100412020076b2007411f4b1b10cd041a200241f0016a2008200710ce041a2001200920076b220a3602042001200820076a22083602002009411f4d0d03200241b0016a41086a200241f0016a41086a290000220b37030020024190016a41186a200241f0016a41186a29000037030020024190016a41106a200241f0016a41106a29000037030020024190016a41086a200b370300200220022900f001220b3703b0012002200b3703900141012106200a21090b200241f0006a41186a20024190016a41186a290300370300200241f0006a41106a20024190016a41106a290300370300200241f0006a41086a20024190016a41086a2903003703002002200229039001370370200241003a00f001200241f0016a20082009410047220710ce041a20092007490d012001200920076b220a3602042001200820076a22073602002009450d0220022d00f001220841014b0d02410021090240024020080e020100010b200241f0016a200a4120200a4120491b22086a41004100412020086b2008411f4b1b10cd041a200241f0016a2007200810ce041a2001200a20086b3602042001200720086a360200200a411f4d0d03200241b0016a41086a200241f0016a41086a290000220b37030020024190016a41186a200241f0016a41186a29000037030020024190016a41106a200241f0016a41106a29000037030020024190016a41086a200b370300200220022900f001220b3703b0012002200b37039001410121090b200241306a41186a220120024190016a41186a290300370300200241306a41106a220720024190016a41106a290300370300200241306a41086a220820024190016a41086a290300370300200241d0006a41086a220a200241f0006a41086a290300370300200241d0006a41106a220c200241f0006a41106a290300370300200241d0006a41186a220d200241f0006a41186a2903003703002002200229039001370330200220022903703703502000200437030820002005370300200020063a001820002003360210200041396a20093a000020002002290350370019200041216a200a290300370000200041296a200c290300370000200041316a200d2903003700002000413a6a2002290330370100200041c2006a2008290300370100200041ca006a2007290300370100200041d2006a2001290300370100200041de006a2002412e6a2f01003b0100200041da006a200228012a3601000c030b20082007103e000b20072009103e000b200041023a00180b20024190026a24000b3400200041ceb8c30036020420004100360200200041146a4107360200200041106a41d4b8c300360200200041086a42043702000b950101057f230041206b22022400200241186a22034200370300200241106a22044200370300200241086a220542003703002002420037030002404120102722060d0041204101102a000b20062002290300370000200042a0808080800437020420002006360200200641186a2003290300370000200641106a2004290300370000200641086a2005290300370000200241206a24000b130020004102360204200041e4c5c3003602000b3101017f02404108102722020d0041084101102a000b20004288808080800137020420002002360200200242f02e3700000b3101017f02404108102722020d0041084101102a000b20004288808080800137020420002002360200200242eb023700000bef0803037f017e047f230041f0026b22052400200541c986c500411910b5010240024002402005280204410020052802001b2206417f6a220720064d0d00200541123602100c010b200541086a200710a70320052802104112460d00200541a8016a200541086a41a00110ce041a20052903a8012108200541a8016a41086a103d20082001580d00200041f7d2c30036020420004101360200200041086a41c7003602002002103d0c010b200541a8016a41086a22074200370300200542003703a80141c986c5004119200541a8016a1004200541086a41086a2007290300370300200520052903a8013703082005200641016a3602a801200541086a4110200541a8016a41041003200520013703a8012007200241880110ce042109200520033a00c002200520043703b802024002400240024002400240411a10272207450d00200741186a41002f00dbd1433b0000200741106a41002900d3d143370000200741086a41002900cbd143370000200741002900c3d1433700002007411a413410282202450d012002200636001a200541086a41186a22074200370300200541086a41106a220a4200370300200541086a41086a220b4200370300200542003703082002411e200541086a1000200541c8026a41186a2007290300370300200541c8026a41106a200a290300370300200541c8026a41086a200b290300370300200520052903083703c802200541003602102005420137030820052903a8012101410810272207450d022005410836020c20052005280210220a41086a360210200520073602082007200a6a20013700002009200541086a1032024020052d00c002220741024b0d00024002400240024020070e03000102000b4100210a0c020b4101210a0c010b4102210a0b2005200a3a00ef0202400240200528020c20052802102207460d002005280208210b0c010b200741016a220b2007490d072007410174220c200b200b200c491b220c4100480d070240024020070d00200c1027210b0c010b20052802082007200c1028210b0b200b450d052005200c36020c2005200b360208200528021021070b2005200741016a360210200b20076a200a3a00000b20052903b802210102400240200528020c220a200528021022076b4108490d002005280208210a0c010b200741086a220b2007490d06200a4101742207200b200b2007491b22074100480d0602400240200a0d0020071027210a0c010b2005280208200a20071028210a0b200a450d052005200736020c2005200a360208200528021021070b2005200741086a360210200a20076a2001370000200528020c2107200541c8026a41202005280208220a2005280210100302402007450d00200a10290b200210292009103d200541b4016a2006360200200541b1016a20033a0000200541a8016a41086a41033a0000200541053a00a80141b8d6c5004100200541a8016a10880120004100360200200020063602040c060b411a4101102a000b41344101102a000b41084101102a000b200c4101102a000b20074101102a000b102b000b200541f0026a24000bd10302047f037e230041d0006b2202240002400240411310272203450d002003410f6a41002800ecd143360000200341086a41002900e5d143370000200341002900ddd14337000020034113412610282203450d0120032001360013200241286a41186a22014200370300200241286a41106a22044200370300200241286a41086a220542003703002002420037032820034117200241286a1000200241086a41186a2001290300370300200241086a41106a2004290300370300200241086a41086a20052903003703002002200229032837030820024100360228200241086a4120200241286a1005210102400240024020022802282204417f460d002001450d00200220013602482002200436024c2002420037033020024200370328200241286a20012004411020044110491b220510ce041a2002200420056b36024c2002200120056a36024802402004410f4d0d00200241306a290300210620022903282107200241286a200241c8006a102d200228022822040d020b418f89c3004133104e000b410021040c010b200229022c2108200110292000200637030820002007370300200020083702140b2000200436021020031029200241d0006a24000f0b41134101102a000b41264101102a000b130020004111360204200041bcd4c3003602000b3400200041f3f3c30036020420004100360200200041146a410f360200200041106a41fcf3c300360200200041086a42093702000ba00101037f230041a0016b220224002002411236020020024100360298012002420137039001200241003a009f010240410110272203450d002002200336029001200320022802980122046a20022d009f013a000020024101360294012002200441016a2203360298012000200229039001370200200041086a2003360200024020022802004112460d002002103d0b200241a0016a24000f0b41014101102a000bb70101057f230041206b22022400200241186a22034200370300200241106a22044200370300200241086a220542003703002002420037030002400240412010272206450d0020062002290300370000200641186a2003290300370000200641106a2004290300370000200641086a20052903003700002006412041c00010282206450d01200042c0808080900437020420002006360200200641003a0020200241206a24000f0b41204101102a000b41c0004101102a000b4901017f230041106b2202240020024100360208200242013703002002410036020c2002410c6a20021030200041086a200228020836020020002002290300370200200241106a24000b1300200041063602042000419490c4003602000b3201017f02404108102722020d0041084101102a000b2000428880808080013702042000200236020020024280af1a3700000b3201017f02404108102722020d0041084101102a000b20004288808080800137020420002002360200200242c0d1023700000b3e01017f02404110102722020d0041104101102a000b20024200370008200242808084fea6dee111370000200042908080808002370204200020023602000b3201017f02404108102722020d0041084101102a000b2000428880808080013702042000200236020020024280ce183700000be51a03037f027e067f230041f0016b220224000240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024020012802000e12000102030405060708090a0b0c0d0e0f1011000b200241e8006a200141086a10960220004100360200200041106a200241e8006a41086a290300370300200041086a20022903683703000c110b109702000b20004102360200200041086a200141086a2903003703000c0f0b200241e8006a200141046a1038200041033602002000410c6a200241f0006a280200360200200020022903683702040c0e0b109802000b0240024002400240200141086a280200417f6a220341014b0d0020030e020102010b41e4bdc0001058000b41012103024002402001410c6a22042d00004101460d00200241026a200441036a2d00003a0000200241f0006a2001411c6a290200370300200241e8006a41106a200141246a29020037030020024180016a2001412c6a2d00003a0000200220042f00013b01002002200141146a290200370368200141106a2802002104410021030c010b200141106a28020021040b200241246a41026a200241026a2d00003a0000200241286a41086a200241e8006a41086a290300370300200241286a41106a200241e8006a41106a290300370300200241286a41186a200241e8006a41186a280200360200200220022f01003b012420022002290368370328200141386a29030021052001290330210641012107200241106a21010c010b41012103024002402001410c6a22042d00004101460d00200241ee016a200441036a2d00003a0000200241f0006a2001411c6a290200370300200241e8006a41106a200141246a29020037030020024180016a2001412c6a2d00003a0000200220042f00013b01ec012002200141146a290200370368200141106a2802002104410021030c010b200141106a28020021040b41022107200241246a41026a200241ec016a41026a2d00003a0000200241286a41086a200241e8006a41086a290300370300200241286a41106a200241e8006a41106a290300370300200241286a41186a200241e8006a41186a280200360200200220022f01ec013b012420022002290368370328200220012903303703102002200141386a290300370318200141c8006a290300210520012903402106200221010b20012006370300200120053703082000410c6a20033a0000200041086a2007360200200020022f01243b000d2000410f6a200241266a2d00003a0000200041106a2004360200200041146a20022903283702002000411c6a200241286a41086a290300370200200041246a200241286a41106a2903003702002000412c6a200241c0006a280200360200200041386a200241106a41086a290300370300200041306a2002290310370300200041c0006a2002290300370300200041c8006a200241086a290300370300200041053602000c0c0b200241e8006a200141086a10990220004106360200200041386a200241e8006a41306a290300370300200041306a200241e8006a41286a290300370300200041286a200241e8006a41206a290300370300200041206a200241e8006a41186a290300370300200041186a200241e8006a41106a290300370300200041106a200241e8006a41086a290300370300200041086a20022903683703000c0b0b200241e8006a41186a200141286a290000370300200241e8006a41106a200141206a290000370300200241f0006a200141186a290000370300200241e8006a41286a200141386a290000370300200241e8006a41306a200141c0006a290000370300200241e8006a41386a200141c8006a2900003703002002200141106a2900003703682002200141306a290000370388012001410c6a2802002203417f4c0d0b0240024020030d00410121010c010b20012802042104200310272201450d0d20012004200310ce041a0b200241286a41386a2204200241e8006a41386a290300370300200241286a41306a2207200241e8006a41306a290300370300200241286a41286a2208200241e8006a41286a290300370300200241286a41206a2209200241e8006a41206a290300370300200241286a41186a220a200241e8006a41186a290300370300200241286a41106a220b200241e8006a41106a290300370300200241286a41086a220c200241e8006a41086a290300370300200220022903683703282000410c6a2003360200200041086a200336020020002001360204200041106a2002290328370200200041186a200c290300370200200041206a200b290300370200200041286a200a290300370200200041306a2009290300370200200041386a2008290300370200200041c0006a2007290300370200200041c8006a2004290300370200200041073602000c0a0b200241e8006a200141086a109a0220004108360200200041386a200241e8006a41306a290300370300200041306a200241e8006a41286a290300370300200041286a200241e8006a41206a290300370300200041206a200241e8006a41186a290300370300200041186a200241e8006a41106a290300370300200041106a200241e8006a41086a290300370300200041086a20022903683703000c090b200241e8006a200141046a109b0220004109360200200041246a20024188016a2903003702002000411c6a20024180016a290300370200200041146a200241f8006a2903003702002000410c6a200241f0006a290300370200200020022903683702040c080b200241e8006a200141046a109b022000410a360200200041246a20024188016a2903003702002000411c6a20024180016a290300370200200041146a200241f8006a2903003702002000410c6a200241f0006a290300370200200020022903683702040c070b200241e8006a200141086a10c8012000410b360200200041c0006a200241e8006a41386a290300370300200041386a200241e8006a41306a290300370300200041306a200241e8006a41286a290300370300200041286a200241e8006a41206a290300370300200041206a200241e8006a41186a290300370300200041186a200241e8006a41106a290300370300200041106a200241e8006a41086a290300370300200041086a20022903683703000c060b2000410c360200200041086a200141086a2903003703000c050b2001410c6a2802002203417f4c0d050240024020030d00410121010c010b20012802042104200310272201450d0820012004200310ce041a0b200020013602042000410d3602002000410c6a2003360200200041086a20033602000c040b024002400240024002400240200141086a280200417f6a220341024b0d0020030e03010203010b4190a9c1001058000b200141386a2903002105200141306a290300210641012103024002402001410c6a2d00004101460d00200241f0006a2001411c6a290200370300200241e8006a41106a200141246a29020037030020024180016a2001412c6a2d00003a00002002200141146a29020037036820012f000d2001410f6a2d0000411074722104200141106a2802002101410021030c010b200141106a28020021010b200241286a41186a200241e8006a41186a280200360200200241286a41106a200241e8006a41106a290300370300200241286a41086a200241e8006a41086a29030037030020022002290368370328410121070c030b2001410c6a28020022034108762104410221070c010b2001410c6a28020022034108762104410321070b0b2000410e360200200041386a2005370300200041306a2006370300200041106a2001360200200041086a2007360200200041146a20022903283702002000410c6a2004410874200341ff0171723602002000411c6a200241286a41086a290300370200200041246a200241286a41106a2903003702002000412c6a200241c0006a2802003602000c030b200241e8006a200141086a109c02200041086a200241e8006a41800110ce041a2000410f3602000c020b02400240024002402001280204417f6a220341014b0d0020030e020102010b41f8e2c1001058000b41880110272203450d072003200141086a280200109502410121010c010b4101210302400240200141086a2d00004101460d00200241e8006a41086a200141186a290200370300200241e8006a41106a200141206a290200370300200241e8006a41186a200141286a2d00003a00002002200141106a29020037036820012f00092001410b6a2d00004110747221072001410c6a2802002104410021030c010b2001410c6a28020021040b200241286a41186a200241e8006a41186a280200360200200241286a41106a200241e8006a41106a290300370300200241286a41086a200241e8006a41086a2903003703002002200229036837032820032007410874722103410221010b20002001360204200041103602002000410c6a2004360200200041086a2003360200200041106a2002290328370200200041186a200241286a41086a290300370200200041206a200241286a41106a290300370200200041286a200241286a41186a2802003602000c010b200241e8006a200141086a10b101200041086a200241e8006a41d80010ce041a200041113602000b200241f0016a24000f0b1039000b20034101102a000b20034101102a000b4188014108102a000bb20503047f027e057f230041d0006b220224000240411310272203450d002003410f6a41002800ecd143360000200341086a41002900e5d143370000200341002900ddd143370000024020034113412610282204450d0020042000360013200241286a41186a22034200370300200241286a41106a22004200370300200241286a41086a220542003703002002420037032820044117200241286a1000200241086a41186a2003290300370300200241086a41106a2000290300370300200241086a41086a2005290300370300200220022903283703082002410036023020024201370328200141086a2903002106200129030021070240411010272203450d00200320073700002003200637000820024290808080800237022c20022003360228200128021021082002200141186a280200220336024c200241cc006a200241286a10300240024020030d0020022802302105200228022c21092002280228210a0c010b2003410574210b2002280228210a200228022c21092002280230210020082103034002400240200920006b4120490d00200041206a21050c010b0240200041206a22052000490d002009410174220c20052005200c491b220c4100480d000240024020090d00200c1027210a0c010b200a2009200c1028210a0b0240200a450d00200c21090c020b200c4101102a000b102b000b200a20006a22002003290000370000200041186a200341186a290000370000200041106a200341106a290000370000200041086a200341086a29000037000020052100200341206a2103200b41606a220b0d000b2002200936022c200220053602302002200a3602280b200241086a4120200a2005100302402009450d00200a10290b200410290240200141146a280200450d00200810290b200241d0006a24000f0b41104101102a000b41264101102a000b41134101102a000bbd0402087f047e230041e0006b22022400024002400240410f10272203450d00200341076a41002900909d44370000200341002900899d443700002003410f412f10282203450d012003200129000037000f200341276a200141186a2900003700002003411f6a200141106a290000370000200341176a200141086a290000370000200241206a41186a22014200370300200241206a41106a22044200370300200241206a41086a22054200370300200242003703202003412f200241206a1000200241186a2001290300370300200241106a2004290300370300200241086a2005290300370300200220022903203703002002410036024020024120200241c0006a100521050240024020022802402201417f460d00200241206a2001412020014120491b22046a41004100412020046b2004411f4b1b10cd041a200241206a2005200410ce041a2001411f4d0d04200241c0006a41186a2201200241206a41186a2204290300370300200241c0006a41106a2206200241206a41106a2207290300370300200241c0006a41086a2208200241206a41086a2209290300370300200220022903203703402005102920042001290300220a37030020072006290300220b37030020092008290300220c37030020022002290340220d370320200041013a00002000200d370001200041096a200c370000200041116a200b370000200041196a200a3700000c010b200041003a00000b20031029200241e0006a24000f0b410f4101102a000b412f4101102a000b418f89c3004133104e000bba0f010f7f230041f0006b22042400024002400240024002400240024002400240024002400240411a10272205450d00200541186a41002f00dbd1433b0000200541106a41002900d3d143370000200541086a41002900cbd143370000200541002900c3d1433700002005411a413410282205450d012005200136001a200441c8006a41186a22064200370300200441c8006a41106a22074200370300200441c8006a41086a22084200370300200442003703482005411e200441c8006a1000200441286a41186a2006290300370300200441286a41106a2007290300370300200441286a41086a200829030037030020042004290348370328200441286a412041b8d6c50041004100100b21062005102902400240024002402006417f470d0041839ec40021070c010b200441086a41186a200041186a290000370300200441086a41106a200041106a290000370300200441086a41086a200041086a29000037030020042000290000370308411010272205450d05200541086a41002900a6d1433700002005410029009ed14337000020054110412010282205450d06200520013600102005412041c00010282205450d07200520042903083700142005412c6a200441086a41186a2209290300370000200541246a200441086a41106a220a2903003700002005411c6a200441086a41086a220b290300370000200441c8006a41186a22064200370300200441c8006a41106a22074200370300200441c8006a41086a220842003703002004420037034820054134200441c8006a1000200441286a41186a2006290300370300200441286a41106a2007290300370300200441286a41086a200829030037030020042004290348370328200441286a412041b8d6c50041004100100b210c200510290240200c417f470d00200441086a200110a8032006200041186a2900003703002007200041106a2900003703002008200041086a2900003703002004200029000037034802400240200428020c220d20042802102206460d00200641016a21052004280208210e0c010b200641016a22052006490d0420064101742207200520052007491b220d41ffffff3f71200d470d04200d41057422074100480d040240024020060d0020071027210e0c010b2004280208200641057420071028210e0b200e450d0a2004200d36020c2004200e3602080b200e20064105746a22062004290348370000200641186a200441c8006a41186a290300370000200641106a200441c8006a41106a290300370000200641086a200441c8006a41086a29030037000020042005360210411310272206450d0a2006410f6a4100280096d243360000200641086a410029008fd24337000020064100290087d2433700002006411341261028220f450d0b200f2001360013200441c8006a41186a22064200370300200441c8006a41106a22074200370300200441c8006a41086a2208420037030020044200370348200f4117200441c8006a1000200441286a41186a2006290300370300200441286a41106a2007290300370300200441286a41086a20082903003703002004200429034837032820044100360250200442013703482004200536026c200441ec006a200441c8006a10300240024020050d0020042802502106200428024c210c200428024821100c010b200541057421114100200428025022066b210820042802482110200428024c210c200e210503400240200c20086a411f4b0d00200641206a22072006490d06200c4101742212200720072012491b22074100480d0602400240200c0d002007102721100c010b2010200c2007102821100b2010450d052007210c0b201020066a22072005290000370000200741186a200541186a290000370000200741106a200541106a290000370000200741086a200541086a290000370000200841606a2108200641206a2106200541206a2105201141606a22110d000b2004200c36024c20042006360250200420103602480b200441286a41202010200610030240200c450d00201010290b200f1029200d450d00200e10290b2009200041186a290000370300200a200041106a290000370300200b200041086a29000037030020042000290000370308411010272205450d0b200541086a41002900a6d1433700002005410029009ed14337000020054110412010282205450d0c200520013600102005412041c00010282205450d0d200520042903083700142005412c6a200441086a41186a290300370000200541246a200441086a41106a2903003700002005411c6a200441086a41086a290300370000200441c8006a41186a22064200370300200441c8006a41106a22074200370300200441c8006a41086a220842003703002004420037034820054134200441c8006a1000200441286a41186a2006290300370300200441286a41106a2007290300370300200441286a41086a200829030037030020042004290348370328410110272206450d0e41002107200641807f410020021b2003723a0000200441286a412020064101100320061029200510290b200441f0006a240020070f0b20074101102a000b102b000b411a4101102a000b41344101102a000b41104101102a000b41204101102a000b41c0004101102a000b20074101102a000b41134101102a000b41264101102a000b41104101102a000b41204101102a000b41c0004101102a000b41014101102a000bec0302047f027e230041d0006b2202240002400240411310272203450d002003410f6a41002800bb9c44360000200341086a41002900b49c44370000200341002900ac9c4437000020034113413310282203450d01200320012900003700132003412b6a200141186a290000370000200341236a200141106a2900003700002003411b6a200141086a290000370000200241286a41186a22014200370300200241286a41106a22044200370300200241286a41086a220542003703002002420037032820034133200241286a1000200241086a41186a2001290300370300200241086a41106a2004290300370300200241086a41086a20052903003703002002200229032837030820024100360228200241086a4120200241286a1005210102400240024020022802282204417f460d002001450d00200220013602482002200436024c20024200370328200241286a20012004410820044108491b220510ce041a2002200420056b36024c2002200120056a3602480240200441074d0d0020022903282106200241286a200241c8006a102d200228022822040d020b418f89c3004133104e000b410021040c010b200229022c2107200110292000200737020c200020063703000b2000200436020820031029200241d0006a24000f0b41134101102a000b41334101102a000bf40801037f200141046a2802002102200141086a280200210302400240024002400240024002400240024020002d00004101460d000240024020022003460d00200128020021020c010b200341016a22022003490d0920034101742204200220022004491b22044100480d090240024020030d002004102721020c010b200128020020032004102821020b2002450d0320012002360200200141046a2004360200200141086a28020021030b200141086a200341016a360200200220036a41003a00000c010b0240024020022003460d00200128020021020c010b200341016a22022003490d0820034101742204200220022004491b22044100480d080240024020030d002004102721020c010b200128020020032004102821020b2002450d0320012002360200200141046a2004360200200141086a28020021030b200141086a2204200341016a360200200220036a41013a000002400240200141046a2802002202200428020022036b4120490d00200128020021020c010b200341206a22042003490d0820024101742203200420042003491b22034100480d080240024020020d002003102721020c010b200128020020022003102821020b2002450d0420012002360200200141046a2003360200200141086a28020021030b200141086a200341206a360200200220036a220341186a200041196a290000370000200341106a200041116a290000370000200341086a200041096a290000370000200320002900013700000b200141046a2802002102200141086a2802002103024020002d00214101460d000240024020022003460d00200128020021000c010b200341016a22002003490d0820034101742202200020002002491b22024100480d080240024020030d002002102721000c010b200128020020032002102821000b2000450d0520012000360200200141046a2002360200200141086a28020021030b200141086a200341016a360200200020036a41003a00000f0b0240024020022003460d00200128020021020c010b200341016a22022003490d0720034101742204200220022004491b22044100480d070240024020030d002004102721020c010b200128020020032004102821020b2002450d0520012002360200200141046a2004360200200141086a28020021030b200141086a2204200341016a360200200220036a41013a000002400240200141046a2802002202200428020022036b4120490d00200128020021020c010b200341206a22042003490d0720024101742203200420042003491b22034100480d070240024020020d002003102721020c010b200128020020022003102821020b2002450d0620012002360200200141046a2003360200200141086a28020021030b200141086a200341206a360200200220036a220141186a2000413a6a290000370000200141106a200041326a290000370000200141086a2000412a6a2900003700002001200041226a2900003700000f0b20044101102a000b20044101102a000b20034101102a000b20024101102a000b20044101102a000b20034101102a000b102b000bab0201027f230041106b2202240020024100360208200242013703000240412010272203450d002003200029002c370000200341086a200041346a290000370000200341106a2000413c6a290000370000200341186a200041c4006a290000370000200242a08080808004370204200220033602002002200036020c2002410c6a200210592002200041106a36020c2002410c6a20021059200028022021032002200041286a280200220036020c2002410c6a2002103002402000450d002003200041186c6a210003402002200336020c2002410c6a20021059200341106a200210302000200341186a2203470d000b0b2002280204210320012802002001280204200228020022002002280208100302402003450d00200010290b200241106a24000f0b41204101102a000bcd0801067f230041106b220224002002410036020820024201370300200041106a200210302002200036020c2002410c6a20021059200228020421032002280208210402400240024002400240024002400240024020002d00184101460d000240024020032004460d00200228020021050c010b200441016a22032004490d0920044101742205200320032005491b22034100480d090240024020040d002003102721050c010b200228020020042003102821050b2005450d0320022003360204200220053602000b2002200441016a2206360208200520046a41003a00000c010b0240024020032004460d00200228020021050c010b200441016a22032004490d0820044101742205200320032005491b22034100480d080240024020040d002003102721050c010b200228020020042003102821050b2005450d0320022003360204200220053602000b2002200441016a360208200520046a41013a00000240024020022802042203200228020822046b4120490d00200441206a21060c010b200441206a22062004490d0820034101742207200620062007491b22074100480d080240024020030d002007102721050c010b200520032007102821050b2005450d042002200736020420022005360200200721030b200520046a220441086a200041216a290000370000200441106a200041296a290000370000200441186a200041316a290000370000200220063602082004200041196a2900003700000b02400240200041396a2d00004101460d00024020032006470d00200341016a22002003490d0920034101742204200020002004491b22004100480d090240024020030d002000102721050c010b200520032000102821050b2005450d0620022000360204200220053602000b2002200641016a360208200520066a41003a00002002280208210420022802042105200228020021030c010b024020032006470d00200341016a22042003490d0820034101742207200420042007491b22044100480d080240024020030d002004102721050c010b200520032004102821050b2005450d0620022004360204200220053602000b2002200641016a360208200520066a41013a00000240024020022802042205200228020822046b4120490d00200228020021030c010b200441206a22032004490d0820054101742206200320032006491b22064100480d080240024020050d002006102721030c010b200228020020052006102821030b2003450d072002200636020420022003360200200621050b200320046a220641086a200041c2006a290000370000200641106a200041ca006a290000370000200641186a200041d2006a2900003700002002200441206a220436020820062000413a6a2900003700000b2001280200200128020420032004100302402005450d00200310290b200241106a24000f0b20034101102a000b20034101102a000b20074101102a000b20004101102a000b20044101102a000b20064101102a000b102b000b9316010c7f230041f0026b2201240002400240024002400240411210272202450d00200241106a41002f0088a3443b0000200241086a4100290080a344370000200241002900f8a24437000020024112413210282202450d01200220002900003700122002412a6a200041186a290000370000200241226a200041106a2900003700002002411a6a200041086a290000370000200141e8006a41186a22004200370300200141e8006a41106a22034200370300200141e8006a41086a220442003703002001420037036820024132200141e8006a1000200141c8016a41186a2000290300370300200141c8016a41106a2003290300370300200141c8016a41086a2004290300370300200120012903683703c8012001410036029002200141c8016a412020014190026a100521002001280290022205417f460d032000450d032001200536024c2001200036024820014190026a200141c8006a10af0320012d00a80222034102460d02200141e8006a41186a200141c1026a290000370300200141e8006a41106a200141b9026a290000370300200141e8006a41086a200141b1026a290000370300200141f0016a41086a200141d2026a290100370300200141f0016a41106a200141da026a290100370300200141f0016a41186a200141e2026a290100370300200120012900a9023703682001200141ca026a2901003703f001200141c9026a2d0000210402402005450d00200010290b200141c8016a4120100c0c040b41124101102a000b41324101102a000b418f89c3004133104e000b410221030b200141286a41186a2200200141e8006a41186a290300370300200141286a41106a2205200141e8006a41106a290300370300200141286a41086a2206200141e8006a41086a290300370300200141086a41086a2207200141f0016a41086a2208290300370300200141086a41106a2209200141f0016a41106a220a290300370300200141086a41186a220b200141f0016a41186a220c29030037030020012001290368370328200120012903f00137030820021029024020034102460d0020082006290300370300200a2005290300370300200c2000290300370300200141c8006a41086a2007290300370300200141c8006a41106a2009290300370300200141c8006a41186a200b290300370300200120012903283703f0012001200129030837034841002102024002400240024002400240024002400240200441ff01714101470d00411210272202450d01200241106a41002f0088a3443b0000200241086a4100290080a344370000200241002900f8a24437000020024112413210282202450d02200220012903483700122002412a6a200141e0006a290300370000200241226a200141c8006a41106a2903003700002002411a6a200141c8006a41086a2903003700000b0240024020034101470d00411210272200450d04200041106a41002f0088a3443b0000200041086a4100290080a344370000200041002900f8a24437000020004112413210282200450d05200020012903f0013700122000412a6a200141f0016a41186a290300370000200041226a200141f0016a41106a2903003700002000411a6a200141f0016a41086a290300370000200141e8006a41186a22054200370300200141e8006a41106a22064200370300200141e8006a41086a220742003703002001420037036820004132200141e8006a1000200141c8016a41186a2005290300370300200141c8016a41106a2006290300370300200141c8016a41086a2007290300370300200120012903683703c8012001410036029002200141c8016a412020014190026a100521062001280290022205417f470d0141e0a3c40041d300104e000b200141e8006a41186a22004200370300200141e8006a41106a22054200370300200141e8006a41086a220642003703002001420037036841b3a4c400411a200141e8006a1000200141c8016a41186a2000290300370300200141c8016a41106a2005290300370300200141c8016a41086a2006290300370300200120012903683703c8010240200441ff01714101460d00200141c8016a4120100c0c080b412010272200450d0520002001290348370000200041186a200141c8006a41186a290300370000200041106a200141c8006a41106a290300370000200041086a200141c8006a41086a290300370000200141c8016a4120200041201003200010290c070b200120053602ec01200120063602e80120014190026a200141e8016a10af0320012d00a80222074102460d05200141b0016a41106a220820014190026a41106a2209290300370300200141b0016a41086a220a20014190026a41086a220b29030037030020012001290390023703b001200141e8006a200141a9026a220c41c70010ce041a02402005450d00200610290b200b200a29030037030020092008290300370300200120012903b00137039002200120073a00a802200c200141e8006a41c70010ce041a200141c9026a20043a0000200141ca026a2001290348370100200141d2026a200141c8006a41086a290300370100200141da026a200141c8006a41106a290300370100200141e2026a200141c8006a41186a290300370100200141e8006a41186a22044200370300200141e8006a41106a22054200370300200141e8006a41086a220642003703002001420037036820004132200141e8006a1000200141c8016a41186a2004290300370300200141c8016a41106a2005290300370300200141c8016a41086a2006290300370300200120012903683703c8012001412036026c2001200141c8016a36026820014190026a200141e8006a10c80320001029410121040c070b41124101102a000b41324101102a000b41124101102a000b41324101102a000b41204101102a000b418f89c3004133104e000b41002100410021040b02400240024002400240024020020d00410021030c010b200141e8006a41186a22054200370300200141e8006a41106a22064200370300200141e8006a41086a220742003703002001420037036820024132200141e8006a1000200141c8016a41186a2005290300370300200141c8016a41106a2006290300370300200141c8016a41086a2007290300370300200120012903683703c8012001410036029002200141c8016a412020014190026a100521062001280290022205417f460d02200120053602ec01200120063602e80120014190026a200141e8016a10af0320012d00a8024102460d01200141b0016a41106a220720014190026a41106a2208290300370300200141b0016a41086a220920014190026a41086a220a29030037030020012001290390023703b001200141e8006a200141a9026a220b41c70010ce041a02402005450d00200610290b200a200929030037030020082007290300370300200120012903b00137039002200b200141e8006a41c70010ce0420012903f001370000200141b1026a200141f0016a41086a290300370000200141b9026a200141f0016a41106a290300370000200141c1026a200141f0016a41186a290300370000200120033a00a802200141e8006a41186a22034200370300200141e8006a41106a22054200370300200141e8006a41086a220642003703002001420037036820024132200141e8006a1000200141c8016a41186a2003290300370300200141c8016a41106a2005290300370300200141c8016a41086a2006290300370300200120012903683703c8012001412036026c2001200141c8016a36026820014190026a200141e8006a10c80320021029410121030b200420004572450d020c030b418f89c3004133104e000b41e0a3c40041d300104e000b200010290b2002452003720d00200210290b200141f0026a24000bf31b01107f230041d0026b220124000240024002400240411210272202450d00200241106a41002f00f6a2443b0000200241086a41002900eea244370000200241002900e6a24437000020024112413210282202450d01200220002900003700122002412a6a200041186a290000370000200241226a200041106a2900003700002002411a6a200041086a290000370000200141b0016a41186a22004200370300200141b0016a41106a22034200370300200141b0016a41086a22044200370300200142003703b00120024132200141b0016a1000200141f8016a41186a2000290300370300200141f8016a41106a2003290300370300200141f8016a41086a2004290300370300200120012903b0013703f80120014100360260200141f8016a4120200141e0006a1005210020012802602204417f460d022000450d02200120043602c402200120003602c002200141c0006a200141c0026a102d0240024020012802402205450d0020012802442106200141e0006a200141c0026a10940320012d006022074102470d012006450d00200510290b418f89c3004133104e000b200141b0016a41186a200141f9006a290000370300200141b0016a41106a200141f1006a290000370300200141b0016a41086a200141e9006a290000370300200141a0026a41086a2001418a016a290100370300200141a0026a41106a20014192016a290100370300200141a0026a41186a2001419a016a290100370300200120012900613703b001200120014182016a2901003703a00220014181016a2d0000210302402004450d00200010290b200141f8016a4120100c0c030b41124101102a000b41324101102a000b410221070b200141206a41186a2200200141b0016a41186a290300370300200141206a41106a2204200141b0016a41106a290300370300200141206a41086a2208200141b0016a41086a290300370300200141086a2209200141a0026a41086a220a290300370300200141106a220b200141a0026a41106a220c290300370300200141186a220d200141a0026a41186a220e290300370300200120012903b001370320200120012903a00237030020021029024002400240024020074102460d00200a2008290300370300200c2004290300370300200e2000290300370300200141c0006a41086a2009290300370300200141c0006a41106a200b290300370300200141c0006a41186a200d290300370300200120012903203703a002200120012903003703404100210c024002400240024002400240024002400240200341ff01714101470d00411210272202450d01200241106a41002f00f6a2443b0000200241086a41002900eea244370000200241002900e6a2443700002002411241321028220c450d02200c2001290340370012200c412a6a200141d8006a290300370000200c41226a200141c0006a41106a290300370000200c411a6a200141c0006a41086a2903003700000b0240024020074101470d00411210272202450d04200241106a41002f00f6a2443b0000200241086a41002900eea244370000200241002900e6a2443700002002411241321028220d450d05200d20012903a002370012200d412a6a200141a0026a41186a290300370000200d41226a200141a0026a41106a290300370000200d411a6a200141a0026a41086a290300370000200141b0016a41186a22024200370300200141b0016a41106a22004200370300200141b0016a41086a22044200370300200142003703b001200d4132200141b0016a1000200141f8016a41186a2002290300370300200141f8016a41106a2000290300370300200141f8016a41086a2004290300370300200120012903b0013703f80120014100360260200141f8016a4120200141e0006a1005210020012802602204417f460d072000450d072001200436029c022001200036029802200141c0026a20014198026a102d024020012802c002220e450d00200141c8026a280200210220012802c402210f200141b0016a20014198026a10940320012d00b00122084102470d02200f450d00200e10290b418f89c3004133104e000b200141b0016a41186a22024200370300200141b0016a41106a22004200370300200141b0016a41086a22044200370300200142003703b00141c6a3c400411a200141b0016a1000200141f8016a41186a2002290300370300200141f8016a41106a2000290300370300200141f8016a41086a2004290300370300200120012903b0013703f8010240200341ff01714101460d00200141f8016a4120100c0c080b412010272202450d0520022001290340370000200241186a200141c0006a41186a290300370000200241106a200141c0006a41106a290300370000200241086a200141c0006a41086a290300370000200141f8016a4120200241201003200210290c070b200141e0006a200141b0016a41017241c10010ce041a200141b0016a200141e0006a41c30010ce041a02402004450d00200010290b200120083a006c200120023602682001200f3602642001200e360260200141ed006a200141b0016a41c30010ce041a2001418d016a20033a00002001418e016a200129034037010020014196016a200141c0006a41086a2903003701002001419e016a200141c0006a41106a290300370100200141a6016a200141c0006a41186a290300370100200141b0016a41186a22004200370300200141b0016a41106a22034200370300200141b0016a41086a22044200370300200142003703b001200d4132200141b0016a1000200141f8016a41186a2000290300370300200141f8016a41106a2003290300370300200141f8016a41086a2004290300370300200120012903b0013703f801200141003602b801200142013703b001200120023602c002200141c0026a200141b0016a1030024002402002450d002002410574210a410020012802b80122006b210420012802b001210920012802b4012108200e210203400240200820046a411f4b0d00200041206a22032000490d0e2008410174220b20032003200b491b22034100480d0e0240024020080d002003102721090c010b200920082003102821090b2009450d03200321080b200920006a22032002290000370000200341186a200241186a290000370000200341106a200241106a290000370000200341086a200241086a290000370000200441606a2104200041206a2100200241206a2102200a41606a220a0d000b200120083602b401200120003602b801200120093602b0010b200141ec006a200141b0016a10c60320012802b4012102200141f8016a412020012802b001220020012802b801100302402002450d00200010290b0240200f450d00200e10290b200d10294101210f0c080b20034101102a000b41124101102a000b41324101102a000b41124101102a000b41324101102a000b41204101102a000b41e0a3c40041d300104e000b4100210d4100210f0b02400240200c0d00410021020c010b200141b0016a41186a22024200370300200141b0016a41106a22004200370300200141b0016a41086a22034200370300200142003703b001200c4132200141b0016a1000200141f8016a41186a2002290300370300200141f8016a41106a2000290300370300200141f8016a41086a2003290300370300200120012903b0013703f80120014100360260200141f8016a4120200141e0006a1005210320012802602200417f460d042001200036029c022001200336029802200141c0026a20014198026a102d0240024020012802c002220e450d00200141c8026a280200210220012802c4022110200141b0016a20014198026a10940320012d00b0014102470d012010450d00200e10290b418f89c3004133104e000b200141e0006a200141b0016a41017241c10010ce041a200141b0016a200141e0006a41c30010ce041a02402000450d00200310290b20012002360268200120103602642001200e360260200141ed006a200141b0016a41c30010ce0420012903a002370000200141f5006a200141a0026a41086a290300370000200141fd006a200141a0026a41106a29030037000020014185016a200141a0026a41186a290300370000200120073a006c200141b0016a41186a22004200370300200141b0016a41106a22034200370300200141b0016a41086a22044200370300200142003703b001200c4132200141b0016a1000200141f8016a41186a2000290300370300200141f8016a41106a2003290300370300200141f8016a41086a2004290300370300200120012903b0013703f801200141003602b801200142013703b001200120023602c002200141c0026a200141b0016a103002402002450d002002410574210a410020012802b80122006b210420012802b001210920012802b4012108200e210203400240200820046a411f4b0d00200041206a22032000490d062008410174220b20032003200b491b22034100480d060240024020080d002003102721090c010b200920082003102821090b2009450d05200321080b200920006a22032002290000370000200341186a200241186a290000370000200341106a200241106a290000370000200341086a200241086a290000370000200441606a2104200041206a2100200241206a2102200a41606a220a0d000b200120083602b401200120003602b801200120093602b0010b200141ec006a200141b0016a10c60320012802b4012102200141f8016a412020012802b001220020012802b801100302402002450d00200010290b02402010450d00200e10290b200c1029410121020b0240200f200d45720d00200d10290b0240200c452002720d00200c10290b2006450d00200510290b200141d0026a24000f0b20034101102a000b102b000b41e0a3c40041d300104e000b13002000410d360204200041d0a4c4003602000b3400200041ced2c40036020420004100360200200041146a4115360200200041106a41d8d2c400360200200041086a42073702000b7501027f230041106b22022400200241003602082002420137030002404104102722030d0041044101102a000b2003410036000020024284808080c000370204200220033602002002410036020c2002410c6a20021030200041086a200228020836020020002002290300370200200241106a24000b3001017f02404108102722020d0041084101102a000b20004288808080800137020420002002360200200242003700000bdf0301077f230041c0006b22022400200241186a4200370300200241106a22034200370300200241086a4200370300200241286a22044100360200200242003703002002420837032020024100360238200242013703302002200236023c2002413c6a200241306a10592002200336023c2002413c6a200241306a10592002280220210320022004280200220436023c2002413c6a200241306a10300240024002402004450d00200441306c210503400240024020022802342206200228023822046b4120490d00200441206a2107200228023021060c010b200441206a22072004490d0420064101742208200720072008491b22084100480d040240024020060d002008102721060c010b200228023020062008102821060b2006450d0320022008360234200220063602300b200620046a220441086a200341186a290000370000200441106a200341206a290000370000200441186a200341286a290000370000200220073602382004200341106a2900003700002002200336023c2002413c6a200241306a1059200341306a2103200541506a22050d000b0b20002002290330370200200041086a200241306a41086a28020036020002402002280224450d00200228022010290b200241c0006a24000f0b20084101102a000b102b000b7001017f230041306b220224002002420037031020024200370308200241033602182002410036022820024201370320200241186a200241206a10302002200241086a36022c2002412c6a200241206a1059200041086a200228022836020020002002290320370200200241306a24000b3201017f02404104102722020d0041044101102a000b20004284808080c00037020420002002360200200241c0843d3600000b3001017f02404104102722020d0041044101102a000b20004284808080c00037020420002002360200200241043600000bdf0606077f047e037f037e017f017e230041a0016b2202240020024180016a41186a2203420037030020024180016a41106a2204420037030020024180016a41086a22054200370300200242003703800120024180016a2001280200220620012802042207412020074120491b220810ce041a2001200720086b3602042001200620086a360200024002402007411f4b0d00200041003602200c010b200241e0006a41186a2003290300370300200241e0006a41106a2004290300370300200241e0006a41086a20052903003703002002200229038001370360200241c8006a2001105302402002290348a70d00200041003602200c010b200241c8006a41106a29030021092002290350210a200241306a2001105302402002290330a70d00200041003602200c010b200241c0006a290300210b2002290338210c200241286a2001102e024002400240024002402002280228450d0002400240200228022c220d41aa01200d41aa01491b220e0d00410821040c010b200e41186c220710272204450d030b0240200d450d00200241106a41106a210f4100210341002106410021080340200241106a20011053024002402002290310a7450d00200f290300211020022903182111200241086a2001102e20022802080d010b200e450d03200410290c030b200841016a2107200228020c210502402008200e470d002003200720072003491b220ead42187e2212422088a70d072012a722134100480d070240024020080d002013102721040c010b200420062013102821040b2004450d060b200420066a2208201037030820082011370300200841106a2005360200200341026a2103200641186a210620072108200d2007470d000b0b20040d010b200041003602200c040b20024180016a41186a200241e0006a41186a290300221037030020024180016a41106a200241e0006a41106a290300221137030020024180016a41086a200241e0006a41086a290300221237030020022002290360221437038001200041186a200b3703002000200c370310200020093703082000200a3703002000200dad422086200ead84370224200020043602202000412c6a2014370200200041346a20123702002000413c6a2011370200200041c4006a20103702000c030b20074108102a000b20134108102a000b102b000b200241a0016a24000b130020004102360204200041b8f6c4003602000b3101017f02404104102722020d0041044101102a000b20004284808080c00037020420002002360200200241a0053600000bb90d021e7f037e230041f0026b22042400024002400240024002400240410d10272205450d00200541056a41002900aca344370000200541002900a7a3443700002005410d412d10282205450d012005200129000037000d200541256a200141186a2900003700002005411d6a200141106a290000370000200541156a200141086a290000370000200441a0026a41186a22064200370300200441a0026a41106a22074200370300200441a0026a41086a22084200370300200442003703a0022005412d200441a0026a1000200441e0016a41186a2006290300370300200441e0016a41106a2007290300370300200441e0016a41086a2008290300370300200420042903a0023703e001200441003602a002200441e0016a4120200441a0026a10052107024002400240024020042802a0022206417f460d00200441003a00a002200441a0026a20072006410047220810ce041a20062008490d062006450d0720042d00a002220641034f0d07200710292005102920060e03010302010b200510290b200441f8006a2001108c0220042d00784101470d06200441a0016a41186a20044191016a2205290000370300200441a0016a41106a20044189016a2206290000370300200441a0016a41086a20044181016a2207290000370300200420042900793703a001200441a0026a200441a0016a108d02200441c0016a41186a22082005290000370300200441c0016a41106a22092006290000370300200441c0016a41086a220a2007290000370300200420042900793703c00120042802c002220b450d06200441e0016a41186a220c2008290300370300200441e0016a41106a220d2009290300370300200441e0016a41086a220e200a290300370300200441e0016a41286a2205200441a0026a41086a2206290300370300200441e0016a41306a2207200441a0026a41106a2208290300370300200441e0016a41386a220f200441a0026a41186a2210290300370300200441086a41286a2211200441ec026a2212280200360200200441086a41206a2213200441e4026a2214290200370300200441086a41186a2215200441dc026a2216290200370300200441086a41106a2217200441d4026a2218290200370300200441086a41086a2219200441cc026a221a290200370300200420042903c0013703e001200420042903a00237038002200420042902c402370308200441386a41386a221b200f290300370300200441386a41306a221c2007290300370300200441386a41286a221d2005290300370300200441386a41206a221e200429038002370300200441386a41186a221f200c290300370300200441386a41106a2220200d290300370300200441386a41086a2221200e290300370300200420042903e001370338200f201b2903003703002007201c2903003703002005201d290300370300200441e0016a41206a221b201e290300370300200c201f290300370300200d2020290300370300200e2021290300370300200420042903383703e001200441f8006a41186a201f290300370300200441f8006a41106a2020290300370300200441f8006a41086a2021290300370300200420042903383703782010200f29030037030020082007290300370300200620052903003703002004200b3602c0022004201b2903003703a002200441c4026a22052004290308370200201a2019290300370200201820172903003702002016201529030037020020142013290300370200201220112802003602002010290300212220082008290300222320027c22243703002010202220037c2024202354ad7c37030020062903002122200420042903a002222320027c22243703a0022006202220037c2024202354ad7c370300200441c0016a200120022003109f0120043502c001210220092903002122200a2903002103200441f8006a200441a0026a10d80302402005280200450d0020042802c00210290b200242018521020c070b200441a0026a2001108c0220042d00a0024101470d05200441f8016a200441b9026a290000370300200441e0016a41106a200441b1026a290000370300200441e0016a41086a200441a9026a290000370300200420042900a1023703e001200441386a200441e0016a20022003109f0120043502384201852102200441386a41106a2903002122200441386a41086a29030021030c060b200441a0026a200120022003109f0120043502a0024201852102200441b0026a2903002122200441a8026a29030021030c050b410d4101102a000b412d4101102a000b20082006103e000b418f89c3004133104e000b420021020b2000200337030820002002370300200041106a2022370300200441f0026a24000b0900200042003702000bdb0201047f230041d0006b22022400200242f3e885db96cddbb320370308200241086a2001412c6a2001290300200141086a290300427f410e10a80102400240410e10272203450d00200341066a410029009fa34437000020034100290099a3443700002003410e412e10282203450d012003200029000037000e200341266a200041186a2900003700002003411e6a200041106a290000370000200341166a200041086a290000370000200241306a41186a22004200370300200241306a41106a22044200370300200241306a41086a22054200370300200242003703302003412e200241306a1000200241106a41186a2000290300370300200241106a41106a2004290300370300200241106a41086a200529030037030020022002290330370310200241203602342002200241106a3602302001200241306a10c70320031029200241d0006a24000f0b410e4101102a000b412e4101102a000b02000bd70302027f077e23004180016b22032400200341c0006a200110ae0302400240024020032903404201520d00200241016a2104200341c0006a41086a21020340200341086a41306a200241306a2903002205370300200341086a41286a200241286a2903002206370300200341086a41206a200241206a2903002207370300200341086a41186a200241186a2903002208370300200341086a41106a200241106a2903002209370300200341086a41086a200241086a290300220a37030020032002290300220b370308200341c0006a41306a2005370300200341c0006a41286a2006370300200341c0006a41206a2007370300200341c0006a41186a2008370300200341c0006a41106a20093703002002200a3703002003200b3703402004417f6a2204450d02200341c0006a200110ae0320032903404201510d000b0b200042003703000c010b2000200329034037030820004201370300200041386a200341c0006a41306a290300370300200041306a200341c0006a41286a290300370300200041286a200341c0006a41206a290300370300200041206a200341c0006a41186a290300370300200041186a200341c0006a41106a290300370300200041106a200341c8006a2903003703000b20034180016a24000beb050a067f017e017f017e017f017e017f017e017f017e230041206b2202240002400240024020014108490d00200141017641feffffff07712203417f6a220420014f0d022001410d74200173220541117620057322054105742005732206417f2001417f6a677622077122054100200120052001491b6b220520014f0d01200020044105746a22042900002108200020054105746a220541086a2209290000210a200541106a220b290000210c200541186a220d290000210e20042005290000370000200441186a220f2900002110200f200e370000200441106a220f290000210e200f200c370000200441086a2204290000210c2004200a370000200d2010370000200b200e3700002009200c37000020052008370000024020032001490d00200321040c030b2006410d7420067322054111762005732205410574200573220620077122054100200120052001491b6b220520014f0d01200020034105746a22042900002108200020054105746a220541086a2209290000210a200541106a220b290000210c200541186a220d290000210e20042005290000370000200441186a220f2900002110200f200e370000200441106a220f290000210e200f200c370000200441086a2204290000210c2004200a370000200d2010370000200b200e3700002009200c370000200520083700002003410172220420014f0d022006410d742006732205411176200573220541057420057320077122054100200120052001491b6b220520014f0d01200020044105746a22012900002108200020054105746a220041086a2205290000210a200041106a2204290000210c200041186a2203290000210e20012000290000370000200141186a220629000021102006200e370000200141106a2206290000210e2006200c370000200141086a2201290000210c2001200a370000200320103700002004200e3700002005200c370000200020083700000b200241206a24000f0b41c481c500200520011037000b41b481c500200420011037000be90609067f017e017f017e017f027e017f017e027f230041206b22022400024020014101762203450d0003402003417f6a2203210402400240024003402004410174220541017221060240200541026a220520014f0d00200620014f0d0220052006200020064105746a200020054105746a412010d0044100481b21060b200620014f0d03200420014f0d02200020044105746a2204200020064105746a2205412010d004417f4a0d03200541086a22072900002108200541106a2209290000210a200541186a220b290000210c2004290000210d20042005290000370000200441186a220e290000210f200e200c370000200441106a220e290000210c200e200a370000200441086a2204290000210a20042008370000200b200f3700002009200c3700002007200a3700002005200d370000200621040c000b0b41b883c500200620011037000b41c883c500200420011037000b20030d000b0b0240024020014102490d002001210703402007417f6a220720014f0d02200241186a2209200041186a2204290000370300200241106a220b200041106a2205290000370300200241086a220e200041086a2203290000370300200020074105746a220641086a2900002108200641106a290000210a200641186a290000210c2000290000210d200020062900003700002004200c3700002005200a370000200320083700002002200d37030041002105024002400240034020062002290300370000200641186a2009290300370000200641106a200b290300370000200641086a200e2903003700002005410174220641017221040240200641026a220620074f0d00200420074f0d0220062004200020044105746a200020064105746a412010d0044100481b21040b200420074f0d03200520074f0d02200020054105746a2205200020044105746a2206412010d004417f4a0d032009200541186a2203290000370300200b200541106a2210290000370300200e200541086a2211290000370300200641086a2900002108200641106a290000210a200641186a290000210c2005290000210d200520062900003700002003200c3700002010200a370000201120083700002002200d370300200421050c000b0b41b883c500200420071037000b41c883c500200520071037000b200741014b0d000b0b200241206a24000f0b41c481c500200720011037000bdb08030a7f017e0a7f230041c0006b22022400200041a07f6a21032001417f6a2104200141324921054101210641002107024003400240024020062001490d00410021080c010b41012108200020064105746a2209200941606a412010d0044100480d0003404101210a20042006460d03200641016a2106200941206a220a2009412010d0042108200a21092008417f4a0d000b200620014921080b2006200146210a20050d0120062001460d0102400240024002402006417f6a220920014f0d002008450d0120002006410574220b6a220a290000210c200a200020094105746a22092900003700002009200c370000200a41086a220d290000210c200d200941086a220e290000370000200e200c370000200a41106a220f290000210c200f200941106a22102900003700002010200c370000200a41186a2211290000210c2011200941186a22122900003700002012200c37000020064102490d03200920002006417e6a22084105746a2213412010d004417f4a0d032009290000210c20092013290000370000200241206a41186a22142012290000370300200241206a41106a22152010290000370300200241206a41086a2216200e290000370300200e201341086a2900003700002010201341106a2900003700002012201341186a2900003700002002200c3703204100210e2008450d022003200b6a210903400240200241206a2009412010d0044100480d002008210e0c040b200941206a2009290000370000200941386a200941186a290000370000200941306a200941106a290000370000200941286a200941086a290000370000200941606a21092008417f6a22080d000c030b0b41b481c500200920011037000b41c481c500200620011037000b2000200e4105746a22092002290320370000200941186a2014290300370000200941106a2015290300370000200941086a20162903003700000b200741016a21070240200120066b22104102490d00200a41206a2209200a412010d004417f4a0d00200a290000210c200a2009290000370000200241206a41186a22122011290000370300200241206a41106a2213200f290000370300200241206a41086a220b200d290000370300200d200941086a290000370000200f200941106a2900003700002011200941186a2900003700002002200c3703204101210d024020104103490d00200a41c0006a200241206a412010d004417f4a0d00410321084102210e0340200a200e4105746a220941606a220d2009290000370000200d41186a200941186a290000370000200d41106a200941106a290000370000200d41086a200941086a290000370000024020082010490d00200e210d0c020b20084105742109200e210d2008210e200841016a2108200a20096a200241206a412010d0044100480d000b0b200a200d4105746a22092002290320370000200941186a2012290300370000200941106a2013290300370000200941086a200b2903003700000b20074105470d000b4100210a0b200241c0006a2400200a0bb204030e7f017e017f230041c0006b22032400200128020022042001280208220541047422066a210720012802042108200421010240024002402005450d00200341306a41017221094100210a200341306a41026a210b200341206a410172220c41076a210d0340200b2004200a6a220141036a2d00003a00002003200141016a2f00003b0130024020012d0000220e41ac01470d00200141106a21010c020b2003410c6a41026a200b2d0000220f3a0000200320032f013022103b010c200141046a29020021112001410c6a2802002112200920103b0000200941026a200f3a00002003200e3a00302003201236023c20032011370234200341206a200341306a200210df032003200c2900003703102003200d290000370017024020032d0020220e411a470d002006200a41106a220a470d010c030b0b2000200e3a000020002003290310370001200041086a20032900173700000240200541047441706a200a460d00200141186a2101034002400240200141786a220a2d0000220b4109460d00200b41ac01470d010c030b200128020041ffffffff0371450d00200a41046a28020010290b200141106a2101200a41106a2007470d000b0b2008450d02200410290c020b20012007460d0003400240024020012d0000220a4109460d00200a41ac01470d010c030b200141086a28020041ffffffff0371450d00200141046a28020010290b200141106a22012007470d000b0b02402008450d00200410290b2000411a3a00000b200341c0006a24000bf6d60202097f017e230041106b220324000240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024020012d00000eac01000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f80018101820183018401850186018701880189018a018b018c018d018e018f0190019101920193019401950196019701980199019a019b019c019d019e019f01a001a101a201a301a401a501a601a701a801a901aa01ab01000b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490df70120044101742206200520052006491b22064100480df7010240024020040d002006102721050c010b200228020420042006102821050b2005450dad0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41003a00000cab010b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490df60120044101742206200520052006491b22064100480df6010240024020040d002006102721050c010b200228020420042006102821050b2005450dad0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41013a00000caa010b200241046a210620012d0001210702400240200241086a2802002002410c6a2802002204460d00200628020021050c010b200441016a22052004490df50120044101742208200520052008491b22084100480df5010240024020040d002008102721050c010b200628020020042008102821050b2005450dad0120022005360204200241086a20083602002002410c6a28020021040b2002410c6a2208200441016a360200200520046a41023a000002400240200241086a28020020082802002204460d00200628020021050c010b200441016a22052004490df50120044101742208200520052008491b22084100480df5010240024020040d002008102721050c010b200628020020042008102821050b2005450dae0120022005360204200241086a20083602002002410c6a28020021040b2002410c6a200441016a360200200520046a42c0818386fcdffffe7c2007410473ad42078342038688a7413f7141c000723a00000ca9010b200241046a210620012d0001210702400240200241086a2802002002410c6a2802002204460d00200628020021050c010b200441016a22052004490df40120044101742208200520052008491b22084100480df4010240024020040d002008102721050c010b200628020020042008102821050b2005450dae0120022005360204200241086a20083602002002410c6a28020021040b2002410c6a2208200441016a360200200520046a41033a000002400240200241086a28020020082802002204460d00200628020021050c010b200441016a22052004490df40120044101742208200520052008491b22084100480df4010240024020040d002008102721050c010b200628020020042008102821050b2005450daf0120022005360204200241086a20083602002002410c6a28020021040b2002410c6a200441016a360200200520046a42c0818386fcdffffe7c2007410473ad42078342038688a7413f7141c000723a00000ca8010b200241046a210620012d0001210702400240200241086a2802002002410c6a2802002204460d00200628020021050c010b200441016a22052004490df30120044101742208200520052008491b22084100480df3010240024020040d002008102721050c010b200628020020042008102821050b2005450daf0120022005360204200241086a20083602002002410c6a28020021040b2002410c6a2208200441016a360200200520046a41043a000002400240200241086a28020020082802002204460d00200628020021050c010b200441016a22052004490df30120044101742208200520052008491b22084100480df3010240024020040d002008102721050c010b200628020020042008102821050b2005450db00120022005360204200241086a20083602002002410c6a28020021040b2002410c6a200441016a360200200520046a42c0818386fcdffffe7c2007410473ad42078342038688a7413f7141c000723a00000ca7010b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490df20120044101742206200520052006491b22064100480df2010240024020040d002006102721050c010b200228020420042006102821050b2005450db00120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41053a00000ca6010b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490df10120044101742206200520052006491b22064100480df1010240024020040d002006102721050c010b200228020420042006102821050b2005450db00120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a410b3a00000ca5010b200241046a2109200141046a280200210502400240200241086a2802002002410c6a2802002204460d00200928020021060c010b200441016a22062004490df00120044101742207200620062007491b22074100480df0010240024020040d002007102721060c010b200928020020042007102821060b2006450db00120022006360204200241086a20073602002002410c6a28020021040b2002410c6a2207200441016a360200200620046a410c3a0000200241086a2108034002400240200828020020072802002204460d00200928020021060c010b200441016a22062004490df1012004410174220a20062006200a491b220a4100480df1010240024020040d00200a102721060c010b20092802002004200a102821060b2006450db201200220063602042008200a360200200728020021040b2007200441016a360200200620046a200541807f72200541ff0071200541077622041b3a00002004210520040d000ca5010b0b200241046a2109200141046a280200210502400240200241086a2802002002410c6a2802002204460d00200928020021060c010b200441016a22062004490def0120044101742207200620062007491b22074100480def010240024020040d002007102721060c010b200928020020042007102821060b2006450db10120022006360204200241086a20073602002002410c6a28020021040b2002410c6a2207200441016a360200200620046a410d3a0000200241086a2108034002400240200828020020072802002204460d00200928020021060c010b200441016a22062004490df0012004410174220a20062006200a491b220a4100480df0010240024020040d00200a102721060c010b20092802002004200a102821060b2006450db301200220063602042008200a360200200728020021040b2007200441016a360200200620046a200541807f72200541ff0071200541077622041b3a00002004210520040d000ca4010b0b200241046a210a2001410c6a2802002104200141086a2802002109200141046a280200210b02400240200241086a2802002002410c6a2802002201460d00200a28020021050c010b200141016a22052001490dee0120014101742206200520052006491b22064100480dee010240024020010d002006102721050c010b200a28020020012006102821050b2005450db20120022005360204200241086a20063602002002410c6a28020021010b2002410c6a2206200141016a360200200520016a410e3a000020032009200b200b20094102746a200210e00320032d0000411a470d9303200241086a2107034002400240200728020020062802002201460d00200a28020021050c010b200141016a22052001490def0120014101742208200520052008491b22084100480def010240024020010d002008102721050c010b200a28020020012008102821050b2005450db4012002200536020420072008360200200628020021010b2006200141016a360200200520016a200441807f72200441ff0071200441077622011b3a00002001210420010d000b0240200941ffffffff0371450d00200b10290b2000411a3a00000c95030b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490ded0120044101742206200520052006491b22064100480ded010240024020040d002006102721050c010b200228020420042006102821050b2005450db30120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a410f3a00000ca1010b200241046a2109200141046a280200210502400240200241086a2802002002410c6a2802002204460d00200928020021060c010b200441016a22062004490dec0120044101742207200620062007491b22074100480dec010240024020040d002007102721060c010b200928020020042007102821060b2006450db30120022006360204200241086a20073602002002410c6a28020021040b2002410c6a2207200441016a360200200620046a41103a0000200241086a2108034002400240200828020020072802002204460d00200928020021060c010b200441016a22062004490ded012004410174220a20062006200a491b220a4100480ded010240024020040d00200a102721060c010b20092802002004200a102821060b2006450db501200220063602042008200a360200200728020021040b2007200441016a360200200620046a200541807f72200541ff0071200541077622041b3a00002004210520040d000ca1010b0b200241046a2109200141046a280200210520012d0001210b02400240200241086a2802002002410c6a2802002204460d00200928020021060c010b200441016a22062004490deb0120044101742207200620062007491b22074100480deb010240024020040d002007102721060c010b200928020020042007102821060b2006450db40120022006360204200241086a20073602002002410c6a28020021040b2002410c6a2207200441016a360200200620046a41113a0000200241086a2108034002400240200828020020072802002204460d00200928020021060c010b200441016a22062004490dec012004410174220a20062006200a491b220a4100480dec010240024020040d00200a102721060c010b20092802002004200a102821060b2006450db601200220063602042008200a360200200728020021040b2007200441016a360200200620046a200541807f72200541ff0071200541077622041b3a00002004210520040d000b02400240200241086a2802002002410c6a2802002204460d00200928020021050c010b200441016a22052004490deb0120044101742206200520052006491b22064100480deb010240024020040d002006102721050c010b200928020020042006102821050b2005450db60120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a200b3a00000c9f010b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490dea0120044101742206200520052006491b22064100480dea010240024020040d002006102721050c010b200228020420042006102821050b2005450db60120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a411a3a00000c9e010b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490de90120044101742206200520052006491b22064100480de9010240024020040d002006102721050c010b200228020420042006102821050b2005450db60120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a411b3a00000c9d010b200241046a2109200141046a280200210502400240200241086a2802002002410c6a2802002204460d00200928020021060c010b200441016a22062004490de80120044101742207200620062007491b22074100480de8010240024020040d002007102721060c010b200928020020042007102821060b2006450db60120022006360204200241086a20073602002002410c6a28020021040b2002410c6a2207200441016a360200200620046a41203a0000200241086a2108034002400240200828020020072802002204460d00200928020021060c010b200441016a22062004490de9012004410174220a20062006200a491b220a4100480de9010240024020040d00200a102721060c010b20092802002004200a102821060b2006450db801200220063602042008200a360200200728020021040b2007200441016a360200200620046a200541807f72200541ff0071200541077622041b3a00002004210520040d000c9d010b0b200241046a2109200141046a280200210502400240200241086a2802002002410c6a2802002204460d00200928020021060c010b200441016a22062004490de70120044101742207200620062007491b22074100480de7010240024020040d002007102721060c010b200928020020042007102821060b2006450db70120022006360204200241086a20073602002002410c6a28020021040b2002410c6a2207200441016a360200200620046a41213a0000200241086a2108034002400240200828020020072802002204460d00200928020021060c010b200441016a22062004490de8012004410174220a20062006200a491b220a4100480de8010240024020040d00200a102721060c010b20092802002004200a102821060b2006450db901200220063602042008200a360200200728020021040b2007200441016a360200200620046a200541807f72200541ff0071200541077622041b3a00002004210520040d000c9c010b0b200241046a2109200141046a280200210502400240200241086a2802002002410c6a2802002204460d00200928020021060c010b200441016a22062004490de60120044101742207200620062007491b22074100480de6010240024020040d002007102721060c010b200928020020042007102821060b2006450db80120022006360204200241086a20073602002002410c6a28020021040b2002410c6a2207200441016a360200200620046a41223a0000200241086a2108034002400240200828020020072802002204460d00200928020021060c010b200441016a22062004490de7012004410174220a20062006200a491b220a4100480de7010240024020040d00200a102721060c010b20092802002004200a102821060b2006450dba01200220063602042008200a360200200728020021040b2007200441016a360200200620046a200541807f72200541ff0071200541077622041b3a00002004210520040d000c9b010b0b200241046a2109200141046a280200210502400240200241086a2802002002410c6a2802002204460d00200928020021060c010b200441016a22062004490de50120044101742207200620062007491b22074100480de5010240024020040d002007102721060c010b200928020020042007102821060b2006450db90120022006360204200241086a20073602002002410c6a28020021040b2002410c6a2207200441016a360200200620046a41233a0000200241086a2108034002400240200828020020072802002204460d00200928020021060c010b200441016a22062004490de6012004410174220a20062006200a491b220a4100480de6010240024020040d00200a102721060c010b20092802002004200a102821060b2006450dbb01200220063602042008200a360200200728020021040b2007200441016a360200200620046a200541807f72200541ff0071200541077622041b3a00002004210520040d000c9a010b0b200241046a2109200141046a280200210502400240200241086a2802002002410c6a2802002204460d00200928020021060c010b200441016a22062004490de40120044101742207200620062007491b22074100480de4010240024020040d002007102721060c010b200928020020042007102821060b2006450dba0120022006360204200241086a20073602002002410c6a28020021040b2002410c6a2207200441016a360200200620046a41243a0000200241086a2108034002400240200828020020072802002204460d00200928020021060c010b200441016a22062004490de5012004410174220a20062006200a491b220a4100480de5010240024020040d00200a102721060c010b20092802002004200a102821060b2006450dbc01200220063602042008200a360200200728020021040b2007200441016a360200200620046a200541807f72200541ff0071200541077622041b3a00002004210520040d000c99010b0b200241046a210a200141086a2802002105200141046a280200210602400240200241086a2802002002410c6a2802002204460d00200a28020021070c010b200441016a22072004490de30120044101742208200720072008491b22084100480de3010240024020040d002008102721070c010b200a28020020042008102821070b2007450dbb0120022007360204200241086a20083602002002410c6a28020021040b2002410c6a2208200441016a360200200720046a41283a0000200241086a2109034002400240200928020020082802002204460d00200a28020021070c010b200441016a22072004490de4012004410174220b20072007200b491b220b4100480de4010240024020040d00200b102721070c010b200a2802002004200b102821070b2007450dbd01200220073602042009200b360200200828020021040b2008200441016a360200200720046a200641807f72200641ff0071200641077622041b3a00002004210620040d000b2002410c6a2107200241086a2108034002400240200828020020072802002204460d00200a28020021060c010b200441016a22062004490de40120044101742209200620062009491b22094100480de4010240024020040d002009102721060c010b200a28020020042009102821060b2006450dbe012002200636020420082009360200200728020021040b2007200441016a360200200620046a200541807f72200541ff0071200541077622041b3a00002004210520040d000c98010b0b200241046a210a200141086a2802002105200141046a280200210602400240200241086a2802002002410c6a2802002204460d00200a28020021070c010b200441016a22072004490de20120044101742208200720072008491b22084100480de2010240024020040d002008102721070c010b200a28020020042008102821070b2007450dbd0120022007360204200241086a20083602002002410c6a28020021040b2002410c6a2208200441016a360200200720046a41293a0000200241086a2109034002400240200928020020082802002204460d00200a28020021070c010b200441016a22072004490de3012004410174220b20072007200b491b220b4100480de3010240024020040d00200b102721070c010b200a2802002004200b102821070b2007450dbf01200220073602042009200b360200200828020021040b2008200441016a360200200720046a200641807f72200641ff0071200641077622041b3a00002004210620040d000b2002410c6a2107200241086a2108034002400240200828020020072802002204460d00200a28020021060c010b200441016a22062004490de30120044101742209200620062009491b22094100480de3010240024020040d002009102721060c010b200a28020020042009102821060b2006450dc0012002200636020420082009360200200728020021040b2007200441016a360200200620046a200541807f72200541ff0071200541077622041b3a00002004210520040d000c97010b0b200241046a210a200141086a2802002105200141046a280200210602400240200241086a2802002002410c6a2802002204460d00200a28020021070c010b200441016a22072004490de10120044101742208200720072008491b22084100480de1010240024020040d002008102721070c010b200a28020020042008102821070b2007450dbf0120022007360204200241086a20083602002002410c6a28020021040b2002410c6a2208200441016a360200200720046a412a3a0000200241086a2109034002400240200928020020082802002204460d00200a28020021070c010b200441016a22072004490de2012004410174220b20072007200b491b220b4100480de2010240024020040d00200b102721070c010b200a2802002004200b102821070b2007450dc101200220073602042009200b360200200828020021040b2008200441016a360200200720046a200641807f72200641ff0071200641077622041b3a00002004210620040d000b2002410c6a2107200241086a2108034002400240200828020020072802002204460d00200a28020021060c010b200441016a22062004490de20120044101742209200620062009491b22094100480de2010240024020040d002009102721060c010b200a28020020042009102821060b2006450dc2012002200636020420082009360200200728020021040b2007200441016a360200200620046a200541807f72200541ff0071200541077622041b3a00002004210520040d000c96010b0b200241046a210a200141086a2802002105200141046a280200210602400240200241086a2802002002410c6a2802002204460d00200a28020021070c010b200441016a22072004490de00120044101742208200720072008491b22084100480de0010240024020040d002008102721070c010b200a28020020042008102821070b2007450dc10120022007360204200241086a20083602002002410c6a28020021040b2002410c6a2208200441016a360200200720046a412b3a0000200241086a2109034002400240200928020020082802002204460d00200a28020021070c010b200441016a22072004490de1012004410174220b20072007200b491b220b4100480de1010240024020040d00200b102721070c010b200a2802002004200b102821070b2007450dc301200220073602042009200b360200200828020021040b2008200441016a360200200720046a200641807f72200641ff0071200641077622041b3a00002004210620040d000b2002410c6a2107200241086a2108034002400240200828020020072802002204460d00200a28020021060c010b200441016a22062004490de10120044101742209200620062009491b22094100480de1010240024020040d002009102721060c010b200a28020020042009102821060b2006450dc4012002200636020420082009360200200728020021040b2007200441016a360200200620046a200541807f72200541ff0071200541077622041b3a00002004210520040d000c95010b0b200241046a210a200141086a2802002105200141046a280200210602400240200241086a2802002002410c6a2802002204460d00200a28020021070c010b200441016a22072004490ddf0120044101742208200720072008491b22084100480ddf010240024020040d002008102721070c010b200a28020020042008102821070b2007450dc30120022007360204200241086a20083602002002410c6a28020021040b2002410c6a2208200441016a360200200720046a412c3a0000200241086a2109034002400240200928020020082802002204460d00200a28020021070c010b200441016a22072004490de0012004410174220b20072007200b491b220b4100480de0010240024020040d00200b102721070c010b200a2802002004200b102821070b2007450dc501200220073602042009200b360200200828020021040b2008200441016a360200200720046a200641807f72200641ff0071200641077622041b3a00002004210620040d000b2002410c6a2107200241086a2108034002400240200828020020072802002204460d00200a28020021060c010b200441016a22062004490de00120044101742209200620062009491b22094100480de0010240024020040d002009102721060c010b200a28020020042009102821060b2006450dc6012002200636020420082009360200200728020021040b2007200441016a360200200620046a200541807f72200541ff0071200541077622041b3a00002004210520040d000c94010b0b200241046a210a200141086a2802002105200141046a280200210602400240200241086a2802002002410c6a2802002204460d00200a28020021070c010b200441016a22072004490dde0120044101742208200720072008491b22084100480dde010240024020040d002008102721070c010b200a28020020042008102821070b2007450dc50120022007360204200241086a20083602002002410c6a28020021040b2002410c6a2208200441016a360200200720046a412d3a0000200241086a2109034002400240200928020020082802002204460d00200a28020021070c010b200441016a22072004490ddf012004410174220b20072007200b491b220b4100480ddf010240024020040d00200b102721070c010b200a2802002004200b102821070b2007450dc701200220073602042009200b360200200828020021040b2008200441016a360200200720046a200641807f72200641ff0071200641077622041b3a00002004210620040d000b2002410c6a2107200241086a2108034002400240200828020020072802002204460d00200a28020021060c010b200441016a22062004490ddf0120044101742209200620062009491b22094100480ddf010240024020040d002009102721060c010b200a28020020042009102821060b2006450dc8012002200636020420082009360200200728020021040b2007200441016a360200200620046a200541807f72200541ff0071200541077622041b3a00002004210520040d000c93010b0b200241046a210a200141086a2802002105200141046a280200210602400240200241086a2802002002410c6a2802002204460d00200a28020021070c010b200441016a22072004490ddd0120044101742208200720072008491b22084100480ddd010240024020040d002008102721070c010b200a28020020042008102821070b2007450dc70120022007360204200241086a20083602002002410c6a28020021040b2002410c6a2208200441016a360200200720046a412e3a0000200241086a2109034002400240200928020020082802002204460d00200a28020021070c010b200441016a22072004490dde012004410174220b20072007200b491b220b4100480dde010240024020040d00200b102721070c010b200a2802002004200b102821070b2007450dc901200220073602042009200b360200200828020021040b2008200441016a360200200720046a200641807f72200641ff0071200641077622041b3a00002004210620040d000b2002410c6a2107200241086a2108034002400240200828020020072802002204460d00200a28020021060c010b200441016a22062004490dde0120044101742209200620062009491b22094100480dde010240024020040d002009102721060c010b200a28020020042009102821060b2006450dca012002200636020420082009360200200728020021040b2007200441016a360200200620046a200541807f72200541ff0071200541077622041b3a00002004210520040d000c92010b0b200241046a210a200141086a2802002105200141046a280200210602400240200241086a2802002002410c6a2802002204460d00200a28020021070c010b200441016a22072004490ddc0120044101742208200720072008491b22084100480ddc010240024020040d002008102721070c010b200a28020020042008102821070b2007450dc90120022007360204200241086a20083602002002410c6a28020021040b2002410c6a2208200441016a360200200720046a412f3a0000200241086a2109034002400240200928020020082802002204460d00200a28020021070c010b200441016a22072004490ddd012004410174220b20072007200b491b220b4100480ddd010240024020040d00200b102721070c010b200a2802002004200b102821070b2007450dcb01200220073602042009200b360200200828020021040b2008200441016a360200200720046a200641807f72200641ff0071200641077622041b3a00002004210620040d000b2002410c6a2107200241086a2108034002400240200828020020072802002204460d00200a28020021060c010b200441016a22062004490ddd0120044101742209200620062009491b22094100480ddd010240024020040d002009102721060c010b200a28020020042009102821060b2006450dcc012002200636020420082009360200200728020021040b2007200441016a360200200620046a200541807f72200541ff0071200541077622041b3a00002004210520040d000c91010b0b200241046a210a200141086a2802002105200141046a280200210602400240200241086a2802002002410c6a2802002204460d00200a28020021070c010b200441016a22072004490ddb0120044101742208200720072008491b22084100480ddb010240024020040d002008102721070c010b200a28020020042008102821070b2007450dcb0120022007360204200241086a20083602002002410c6a28020021040b2002410c6a2208200441016a360200200720046a41303a0000200241086a2109034002400240200928020020082802002204460d00200a28020021070c010b200441016a22072004490ddc012004410174220b20072007200b491b220b4100480ddc010240024020040d00200b102721070c010b200a2802002004200b102821070b2007450dcd01200220073602042009200b360200200828020021040b2008200441016a360200200720046a200641807f72200641ff0071200641077622041b3a00002004210620040d000b2002410c6a2107200241086a2108034002400240200828020020072802002204460d00200a28020021060c010b200441016a22062004490ddc0120044101742209200620062009491b22094100480ddc010240024020040d002009102721060c010b200a28020020042009102821060b2006450dce012002200636020420082009360200200728020021040b2007200441016a360200200620046a200541807f72200541ff0071200541077622041b3a00002004210520040d000c90010b0b200241046a210a200141086a2802002105200141046a280200210602400240200241086a2802002002410c6a2802002204460d00200a28020021070c010b200441016a22072004490dda0120044101742208200720072008491b22084100480dda010240024020040d002008102721070c010b200a28020020042008102821070b2007450dcd0120022007360204200241086a20083602002002410c6a28020021040b2002410c6a2208200441016a360200200720046a41313a0000200241086a2109034002400240200928020020082802002204460d00200a28020021070c010b200441016a22072004490ddb012004410174220b20072007200b491b220b4100480ddb010240024020040d00200b102721070c010b200a2802002004200b102821070b2007450dcf01200220073602042009200b360200200828020021040b2008200441016a360200200720046a200641807f72200641ff0071200641077622041b3a00002004210620040d000b2002410c6a2107200241086a2108034002400240200828020020072802002204460d00200a28020021060c010b200441016a22062004490ddb0120044101742209200620062009491b22094100480ddb010240024020040d002009102721060c010b200a28020020042009102821060b2006450dd0012002200636020420082009360200200728020021040b2007200441016a360200200620046a200541807f72200541ff0071200541077622041b3a00002004210520040d000c8f010b0b200241046a210a200141086a2802002105200141046a280200210602400240200241086a2802002002410c6a2802002204460d00200a28020021070c010b200441016a22072004490dd90120044101742208200720072008491b22084100480dd9010240024020040d002008102721070c010b200a28020020042008102821070b2007450dcf0120022007360204200241086a20083602002002410c6a28020021040b2002410c6a2208200441016a360200200720046a41323a0000200241086a2109034002400240200928020020082802002204460d00200a28020021070c010b200441016a22072004490dda012004410174220b20072007200b491b220b4100480dda010240024020040d00200b102721070c010b200a2802002004200b102821070b2007450dd101200220073602042009200b360200200828020021040b2008200441016a360200200720046a200641807f72200641ff0071200641077622041b3a00002004210620040d000b2002410c6a2107200241086a2108034002400240200828020020072802002204460d00200a28020021060c010b200441016a22062004490dda0120044101742209200620062009491b22094100480dda010240024020040d002009102721060c010b200a28020020042009102821060b2006450dd2012002200636020420082009360200200728020021040b2007200441016a360200200620046a200541807f72200541ff0071200541077622041b3a00002004210520040d000c8e010b0b200241046a210a200141086a2802002105200141046a280200210602400240200241086a2802002002410c6a2802002204460d00200a28020021070c010b200441016a22072004490dd80120044101742208200720072008491b22084100480dd8010240024020040d002008102721070c010b200a28020020042008102821070b2007450dd10120022007360204200241086a20083602002002410c6a28020021040b2002410c6a2208200441016a360200200720046a41333a0000200241086a2109034002400240200928020020082802002204460d00200a28020021070c010b200441016a22072004490dd9012004410174220b20072007200b491b220b4100480dd9010240024020040d00200b102721070c010b200a2802002004200b102821070b2007450dd301200220073602042009200b360200200828020021040b2008200441016a360200200720046a200641807f72200641ff0071200641077622041b3a00002004210620040d000b2002410c6a2107200241086a2108034002400240200828020020072802002204460d00200a28020021060c010b200441016a22062004490dd90120044101742209200620062009491b22094100480dd9010240024020040d002009102721060c010b200a28020020042009102821060b2006450dd4012002200636020420082009360200200728020021040b2007200441016a360200200620046a200541807f72200541ff0071200541077622041b3a00002004210520040d000c8d010b0b200241046a210a200141086a2802002105200141046a280200210602400240200241086a2802002002410c6a2802002204460d00200a28020021070c010b200441016a22072004490dd70120044101742208200720072008491b22084100480dd7010240024020040d002008102721070c010b200a28020020042008102821070b2007450dd30120022007360204200241086a20083602002002410c6a28020021040b2002410c6a2208200441016a360200200720046a41343a0000200241086a2109034002400240200928020020082802002204460d00200a28020021070c010b200441016a22072004490dd8012004410174220b20072007200b491b220b4100480dd8010240024020040d00200b102721070c010b200a2802002004200b102821070b2007450dd501200220073602042009200b360200200828020021040b2008200441016a360200200720046a200641807f72200641ff0071200641077622041b3a00002004210620040d000b2002410c6a2107200241086a2108034002400240200828020020072802002204460d00200a28020021060c010b200441016a22062004490dd80120044101742209200620062009491b22094100480dd8010240024020040d002009102721060c010b200a28020020042009102821060b2006450dd6012002200636020420082009360200200728020021040b2007200441016a360200200620046a200541807f72200541ff0071200541077622041b3a00002004210520040d000c8c010b0b200241046a210a200141086a2802002105200141046a280200210602400240200241086a2802002002410c6a2802002204460d00200a28020021070c010b200441016a22072004490dd60120044101742208200720072008491b22084100480dd6010240024020040d002008102721070c010b200a28020020042008102821070b2007450dd50120022007360204200241086a20083602002002410c6a28020021040b2002410c6a2208200441016a360200200720046a41353a0000200241086a2109034002400240200928020020082802002204460d00200a28020021070c010b200441016a22072004490da3022004410174220b20072007200b491b220b4100480da3020240024020040d00200b102721070c010b200a2802002004200b102821070b2007450dd801200220073602042009200b360200200828020021040b2008200441016a360200200720046a200641807f72200641ff0071200641077622041b3a00002004210620040d000b2002410c6a2107200241086a2108034002400240200828020020072802002204460d00200a28020021060c010b200441016a22062004490da30220044101742209200620062009491b22094100480da3020240024020040d002009102721060c010b200a28020020042009102821060b2006450dd9012002200636020420082009360200200728020021040b2007200441016a360200200620046a200541807f72200541ff0071200541077622041b3a00002004210520040d000c8b010b0b200241046a210a200141086a2802002105200141046a280200210602400240200241086a2802002002410c6a2802002204460d00200a28020021070c010b200441016a22072004490da10220044101742208200720072008491b22084100480da1020240024020040d002008102721070c010b200a28020020042008102821070b2007450dd80120022007360204200241086a20083602002002410c6a28020021040b2002410c6a2208200441016a360200200720046a41363a0000200241086a2109034002400240200928020020082802002204460d00200a28020021070c010b200441016a22072004490da2022004410174220b20072007200b491b220b4100480da2020240024020040d00200b102721070c010b200a2802002004200b102821070b2007450dda01200220073602042009200b360200200828020021040b2008200441016a360200200720046a200641807f72200641ff0071200641077622041b3a00002004210620040d000b2002410c6a2107200241086a2108034002400240200828020020072802002204460d00200a28020021060c010b200441016a22062004490da20220044101742209200620062009491b22094100480da2020240024020040d002009102721060c010b200a28020020042009102821060b2006450ddb012002200636020420082009360200200728020021040b2007200441016a360200200620046a200541807f72200541ff0071200541077622041b3a00002004210520040d000c8a010b0b200241046a210a200141086a2802002105200141046a280200210602400240200241086a2802002002410c6a2802002204460d00200a28020021070c010b200441016a22072004490da00220044101742208200720072008491b22084100480da0020240024020040d002008102721070c010b200a28020020042008102821070b2007450dda0120022007360204200241086a20083602002002410c6a28020021040b2002410c6a2208200441016a360200200720046a41373a0000200241086a2109034002400240200928020020082802002204460d00200a28020021070c010b200441016a22072004490da1022004410174220b20072007200b491b220b4100480da1020240024020040d00200b102721070c010b200a2802002004200b102821070b2007450ddc01200220073602042009200b360200200828020021040b2008200441016a360200200720046a200641807f72200641ff0071200641077622041b3a00002004210620040d000b2002410c6a2107200241086a2108034002400240200828020020072802002204460d00200a28020021060c010b200441016a22062004490da10220044101742209200620062009491b22094100480da1020240024020040d002009102721060c010b200a28020020042009102821060b2006450ddd012002200636020420082009360200200728020021040b2007200441016a360200200620046a200541807f72200541ff0071200541077622041b3a00002004210520040d000c89010b0b200241046a210a200141086a2802002105200141046a280200210602400240200241086a2802002002410c6a2802002204460d00200a28020021070c010b200441016a22072004490d9f0220044101742208200720072008491b22084100480d9f020240024020040d002008102721070c010b200a28020020042008102821070b2007450ddc0120022007360204200241086a20083602002002410c6a28020021040b2002410c6a2208200441016a360200200720046a41383a0000200241086a2109034002400240200928020020082802002204460d00200a28020021070c010b200441016a22072004490da0022004410174220b20072007200b491b220b4100480da0020240024020040d00200b102721070c010b200a2802002004200b102821070b2007450dde01200220073602042009200b360200200828020021040b2008200441016a360200200720046a200641807f72200641ff0071200641077622041b3a00002004210620040d000b2002410c6a2107200241086a2108034002400240200828020020072802002204460d00200a28020021060c010b200441016a22062004490da00220044101742209200620062009491b22094100480da0020240024020040d002009102721060c010b200a28020020042009102821060b2006450ddf012002200636020420082009360200200728020021040b2007200441016a360200200620046a200541807f72200541ff0071200541077622041b3a00002004210520040d000c88010b0b200241046a210a200141086a2802002105200141046a280200210602400240200241086a2802002002410c6a2802002204460d00200a28020021070c010b200441016a22072004490d9e0220044101742208200720072008491b22084100480d9e020240024020040d002008102721070c010b200a28020020042008102821070b2007450dde0120022007360204200241086a20083602002002410c6a28020021040b2002410c6a2208200441016a360200200720046a41393a0000200241086a2109034002400240200928020020082802002204460d00200a28020021070c010b200441016a22072004490d9f022004410174220b20072007200b491b220b4100480d9f020240024020040d00200b102721070c010b200a2802002004200b102821070b2007450de001200220073602042009200b360200200828020021040b2008200441016a360200200720046a200641807f72200641ff0071200641077622041b3a00002004210620040d000b2002410c6a2107200241086a2108034002400240200828020020072802002204460d00200a28020021060c010b200441016a22062004490d9f0220044101742209200620062009491b22094100480d9f020240024020040d002009102721060c010b200a28020020042009102821060b2006450de1012002200636020420082009360200200728020021040b2007200441016a360200200620046a200541807f72200541ff0071200541077622041b3a00002004210520040d000c87010b0b200241046a210a200141086a2802002105200141046a280200210602400240200241086a2802002002410c6a2802002204460d00200a28020021070c010b200441016a22072004490d9d0220044101742208200720072008491b22084100480d9d020240024020040d002008102721070c010b200a28020020042008102821070b2007450de00120022007360204200241086a20083602002002410c6a28020021040b2002410c6a2208200441016a360200200720046a413a3a0000200241086a2109034002400240200928020020082802002204460d00200a28020021070c010b200441016a22072004490d9e022004410174220b20072007200b491b220b4100480d9e020240024020040d00200b102721070c010b200a2802002004200b102821070b2007450de201200220073602042009200b360200200828020021040b2008200441016a360200200720046a200641807f72200641ff0071200641077622041b3a00002004210620040d000b2002410c6a2107200241086a2108034002400240200828020020072802002204460d00200a28020021060c010b200441016a22062004490d9e0220044101742209200620062009491b22094100480d9e020240024020040d002009102721060c010b200a28020020042009102821060b2006450de3012002200636020420082009360200200728020021040b2007200441016a360200200620046a200541807f72200541ff0071200541077622041b3a00002004210520040d000c86010b0b200241046a210a200141086a2802002105200141046a280200210602400240200241086a2802002002410c6a2802002204460d00200a28020021070c010b200441016a22072004490d9c0220044101742208200720072008491b22084100480d9c020240024020040d002008102721070c010b200a28020020042008102821070b2007450de20120022007360204200241086a20083602002002410c6a28020021040b2002410c6a2208200441016a360200200720046a413b3a0000200241086a2109034002400240200928020020082802002204460d00200a28020021070c010b200441016a22072004490d9d022004410174220b20072007200b491b220b4100480d9d020240024020040d00200b102721070c010b200a2802002004200b102821070b2007450de401200220073602042009200b360200200828020021040b2008200441016a360200200720046a200641807f72200641ff0071200641077622041b3a00002004210620040d000b2002410c6a2107200241086a2108034002400240200828020020072802002204460d00200a28020021060c010b200441016a22062004490d9d0220044101742209200620062009491b22094100480d9d020240024020040d002009102721060c010b200a28020020042009102821060b2006450de5012002200636020420082009360200200728020021040b2007200441016a360200200620046a200541807f72200541ff0071200541077622041b3a00002004210520040d000c85010b0b200241046a210a200141086a2802002106200141046a280200210502400240200241086a2802002002410c6a2802002204460d00200a28020021070c010b200441016a22072004490d9b0220044101742208200720072008491b22084100480d9b020240024020040d002008102721070c010b200a28020020042008102821070b2007450de40120022007360204200241086a20083602002002410c6a28020021040b2002410c6a2208200441016a360200200720046a413c3a0000200241086a2109034002400240200928020020082802002204460d00200a28020021070c010b200441016a22072004490d9c022004410174220b20072007200b491b220b4100480d9c020240024020040d00200b102721070c010b200a2802002004200b102821070b2007450de601200220073602042009200b360200200828020021040b2008200441016a360200200720046a200541807f72200541ff0071200541077622041b3a00002004210520040d000b2002410c6a2107200241086a2108034002400240200828020020072802002204460d00200a28020021050c010b200441016a22052004490d9c0220044101742209200520052009491b22094100480d9c020240024020040d002009102721050c010b200a28020020042009102821050b2005450de7012002200536020420082009360200200728020021040b2007200441016a360200200520046a200641807f72200641ff0071200641077622041b3a00002004210620040d000c84010b0b200241046a210a200141086a2802002105200141046a280200210602400240200241086a2802002002410c6a2802002204460d00200a28020021070c010b200441016a22072004490d9a0220044101742208200720072008491b22084100480d9a020240024020040d002008102721070c010b200a28020020042008102821070b2007450de60120022007360204200241086a20083602002002410c6a28020021040b2002410c6a2208200441016a360200200720046a413d3a0000200241086a2109034002400240200928020020082802002204460d00200a28020021070c010b200441016a22072004490d9b022004410174220b20072007200b491b220b4100480d9b020240024020040d00200b102721070c010b200a2802002004200b102821070b2007450de801200220073602042009200b360200200828020021040b2008200441016a360200200720046a200641807f72200641ff0071200641077622041b3a00002004210620040d000b2002410c6a2107200241086a2108034002400240200828020020072802002204460d00200a28020021060c010b200441016a22062004490d9b0220044101742209200620062009491b22094100480d9b020240024020040d002009102721060c010b200a28020020042009102821060b2006450de9012002200636020420082009360200200728020021040b2007200441016a360200200620046a200541807f72200541ff0071200541077622041b3a00002004210520040d000c83010b0b200241046a210a200141086a2802002105200141046a280200210602400240200241086a2802002002410c6a2802002204460d00200a28020021070c010b200441016a22072004490d990220044101742208200720072008491b22084100480d99020240024020040d002008102721070c010b200a28020020042008102821070b2007450de80120022007360204200241086a20083602002002410c6a28020021040b2002410c6a2208200441016a360200200720046a413e3a0000200241086a2109034002400240200928020020082802002204460d00200a28020021070c010b200441016a22072004490d9a022004410174220b20072007200b491b220b4100480d9a020240024020040d00200b102721070c010b200a2802002004200b102821070b2007450dea01200220073602042009200b360200200828020021040b2008200441016a360200200720046a200641807f72200641ff0071200641077622041b3a00002004210620040d000b2002410c6a2107200241086a2108034002400240200828020020072802002204460d00200a28020021060c010b200441016a22062004490d9a0220044101742209200620062009491b22094100480d9a020240024020040d002009102721060c010b200a28020020042009102821060b2006450deb012002200636020420082009360200200728020021040b2007200441016a360200200620046a200541807f72200541ff0071200541077622041b3a00002004210520040d000c82010b0b200241046a210620012d0001210702400240200241086a2802002002410c6a2802002204460d00200628020021050c010b200441016a22052004490d980220044101742208200520052008491b22084100480d98020240024020040d002008102721050c010b200628020020042008102821050b2005450dea0120022005360204200241086a20083602002002410c6a28020021040b2002410c6a2208200441016a360200200520046a413f3a000002400240200241086a28020020082802002204460d00200628020021050c010b200441016a22052004490d980220044101742208200520052008491b22084100480d98020240024020040d002008102721050c010b200628020020042008102821050b2005450deb0120022005360204200241086a20083602002002410c6a28020021040b2002410c6a200441016a360200200520046a20073a00000c80010b200241046a210620012d0001210702400240200241086a2802002002410c6a2802002204460d00200628020021050c010b200441016a22052004490d970220044101742208200520052008491b22084100480d97020240024020040d002008102721050c010b200628020020042008102821050b2005450deb0120022005360204200241086a20083602002002410c6a28020021040b2002410c6a2208200441016a360200200520046a41c0003a000002400240200241086a28020020082802002204460d00200628020021050c010b200441016a22052004490d970220044101742208200520052008491b22084100480d97020240024020040d002008102721050c010b200628020020042008102821050b2005450dec0120022005360204200241086a20083602002002410c6a28020021040b2002410c6a200441016a360200200520046a20073a00000c7f0b200141046a280200210602400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d960220044101742207200520052007491b22074100480d96020240024020040d002007102721050c010b200228020420042007102821050b2005450dec0120022005360204200241086a20073602002002410c6a28020021040b2002410c6a200441016a360200200520046a41c1003a000020032006200210e1032003210220032d0000411a470df0020c7e0b200141086a290300210c02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d950220044101742206200520052006491b22064100480d95020240024020040d002006102721050c010b200228020420042006102821050b2005450dec0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41c2003a00002003200c200210e2032003210220032d0000411a470def020c7d0b200241046a2106200141046a280200210702400240200241086a2802002002410c6a2802002204460d00200628020021050c010b200441016a22052004490d940220044101742208200520052008491b22084100480d94020240024020040d002008102721050c010b200628020020042008102821050b2005450dec0120022005360204200241086a20083602002002410c6a28020021040b2002410c6a2208200441016a360200200520046a41c3003a000002400240200241086a2802002205200828020022046b4104490d00200628020021050c010b200441046a22082004490d940220054101742204200820082004491b22044100480d94020240024020050d002004102721050c010b200628020020052004102821050b2005450ded0120022005360204200241086a20043602002002410c6a28020021040b2002410c6a200441046a360200200520046a20073600000c7c0b200241046a2106200141086a290300210c02400240200241086a2802002002410c6a2802002204460d00200628020021050c010b200441016a22052004490d930220044101742207200520052007491b22074100480d93020240024020040d002007102721050c010b200628020020042007102821050b2005450ded0120022005360204200241086a20073602002002410c6a28020021040b2002410c6a2207200441016a360200200520046a41c4003a000002400240200241086a2802002205200728020022046b4108490d00200628020021050c010b200441086a22072004490d930220054101742204200720072004491b22044100480d93020240024020050d002004102721050c010b200628020020052004102821050b2005450dee0120022005360204200241086a20043602002002410c6a28020021040b2002410c6a200441086a360200200520046a200c3700000c7b0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d920220044101742206200520052006491b22064100480d92020240024020040d002006102721050c010b200228020420042006102821050b2005450dee0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41c5003a00000c7a0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d910220044101742206200520052006491b22064100480d91020240024020040d002006102721050c010b200228020420042006102821050b2005450dee0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41c6003a00000c790b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d900220044101742206200520052006491b22064100480d90020240024020040d002006102721050c010b200228020420042006102821050b2005450dee0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41c7003a00000c780b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d8f0220044101742206200520052006491b22064100480d8f020240024020040d002006102721050c010b200228020420042006102821050b2005450dee0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41c8003a00000c770b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d8e0220044101742206200520052006491b22064100480d8e020240024020040d002006102721050c010b200228020420042006102821050b2005450dee0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41c9003a00000c760b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d8d0220044101742206200520052006491b22064100480d8d020240024020040d002006102721050c010b200228020420042006102821050b2005450dee0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41ca003a00000c750b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d8c0220044101742206200520052006491b22064100480d8c020240024020040d002006102721050c010b200228020420042006102821050b2005450dee0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41cb003a00000c740b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d8b0220044101742206200520052006491b22064100480d8b020240024020040d002006102721050c010b200228020420042006102821050b2005450dee0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41cc003a00000c730b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d8a0220044101742206200520052006491b22064100480d8a020240024020040d002006102721050c010b200228020420042006102821050b2005450dee0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41cd003a00000c720b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d890220044101742206200520052006491b22064100480d89020240024020040d002006102721050c010b200228020420042006102821050b2005450dee0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41ce003a00000c710b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d880220044101742206200520052006491b22064100480d88020240024020040d002006102721050c010b200228020420042006102821050b2005450dee0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41cf003a00000c700b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d870220044101742206200520052006491b22064100480d87020240024020040d002006102721050c010b200228020420042006102821050b2005450dee0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41d0003a00000c6f0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d860220044101742206200520052006491b22064100480d86020240024020040d002006102721050c010b200228020420042006102821050b2005450dee0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41d1003a00000c6e0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d850220044101742206200520052006491b22064100480d85020240024020040d002006102721050c010b200228020420042006102821050b2005450dee0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41d2003a00000c6d0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d840220044101742206200520052006491b22064100480d84020240024020040d002006102721050c010b200228020420042006102821050b2005450dee0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41d3003a00000c6c0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d830220044101742206200520052006491b22064100480d83020240024020040d002006102721050c010b200228020420042006102821050b2005450dee0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41d4003a00000c6b0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d820220044101742206200520052006491b22064100480d82020240024020040d002006102721050c010b200228020420042006102821050b2005450dee0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41d5003a00000c6a0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d810220044101742206200520052006491b22064100480d81020240024020040d002006102721050c010b200228020420042006102821050b2005450dee0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41d6003a00000c690b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d800220044101742206200520052006491b22064100480d80020240024020040d002006102721050c010b200228020420042006102821050b2005450dee0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41d7003a00000c680b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490dff0120044101742206200520052006491b22064100480dff010240024020040d002006102721050c010b200228020420042006102821050b2005450dee0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41d8003a00000c670b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490dfe0120044101742206200520052006491b22064100480dfe010240024020040d002006102721050c010b200228020420042006102821050b2005450dee0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41d9003a00000c660b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490dfd0120044101742206200520052006491b22064100480dfd010240024020040d002006102721050c010b200228020420042006102821050b2005450dee0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41da003a00000c650b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490dfc0120044101742206200520052006491b22064100480dfc010240024020040d002006102721050c010b200228020420042006102821050b2005450dee0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41db003a00000c640b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490dfb0120044101742206200520052006491b22064100480dfb010240024020040d002006102721050c010b200228020420042006102821050b2005450dee0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41dc003a00000c630b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490dfa0120044101742206200520052006491b22064100480dfa010240024020040d002006102721050c010b200228020420042006102821050b2005450dee0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41dd003a00000c620b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490df90120044101742206200520052006491b22064100480df9010240024020040d002006102721050c010b200228020420042006102821050b2005450dee0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41de003a00000c610b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490df80120044101742206200520052006491b22064100480df8010240024020040d002006102721050c010b200228020420042006102821050b2005450dee0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41df003a00000c600b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490df70120044101742206200520052006491b22064100480df7010240024020040d002006102721050c010b200228020420042006102821050b2005450dee0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41e0003a00000c5f0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490df60120044101742206200520052006491b22064100480df6010240024020040d002006102721050c010b200228020420042006102821050b2005450dee0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41e1003a00000c5e0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490df50120044101742206200520052006491b22064100480df5010240024020040d002006102721050c010b200228020420042006102821050b2005450dee0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41e2003a00000c5d0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490df40120044101742206200520052006491b22064100480df4010240024020040d002006102721050c010b200228020420042006102821050b2005450dee0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41e3003a00000c5c0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490df30120044101742206200520052006491b22064100480df3010240024020040d002006102721050c010b200228020420042006102821050b2005450dee0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41e4003a00000c5b0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490df20120044101742206200520052006491b22064100480df2010240024020040d002006102721050c010b200228020420042006102821050b2005450dee0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41e5003a00000c5a0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490df10120044101742206200520052006491b22064100480df1010240024020040d002006102721050c010b200228020420042006102821050b2005450dee0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41e6003a00000c590b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490df00120044101742206200520052006491b22064100480df0010240024020040d002006102721050c010b200228020420042006102821050b2005450dee0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41e7003a00000c580b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490def0120044101742206200520052006491b22064100480def010240024020040d002006102721050c010b200228020420042006102821050b2005450dee0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41e8003a00000c570b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490dba0220044101742206200520052006491b22064100480dba020240024020040d002006102721050c010b200228020420042006102821050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41e9003a00000c560b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490db90220044101742206200520052006491b22064100480db9020240024020040d002006102721050c010b200228020420042006102821050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41ea003a00000c550b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490db80220044101742206200520052006491b22064100480db8020240024020040d002006102721050c010b200228020420042006102821050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41eb003a00000c540b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490db70220044101742206200520052006491b22064100480db7020240024020040d002006102721050c010b200228020420042006102821050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41ec003a00000c530b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490db60220044101742206200520052006491b22064100480db6020240024020040d002006102721050c010b200228020420042006102821050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41ed003a00000c520b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490db50220044101742206200520052006491b22064100480db5020240024020040d002006102721050c010b200228020420042006102821050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41ee003a00000c510b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490db40220044101742206200520052006491b22064100480db4020240024020040d002006102721050c010b200228020420042006102821050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41ef003a00000c500b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490db30220044101742206200520052006491b22064100480db3020240024020040d002006102721050c010b200228020420042006102821050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41f0003a00000c4f0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490db20220044101742206200520052006491b22064100480db2020240024020040d002006102721050c010b200228020420042006102821050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41f1003a00000c4e0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490db10220044101742206200520052006491b22064100480db1020240024020040d002006102721050c010b200228020420042006102821050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41f2003a00000c4d0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490db00220044101742206200520052006491b22064100480db0020240024020040d002006102721050c010b200228020420042006102821050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41f3003a00000c4c0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490daf0220044101742206200520052006491b22064100480daf020240024020040d002006102721050c010b200228020420042006102821050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41f4003a00000c4b0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490dae0220044101742206200520052006491b22064100480dae020240024020040d002006102721050c010b200228020420042006102821050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41f5003a00000c4a0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490dad0220044101742206200520052006491b22064100480dad020240024020040d002006102721050c010b200228020420042006102821050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41f6003a00000c490b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490dac0220044101742206200520052006491b22064100480dac020240024020040d002006102721050c010b200228020420042006102821050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41f7003a00000c480b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490dab0220044101742206200520052006491b22064100480dab020240024020040d002006102721050c010b200228020420042006102821050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41f8003a00000c470b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490daa0220044101742206200520052006491b22064100480daa020240024020040d002006102721050c010b200228020420042006102821050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41f9003a00000c460b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490da90220044101742206200520052006491b22064100480da9020240024020040d002006102721050c010b200228020420042006102821050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41fa003a00000c450b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490da80220044101742206200520052006491b22064100480da8020240024020040d002006102721050c010b200228020420042006102821050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41fb003a00000c440b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490da70220044101742206200520052006491b22064100480da7020240024020040d002006102721050c010b200228020420042006102821050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41fc003a00000c430b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490da60220044101742206200520052006491b22064100480da6020240024020040d002006102721050c010b200228020420042006102821050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41fd003a00000c420b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490da50220044101742206200520052006491b22064100480da5020240024020040d002006102721050c010b200228020420042006102821050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41fe003a00000c410b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490da40220044101742206200520052006491b22064100480da4020240024020040d002006102721050c010b200228020420042006102821050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41ff003a00000c400b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490da30220044101742206200520052006491b22064100480da3020240024020040d002006102721050c010b200228020420042006102821050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a4180013a00000c3f0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490da20220044101742206200520052006491b22064100480da2020240024020040d002006102721050c010b200228020420042006102821050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a4181013a00000c3e0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490da10220044101742206200520052006491b22064100480da1020240024020040d002006102721050c010b200228020420042006102821050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a4182013a00000c3d0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490da00220044101742206200520052006491b22064100480da0020240024020040d002006102721050c010b200228020420042006102821050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a4183013a00000c3c0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d9f0220044101742206200520052006491b22064100480d9f020240024020040d002006102721050c010b200228020420042006102821050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a4184013a00000c3b0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d9e0220044101742206200520052006491b22064100480d9e020240024020040d002006102721050c010b200228020420042006102821050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a4185013a00000c3a0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d9d0220044101742206200520052006491b22064100480d9d020240024020040d002006102721050c010b200228020420042006102821050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a4186013a00000c390b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d9c0220044101742206200520052006491b22064100480d9c020240024020040d002006102721050c010b200228020420042006102821050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a4187013a00000c380b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d9b0220044101742206200520052006491b22064100480d9b020240024020040d002006102721050c010b200228020420042006102821050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a4188013a00000c370b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d9a0220044101742206200520052006491b22064100480d9a020240024020040d002006102721050c010b200228020420042006102821050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a4189013a00000c360b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d990220044101742206200520052006491b22064100480d99020240024020040d002006102721050c010b200228020420042006102821050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a418a013a00000c350b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d980220044101742206200520052006491b22064100480d98020240024020040d002006102721050c010b200228020420042006102821050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a418b013a00000c340b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d970220044101742206200520052006491b22064100480d97020240024020040d002006102721050c010b200228020420042006102821050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a418c013a00000c330b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d960220044101742206200520052006491b22064100480d96020240024020040d002006102721050c010b200228020420042006102821050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a418d013a00000c320b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d950220044101742206200520052006491b22064100480d95020240024020040d002006102721050c010b200228020420042006102821050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a418e013a00000c310b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d940220044101742206200520052006491b22064100480d94020240024020040d002006102721050c010b200228020420042006102821050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a418f013a00000c300b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d930220044101742206200520052006491b22064100480d93020240024020040d002006102721050c010b200228020420042006102821050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a4190013a00000c2f0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d920220044101742206200520052006491b22064100480d92020240024020040d002006102721050c010b200228020420042006102821050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a4191013a00000c2e0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d910220044101742206200520052006491b22064100480d91020240024020040d002006102721050c010b200228020420042006102821050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a4192013a00000c2d0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d900220044101742206200520052006491b22064100480d90020240024020040d002006102721050c010b200228020420042006102821050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a4193013a00000c2c0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d8f0220044101742206200520052006491b22064100480d8f020240024020040d002006102721050c010b200228020420042006102821050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a4194013a00000c2b0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d8e0220044101742206200520052006491b22064100480d8e020240024020040d002006102721050c010b200228020420042006102821050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a4195013a00000c2a0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d8d0220044101742206200520052006491b22064100480d8d020240024020040d002006102721050c010b200228020420042006102821050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a4196013a00000c290b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d8c0220044101742206200520052006491b22064100480d8c020240024020040d002006102721050c010b200228020420042006102821050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a4197013a00000c280b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d8b0220044101742206200520052006491b22064100480d8b020240024020040d002006102721050c010b200228020420042006102821050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a4198013a00000c270b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d8a0220044101742206200520052006491b22064100480d8a020240024020040d002006102721050c010b200228020420042006102821050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a4199013a00000c260b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d890220044101742206200520052006491b22064100480d89020240024020040d002006102721050c010b200228020420042006102821050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a419a013a00000c250b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d880220044101742206200520052006491b22064100480d88020240024020040d002006102721050c010b200228020420042006102821050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a419b013a00000c240b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d870220044101742206200520052006491b22064100480d87020240024020040d002006102721050c010b200228020420042006102821050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a419c013a00000c230b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d860220044101742206200520052006491b22064100480d86020240024020040d002006102721050c010b200228020420042006102821050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a419d013a00000c220b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d850220044101742206200520052006491b22064100480d85020240024020040d002006102721050c010b200228020420042006102821050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a419e013a00000c210b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d840220044101742206200520052006491b22064100480d84020240024020040d002006102721050c010b200228020420042006102821050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a419f013a00000c200b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d830220044101742206200520052006491b22064100480d83020240024020040d002006102721050c010b200228020420042006102821050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41a0013a00000c1f0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d820220044101742206200520052006491b22064100480d82020240024020040d002006102721050c010b200228020420042006102821050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41a1013a00000c1e0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d810220044101742206200520052006491b22064100480d81020240024020040d002006102721050c010b200228020420042006102821050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41a2013a00000c1d0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d800220044101742206200520052006491b22064100480d80020240024020040d002006102721050c010b200228020420042006102821050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41a3013a00000c1c0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490dff0120044101742206200520052006491b22064100480dff010240024020040d002006102721050c010b200228020420042006102821050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41a4013a00000c1b0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490dfe0120044101742206200520052006491b22064100480dfe010240024020040d002006102721050c010b200228020420042006102821050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41a5013a00000c1a0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490dfd0120044101742206200520052006491b22064100480dfd010240024020040d002006102721050c010b200228020420042006102821050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41a6013a00000c190b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490dfc0120044101742206200520052006491b22064100480dfc010240024020040d002006102721050c010b200228020420042006102821050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41a7013a00000c180b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490dfb0120044101742206200520052006491b22064100480dfb010240024020040d002006102721050c010b200228020420042006102821050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41a8013a00000c170b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490dfa0120044101742206200520052006491b22064100480dfa010240024020040d002006102721050c010b200228020420042006102821050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41a9013a00000c160b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490df90120044101742206200520052006491b22064100480df9010240024020040d002006102721050c010b200228020420042006102821050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41aa013a00000c150b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490df80120044101742206200520052006491b22064100480df8010240024020040d002006102721050c010b200228020420042006102821050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41ab013a00000c140b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490df70120044101742206200520052006491b22064100480df7010240024020040d002006102721050c010b200228020420042006102821050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41ac013a00000c130b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490df60120044101742206200520052006491b22064100480df6010240024020040d002006102721050c010b200228020420042006102821050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41ad013a00000c120b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490df50120044101742206200520052006491b22064100480df5010240024020040d002006102721050c010b200228020420042006102821050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41ae013a00000c110b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490df40120044101742206200520052006491b22064100480df4010240024020040d002006102721050c010b200228020420042006102821050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41af013a00000c100b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490df30120044101742206200520052006491b22064100480df3010240024020040d002006102721050c010b200228020420042006102821050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41b0013a00000c0f0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490df20120044101742206200520052006491b22064100480df2010240024020040d002006102721050c010b200228020420042006102821050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41b1013a00000c0e0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490df10120044101742206200520052006491b22064100480df1010240024020040d002006102721050c010b200228020420042006102821050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41b2013a00000c0d0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490df00120044101742206200520052006491b22064100480df0010240024020040d002006102721050c010b200228020420042006102821050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41b3013a00000c0c0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490dfc0120044101742206200520052006491b22064100480dfc010240024020040d002006102721050c010b200228020420042006102821050b2005450df00120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41b4013a00000c0b0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490dfb0120044101742206200520052006491b22064100480dfb010240024020040d002006102721050c010b200228020420042006102821050b2005450df00120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41b5013a00000c0a0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490dfa0120044101742206200520052006491b22064100480dfa010240024020040d002006102721050c010b200228020420042006102821050b2005450df00120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41b6013a00000c090b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490df90120044101742206200520052006491b22064100480df9010240024020040d002006102721050c010b200228020420042006102821050b2005450df00120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41b7013a00000c080b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490df80120044101742206200520052006491b22064100480df8010240024020040d002006102721050c010b200228020420042006102821050b2005450df00120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41b8013a00000c070b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490df70120044101742206200520052006491b22064100480df7010240024020040d002006102721050c010b200228020420042006102821050b2005450df00120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41b9013a00000c060b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490df60120044101742206200520052006491b22064100480df6010240024020040d002006102721050c010b200228020420042006102821050b2005450df00120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41ba013a00000c050b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490df50120044101742206200520052006491b22064100480df5010240024020040d002006102721050c010b200228020420042006102821050b2005450df00120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41bb013a00000c040b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490df40120044101742206200520052006491b22064100480df4010240024020040d002006102721050c010b200228020420042006102821050b2005450df00120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41bc013a00000c030b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490df30120044101742206200520052006491b22064100480df3010240024020040d002006102721050c010b200228020420042006102821050b2005450df00120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41bd013a00000c020b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490df20120044101742206200520052006491b22064100480df2010240024020040d002006102721050c010b200228020420042006102821050b2005450df00120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41be013a00000c010b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490df10120044101742206200520052006491b22064100480df1010240024020040d002006102721050c010b200228020420042006102821050b2005450df00120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41bf013a00000b2000411a3a000020012d00004109470df201200141086a28020041ffffffff0371450df201200141046a28020010290cf2010b20064101102a000b20064101102a000b20084101102a000b20084101102a000b20084101102a000b20084101102a000b20084101102a000b20084101102a000b20064101102a000b20064101102a000b20074101102a000b200a4101102a000b20074101102a000b200a4101102a000b20064101102a000b20084101102a000b20064101102a000b20074101102a000b200a4101102a000b20074101102a000b200a4101102a000b20064101102a000b20064101102a000b20064101102a000b20074101102a000b200a4101102a000b20074101102a000b200a4101102a000b20074101102a000b200a4101102a000b20074101102a000b200a4101102a000b20074101102a000b200a4101102a000b20084101102a000b200b4101102a000b20094101102a000b20084101102a000b200b4101102a000b20094101102a000b20084101102a000b200b4101102a000b20094101102a000b20084101102a000b200b4101102a000b20094101102a000b20084101102a000b200b4101102a000b20094101102a000b20084101102a000b200b4101102a000b20094101102a000b20084101102a000b200b4101102a000b20094101102a000b20084101102a000b200b4101102a000b20094101102a000b20084101102a000b200b4101102a000b20094101102a000b20084101102a000b200b4101102a000b20094101102a000b20084101102a000b200b4101102a000b20094101102a000b20084101102a000b200b4101102a000b20094101102a000b20084101102a000b200b4101102a000b20094101102a000b20084101102a000b102b000b200b4101102a000b20094101102a000b20084101102a000b200b4101102a000b20094101102a000b20084101102a000b200b4101102a000b20094101102a000b20084101102a000b200b4101102a000b20094101102a000b20084101102a000b200b4101102a000b20094101102a000b20084101102a000b200b4101102a000b20094101102a000b20084101102a000b200b4101102a000b20094101102a000b20084101102a000b200b4101102a000b20094101102a000b20084101102a000b200b4101102a000b20094101102a000b20084101102a000b200b4101102a000b20094101102a000b20084101102a000b20084101102a000b20084101102a000b20084101102a000b20074101102a000b20064101102a000b20084101102a000b20044101102a000b20074101102a000b20044101102a000b20064101102a000b20064101102a000b20064101102a000b20064101102a000b20064101102a000b20064101102a000b20064101102a000b20064101102a000b20064101102a000b20064101102a000b20064101102a000b20064101102a000b20064101102a000b20064101102a000b20064101102a000b20064101102a000b20064101102a000b20064101102a000b20064101102a000b20064101102a000b20064101102a000b20064101102a000b20064101102a000b20064101102a000b20064101102a000b20064101102a000b20064101102a000b20064101102a000b20064101102a000b20064101102a000b20064101102a000b20064101102a000b20064101102a000b20064101102a000b20064101102a000b20064101102a000b102b000b20064101102a000b20064101102a000b20064101102a000b20064101102a000b20064101102a000b20064101102a000b20064101102a000b20064101102a000b20064101102a000b20064101102a000b20064101102a000b20064101102a000b20064101102a000b20064101102a000b20064101102a000b20064101102a000b20064101102a000b20064101102a000b20064101102a000b20064101102a000b20064101102a000b20064101102a000b20064101102a000b20064101102a000b20064101102a000b20064101102a000b20064101102a000b20064101102a000b20064101102a000b20064101102a000b20064101102a000b20064101102a000b20064101102a000b20064101102a000b20064101102a000b20064101102a000b20064101102a000b20064101102a000b20064101102a000b20064101102a000b20064101102a000b20064101102a000b20064101102a000b20064101102a000b20064101102a000b20064101102a000b20064101102a000b20064101102a000b20064101102a000b20064101102a000b20064101102a000b20064101102a000b20064101102a000b20064101102a000b20064101102a000b20064101102a000b20064101102a000b20064101102a000b20064101102a000b20064101102a000b20064101102a000b20064101102a000b20064101102a000b20064101102a000b20064101102a000b20064101102a000b20064101102a000b20064101102a000b20064101102a000b20064101102a000b20064101102a000b20064101102a000b20064101102a000b20064101102a000b20064101102a000b102b000b20064101102a000b20064101102a000b20064101102a000b20064101102a000b20064101102a000b20064101102a000b20064101102a000b20064101102a000b20064101102a000b20064101102a000b20064101102a000b20064101102a000b102b000b20002003290300370200200041086a200341086a290300370200200941ffffffff0371450d01200b10290c010b20002002290200370200200041086a200241086a29020037020020012d00004109470d00200141086a28020041ffffffff0371450d00200141046a28020010290b200341106a24000bb60301057f2004410c6a2105200441086a2106024002400240034002400240200628020020052802002207460d00200428020421080c010b200741016a22082007490d0420074101742209200820082009491b22094100480d040240024020070d002009102721080c010b200428020420072009102821080b2008450d022004200836020420062009360200200528020021070b2005200741016a360200200820076a200141807f72200141ff0071200141077622071b3a00002007210120070d000b024020022003460d002004410c6a2105200441086a2106034020022802002101034002400240200628020020052802002207460d00200428020421080c010b200741016a22082007490d0620074101742209200820082009491b22094100480d060240024020070d002009102721080c010b200428020420072009102821080b2008450d052004200836020420062009360200200528020021070b2005200741016a360200200820076a200141807f72200141ff0071200141077622071b3a00002007210120070d000b200241046a22022003470d000b0b2000411a3a00000f0b20094101102a000b20094101102a000b102b000bc30301067f200141c000712103200141ff0071210402400240024002400240200141077522050d002003450d010b2002410c6a2106200241086a2107034002402005417f470d00200341ff01710d020b02400240200728020020062802002208460d00200228020421030c010b200841016a22032008490d0520084101742204200320032004491b22044100480d050240024020080d002004102721030c010b200228020420082004102821030b2003450d032002200336020420072004360200200628020021080b2006200841016a360200200320086a200141807f723a0000200541c000712103200541ff007121042005210120054107752208210520080d002008210520030d000b0b02400240200241086a2802002002410c6a2802002205460d00200228020421080c010b200541016a22082005490d0320054101742203200820082003491b22034100480d030240024020050d002003102721080c010b200228020420052003102821080b2008450d0220022008360204200241086a20033602002002410c6a28020021050b2002410c6a200541016a360200200820056a20043a00002000411a3a00000f0b20044101102a000b20034101102a000b102b000bc30301067f2001a7220341c000712104200341ff0071210502400240024002400240200142078722014200520d002004450d010b2002410c6a2106200241086a2107034002402001427f520d00200441ff01710d020b02400240200728020020062802002204460d00200228020421050c010b200441016a22052004490d0520044101742208200520052008491b22084100480d050240024020040d002008102721050c010b200228020420042008102821050b2005450d032002200536020420072008360200200628020021040b2006200441016a360200200520046a200341807f723a00002001a7220341c000712104200341ff00712105200142078722014200520d0020040d000b0b02400240200241086a2802002002410c6a2802002204460d00200228020421030c010b200441016a22032004490d0320044101742206200320032006491b22064100480d030240024020040d002006102721030c010b200228020420042006102821030b2003450d0220022003360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200320046a20053a00002000411a3a00000f0b20084101102a000b20064101102a000b102b000bcf03010a7f230041306b22022400200241216a220341076a210441002105410021064100210741002108410821090240024002400340200241186a200110e403024020022802184101470d002000200229021c370204200041013602002000410c6a200241186a410c6a29020037020002402007450d00200921070340024020072d00004109470d00200741086a28020041ffffffff0371450d00200741046a28020010290b200741106a2107200641706a22060d000b0b2008450d04200910290c040b200220032900003703082002200429000037000f20022d0020210a2002200229000f37001f200220022903083703180240024020072008470d00200741016a220b2007490d032005200b200b2005491b220841ffffffff00712008470d032008410474220b4100480d030240024020070d00200b102721090c010b20092006200b102821090b2009450d010b200920066a220b200a3a0000200b41016a2002290318370000200b41086a200229001f370000200541026a2105200641106a2106200741016a2107200a41ff01714106460d030c010b0b200b4108102a000b102b000b20002009360204200041003602002000410c6a2007360200200041086a20083602000b200241306a24000b99b601020a7f017e230041f0006b2202240002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024020012802082203200128020c2204460d00200441016a22052004490d02200320054f0d0120052003107f000b200241013a0048200241ec006a41013602002002420137025c20024180c0c5003602582002411f36023c2002200241386a3602682002200241c8006a360238200241086a200241d8006a10e603200241336a200241106a2802003600002002200229030837002b2002200229002837031820022002412f6a29000037001f200041053a0004200020022903183700052000410c6a200229001f370000200041013602000c610b2001280200220620046a2d000021072001410c6a2208200536020002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240200741bf014b0d0020070ec001b702b702010203b70200000000000405060708090a00000000000000000b0c000000000d0e0f101100000012131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f80018101820183018401850186018701880189018a018b018c018d018e018f0190019101920193019401950196019701980199019a019b019c019d019e019f01a001a101a201a301a401a501a601a701a801a901b7020b2000410b3a000420004101360200200041056a20073a00000cb9020b024002400240024002400240024020032005460d00200441026a21092005417f460de00120032009490da102200620056a2c00002101200820093602004100210a0240200141004e0d00411821090c020b0240200141017441807f71200172220141ff0171220541847e6a220941034d0d0041062109200541c001470d034104210a410221070cbd020b20090e0404030506040b200241013a0047200241ec006a41013602002002420137025c20024180c0c5003602582002411f36023c2002200241386a3602682002200241c7006a360238200241c8006a200241d8006a10e603200241326a200241d0006a2802003601002002200229034837012a2002200229012837031820022002412e6a29010037011e410521090b2002200229011e37010e200220022903183703080b200020013a0005200020093a000420002002290308370106200041013602002000410c6a200229010e3701000cbc020b4102210a410221070cb8020b4103210a410221070cb7020b4101210a0b410221070cb5020b024002400240024002400240024020032005460d00200441026a21092005417f460de00120032009490da102200620056a2c00002101200820093602004100210a0240200141004e0d00411821090c020b0240200141017441807f71200172220141ff0171220541847e6a220941034d0d0041062109200541c001470d034104210a410321070cbc020b20090e0404030506040b200241013a0047200241ec006a41013602002002420137025c20024180c0c5003602582002411f36023c2002200241386a3602682002200241c7006a360238200241c8006a200241d8006a10e603200241326a200241d0006a2802003601002002200229034837012a2002200229012837031820022002412e6a29010037011e410521090b2002200229011e37010e200220022903183703080b200020013a0005200020093a000420002002290308370106200041013602002000410c6a200229010e3701000cbb020b4102210a410321070cb7020b4103210a410321070cb6020b4101210a0b410321070cb4020b024002400240024002400240024020032005460d00200441026a21092005417f460de00120032009490da102200620056a2c00002101200820093602004100210a0240200141004e0d00411821090c020b0240200141017441807f71200172220141ff0171220541847e6a220941034d0d0041062109200541c001470d034104210a410421070cbb020b20090e0404030506040b200241013a0047200241ec006a41013602002002420137025c20024180c0c5003602582002411f36023c2002200241386a3602682002200241c7006a360238200241c8006a200241d8006a10e603200241326a200241d0006a2802003601002002200229034837012a2002200229012837031820022002412e6a29010037011e410521090b2002200229011e37010e200220022903183703080b200020013a0005200020093a000420002002290308370106200041013602002000410c6a200229010e3701000cba020b4102210a410421070cb6020b4103210a410421070cb5020b4101210a0b410421070cb3020b410621070cb2020b410021014100210902400240034002402001411f4d0d00410f21010c020b0240024020032005460d002005417f460ddd012003200541016a22074f0d01200541016a2003107f000b200241013a0018200241ec006a41013602002002420137025c20024180c0c5003602582002411f36023c2002200241386a3602682002200241186a360238200241286a200241d8006a10e603410521010c020b200620056a2d0000210420082007360200200441ff00712001411f71742009722109200141076a2101200721052004418001710d000b20014120490d01410d210120044110490d010b2000200136020420004101360200200041086a2002290228370200200041106a200241286a41086a2802003602000cb5020b410721070cb1020b410021014100210902400240034002402001411f4d0d00410f21010c020b0240024020032005460d002005417f460ddd012003200541016a22074f0d01200541016a2003107f000b200241013a0018200241ec006a41013602002002420137025c20024180c0c5003602582002411f36023c2002200241386a3602682002200241186a360238200241286a200241d8006a10e603410521010c020b200620056a2d0000210420082007360200200441ff00712001411f71742009722109200141076a2101200721052004418001710d000b20014120490d01410d210120044110490d010b2000200136020420004101360200200041086a2002290228370200200041106a200241286a41086a2802003602000cb4020b410821070cb0020b200241d8006a200110e70341042109200228025822064101460da201200241e0006a280200210b200228025c210302400240200241e4006a28020022040d00410021074100210a0c010b0240024020044102742205410275220741ffffffff03712007470d0020054100480d002005102722090d0120054104102a000b102b000b200441027421042005417c6a210a410021050340200920056a200320056a2802003602002004200541046a2205470d000b200a41027641016a210a0b0240200b450d00200310290b20022d005c4105470dae022006450dae0220022802640da3010cae020b410a21070cae020b410021014100210902400240034002402001411f4d0d00410f21010c020b0240024020032005460d002005417f460ddb012003200541016a22074f0d01200541016a2003107f000b200241013a0018200241ec006a41013602002002420137025c20024180c0c5003602582002411f36023c2002200241386a3602682002200241186a360238200241286a200241d8006a10e603410521010c020b200620056a2d0000210420082007360200200441ff00712001411f71742009722109200141076a2101200721052004418001710d000b20014120490d01410d210120044110490d010b2000200136020420004101360200200041086a2002290228370200200041106a200241286a41086a2802003602000cb1020b410b21070cad020b410021014100210902400240034002402001411f4d0d00410f21010c020b0240024020032005460d002005417f460ddb012003200541016a22044f0d01200541016a2003107f000b200241013a0018200241ec006a41013602002002420137025c20024180c0c5003602582002411f36023c2002200241386a3602682002200241186a360238200241286a200241d8006a10e603410521010c020b200620056a2d0000210720082004360200200741ff00712001411f71742009722109200141076a2101200421052007418001710d000b20014120490d01410d210120074110490d010b2000200136020420004101360200200041086a2002290228370200200041106a200241286a41086a2802003602000cb0020b0240024020032004460d00200441016a22012004490dd901200320014f0d0120012003107f000b200241013a0048200241ec006a41013602002002420137025c20024180c0c5003602582002411f36023c2002200241386a3602682002200241c8006a360238200241086a200241d8006a10e603200241336a200241106a2802003600002002200229030837002b2002200229002837031820022002412f6a29000037001f200041053a0004200020022903183700052000410c6a200229001f370000200041013602000cb0020b200620046a2d0000210520082001360200024020050d00410c21074100210a0cad020b200041163a000420004101360200200041056a20053a00000caf020b410d21070cab020b410e21070caa020b410021014100210902400240034002402001411f4d0d00410f21010c020b0240024020032005460d002005417f460dda012003200541016a22074f0d01200541016a2003107f000b200241013a0018200241ec006a41013602002002420137025c20024180c0c5003602582002411f36023c2002200241386a3602682002200241186a360238200241286a200241d8006a10e603410521010c020b200620056a2d0000210420082007360200200441ff00712001411f71742009722109200141076a2101200721052004418001710d000b20014120490d01410d210120044110490d010b2000200136020420004101360200200041086a2002290228370200200041106a200241286a41086a2802003602000cad020b410f21070ca9020b410021014100210902400240034002402001411f4d0d00410f21010c020b0240024020032005460d002005417f460dda012003200541016a22074f0d01200541016a2003107f000b200241013a0018200241ec006a41013602002002420137025c20024180c0c5003602582002411f36023c2002200241386a3602682002200241186a360238200241286a200241d8006a10e603410521010c020b200620056a2d0000210420082007360200200441ff00712001411f71742009722109200141076a2101200721052004418001710d000b20014120490d01410d210120044110490d010b2000200136020420004101360200200041086a2002290228370200200041106a200241286a41086a2802003602000cac020b411021070ca8020b410021014100210902400240034002402001411f4d0d00410f21010c020b0240024020032005460d002005417f460dda012003200541016a22074f0d01200541016a2003107f000b200241013a0018200241ec006a41013602002002420137025c20024180c0c5003602582002411f36023c2002200241386a3602682002200241186a360238200241286a200241d8006a10e603410521010c020b200620056a2d0000210420082007360200200441ff00712001411f71742009722109200141076a2101200721052004418001710d000b20014120490d01410d210120044110490d010b2000200136020420004101360200200041086a2002290228370200200041106a200241286a41086a2802003602000cab020b411121070ca7020b410021014100210902400240034002402001411f4d0d00410f21010c020b0240024020032005460d002005417f460dda012003200541016a22074f0d01200541016a2003107f000b200241013a0018200241ec006a41013602002002420137025c20024180c0c5003602582002411f36023c2002200241386a3602682002200241186a360238200241286a200241d8006a10e603410521010c020b200620056a2d0000210420082007360200200441ff00712001411f71742009722109200141076a2101200721052004418001710d000b20014120490d01410d210120044110490d010b2000200136020420004101360200200041086a2002290228370200200041106a200241286a41086a2802003602000caa020b411221070ca6020b410021014100210902400240034002402001411f4d0d00410f21010c020b0240024020032005460d002005417f460dda012003200541016a22074f0d01200541016a2003107f000b200241013a0018200241ec006a41013602002002420137025c20024180c0c5003602582002411f36023c2002200241386a3602682002200241186a360238200241286a200241d8006a10e603410521010c020b200620056a2d0000210420082007360200200441ff00712001411f71742009722109200141076a2101200721052004418001710d000b20014120490d01410d210120044110490d010b2000200136020420004101360200200041086a2002290228370200200041106a200241286a41086a2802003602000ca9020b411321070ca5020b410120036b2107200441026a21014100210541002109024002400240034002402005411f4d0d00410f21010c020b02400240200720016a4102460d002001450ddb01200320014f0d0120012003107f000b200241013a0018200241ec006a41013602002002420137025c20024180c0c5003602582002411f36023c2002200241386a3602682002200241186a360238200241286a200241d8006a10e60320022802282109200228022c210520022802302103410521010c030b200620016a417f6a2d0000210420082001360200200441ff00712005411f71742009722109200141016a2101200541076a21052004418001710d000b20054120490d0220044110490d02410d21010b0b2000200136020420004101360200200041106a20033602002000410c6a2005360200200041086a20093602000ca8020b2001417f6a2101410021054100210a034002402005411f4d0d00410f21010c9c010b20032001460d9a012001417f460dd7012003200141016a2207490d8d02200620016a2d0000210420082007360200200441ff00712005411f7174200a72210a200541076a2105200721012004418001710d000b024020054120490d00410d21012004410f4b0d9b010b200aad210c411421070ca4020b410120036b2107200441026a21014100210541002109024002400240034002402005411f4d0d00410f21010c020b02400240200720016a4102460d002001450ddc01200320014f0d0120012003107f000b200241013a0018200241ec006a41013602002002420137025c20024180c0c5003602582002411f36023c2002200241386a3602682002200241186a360238200241286a200241d8006a10e60320022802282109200228022c210520022802302103410521010c030b200620016a417f6a2d0000210420082001360200200441ff00712005411f71742009722109200141016a2101200541076a21052004418001710d000b20054120490d0220044110490d02410d21010b0b2000200136020420004101360200200041106a20033602002000410c6a2005360200200041086a20093602000ca7020b2001417f6a2101410021054100210a034002402005411f4d0d00410f21010c9d010b20032001460d9b012001417f460dd8012003200141016a2207490d8d02200620016a2d0000210420082007360200200441ff00712005411f7174200a72210a200541076a2105200721012004418001710d000b024020054120490d00410d21012004410f4b0d9c010b200aad210c411521070ca3020b410120036b2107200441026a21014100210541002109024002400240034002402005411f4d0d00410f21010c020b02400240200720016a4102460d002001450ddd01200320014f0d0120012003107f000b200241013a0018200241ec006a41013602002002420137025c20024180c0c5003602582002411f36023c2002200241386a3602682002200241186a360238200241286a200241d8006a10e60320022802282109200228022c210520022802302103410521010c030b200620016a417f6a2d0000210420082001360200200441ff00712005411f71742009722109200141016a2101200541076a21052004418001710d000b20054120490d0220044110490d02410d21010b0b2000200136020420004101360200200041106a20033602002000410c6a2005360200200041086a20093602000ca6020b2001417f6a2101410021054100210a034002402005411f4d0d00410f21010c9e010b20032001460d9c012001417f460dd9012003200141016a2207490d8d02200620016a2d0000210420082007360200200441ff00712005411f7174200a72210a200541076a2105200721012004418001710d000b024020054120490d00410d21012004410f4b0d9d010b200aad210c411621070ca2020b410120036b2107200441026a21014100210541002109024002400240034002402005411f4d0d00410f21010c020b02400240200720016a4102460d002001450dde01200320014f0d0120012003107f000b200241013a0018200241ec006a41013602002002420137025c20024180c0c5003602582002411f36023c2002200241386a3602682002200241186a360238200241286a200241d8006a10e60320022802282109200228022c210520022802302103410521010c030b200620016a417f6a2d0000210420082001360200200441ff00712005411f71742009722109200141016a2101200541076a21052004418001710d000b20054120490d0220044110490d02410d21010b0b2000200136020420004101360200200041106a20033602002000410c6a2005360200200041086a20093602000ca5020b2001417f6a2101410021054100210a034002402005411f4d0d00410f21010c9f010b20032001460d9d012001417f460dda012003200141016a2207490d8d02200620016a2d0000210420082007360200200441ff00712005411f7174200a72210a200541076a2105200721012004418001710d000b024020054120490d00410d21012004410f4b0d9e010b200aad210c411721070ca1020b410120036b2107200441026a21014100210541002109024002400240034002402005411f4d0d00410f21010c020b02400240200720016a4102460d002001450ddf01200320014f0d0120012003107f000b200241013a0018200241ec006a41013602002002420137025c20024180c0c5003602582002411f36023c2002200241386a3602682002200241186a360238200241286a200241d8006a10e60320022802282109200228022c210520022802302103410521010c030b200620016a417f6a2d0000210420082001360200200441ff00712005411f71742009722109200141016a2101200541076a21052004418001710d000b20054120490d0220044110490d02410d21010b0b2000200136020420004101360200200041106a20033602002000410c6a2005360200200041086a20093602000ca4020b2001417f6a2101410021054100210a034002402005411f4d0d00410f21010ca0010b20032001460d9e012001417f460ddb012003200141016a2207490d8d02200620016a2d0000210420082007360200200441ff00712005411f7174200a72210a200541076a2105200721012004418001710d000b024020054120490d00410d21012004410f4b0d9f010b200aad210c411821070ca0020b410120036b2107200441026a21014100210541002109024002400240034002402005411f4d0d00410f21010c020b02400240200720016a4102460d002001450de001200320014f0d0120012003107f000b200241013a0018200241ec006a41013602002002420137025c20024180c0c5003602582002411f36023c2002200241386a3602682002200241186a360238200241286a200241d8006a10e60320022802282109200228022c210520022802302103410521010c030b200620016a417f6a2d0000210420082001360200200441ff00712005411f71742009722109200141016a2101200541076a21052004418001710d000b20054120490d0220044110490d02410d21010b0b2000200136020420004101360200200041106a20033602002000410c6a2005360200200041086a20093602000ca3020b2001417f6a2101410021054100210a034002402005411f4d0d00410f21010ca1010b20032001460d9f012001417f460ddc012003200141016a2207490d8d02200620016a2d0000210420082007360200200441ff00712005411f7174200a72210a200541076a2105200721012004418001710d000b024020054120490d00410d21012004410f4b0da0010b200aad210c411921070c9f020b410120036b2107200441026a21014100210541002109024002400240034002402005411f4d0d00410f21010c020b02400240200720016a4102460d002001450de101200320014f0d0120012003107f000b200241013a0018200241ec006a41013602002002420137025c20024180c0c5003602582002411f36023c2002200241386a3602682002200241186a360238200241286a200241d8006a10e60320022802282109200228022c210520022802302103410521010c030b200620016a417f6a2d0000210420082001360200200441ff00712005411f71742009722109200141016a2101200541076a21052004418001710d000b20054120490d0220044110490d02410d21010b0b2000200136020420004101360200200041106a20033602002000410c6a2005360200200041086a20093602000ca2020b2001417f6a2101410021054100210a034002402005411f4d0d00410f21010ca2010b20032001460da0012001417f460ddd012003200141016a2207490d8d02200620016a2d0000210420082007360200200441ff00712005411f7174200a72210a200541076a2105200721012004418001710d000b024020054120490d00410d21012004410f4b0da1010b200aad210c411a21070c9e020b410120036b2107200441026a21014100210541002109024002400240034002402005411f4d0d00410f21010c020b02400240200720016a4102460d002001450de201200320014f0d0120012003107f000b200241013a0018200241ec006a41013602002002420137025c20024180c0c5003602582002411f36023c2002200241386a3602682002200241186a360238200241286a200241d8006a10e60320022802282109200228022c210520022802302103410521010c030b200620016a417f6a2d0000210420082001360200200441ff00712005411f71742009722109200141016a2101200541076a21052004418001710d000b20054120490d0220044110490d02410d21010b0b2000200136020420004101360200200041106a20033602002000410c6a2005360200200041086a20093602000ca1020b2001417f6a2101410021054100210a034002402005411f4d0d00410f21010ca3010b20032001460da1012001417f460dde012003200141016a2207490d8d02200620016a2d0000210420082007360200200441ff00712005411f7174200a72210a200541076a2105200721012004418001710d000b024020054120490d00410d21012004410f4b0da2010b200aad210c411b21070c9d020b410120036b2107200441026a21014100210541002109024002400240034002402005411f4d0d00410f21010c020b02400240200720016a4102460d002001450de301200320014f0d0120012003107f000b200241013a0018200241ec006a41013602002002420137025c20024180c0c5003602582002411f36023c2002200241386a3602682002200241186a360238200241286a200241d8006a10e60320022802282109200228022c210520022802302103410521010c030b200620016a417f6a2d0000210420082001360200200441ff00712005411f71742009722109200141016a2101200541076a21052004418001710d000b20054120490d0220044110490d02410d21010b0b2000200136020420004101360200200041106a20033602002000410c6a2005360200200041086a20093602000ca0020b2001417f6a2101410021054100210a034002402005411f4d0d00410f21010ca4010b20032001460da2012001417f460ddf012003200141016a2207490d8d02200620016a2d0000210420082007360200200441ff00712005411f7174200a72210a200541076a2105200721012004418001710d000b024020054120490d00410d21012004410f4b0da3010b200aad210c411c21070c9c020b410120036b2107200441026a21014100210541002109024002400240034002402005411f4d0d00410f21010c020b02400240200720016a4102460d002001450de401200320014f0d0120012003107f000b200241013a0018200241ec006a41013602002002420137025c20024180c0c5003602582002411f36023c2002200241386a3602682002200241186a360238200241286a200241d8006a10e60320022802282109200228022c210520022802302103410521010c030b200620016a417f6a2d0000210420082001360200200441ff00712005411f71742009722109200141016a2101200541076a21052004418001710d000b20054120490d0220044110490d02410d21010b0b2000200136020420004101360200200041106a20033602002000410c6a2005360200200041086a20093602000c9f020b2001417f6a2101410021054100210a034002402005411f4d0d00410f21010ca5010b20032001460da3012001417f460de0012003200141016a2207490d8d02200620016a2d0000210420082007360200200441ff00712005411f7174200a72210a200541076a2105200721012004418001710d000b024020054120490d00410d21012004410f4b0da4010b200aad210c411d21070c9b020b410120036b2107200441026a21014100210541002109024002400240034002402005411f4d0d00410f21010c020b02400240200720016a4102460d002001450de501200320014f0d0120012003107f000b200241013a0018200241ec006a41013602002002420137025c20024180c0c5003602582002411f36023c2002200241386a3602682002200241186a360238200241286a200241d8006a10e60320022802282109200228022c210520022802302103410521010c030b200620016a417f6a2d0000210420082001360200200441ff00712005411f71742009722109200141016a2101200541076a21052004418001710d000b20054120490d0220044110490d02410d21010b0b2000200136020420004101360200200041106a20033602002000410c6a2005360200200041086a20093602000c9e020b2001417f6a2101410021054100210a034002402005411f4d0d00410f21010ca6010b20032001460da4012001417f460de1012003200141016a2207490d8d02200620016a2d0000210420082007360200200441ff00712005411f7174200a72210a200541076a2105200721012004418001710d000b024020054120490d00410d21012004410f4b0da5010b200aad210c411e21070c9a020b410120036b2107200441026a21014100210541002109024002400240034002402005411f4d0d00410f21010c020b02400240200720016a4102460d002001450de601200320014f0d0120012003107f000b200241013a0018200241ec006a41013602002002420137025c20024180c0c5003602582002411f36023c2002200241386a3602682002200241186a360238200241286a200241d8006a10e60320022802282109200228022c210520022802302103410521010c030b200620016a417f6a2d0000210420082001360200200441ff00712005411f71742009722109200141016a2101200541076a21052004418001710d000b20054120490d0220044110490d02410d21010b0b2000200136020420004101360200200041106a20033602002000410c6a2005360200200041086a20093602000c9d020b2001417f6a2101410021054100210a034002402005411f4d0d00410f21010ca7010b20032001460da5012001417f460de2012003200141016a2207490d8d02200620016a2d0000210420082007360200200441ff00712005411f7174200a72210a200541076a2105200721012004418001710d000b024020054120490d00410d21012004410f4b0da6010b200aad210c411f21070c99020b410120036b2107200441026a21014100210541002109024002400240034002402005411f4d0d00410f21010c020b02400240200720016a4102460d002001450de701200320014f0d0120012003107f000b200241013a0018200241ec006a41013602002002420137025c20024180c0c5003602582002411f36023c2002200241386a3602682002200241186a360238200241286a200241d8006a10e60320022802282109200228022c210520022802302103410521010c030b200620016a417f6a2d0000210420082001360200200441ff00712005411f71742009722109200141016a2101200541076a21052004418001710d000b20054120490d0220044110490d02410d21010b0b2000200136020420004101360200200041106a20033602002000410c6a2005360200200041086a20093602000c9c020b2001417f6a2101410021054100210a034002402005411f4d0d00410f21010ca8010b20032001460da6012001417f460de3012003200141016a2207490d8d02200620016a2d0000210420082007360200200441ff00712005411f7174200a72210a200541076a2105200721012004418001710d000b41202107024020054120490d00410d21012004410f4b0da7010b200aad210c0c98020b410120036b2107200441026a21014100210541002109024002400240034002402005411f4d0d00410f21010c020b02400240200720016a4102460d002001450de801200320014f0d0120012003107f000b200241013a0018200241ec006a41013602002002420137025c20024180c0c5003602582002411f36023c2002200241386a3602682002200241186a360238200241286a200241d8006a10e60320022802282109200228022c210520022802302103410521010c030b200620016a417f6a2d0000210420082001360200200441ff00712005411f71742009722109200141016a2101200541076a21052004418001710d000b20054120490d0220044110490d02410d21010b0b2000200136020420004101360200200041106a20033602002000410c6a2005360200200041086a20093602000c9b020b2001417f6a2101410021054100210a034002402005411f4d0d00410f21010ca9010b20032001460da7012001417f460de4012003200141016a2207490d8d02200620016a2d0000210420082007360200200441ff00712005411f7174200a72210a200541076a2105200721012004418001710d000b024020054120490d00410d21012004410f4b0da8010b200aad210c412121070c97020b410120036b2107200441026a21014100210541002109024002400240034002402005411f4d0d00410f21010c020b02400240200720016a4102460d002001450de901200320014f0d0120012003107f000b200241013a0018200241ec006a41013602002002420137025c20024180c0c5003602582002411f36023c2002200241386a3602682002200241186a360238200241286a200241d8006a10e60320022802282109200228022c210520022802302103410521010c030b200620016a417f6a2d0000210420082001360200200441ff00712005411f71742009722109200141016a2101200541076a21052004418001710d000b20054120490d0220044110490d02410d21010b0b2000200136020420004101360200200041106a20033602002000410c6a2005360200200041086a20093602000c9a020b2001417f6a2101410021054100210a034002402005411f4d0d00410f21010caa010b20032001460da8012001417f460de5012003200141016a2207490d8d02200620016a2d0000210420082007360200200441ff00712005411f7174200a72210a200541076a2105200721012004418001710d000b024020054120490d00410d21012004410f4b0da9010b200aad210c412221070c96020b410120036b2107200441026a21014100210541002109024002400240034002402005411f4d0d00410f21010c020b02400240200720016a4102460d002001450dea01200320014f0d0120012003107f000b200241013a0018200241ec006a41013602002002420137025c20024180c0c5003602582002411f36023c2002200241386a3602682002200241186a360238200241286a200241d8006a10e60320022802282109200228022c210520022802302103410521010c030b200620016a417f6a2d0000210420082001360200200441ff00712005411f71742009722109200141016a2101200541076a21052004418001710d000b20054120490d0220044110490d02410d21010b0b2000200136020420004101360200200041106a20033602002000410c6a2005360200200041086a20093602000c99020b2001417f6a2101410021054100210a034002402005411f4d0d00410f21010cab010b20032001460da9012001417f460de6012003200141016a2207490d8d02200620016a2d0000210420082007360200200441ff00712005411f7174200a72210a200541076a2105200721012004418001710d000b024020054120490d00410d21012004410f4b0daa010b200aad210c412321070c95020b410120036b2107200441026a21014100210541002109024002400240034002402005411f4d0d00410f21010c020b02400240200720016a4102460d002001450deb01200320014f0d0120012003107f000b200241013a0018200241ec006a41013602002002420137025c20024180c0c5003602582002411f36023c2002200241386a3602682002200241186a360238200241286a200241d8006a10e60320022802282109200228022c210520022802302103410521010c030b200620016a417f6a2d0000210420082001360200200441ff00712005411f71742009722109200141016a2101200541076a21052004418001710d000b20054120490d0220044110490d02410d21010b0b2000200136020420004101360200200041106a20033602002000410c6a2005360200200041086a20093602000c98020b2001417f6a2101410021054100210a034002402005411f4d0d00410f21010cac010b20032001460daa012001417f460de7012003200141016a2207490d8d02200620016a2d0000210420082007360200200441ff00712005411f7174200a72210a200541076a2105200721012004418001710d000b024020054120490d00410d21012004410f4b0dab010b200aad210c412421070c94020b410120036b2107200441026a21014100210541002109024002400240034002402005411f4d0d00410f21010c020b02400240200720016a4102460d002001450dec01200320014f0d0120012003107f000b200241013a0018200241ec006a41013602002002420137025c20024180c0c5003602582002411f36023c2002200241386a3602682002200241186a360238200241286a200241d8006a10e60320022802282109200228022c210520022802302103410521010c030b200620016a417f6a2d0000210420082001360200200441ff00712005411f71742009722109200141016a2101200541076a21052004418001710d000b20054120490d0220044110490d02410d21010b0b2000200136020420004101360200200041106a20033602002000410c6a2005360200200041086a20093602000c97020b2001417f6a2101410021054100210a034002402005411f4d0d00410f21010cad010b20032001460dab012001417f460de8012003200141016a2207490d8d02200620016a2d0000210420082007360200200441ff00712005411f7174200a72210a200541076a2105200721012004418001710d000b024020054120490d00410d21012004410f4b0dac010b200aad210c412521070c93020b410120036b2107200441026a21014100210541002109024002400240034002402005411f4d0d00410f21010c020b02400240200720016a4102460d002001450ded01200320014f0d0120012003107f000b200241013a0018200241ec006a41013602002002420137025c20024180c0c5003602582002411f36023c2002200241386a3602682002200241186a360238200241286a200241d8006a10e60320022802282109200228022c210520022802302103410521010c030b200620016a417f6a2d0000210420082001360200200441ff00712005411f71742009722109200141016a2101200541076a21052004418001710d000b20054120490d0220044110490d02410d21010b0b2000200136020420004101360200200041106a20033602002000410c6a2005360200200041086a20093602000c96020b2001417f6a2101410021054100210a034002402005411f4d0d00410f21010cae010b20032001460dac012001417f460de9012003200141016a2207490d8d02200620016a2d0000210420082007360200200441ff00712005411f7174200a72210a200541076a2105200721012004418001710d000b024020054120490d00410d21012004410f4b0dad010b200aad210c412621070c92020b410120036b2107200441026a21014100210541002109024002400240034002402005411f4d0d00410f21010c020b02400240200720016a4102460d002001450dee01200320014f0d0120012003107f000b200241013a0018200241ec006a41013602002002420137025c20024180c0c5003602582002411f36023c2002200241386a3602682002200241186a360238200241286a200241d8006a10e60320022802282109200228022c210520022802302103410521010c030b200620016a417f6a2d0000210420082001360200200441ff00712005411f71742009722109200141016a2101200541076a21052004418001710d000b20054120490d0220044110490d02410d21010b0b2000200136020420004101360200200041106a20033602002000410c6a2005360200200041086a20093602000c95020b2001417f6a2101410021054100210a034002402005411f4d0d00410f21010caf010b20032001460dad012001417f460dea012003200141016a2207490d8d02200620016a2d0000210420082007360200200441ff00712005411f7174200a72210a200541076a2105200721012004418001710d000b024020054120490d00410d21012004410f4b0dae010b200aad210c412721070c91020b410120036b2107200441026a21014100210541002109024002400240034002402005411f4d0d00410f21010c020b02400240200720016a4102460d002001450def01200320014f0d0120012003107f000b200241013a0018200241ec006a41013602002002420137025c20024180c0c5003602582002411f36023c2002200241386a3602682002200241186a360238200241286a200241d8006a10e60320022802282109200228022c210520022802302103410521010c030b200620016a417f6a2d0000210420082001360200200441ff00712005411f71742009722109200141016a2101200541076a21052004418001710d000b20054120490d0220044110490d02410d21010b0b2000200136020420004101360200200041106a20033602002000410c6a2005360200200041086a20093602000c94020b2001417f6a2101410021054100210a034002402005411f4d0d00410f21010cb0010b20032001460dae012001417f460deb012003200141016a2207490d8d02200620016a2d0000210420082007360200200441ff00712005411f7174200a72210a200541076a2105200721012004418001710d000b024020054120490d00410d21012004410f4b0daf010b200aad210c412821070c90020b410120036b2107200441026a21014100210541002109024002400240034002402005411f4d0d00410f21010c020b02400240200720016a4102460d002001450df001200320014f0d0120012003107f000b200241013a0018200241ec006a41013602002002420137025c20024180c0c5003602582002411f36023c2002200241386a3602682002200241186a360238200241286a200241d8006a10e60320022802282109200228022c210520022802302103410521010c030b200620016a417f6a2d0000210420082001360200200441ff00712005411f71742009722109200141016a2101200541076a21052004418001710d000b20054120490d0220044110490d02410d21010b0b2000200136020420004101360200200041106a20033602002000410c6a2005360200200041086a20093602000c93020b2001417f6a2101410021054100210a034002402005411f4d0d00410f21010cb1010b20032001460daf012001417f460dec012003200141016a2207490d8d02200620016a2d0000210420082007360200200441ff00712005411f7174200a72210a200541076a2105200721012004418001710d000b024020054120490d00410d21012004410f4b0db0010b200aad210c412921070c8f020b410120036b2107200441026a21014100210541002109024002400240034002402005411f4d0d00410f21010c020b02400240200720016a4102460d002001450df101200320014f0d0120012003107f000b200241013a0018200241ec006a41013602002002420137025c20024180c0c5003602582002411f36023c2002200241386a3602682002200241186a360238200241286a200241d8006a10e60320022802282109200228022c210520022802302103410521010c030b200620016a417f6a2d0000210420082001360200200441ff00712005411f71742009722109200141016a2101200541076a21052004418001710d000b20054120490d0220044110490d02410d21010b0b2000200136020420004101360200200041106a20033602002000410c6a2005360200200041086a20093602000c92020b2001417f6a2101410021054100210a034002402005411f4d0d00410f21010cb2010b20032001460db0012001417f460ded012003200141016a2207490d8d02200620016a2d0000210420082007360200200441ff00712005411f7174200a72210a200541076a2105200721012004418001710d000b024020054120490d00410d21012004410f4b0db1010b200aad210c412a21070c8e020b0240024020032005460d00200441026a21012005417f460dee01200320014f0d0120012003107f000b200241013a0048200241ec006a41013602002002420137025c20024180c0c5003602582002411f36023c2002200241386a3602682002200241c8006a360238200241086a200241d8006a10e603200241336a200241106a2802003600002002200229030837002b2002200229002837031820022002412f6a29000037001f200041053a0004200020022903183700052000410c6a200229001f370000200041013602000c91020b200620056a2d0000210920082001360200024020090d00412b21074100210a0c8e020b200041153a000420004101360200200041056a20093a00000c90020b0240024020032005460d00200441026a21012005417f460dee01200320014f0d0120012003107f000b200241013a0048200241ec006a41013602002002420137025c20024180c0c5003602582002411f36023c2002200241386a3602682002200241c8006a360238200241086a200241d8006a10e603200241336a200241106a2802003600002002200229030837002b2002200229002837031820022002412f6a29000037001f200041053a0004200020022903183700052000410c6a200229001f370000200041013602000c90020b200620056a2d0000210920082001360200024020090d00412c21074100210a0c8d020b200041153a000420004101360200200041056a20093a00000c8f020b41002101410021090240024002400340410d210a2001411f4b0d010240024020032005460d002005417f460df2012003200541016a22074f0d01200541016a2003107f000b200241013a0018200241ec006a41013602002002420137025c20024180c0c5003602582002411f36023c2002200241386a3602682002200241186a360238200241286a200241d8006a10e6034105210a0c020b200620056a2c0000210420082007360200200441ff00712001411f71742009722109200141076a21012007210520044100480d000b200441c00071210502402001411f4b0d0020050d020b0240024020014120490d0020050d010b200441ff01714108490d0320014120490d032005450d010c030b20044180017241ff017141f7014b0d020b2000200a36020420004101360200200041086a2002290228370200200041106a200241286a41086a2802003602000c90020b2009417f2001411f71747221090b412d21070c8b020b4200210c4100210102400240024002400340410e21072001413f4b0d010240024020032005460d002005417f460df3012003200541016a22094f0d01200541016a2003107f000b200241013a0008200241ec006a41013602002002420137025c20024180c0c5003602582002411f36023c2002200241386a3602682002200241086a360238200241286a200241d8006a10e6032002290328210c20022802302101410521070c030b200620056a2d0000210420082009360200200441ff0071220aad2001413f71ad86200c84210c200141076a210120092105200441187441187522094100480d000b200941c00071210502402001413f4b0d0020050d030b02400240200141c000490d0020050d010b200141c000490d0420090d010c040b200a41ff00460d030b0b200020073a0004200020022f00183b000520004101360200200041106a2001360200200041086a200c370200200041076a2002411a6a2d00003a00000c8f020b200c427f2001413f71ad8684210c0b412e21070c8a020b02400240200320056b4104490d00200441056a21012005417b4b0dee01200320014f0d0120012003107f000b200241013a0018200241ec006a41013602002002420137025c20024180c0c5003602582002411f36023c2002200241386a3602682002200241186a360238200241286a200241d8006a10e60320004281808080d000370300200041086a2002290228370200200041106a200241286a41086a2802003602000c8d020b200620056a280000210920082001360200412f21070c89020b02400240200320056b4108490d00200441096a2101200541774b0dee01200320014f0d0120012003107f000b200241013a0018200241ec006a41013602002002420137025c20024180c0c5003602582002411f36023c2002200241386a3602682002200241186a360238200241286a200241d8006a10e6032002290328210c200041106a2002280230360200200041086a200c37020020004281808080d0003703000c8c020b200620056a290000210c20082001360200413021070c88020b413121070c87020b413221070c86020b413321070c85020b413421070c84020b413521070c83020b413621070c82020b413721070c81020b413821070c80020b413921070cff010b413a21070cfe010b413b21070cfd010b413c21070cfc010b413d21070cfb010b413e21070cfa010b413f21070cf9010b41c00021070cf8010b41c10021070cf7010b41c20021070cf6010b41c30021070cf5010b41c40021070cf4010b41c50021070cf3010b41c60021070cf2010b41c70021070cf1010b41c80021070cf0010b41c90021070cef010b41ca0021070cee010b41cb0021070ced010b41cc0021070cec010b41cd0021070ceb010b41ce0021070cea010b41cf0021070ce9010b41d00021070ce8010b41d10021070ce7010b41d20021070ce6010b41d30021070ce5010b41d40021070ce4010b41d50021070ce3010b41d60021070ce2010b41d70021070ce1010b41d80021070ce0010b41d90021070cdf010b41da0021070cde010b41db0021070cdd010b41dc0021070cdc010b41dd0021070cdb010b41de0021070cda010b41df0021070cd9010b41e00021070cd8010b41e10021070cd7010b41e20021070cd6010b41e30021070cd5010b41e40021070cd4010b41e50021070cd3010b41e60021070cd2010b41e70021070cd1010b41e80021070cd0010b41e90021070ccf010b41ea0021070cce010b41eb0021070ccd010b41ec0021070ccc010b41ed0021070ccb010b41ee0021070cca010b41ef0021070cc9010b41f00021070cc8010b41f10021070cc7010b41f20021070cc6010b41f30021070cc5010b41f40021070cc4010b41f50021070cc3010b41f60021070cc2010b41f70021070cc1010b41f80021070cc0010b41f90021070cbf010b41fa0021070cbe010b41fb0021070cbd010b41fc0021070cbc010b41fd0021070cbb010b41fe0021070cba010b41ff0021070cb9010b41800121070cb8010b41810121070cb7010b41820121070cb6010b41830121070cb5010b41840121070cb4010b41850121070cb3010b41860121070cb2010b41870121070cb1010b41880121070cb0010b41890121070caf010b418a0121070cae010b418b0121070cad010b418c0121070cac010b418d0121070cab010b418e0121070caa010b418f0121070ca9010b41900121070ca8010b41910121070ca7010b41920121070ca6010b41930121070ca5010b41940121070ca4010b41950121070ca3010b41960121070ca2010b41970121070ca1010b41980121070ca0010b41990121070c9f010b419a0121070c9e010b419b0121070c9d010b419c0121070c9c010b419d0121070c9b010b419e0121070c9a010b419f0121070c99010b41a00121070c98010b41a10121070c97010b41a20121070c96010b41a30121070c95010b41a40121070c94010b41a50121070c93010b41a60121070c92010b41a70121070c91010b41a80121070c90010b41a90121070c8f010b41aa0121070c8e010b41ab0121070c8d010b200041013602002000200241d8006a41047222012902003702042000410c6a200141086a2902003702000c8f010b200228026010290c8a010b200241013a0018200241ec006a41013602002002420137025c20024180c0c5003602582002411f36023c2002200241386a3602682002200241186a360238200241286a200241d8006a10e603410521010b2000200136020420004101360200200041086a2002290228370200200041106a200241286a41086a2802003602000c8c010b200241013a0018200241ec006a41013602002002420137025c20024180c0c5003602582002411f36023c2002200241386a3602682002200241186a360238200241286a200241d8006a10e603410521010b2000200136020420004101360200200041086a2002290228370200200041106a200241286a41086a2802003602000c8a010b200241013a0018200241ec006a41013602002002420137025c20024180c0c5003602582002411f36023c2002200241386a3602682002200241186a360238200241286a200241d8006a10e603410521010b2000200136020420004101360200200041086a2002290228370200200041106a200241286a41086a2802003602000c88010b200241013a0018200241ec006a41013602002002420137025c20024180c0c5003602582002411f36023c2002200241386a3602682002200241186a360238200241286a200241d8006a10e603410521010b2000200136020420004101360200200041086a2002290228370200200041106a200241286a41086a2802003602000c86010b200241013a0018200241ec006a41013602002002420137025c20024180c0c5003602582002411f36023c2002200241386a3602682002200241186a360238200241286a200241d8006a10e603410521010b2000200136020420004101360200200041086a2002290228370200200041106a200241286a41086a2802003602000c84010b200241013a0018200241ec006a41013602002002420137025c20024180c0c5003602582002411f36023c2002200241386a3602682002200241186a360238200241286a200241d8006a10e603410521010b2000200136020420004101360200200041086a2002290228370200200041106a200241286a41086a2802003602000c82010b200241013a0018200241ec006a41013602002002420137025c20024180c0c5003602582002411f36023c2002200241386a3602682002200241186a360238200241286a200241d8006a10e603410521010b2000200136020420004101360200200041086a2002290228370200200041106a200241286a41086a2802003602000c80010b200241013a0018200241ec006a41013602002002420137025c20024180c0c5003602582002411f36023c2002200241386a3602682002200241186a360238200241286a200241d8006a10e603410521010b2000200136020420004101360200200041086a2002290228370200200041106a200241286a41086a2802003602000c7e0b200241013a0018200241ec006a41013602002002420137025c20024180c0c5003602582002411f36023c2002200241386a3602682002200241186a360238200241286a200241d8006a10e603410521010b2000200136020420004101360200200041086a2002290228370200200041106a200241286a41086a2802003602000c7c0b200241013a0018200241ec006a41013602002002420137025c20024180c0c5003602582002411f36023c2002200241386a3602682002200241186a360238200241286a200241d8006a10e603410521010b2000200136020420004101360200200041086a2002290228370200200041106a200241286a41086a2802003602000c7a0b200241013a0018200241ec006a41013602002002420137025c20024180c0c5003602582002411f36023c2002200241386a3602682002200241186a360238200241286a200241d8006a10e603410521010b2000200136020420004101360200200041086a2002290228370200200041106a200241286a41086a2802003602000c780b200241013a0018200241ec006a41013602002002420137025c20024180c0c5003602582002411f36023c2002200241386a3602682002200241186a360238200241286a200241d8006a10e603410521010b2000200136020420004101360200200041086a2002290228370200200041106a200241286a41086a2802003602000c760b200241013a0018200241ec006a41013602002002420137025c20024180c0c5003602582002411f36023c2002200241386a3602682002200241186a360238200241286a200241d8006a10e603410521010b2000200136020420004101360200200041086a2002290228370200200041106a200241286a41086a2802003602000c740b200241013a0018200241ec006a41013602002002420137025c20024180c0c5003602582002411f36023c2002200241386a3602682002200241186a360238200241286a200241d8006a10e603410521010b2000200136020420004101360200200041086a2002290228370200200041106a200241286a41086a2802003602000c720b200241013a0018200241ec006a41013602002002420137025c20024180c0c5003602582002411f36023c2002200241386a3602682002200241186a360238200241286a200241d8006a10e603410521010b2000200136020420004101360200200041086a2002290228370200200041106a200241286a41086a2802003602000c700b200241013a0018200241ec006a41013602002002420137025c20024180c0c5003602582002411f36023c2002200241386a3602682002200241186a360238200241286a200241d8006a10e603410521010b2000200136020420004101360200200041086a2002290228370200200041106a200241286a41086a2802003602000c6e0b200241013a0018200241ec006a41013602002002420137025c20024180c0c5003602582002411f36023c2002200241386a3602682002200241186a360238200241286a200241d8006a10e603410521010b2000200136020420004101360200200041086a2002290228370200200041106a200241286a41086a2802003602000c6c0b200241013a0018200241ec006a41013602002002420137025c20024180c0c5003602582002411f36023c2002200241386a3602682002200241186a360238200241286a200241d8006a10e603410521010b2000200136020420004101360200200041086a2002290228370200200041106a200241286a41086a2802003602000c6a0b200241013a0018200241ec006a41013602002002420137025c20024180c0c5003602582002411f36023c2002200241386a3602682002200241186a360238200241286a200241d8006a10e603410521010b2000200136020420004101360200200041086a2002290228370200200041106a200241286a41086a2802003602000c680b200241013a0018200241ec006a41013602002002420137025c20024180c0c5003602582002411f36023c2002200241386a3602682002200241186a360238200241286a200241d8006a10e603410521010b2000200136020420004101360200200041086a2002290228370200200041106a200241286a41086a2802003602000c660b200241013a0018200241ec006a41013602002002420137025c20024180c0c5003602582002411f36023c2002200241386a3602682002200241186a360238200241286a200241d8006a10e603410521010b2000200136020420004101360200200041086a2002290228370200200041106a200241286a41086a2802003602000c640b200241013a0018200241ec006a41013602002002420137025c20024180c0c5003602582002411f36023c2002200241386a3602682002200241186a360238200241286a200241d8006a10e603410521010b2000200136020420004101360200200041086a2002290228370200200041106a200241286a41086a2802003602000c620b200241013a0018200241ec006a41013602002002420137025c20024180c0c5003602582002411f36023c2002200241386a3602682002200241186a360238200241286a200241d8006a10e603410521010b2000200136020420004101360200200041086a2002290228370200200041106a200241286a41086a2802003602000c600b417f2005103e000b417f2009103e000b417f2009103e000b417f2009103e000b417f200541016a103e000b417f200541016a103e000b417f200541016a103e000b417f200541016a103e000b417f2001103e000b417f200541016a103e000b417f200541016a103e000b417f200541016a103e000b417f200541016a103e000b417f200541016a103e000b417f2001103e000b417f200141016a103e000b417f2001103e000b417f200141016a103e000b417f2001103e000b417f200141016a103e000b417f2001103e000b417f200141016a103e000b417f2001103e000b417f200141016a103e000b417f2001103e000b417f200141016a103e000b417f2001103e000b417f200141016a103e000b417f2001103e000b417f200141016a103e000b417f2001103e000b417f200141016a103e000b417f2001103e000b417f200141016a103e000b417f2001103e000b417f200141016a103e000b417f2001103e000b417f200141016a103e000b417f2001103e000b417f200141016a103e000b417f2001103e000b417f200141016a103e000b417f2001103e000b417f200141016a103e000b417f2001103e000b417f200141016a103e000b417f2001103e000b417f200141016a103e000b417f2001103e000b417f200141016a103e000b417f2001103e000b417f200141016a103e000b417f2001103e000b417f200141016a103e000b417f2001103e000b417f200141016a103e000b417f2001103e000b417f200141016a103e000b417f2001103e000b417f200141016a103e000b417f2001103e000b417f2001103e000b417f200541016a103e000b417f200541016a103e000b20052001103e000b20052001103e000b20092003107f000b20092003107f000b20092003107f000b200141016a2003107f000b200141016a2003107f000b200141016a2003107f000b200141016a2003107f000b200141016a2003107f000b200141016a2003107f000b200141016a2003107f000b200141016a2003107f000b200141016a2003107f000b200141016a2003107f000b200141016a2003107f000b200141016a2003107f000b200141016a2003107f000b200141016a2003107f000b200141016a2003107f000b200141016a2003107f000b200141016a2003107f000b200141016a2003107f000b200141016a2003107f000b200141016a2003107f000b200141016a2003107f000b200141016a2003107f000b200141016a2003107f000b0240024002400240024002402007200a470d002007210a0c010b2007200a490d010240200a0d004100210a024020070d00410421090c020b20091029410421090c010b20092007410274200a410274220510282209450d020b4100210541002107034002402005411f4d0d00410f21010c080b20012802082206200128020c2203460d06200341016a22042003490d0320062004490d04200128020020036a2d0000210320082004360200200341ff00712005411f71742007722107200541076a21052003418001710d000b024020054120490d00410d21012003410f4b0d070b2007ad422086200aad84210c410921070c040b41ac87c5001058000b20054104102a000b417f2004103e000b20042006107f000b20004100360200200041106a200c3703002000410c6a2009360200200041096a200a3a0000200041086a20073a00000c020b200241013a0018200241ec006a41013602002002420137025c20024180c0c5003602582002411f36023c2002200241386a3602682002200241186a360238200241286a200241d8006a10e603410521010b2000200136020420004101360200200041086a2002290228370200200041106a200241286a41086a280200360200200a41ffffffff0371450d00200910290b200241f0006a24000bd30101017f230041106b22022400024002400240024020002d00000e03010200010b2002200128021841dcbfc500410b2001411c6a28020028020c11050022003a000820022001360200200241003a0009200241003602040c020b2002200128021841e7bfc500410c2001411c6a28020028020c11050022003a000820022001360200200241003a0009200241003602040c010b2002200128021841f3bfc500410d2001411c6a28020028020c11050022003a000820022001360200200241003a0009200241003602040b200241106a240020000b8a0301067f230041306b2202240020012802002103024002402001280204220441037422050d00410021060c010b200341046a2107410021060340200728020020066a2106200741086a2107200541786a22050d000b0b024002400240024002400240200141146a2802000d00200621070c010b02402004450d00024002402006410f4b0d002003280204450d010b200620066a220720064f0d020b4101210541002107200241086a21060c020b41f0d2c500410041001037000b2007417f4c0d01200241086a2106024020070d0041012105410021070c010b200710272205450d020b200241003602102002200736020c200220053602082002200241086a360214200241186a41106a200141106a290200370300200241186a41086a200141086a29020037030020022001290200370318200241146a4180d3c500200241186a1091040d0220002006290200370200200041086a200641086a280200360200200241306a24000f0b1039000b20074101102a000b4198d3c5004133200241186a41ccd3c50010a201000bf30603067f017e067f230041c0006b2202240041002103410021040240024002400240024002400240034002402003411f4d0d00410f21030c020b0240024020012802082205200128020c2206460d00200641016a22072006490d05200520074f0d0120072005107f000b200241013a000f2002413c6a41013602002002420137022c20024180c0c5003602282002411f3602142002200241106a36023820022002410f6a360210200241186a200241286a10e603410521030c020b200128020020066a2d000021062001200736020c200641ff00712003411f71742004722104200341076a21032006418001710d000b20034120490d01410d210320064110490d010b200241086a200241186a41086a280200220136020020022002290218220837030020002003360204200041086a2008370200200041106a2001360200200041013602000c050b410421090240024020040d004100210a0c010b4100210a4100210b0340200b220c41016a210b4100210341002105024002400240034002402003411f4d0d00410f21010c020b024002402001280208220d200128020c2206460d00200641016a22072006490d09200d20074f0d012007200d107f000b200241013a00002002413c6a41013602002002420137022c20024180c0c5003602282002411f3602142002200241106a36023820022002360210200241186a200241286a10e60320022802182103200228021c2106200228022021074100210e410521010c030b200128020020066a2d000021062001200736020c200641ff00712003411f71742005722105200341076a21032006418001710d000b20034120490d0220064110490d02410d21010b0b20004101360200200041106a20073602002000410c6a2006360200200041086a20033602002000200e410874200172360204200a450d07200910290c070b0240200a200c470d00200a4101742203200a41016a220620062003491b220341ffffffff03712003470d06200341027422064100480d0602400240200a0d002006102721090c010b2009200a4102742006102821090b2009450d052003210a0b2005410876210e2009200c4102746a2005360200200b2004470d000b0b20002009360204200041003602002000410c6a2004360200200041086a200a3602000c040b417f2007103e000b417f2007103e000b20064104102a000b102b000b200241c0006a24000bf6d60202097f017e230041106b220324000240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024020012d00000eac01000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f80018101820183018401850186018701880189018a018b018c018d018e018f0190019101920193019401950196019701980199019a019b019c019d019e019f01a001a101a201a301a401a501a601a701a801a901aa01ab01000b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490df70120044101742206200520052006491b22064100480df7010240024020040d002006102721050c010b200228020420042006102821050b2005450dad0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41003a00000cab010b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490df60120044101742206200520052006491b22064100480df6010240024020040d002006102721050c010b200228020420042006102821050b2005450dad0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41013a00000caa010b200241046a210620012d0001210702400240200241086a2802002002410c6a2802002204460d00200628020021050c010b200441016a22052004490df50120044101742208200520052008491b22084100480df5010240024020040d002008102721050c010b200628020020042008102821050b2005450dad0120022005360204200241086a20083602002002410c6a28020021040b2002410c6a2208200441016a360200200520046a41023a000002400240200241086a28020020082802002204460d00200628020021050c010b200441016a22052004490df50120044101742208200520052008491b22084100480df5010240024020040d002008102721050c010b200628020020042008102821050b2005450dae0120022005360204200241086a20083602002002410c6a28020021040b2002410c6a200441016a360200200520046a42c0818386fcdffffe7c2007410473ad42078342038688a7413f7141c000723a00000ca9010b200241046a210620012d0001210702400240200241086a2802002002410c6a2802002204460d00200628020021050c010b200441016a22052004490df40120044101742208200520052008491b22084100480df4010240024020040d002008102721050c010b200628020020042008102821050b2005450dae0120022005360204200241086a20083602002002410c6a28020021040b2002410c6a2208200441016a360200200520046a41033a000002400240200241086a28020020082802002204460d00200628020021050c010b200441016a22052004490df40120044101742208200520052008491b22084100480df4010240024020040d002008102721050c010b200628020020042008102821050b2005450daf0120022005360204200241086a20083602002002410c6a28020021040b2002410c6a200441016a360200200520046a42c0818386fcdffffe7c2007410473ad42078342038688a7413f7141c000723a00000ca8010b200241046a210620012d0001210702400240200241086a2802002002410c6a2802002204460d00200628020021050c010b200441016a22052004490df30120044101742208200520052008491b22084100480df3010240024020040d002008102721050c010b200628020020042008102821050b2005450daf0120022005360204200241086a20083602002002410c6a28020021040b2002410c6a2208200441016a360200200520046a41043a000002400240200241086a28020020082802002204460d00200628020021050c010b200441016a22052004490df30120044101742208200520052008491b22084100480df3010240024020040d002008102721050c010b200628020020042008102821050b2005450db00120022005360204200241086a20083602002002410c6a28020021040b2002410c6a200441016a360200200520046a42c0818386fcdffffe7c2007410473ad42078342038688a7413f7141c000723a00000ca7010b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490df20120044101742206200520052006491b22064100480df2010240024020040d002006102721050c010b200228020420042006102821050b2005450db00120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41053a00000ca6010b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490df10120044101742206200520052006491b22064100480df1010240024020040d002006102721050c010b200228020420042006102821050b2005450db00120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a410b3a00000ca5010b200241046a2109200141046a280200210502400240200241086a2802002002410c6a2802002204460d00200928020021060c010b200441016a22062004490df00120044101742207200620062007491b22074100480df0010240024020040d002007102721060c010b200928020020042007102821060b2006450db00120022006360204200241086a20073602002002410c6a28020021040b2002410c6a2207200441016a360200200620046a410c3a0000200241086a2108034002400240200828020020072802002204460d00200928020021060c010b200441016a22062004490df1012004410174220a20062006200a491b220a4100480df1010240024020040d00200a102721060c010b20092802002004200a102821060b2006450db201200220063602042008200a360200200728020021040b2007200441016a360200200620046a200541807f72200541ff0071200541077622041b3a00002004210520040d000ca5010b0b200241046a2109200141046a280200210502400240200241086a2802002002410c6a2802002204460d00200928020021060c010b200441016a22062004490def0120044101742207200620062007491b22074100480def010240024020040d002007102721060c010b200928020020042007102821060b2006450db10120022006360204200241086a20073602002002410c6a28020021040b2002410c6a2207200441016a360200200620046a410d3a0000200241086a2108034002400240200828020020072802002204460d00200928020021060c010b200441016a22062004490df0012004410174220a20062006200a491b220a4100480df0010240024020040d00200a102721060c010b20092802002004200a102821060b2006450db301200220063602042008200a360200200728020021040b2007200441016a360200200620046a200541807f72200541ff0071200541077622041b3a00002004210520040d000ca4010b0b200241046a210a2001410c6a2802002104200141086a2802002109200141046a280200210b02400240200241086a2802002002410c6a2802002201460d00200a28020021050c010b200141016a22052001490dee0120014101742206200520052006491b22064100480dee010240024020010d002006102721050c010b200a28020020012006102821050b2005450db20120022005360204200241086a20063602002002410c6a28020021010b2002410c6a2206200141016a360200200520016a410e3a000020032009200b200b20094102746a200210e00320032d0000411a470d9303200241086a2107034002400240200728020020062802002201460d00200a28020021050c010b200141016a22052001490def0120014101742208200520052008491b22084100480def010240024020010d002008102721050c010b200a28020020012008102821050b2005450db4012002200536020420072008360200200628020021010b2006200141016a360200200520016a200441807f72200441ff0071200441077622011b3a00002001210420010d000b0240200941ffffffff0371450d00200b10290b2000411a3a00000c95030b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490ded0120044101742206200520052006491b22064100480ded010240024020040d002006102721050c010b200228020420042006102821050b2005450db30120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a410f3a00000ca1010b200241046a2109200141046a280200210502400240200241086a2802002002410c6a2802002204460d00200928020021060c010b200441016a22062004490dec0120044101742207200620062007491b22074100480dec010240024020040d002007102721060c010b200928020020042007102821060b2006450db30120022006360204200241086a20073602002002410c6a28020021040b2002410c6a2207200441016a360200200620046a41103a0000200241086a2108034002400240200828020020072802002204460d00200928020021060c010b200441016a22062004490ded012004410174220a20062006200a491b220a4100480ded010240024020040d00200a102721060c010b20092802002004200a102821060b2006450db501200220063602042008200a360200200728020021040b2007200441016a360200200620046a200541807f72200541ff0071200541077622041b3a00002004210520040d000ca1010b0b200241046a2109200141046a280200210520012d0001210b02400240200241086a2802002002410c6a2802002204460d00200928020021060c010b200441016a22062004490deb0120044101742207200620062007491b22074100480deb010240024020040d002007102721060c010b200928020020042007102821060b2006450db40120022006360204200241086a20073602002002410c6a28020021040b2002410c6a2207200441016a360200200620046a41113a0000200241086a2108034002400240200828020020072802002204460d00200928020021060c010b200441016a22062004490dec012004410174220a20062006200a491b220a4100480dec010240024020040d00200a102721060c010b20092802002004200a102821060b2006450db601200220063602042008200a360200200728020021040b2007200441016a360200200620046a200541807f72200541ff0071200541077622041b3a00002004210520040d000b02400240200241086a2802002002410c6a2802002204460d00200928020021050c010b200441016a22052004490deb0120044101742206200520052006491b22064100480deb010240024020040d002006102721050c010b200928020020042006102821050b2005450db60120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a200b3a00000c9f010b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490dea0120044101742206200520052006491b22064100480dea010240024020040d002006102721050c010b200228020420042006102821050b2005450db60120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a411a3a00000c9e010b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490de90120044101742206200520052006491b22064100480de9010240024020040d002006102721050c010b200228020420042006102821050b2005450db60120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a411b3a00000c9d010b200241046a2109200141046a280200210502400240200241086a2802002002410c6a2802002204460d00200928020021060c010b200441016a22062004490de80120044101742207200620062007491b22074100480de8010240024020040d002007102721060c010b200928020020042007102821060b2006450db60120022006360204200241086a20073602002002410c6a28020021040b2002410c6a2207200441016a360200200620046a41203a0000200241086a2108034002400240200828020020072802002204460d00200928020021060c010b200441016a22062004490de9012004410174220a20062006200a491b220a4100480de9010240024020040d00200a102721060c010b20092802002004200a102821060b2006450db801200220063602042008200a360200200728020021040b2007200441016a360200200620046a200541807f72200541ff0071200541077622041b3a00002004210520040d000c9d010b0b200241046a2109200141046a280200210502400240200241086a2802002002410c6a2802002204460d00200928020021060c010b200441016a22062004490de70120044101742207200620062007491b22074100480de7010240024020040d002007102721060c010b200928020020042007102821060b2006450db70120022006360204200241086a20073602002002410c6a28020021040b2002410c6a2207200441016a360200200620046a41213a0000200241086a2108034002400240200828020020072802002204460d00200928020021060c010b200441016a22062004490de8012004410174220a20062006200a491b220a4100480de8010240024020040d00200a102721060c010b20092802002004200a102821060b2006450db901200220063602042008200a360200200728020021040b2007200441016a360200200620046a200541807f72200541ff0071200541077622041b3a00002004210520040d000c9c010b0b200241046a2109200141046a280200210502400240200241086a2802002002410c6a2802002204460d00200928020021060c010b200441016a22062004490de60120044101742207200620062007491b22074100480de6010240024020040d002007102721060c010b200928020020042007102821060b2006450db80120022006360204200241086a20073602002002410c6a28020021040b2002410c6a2207200441016a360200200620046a41223a0000200241086a2108034002400240200828020020072802002204460d00200928020021060c010b200441016a22062004490de7012004410174220a20062006200a491b220a4100480de7010240024020040d00200a102721060c010b20092802002004200a102821060b2006450dba01200220063602042008200a360200200728020021040b2007200441016a360200200620046a200541807f72200541ff0071200541077622041b3a00002004210520040d000c9b010b0b200241046a2109200141046a280200210502400240200241086a2802002002410c6a2802002204460d00200928020021060c010b200441016a22062004490de50120044101742207200620062007491b22074100480de5010240024020040d002007102721060c010b200928020020042007102821060b2006450db90120022006360204200241086a20073602002002410c6a28020021040b2002410c6a2207200441016a360200200620046a41233a0000200241086a2108034002400240200828020020072802002204460d00200928020021060c010b200441016a22062004490de6012004410174220a20062006200a491b220a4100480de6010240024020040d00200a102721060c010b20092802002004200a102821060b2006450dbb01200220063602042008200a360200200728020021040b2007200441016a360200200620046a200541807f72200541ff0071200541077622041b3a00002004210520040d000c9a010b0b200241046a2109200141046a280200210502400240200241086a2802002002410c6a2802002204460d00200928020021060c010b200441016a22062004490de40120044101742207200620062007491b22074100480de4010240024020040d002007102721060c010b200928020020042007102821060b2006450dba0120022006360204200241086a20073602002002410c6a28020021040b2002410c6a2207200441016a360200200620046a41243a0000200241086a2108034002400240200828020020072802002204460d00200928020021060c010b200441016a22062004490de5012004410174220a20062006200a491b220a4100480de5010240024020040d00200a102721060c010b20092802002004200a102821060b2006450dbc01200220063602042008200a360200200728020021040b2007200441016a360200200620046a200541807f72200541ff0071200541077622041b3a00002004210520040d000c99010b0b200241046a210a200141086a2802002105200141046a280200210602400240200241086a2802002002410c6a2802002204460d00200a28020021070c010b200441016a22072004490de30120044101742208200720072008491b22084100480de3010240024020040d002008102721070c010b200a28020020042008102821070b2007450dbb0120022007360204200241086a20083602002002410c6a28020021040b2002410c6a2208200441016a360200200720046a41283a0000200241086a2109034002400240200928020020082802002204460d00200a28020021070c010b200441016a22072004490de4012004410174220b20072007200b491b220b4100480de4010240024020040d00200b102721070c010b200a2802002004200b102821070b2007450dbd01200220073602042009200b360200200828020021040b2008200441016a360200200720046a200641807f72200641ff0071200641077622041b3a00002004210620040d000b2002410c6a2107200241086a2108034002400240200828020020072802002204460d00200a28020021060c010b200441016a22062004490de40120044101742209200620062009491b22094100480de4010240024020040d002009102721060c010b200a28020020042009102821060b2006450dbe012002200636020420082009360200200728020021040b2007200441016a360200200620046a200541807f72200541ff0071200541077622041b3a00002004210520040d000c98010b0b200241046a210a200141086a2802002105200141046a280200210602400240200241086a2802002002410c6a2802002204460d00200a28020021070c010b200441016a22072004490de20120044101742208200720072008491b22084100480de2010240024020040d002008102721070c010b200a28020020042008102821070b2007450dbd0120022007360204200241086a20083602002002410c6a28020021040b2002410c6a2208200441016a360200200720046a41293a0000200241086a2109034002400240200928020020082802002204460d00200a28020021070c010b200441016a22072004490de3012004410174220b20072007200b491b220b4100480de3010240024020040d00200b102721070c010b200a2802002004200b102821070b2007450dbf01200220073602042009200b360200200828020021040b2008200441016a360200200720046a200641807f72200641ff0071200641077622041b3a00002004210620040d000b2002410c6a2107200241086a2108034002400240200828020020072802002204460d00200a28020021060c010b200441016a22062004490de30120044101742209200620062009491b22094100480de3010240024020040d002009102721060c010b200a28020020042009102821060b2006450dc0012002200636020420082009360200200728020021040b2007200441016a360200200620046a200541807f72200541ff0071200541077622041b3a00002004210520040d000c97010b0b200241046a210a200141086a2802002105200141046a280200210602400240200241086a2802002002410c6a2802002204460d00200a28020021070c010b200441016a22072004490de10120044101742208200720072008491b22084100480de1010240024020040d002008102721070c010b200a28020020042008102821070b2007450dbf0120022007360204200241086a20083602002002410c6a28020021040b2002410c6a2208200441016a360200200720046a412a3a0000200241086a2109034002400240200928020020082802002204460d00200a28020021070c010b200441016a22072004490de2012004410174220b20072007200b491b220b4100480de2010240024020040d00200b102721070c010b200a2802002004200b102821070b2007450dc101200220073602042009200b360200200828020021040b2008200441016a360200200720046a200641807f72200641ff0071200641077622041b3a00002004210620040d000b2002410c6a2107200241086a2108034002400240200828020020072802002204460d00200a28020021060c010b200441016a22062004490de20120044101742209200620062009491b22094100480de2010240024020040d002009102721060c010b200a28020020042009102821060b2006450dc2012002200636020420082009360200200728020021040b2007200441016a360200200620046a200541807f72200541ff0071200541077622041b3a00002004210520040d000c96010b0b200241046a210a200141086a2802002105200141046a280200210602400240200241086a2802002002410c6a2802002204460d00200a28020021070c010b200441016a22072004490de00120044101742208200720072008491b22084100480de0010240024020040d002008102721070c010b200a28020020042008102821070b2007450dc10120022007360204200241086a20083602002002410c6a28020021040b2002410c6a2208200441016a360200200720046a412b3a0000200241086a2109034002400240200928020020082802002204460d00200a28020021070c010b200441016a22072004490de1012004410174220b20072007200b491b220b4100480de1010240024020040d00200b102721070c010b200a2802002004200b102821070b2007450dc301200220073602042009200b360200200828020021040b2008200441016a360200200720046a200641807f72200641ff0071200641077622041b3a00002004210620040d000b2002410c6a2107200241086a2108034002400240200828020020072802002204460d00200a28020021060c010b200441016a22062004490de10120044101742209200620062009491b22094100480de1010240024020040d002009102721060c010b200a28020020042009102821060b2006450dc4012002200636020420082009360200200728020021040b2007200441016a360200200620046a200541807f72200541ff0071200541077622041b3a00002004210520040d000c95010b0b200241046a210a200141086a2802002105200141046a280200210602400240200241086a2802002002410c6a2802002204460d00200a28020021070c010b200441016a22072004490ddf0120044101742208200720072008491b22084100480ddf010240024020040d002008102721070c010b200a28020020042008102821070b2007450dc30120022007360204200241086a20083602002002410c6a28020021040b2002410c6a2208200441016a360200200720046a412c3a0000200241086a2109034002400240200928020020082802002204460d00200a28020021070c010b200441016a22072004490de0012004410174220b20072007200b491b220b4100480de0010240024020040d00200b102721070c010b200a2802002004200b102821070b2007450dc501200220073602042009200b360200200828020021040b2008200441016a360200200720046a200641807f72200641ff0071200641077622041b3a00002004210620040d000b2002410c6a2107200241086a2108034002400240200828020020072802002204460d00200a28020021060c010b200441016a22062004490de00120044101742209200620062009491b22094100480de0010240024020040d002009102721060c010b200a28020020042009102821060b2006450dc6012002200636020420082009360200200728020021040b2007200441016a360200200620046a200541807f72200541ff0071200541077622041b3a00002004210520040d000c94010b0b200241046a210a200141086a2802002105200141046a280200210602400240200241086a2802002002410c6a2802002204460d00200a28020021070c010b200441016a22072004490dde0120044101742208200720072008491b22084100480dde010240024020040d002008102721070c010b200a28020020042008102821070b2007450dc50120022007360204200241086a20083602002002410c6a28020021040b2002410c6a2208200441016a360200200720046a412d3a0000200241086a2109034002400240200928020020082802002204460d00200a28020021070c010b200441016a22072004490ddf012004410174220b20072007200b491b220b4100480ddf010240024020040d00200b102721070c010b200a2802002004200b102821070b2007450dc701200220073602042009200b360200200828020021040b2008200441016a360200200720046a200641807f72200641ff0071200641077622041b3a00002004210620040d000b2002410c6a2107200241086a2108034002400240200828020020072802002204460d00200a28020021060c010b200441016a22062004490ddf0120044101742209200620062009491b22094100480ddf010240024020040d002009102721060c010b200a28020020042009102821060b2006450dc8012002200636020420082009360200200728020021040b2007200441016a360200200620046a200541807f72200541ff0071200541077622041b3a00002004210520040d000c93010b0b200241046a210a200141086a2802002105200141046a280200210602400240200241086a2802002002410c6a2802002204460d00200a28020021070c010b200441016a22072004490ddd0120044101742208200720072008491b22084100480ddd010240024020040d002008102721070c010b200a28020020042008102821070b2007450dc70120022007360204200241086a20083602002002410c6a28020021040b2002410c6a2208200441016a360200200720046a412e3a0000200241086a2109034002400240200928020020082802002204460d00200a28020021070c010b200441016a22072004490dde012004410174220b20072007200b491b220b4100480dde010240024020040d00200b102721070c010b200a2802002004200b102821070b2007450dc901200220073602042009200b360200200828020021040b2008200441016a360200200720046a200641807f72200641ff0071200641077622041b3a00002004210620040d000b2002410c6a2107200241086a2108034002400240200828020020072802002204460d00200a28020021060c010b200441016a22062004490dde0120044101742209200620062009491b22094100480dde010240024020040d002009102721060c010b200a28020020042009102821060b2006450dca012002200636020420082009360200200728020021040b2007200441016a360200200620046a200541807f72200541ff0071200541077622041b3a00002004210520040d000c92010b0b200241046a210a200141086a2802002105200141046a280200210602400240200241086a2802002002410c6a2802002204460d00200a28020021070c010b200441016a22072004490ddc0120044101742208200720072008491b22084100480ddc010240024020040d002008102721070c010b200a28020020042008102821070b2007450dc90120022007360204200241086a20083602002002410c6a28020021040b2002410c6a2208200441016a360200200720046a412f3a0000200241086a2109034002400240200928020020082802002204460d00200a28020021070c010b200441016a22072004490ddd012004410174220b20072007200b491b220b4100480ddd010240024020040d00200b102721070c010b200a2802002004200b102821070b2007450dcb01200220073602042009200b360200200828020021040b2008200441016a360200200720046a200641807f72200641ff0071200641077622041b3a00002004210620040d000b2002410c6a2107200241086a2108034002400240200828020020072802002204460d00200a28020021060c010b200441016a22062004490ddd0120044101742209200620062009491b22094100480ddd010240024020040d002009102721060c010b200a28020020042009102821060b2006450dcc012002200636020420082009360200200728020021040b2007200441016a360200200620046a200541807f72200541ff0071200541077622041b3a00002004210520040d000c91010b0b200241046a210a200141086a2802002105200141046a280200210602400240200241086a2802002002410c6a2802002204460d00200a28020021070c010b200441016a22072004490ddb0120044101742208200720072008491b22084100480ddb010240024020040d002008102721070c010b200a28020020042008102821070b2007450dcb0120022007360204200241086a20083602002002410c6a28020021040b2002410c6a2208200441016a360200200720046a41303a0000200241086a2109034002400240200928020020082802002204460d00200a28020021070c010b200441016a22072004490ddc012004410174220b20072007200b491b220b4100480ddc010240024020040d00200b102721070c010b200a2802002004200b102821070b2007450dcd01200220073602042009200b360200200828020021040b2008200441016a360200200720046a200641807f72200641ff0071200641077622041b3a00002004210620040d000b2002410c6a2107200241086a2108034002400240200828020020072802002204460d00200a28020021060c010b200441016a22062004490ddc0120044101742209200620062009491b22094100480ddc010240024020040d002009102721060c010b200a28020020042009102821060b2006450dce012002200636020420082009360200200728020021040b2007200441016a360200200620046a200541807f72200541ff0071200541077622041b3a00002004210520040d000c90010b0b200241046a210a200141086a2802002105200141046a280200210602400240200241086a2802002002410c6a2802002204460d00200a28020021070c010b200441016a22072004490dda0120044101742208200720072008491b22084100480dda010240024020040d002008102721070c010b200a28020020042008102821070b2007450dcd0120022007360204200241086a20083602002002410c6a28020021040b2002410c6a2208200441016a360200200720046a41313a0000200241086a2109034002400240200928020020082802002204460d00200a28020021070c010b200441016a22072004490ddb012004410174220b20072007200b491b220b4100480ddb010240024020040d00200b102721070c010b200a2802002004200b102821070b2007450dcf01200220073602042009200b360200200828020021040b2008200441016a360200200720046a200641807f72200641ff0071200641077622041b3a00002004210620040d000b2002410c6a2107200241086a2108034002400240200828020020072802002204460d00200a28020021060c010b200441016a22062004490ddb0120044101742209200620062009491b22094100480ddb010240024020040d002009102721060c010b200a28020020042009102821060b2006450dd0012002200636020420082009360200200728020021040b2007200441016a360200200620046a200541807f72200541ff0071200541077622041b3a00002004210520040d000c8f010b0b200241046a210a200141086a2802002105200141046a280200210602400240200241086a2802002002410c6a2802002204460d00200a28020021070c010b200441016a22072004490dd90120044101742208200720072008491b22084100480dd9010240024020040d002008102721070c010b200a28020020042008102821070b2007450dcf0120022007360204200241086a20083602002002410c6a28020021040b2002410c6a2208200441016a360200200720046a41323a0000200241086a2109034002400240200928020020082802002204460d00200a28020021070c010b200441016a22072004490dda012004410174220b20072007200b491b220b4100480dda010240024020040d00200b102721070c010b200a2802002004200b102821070b2007450dd101200220073602042009200b360200200828020021040b2008200441016a360200200720046a200641807f72200641ff0071200641077622041b3a00002004210620040d000b2002410c6a2107200241086a2108034002400240200828020020072802002204460d00200a28020021060c010b200441016a22062004490dda0120044101742209200620062009491b22094100480dda010240024020040d002009102721060c010b200a28020020042009102821060b2006450dd2012002200636020420082009360200200728020021040b2007200441016a360200200620046a200541807f72200541ff0071200541077622041b3a00002004210520040d000c8e010b0b200241046a210a200141086a2802002105200141046a280200210602400240200241086a2802002002410c6a2802002204460d00200a28020021070c010b200441016a22072004490dd80120044101742208200720072008491b22084100480dd8010240024020040d002008102721070c010b200a28020020042008102821070b2007450dd10120022007360204200241086a20083602002002410c6a28020021040b2002410c6a2208200441016a360200200720046a41333a0000200241086a2109034002400240200928020020082802002204460d00200a28020021070c010b200441016a22072004490dd9012004410174220b20072007200b491b220b4100480dd9010240024020040d00200b102721070c010b200a2802002004200b102821070b2007450dd301200220073602042009200b360200200828020021040b2008200441016a360200200720046a200641807f72200641ff0071200641077622041b3a00002004210620040d000b2002410c6a2107200241086a2108034002400240200828020020072802002204460d00200a28020021060c010b200441016a22062004490dd90120044101742209200620062009491b22094100480dd9010240024020040d002009102721060c010b200a28020020042009102821060b2006450dd4012002200636020420082009360200200728020021040b2007200441016a360200200620046a200541807f72200541ff0071200541077622041b3a00002004210520040d000c8d010b0b200241046a210a200141086a2802002105200141046a280200210602400240200241086a2802002002410c6a2802002204460d00200a28020021070c010b200441016a22072004490dd70120044101742208200720072008491b22084100480dd7010240024020040d002008102721070c010b200a28020020042008102821070b2007450dd30120022007360204200241086a20083602002002410c6a28020021040b2002410c6a2208200441016a360200200720046a41343a0000200241086a2109034002400240200928020020082802002204460d00200a28020021070c010b200441016a22072004490dd8012004410174220b20072007200b491b220b4100480dd8010240024020040d00200b102721070c010b200a2802002004200b102821070b2007450dd501200220073602042009200b360200200828020021040b2008200441016a360200200720046a200641807f72200641ff0071200641077622041b3a00002004210620040d000b2002410c6a2107200241086a2108034002400240200828020020072802002204460d00200a28020021060c010b200441016a22062004490dd80120044101742209200620062009491b22094100480dd8010240024020040d002009102721060c010b200a28020020042009102821060b2006450dd6012002200636020420082009360200200728020021040b2007200441016a360200200620046a200541807f72200541ff0071200541077622041b3a00002004210520040d000c8c010b0b200241046a210a200141086a2802002105200141046a280200210602400240200241086a2802002002410c6a2802002204460d00200a28020021070c010b200441016a22072004490dd60120044101742208200720072008491b22084100480dd6010240024020040d002008102721070c010b200a28020020042008102821070b2007450dd50120022007360204200241086a20083602002002410c6a28020021040b2002410c6a2208200441016a360200200720046a41353a0000200241086a2109034002400240200928020020082802002204460d00200a28020021070c010b200441016a22072004490da3022004410174220b20072007200b491b220b4100480da3020240024020040d00200b102721070c010b200a2802002004200b102821070b2007450dd801200220073602042009200b360200200828020021040b2008200441016a360200200720046a200641807f72200641ff0071200641077622041b3a00002004210620040d000b2002410c6a2107200241086a2108034002400240200828020020072802002204460d00200a28020021060c010b200441016a22062004490da30220044101742209200620062009491b22094100480da3020240024020040d002009102721060c010b200a28020020042009102821060b2006450dd9012002200636020420082009360200200728020021040b2007200441016a360200200620046a200541807f72200541ff0071200541077622041b3a00002004210520040d000c8b010b0b200241046a210a200141086a2802002105200141046a280200210602400240200241086a2802002002410c6a2802002204460d00200a28020021070c010b200441016a22072004490da10220044101742208200720072008491b22084100480da1020240024020040d002008102721070c010b200a28020020042008102821070b2007450dd80120022007360204200241086a20083602002002410c6a28020021040b2002410c6a2208200441016a360200200720046a41363a0000200241086a2109034002400240200928020020082802002204460d00200a28020021070c010b200441016a22072004490da2022004410174220b20072007200b491b220b4100480da2020240024020040d00200b102721070c010b200a2802002004200b102821070b2007450dda01200220073602042009200b360200200828020021040b2008200441016a360200200720046a200641807f72200641ff0071200641077622041b3a00002004210620040d000b2002410c6a2107200241086a2108034002400240200828020020072802002204460d00200a28020021060c010b200441016a22062004490da20220044101742209200620062009491b22094100480da2020240024020040d002009102721060c010b200a28020020042009102821060b2006450ddb012002200636020420082009360200200728020021040b2007200441016a360200200620046a200541807f72200541ff0071200541077622041b3a00002004210520040d000c8a010b0b200241046a210a200141086a2802002105200141046a280200210602400240200241086a2802002002410c6a2802002204460d00200a28020021070c010b200441016a22072004490da00220044101742208200720072008491b22084100480da0020240024020040d002008102721070c010b200a28020020042008102821070b2007450dda0120022007360204200241086a20083602002002410c6a28020021040b2002410c6a2208200441016a360200200720046a41373a0000200241086a2109034002400240200928020020082802002204460d00200a28020021070c010b200441016a22072004490da1022004410174220b20072007200b491b220b4100480da1020240024020040d00200b102721070c010b200a2802002004200b102821070b2007450ddc01200220073602042009200b360200200828020021040b2008200441016a360200200720046a200641807f72200641ff0071200641077622041b3a00002004210620040d000b2002410c6a2107200241086a2108034002400240200828020020072802002204460d00200a28020021060c010b200441016a22062004490da10220044101742209200620062009491b22094100480da1020240024020040d002009102721060c010b200a28020020042009102821060b2006450ddd012002200636020420082009360200200728020021040b2007200441016a360200200620046a200541807f72200541ff0071200541077622041b3a00002004210520040d000c89010b0b200241046a210a200141086a2802002105200141046a280200210602400240200241086a2802002002410c6a2802002204460d00200a28020021070c010b200441016a22072004490d9f0220044101742208200720072008491b22084100480d9f020240024020040d002008102721070c010b200a28020020042008102821070b2007450ddc0120022007360204200241086a20083602002002410c6a28020021040b2002410c6a2208200441016a360200200720046a41383a0000200241086a2109034002400240200928020020082802002204460d00200a28020021070c010b200441016a22072004490da0022004410174220b20072007200b491b220b4100480da0020240024020040d00200b102721070c010b200a2802002004200b102821070b2007450dde01200220073602042009200b360200200828020021040b2008200441016a360200200720046a200641807f72200641ff0071200641077622041b3a00002004210620040d000b2002410c6a2107200241086a2108034002400240200828020020072802002204460d00200a28020021060c010b200441016a22062004490da00220044101742209200620062009491b22094100480da0020240024020040d002009102721060c010b200a28020020042009102821060b2006450ddf012002200636020420082009360200200728020021040b2007200441016a360200200620046a200541807f72200541ff0071200541077622041b3a00002004210520040d000c88010b0b200241046a210a200141086a2802002105200141046a280200210602400240200241086a2802002002410c6a2802002204460d00200a28020021070c010b200441016a22072004490d9e0220044101742208200720072008491b22084100480d9e020240024020040d002008102721070c010b200a28020020042008102821070b2007450dde0120022007360204200241086a20083602002002410c6a28020021040b2002410c6a2208200441016a360200200720046a41393a0000200241086a2109034002400240200928020020082802002204460d00200a28020021070c010b200441016a22072004490d9f022004410174220b20072007200b491b220b4100480d9f020240024020040d00200b102721070c010b200a2802002004200b102821070b2007450de001200220073602042009200b360200200828020021040b2008200441016a360200200720046a200641807f72200641ff0071200641077622041b3a00002004210620040d000b2002410c6a2107200241086a2108034002400240200828020020072802002204460d00200a28020021060c010b200441016a22062004490d9f0220044101742209200620062009491b22094100480d9f020240024020040d002009102721060c010b200a28020020042009102821060b2006450de1012002200636020420082009360200200728020021040b2007200441016a360200200620046a200541807f72200541ff0071200541077622041b3a00002004210520040d000c87010b0b200241046a210a200141086a2802002105200141046a280200210602400240200241086a2802002002410c6a2802002204460d00200a28020021070c010b200441016a22072004490d9d0220044101742208200720072008491b22084100480d9d020240024020040d002008102721070c010b200a28020020042008102821070b2007450de00120022007360204200241086a20083602002002410c6a28020021040b2002410c6a2208200441016a360200200720046a413a3a0000200241086a2109034002400240200928020020082802002204460d00200a28020021070c010b200441016a22072004490d9e022004410174220b20072007200b491b220b4100480d9e020240024020040d00200b102721070c010b200a2802002004200b102821070b2007450de201200220073602042009200b360200200828020021040b2008200441016a360200200720046a200641807f72200641ff0071200641077622041b3a00002004210620040d000b2002410c6a2107200241086a2108034002400240200828020020072802002204460d00200a28020021060c010b200441016a22062004490d9e0220044101742209200620062009491b22094100480d9e020240024020040d002009102721060c010b200a28020020042009102821060b2006450de3012002200636020420082009360200200728020021040b2007200441016a360200200620046a200541807f72200541ff0071200541077622041b3a00002004210520040d000c86010b0b200241046a210a200141086a2802002105200141046a280200210602400240200241086a2802002002410c6a2802002204460d00200a28020021070c010b200441016a22072004490d9c0220044101742208200720072008491b22084100480d9c020240024020040d002008102721070c010b200a28020020042008102821070b2007450de20120022007360204200241086a20083602002002410c6a28020021040b2002410c6a2208200441016a360200200720046a413b3a0000200241086a2109034002400240200928020020082802002204460d00200a28020021070c010b200441016a22072004490d9d022004410174220b20072007200b491b220b4100480d9d020240024020040d00200b102721070c010b200a2802002004200b102821070b2007450de401200220073602042009200b360200200828020021040b2008200441016a360200200720046a200641807f72200641ff0071200641077622041b3a00002004210620040d000b2002410c6a2107200241086a2108034002400240200828020020072802002204460d00200a28020021060c010b200441016a22062004490d9d0220044101742209200620062009491b22094100480d9d020240024020040d002009102721060c010b200a28020020042009102821060b2006450de5012002200636020420082009360200200728020021040b2007200441016a360200200620046a200541807f72200541ff0071200541077622041b3a00002004210520040d000c85010b0b200241046a210a200141086a2802002106200141046a280200210502400240200241086a2802002002410c6a2802002204460d00200a28020021070c010b200441016a22072004490d9b0220044101742208200720072008491b22084100480d9b020240024020040d002008102721070c010b200a28020020042008102821070b2007450de40120022007360204200241086a20083602002002410c6a28020021040b2002410c6a2208200441016a360200200720046a413c3a0000200241086a2109034002400240200928020020082802002204460d00200a28020021070c010b200441016a22072004490d9c022004410174220b20072007200b491b220b4100480d9c020240024020040d00200b102721070c010b200a2802002004200b102821070b2007450de601200220073602042009200b360200200828020021040b2008200441016a360200200720046a200541807f72200541ff0071200541077622041b3a00002004210520040d000b2002410c6a2107200241086a2108034002400240200828020020072802002204460d00200a28020021050c010b200441016a22052004490d9c0220044101742209200520052009491b22094100480d9c020240024020040d002009102721050c010b200a28020020042009102821050b2005450de7012002200536020420082009360200200728020021040b2007200441016a360200200520046a200641807f72200641ff0071200641077622041b3a00002004210620040d000c84010b0b200241046a210a200141086a2802002105200141046a280200210602400240200241086a2802002002410c6a2802002204460d00200a28020021070c010b200441016a22072004490d9a0220044101742208200720072008491b22084100480d9a020240024020040d002008102721070c010b200a28020020042008102821070b2007450de60120022007360204200241086a20083602002002410c6a28020021040b2002410c6a2208200441016a360200200720046a413d3a0000200241086a2109034002400240200928020020082802002204460d00200a28020021070c010b200441016a22072004490d9b022004410174220b20072007200b491b220b4100480d9b020240024020040d00200b102721070c010b200a2802002004200b102821070b2007450de801200220073602042009200b360200200828020021040b2008200441016a360200200720046a200641807f72200641ff0071200641077622041b3a00002004210620040d000b2002410c6a2107200241086a2108034002400240200828020020072802002204460d00200a28020021060c010b200441016a22062004490d9b0220044101742209200620062009491b22094100480d9b020240024020040d002009102721060c010b200a28020020042009102821060b2006450de9012002200636020420082009360200200728020021040b2007200441016a360200200620046a200541807f72200541ff0071200541077622041b3a00002004210520040d000c83010b0b200241046a210a200141086a2802002105200141046a280200210602400240200241086a2802002002410c6a2802002204460d00200a28020021070c010b200441016a22072004490d990220044101742208200720072008491b22084100480d99020240024020040d002008102721070c010b200a28020020042008102821070b2007450de80120022007360204200241086a20083602002002410c6a28020021040b2002410c6a2208200441016a360200200720046a413e3a0000200241086a2109034002400240200928020020082802002204460d00200a28020021070c010b200441016a22072004490d9a022004410174220b20072007200b491b220b4100480d9a020240024020040d00200b102721070c010b200a2802002004200b102821070b2007450dea01200220073602042009200b360200200828020021040b2008200441016a360200200720046a200641807f72200641ff0071200641077622041b3a00002004210620040d000b2002410c6a2107200241086a2108034002400240200828020020072802002204460d00200a28020021060c010b200441016a22062004490d9a0220044101742209200620062009491b22094100480d9a020240024020040d002009102721060c010b200a28020020042009102821060b2006450deb012002200636020420082009360200200728020021040b2007200441016a360200200620046a200541807f72200541ff0071200541077622041b3a00002004210520040d000c82010b0b200241046a210620012d0001210702400240200241086a2802002002410c6a2802002204460d00200628020021050c010b200441016a22052004490d980220044101742208200520052008491b22084100480d98020240024020040d002008102721050c010b200628020020042008102821050b2005450dea0120022005360204200241086a20083602002002410c6a28020021040b2002410c6a2208200441016a360200200520046a413f3a000002400240200241086a28020020082802002204460d00200628020021050c010b200441016a22052004490d980220044101742208200520052008491b22084100480d98020240024020040d002008102721050c010b200628020020042008102821050b2005450deb0120022005360204200241086a20083602002002410c6a28020021040b2002410c6a200441016a360200200520046a20073a00000c80010b200241046a210620012d0001210702400240200241086a2802002002410c6a2802002204460d00200628020021050c010b200441016a22052004490d970220044101742208200520052008491b22084100480d97020240024020040d002008102721050c010b200628020020042008102821050b2005450deb0120022005360204200241086a20083602002002410c6a28020021040b2002410c6a2208200441016a360200200520046a41c0003a000002400240200241086a28020020082802002204460d00200628020021050c010b200441016a22052004490d970220044101742208200520052008491b22084100480d97020240024020040d002008102721050c010b200628020020042008102821050b2005450dec0120022005360204200241086a20083602002002410c6a28020021040b2002410c6a200441016a360200200520046a20073a00000c7f0b200141046a280200210602400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d960220044101742207200520052007491b22074100480d96020240024020040d002007102721050c010b200228020420042007102821050b2005450dec0120022005360204200241086a20073602002002410c6a28020021040b2002410c6a200441016a360200200520046a41c1003a000020032006200210e1032003210220032d0000411a470df0020c7e0b200141086a290300210c02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d950220044101742206200520052006491b22064100480d95020240024020040d002006102721050c010b200228020420042006102821050b2005450dec0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41c2003a00002003200c200210e2032003210220032d0000411a470def020c7d0b200241046a2106200141046a280200210702400240200241086a2802002002410c6a2802002204460d00200628020021050c010b200441016a22052004490d940220044101742208200520052008491b22084100480d94020240024020040d002008102721050c010b200628020020042008102821050b2005450dec0120022005360204200241086a20083602002002410c6a28020021040b2002410c6a2208200441016a360200200520046a41c3003a000002400240200241086a2802002205200828020022046b4104490d00200628020021050c010b200441046a22082004490d940220054101742204200820082004491b22044100480d94020240024020050d002004102721050c010b200628020020052004102821050b2005450ded0120022005360204200241086a20043602002002410c6a28020021040b2002410c6a200441046a360200200520046a20073600000c7c0b200241046a2106200141086a290300210c02400240200241086a2802002002410c6a2802002204460d00200628020021050c010b200441016a22052004490d930220044101742207200520052007491b22074100480d93020240024020040d002007102721050c010b200628020020042007102821050b2005450ded0120022005360204200241086a20073602002002410c6a28020021040b2002410c6a2207200441016a360200200520046a41c4003a000002400240200241086a2802002205200728020022046b4108490d00200628020021050c010b200441086a22072004490d930220054101742204200720072004491b22044100480d93020240024020050d002004102721050c010b200628020020052004102821050b2005450dee0120022005360204200241086a20043602002002410c6a28020021040b2002410c6a200441086a360200200520046a200c3700000c7b0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d920220044101742206200520052006491b22064100480d92020240024020040d002006102721050c010b200228020420042006102821050b2005450dee0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41c5003a00000c7a0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d910220044101742206200520052006491b22064100480d91020240024020040d002006102721050c010b200228020420042006102821050b2005450dee0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41c6003a00000c790b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d900220044101742206200520052006491b22064100480d90020240024020040d002006102721050c010b200228020420042006102821050b2005450dee0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41c7003a00000c780b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d8f0220044101742206200520052006491b22064100480d8f020240024020040d002006102721050c010b200228020420042006102821050b2005450dee0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41c8003a00000c770b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d8e0220044101742206200520052006491b22064100480d8e020240024020040d002006102721050c010b200228020420042006102821050b2005450dee0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41c9003a00000c760b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d8d0220044101742206200520052006491b22064100480d8d020240024020040d002006102721050c010b200228020420042006102821050b2005450dee0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41ca003a00000c750b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d8c0220044101742206200520052006491b22064100480d8c020240024020040d002006102721050c010b200228020420042006102821050b2005450dee0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41cb003a00000c740b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d8b0220044101742206200520052006491b22064100480d8b020240024020040d002006102721050c010b200228020420042006102821050b2005450dee0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41cc003a00000c730b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d8a0220044101742206200520052006491b22064100480d8a020240024020040d002006102721050c010b200228020420042006102821050b2005450dee0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41cd003a00000c720b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d890220044101742206200520052006491b22064100480d89020240024020040d002006102721050c010b200228020420042006102821050b2005450dee0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41ce003a00000c710b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d880220044101742206200520052006491b22064100480d88020240024020040d002006102721050c010b200228020420042006102821050b2005450dee0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41cf003a00000c700b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d870220044101742206200520052006491b22064100480d87020240024020040d002006102721050c010b200228020420042006102821050b2005450dee0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41d0003a00000c6f0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d860220044101742206200520052006491b22064100480d86020240024020040d002006102721050c010b200228020420042006102821050b2005450dee0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41d1003a00000c6e0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d850220044101742206200520052006491b22064100480d85020240024020040d002006102721050c010b200228020420042006102821050b2005450dee0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41d2003a00000c6d0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d840220044101742206200520052006491b22064100480d84020240024020040d002006102721050c010b200228020420042006102821050b2005450dee0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41d3003a00000c6c0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d830220044101742206200520052006491b22064100480d83020240024020040d002006102721050c010b200228020420042006102821050b2005450dee0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41d4003a00000c6b0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d820220044101742206200520052006491b22064100480d82020240024020040d002006102721050c010b200228020420042006102821050b2005450dee0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41d5003a00000c6a0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d810220044101742206200520052006491b22064100480d81020240024020040d002006102721050c010b200228020420042006102821050b2005450dee0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41d6003a00000c690b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d800220044101742206200520052006491b22064100480d80020240024020040d002006102721050c010b200228020420042006102821050b2005450dee0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41d7003a00000c680b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490dff0120044101742206200520052006491b22064100480dff010240024020040d002006102721050c010b200228020420042006102821050b2005450dee0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41d8003a00000c670b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490dfe0120044101742206200520052006491b22064100480dfe010240024020040d002006102721050c010b200228020420042006102821050b2005450dee0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41d9003a00000c660b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490dfd0120044101742206200520052006491b22064100480dfd010240024020040d002006102721050c010b200228020420042006102821050b2005450dee0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41da003a00000c650b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490dfc0120044101742206200520052006491b22064100480dfc010240024020040d002006102721050c010b200228020420042006102821050b2005450dee0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41db003a00000c640b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490dfb0120044101742206200520052006491b22064100480dfb010240024020040d002006102721050c010b200228020420042006102821050b2005450dee0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41dc003a00000c630b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490dfa0120044101742206200520052006491b22064100480dfa010240024020040d002006102721050c010b200228020420042006102821050b2005450dee0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41dd003a00000c620b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490df90120044101742206200520052006491b22064100480df9010240024020040d002006102721050c010b200228020420042006102821050b2005450dee0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41de003a00000c610b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490df80120044101742206200520052006491b22064100480df8010240024020040d002006102721050c010b200228020420042006102821050b2005450dee0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41df003a00000c600b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490df70120044101742206200520052006491b22064100480df7010240024020040d002006102721050c010b200228020420042006102821050b2005450dee0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41e0003a00000c5f0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490df60120044101742206200520052006491b22064100480df6010240024020040d002006102721050c010b200228020420042006102821050b2005450dee0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41e1003a00000c5e0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490df50120044101742206200520052006491b22064100480df5010240024020040d002006102721050c010b200228020420042006102821050b2005450dee0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41e2003a00000c5d0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490df40120044101742206200520052006491b22064100480df4010240024020040d002006102721050c010b200228020420042006102821050b2005450dee0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41e3003a00000c5c0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490df30120044101742206200520052006491b22064100480df3010240024020040d002006102721050c010b200228020420042006102821050b2005450dee0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41e4003a00000c5b0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490df20120044101742206200520052006491b22064100480df2010240024020040d002006102721050c010b200228020420042006102821050b2005450dee0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41e5003a00000c5a0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490df10120044101742206200520052006491b22064100480df1010240024020040d002006102721050c010b200228020420042006102821050b2005450dee0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41e6003a00000c590b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490df00120044101742206200520052006491b22064100480df0010240024020040d002006102721050c010b200228020420042006102821050b2005450dee0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41e7003a00000c580b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490def0120044101742206200520052006491b22064100480def010240024020040d002006102721050c010b200228020420042006102821050b2005450dee0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41e8003a00000c570b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490dba0220044101742206200520052006491b22064100480dba020240024020040d002006102721050c010b200228020420042006102821050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41e9003a00000c560b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490db90220044101742206200520052006491b22064100480db9020240024020040d002006102721050c010b200228020420042006102821050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41ea003a00000c550b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490db80220044101742206200520052006491b22064100480db8020240024020040d002006102721050c010b200228020420042006102821050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41eb003a00000c540b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490db70220044101742206200520052006491b22064100480db7020240024020040d002006102721050c010b200228020420042006102821050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41ec003a00000c530b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490db60220044101742206200520052006491b22064100480db6020240024020040d002006102721050c010b200228020420042006102821050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41ed003a00000c520b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490db50220044101742206200520052006491b22064100480db5020240024020040d002006102721050c010b200228020420042006102821050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41ee003a00000c510b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490db40220044101742206200520052006491b22064100480db4020240024020040d002006102721050c010b200228020420042006102821050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41ef003a00000c500b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490db30220044101742206200520052006491b22064100480db3020240024020040d002006102721050c010b200228020420042006102821050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41f0003a00000c4f0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490db20220044101742206200520052006491b22064100480db2020240024020040d002006102721050c010b200228020420042006102821050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41f1003a00000c4e0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490db10220044101742206200520052006491b22064100480db1020240024020040d002006102721050c010b200228020420042006102821050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41f2003a00000c4d0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490db00220044101742206200520052006491b22064100480db0020240024020040d002006102721050c010b200228020420042006102821050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41f3003a00000c4c0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490daf0220044101742206200520052006491b22064100480daf020240024020040d002006102721050c010b200228020420042006102821050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41f4003a00000c4b0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490dae0220044101742206200520052006491b22064100480dae020240024020040d002006102721050c010b200228020420042006102821050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41f5003a00000c4a0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490dad0220044101742206200520052006491b22064100480dad020240024020040d002006102721050c010b200228020420042006102821050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41f6003a00000c490b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490dac0220044101742206200520052006491b22064100480dac020240024020040d002006102721050c010b200228020420042006102821050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41f7003a00000c480b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490dab0220044101742206200520052006491b22064100480dab020240024020040d002006102721050c010b200228020420042006102821050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41f8003a00000c470b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490daa0220044101742206200520052006491b22064100480daa020240024020040d002006102721050c010b200228020420042006102821050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41f9003a00000c460b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490da90220044101742206200520052006491b22064100480da9020240024020040d002006102721050c010b200228020420042006102821050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41fa003a00000c450b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490da80220044101742206200520052006491b22064100480da8020240024020040d002006102721050c010b200228020420042006102821050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41fb003a00000c440b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490da70220044101742206200520052006491b22064100480da7020240024020040d002006102721050c010b200228020420042006102821050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41fc003a00000c430b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490da60220044101742206200520052006491b22064100480da6020240024020040d002006102721050c010b200228020420042006102821050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41fd003a00000c420b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490da50220044101742206200520052006491b22064100480da5020240024020040d002006102721050c010b200228020420042006102821050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41fe003a00000c410b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490da40220044101742206200520052006491b22064100480da4020240024020040d002006102721050c010b200228020420042006102821050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41ff003a00000c400b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490da30220044101742206200520052006491b22064100480da3020240024020040d002006102721050c010b200228020420042006102821050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a4180013a00000c3f0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490da20220044101742206200520052006491b22064100480da2020240024020040d002006102721050c010b200228020420042006102821050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a4181013a00000c3e0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490da10220044101742206200520052006491b22064100480da1020240024020040d002006102721050c010b200228020420042006102821050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a4182013a00000c3d0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490da00220044101742206200520052006491b22064100480da0020240024020040d002006102721050c010b200228020420042006102821050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a4183013a00000c3c0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d9f0220044101742206200520052006491b22064100480d9f020240024020040d002006102721050c010b200228020420042006102821050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a4184013a00000c3b0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d9e0220044101742206200520052006491b22064100480d9e020240024020040d002006102721050c010b200228020420042006102821050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a4185013a00000c3a0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d9d0220044101742206200520052006491b22064100480d9d020240024020040d002006102721050c010b200228020420042006102821050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a4186013a00000c390b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d9c0220044101742206200520052006491b22064100480d9c020240024020040d002006102721050c010b200228020420042006102821050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a4187013a00000c380b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d9b0220044101742206200520052006491b22064100480d9b020240024020040d002006102721050c010b200228020420042006102821050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a4188013a00000c370b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d9a0220044101742206200520052006491b22064100480d9a020240024020040d002006102721050c010b200228020420042006102821050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a4189013a00000c360b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d990220044101742206200520052006491b22064100480d99020240024020040d002006102721050c010b200228020420042006102821050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a418a013a00000c350b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d980220044101742206200520052006491b22064100480d98020240024020040d002006102721050c010b200228020420042006102821050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a418b013a00000c340b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d970220044101742206200520052006491b22064100480d97020240024020040d002006102721050c010b200228020420042006102821050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a418c013a00000c330b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d960220044101742206200520052006491b22064100480d96020240024020040d002006102721050c010b200228020420042006102821050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a418d013a00000c320b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d950220044101742206200520052006491b22064100480d95020240024020040d002006102721050c010b200228020420042006102821050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a418e013a00000c310b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d940220044101742206200520052006491b22064100480d94020240024020040d002006102721050c010b200228020420042006102821050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a418f013a00000c300b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d930220044101742206200520052006491b22064100480d93020240024020040d002006102721050c010b200228020420042006102821050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a4190013a00000c2f0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d920220044101742206200520052006491b22064100480d92020240024020040d002006102721050c010b200228020420042006102821050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a4191013a00000c2e0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d910220044101742206200520052006491b22064100480d91020240024020040d002006102721050c010b200228020420042006102821050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a4192013a00000c2d0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d900220044101742206200520052006491b22064100480d90020240024020040d002006102721050c010b200228020420042006102821050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a4193013a00000c2c0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d8f0220044101742206200520052006491b22064100480d8f020240024020040d002006102721050c010b200228020420042006102821050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a4194013a00000c2b0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d8e0220044101742206200520052006491b22064100480d8e020240024020040d002006102721050c010b200228020420042006102821050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a4195013a00000c2a0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d8d0220044101742206200520052006491b22064100480d8d020240024020040d002006102721050c010b200228020420042006102821050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a4196013a00000c290b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d8c0220044101742206200520052006491b22064100480d8c020240024020040d002006102721050c010b200228020420042006102821050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a4197013a00000c280b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d8b0220044101742206200520052006491b22064100480d8b020240024020040d002006102721050c010b200228020420042006102821050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a4198013a00000c270b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d8a0220044101742206200520052006491b22064100480d8a020240024020040d002006102721050c010b200228020420042006102821050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a4199013a00000c260b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d890220044101742206200520052006491b22064100480d89020240024020040d002006102721050c010b200228020420042006102821050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a419a013a00000c250b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d880220044101742206200520052006491b22064100480d88020240024020040d002006102721050c010b200228020420042006102821050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a419b013a00000c240b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d870220044101742206200520052006491b22064100480d87020240024020040d002006102721050c010b200228020420042006102821050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a419c013a00000c230b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d860220044101742206200520052006491b22064100480d86020240024020040d002006102721050c010b200228020420042006102821050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a419d013a00000c220b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d850220044101742206200520052006491b22064100480d85020240024020040d002006102721050c010b200228020420042006102821050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a419e013a00000c210b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d840220044101742206200520052006491b22064100480d84020240024020040d002006102721050c010b200228020420042006102821050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a419f013a00000c200b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d830220044101742206200520052006491b22064100480d83020240024020040d002006102721050c010b200228020420042006102821050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41a0013a00000c1f0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d820220044101742206200520052006491b22064100480d82020240024020040d002006102721050c010b200228020420042006102821050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41a1013a00000c1e0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d810220044101742206200520052006491b22064100480d81020240024020040d002006102721050c010b200228020420042006102821050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41a2013a00000c1d0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d800220044101742206200520052006491b22064100480d80020240024020040d002006102721050c010b200228020420042006102821050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41a3013a00000c1c0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490dff0120044101742206200520052006491b22064100480dff010240024020040d002006102721050c010b200228020420042006102821050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41a4013a00000c1b0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490dfe0120044101742206200520052006491b22064100480dfe010240024020040d002006102721050c010b200228020420042006102821050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41a5013a00000c1a0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490dfd0120044101742206200520052006491b22064100480dfd010240024020040d002006102721050c010b200228020420042006102821050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41a6013a00000c190b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490dfc0120044101742206200520052006491b22064100480dfc010240024020040d002006102721050c010b200228020420042006102821050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41a7013a00000c180b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490dfb0120044101742206200520052006491b22064100480dfb010240024020040d002006102721050c010b200228020420042006102821050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41a8013a00000c170b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490dfa0120044101742206200520052006491b22064100480dfa010240024020040d002006102721050c010b200228020420042006102821050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41a9013a00000c160b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490df90120044101742206200520052006491b22064100480df9010240024020040d002006102721050c010b200228020420042006102821050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41aa013a00000c150b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490df80120044101742206200520052006491b22064100480df8010240024020040d002006102721050c010b200228020420042006102821050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41ab013a00000c140b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490df70120044101742206200520052006491b22064100480df7010240024020040d002006102721050c010b200228020420042006102821050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41ac013a00000c130b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490df60120044101742206200520052006491b22064100480df6010240024020040d002006102721050c010b200228020420042006102821050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41ad013a00000c120b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490df50120044101742206200520052006491b22064100480df5010240024020040d002006102721050c010b200228020420042006102821050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41ae013a00000c110b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490df40120044101742206200520052006491b22064100480df4010240024020040d002006102721050c010b200228020420042006102821050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41af013a00000c100b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490df30120044101742206200520052006491b22064100480df3010240024020040d002006102721050c010b200228020420042006102821050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41b0013a00000c0f0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490df20120044101742206200520052006491b22064100480df2010240024020040d002006102721050c010b200228020420042006102821050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41b1013a00000c0e0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490df10120044101742206200520052006491b22064100480df1010240024020040d002006102721050c010b200228020420042006102821050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41b2013a00000c0d0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490df00120044101742206200520052006491b22064100480df0010240024020040d002006102721050c010b200228020420042006102821050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41b3013a00000c0c0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490dfc0120044101742206200520052006491b22064100480dfc010240024020040d002006102721050c010b200228020420042006102821050b2005450df00120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41b4013a00000c0b0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490dfb0120044101742206200520052006491b22064100480dfb010240024020040d002006102721050c010b200228020420042006102821050b2005450df00120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41b5013a00000c0a0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490dfa0120044101742206200520052006491b22064100480dfa010240024020040d002006102721050c010b200228020420042006102821050b2005450df00120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41b6013a00000c090b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490df90120044101742206200520052006491b22064100480df9010240024020040d002006102721050c010b200228020420042006102821050b2005450df00120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41b7013a00000c080b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490df80120044101742206200520052006491b22064100480df8010240024020040d002006102721050c010b200228020420042006102821050b2005450df00120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41b8013a00000c070b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490df70120044101742206200520052006491b22064100480df7010240024020040d002006102721050c010b200228020420042006102821050b2005450df00120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41b9013a00000c060b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490df60120044101742206200520052006491b22064100480df6010240024020040d002006102721050c010b200228020420042006102821050b2005450df00120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41ba013a00000c050b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490df50120044101742206200520052006491b22064100480df5010240024020040d002006102721050c010b200228020420042006102821050b2005450df00120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41bb013a00000c040b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490df40120044101742206200520052006491b22064100480df4010240024020040d002006102721050c010b200228020420042006102821050b2005450df00120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41bc013a00000c030b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490df30120044101742206200520052006491b22064100480df3010240024020040d002006102721050c010b200228020420042006102821050b2005450df00120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41bd013a00000c020b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490df20120044101742206200520052006491b22064100480df2010240024020040d002006102721050c010b200228020420042006102821050b2005450df00120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41be013a00000c010b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490df10120044101742206200520052006491b22064100480df1010240024020040d002006102721050c010b200228020420042006102821050b2005450df00120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41bf013a00000b2000411a3a000020012d00004109470df201200141086a28020041ffffffff0371450df201200141046a28020010290cf2010b20064101102a000b20064101102a000b20084101102a000b20084101102a000b20084101102a000b20084101102a000b20084101102a000b20084101102a000b20064101102a000b20064101102a000b20074101102a000b200a4101102a000b20074101102a000b200a4101102a000b20064101102a000b20084101102a000b20064101102a000b20074101102a000b200a4101102a000b20074101102a000b200a4101102a000b20064101102a000b20064101102a000b20064101102a000b20074101102a000b200a4101102a000b20074101102a000b200a4101102a000b20074101102a000b200a4101102a000b20074101102a000b200a4101102a000b20074101102a000b200a4101102a000b20084101102a000b200b4101102a000b20094101102a000b20084101102a000b200b4101102a000b20094101102a000b20084101102a000b200b4101102a000b20094101102a000b20084101102a000b200b4101102a000b20094101102a000b20084101102a000b200b4101102a000b20094101102a000b20084101102a000b200b4101102a000b20094101102a000b20084101102a000b200b4101102a000b20094101102a000b20084101102a000b200b4101102a000b20094101102a000b20084101102a000b200b4101102a000b20094101102a000b20084101102a000b200b4101102a000b20094101102a000b20084101102a000b200b4101102a000b20094101102a000b20084101102a000b200b4101102a000b20094101102a000b20084101102a000b200b4101102a000b20094101102a000b20084101102a000b102b000b200b4101102a000b20094101102a000b20084101102a000b200b4101102a000b20094101102a000b20084101102a000b200b4101102a000b20094101102a000b20084101102a000b200b4101102a000b20094101102a000b20084101102a000b200b4101102a000b20094101102a000b20084101102a000b200b4101102a000b20094101102a000b20084101102a000b200b4101102a000b20094101102a000b20084101102a000b200b4101102a000b20094101102a000b20084101102a000b200b4101102a000b20094101102a000b20084101102a000b200b4101102a000b20094101102a000b20084101102a000b20084101102a000b20084101102a000b20084101102a000b20074101102a000b20064101102a000b20084101102a000b20044101102a000b20074101102a000b20044101102a000b20064101102a000b20064101102a000b20064101102a000b20064101102a000b20064101102a000b20064101102a000b20064101102a000b20064101102a000b20064101102a000b20064101102a000b20064101102a000b20064101102a000b20064101102a000b20064101102a000b20064101102a000b20064101102a000b20064101102a000b20064101102a000b20064101102a000b20064101102a000b20064101102a000b20064101102a000b20064101102a000b20064101102a000b20064101102a000b20064101102a000b20064101102a000b20064101102a000b20064101102a000b20064101102a000b20064101102a000b20064101102a000b20064101102a000b20064101102a000b20064101102a000b20064101102a000b102b000b20064101102a000b20064101102a000b20064101102a000b20064101102a000b20064101102a000b20064101102a000b20064101102a000b20064101102a000b20064101102a000b20064101102a000b20064101102a000b20064101102a000b20064101102a000b20064101102a000b20064101102a000b20064101102a000b20064101102a000b20064101102a000b20064101102a000b20064101102a000b20064101102a000b20064101102a000b20064101102a000b20064101102a000b20064101102a000b20064101102a000b20064101102a000b20064101102a000b20064101102a000b20064101102a000b20064101102a000b20064101102a000b20064101102a000b20064101102a000b20064101102a000b20064101102a000b20064101102a000b20064101102a000b20064101102a000b20064101102a000b20064101102a000b20064101102a000b20064101102a000b20064101102a000b20064101102a000b20064101102a000b20064101102a000b20064101102a000b20064101102a000b20064101102a000b20064101102a000b20064101102a000b20064101102a000b20064101102a000b20064101102a000b20064101102a000b20064101102a000b20064101102a000b20064101102a000b20064101102a000b20064101102a000b20064101102a000b20064101102a000b20064101102a000b20064101102a000b20064101102a000b20064101102a000b20064101102a000b20064101102a000b20064101102a000b20064101102a000b20064101102a000b20064101102a000b20064101102a000b20064101102a000b102b000b20064101102a000b20064101102a000b20064101102a000b20064101102a000b20064101102a000b20064101102a000b20064101102a000b20064101102a000b20064101102a000b20064101102a000b20064101102a000b20064101102a000b102b000b20002003290300370200200041086a200341086a290300370200200941ffffffff0371450d01200b10290c010b20002002290200370200200041086a200241086a29020037020020012d00004109470d00200141086a28020041ffffffff0371450d00200141046a28020010290b200341106a24000b8307010c7f200028021021030240024002400240200028020822044101460d0020030d012000280218200120022000411c6a28020028020c11050021030c030b2003450d010b0240024020020d00410021020c010b200120026a2105200041146a28020041016a21064100210720012103200121080340200341016a210902400240024020032c0000220a417f4a0d000240024020092005470d004100210b200521030c010b20032d0001413f71210b200341026a220921030b200a411f71210c0240200a41ff0171220a41df014b0d00200b200c41067472210a0c020b0240024020032005470d004100210d2005210e0c010b20032d0000413f71210d200341016a2209210e0b200d200b41067472210b0240200a41f0014f0d00200b200c410c7472210a0c020b02400240200e2005470d004100210a200921030c010b200e41016a2103200e2d0000413f71210a0b200b410674200c411274418080f0007172200a72220a418080c400470d020c040b200a41ff0171210a0b200921030b02402006417f6a2206450d00200720086b20036a21072003210820052003470d010c020b0b200a418080c400460d00024002402007450d0020072002460d0041002103200720024f0d01200120076a2c00004140480d010b200121030b2007200220031b21022003200120031b21010b20040d002000280218200120022000411c6a28020028020c1105000f0b4100210902402002450d002002210a200121030340200920032d000041c00171418001466a2109200341016a2103200a417f6a220a0d000b0b0240200220096b200028020c2206490d002000280218200120022000411c6a28020028020c1105000f0b410021074100210902402002450d00410021092002210a200121030340200920032d000041c00171418001466a2109200341016a2103200a417f6a220a0d000b0b200920026b20066a210a024002400240410020002d0030220320034103461b0e0402000100020b200a21074100210a0c010b200a4101762107200a41016a410176210a0b200741016a2103024003402003417f6a2203450d0120002802182000280204200028021c280210110400450d000b41010f0b2000280204210941012103200028021820012002200028021c28020c1105000d00200a41016a2103200028021c210a20002802182100034002402003417f6a22030d0041000f0b20002009200a280210110400450d000b41010f0b20030bfb07030e7f017e017f200241086a2103200241046a210420012802002205210602400240024002400240034002400240200428020020032802002207460d00200228020021080c010b200741016a22082007490d0220074101742209200820082009491b22094100480d020240024020070d002009102721080c010b200228020020072009102821080b2008450d032002200836020020042009360200200328020021070b2003200741016a360200200820076a200641807f72200641ff0071200641077622071b3a00002007210620070d000b2001280204220a2001410c6a2802002206410c6c6a210b200141086a280200210c200a21072006450d03200a21072005450d03200b41746a210d200241086a210841002107200a210e02400340200e2103024003402003280200220f0d01200741016a2107200b2003410c6a2203470d000c080b0b2003410c6a210e200741016a21102005417f6a2105200341046a290200211102400240034002400240200241046a220428020020082802002206460d00200228020021090c010b200641016a22092006490d0620064101742201200920092001491b22014100480d060240024020060d002001102721090c010b200228020020062001102821090b2009450d022002200936020020042001360200200828020021060b2008200641016a360200200920066a200741807f72200741ff0071200741077622061b3a0000200621072006450d020c000b0b20014101102a000b2011422088a7221221060240034002400240200428020020082802002207460d00200228020021090c010b200741016a22092007490d0520074101742201200920092001491b22014100480d050240024020070d002001102721090c010b200228020020072001102821090b2009450d022002200936020020042001360200200828020021070b2008200741016a360200200920076a200641807f72200641ff0071200641077622071b3a00002007210620070d000b0240024020042802002206200828020022076b2012490d00200228020021060c010b200720126a22092007490d0420064101742207200920092007491b22074100480d040240024020060d002007102721060c010b200228020020062007102821060b2006450d032002200636020020042007360200200828020021070b2008200720126a360200200620076a200f201210ce041a02402011a7450d00200f10290b200d2003460d052010210720050d010c050b0b20014101102a000b20074101102a000b102b000b20094101102a000b2003410c6a21070b2007200b460d000340024020072802002206450d00200741046a280200450d00200610290b2007410c6a2207200b470d000b0b0240200c450d00200a10290b2000411a3a00000bcb0401067f200441046a2105024002400240024002400240200441086a2802002004410c6a2802002206460d00200528020021070c010b200641016a22072006490d0420064101742208200720072008491b22084100480d040240024020060d002008102721070c010b200528020020062008102821070b2007450d0120042007360204200441086a20083602002004410c6a28020021060b2004410c6a2208200641016a360200200720066a20024101463a0000200441086a2109034002400240200928020020082802002206460d00200528020021070c010b200641016a22072006490d052006410174220a20072007200a491b220a4100480d050240024020060d00200a102721070c010b20052802002006200a102821070b2007450d03200420073602042009200a360200200828020021060b2008200641016a360200200720066a200141807f72200141ff0071200141077622061b3a00002006210120060d000b024020024101470d002004410c6a2107200441086a2108034002400240200828020020072802002206460d00200528020021010c010b200641016a22012006490d0620064101742209200120012009491b22094100480d060240024020060d002009102721010c010b200528020020062009102821010b2001450d052004200136020420082009360200200728020021060b2007200641016a360200200120066a200341807f72200341ff0071200341077622061b3a00002006210320060d000b0b2000411a3a00000f0b20084101102a000b200a4101102a000b20094101102a000b102b000bc30701097f230041d0006b2202240002400240024002400240024002400240024020012802082203200128020c2204460d00200441016a22052004490d0420032005490d072001280200220620046a2d000021072001200536020c0240200741014d0d00410c21040c020b4100210820070e020302030b200241013a001f200241cc006a41013602002002420137023c20024180c0c5003602382002411f3602342002200241306a36024820022002411f6a360230200241206a200241386a10e6032002411a6a200241286a28020036010020022002290320370112200220022901103703002002200241166a290100370106410521040b200020073a0005200020043a000420002002290300370106200041013602002000410c6a20022901063701000c060b410121080b410120036b2109200441026a2104410021074100210a02400240034002402007411f4d0d00410f21070c020b02400240200920046a4102460d002004450d06200320044f0d0120042003107f000b200241013a0000200241cc006a41013602002002420137023c20024180c0c5003602382002411f3602342002200241306a36024820022002360230200241106a200241386a10e603410521070c020b200620046a417f6a2d000021052001200436020c200541ff00712007411f7174200a72210a200441016a2104200741076a21072005418001710d000b20074120490d01410d210720054110490d010b2000200736020420004101360200200041086a2002290210370200200041106a200241106a41086a2802003602000c050b0240024020080d00410021040c010b2004417f6a2104410021074100210802400240034002402007411f4d0d00410f21040c020b0240024020032004460d002004417f460d082003200441016a22094f0d01200441016a2003107f000b200241013a0000200241cc006a41013602002002420137023c20024180c0c5003602382002411f3602342002200241306a36024820022002360230200241106a200241386a10e603410521040c020b200620046a2d000021052001200936020c200541ff00712007411f71742008722108200741076a2107200921042005418001710d000b20074120490d01410d210420054110490d010b2000200436020420004101360200200041086a2002290210370200200041106a200241106a41086a2802003602000c060b410121040b2000200a360204200041003602002000410c6a2008360200200041086a20043602000c040b417f2005103e000b417f2004103e000b417f200441016a103e000b20052003107f000b200241d0006a24000ba60301077f2002410c6a2103200141086a28020022042105024002400240034002400240200241086a220628020020032802002207460d00200228020421080c010b200741016a22082007490d0420074101742209200820082009491b22094100480d040240024020070d002009102721080c010b200228020420072009102821080b2008450d022002200836020420062009360200200328020021070b2003200741016a360200200820076a200541807f72200541ff0071200541077622071b3a00002007210520070d000b200128020421032001280200210802400240200241086a28020022052002410c6a28020022076b2004490d00200228020421050c010b200720046a22062007490d0320054101742207200620062007491b22074100480d030240024020050d002007102721050c010b200228020420052007102821050b2005450d0220022005360204200241086a20073602002002410c6a28020021070b2002410c6a200720046a360200200520076a2008200410ce041a02402003450d00200810290b2000411a3a00000f0b20094101102a000b20074101102a000b102b000b8b07010b7f230041d0086b22022400410021034100210402400240024002400240034002402003411f4d0d00410f21030c020b0240024020012802082205200128020c2206460d00200641016a22072006490d05200520074f0d0120072005107f000b200241013a0089082002411c6a41013602002002420137020c20024180c0c5003602082002411f36029c08200220024198086a360218200220024189086a36029808200241b8086a200241086a10e603410521030c020b2001280200220820066a2d000021062001200736020c200641ff00712003411f71742004722104200341076a21032006418001710d000b20034120490d01410d210320064110490d010b2000200336020420004101360200200041086a20022902b808370200200041106a200241b8086a41086a2802003602000c030b024020040d002000428080808010370200200041086a42003702000c030b200241086a410041800810cd041a410121094100210a410021064100210b03400240024002400240200520076b2004200b6b22034180082003418008491b2203490d00200720036a220c2007490d022005200c4f0d01200c2005107f000b200241013a00a708200241cc086a4101360200200242013702bc0820024180c0c5003602b8082002411f36029c08200220024198086a3602c8082002200241a7086a36029808200241a8086a200241b8086a10e60320024194086a200241b0086a280200360000200220022903a80837008c08200041053a000420002002290089083700052000410c6a20024190086a29000037000020004101360200200a450d06200910290c060b200241086a200820076a200310ce041a2001200c36020c0240200a20066b2003490d00200320066a210c0c020b0240200620036a220c2006490d00200a4101742207200c200c2007491b22074100480d0002400240200a0d002007102721090c010b2009200a2007102821090b02402009450d002007210a0c030b20074101102a000b102b000b2007200c103e000b200920066a200241086a200310ce041a20042003200b6a220b4d0d02200128020c21072001280208210520012802002108200c21060c000b0b417f2007103e000b200241086a2009200c10dc01024020022802084101470d000240200a450d00200910290b200041083a0004200041013602000c010b200020093602042000410c6a200c360200200041086a200a360200200041003602000b200241d0086a24000b1600200120002802002200280200200028020810e9030bef0201067f230041c0006b2202240041002103410021040240024003400240024002402003411f4b0d002001280204220520012802082206460d01200641016a22072006490d04200520074f0d0220072005107f000b200041013602002000410f3a00040c040b200241013a000f200241346a41013602002002420137022420024180c0c5003602202002411f36023c2002200241386a36023020022002410f6a360238200241106a200241206a10e6032002410b6a200241186a28020036000020022002290310370003200041053a0004200020022900003700052000410c6a200241076a290000370000200041013602000c030b200128020020066a2d0000210620012007360208200641ff00712003411f71742004722104200341076a21032006418001710d000b0240024020034120490d002006410f4b0d010b20004100360200200020043602040c020b200041013602002000410d3a00040c010b417f2007103e000b200241c0006a24000bdb06010a7f20012802042103200128020021044100210541012106410021072001280208220821090240024002400240024002400340024020072005470d002005410174220a200541016a220b200b200a491b220a4100480d070240024020050d00200a102721060c010b20062005200a102821060b2006450d02200a21050b200620076a200941807f72200941ff00712009410776220a1b3a0000200741016a2107200a2109200a0d000b200520076b20084f0d02200720086a22092007490d052005410174220a20092009200a491b220941004e0d010c050b200a4101102a000b0240024020050d002009102721060c010b200620052009102821060b2006450d01200921050b200620076a2004200810ce041a02402003450d00200410290b200128020c210c0240200520086b20076b200141146a2802002209490d00200820096a20076a21030c020b200820076a220a20096a2203200a490d022005410174220a20032003200a491b220a4100480d020240024020050d00200a102721060c010b20062005200a102821060b02402006450d00200a21050c020b200a4101102a000b20094101102a000b200620086a20076a200c200910ce041a200241086a210b200241046a210820032109024002400340024002402008280200200b2802002207460d002002280200210a0c010b200741016a220a2007490d0420074101742204200a200a2004491b22044100480d040240024020070d0020041027210a0c010b2002280200200720041028210a0b200a450d022002200a36020020082004360200200b28020021070b200b200741016a360200200a20076a200941807f72200941ff0071200941077622071b3a00002007210920070d000b02400240200241046a2802002209200241086a28020022076b2003490d00200228020021090c010b200720036a220a2007490d0320094101742207200a200a2007491b22074100480d030240024020090d002007102721090c010b200228020020092007102821090b2009450d0220022009360200200241046a2007360200200241086a28020021070b200241086a200720036a360200200920076a2006200310ce041a02402005450d00200610290b2000411a3a00000240200141106a280200450d00200c10290b0f0b20044101102a000b20074101102a000b102b000be5bc0106077f017e047f017e197f027e230041f080046b2202240002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002402001280204220320012802082204460d00200441016a22052004490d02200320054f0d0120052003107f000b200241013a0028200241d4006a41013602002002420137024420024180c0c5003602402002411f3602242002200241206a3602502002200241286a360220200241d880046a200241c0006a10e60320022802d88004210420022802dc8004210120004101360200200041003a00042001450d1d200410290c1d0b200128020020046a2d00002104200120053602082004410b4b0d02024020040e0c00100f0e0d0c0b0a02060504000b200241c0006a200110f0034101210620022802442107024020022802404101470d0020074108762108200241d0006a2802002101200241c0006a41086a29030021090c1c0b4100210a200241c0006a41004180800110cd041a4100210b410021032007450d10410121064100210b410021054100210c034002400240024002402001280204220d200128020822036b2007200c6b220441808001200441808001491b2204490d00200320046a22082003490d02200d20084f0d012008200d107f000b200241013a00c88004200241ec80046a4101360200200242013702dc800420024180c0c5003602d880042002411f3602242002200241206a3602e880042002200241c880046a360220200241286a200241d880046a10e6032002290328210920022802302101410521070240200b450d00200610290b0c1f0b200241c0006a200128020020036a200410ce041a200120083602080240200b20056b2004490d00200420056a21030c020b200520046a22032005490d14200b4101742208200320032008491b22084100480d1402400240200b0d002008102721060c010b2006200b2008102821060b02402006450d002008210b0c020b20084101102a000b20032008103e000b200620056a200241c0006a200410ce041a2003210520072004200c6a220c4b0d000c110b0b417f2005103e000b200241c0006a200110f303024020022802404101470d00200041013602002000200241c0006a41047222012902003702042000410c6a200141086a2902003702000c1b0b200241d4006a2802002108200241d0006a2802002101200241cc006a2802002105200241c8006a280200210b2002280244210c410021044100210302400240034002402004411f4d0d00410f21010c0a0b20052001460d082001417f460d012005200141016a2206490d02200c20016a2d0000220a41ff00712004411f71742003722103200441076a210420062101200a418001710d000b20044120490d06410d2101200a410f4b0d080c060b417f200141016a103e000b200141016a2005107f000b200041123a000420004101360200200041056a20043a00000c190b200241c0006a200110f3030240024020022802404101470d00200228024422014108762106200241c0006a41086a2903002209422088210e200241d0006a280200210a0c010b200241386a200241d4006a280200360200200241306a200241cc006a29020037030020022002290244370328410021064100210141002105024002400240024002400240024002400240034002402001411f4d0d00410f21070c070b2002280230220a20022802342204460d08200441016a22032004490d02200a2003490d01200228022820046a2d0000210420022003360234200441ff00712001411f71742005722105200141076a21012004418001710d000b024020014120490d002004410f4d0d0041002106410d21070c060b02400240024020050d004100210d410421030c010b410421034100210d4100210703402007220f41016a2107410021014100210c02400240024002400240024003404100210602402001411f4d0d00410f21070c0f0b2002280230220b20022802342204460d01200441016a220a2004490d02200b200a490d04200228022820046a2d000021042002200a360234200441ff00712001411f7174200c72210c200141076a21012004418001710d000b024020014120490d002004410f4d0d00410d21070c0e0b200241c0006a200241286a10e303024020022802404101470d002002280244220741087621062002280250210a200228024c210b200228024821080c0e0b200228024c21102002280248211120022802442112410021044100210b034002402004411f4d0d00410f21070c0e0b200228023022062002280234220a460d0c200a41016a2201200a490d0320062001490d0520022802282208200a6a2d0000210a20022001360234200a41ff00712004411f7174200b72210b200441076a2104200a418001710d000b20044120490d05200a410f4d0d05410d21070c0c0b200241013a00c88004200241013602542002420137024420024180c0c5003602402002411f3602242002200241206a3602502002200241c880046a360220200241d880046a200241c0006a10e60320022903d880042209422088a7210b20022802e08004210a2009a72108410521070c0c0b417f200a103e000b417f2001103e000b200a200b107f000b20012006107f000b41002113200241c0006a41004180800410cd041a02400240200b0d0041012114410021150c010b41002113410121144100210a4100211603400240024002400240200620016b200b20166b220441808004200441808004491b2204490d00200120046a22152001490d02200620154f0d0120152006107f000b200241013a00c78004200241013602ec8004200242013702dc800420024180c0c5003602d880042002411f3602242002200241206a3602e880042002200241c780046a360220200241c880046a200241d880046a10e60320022802c88004210820022802cc8004210b20022802d08004210a410521072013450d0b201410290c0b0b200241c0006a200820016a200410ce041a2002201536023402402013200a6b2004490d002004200a6a21150c020b200a20046a2215200a490d1e20134101742201201520152001491b22014100480d1e0240024020130d002001102721140c010b201420132001102821140b02402014450d00200121130c020b20014101102a000b20012015103e000b2014200a6a200241c0006a200410ce041a200b200420166a22164d0d012002280234210120022802302106200228022821082015210a0c000b0b0240200d200f470d00200d4101742201200d41016a220420042001491b2201ad421c7e2209422088a70d1b2009a722044100480d1b02400240200d0d002004102721030c010b2003200d411c6c2004102821030b2003450d032001210d0b2003200f411c6c6a2201200c41087622043b000120012014360210200120123602042001200c3a0000200141036a20044110763a0000200141186a2015360200200141146a20133602002001410c6a2010360200200141086a201136020020072005470d000b0b200228023420022802384621010240200228022c450d00200228022810290b2001450d072005ad422086200dad842109410c21040c1c0b20044104102a000b2003200a107f000b417f2003103e000b200241013a00c88004200241013602542002420137024420024180c0c5003602402002411f3602242002200241206a3602502002200241c880046a360220200241d880046a200241c0006a10e60320022903d880042209422088a7210b20022802e08004210a2009a72108410521070b02402010450d0020104104742104201221010340024020012d00004109470d00200141086a28020041ffffffff0371450d00200141046a28020010290b200141106a2101200441706a22040d000b0b410021062011450d00201210290b0240200f450d002003200f411c6c6a210c20032105034002402005410c6a2802002204450d0020052802042101200441047421040340024020012d00004109470d00200141086a28020041ffffffff0371450d00200141046a28020010290b200141106a2101200441706a22040d000b0b0240200541086a280200450d00200528020410290b2005411c6a21010240200541146a280200450d00200528021010290b200121052001200c470d000b0b200d450d03200310290c030b4100210b410021080c020b20024103410220011b3a00c88004200241c0006a41146a41013602002002420137024420024180c0c5003602402002411f3602242002200241206a3602502002200241c880046a360220200241d880046a200241c0006a10e60320022903d88004210920022802e08004210a02402005450d0020032005411c6c6a210620032105034002402005410c6a2802002204450d0020052802042101200441047421040340024020012d00004109470d00200141086a28020041ffffffff0371450d00200141046a28020010290b200141106a2101200441706a22040d000b0b0240200541086a280200450d00200528020410290b2005411c6a21010240200541146a280200450d00200528021010290b2001210520012006470d000b0b2009422088210e4105210141002106200d450d02200310290c020b200241013a00c88004200241d4006a41013602002002420137024420024180c0c5003602402002411f3602242002200241206a3602502002200241c880046a360220200241d880046a200241c0006a10e60320022903d880042209422088a7210b20022802e08004210a2009a7210841052107410021060b2006410874200741ff0171722101200bad220e4220862008ad842109200228022c450d00200228022810290b20004101360200200041106a200a360200200041086a200e422086200942ffffffff0f838437020020002006410874200141ff0171723602040c180b200241c0006a200110f3030240024020022802404101470d002002280244220b4108762101200241c0006a41086a2903002209422088210e200241d0006a28020021080c010b200241d4006a2802002114200241d0006a2802002101200241cc006a280200210a200241c8006a28020021132002280244210c410021044100210602400240024002400240024002400240024002400240024002400240034002402004411f4d0d00410f210b0c020b02400240200a2001460d002001417f460d06200a200141016a22054f0d01200141016a200a107f000b200241013a0028200241d4006a41013602002002420137024420024180c0c5003602402002411f3602242002200241206a3602502002200241286a360220200241d880046a200241c0006a10e60320022903d88004210920022802e0800421084105210b0c030b200c20016a2d0000220341ff00712004411f71742006722106200441076a2104200521012003418001710d000b20044120490d0220034110490d02410d210b0b0b2009422088a7210d2009a721160c0b0b024002400240024002400240024002400240024002400240024020060d0041002117410421030c010b200241c9006a211841042103410021174100211903402019221a41016a2119410021014100210b034002402001411f4d0d00410f210b0c170b200a2005460d142005417f460d0d200a200541016a2204490d06200c20056a2d0000220741ff00712001411f7174200b72210b200141076a2101200421052007418001710d000b024020014120490d002007410f4d0d00410d210b0c160b4100210f200241c0006a41004180800110cd041a02400240200b0d00410121102004210541002111410021070c010b41002111410121104100211541002112034002400240200a20046b200b20126b220141808001200141808001491b2201490d00200420016a22052004490d0f200a20054f0d012005200a107f000b200241013a00c78004200241013602ec8004200242013702dc800420024180c0c5003602d880042002411f3602242002200241206a3602e880042002200241c780046a360220200241c880046a200241d880046a10e60320022903c880042209422088a7210d20022802d0800421082009a721164105210b2011450d18201010290c180b200241c0006a200c20046a200110ce041a02400240201120156b2001490d00200120156a21070c010b201520016a22072015490d2820114101742204200720072004491b22044100480d280240024020110d002004102721100c010b201020112004102821100b2010450d0d200421110b201020156a200241c0006a200110ce041a2005210420072115200b200120126a22124b0d000b0b20024100360234200220103602282002200736023820022007ad4220862011ad8437022c4100210141002112034002402001411f4d0d00410f210b0c140b2007200f460d12200f417f460d0a2007200f41016a220b490d052010200f6a2d000021042002200b360234200441ff00712001411f71742012722112200141076a2101200b210f2004418001710d000b024020014120490d002004410f4d0d00410d210b0c130b4100211b0240024020120d004104211c410021110c010b410021114104211c4100211d0340201d221e41016a211d4100210141002115024002400240034002402001411f4d0d00410f211520162101200d211f0c020b024002402002280230220f20022802342204460d00200441016a220b2004490d10200f200b4f0d01200b200f107f000b200241013a00c88004200241013602542002420137024420024180c0c5003602402002411f3602242002200241206a3602502002200241c880046a360220200241d880046a200241c0006a10e60320022903d880042209422088a7211f20022802e0800421082009a72101410521150c020b2002280228221020046a2d000021072002200b360234200741ff00712001411f71742015722115200141076a21012007418001710d000b20014120490d0120074110490d0120162101200d211f410d21150b200141087621204101210741002104200821214100210b20012116201f210d0c010b0240024002400240200f200b460d00200441026a2101200b417f460d0e200f20014f0d012001200f107f000b200241013a00c88004200241013602542002420137024420024180c0c5003602402002411f3602242002200241206a3602502002200241c880046a360220200241d880046a200241c0006a10e60320022802d88004212220022802dc8004212320022802e080042124410521150c010b2010200b6a2c00002104200220013602340240200441004e0d00411821150c010b0240200441c000710d00410621150c010b200441807f72220141ff017141fb014b0d0141062115200121040b20224108762120410121074100210b2023211f20242121202221010c010b20154180807c71210b201541087621042001417f732101410021070b200b200441ff017141087472201541ff017172210b02402007450d002020410874200141ff01717221162011450d15201c10290c150b02402011201e470d0020114101742204201141016a220720072004491b220441ffffffff01712004470d28200441037422074100480d280240024020110d0020071027211c0c010b201c201141037420071028211c0b201c450d09200421110b201c201e4103746a220420013a00042004200b360200201d2012470d000b0b4101210b41082110410021014100210741002115034020012104200241c0006a200241286a10e403024020022802404101470d0020022802502121200228024c211f200228024821162002280244210b0c120b200241d880046a41026a2201201841026a2d00003a0000200220182f00003b01d88004200228024c211e2002280250211d200228025421250240024020022d0048220f4106470d00200b417f6a210b0c010b200f417e6a41034f0d00200b41016a2226200b4f21272026210b20270d004115211f419487c50021164104210b200f4109470d11201d41ffffffff03710d100c110b200241c0006a41026a222620012d00003a0000200220022f01d880043b0140024020072015470d00200741016a22012007490d27201b20012001201b491b221541ffffffff00712015470d27201541047422014100480d270240024020070d002001102721100c010b201020042001102821100b2010450d040b201020046a2201200f3a00002001410c6a2025360200200141086a201d360200200141046a201e360200200141016a20022f01403b0000200141036a20262d00003a0000201b41026a211b200441106a2101200741016a2107200b0d000b200228023420022802384621010240200228022c450d00200228022810290b2001450d1402402017201a470d0020174101742201201741016a220420042001491b2201ad42187e2209422088a70d262009a722044100480d260240024020170d002004102721030c010b2003201741186c2004102821030b2003450d04200121170b2003201a41186c6a2201201036020c20012012360208200120113602042001201c360200200141146a2007360200200141106a201536020020192006470d000b0b2005201446210102402013450d00200c10290b2001450d142006ad4220862017ad842109410b21040c270b20014108102a000b20044104102a000b200f41016a2007107f000b200541016a200a107f000b20074104102a000b417f2001103e000b417f200b103e000b417f200f41016a103e000b20044101102a000b20042005103e000b417f200541016a103e000b417f200141016a103e000b201e10290b0b02402007450d00201021010340024020012d00004109470d00200141086a28020041ffffffff0371450d00200141046a28020010290b200141106a2101200441706a22040d000b0b02402015450d00201010290b2011450d01201c10290c010b200241013a00c88004200241013602542002420137024420024180c0c5003602402002411f3602242002200241206a3602502002200241c880046a360220200241d880046a200241c0006a10e60320022903d880042209422088a7211f20022802e0800421212009a721164105210b0b0240200228022c450d00200228022810290b201f210d202121080c020b200241013a00c88004200241013602542002420137024420024180c0c5003602402002411f3602242002200241206a3602502002200241c880046a360220200241d880046a200241c0006a10e60320022903d880042209422088a7210d20022802e0800421082009a721164105210b0c010b20024103410220011b3a00c88004200241013602542002420137024420024180c0c5003602402002411f3602242002200241206a3602502002200241c880046a360220200241d880046a200241c0006a10e60320022802d88004211620022802dc8004210d20022802e08004210802402007450d00200441106a21054100210103400240201020016a22042d00004109470d00200441086a28020041ffffffff0371450d00200441046a28020010290b2005200141106a2201470d000b0b02402015450d00201010290b4105210b2011450d00201c10290b0240201a450d002003201a41186c6a210a2003210503400240200541046a280200450d00200528020010290b0240200541146a2802002204450d00200528020c2101200441047421040340024020012d00004109470d00200141086a28020041ffffffff0371450d00200141046a28020010290b200141106a2101200441706a22040d000b0b200541186a21010240200541106a280200450d00200528020c10290b200121052001200a470d000b0b2017450d01200310290c010b20024103410220011b3a0028200241c0006a41146a41013602002002420137024420024180c0c5003602402002411f3602242002200241206a3602502002200241286a360220200241d880046a200241c0006a10e60320022903d88004210920022802e08004210802402006450d002003200641186c6a210a2003210503400240200541046a280200450d00200528020010290b0240200541146a2802002204450d00200528020c2101200441047421040340024020012d00004109470d00200141086a28020041ffffffff0371450d00200141046a28020010290b200141106a2101200441706a22040d000b0b200541186a21010240200541106a280200450d00200528020c10290b200121052001200a470d000b0b2009422088210e4105210b410021012017450d01200310290c010b200b4108762101200dad220e4220862016ad8421092013450d00200c10290b20004101360200200041106a2008360200200041086a200e422086200942ffffffff0f838437020020002001410874200b41ff0171723602040c170b200241c0006a200110f3030240024020022802404101470d00200228024422014108762106200241c0006a41086a2903002209422088210e200241d0006a280200210a0c010b200241e880046a200241d4006a280200360200200241e080046a200241cc006a290200370300200220022902443703d880044100210641002101410021050240024002400240024002400240024002400240034002402001411f4d0d00410f210b0c080b20022802e08004220a20022802e480042204460d09200441016a22032004490d01200a2003490d0420022802d8800420046a2d00002104200220033602e48004200441ff00712001411f71742005722105200141076a21012004418001710d000b024020014120490d002004410f4d0d0041002106410d210b0c070b0240024020050d004100210d410421030c010b410421034100210d4100210803402008221641016a2108410021014100210c0240024002400240024003404100210602402001411f4d0d00410f210b0c030b20022802e08004220b20022802e480042204460d01200441016a220a2004490d09200b200a490d0c20022802d8800420046a2d000021042002200a3602e48004200441ff00712001411f7174200c72210c200141076a21012004418001710d000b024020014120490d002004410f4d0d00410d210b0c020b200241c0006a200241d880046a10e303024020022802404101470d002002280244220b41087621062002280250210a200228024c2108200228024821070c020b200228024c21132002280248210f20022802442115200241c0006a200241d880046a10e703024020022802404101470d002002280244210b2002280250210a200228024c21082002280248210702402013450d0020134104742104201521010340024020012d00004109470d00200141086a28020041ffffffff0371450d00200141046a28020010290b200141106a2101200441706a22040d000b0b200b4108762106200f450d02201510290c020b200228024821142002280244210702400240200228024c22010d00410021064104210b4100210a0c010b2001410274220a410275220641ffffffff03712006470d1e200a4100480d1e200a1027220b450d0d200a417c6a2110200b210120072104034020012004280200360200200141046a2101200441046a2104200a417c6a220a0d000b201041027641016a210a0b02402014450d00200710290b200d2016470d04200d4101742201200d41016a220420042001491b2201ad421c7e2209422088a70d1d2009a722044100480d1d200d0d022004102721030c030b200241013a00c88004200241013602542002420137024420024180c0c5003602402002411f3602242002200241206a3602502002200241c880046a360220200241286a200241c0006a10e60320022903282209422088a721082002280230210a2009a721074105210b0b02402016450d0020032016411c6c6a210c20032105034002402005410c6a2802002204450d0020052802042101200441047421040340024020012d00004109470d00200141086a28020041ffffffff0371450d00200141046a28020010290b200141106a2101200441706a22040d000b0b0240200541086a280200450d00200528020410290b2005411c6a21010240200541146a280200450d00200528021010290b200121052001200c470d000b0b200d450d0e200310290c0e0b2003200d411c6c2004102821030b2003450d052001210d0b20032016411c6c6a2201200c41087622043b00012001200b360210200120153602042001200c3a0000200141036a20044110763a0000200141186a200a360200200141146a20063602002001410c6a2013360200200141086a200f36020020082005470d000b0b20022802e4800420022802e88004462101024020022802dc8004450d0020022802d8800410290b2001450d072005ad422086200dad842109410a21040c1a0b417f2003103e000b417f200a103e000b20044104102a000b2003200a107f000b200a200b107f000b200a4104102a000b41002108410021070c020b20024103410220011b3a00c88004200241c0006a41146a41013602002002420137024420024180c0c5003602402002411f3602242002200241206a3602502002200241c880046a360220200241286a200241c0006a10e603200229032821092002280230210a02402005450d0020032005411c6c6a210620032105034002402005410c6a2802002204450d0020052802042101200441047421040340024020012d00004109470d00200141086a28020041ffffffff0371450d00200141046a28020010290b200141106a2101200441706a22040d000b0b0240200541086a280200450d00200528020410290b2005411c6a21010240200541146a280200450d00200528021010290b2001210520012006470d000b0b2009422088210e4105210141002106200d450d02200310290c020b200241013a00c88004200241d4006a41013602002002420137024420024180c0c5003602402002411f3602242002200241206a3602502002200241c880046a360220200241286a200241c0006a10e60320022903282209422088a721082002280230210a2009a721074105210b410021060b2006410874200b41ff01717221012008ad220e4220862007ad84210920022802dc8004450d0020022802d8800410290b20004101360200200041106a200a360200200041086a200e422086200942ffffffff0f838437020020002006410874200141ff0171723602040c160b200820064621010240200b450d00200c10290b02402001450d00410921040c0f0b20024103410220011b3a00c88004200241d4006a41013602002002420137024420024180c0c5003602402002411f3602242002200241206a3602502002200241c880046a360220200241286a200241c0006a10e603200241e380046a200241306a280200360000200220022903283700db8004200041053a0004200020022900d880043700052000410c6a200241df80046a290000370000200041013602000c150b200241013a0028200241d4006a41013602002002420137024420024180c0c5003602402002411f3602242002200241206a3602502002200241286a360220200241d880046a200241c0006a10e603410521010b2000200136020420004101360200200041086a20022902d88004370200200041106a200241d880046a41086a280200360200200b450d13200c10290c130b200241c0006a200110f3030240024020022802404101470d00200228024422044108762101200241c0006a41086a2903002209422088210e200241d0006a28020021060c010b200241e880046a200241d4006a280200360200200241e080046a200241cc006a290200370300200220022902443703d880044100210c4100210141002105024002400240024002400240024002400240024002400240024002400240024002400240034002402001411f4d0d00410f2104410021050c130b20022802e08004220a20022802e480042204460d11200441016a22032004490d01200a2003490d0820022802d8800420046a2d00002104200220033602e48004200441ff00712001411f71742005722105200141076a21012004418001710d000b024020014120490d002004410f4d0d00410d2104410021050c120b0240024020050d0041002116410421030c010b410421034100210a41002116410021130340200241c0006a200241d880046a10ee03024020022802404101470d002002200229024c22093703c8800420022802482105200228024421042009a7210c0c110b200228024821152002280244210f0240024020022802e08004220420022802e480042206460d00200641016a22012006490d05200420014f0d0120012004107f000b200241013a00c78004200241013602542002420137024420024180c0c5003602402002411f3602242002200241206a3602502002200241c780046a360220200241286a200241c0006a10e6030c0e0b200228024c211420022802d88004220c20066a2d0000210d200220013602e480040240200d41034d0d00410a21010c100b02400240024002400240200d0e0400010203000b4100210d4100210b4100210603400240200b411f4d0d00410f21010c150b20042001460d132001417f460d092004200141016a2207490d0f200c20016a2d00002108200220073602e48004200841ff0071200b411f71742006722106200b41076a210b200721012008418001710d000b4100210d200b4120490d032008410f4d0d03410d21010c130b4100210b410021060340200b411f4b0d100240024020042001460d002001417f460d0b2004200141016a22074f0d01200141016a2004107f000b200241013a00c78004200241013602542002420137024420024180c0c5003602402002411f3602242002200241206a3602502002200241c780046a360220200241286a200241c0006a10e6030c120b200c20016a2d00002108200220073602e48004200841ff0071200b411f71742006722106200b41076a210b200721012008418001710d000b4101210d200b4120490d022008410f4d0d020c0e0b4100210b410021060340200b411f4b0d0f0240024020042001460d002001417f460d0b2004200141016a22074f0d01200141016a2004107f000b200241013a00c78004200241013602542002420137024420024180c0c5003602402002411f3602242002200241206a3602502002200241c780046a360220200241286a200241c0006a10e6030c110b200c20016a2d00002108200220073602e48004200841ff0071200b411f71742006722106200b41076a210b200721012008418001710d000b4102210d200b4120490d012008410f4b0d0d0c010b4100210b410021060340200b411f4b0d0e0240024020042001460d002001417f460d0b2004200141016a22074f0d01200141016a2004107f000b200241013a00c78004200241013602542002420137024420024180c0c5003602402002411f3602242002200241206a3602502002200241c780046a360220200241286a200241c0006a10e6030c100b200c20016a2d00002108200220073602e48004200841ff0071200b411f71742006722106200b41076a210b200721012008418001710d000b4103210d200b4120490d002008410f4b0d0c0b200220063602d080042002200d3602cc800420022902cc80042109024020162013470d0020164101742201201641016a220420042001491b2201ad42147e220e422088a70d1d200ea722044100480d1d0240024020160d002004102721030c010b2003201641146c2004102821030b2003450d09200121160b2003201341146c6a2201200937020c20012014360208200120153602042001200f360200200a41146a210a201341016a2201211320012005470d000b0b20022802e4800420022802e88004462101024020022802dc8004450d0020022802d8800410290b2001450d0f2005ad4220862016ad842109410821040c1e0b417f2003103e000b417f2001103e000b417f200141016a103e000b417f200141016a103e000b417f200141016a103e000b417f200141016a103e000b20044104102a000b2003200a107f000b200141016a2004107f000b410d21014100210d0c030b410f21014100210d0c020b20022802282105200229022c2109410521014100210d0c010b200241013a00c78004200241013602542002420137024420024180c0c5003602402002411f3602242002200241206a3602502002200241c780046a360220200241286a200241c0006a10e60320022802282105200229022c2109410521010b200d4108742001722104200220093703c880042009a7210c2015450d00200f10290b20022802cc8004210602402013450d002003210103400240200141046a280200450d00200128020010290b200141146a2101200a416c6a220a0d000b0b2016450d02200310290c020b20024103410220011b3a00c88004200241c0006a41146a41013602002002420137024420024180c0c5003602402002411f3602242002200241206a3602502002200241c880046a360220200241286a200241c0006a10e603200229032821092002280230210602402005450d00200541146c21042003210103400240200141046a280200450d00200128020010290b200141146a21012004416c6a22040d000b0b2009422088210e41052104410021012016450d02200310290c020b200241013a00c88004200241d4006a41013602002002420137024420024180c0c5003602402002411f3602242002200241206a3602502002200241c880046a360220200241286a200241c0006a10e60320022903282209422088a7210c200228023021062009a72105410521040b20044108762101200cad220e4220862005ad84210920022802dc8004450d0020022802d8800410290b20004101360200200041106a2006360200200041086a200e422086200942ffffffff0f838437020020002001410874200441ff0171723602040c120b200241c0006a200110f3030240024020022802404101470d00200228024422054108762101200241c0006a41086a2903002209422088210e200241d0006a280200210a0c010b200241386a200241d4006a280200360200200241306a200241cc006a290200370300200220022902443703284100210b410021014100210602400240024002400240024002400240034002402001411f4d0d00410f21054100210c0c090b2002280230220a20022802342204460d07200441016a22052004490d01200a2005490d052002280228220c20046a2d0000210420022005360234200441ff00712001411f71742006722106200141076a21012004418001710d000b024020014120490d002004410f4d0d00410d21054100210c0c080b024020060d00410421034100210d0c060b2006417f6a21144100211641002107410021084100210d4104210f410421030340024002400240024002400240024002400240200a2005460d00200541016a22042005490d0b200a20044f0d012004200a107f000b200241013a00c78004200241d4006a41013602002002420137024420024180c0c5003602402002411f3602242002200241206a3602502002200241c780046a360220200241c880046a200241c0006a10e60320022802c88004210c20022802cc8004210b20022802d08004210a410521130c010b200c20056a2c000021012002200436023402400240200141004e0d00411821130c010b41062113200141c00071450d00200141807f72220141ff017141fb014b0d020b0b200241e880046a200a360200200241e480046a200b360200200241e080046a200c360200200220013a00dd8004200220133a00dc80040c010b024002400240200a2004460d00200541026a21052004417f460d0b200a20054f0d012005200a107f000b200241013a00c78004200241d4006a41013602002002420137024420024180c0c5003602402002411f3602242002200241206a3602502002200241c780046a360220200241c880046a200241c0006a10e60320022802c88004210c20022802cc8004210b20022802d08004210a410521010c010b200c20046a2d00002104200220053602340240200441014b0d004100210a20040e020403040b410c21010b200241e880046a200a360200200241e480046a200b360200200241e080046a200c360200200220043a00dd8004200220013a00dc80040b200241013a00d8800420022802dc800421050c020b418002210a0b200241c0006a200241286a10e303200228024c210b2002280248210c2002280244210520022802404101470d01200241d0006a280200210a0b02402008450d00200320076a21060340024020032802082204450d0020032802002101200441047421040340024020012d00004109470d00200141086a28020041ffffffff0371450d00200141046a28020010290b200141106a2101200441706a22040d000b0b200341106a21010240200341046a280200450d00200328020010290b2001210320062001470d000b0b200d450d09200f10290c090b200841016a211302402008200d470d002016201320132016491b220d41ffffffff0071200d470d11200d41047422044100480d110240024020080d0020041027210f0c010b200f200720041028210f0b200f450d05200f21030b200320076a220420053602002004410c6a20154180807c712001417f7341ff017172200a722215360200200441086a200b360200200441046a200c36020020142008460d06201641026a2116200741106a2107200228023421052002280230210a2002280228210c201321080c000b0b417f2005103e000b417f2004103e000b417f2005103e000b20044104102a000b2005200a107f000b200228023420022802384621010240200228022c450d00200228022810290b02402001450d002006ad422086200dad842109410721040c0e0b20024103410220011b3a00c88004200241d4006a41013602002002420137024420024180c0c5003602402002411f3602242002200241206a3602502002200241c880046a360220200241d880046a200241c0006a10e60320022903d88004210920022802e08004210a02402006450d00200320064104746a2106200321050340024020052802082204450d0020052802002101200441047421040340024020012d00004109470d00200141086a28020041ffffffff0371450d00200141046a28020010290b200141106a2101200441706a22040d000b0b200541106a21010240200541046a280200450d00200528020010290b2001210520012006470d000b0b2009422088210e4105210541002101200d450d02200310290c020b200241013a00c88004200241d4006a41013602002002420137024420024180c0c5003602402002411f3602242002200241206a3602502002200241c880046a360220200241d880046a200241c0006a10e60320022903d880042209422088a7210b20022802e08004210a2009a7210c410521050b20054108762101200bad220e422086200cad842109200228022c450d00200228022810290b20004101360200200041106a200a360200200041086a200e422086200942ffffffff0f838437020020002001410874200541ff0171723602040c110b200241c0006a200110f3030240024020022802404101470d00200228024422044108762105200241c0006a41086a2903002209422088210e200241d0006a28020021010c010b200241e880046a200241d4006a280200360200200241e080046a200241cc006a290200220937030020022002290244220e3703d88004200ea7210c2009a721034100210420022802e4800421014100210502400240024002400240024002400240024003402004411f4b0d0120032001460d032001417f460d042003200141016a220a490d06200c20016a2d0000220641ff00712004411f71742005722105200441076a2104200a21012006418001710d000b2002200a3602e4800420044120490d012006410f4d0d0141002104410d210c0c060b200220013602e4800441002104410f210c0c050b0240024020050d00410421034100210d0c010b4100210741002106410021014100210d410421030340200241c0006a200241d880046a10ec0320022f004520022d0047411074722104200228024c210b2002280248210820022d0044210c024020022802404101470d00200241d0006a2802002101200d450d08200310290c080b200141016a210a02402001200d470d002007200a200a2007491b220dad420c7e2209422088a70d102009a722164100480d100240024020010d002016102721030c010b200320062016102821030b2003450d050b200320066a2201200c3a0000200141036a20044110763a0000200141016a20043b0000200141086a200b360200200141046a2008360200200741026a21072006410c6a2106200a21012005200a470d000b0b20022802e4800420022802e88004462101024020022802dc8004450d0020022802d8800410290b2001450d062005ad422086200dad842109410621040c110b200220033602e48004200241013a00c88004200241d4006a41013602002002420137024420024180c0c5003602402002411f3602242002200241206a3602502002200241c880046a360220200241286a200241c0006a10e60320022903282209422088a7210b200228023021012009a721084105210c410021040c040b417f200141016a103e000b20164104102a000b200141016a2003107f000b4100210b410021080b200441ffffff07712205410874200c41ff0171722104200bad220e4220862008ad84210920022802dc8004450d0120022802d8800410290c010b20024103410220011b3a00c88004200241d4006a41013602002002420137024420024180c0c5003602402002411f3602242002200241206a3602502002200241c880046a360220200241286a200241c0006a10e60320022903282209422088210e200228023021014105210441002105200d450d00200310290b20004101360200200041106a2001360200200041086a200e422086200942ffffffff0f838437020020002005410874200441ff0171723602040c100b200241c0006a200110f3030240024020022802404101470d00200228024422044108762105200241c0006a41086a2903002209422088210e200241d0006a28020021010c010b200241e880046a200241d4006a280200360200200241e080046a200241cc006a290200220937030020022002290244220e3703d88004200ea7210c2009a721054100210420022802e480042101410021060240024002400240024002400240024002400240024003402004411f4b0d0120052001460d032001417f460d042005200141016a220a490d07200c20016a2d0000220341ff00712004411f71742006722106200441076a2104200a21012003418001710d000b2002200a3602e4800420044120490d012003410f4d0d0141002104410d210a0c080b200220013602e4800441002104410f210a0c070b024020060d004100210b410421030c060b2006417f6a2116410421034108210d4100210841002107034002400240024002402005200a460d00200a41016a2201200a490d07200520014f0d0120012005107f000b200241013a00c88004200241013602542002420137024420024180c0c5003602402002411f3602242002200241206a3602502002200241c880046a360220200241286a200241c0006a10e6032002280228210b200228022c210c200228023021014105210a0c010b200c200a6a2c00002104200220013602e480040240200441004e0d004118210a0c010b4107210a0240200441c000710d000c010b200441807f7222044170470d00200241c0006a200241d880046a10ec0320022f004520022d004741107472210420022d0044210a20022802404101470d0120044180feff0771410876210520022802502101200228024c210c2002280248210b0b2005410874200441ff01717221042008450d09200310290c090b200228024c21052002280248210c0240024020072008460d002008210b0c010b20084101742201200841016a220b200b2001491b220bad420c7e2209422088a70d102009a722014100480d100240024020080d002001102721030c010b20032008410c6c2001102821030b2003450d050b2003200d6a22012005360200200141796a220520043b00002001417c6a200c360200200141786a200a3a0000200541026a20044110763a000020162007460d06200741016a2107200d410c6a210d20022802e48004210a20022802e08004210520022802d88004210c200b21080c000b0b200220053602e48004200241013a00c88004200241d4006a41013602002002420137024420024180c0c5003602402002411f3602242002200241206a3602502002200241c880046a360220200241286a200241c0006a10e60320022903282209422088a7210c200228023021012009a7210b4105210a410021040c060b417f200141016a103e000b417f2001103e000b20014104102a000b200141016a2005107f000b20022802e4800420022802e88004462101024020022802dc8004450d0020022802d8800410290b2001450d022006ad422086200bad842109410521040c0c0b4100210c4100210b0b200441ffffff07712205410874200a41ff0171722104200cad220e422086200bad84210920022802dc8004450d0120022802d8800410290c010b20024103410220011b3a00c88004200241d4006a41013602002002420137024420024180c0c5003602402002411f3602242002200241206a3602502002200241c880046a360220200241286a200241c0006a10e60320022903282209422088210e200228023021014105210441002105200b450d00200310290b20004101360200200041106a2001360200200041086a200e422086200942ffffffff0f838437020020002005410874200441ff0171723602040c0f0b200241c0006a200110f3030240024020022802404101470d00200228024422044108762105200241c0006a41086a2903002209422088210e200241d0006a28020021010c010b200241d4006a280200210d200241d0006a2802002101200241cc006a2802002105200241c8006a28020021072002280244210c4100210b41002104410021060240024002400240024002400240034002402004411f4d0d00410f2104410021050c030b20052001460d012001417f460d032005200141016a220a490d06200c20016a2d0000220341ff00712004411f71742006722106200441076a2104200a21012003418001710d000b024020044120490d002003410f4d0d00410d2104410021050c020b410421030240024020060d00410021130c010b410021164100211303402016221541016a2116200a2101410021044100210b024002400240034002402004411f4d0d00410f21040c020b0240024020052001460d002001417f460d0b2005200141016a220a4f0d01200141016a2005107f000b200241013a0028200241d4006a41013602002002420137024420024180c0c5003602402002411f3602242002200241206a3602502002200241286a360220200241d880046a200241c0006a10e60320022802d88004210520022802dc8004210b20022802e080042101410521040c030b200c20016a2d0000220841ff00712004411f7174200b72210b200441076a2104200a21012008418001710d000b20044120490d0220084110490d02410d21040b0b2013450d04200310290c040b024020132015470d0020154101742201201620162001491b221341ffffffff03712013470d0e201341027422014100480d0e0240024020150d002001102721030c010b200320154102742001102821030b2003450d070b200320154102746a200b36020020162006470d000b0b200a200d46210102402007450d00200c10290b2001450d062006ad4220862013ad842109410421040c0f0b200241013a0028200241d4006a41013602002002420137024420024180c0c5003602402002411f3602242002200241206a3602502002200241286a360220200241d880046a200241c0006a10e60320022903d880042209422088a7210b20022802e0800421012009a72105410521040b200bad220e4220862005ad842109410021052007450d05200c10290c050b417f200141016a103e000b417f200141016a103e000b20014104102a000b200141016a2005107f000b20024103410220011b3a0028200241d4006a41013602002002420137024420024180c0c5003602402002411f3602242002200241206a3602502002200241286a360220200241d880046a200241c0006a10e60320022903d880042209422088210e20022802e08004210141052104410021052013450d00200310290b20004101360200200041106a2001360200200041086a200e422086200942ffffffff0f838437020020002005410874200441ff0171723602040c0e0b200241c0006a200110f3030240024020022802404101470d00200228024422044108762101200241c0006a41086a2903002209422088210e200241d0006a28020021060c010b200241e880046a200241d4006a280200360200200241e080046a200241cc006a290200370300200220022902443703d880044100210c41002101410021050240024002400240024002400240024002400240034002402001411f4d0d00410f2104410021050c0b0b20022802e08004220a20022802e480042204460d09200441016a22032004490d02200a2003490d0120022802d8800420046a2d00002104200220033602e48004200441ff00712001411f71742005722105200141076a21012004418001710d000b024020014120490d002004410f4d0d00410d2104410021050c0a0b02400240024020050d0041002116410421030c010b410421034100210a41002116410021130340200241c0006a200241d880046a10ee03200228024c210c2002280248210f20022802442110024020022802404101470d0020022802502106200f2105201021040c0a0b200241c0006a200241d880046a10ee03200228024c21112002280248211420022802442112024020022802404101470d0020022802502106201421052011210c201221040c090b024002400240024002400240024002400240024002400240024002400240024020022802e08004220620022802e48004220b460d00200b41016a2201200b490d02200620014f0d0120012006107f000b200241013a00c88004200241013602542002420137024420024180c0c5003602402002411f3602242002200241206a3602502002200241c880046a360220200241286a200241c0006a10e60320022802282105200229022c210e4105210741002115410021060c160b20022802d88004220d200b6a2d00002104200220013602e48004410021150240200441034d0d0041092107410021060c160b024002400240024020040e0400010203000b410021154100210441002107034002402004411f4d0d00410f21070c180b0240024020062001460d002001417f460d072006200141016a22084f0d01200141016a2006107f000b200241013a00c88004200241013602542002420137024420024180c0c5003602402002411f3602242002200241206a3602502002200241c880046a360220200241286a200241c0006a10e60320022802282105200229022c210e41052107410021150c190b200d20016a2d0000210b200220083602e48004200b41ff00712004411f71742007722107200441076a210420082101200b418001710d000b4100211520044120490d0f200b410f4d0d0f410d21070c160b0240024020062001460d00200b41026a21042001417f460d0620062004490d07200d20016a2c00002101200220043602e4800402402001417f4a0d00411821050c0e0b200141c000710d010c0c0b200241013a00c88004200241013602542002420137024420024180c0c5003602402002411f3602242002200241206a3602502002200241c880046a360220200241286a200241c0006a10e6032002290328210920022802302104410521050c0c0b200141807f7222014170470d0a200241c0006a200241d880046a10ec032002290348210920022802442107024020022802404101470d00200228025021040c0d0b410121150c0f0b200241c0006a200241d880046a10ec032002290348210920022802442107024020022802404101460d00410221150c0f0b200220022802503602482007418080807871211520074180807c712106200741087621040c0c0b0240024020062001460d00200b41026a21082001417f460d0620062008490d08200d20016a2c00002104200220083602e480040240200441004e0d0041182107410021060c180b200441c000710d010c090b200241013a00c88004200241013602542002420137024420024180c0c5003602402002411f3602242002200241206a3602502002200241c880046a360220200241286a200241c0006a10e60341052107200229022c210e20022802282105410021060c160b200441807f72220441ff017141fc01490d070240024020062008460d00200b41036a21012008417f460d07200620014f0d0120012006107f000b200241013a00c88004200241013602542002420137024420024180c0c5003602402002411f3602242002200241206a3602502002200241c880046a360220200241286a200241c0006a10e60320022802282105200229022c210e41052107410021060c160b200d20086a2d0000210b200220013602e48004410021060240200b41014d0d00410c210741002115200b21040c160b2004417f732104410321150240200b0e020e000e0b410121060c0d0b417f2001103e000b417f200141016a103e000b417f2004103e000b20042006107f000b417f2008103e000b417f2001103e000b20082006107f000b41062107410021060c0d0b410721050b200141ff017141087420057221070b200220043602482007418080807871211520074180807c712106200741087621040b200220093703402002290244210e2009a721050c090b0b024020162013470d0020164101742201201641016a220b200b2001491b2201ad42287e220e422088a70d11200ea7220b4100480d110240024020160d00200b102721030c010b2003201641286c200b102821030b2003450d03200121160b2003201341286c6a2201201236020c2001200c3602082001200f36020420012010360200200141206a20093702002001411c6a20073602002001411a6a20063a0000200141196a20043a0000200141186a20153a0000200141146a2011360200200141106a2014360200200a41286a210a201341016a2201211320012005470d000b0b20022802e4800420022802e88004462101024020022802dc8004450d0020022802d8800410290b2001450d082005ad4220862016ad842109410321040c120b200b4104102a000b2003200a107f000b417f2003103e000b0b41002106410021040b200741ff0171200441ff0171410874722006418080fc0771722015722104200e422088a72106200ea7210c2014450d00201210290b200f450d00201010290b02402013450d002003210103400240200141046a280200450d00200128020010290b0240200141106a280200450d002001410c6a28020010290b200141286a2101200a41586a220a0d000b0b2016450d02200310290c020b20024103410220011b3a00c88004200241d4006a41013602002002420137024420024180c0c5003602402002411f3602242002200241206a3602502002200241c880046a360220200241286a200241c0006a10e603200229032821092002280230210602402005450d00200541286c21042003210103400240200141046a280200450d00200128020010290b0240200141106a280200450d002001410c6a28020010290b200141286a2101200441586a22040d000b0b2009422088210e41052104410021012016450d02200310290c020b200241013a00c88004200241d4006a41013602002002420137024420024180c0c5003602402002411f3602242002200241206a3602502002200241c880046a360220200241286a200241c0006a10e60320022903282209422088a7210c200228023021062009a72105410521040b20044108762101200cad220e4220862005ad84210920022802dc8004450d0020022802d8800410290b20004101360200200041106a2006360200200041086a200e422086200942ffffffff0f838437020020002001410874200441ff0171723602040c0d0b200241c0006a200110f3030240024020022802404101470d00200228024422014108762105200241c0006a41086a2903002209422088210e200241d0006a28020021040c010b200241d4006a2802002113200241d0006a2802002101200241cc006a2802002105200241c8006a28020021072002280244210c41002108410021044100210a024002400240024002400240024002400240034002402004411f4d0d00410f21014100210a0c0a0b20052001460d082001417f460d022005200141016a2206490d01200c20016a2d0000220341ff00712004411f7174200a72210a200441076a2104200621012003418001710d000b024020044120490d002003410f4d0d00410d21014100210a0c090b024002400240200a0d0041002112410421030c010b410120056b210d4100210b4104210341002112410021110340024002400240024002400240024002400240024020052006460d00200641016a22012006490d0120052001490d050240200c20066a2d0000221641e000460d004117210f0c130b201141016a211a200641026a2101410021164100210441002108034002402004411f4d0d00410f210f0c0a0b200d20016a4102460d082001450d0320052001490d07200c20016a417f6a2d0000220641ff00712004411f71742008722108200141016a2101200441076a21042006418001710d000b024020044120490d002006410f4d0d00410d210f0c090b2001417f6a210441002115410121100240024020080d00410021170c010b4100211441002106410021170340024002400240024020052004460d00200120066a2216450d09200520164f0d0120162005107f000b200241013a0028200241013602542002420137024420024180c0c5003602402002411f3602242002200241206a3602502002200241286a360220200241d880046a200241c0006a10e60320022802d88004210a20022802dc8004210820022802e0800421014105210f0c010b02400240200c20046a2c0000221641004e0d004118210f0c010b4106210f201641c00071450d00201641807f72221641ff017141fb014b0d020b0b2017450d0b201010290c0b0b200641016a210f024020062017470d002014200f200f2014491b22174100480d1b0240024020060d002017102721100c010b201020062017102821100b20100d0020174101102a000b200441016a2104201020066a2016417f733a0000201441026a2114200f21062008200f470d000b0b2010411076411074221f201041087641ff0171410874221872201041ff017122107221144100210103404100211602402015411f4d0d00410f210f0c130b0240024020052004460d002004417f460d072005200441016a22064f0d01200441016a2005107f000b200241013a0028200241013602542002420137024420024180c0c5003602402002411f3602242002200241206a3602502002200241286a360220200241d880046a200241c0006a10e60320022802d88004210a20022802dc8004210820022d00e08004210120022d00e18004210520022f01e2800421044105210f0c130b200c20046a2d0000220f41ff00712015411f71742001722101201541076a211520062104200f418001710d000b20154120490d09200f410f4d0d09410d210f0c110b200241013a0028200241013602542002420137024420024180c0c5003602402002411f3602242002200241206a3602502002200241286a360220200241d880046a200241c0006a10e60320022802d88004210a20022802dc8004210820022d00e08004210120022d00e18004210520022f01e2800421044105210f0c110b417f2001103e000b417f2001103e000b417f2016103e000b417f200441016a103e000b20012005107f000b20012005107f000b200241013a0028200241013602542002420137024420024180c0c5003602402002411f3602242002200241206a3602502002200241286a360220200241d880046a200241c0006a10e60320022903d880042209422088a7210820022802e0800421012009a7210a4105210f0b20014110762104200141087621050c090b0240200141014d0d004104210f41ba8cc500210a412421080c070b02400240024020010e020001000b410421040c010b20052006460d06024002400240200641016a22012006490d0020052001490d010240200c20066a2c0000221641004e0d004118210f0c0c0b4106210f201641c00071450d02201641807f72221641ff017141fb014d0d022016417f732104200121060c030b417f200641016a103e000b200641016a2005107f000b0c080b024020122011470d0020124101742201201241016a221620162001491b220141ffffffff00712001470d0f200141047422164100480d0f0240024020120d002016102721030c010b200320124104742016102821030b2003450d03200121120b200320114104746a220120194180807c71200441ff01714108747241e00072221936020c200120083602082001201736020420012018201072201f72360200200b41106a210b201a2111201a200a470d000b0b2006201346210102402007450d00200c10290b2001450d07200aad4220862012ad842109410221040c100b20164104102a000b200141016a2005107f000b417f200141016a103e000b200241013a0028200241013602542002420137024420024180c0c5003602402002411f3602242002200241206a3602502002200241286a360220200241d880046a200241c0006a10e60320022802d88004210a20022802dc8004210820022d00e08004210120022d00e18004210520022f01e2800421044105210f0b0b2017450d00201410290b200541ff0171410874200141ff017172210520044110742104201641ff0171410874210602402011450d002003210103400240200141046a280200450d00200128020010290b200141106a2101200b41706a220b0d000b0b200520047221042006200f7221012012450d02200310290c020b20024103410220011b3a0028200241d4006a41013602002002420137024420024180c0c5003602402002411f3602242002200241206a3602502002200241286a360220200241d880046a200241c0006a10e60320022903d88004210920022802e0800421040240200a450d00200a41047421052003210103400240200141046a280200450d00200128020010290b200141106a2101200541706a22050d000b0b2009422088210e41052101410021052012450d02200310290c020b200241013a0028200241d4006a41013602002002420137024420024180c0c5003602402002411f3602242002200241206a3602502002200241286a360220200241d880046a200241c0006a10e60320022903d880042209422088a7210820022802e0800421042009a7210a410521010b200141087621052008ad220e422086200aad8421092007450d00200c10290b20004101360200200041106a2004360200200041086a200e422086200942ffffffff0f838437020020002005410874200141ff0171723602040c0c0b410021014100210402400340410021080240200a4105470d00410f21070c0b0b2003200a460d032003200a4d0d012006200a6a2d0000220541ff00712001411f71742004722104200141076a2101200a41016a220c210a2005418001710d000b024020014120490d002005410f4d0d00410d21070c0a0b024020040d0041002105410121134100210a4100210d0c050b200241c0006a410041800810cd041a410121134100210d4100210541002107034002400240024002402003200c6b200420076b22014180082001418008491b2201490d00200c20016a2216200c490d02200320164f0d0120162003107f000b200241013a00c88004200241ec80046a4101360200200242013702dc800420024180c0c5003602d880042002411f3602242002200241206a3602e880042002200241c880046a360220200241286a200241d880046a10e60320022903282209422088a7210a200228023021012009a72104410521070240200d0d002004210d0c0f0b201310292004210d0c0e0b200241c0006a2006200c6a200110ce041a0240200d20056b2001490d00200120056a210a0c020b200520016a220a2005490d04200d410174220c200a200a200c491b220c4100480d0402400240200d0d00200c102721130c010b2013200d200c102821130b02402013450d00200c210d0c020b200c4101102a000b200c2016103e000b201320056a200241c0006a200110ce041a2016210c200a21052004200120076a22074d0d040c000b0b200a41016a2003107f000b102b000b200241013a0028200241d4006a41013602002002420137024420024180c0c5003602402002411f3602242002200241206a3602502002200241286a360220200241d880046a200241c0006a10e60320022903d880042209422088a7210a20022802e0800421012009a7210d410521070c070b200241c0006a2013200a10dc01024020022802404101470d00410821070240200d0d000c080b201310290c070b201341087621052016210c0b2003200c490d012003200c6b2204417f4c0d020240024020040d00410121010c010b200410272201450d0420012006200c6a200410ce041a0b200aad4220862109200dad210e2004ad222842208621290240200b450d00200610290b2009200e8421092029202884210e2005410874201341ff0171722103410121040b200020043a000420004100360200200041056a20022f001d3b0000200041186a200e370200200041146a20013602002000410c6a2009370200200041086a2003360200200041206a200229020c370200200041076a2002411f6a2d00003a0000200041286a2002410c6a41086a2902003702000c060b200c2003103e000b1039000b20044101102a000b4100210a4100210d0b200aad422086200dad842109200b450d00200610290b20004101360200200041106a2001360200200041086a200937020020002008410874200741ff0171723602040b200241f080046a24000bf404010b7f230041c080016b220224002002200110f003410121030240024020022802004101470d0020002002290204370204200041013602002000410c6a2002410c6a2902003702000c010b20022802042104200241004180800110cd042105410021064100210702400240024002402004450d00410021084100210641012103410021090340024002402001280204220a200128020822076b200420096b220b41808001200b41808001491b220b490d002007200b6a220c2007490d04200a200c4f0d01200c200a107f000b200541013a008f8001200541b480016a4101360200200542013702a4800120054180c0c5003602a080012005411f3602bc80012005200541b880016a3602b0800120052005418f80016a3602b880012005419080016a200541a080016a10e6032005418b80016a2005419880016a2802003600002005200529039080013700838001200041053a00042000200529008080013700052000410c6a2005418780016a290000370000200041013602002006450d06200310290c060b2005200128020020076a200b10ce04210a2001200c36020802400240200620086b200b490d00200b20086a21070c010b2008200b6a22072008490d052006410174220c20072007200c491b220c4100480d050240024020060d00200c102721030c010b20032006200c102821030b2003450d04200c21060b200320086a200a200b10ce041a200721082004200b20096a22094b0d000b0b2000200336020420004100360200200041146a2007360200200041106a41003602002000410c6a2007360200200041086a20063602000c030b2007200c103e000b200c4101102a000b102b000b200241c080016a24000b0e0020003502004101200110aa010bf60201037f230041c0006b22022400200141086a2802002103200128020421042002200128020022013602100240024002402001418080044b0d0002402004450d0020022003360214200120034b0d022003418080044d0d002002413c6a41013602002002420237022c200241ec9cc5003602282002410136021c200241c89cc5003602182002200241186a3602382002200241286a10e6030c030b200241003602000c020b2002413c6a41013602002002420237022c200241cc9cc5003602282002410136021c200241c89cc5003602182002200241186a3602382002200241286a10e6030c010b200241246a41013602002002413c6a41023602002002420237022c200241dc9cc5003602282002410136021c2002200241186a3602382002200241106a3602202002200241146a3602182002200241286a10e6030b024002402002280200450d0020002002290300370200200041086a200241086a2802003602000c010b200041003602000b200241c0006a24000bf90501037f230041f0006b2204240002400240024002400240024020012802084102460d00412e10272201450d01200041013a0000200141266a41002900e09e45370000200141206a41002900da9e45370000200141186a41002900d29e45370000200141106a41002900ca9e45370000200141086a41002900c29e45370000200141002900ba9e45370000200041086a42ae808080e005370200200041046a20013602000c050b02400240024002400240200128020022052d0000416e6a2201411e4b0d004100210620010e1f03000000000000000000000000000000000000000000000000000008040102030b412010272201450d05200041013a0000200141186a41002900809f45370000200141106a41002900f89e45370000200141086a41002900f09e45370000200141002900e89e45370000200041086a42a08080808004370200200041046a20013602000c080b410221060c060b410321060c050b20042005280204220136020c0240024020012003490d0041889fc5002105200441e8006a2103200441d0006a2101200441c0006a21020c010b200220014101746a22012d0001450d0441989fc5002105200441386a2103200441206a2101200441106a21020b20034101360204200141146a410136020020012003360210200142023702042001200536020020032004410c6a3602002002200110e603200041013a00002000410c6a200241086a280200360200200041046a20022902003702000c050b410121060c030b412e4101102a000b41204101102a000b20012d000021060b0240200541106a2d00004106470d00200041003a0000200020063a00010c010b0240412910272201450d00200041013a0000200141286a41002d00d09f453a0000200141206a41002900c89f45370000200141186a41002900c09f45370000200141106a41002900b89f45370000200141086a41002900b09f45370000200141002900a89f45370000200041086a42a98080809005370200200041046a20013602000c010b41294101102a000b200441f0006a24000b8f0201017f230041106b220224000240024002400240024020002d00000e0401020300010b2002200128021841d0bfc50041032001411c6a28020028020c11050022003a000820022001360200200241003a0009200241003602040c030b2002200128021841d3bfc50041032001411c6a28020028020c11050022003a000820022001360200200241003a0009200241003602040c020b2002200128021841d6bfc50041032001411c6a28020028020c11050022003a000820022001360200200241003a0009200241003602040c010b2002200128021841d9bfc50041032001411c6a28020028020c11050022003a000820022001360200200241003a0009200241003602040b200241106a240020000bf7c30103077f027e027f230041f0006b2203240002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024020022d00000eac0100df010102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f80018101820183018401850186018701880189018a018b018c018d018e018f0190019101920193019401950196019701980199019a019b019c019d019e019f01a001a101a201a301a401a501a601a701a801a901aa01000b02400240200141306a2802002202417f6a220420024f0d00200420024d0d010b411810272200450dab012003421837025c20032000360258200341d8006a4100411810fe0320032003280260220041186a3602602000200328025822016a411841f6a1c500411810ff032003200329025c37025c20032001360258418697c500413b200341d8006a41c497c50010a201000b02400240200128022820044103746a22052802002206200141206a28020022024b0d002006200220062002491b21040c010b024002402001411c6a280200220420026b200620026b2207490d0020012802182108200221040c010b200220076a22082002490dde0120044101742209200820082009491b22094100480dde010240024020040d002009102721080c010b200128021820042009102821080b2008450dad01200120083602182001411c6a2009360200200141206a28020021040b200820046a21090240024020074102490d002009410420062002417f736a220210cd041a2008200220046a22046a21090c010b2007450d010b200941043a0000200441016a21040b200141206a2004360200200541013a00060cde010b0240200141306a2802002204200141346a22062802004f0d002002310001210a200141206a350200210b024020042001412c6a280200470d00200441016a22022004490ddd0120044101742206200220022006491b220241ffffffff01712002470ddd01200241037422064100480ddd010240024020040d002006102721040c010b200128022820044103742006102821040b2004450dad01200120043602282001412c6a2002360200200141306a28020021040b200128022820044103746a200a422886200b84370200200141306a2201200128020041016a3602000cde010b200341ec006a220141013602002003420137025c200341f0a2c500360258200341013602042003200636020020032003360268200341106a200341d8006a10e60320032802102202450ddd012003200329021437021420032002360210200141013602002003420137025c200341b89cc50036025820034121360204200320033602682003200341106a360200200341386a200341d8006a10e60302402003280214450d00200328021010290b20032802382201450ddd012000200329023c370204200020013602000cde010b0240200141306a2802002204200141346a22062802004f0d002002310001210a200141206a350200210b024020042001412c6a280200470d00200441016a22022004490ddc0120044101742206200220022006491b220241ffffffff01712002470ddc01200241037422064100480ddc010240024020040d002006102721040c010b200128022820044103742006102821040b2004450dad01200120043602282001412c6a2002360200200141306a28020021040b200128022820044103746a200a422886200b8442808080803084370200200141306a2201200128020041016a3602000cdd010b200341ec006a220141013602002003420137025c200341f0a2c500360258200341013602042003200636020020032003360268200341106a200341d8006a10e60320032802102202450ddc012003200329021437021420032002360210200141013602002003420137025c200341b89cc50036025820034121360204200320033602682003200341106a360200200341386a200341d8006a10e60302402003280214450d00200328021010290b20032802382201450ddc012000200329023c370204200020013602000cdd010b2002310001210a200341d8006a200141186a200141286a22044100108004024020032d00584101470d002000200329025c370200200041086a200341e4006a2802003602000cdd010b0240200141306a2802002202200141346a22062802004f0d00200141206a350200210b024020022001412c6a280200470d00200241016a22062002490ddb0120024101742205200620062005491b220641ffffffff01712006470ddb01200641037422054100480ddb010240024020020d002005102721020c010b200428020020024103742005102821020b2002450dad01200120023602282001412c6a2006360200200141306a28020021020b200128022820024103746a200a422886200b8442808080801084370200200141306a2201200128020041016a3602000cdc010b200341ec006a220141013602002003420137025c200341f0a2c500360258200341013602042003200636020020032003360268200341106a200341d8006a10e60320032802102202450ddb012003200329021437021420032002360210200141013602002003420137025c200341b89cc50036025820034121360204200320033602682003200341106a360200200341386a200341d8006a10e60302402003280214450d00200328021010290b20032802382201450ddb012000200329023c370204200020013602000cdc010b02400240200141306a2802002202417f6a220420024f0d00200420024d0d010b411810272200450dac012003421837025c20032000360258200341d8006a4100411810fe0320032003280260220041186a3602602000200328025822016a411841f6a1c500411810ff032003200329025c37025c2003200136025841d497c5004134200341d8006a41c497c50010a201000b02400240200141286a220228020020044103746a22042d00044101470d002004310005210a200341d8006a200141186a20021081042003280258450d0120002003290358370200200041086a200341d8006a41086a2802003602000cdd010b411a10272201450dad01200141186a41002f00a098453b0000200141106a41002900989845370000200141086a410029009098453700002001410029008898453700002000429a808080a003370204200020013602000cdc010b0240200141306a2802002204200141346a22062802004f0d00200141206a350200210b024020042001412c6a280200470d00200441016a22062004490dda0120044101742205200620062005491b220641ffffffff01712006470dda01200641037422054100480dda010240024020040d002005102721020c010b200228020020044103742005102821020b2002450daf01200120023602282001412c6a2006360200200141306a28020021040b200128022820044103746a200a422886200b8442808080802084370200200141306a2201200128020041016a3602000cdb010b200341ec006a220141013602002003420137025c200341f0a2c500360258200341013602042003200636020020032003360268200341106a200341d8006a10e60320032802102202450dda012003200329021437021420032002360210200141013602002003420137025c200341b89cc50036025820034121360204200320033602682003200341106a360200200341386a200341d8006a10e60302402003280214450d00200328021010290b20032802382201450dda012000200329023c370204200020013602000cdb010b02400240200141306a2802002202417f6a220420024f0d00200420024d0d010b411810272200450dae012003421837025c20032000360258200341d8006a4100411810fe0320032003280260220041186a3602602000200328025822016a411841f6a1c500411810ff032003200329025c37025c2003200136025841d497c5004134200341d8006a41c497c50010a201000b200141286a220528020020044103746a22042d00052106024020042d00044101470d00200641ff01714104470daf010b0240024020024101460d00200341d8006a200141186a220220051081042003280258450d0120002003290358370200200041086a200341d8006a41086a2802003602000cdc010b20012d003822024104460dd901200341d8006a200141186a2206200520021080040240024020032d00584101460d000240200141206a2802002204200141246a22082802004f0d00024020042001411c6a280200470d00200441016a22082004490ddc0120044101742207200820082007491b22084100480ddc010240024020040d002008102721040c010b200628020020042008102821040b2004450db401200120043602182001411c6a2008360200200141206a28020021040b200128021820046a20023a0000200141206a2202200228020041016a3602000cdc010b200341ec006a220241013602002003420137025c200341f0a2c500360258200341013602042003200836020020032003360268200341106a200341d8006a10e60320032802102204450ddb012003200329021437021420032004360210200241013602002003420137025c200341b89cc50036025820034121360204200320033602682003200341106a360200200341386a200341d8006a10e60302402003280214450d00200328021010290b20032802382202450ddb01200329023c210a0c010b200328025c2202450dda01200341e0006a290300210a0b2000200a370204200020023602000cdb010b200641ff01714104460dd9010240200141206a2802002204200141246a22052802004f0d00024020042001411c6a280200470d00200441016a22052004490dd90120044101742208200520052008491b22054100480dd9010240024020040d002005102721020c010b200228020020042005102821020b2002450db201200120023602182001411c6a2005360200200141206a28020021040b200128021820046a20063a0000200141206a2201200128020041016a3602000cda010b200341ec006a220141013602002003420137025c200341f0a2c500360258200341013602042003200536020020032003360268200341106a200341d8006a10e60320032802102202450dd9012003200329021437021420032002360210200141013602002003420137025c200341b89cc50036025820034121360204200320033602682003200341106a360200200341386a200341d8006a10e60302402003280214450d00200328021010290b20032802382201450dd9012000200329023c370204200020013602000cda010b2003200241046a280200220236024802400240200141306a280200220420024d0d0020042002417f736a22022004490d0141d2a2c500411d104e000b200341ec006a220241023602002003411c6a41013602002003420237025c20034190a2c50036025820034101360214200320043602002003200341106a360268200320033602182003200341c8006a360210200341386a200341d8006a10e603200328023821042003200329023c37021420032004360210200241013602002003420137025c200341b89cc50036025820034121360204200320033602682003200341106a360200200341386a200341d8006a10e6032003280214450dd101200328021010290cd1010b200141286a220428020020024103746a22022d00044103460dd10120022d0005220241ff01714104460dd101200341d8006a200141186a220620042002108004024020032d00584101460d000240200141206a2802002204200141246a22052802004f0d00024020042001411c6a280200470d00200441016a22052004490dd90120044101742208200520052008491b22054100480dd9010240024020040d002005102721040c010b200628020020042005102821040b2004450db301200120043602182001411c6a2005360200200141206a28020021040b200128021820046a20023a0000200141206a2202200228020041016a3602000cd3010b200341ec006a220241013602002003420137025c200341f0a2c500360258200341013602042003200536020020032003360268200341106a200341d8006a10e60320032802102204450dd2012003200329021437021420032004360210200241013602002003420137025c200341b89cc50036025820034121360204200320033602682003200341106a360200200341386a200341d8006a10e6032003280214450dd101200328021010290cd1010b200328025c2202450dd101200341e0006a290300210a0cd2010b200241046a2802002102200341d8006a200141186a2205200141286a220641001080040240024020032d00584101470d00200341e0006a290300210a200328025c22010d010cd9010b200141306a28020021042003200236024802400240200420024d0d0020042002417f736a22022004490d0141d2a2c500411d104e000b200341ec006a220141023602002003411c6a41013602002003420237025c20034190a2c50036025820034101360214200320043602002003200341106a360268200320033602182003200341c8006a360210200341386a200341d8006a10e603200328023821022003200329023c37021420032002360210200141013602002003420137025c200341b89cc50036025820034121360204200320033602682003200341106a360200200341386a200341d8006a10e60302402003280214450d00200328021010290b200329023c210a200328023822010d010cd9010b200628020020024103746a22022d00044103460dd80120022d0005220241ff01714104460dd801200341d8006a200520062002108004024020032d00584101460d000240200141206a2802002204200141246a22062802004f0d00024020042001411c6a280200470d00200441016a22062004490dd90120044101742208200620062008491b22064100480dd9010240024020040d002006102721040c010b200528020020042006102821040b2004450db401200120043602182001411c6a2006360200200141206a28020021040b200128021820046a20023a0000200141206a2201200128020041016a3602000cda010b200341ec006a220141013602002003420137025c200341f0a2c500360258200341013602042003200636020020032003360268200341106a200341d8006a10e60320032802102202450dd9012003200329021437021420032002360210200141013602002003420137025c200341b89cc50036025820034121360204200320033602682003200341106a360200200341386a200341d8006a10e60302402003280214450d00200328021010290b20032802382201450dd901200329023c210a0c010b200328025c2201450dd801200341e0006a290300210a0b2000200a370204200020013602000cd8010b200241086a2802002105200241046a280200210420032002410c6a280200220636024802400240200141306a280200220220064d0d0020022006417f736a22062002490d0141d2a2c500411d104e000b200341ec006a22044102360200200341106a410c6a41013602002003420237025c20034190a2c50036025820034101360214200320023602002003200341106a360268200320033602182003200341c8006a360210200341386a200341d8006a10e603200328023821022003200329023c37021420032002360210200441013602002003420137025c200341b89cc50036025820034121360204200320033602682003200341106a360200200341386a200341d8006a10e60302402003280214450d00200328021010290b2003200329023c370204200320032802383602000ccd010b410421090240200141286a220c280200220820064103746a22062d00044103460d0020062d000521090b200320093a00302005450dc801200941ff0171220d4104460dc701200541027421050340200320042802002206360248200220064d0dca0120022006417f736a220620024f0dce01200820064103746a22062d00044103460dcb0120062d000522074104460dcb01200d2007470dcb01200441046a21042005417c6a22050d000cc9010b0b20012d003822024104460dc501200341d8006a200141186a2206200141286a20021080040240024020032d00584101460d000240200141206a2802002204200141246a22052802004f0d00024020042001411c6a280200470d00200441016a22052004490dd70120044101742208200520052008491b22054100480dd7010240024020040d002005102721040c010b200628020020042005102821040b2004450db301200120043602182001411c6a2005360200200141206a28020021040b200128021820046a20023a0000200141206a2202200228020041016a3602000cc8010b200341ec006a220241013602002003420137025c200341f0a2c500360258200341013602042003200536020020032003360268200341106a200341d8006a10e60320032802102204450dc7012003200329021437021420032004360210200241013602002003420137025c200341b89cc50036025820034121360204200320033602682003200341106a360200200341386a200341d8006a10e60302402003280214450d00200328021010290b20032802382202450dc701200329023c210a0c010b200328025c2202450dc601200341e0006a290300210a0b2000200a370204200020023602000cd6010b200128020021042003200241046a2802002202360254024002400240200441386a28020020024b0d00200341ec006a41013602002003420237025c200341d8a0c500360258200341013602342003200341306a3602682003200341d4006a360230200341386a200341d8006a10e603200341186a200329023c370300200341013602102003200328023822043602140c010b2003200428023020024102746a2802002202360200024002402004412c6a28020020024b0d0041012106200341ec006a41013602002003420237025c200341e8a0c5003602582003410136024c2003200341c8006a36026820032003360248200341386a200341d8006a10e603200341186a200329023c220a370300200a422088a7210820032802382104200aa721020c010b2003411c6a200428022420024104746a22042d000d22083a0000200341186a2004280208220236020020042802002104410021060b20032006360210200320043602142006450d010b200341186a21010cc3010b02402002450d002004417f6a2104200141286a2106200141186a21050340200341d8006a20052006200420026a2d0000108004024020032d00584101470d00200341e0006a2101200328025c21040cc5010b2002417f6a22020d000b0b200841ff01714104460dd4010240200141206a2802002202200141246a22042802004f0d00024020022001411c6a280200470d00200241016a22042002490dd40120024101742206200420042006491b22044100480dd4010240024020020d002004102721020c010b200128021820022004102821020b2002450db101200120023602182001411c6a2004360200200141206a28020021020b200128021820026a20083a0000200141206a2201200128020041016a3602000cd5010b200341ec006a220141013602002003420137025c200341f0a2c500360258200341013602042003200436020020032003360268200341106a200341d8006a10e60320032802102202450dd4012003200329021437021420032002360210200141013602002003420137025c200341b89cc50036025820034121360204200320033602682003200341106a360200200341386a200341d8006a10e60302402003280214450d00200328021010290b20032802382204450dd401200329023c210a0cc3010b200241046a28020021052001280200210220034100360238024002400240200241146a2802000d00200341d8006a41146a41013602002003420237025c200341b8a0c50036025820034101360204200320033602682003200341386a360200200341106a200341d8006a10e6030c010b200341d8006a200141186a2204200141286a22064100108004024020032d00584101470d00200341e0006a290300210a0cc2010b20012802002208412c6a280200210220032005360238200220054b0d01200341ec006a41013602002003420237025c200341e8a0c50036025820034101360204200320033602682003200341386a360200200341106a200341d8006a10e6030b2003290214210a200328021022010dc1010cd4010b200828022420054104746a22052d000d2108024020052802082202450d002005280200417f6a21050340200341d8006a20042006200520026a2d0000108004024020032d00584101470d00200341e0006a290300210a0cc2010b2002417f6a22020d000b0b200841ff01714104460dd3010240200141206a2802002202200141246a22062802004f0d00024020022001411c6a280200470d00200241016a22062002490dd30120024101742205200620062005491b22064100480dd3010240024020020d002006102721020c010b200428020020022006102821020b2002450db101200120023602182001411c6a2006360200200141206a28020021020b200128021820026a20083a0000200141206a2201200128020041016a3602000cd4010b200341ec006a220141013602002003420137025c200341f0a2c500360258200341013602042003200636020020032003360268200341106a200341d8006a10e60320032802102202450dd3012003200329021437021420032002360210200141013602002003420137025c200341b89cc50036025820034121360204200320033602682003200341106a360200200341386a200341d8006a10e60302402003280214450d00200328021010290b20032802382201450dd301200329023c210a0cc0010b200341d8006a200141186a200141286a410410800420032d00584101470dd201200328025c2201450dd2012000200341e0006a290300370204200020013602000cd3010b200341d8006a200141186a2204200141286a22064100108004200341d8006a21020240024020032d00584101460d00200341d8006a200420064104108004200341d8006a210220032d00584101460d00200341d8006a2004200620032d00592205108004200341d8006a210220032d00584101460d000240200141206a2802002202200141246a22062802004f0d00024020022001411c6a280200470d00200241016a22062002490dd30120024101742208200620062008491b22064100480dd3010240024020020d002006102721020c010b200428020020022006102821020b2002450db201200120023602182001411c6a2006360200200141206a28020021020b200128021820026a20053a0000200141206a2201200128020041016a3602000cd4010b200341ec006a220141013602002003420137025c200341f0a2c500360258200341013602042003200636020020032003360268200341106a200341d8006a10e60320032802102202450dd3012003200329021437021420032002360210200141013602002003420137025c200341b89cc50036025820034121360204200320033602682003200341106a360200200341386a200341d8006a10e60302402003280214450d00200328021010290b20032802382201450dd301200329023c210a0c010b200241046a2802002201450dd201200241086a290200210a0b2000200a370204200020013602000cd2010b200341d8006a200141046a200241046a2802001082040240024020032d00584101460d000240200141206a2802002202200141246a22042802004f0d0020032d00592104024020022001411c6a280200470d00200241016a22062002490dd20120024101742205200620062005491b22064100480dd2010240024020020d002006102721020c010b200128021820022006102821020b2002450db201200120023602182001411c6a2006360200200141206a28020021020b200128021820026a20043a0000200141206a2201200128020041016a3602000cd3010b200341ec006a220141013602002003420137025c200341f0a2c500360258200341013602042003200436020020032003360268200341106a200341d8006a10e60320032802102202450dd2012003200329021437021420032002360210200141013602002003420137025c200341b89cc50036025820034121360204200320033602682003200341106a360200200341386a200341d8006a10e60302402003280214450d00200328021010290b20032802382201450dd201200329023c210a0c010b200328025c2201450dd101200341e0006a290300210a0b2000200a370204200020013602000cd1010b2003200241046a2802002202360200200341d8006a200141046a2002108204024020032d00584101470d002003200328025c22013602382003200341e0006a290300220a37023c0cbb010b200320032d005922023a0030200341d8006a200141186a200141286a4104108004024020032d00584101470d00200341c0006a200341e4006a2802003602002003200329025c3703380cba010b200320032d005922013a004820014104460dcf01200241ff01712001460dcf01200341106a41146a41253602002003411c6a4120360200200341d8006a41146a41033602002003420337025c200341c498c500360258200341013602142003200341106a3602682003200341c8006a3602202003200341306a36021820032003360210200341386a200341d8006a10e6030cb9010b200341d8006a200141046a200241046a2802001082040240024020032d00584101460d00200341d8006a200141186a2206200141286a20032d00592204108004024020032d00584101460d000240200141206a2802002202200141246a22052802004f0d00024020022001411c6a280200470d00200241016a22052002490dd10120024101742208200520052008491b22054100480dd1010240024020020d002005102721020c010b200628020020022005102821020b2002450db201200120023602182001411c6a2005360200200141206a28020021020b200128021820026a20043a0000200141206a2201200128020041016a3602000cd2010b200341ec006a220141013602002003420137025c200341f0a2c500360258200341013602042003200536020020032003360268200341106a200341d8006a10e60320032802102202450dd1012003200329021437021420032002360210200141013602002003420137025c200341b89cc50036025820034121360204200320033602682003200341106a360200200341386a200341d8006a10e60302402003280214450d00200328021010290b20032802382201450dd101200329023c210a0c020b200328025c2201450dd001200341e0006a290300210a0c010b200328025c2201450dcf01200341e0006a290300210a0b2000200a370204200020013602000ccf010b200128020021042003200241046a280200220236023802400240200441206a28020020024d0d000240200141206a2802002206200141246a22052802004f0d00200428021820024101746a2d00002102024020062001411c6a280200470d00200641016a22042006490dcf0120064101742205200420042005491b22044100480dcf010240024020060d002004102721060c010b200128021820062004102821060b2006450db101200120063602182001411c6a2004360200200141206a28020021060b200128021820066a20023a0000200141206a2201200128020041016a3602000cd0010b200341ec006a220141013602002003420137025c200341f0a2c500360258200341013602042003200536020020032003360268200341106a200341d8006a10e60320032802102202450dcf012003200329021437021420032002360210200141013602002003420137025c200341b89cc50036025820034121360204200320033602682003200341106a360200200341386a200341d8006a10e60302402003280214450d00200328021010290b20032802382201450dcf01200329023c210a0c010b200341ec006a41013602002003420237025c20034188a1c5003602582003410136024c2003200341c8006a3602682003200341386a360248200341106a200341d8006a10e60320032802102201450dce012003290214210a0b2000200a370204200020013602000cce010b2003200241046a28020022023602282001280200210420032002360254024002400240200441206a28020020024b0d00200341ec006a41013602002003420237025c20034188a1c5003602582003410136024c2003200341c8006a3602682003200341d4006a360248200341106a200341d8006a10e6030c010b200428021820024101746a22022d00010d01200341ec006a41013602002003420237025c20034198a1c50036025820034101360204200320033602682003200341d4006a360200200341106a200341d8006a10e6030b2003280210210120032003290214220a37023c200320013602380cb6010b200320022d000022023a002f200341d8006a200141186a200141286a4104108004024020032d00584101470d00200341c0006a200341e4006a2802003602002003200329025c3703380cb5010b200320032d005922013a00002001200241ff0171460dcc0120014104460dcc01200341106a41146a41253602002003411c6a4125360200200341d8006a41146a41033602002003420337025c200341dc98c500360258200341013602142003200341106a3602682003200336022020032003412f6a3602182003200341286a360210200341386a200341d8006a10e6030cb4010b200341d8006a2001200241046a280200410441001084042003280258450dcb0120002003290358370200200041086a200341d8006a41086a2802003602000ccc010b200341d8006a2001200241046a280200410841011084042003280258450dca0120002003290358370200200041086a200341d8006a41086a2802003602000ccb010b200341d8006a2001200241046a280200410441021084042003280258450dc90120002003290358370200200041086a200341d8006a41086a2802003602000cca010b200341d8006a2001200241046a280200410841031084042003280258450dc80120002003290358370200200041086a200341d8006a41086a2802003602000cc9010b200341d8006a2001200241046a280200410141001084042003280258450dc70120002003290358370200200041086a200341d8006a41086a2802003602000cc8010b200341d8006a2001200241046a280200410141001084042003280258450dc60120002003290358370200200041086a200341d8006a41086a2802003602000cc7010b200341d8006a2001200241046a280200410241001084042003280258450dc50120002003290358370200200041086a200341d8006a41086a2802003602000cc6010b200341d8006a2001200241046a280200410241001084042003280258450dc40120002003290358370200200041086a200341d8006a41086a2802003602000cc5010b200341d8006a2001200241046a280200410141011084042003280258450dc30120002003290358370200200041086a200341d8006a41086a2802003602000cc4010b200341d8006a2001200241046a280200410141011084042003280258450dc20120002003290358370200200041086a200341d8006a41086a2802003602000cc3010b200341d8006a2001200241046a280200410241011084042003280258450dc10120002003290358370200200041086a200341d8006a41086a2802003602000cc2010b200341d8006a2001200241046a280200410241011084042003280258450dc00120002003290358370200200041086a200341d8006a41086a2802003602000cc1010b200341d8006a2001200241046a280200410441011084042003280258450dbf0120002003290358370200200041086a200341d8006a41086a2802003602000cc0010b200341d8006a2001200241046a280200410441011084042003280258450dbe0120002003290358370200200041086a200341d8006a41086a2802003602000cbf010b200341d8006a2001200241046a280200410441001085042003280258450dbd0120002003290358370200200041086a200341d8006a41086a2802003602000cbe010b200341d8006a2001200241046a280200410841011085042003280258450dbc0120002003290358370200200041086a200341d8006a41086a2802003602000cbd010b200341d8006a2001200241046a280200410441021085042003280258450dbb0120002003290358370200200041086a200341d8006a41086a2802003602000cbc010b200341d8006a2001200241046a280200410841031085042003280258450dba0120002003290358370200200041086a200341d8006a41086a2802003602000cbb010b200341d8006a2001200241046a280200410141001085042003280258450db90120002003290358370200200041086a200341d8006a41086a2802003602000cba010b200341d8006a2001200241046a280200410241001085042003280258450db80120002003290358370200200041086a200341d8006a41086a2802003602000cb9010b200341d8006a2001200241046a280200410141011085042003280258450db70120002003290358370200200041086a200341d8006a41086a2802003602000cb8010b200341d8006a2001200241046a280200410241011085042003280258450db60120002003290358370200200041086a200341d8006a41086a2802003602000cb7010b200341d8006a2001200241046a280200410441011085042003280258450db50120002003290358370200200041086a200341d8006a41086a2802003602000cb6010b20012802002102200341003602380240024020022802080d00200341ec006a41013602002003420237025c20034188a0c50036025820034101360204200320033602682003200341386a360200200341106a200341d8006a10e60320032802102202450d002003290214210a0c010b0240200141206a2802002202200141246a22042802004f0d00024020022001411c6a280200470d00200241016a22042002490db50120024101742206200420042006491b22044100480db5010240024020020d002004102721020c010b200128021820022004102821020b2002450d9801200120023602182001411c6a2004360200200141206a28020021020b200128021820026a41003a0000200141206a2201200128020041016a3602000cb6010b200341ec006a220141013602002003420137025c200341f0a2c500360258200341013602042003200436020020032003360268200341106a200341d8006a10e60320032802102202450db5012003200329021437021420032002360210200141013602002003420137025c200341b89cc50036025820034121360204200320033602682003200341106a360200200341386a200341d8006a10e60302402003280214450d00200328021010290b20032802382202450db501200329023c210a0b2000200a370204200020023602000cb5010b20012802002102200341003602380240024020022802080d00200341ec006a41013602002003420237025c20034188a0c50036025820034101360204200320033602682003200341386a360200200341106a200341d8006a10e60320032802102202450d002003290214210a0c010b200341d8006a200141186a2204200141286a4100108004024020032d00584101460d000240200141206a2802002202200141246a22062802004f0d00024020022001411c6a280200470d00200241016a22062002490db50120024101742205200620062005491b22064100480db5010240024020020d002006102721020c010b200428020020022006102821020b2002450d9901200120023602182001411c6a2006360200200141206a28020021020b200128021820026a41003a0000200141206a2201200128020041016a3602000cb6010b200341ec006a220141013602002003420137025c200341f0a2c500360258200341013602042003200636020020032003360268200341106a200341d8006a10e60320032802102202450db5012003200329021437021420032002360210200141013602002003420137025c200341b89cc50036025820034121360204200320033602682003200341106a360200200341386a200341d8006a10e60302402003280214450d00200328021010290b20032802382202450db501200329023c210a0c010b200328025c2202450db401200341e0006a290300210a0b2000200a370204200020023602000cb4010b0240200141206a2802002202200141246a22042802004f0d00024020022001411c6a280200470d00200241016a22042002490db20120024101742206200420042006491b22044100480db2010240024020020d002004102721020c010b200128021820022004102821020b2002450d9701200120023602182001411c6a2004360200200141206a28020021020b200128021820026a41003a0000200141206a2201200128020041016a3602000cb3010b200341ec006a220141013602002003420137025c200341f0a2c500360258200341013602042003200436020020032003360268200341106a200341d8006a10e60320032802102202450db2012003200329021437021420032002360210200141013602002003420137025c200341b89cc50036025820034121360204200320033602682003200341106a360200200341386a200341d8006a10e60302402003280214450d00200328021010290b20032802382201450db2012000200329023c370204200020013602000cb3010b0240200141206a2802002202200141246a22042802004f0d00024020022001411c6a280200470d00200241016a22042002490db10120024101742206200420042006491b22044100480db1010240024020020d002004102721020c010b200128021820022004102821020b2002450d9701200120023602182001411c6a2004360200200141206a28020021020b200128021820026a41013a0000200141206a2201200128020041016a3602000cb2010b200341ec006a220141013602002003420137025c200341f0a2c500360258200341013602042003200436020020032003360268200341106a200341d8006a10e60320032802102202450db1012003200329021437021420032002360210200141013602002003420137025c200341b89cc50036025820034121360204200320033602682003200341106a360200200341386a200341d8006a10e60302402003280214450d00200328021010290b20032802382201450db1012000200329023c370204200020013602000cb2010b0240200141206a2802002202200141246a22042802004f0d00024020022001411c6a280200470d00200241016a22042002490db00120024101742206200420042006491b22044100480db0010240024020020d002004102721020c010b200128021820022004102821020b2002450d9701200120023602182001411c6a2004360200200141206a28020021020b200128021820026a41023a0000200141206a2201200128020041016a3602000cb1010b200341ec006a220141013602002003420137025c200341f0a2c500360258200341013602042003200436020020032003360268200341106a200341d8006a10e60320032802102202450db0012003200329021437021420032002360210200141013602002003420137025c200341b89cc50036025820034121360204200320033602682003200341106a360200200341386a200341d8006a10e60302402003280214450d00200328021010290b20032802382201450db0012000200329023c370204200020013602000cb1010b0240200141206a2802002202200141246a22042802004f0d00024020022001411c6a280200470d00200241016a22042002490daf0120024101742206200420042006491b22044100480daf010240024020020d002004102721020c010b200128021820022004102821020b2002450d9701200120023602182001411c6a2004360200200141206a28020021020b200128021820026a41033a0000200141206a2201200128020041016a3602000cb0010b200341ec006a220141013602002003420137025c200341f0a2c500360258200341013602042003200436020020032003360268200341106a200341d8006a10e60320032802102202450daf012003200329021437021420032002360210200141013602002003420137025c200341b89cc50036025820034121360204200320033602682003200341106a360200200341386a200341d8006a10e60302402003280214450d00200328021010290b20032802382201450daf012000200329023c370204200020013602000cb0010b200341d8006a200141001086042003280258450dae0120002003290358370200200041086a200341d8006a41086a2802003602000caf010b200341d8006a200141001087042003280258450dad0120002003290358370200200041086a200341d8006a41086a2802003602000cae010b200341d8006a200141001087042003280258450dac0120002003290358370200200041086a200341d8006a41086a2802003602000cad010b200341d8006a200141001087042003280258450dab0120002003290358370200200041086a200341d8006a41086a2802003602000cac010b200341d8006a200141001087042003280258450daa0120002003290358370200200041086a200341d8006a41086a2802003602000cab010b200341d8006a200141001087042003280258450da90120002003290358370200200041086a200341d8006a41086a2802003602000caa010b200341d8006a200141001087042003280258450da80120002003290358370200200041086a200341d8006a41086a2802003602000ca9010b200341d8006a200141001087042003280258450da70120002003290358370200200041086a200341d8006a41086a2802003602000ca8010b200341d8006a200141001087042003280258450da60120002003290358370200200041086a200341d8006a41086a2802003602000ca7010b200341d8006a200141001087042003280258450da50120002003290358370200200041086a200341d8006a41086a2802003602000ca6010b200341d8006a200141001087042003280258450da40120002003290358370200200041086a200341d8006a41086a2802003602000ca5010b200341d8006a200141011086042003280258450da30120002003290358370200200041086a200341d8006a41086a2802003602000ca4010b200341d8006a200141011087042003280258450da20120002003290358370200200041086a200341d8006a41086a2802003602000ca3010b200341d8006a200141011087042003280258450da10120002003290358370200200041086a200341d8006a41086a2802003602000ca2010b200341d8006a200141011087042003280258450da00120002003290358370200200041086a200341d8006a41086a2802003602000ca1010b200341d8006a200141011087042003280258450d9f0120002003290358370200200041086a200341d8006a41086a2802003602000ca0010b200341d8006a200141011087042003280258450d9e0120002003290358370200200041086a200341d8006a41086a2802003602000c9f010b200341d8006a200141011087042003280258450d9d0120002003290358370200200041086a200341d8006a41086a2802003602000c9e010b200341d8006a200141011087042003280258450d9c0120002003290358370200200041086a200341d8006a41086a2802003602000c9d010b200341d8006a200141011087042003280258450d9b0120002003290358370200200041086a200341d8006a41086a2802003602000c9c010b200341d8006a200141011087042003280258450d9a0120002003290358370200200041086a200341d8006a41086a2802003602000c9b010b200341d8006a200141011087042003280258450d990120002003290358370200200041086a200341d8006a41086a2802003602000c9a010b200341d8006a200141021087042003280258450d980120002003290358370200200041086a200341d8006a41086a2802003602000c99010b200341d8006a200141021087042003280258450d970120002003290358370200200041086a200341d8006a41086a2802003602000c98010b200341d8006a200141021087042003280258450d960120002003290358370200200041086a200341d8006a41086a2802003602000c97010b200341d8006a200141021087042003280258450d950120002003290358370200200041086a200341d8006a41086a2802003602000c96010b200341d8006a200141021087042003280258450d940120002003290358370200200041086a200341d8006a41086a2802003602000c95010b200341d8006a200141021087042003280258450d930120002003290358370200200041086a200341d8006a41086a2802003602000c94010b200341d8006a200141031087042003280258450d920120002003290358370200200041086a200341d8006a41086a2802003602000c93010b200341d8006a200141031087042003280258450d910120002003290358370200200041086a200341d8006a41086a2802003602000c92010b200341d8006a200141031087042003280258450d900120002003290358370200200041086a200341d8006a41086a2802003602000c91010b200341d8006a200141031087042003280258450d8f0120002003290358370200200041086a200341d8006a41086a2802003602000c90010b200341d8006a200141031087042003280258450d8e0120002003290358370200200041086a200341d8006a41086a2802003602000c8f010b200341d8006a200141031087042003280258450d8d0120002003290358370200200041086a200341d8006a41086a2802003602000c8e010b200341d8006a200141001088042003280258450d8c0120002003290358370200200041086a200341d8006a41086a2802003602000c8d010b200341d8006a200141001088042003280258450d8b0120002003290358370200200041086a200341d8006a41086a2802003602000c8c010b200341d8006a200141001088042003280258450d8a0120002003290358370200200041086a200341d8006a41086a2802003602000c8b010b200341d8006a200141001089042003280258450d890120002003290358370200200041086a200341d8006a41086a2802003602000c8a010b200341d8006a200141001089042003280258450d880120002003290358370200200041086a200341d8006a41086a2802003602000c89010b200341d8006a200141001089042003280258450d870120002003290358370200200041086a200341d8006a41086a2802003602000c88010b200341d8006a200141001089042003280258450d860120002003290358370200200041086a200341d8006a41086a2802003602000c87010b200341d8006a200141001089042003280258450d850120002003290358370200200041086a200341d8006a41086a2802003602000c86010b200341d8006a200141001089042003280258450d840120002003290358370200200041086a200341d8006a41086a2802003602000c85010b200341d8006a200141001089042003280258450d830120002003290358370200200041086a200341d8006a41086a2802003602000c84010b200341d8006a200141001089042003280258450d820120002003290358370200200041086a200341d8006a41086a2802003602000c83010b200341d8006a200141001089042003280258450d810120002003290358370200200041086a200341d8006a41086a2802003602000c82010b200341d8006a200141001089042003280258450d800120002003290358370200200041086a200341d8006a41086a2802003602000c81010b200341d8006a200141001089042003280258450d7f20002003290358370200200041086a200341d8006a41086a2802003602000c80010b200341d8006a200141001089042003280258450d7e20002003290358370200200041086a200341d8006a41086a2802003602000c7f0b200341d8006a200141001089042003280258450d7d20002003290358370200200041086a200341d8006a41086a2802003602000c7e0b200341d8006a200141001089042003280258450d7c20002003290358370200200041086a200341d8006a41086a2802003602000c7d0b200341d8006a200141001089042003280258450d7b20002003290358370200200041086a200341d8006a41086a2802003602000c7c0b200341d8006a200141011088042003280258450d7a20002003290358370200200041086a200341d8006a41086a2802003602000c7b0b200341d8006a200141011088042003280258450d7920002003290358370200200041086a200341d8006a41086a2802003602000c7a0b200341d8006a200141011088042003280258450d7820002003290358370200200041086a200341d8006a41086a2802003602000c790b200341d8006a200141011089042003280258450d7720002003290358370200200041086a200341d8006a41086a2802003602000c780b200341d8006a200141011089042003280258450d7620002003290358370200200041086a200341d8006a41086a2802003602000c770b200341d8006a200141011089042003280258450d7520002003290358370200200041086a200341d8006a41086a2802003602000c760b200341d8006a200141011089042003280258450d7420002003290358370200200041086a200341d8006a41086a2802003602000c750b200341d8006a200141011089042003280258450d7320002003290358370200200041086a200341d8006a41086a2802003602000c740b200341d8006a200141011089042003280258450d7220002003290358370200200041086a200341d8006a41086a2802003602000c730b200341d8006a200141011089042003280258450d7120002003290358370200200041086a200341d8006a41086a2802003602000c720b200341d8006a200141011089042003280258450d7020002003290358370200200041086a200341d8006a41086a2802003602000c710b200341d8006a200141011089042003280258450d6f20002003290358370200200041086a200341d8006a41086a2802003602000c700b200341d8006a200141011089042003280258450d6e20002003290358370200200041086a200341d8006a41086a2802003602000c6f0b200341d8006a200141011089042003280258450d6d20002003290358370200200041086a200341d8006a41086a2802003602000c6e0b200341d8006a200141011089042003280258450d6c20002003290358370200200041086a200341d8006a41086a2802003602000c6d0b200341d8006a200141011089042003280258450d6b20002003290358370200200041086a200341d8006a41086a2802003602000c6c0b200341d8006a200141011089042003280258450d6a20002003290358370200200041086a200341d8006a41086a2802003602000c6b0b200341d8006a200141011089042003280258450d6920002003290358370200200041086a200341d8006a41086a2802003602000c6a0b200341d8006a200141021088042003280258450d6820002003290358370200200041086a200341d8006a41086a2802003602000c690b200341d8006a200141021088042003280258450d6720002003290358370200200041086a200341d8006a41086a2802003602000c680b200341d8006a200141021088042003280258450d6620002003290358370200200041086a200341d8006a41086a2802003602000c670b200341d8006a200141021088042003280258450d6520002003290358370200200041086a200341d8006a41086a2802003602000c660b200341d8006a200141021088042003280258450d6420002003290358370200200041086a200341d8006a41086a2802003602000c650b200341d8006a200141021088042003280258450d6320002003290358370200200041086a200341d8006a41086a2802003602000c640b200341d8006a200141021088042003280258450d6220002003290358370200200041086a200341d8006a41086a2802003602000c630b200341d8006a200141021089042003280258450d6120002003290358370200200041086a200341d8006a41086a2802003602000c620b200341d8006a200141021089042003280258450d6020002003290358370200200041086a200341d8006a41086a2802003602000c610b200341d8006a200141021089042003280258450d5f20002003290358370200200041086a200341d8006a41086a2802003602000c600b200341d8006a200141021089042003280258450d5e20002003290358370200200041086a200341d8006a41086a2802003602000c5f0b200341d8006a200141021089042003280258450d5d20002003290358370200200041086a200341d8006a41086a2802003602000c5e0b200341d8006a200141021089042003280258450d5c20002003290358370200200041086a200341d8006a41086a2802003602000c5d0b200341d8006a200141021089042003280258450d5b20002003290358370200200041086a200341d8006a41086a2802003602000c5c0b200341d8006a200141031088042003280258450d5a20002003290358370200200041086a200341d8006a41086a2802003602000c5b0b200341d8006a200141031088042003280258450d5920002003290358370200200041086a200341d8006a41086a2802003602000c5a0b200341d8006a200141031088042003280258450d5820002003290358370200200041086a200341d8006a41086a2802003602000c590b200341d8006a200141031088042003280258450d5720002003290358370200200041086a200341d8006a41086a2802003602000c580b200341d8006a200141031088042003280258450d5620002003290358370200200041086a200341d8006a41086a2802003602000c570b200341d8006a200141031088042003280258450d5520002003290358370200200041086a200341d8006a41086a2802003602000c560b200341d8006a200141031088042003280258450d5420002003290358370200200041086a200341d8006a41086a2802003602000c550b200341d8006a200141031089042003280258450d5320002003290358370200200041086a200341d8006a41086a2802003602000c540b200341d8006a200141031089042003280258450d5220002003290358370200200041086a200341d8006a41086a2802003602000c530b200341d8006a200141031089042003280258450d5120002003290358370200200041086a200341d8006a41086a2802003602000c520b200341d8006a200141031089042003280258450d5020002003290358370200200041086a200341d8006a41086a2802003602000c510b200341d8006a200141031089042003280258450d4f20002003290358370200200041086a200341d8006a41086a2802003602000c500b200341d8006a200141031089042003280258450d4e20002003290358370200200041086a200341d8006a41086a2802003602000c4f0b200341d8006a200141031089042003280258450d4d20002003290358370200200041086a200341d8006a41086a2802003602000c4e0b200341d8006a200141014100108a042003280258450d4c20002003290358370200200041086a200341d8006a41086a2802003602000c4d0b200341d8006a200141024100108a042003280258450d4b20002003290358370200200041086a200341d8006a41086a2802003602000c4c0b200341d8006a200141024100108a042003280258450d4a20002003290358370200200041086a200341d8006a41086a2802003602000c4b0b200341d8006a200141034100108a042003280258450d4920002003290358370200200041086a200341d8006a41086a2802003602000c4a0b200341d8006a200141034100108a042003280258450d4820002003290358370200200041086a200341d8006a41086a2802003602000c490b200341d8006a200141004101108a042003280258450d4720002003290358370200200041086a200341d8006a41086a2802003602000c480b200341d8006a200141004101108a042003280258450d4620002003290358370200200041086a200341d8006a41086a2802003602000c470b200341d8006a200141024101108a042003280258450d4520002003290358370200200041086a200341d8006a41086a2802003602000c460b200341d8006a200141024101108a042003280258450d4420002003290358370200200041086a200341d8006a41086a2802003602000c450b200341d8006a200141034101108a042003280258450d4320002003290358370200200041086a200341d8006a41086a2802003602000c440b200341d8006a200141034101108a042003280258450d4220002003290358370200200041086a200341d8006a41086a2802003602000c430b200341d8006a200141004102108a042003280258450d4120002003290358370200200041086a200341d8006a41086a2802003602000c420b200341d8006a200141004102108a042003280258450d4020002003290358370200200041086a200341d8006a41086a2802003602000c410b200341d8006a200141014102108a042003280258450d3f20002003290358370200200041086a200341d8006a41086a2802003602000c400b200341d8006a200141014102108a042003280258450d3e20002003290358370200200041086a200341d8006a41086a2802003602000c3f0b200341d8006a200141034102108a042003280258450d3d20002003290358370200200041086a200341d8006a41086a2802003602000c3e0b200341d8006a200141004103108a042003280258450d3c20002003290358370200200041086a200341d8006a41086a2802003602000c3d0b200341d8006a200141004103108a042003280258450d3b20002003290358370200200041086a200341d8006a41086a2802003602000c3c0b200341d8006a200141014103108a042003280258450d3a20002003290358370200200041086a200341d8006a41086a2802003602000c3b0b200341d8006a200141014103108a042003280258450d3920002003290358370200200041086a200341d8006a41086a2802003602000c3a0b200341d8006a200141024103108a042003280258450d3820002003290358370200200041086a200341d8006a41086a2802003602000c390b200341d8006a200141024100108a042003280258450d3720002003290358370200200041086a200341d8006a41086a2802003602000c380b200341d8006a200141034101108a042003280258450d3620002003290358370200200041086a200341d8006a41086a2802003602000c370b200341d8006a200141004102108a042003280258450d3520002003290358370200200041086a200341d8006a41086a2802003602000c360b200341d8006a200141014103108a0420032802580d1b0c340b41184101102a000b20094101102a000b20064104102a000b20064104102a000b20054104102a000b41184101102a000b411a4101102a000b20054104102a000b41184101102a000b200341ec006a41013602002003420237025c200341a498c5003602582003412636023c2003200441056a3602382003200341386a360268200341106a200341d8006a10e603200041086a200341106a41086a280200360200200020032903103702000c2b0b20084101102a000b20054101102a000b20054101102a000b20064101102a000b20054101102a000b20044101102a000b20064101102a000b20064101102a000b20064101102a000b20054101102a000b20044101102a000b20044101102a000b20064101102a000b20044101102a000b20044101102a000b20044101102a000b20044101102a000b20002003290358370200200041086a200341d8006a41086a2802003602000c190b200329023c210a200328023821010b2001450d162000200a370204200020013602000c170b200329023c210a200328023821010b2001450d142000200a370204200020013602000c150b200328025c2201450d130b2000200a370204200020013602000c130b2004450d112001290200210a0b2000200a370204200020043602000c110b0240024002400240200141306a2802002202417f6a220420024f0d00200420024d0d010b411810272200450d012003421837025c20032000360258200341d8006a4100411810fe0320032003280260220041186a3602602000200328025822016a411841f6a1c500411810ff032003200329025c37025c20032001360258418697c500413b200341d8006a41c497c50010a201000b02400240200128022820044103746a22052802002206200141206a28020022024b0d002006200220062002491b21040c010b024002402001411c6a280200220420026b200620026b2207490d0020012802182108200221040c010b200220076a22082002490d1120044101742209200820082009491b22094100480d110240024020040d002009102721080c010b200128021820042009102821080b2008450d03200120083602182001411c6a2009360200200141206a28020021040b200820046a21090240024020074102490d002009410420062002417f736a220210cd041a2008200220046a22046a21090c010b2007450d010b200941043a0000200441016a21040b200141206a2004360200200541013a00060c110b41184101102a000b20094101102a000b200541027421050340200320042802002206360248200220064d0d0220022006417f736a220620024f0d060240200820064103746a22062d00044103460d0020062d00054104470d040b200441046a21042005417c6a22050d000b410421090b200341d8006a200141186a2202200c410010800420032d00584101470d02200341086a200341e4006a2802003602002003200329025c3703000c030b200341ec006a220441023602002003411c6a41013602002003420237025c20034190a2c50036025820034101360214200320023602002003200341106a360268200320033602182003200341c8006a360210200341386a200341d8006a10e603200328023821022003200329023c37021420032002360210200441013602002003420137025c200341b89cc50036025820034121360204200320033602682003200341106a360200200341386a200341d8006a10e60302402003280214450d00200328021010290b2003200329023c370204200320032802383602000c020b2003411c6a4126360200200341ec006a41023602002003420237025c200341b498c5003602582003200641056a360218200341263602142003200341106a3602682003200341306a3602102003200341d8006a10e6030c010b0240200941ff01714104460d00200341d8006a2002200c200910800402400240024020032d00584101460d000240200141206a2802002204200141246a22062802004f0d00024020042001411c6a280200470d00200441016a22062004490d0e20044101742205200620062005491b22064100480d0e0240024020040d002006102721020c010b200228020020042006102821020b2002450d04200120023602182001411c6a2006360200200141206a28020021040b200128021820046a20093a0000200141206a2202200228020041016a3602000c040b200341ec006a220241013602002003420137025c200341f0a2c500360258200341013602042003200636020020032003360268200341106a200341d8006a10e60320032802102204450d032003200329021437021420032004360210200241013602002003420137025c200341b89cc50036025820034121360204200320033602682003200341106a360200200341386a200341d8006a10e60302402003280214450d00200328021010290b20032802382202450d03200329023c210a0c010b200328025c2202450d02200341e0006a290300210a0b2003200a370204200320023602000c020b20064101102a000b200341003602000b024020032802002202450d0020002003290204370204200020023602000c0b0b0240024002400240200141306a2802002202417f6a220420024f0d00200420024d0d010b411810272200450d012003421837025c20032000360258200341d8006a4100411810fe0320032003280260220041186a3602602000200328025822016a411841f6a1c500411810ff032003200329025c37025c20032001360258418697c500413b200341d8006a41c497c50010a201000b02400240200128022820044103746a22052802002206200141206a28020022024b0d002006200220062002491b21040c010b024002402001411c6a280200220420026b200620026b2207490d0020012802182108200221040c010b200220076a22082002490d0b20044101742209200820082009491b22094100480d0b0240024020040d002009102721080c010b200128021820042009102821080b2008450d03200120083602182001411c6a2009360200200141206a28020021040b200820046a21090240024020074102490d002009410420062002417f736a220210cd041a2008200220046a22046a21090c010b2007450d010b200941043a0000200441016a21040b200141206a2004360200200541013a00060c0b0b41184101102a000b20094101102a000b41d2a2c500411d104e000b20032802382202450d00200329023c210a0c010b0240200141306a2802002202417f6a220420024f0d00200420024d0d020b411810272200450d022003421837025c20032000360258200341d8006a4100411810fe0320032003280260220041186a3602602000200328025822016a411841f6a1c500411810ff032003200329025c37025c20032001360258418697c500413b200341d8006a41c497c50010a201000b2000200a370204200020023602000c060b02400240200128022820044103746a22052802002206200141206a28020022024b0d002006200220062002491b21040c010b024002402001411c6a280200220420026b200620026b2207490d0020012802182108200221040c010b200220076a22082002490d0420044101742209200820082009491b22094100480d040240024020040d002009102721080c010b200128021820042009102821080b2008450d03200120083602182001411c6a2009360200200141206a28020021040b200820046a21090240024020074102490d002009410420062002417f736a220210cd041a2008200220046a22046a21090c010b2007450d010b200941043a0000200441016a21040b200141206a2004360200200541013a00060c040b41184101102a000b20094101102a000b102b000b200341d8006a200141186a20051081042003280258450d0020002003290358370200200041086a200341d8006a41086a2802003602000c010b200041003602000b200341f0006a24000b6501017f230041206b2202240020024127360204200220003602002001411c6a2802002100200128021821012002411c6a41013602002002420137020c2002419c81c6003602082002200236021820012000200241086a1091042101200241206a240020010b0c00200028020020011093040bcd0201067f02400240024002402001450d0020014108490d010240200141ffffffff01712001470d00200141037441076e21010c030b41f495c5001058000b200041106a4200370200200041086a4280808080c000370200200041046a418c96c5003602000c020b200141016a21010b02400240417f2001417f6a6776220141016a220241ffffffff01712002470d00200141086a417c712203200141056a2204490d00200320024103746a22052003490d002005417d4f0d00200510272206450d012001200241037641076c20014108491b2107200641ff01200410cd04220520036a21030240200241034b0d00200520026a418001410320016b10cd041a0b200041146a2007360200200041106a41003602002000410c6a2003360200200041086a2001360200200041046a20053602000c020b41f495c5001058000b20054104102a000b200041003a00000b970d02117f017e230041206b220124000240024002400240200028020c220241016a22032002490d00200041046a28020022022104024020024108490d00200241016a41037641076c21040b024020032004410176490d00200141086a200310fb0320012d00084101460d042001411c6a2802002105200141146a2802002106200141106a2802002107200128020c210820002802002209280200417f7341808182847871210a200041046a28020020096a41016a210b2000280208210c200028020c210d03400240024002400240200a0d00200941046a210203402002200b4f0d02200c41206a210c20022802002103200241046a220421022003418081828478712203418081828478460d000b200341808182847873210a2004417c6a21090b200c200a684138716a220e280200210f410021030240200e28020422104104490d0041002103200f2102201021040340200228000020034105777341b9f3ddf1796c2103200241046a21022004417c6a220441034b0d000b2010417c6a22022002417c7122026b21102002200f6a41046a210f0b201041014b0d01200f21020c020b2000200d36020c2000200636020820002005200d6b3602102000280200210420002008360200200041046a22032802002102200320073602002002450d070240200241016a220341ffffffff01712003470d00200241086a417c712208200241056a490d00200820034103746a2008491a0b200410290c070b200f41026a21022010417e6a21102003410577200f2f00007341b9f3ddf1796c21030b02402010450d00200341057720022d00007341b9f3ddf1796c21030b200a417f6a210f41002102200341057741ff017341b9f3ddf1796c221121030340200241046a2202200320077122046a2103200820046a280000418081828478712210450d000b0240200820106841037620046a20077122026a2c00004100480d002008280200418081828478716841037621020b200f200a71210a200820026a201141197622033a00002002417c6a20077120086a41046a20033a0000200620024103746a200e2902003702000c000b0b200241016a21044100210341002102024003400240024020034101710d00200220044f0d0320022103200241016a21020c010b200241036a220320024922080d0220032004492207450d022004200241046a20081b200420071b21020b200028020020036a220320032802002203410776417f73418182840871200341fffefdfb07726a360200410121030c000b0b20002802002102200041046a220428020041016a220341044f0d01200241046a2002200310cf041a2004280200220220002802006a41016a418001410320026b10cd041a0c020b41f495c5001058000b200220036a20022800003600000b417f210202400240200041046a2211280200220341016a220f2003490d00200041086a21064100210b0340200b220c41016a210b0240200c20002802006a2d0000418001470d00024003402006280200200c4103746a220e2802002107410021030240200e28020422084104490d004100210320072102200821040340200228000020034105777341b9f3ddf1796c2103200241046a21022004417c6a220441034b0d000b2008417c6a22022002417c7122026b2108200220076a41046a21070b02400240200841014b0d00200721020c010b200741026a21022008417e6a2108200341057720072f00007341b9f3ddf1796c21030b02402008450d00200341057720022d00007341b9f3ddf1796c21030b201128020021082000280200210741002102200341057741ff017341b9f3ddf1796c220a21030340200241046a2202200320087122046a2103200720046a280000418081828478712210450d000b0240200720106841037620046a20087122026a2c00004100480d002007280200418081828478716841037621020b2002200a20087122036b200c20036b732008714104490d01200720026a22032d000021042003200a41197622103a00002002417c6a20087120076a41046a20103a00000240200441ff01460d00200628020020024103746a220229020021122002200e290200370200200e20123702000c010b0b20002802002203200c6a41ff013a000020032011280200200c417c6a716a41046a41ff013a0000200628020020024103746a200e2902003702000c010b2007200c6a200a41197622023a00002008200c417c6a7120076a41046a20023a00000b200b200f470d000b200041046a28020022024108490d010b200241016a41037641076c21020b20002002200028020c6b3602100b200141206a24000b19002000200141186a280200360204200020012802103602000b810101017f024002400240200041046a280200220320016b20024f0d00200120026a22022001490d0220034101742201200220022001491b22014100480d020240024020030d002001102721020c010b200028020020032001102821020b2002450d0120002002360200200041046a20013602000b0f0b20014101102a000b102b000bea0101017f230041e0006b22042400200420013602082004200336020c024020012003470d0020002002200110ce041a200441e0006a24000f0b200441286a41146a4103360200200441346a411d360200200441106a41146a41033602002004200441086a36024020042004410c6a360244200441c8006a41146a41003602002004420337021420044190d1c5003602102004411d36022c200441b8d6c5003602582004420137024c200441e4d1c5003602482004200441286a3602202004200441c8006a3602382004200441c4006a3602302004200441c0006a360228200441106a41a0d2c5001057000bbc0601037f230041d0006b22042400200420033a000f0240024002400240024020022802082205417f6a220620054f0d00200620054d0d010b411810272202450d012004421837023420042002360230200441306a4100411810fe0320042004280238220241186a3602382002200428023022056a411841f6a1c500411810ff03200420042902343702342004200536023041d497c5004134200441306a41c497c50010a201000b200141086a2802002105200228020020064103746a2206280200210202400240024020062d0006450d0020052002460d010b024002400240200520024d0d00200141086a2005417f6a2202360200200128020020026a2d00002205417c6a220241014b0d02024020020e020400040b4118102722020d0141184101102a000b412b10272202450d05200041013a0000200241276a41002800f29b45360000200241206a41002900eb9b45370000200241186a41002900e39b45370000200241106a41002900db9b45370000200241086a41002900d39b45370000200241002900cb9b45370000200041086a42ab808080b005370200200041046a20023602000c060b200241106a4100290086a245370000200241086a41002900fea145370000200241002900f6a14537000020044298808080800337022420042002360220200441c4006a410136020020044201370234200441b89cc5003602302004412136024c2004200441c8006a3602402004200441206a360248200441106a200441306a10e60302402004280224450d00200428022010290b200041013a0000200041046a20042903103702002000410c6a200441106a41086a2802003602000c050b0240200341ff017122024104460d0020052002470d020b200041003a0000200020053a00010c040b20004180083b01000c030b200420053a0048200441c4006a4102360200200441206a410c6a412536020020044202370234200441f89bc500360230200441253602242004200441206a3602402004200441c8006a36022820042004410f6a360220200441106a200441306a10e6032000410c6a200441186a280200360200200041046a2004290310370200200041013a00000c020b41184101102a000b412b4101102a000b200441d0006a24000bc00502047f017e230041d0006b22032400024002400240024002400240200241086a2802002204417f6a220520044f0d00200520044d0d010b411810272202450d01200241106a4100290086a245370000200241086a41002900fea145370000200241002900f6a14537000020034298808080800337022420032002360220200341cc006a41013602002003420137023c200341b89cc500360238200341213602142003200341106a3602482003200341206a3602102000200341386a10e6032003280224450d04200328022010290c040b0240024002402002280200220620054103746a2d000522054104460d00200341386a200120022005108004024020032d00384101470d002000200329023c370200200041086a200341c4006a2802003602000c070b200241086a2802002204450d01200228020021060b200241086a2004417f6a2202360200200620024103746a290200220742808080808080c0ff0083428080808080808001520d010b411810272202450d02200241106a4100290086a245370000200241086a41002900fea145370000200241002900f6a14537000020034298808080800337022420032002360220200341cc006a41013602002003420137023c200341b89cc500360238200341213602142003200341106a3602482003200341206a3602102000200341386a10e6032003280224450d04200328022010290c040b200141086a28020021022003200737030820022007a7470d02200041003602000c030b41184101102a000b41184101102a000b200341cc006a41023602002003412c6a41013602002003420237023c200341989bc50036023820034101360224200320023602342003200341206a3602482003200341086a3602282003200341346a360220200341106a200341386a10e603200041086a200341106a41086a280200360200200020032903103702000b200341d0006a24000bad0301057f230041c0006b2203240020032002360200024002402001280204220420024b0d002001280208417c6a21052001410c6a280200410374210102400340024020010d00200320043602042003412c6a4102360200200341306a410c6a41013602002003420337021c200341c0a3c500360218200341013602342003200341306a3602282003200341046a36023820032003360230200341086a200341186a10e6032000410c6a200341106a280200360200200041046a2003290308370200200041013a00000c040b02402004200541046a2802006a220620044f0d00412010272204450d02200041013a0000200441186a41002900b8a345370000200441106a41002900b0a345370000200441086a41002900a8a345370000200441002900a0a345370000200041086a42a08080808004370200200041046a20043602000c040b200141786a2101200541086a2105200420024b21072006210420070d0020062104200620024d0d000b20052d00002104200041003a0000200020043a00010c020b41204101102a000b200041003a00002000200128020020026a2d00003a00010b200341c0006a24000bbe0201037f230041106b220224000240024020002d00004104470d002002200128021841f499c50041032001411c6a28020028020c11050022003a000820022001360200200241003a0009200241003602040c010b2002200128021841f799c50041082001411c6a28020028020c1105003a000820022001360200200241003a0009200241003602042002200036020c20022002410c6a41809ac500108c04210120022d0008210020022802042203450d00200041ff0171210441012100024020040d00024020034101470d0020012d0009450d00200128020022042d00004104710d0041012100200428021841b682c60041012004411c6a28020028020c1105000d010b2001280200220028021841b782c60041012000411c6a28020028020c11050021000b200120003a00080b200241106a2400200041ff01714100470b820601037f230041d0006b22052400200520023602082005200336020c024002400240417f41012002411f71742002411f4b1b20034b0d00200541386a200141186a2203200141286a410010800420052d00384101470d012000200529023c370200200041086a200541c4006a2802003602000c020b200541cc006a41023602002005411c6a41013602002005420337023c200541f498c500360238200541013602142005200541106a36024820052005410c6a3602182005200541086a360210200541206a200541386a10e603200041086a200541206a41086a280200360200200020052903203702000c010b2001280200210220054100360220024020022802080d00200541cc006a41013602002005420237023c20054188a0c500360238200541013602342005200541306a3602482005200541206a360230200541106a200541386a10e60320052802102202450d0020002005290214370204200020023602000c010b0240024002400240200141206a2802002202200141246a22062802004f0d00024020022001411c6a280200470d00200241016a22062002490d0320024101742207200620062007491b22064100480d030240024020020d002006102721020c010b200328020020022006102821020b2002450d02200120023602182001411c6a2006360200200141206a28020021020b200128021820026a20043a0000200141206a2202200228020041016a3602000c030b200541cc006a220241013602002005420137023c200541f0a2c50036023820054101360234200520063602302005200541306a360248200541106a200541386a10e60320052802102201450d022005200529021437021420052001360210200241013602002005420137023c200541b89cc500360238200541213602342005200541306a3602482005200541106a360230200541206a200541386a10e60302402005280214450d00200528021010290b20052802202202450d0220002005290224370204200020023602000c030b20064101102a000b102b000b200041003602000b200541d0006a24000bb00301017f230041d0006b22052400200520023602082005200336020c024002400240417f41012002411f71742002411f4b1b20034b0d00200128020021022005410036023420022802080d01200541cc006a41013602002005420237023c20054188a0c500360238200541013602142005200541106a3602482005200541346a360210200541206a200541386a10e60320052802202202450d0120002005290224370204200020023602000c020b200541cc006a41023602002005412c6a41013602002005420337023c200541f498c500360238200541013602242005200541206a36024820052005410c6a3602282005200541086a360220200541106a200541386a10e603200041086a200541106a41086a280200360200200020052903103702000c010b200541386a200141186a2202200141286a22032004108004024020052d00384101470d002000200529023c370200200041086a200541c4006a2802003602000c010b200541386a200220034100108004024020052d00384101470d002000200529023c370200200041086a200541c4006a2802003602000c010b200041003602000b200541d0006a24000be70301047f230041c0006b22032400200341286a200141186a2204200141286a20021080040240024020032d00284101470d002000200329022c370200200041086a200341346a2802003602000c010b0240024002400240200141206a2802002202200141246a22052802004f0d00024020022001411c6a280200470d00200241016a22052002490d0320024101742206200520052006491b22054100480d030240024020020d002005102721020c010b200428020020022005102821020b2002450d02200120023602182001411c6a2005360200200141206a28020021020b200128021820026a41003a0000200141206a2201200128020041016a3602000c030b2003413c6a220141013602002003420137022c200341f0a2c50036022820034101360214200320053602102003200341106a360238200341186a200341286a10e60320032802182202450d022003200329021c37021c20032002360218200141013602002003420137022c200341b89cc500360228200341213602142003200341106a3602382003200341186a3602102003200341286a10e6030240200328021c450d00200328021810290b20032802002201450d0220002003290204370204200020013602000c030b20054101102a000b102b000b200041003602000b200341c0006a24000ba00401047f230041c0006b22032400200341286a200141186a2204200141286a220520021080040240024020032d00284101470d002000200329022c370200200041086a200341346a2802003602000c010b200341286a200420052002108004024020032d00284101470d002000200329022c370200200041086a200341346a2802003602000c010b0240024002400240200141206a2802002202200141246a22052802004f0d00024020022001411c6a280200470d00200241016a22052002490d0320024101742206200520052006491b22054100480d030240024020020d002005102721020c010b200428020020022005102821020b2002450d02200120023602182001411c6a2005360200200141206a28020021020b200128021820026a41003a0000200141206a2201200128020041016a3602000c030b2003413c6a220141013602002003420137022c200341f0a2c50036022820034101360214200320053602102003200341106a360238200341186a200341286a10e60320032802182202450d022003200329021c37021c20032002360218200141013602002003420137022c200341b89cc500360228200341213602142003200341106a3602382003200341186a3602102003200341286a10e6030240200328021c450d00200328021810290b20032802002201450d0220002003290204370204200020013602000c030b20054101102a000b102b000b200041003602000b200341c0006a24000be70301057f230041c0006b22032400200341286a200141186a2204200141286a20021080040240024020032d00284101470d002000200329022c370200200041086a200341346a2802003602000c010b0240024002400240200141206a2802002205200141246a22062802004f0d00024020052001411c6a280200470d00200541016a22062005490d0320054101742207200620062007491b22064100480d030240024020050d002006102721050c010b200428020020052006102821050b2005450d02200120053602182001411c6a2006360200200141206a28020021050b200128021820056a20023a0000200141206a2201200128020041016a3602000c030b2003413c6a220141013602002003420137022c200341f0a2c50036022820034101360214200320063602102003200341106a360238200341186a200341286a10e60320032802182202450d022003200329021c37021c20032002360218200141013602002003420137022c200341b89cc500360228200341213602142003200341106a3602382003200341186a3602102003200341286a10e6030240200328021c450d00200328021810290b20032802002201450d0220002003290204370204200020013602000c030b20064101102a000b102b000b200041003602000b200341c0006a24000ba00401057f230041c0006b22032400200341286a200141186a2204200141286a220520021080040240024020032d00284101470d002000200329022c370200200041086a200341346a2802003602000c010b200341286a200420052002108004024020032d00284101470d002000200329022c370200200041086a200341346a2802003602000c010b0240024002400240200141206a2802002205200141246a22062802004f0d00024020052001411c6a280200470d00200541016a22062005490d0320054101742207200620062007491b22064100480d030240024020050d002006102721040c010b200428020020052006102821040b2004450d02200120043602182001411c6a2006360200200141206a28020021050b200128021820056a20023a0000200141206a2201200128020041016a3602000c030b2003413c6a220141013602002003420137022c200341f0a2c50036022820034101360214200320063602102003200341106a360238200341186a200341286a10e60320032802182202450d022003200329021c37021c20032002360218200141013602002003420137022c200341b89cc500360228200341213602142003200341106a3602382003200341186a3602102003200341286a10e6030240200328021c450d00200328021810290b20032802002201450d0220002003290204370204200020013602000c030b20064101102a000b102b000b200041003602000b200341c0006a24000be70301047f230041c0006b22042400200441286a200141186a2205200141286a20021080040240024020042d00284101470d002000200429022c370200200041086a200441346a2802003602000c010b0240024002400240200141206a2802002202200141246a22062802004f0d00024020022001411c6a280200470d00200241016a22062002490d0320024101742207200620062007491b22064100480d030240024020020d002006102721020c010b200528020020022006102821020b2002450d02200120023602182001411c6a2006360200200141206a28020021020b200128021820026a20033a0000200141206a2201200128020041016a3602000c030b2004413c6a220141013602002004420137022c200441f0a2c50036022820044101360214200420063602102004200441106a360238200441186a200441286a10e60320042802182202450d022004200429021c37021c20042002360218200141013602002004420137022c200441b89cc500360228200441213602142004200441106a3602382004200441186a3602102004200441286a10e6030240200428021c450d00200428021810290b20042802002201450d0220002004290204370204200020013602000c030b20064101102a000b102b000b200041003602000b200441c0006a24000bc10201037f230041206b220224000240024020002d00004104470d002002200128021841b2bfc50041082001411c6a28020028020c11050022003a001820022001360210200241003a0019200241003602140c010b2002200128021841babfc50041052001411c6a28020028020c1105003a001820022001360210200241003a0019200241003602142002200036020c200241106a2002410c6a41c0bfc500108c04210120022d0018210020022802142203450d00200041ff0171210441012100024020040d00024020034101470d0020012d0009450d00200128020022042d00004104710d0041012100200428021841b682c60041012004411c6a28020028020c1105000d010b2001280200220028021841b782c60041012000411c6a28020028020c11050021000b200120003a00080b200241206a2400200041ff01714100470bf30202047f057e230041d0006b2203240041012104024020002d00080d00200028020421050240200028020022062d00004104710d0041012104200628021841f481c60041b382c60020051b4102410120051b2006411c6a28020028020c1105000d0120012000280200200228020c11040021040c010b024020050d0041012104200628021841b482c60041022006411c6a28020028020c1105000d01200028020021060b41012104200341013a00172003200341176a3602102006290208210720062902102108200341346a41fc81c60036020020032006290218370308200629022021092006290228210a200320062d00303a00482006290200210b2003200a3703402003200937033820032008370328200320073703202003200b3703182003200341086a3602302001200341186a200228020c1104000d002003280230419482c6004102200328023428020c11050021040b200020043a00082000200028020441016a360204200341d0006a240020000b17000240200041046a280200450d00200028020010290b0b0c002000280200200110f7030b160020002802002200280200200028020820011082010b110020012000280200200028020810e9030bbd0801087f230041c0006b22032400200341246a2001360200200341346a200241146a2802002204360200200341033a00382003412c6a2002280210220520044103746a36020020034280808080800437030820032000360220410021062003410036021820034100360210200320053602302003200536022802400240024002400240200228020822070d0020022802002108200228020422092004200420094b1b220a450d0141012104200020082802002008280204200128020c1105000d04200841086a210241012106034002402005280200200341086a200541046a280200110400450d00410121040c060b2006200a4f0d02200241046a210020022802002101200541086a2105200241086a210241012104200641016a2106200328022020012000280200200328022428020c110500450d000c050b0b20022802002108200228020422092002410c6a2802002205200520094b1b220a450d0041012104200020082802002008280204200128020c1105000d03200741106a2105200841086a21024101210603402003200541786a28020036020c2003200541106a2d00003a003820032005417c6a28020036020841002101410021040240024002400240200541086a2802000e0400010203000b2005410c6a2802002100410121040c020b02402005410c6a2802002207200328023422044f0d0041002104200328023020074103746a22072802044128470d0220072802002802002100410121040c020b41f8dbc500200720041037000b4100210420032802282207200328022c460d002003200741086a3602284100210420072802044128470d0020072802002802002100410121040b2003200036021420032004360210024002400240024002400240024020052802000e0404010006040b20032802282200200328022c470d010c050b200541046a2802002200200328023422044f0d01200328023020004103746a22002802044128470d04200028020028020021040c030b2003200041086a36022820002802044128470d03200028020028020021040c020b41f8dbc500200020041037000b200541046a28020021040b410121010b2003200436021c2003200136021802400240200541706a2802004101460d0020032802282204200328022c460d042003200441086a3602280c010b200541746a2802002204200328023422004f0d04200328023020044103746a21040b02402004280200200341086a200441046a280200110400450d00410121040c050b2006200a4f0d01200241046a210020022802002101200541246a2105200241086a210241012104200641016a2106200328022020012000280200200328022428020c110500450d000c040b0b0240200920064d0d00410121042003280220200820064103746a22052802002005280204200328022428020c1105000d030b410021040c020b41c8dac5001058000b4188dcc500200420001037000b200341c0006a240020040bfc0101027f230041106b220224002002200128021841bb82c60041052001411c6a28020028020c1105003a000820022001360200200241003a0009200241003602042002200036020c20022002410c6a4190a3c500108c041a20022d00082101024020022802042203450d00200141ff0171210041012101024020000d00024020034101470d0020022d000941ff0171450d00200228020022002d00004104710d0041012101200028021841b682c60041012000411c6a28020028020c1105000d010b2002280200220128021841b782c60041012001411c6a28020028020c11050021010b200220013a00080b200241106a2400200141ff01714100470ba46601037f230041206b220224000240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024020002d00000eac010102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f80018101820183018401850186018701880189018a018b018c018d018e018f0190019101920193019401950196019701980199019a019b019c019d019e019f01a001a101a201a301a401a501a601a701a801a901aa01ab0100010b200220012802184183b4c50041112001411c6a28020028020c1105003a001820022001360210200241003a001920024100360214200241106a21000cab010b200220012802184194b4c500410b2001411c6a28020028020c1105003a001820022001360210200241003a001920024100360214200241106a21000caa010b20022001280218419fb4c50041032001411c6a28020028020c1105003a001820022001360210200241003a001920024100360214200241106a21000ca9010b2002200128021841a2b4c50041052001411c6a28020028020c1105003a001820022001360210200241003a0019200241003602142002200041016a36020c200241106a2002410c6a41a8b4c500108c0421000ca8010b2002200128021841b8b4c50041042001411c6a28020028020c1105003a001820022001360210200241003a0019200241003602142002200041016a36020c200241106a2002410c6a41a8b4c500108c0421000ca7010b2002200128021841bcb4c50041022001411c6a28020028020c1105003a001820022001360210200241003a0019200241003602142002200041016a36020c200241106a2002410c6a41a8b4c500108c0421000ca6010b2002200128021841beb4c50041042001411c6a28020028020c1105003a001820022001360210200241003a001920024100360214200241106a21000ca5010b2002200128021841c2b4c50041032001411c6a28020028020c1105003a001820022001360210200241003a001920024100360214200241106a21000ca4010b2002200128021841c5b4c50041022001411c6a28020028020c1105003a001820022001360210200241003a0019200241003602142002200041046a36020c200241106a2002410c6a41c8b4c500108c0421000ca3010b2002200128021841d8b4c50041042001411c6a28020028020c1105003a001820022001360210200241003a0019200241003602142002200041046a36020c200241106a2002410c6a41c8b4c500108c0421000ca2010b2002200128021841dcb4c50041072001411c6a28020028020c1105003a001820022001360210200241003a0019200241003602142002200041046a36020c200241106a2002410c6a41e4b4c500108c04210120022000410c6a36020c20012002410c6a41c8b4c500108c0421000ca1010b2002200128021841f4b4c50041062001411c6a28020028020c1105003a001820022001360210200241003a001920024100360214200241106a21000ca0010b2002200128021841fab4c50041042001411c6a28020028020c1105003a001820022001360210200241003a0019200241003602142002200041046a36020c200241106a2002410c6a41c8b4c500108c0421000c9f010b2002200128021841feb4c500410c2001411c6a28020028020c1105003a001820022001360210200241003a0019200241003602142002200041046a36020c200241106a2002410c6a41c8b4c500108c0421012002200041016a36020c20012002410c6a418cb5c500108c0421000c9e010b20022001280218419cb5c50041042001411c6a28020028020c1105003a001820022001360210200241003a001920024100360214200241106a21000c9d010b2002200128021841a0b5c50041062001411c6a28020028020c1105003a001820022001360210200241003a001920024100360214200241106a21000c9c010b2002200128021841a6b5c50041082001411c6a28020028020c1105003a001820022001360210200241003a0019200241003602142002200041046a36020c200241106a2002410c6a41c8b4c500108c0421000c9b010b2002200128021841aeb5c50041082001411c6a28020028020c1105003a001820022001360210200241003a0019200241003602142002200041046a36020c200241106a2002410c6a41c8b4c500108c0421000c9a010b2002200128021841b6b5c50041082001411c6a28020028020c1105003a001820022001360210200241003a0019200241003602142002200041046a36020c200241106a2002410c6a41c8b4c500108c0421000c99010b2002200128021841beb5c50041092001411c6a28020028020c1105003a001820022001360210200241003a0019200241003602142002200041046a36020c200241106a2002410c6a41c8b4c500108c0421000c98010b2002200128021841c7b5c50041092001411c6a28020028020c1105003a001820022001360210200241003a0019200241003602142002200041046a36020c200241106a2002410c6a41c8b4c500108c0421000c97010b2002200128021841d0b5c50041072001411c6a28020028020c1105003a001820022001360210200241003a0019200241003602142002200041046a36020c200241106a2002410c6a41c8b4c500108c0421012002200041086a36020c20012002410c6a41c8b4c500108c0421000c96010b2002200128021841d7b5c50041072001411c6a28020028020c1105003a001820022001360210200241003a0019200241003602142002200041046a36020c200241106a2002410c6a41c8b4c500108c0421012002200041086a36020c20012002410c6a41c8b4c500108c0421000c95010b2002200128021841deb5c50041072001411c6a28020028020c1105003a001820022001360210200241003a0019200241003602142002200041046a36020c200241106a2002410c6a41c8b4c500108c0421012002200041086a36020c20012002410c6a41c8b4c500108c0421000c94010b2002200128021841e5b5c50041072001411c6a28020028020c1105003a001820022001360210200241003a0019200241003602142002200041046a36020c200241106a2002410c6a41c8b4c500108c0421012002200041086a36020c20012002410c6a41c8b4c500108c0421000c93010b2002200128021841ecb5c50041092001411c6a28020028020c1105003a001820022001360210200241003a0019200241003602142002200041046a36020c200241106a2002410c6a41c8b4c500108c0421012002200041086a36020c20012002410c6a41c8b4c500108c0421000c92010b2002200128021841f5b5c50041092001411c6a28020028020c1105003a001820022001360210200241003a0019200241003602142002200041046a36020c200241106a2002410c6a41c8b4c500108c0421012002200041086a36020c20012002410c6a41c8b4c500108c0421000c91010b2002200128021841feb5c500410a2001411c6a28020028020c1105003a001820022001360210200241003a0019200241003602142002200041046a36020c200241106a2002410c6a41c8b4c500108c0421012002200041086a36020c20012002410c6a41c8b4c500108c0421000c90010b200220012802184188b6c500410a2001411c6a28020028020c1105003a001820022001360210200241003a0019200241003602142002200041046a36020c200241106a2002410c6a41c8b4c500108c0421012002200041086a36020c20012002410c6a41c8b4c500108c0421000c8f010b200220012802184192b6c50041092001411c6a28020028020c1105003a001820022001360210200241003a0019200241003602142002200041046a36020c200241106a2002410c6a41c8b4c500108c0421012002200041086a36020c20012002410c6a41c8b4c500108c0421000c8e010b20022001280218419bb6c50041092001411c6a28020028020c1105003a001820022001360210200241003a0019200241003602142002200041046a36020c200241106a2002410c6a41c8b4c500108c0421012002200041086a36020c20012002410c6a41c8b4c500108c0421000c8d010b2002200128021841a4b6c500410a2001411c6a28020028020c1105003a001820022001360210200241003a0019200241003602142002200041046a36020c200241106a2002410c6a41c8b4c500108c0421012002200041086a36020c20012002410c6a41c8b4c500108c0421000c8c010b2002200128021841aeb6c500410a2001411c6a28020028020c1105003a001820022001360210200241003a0019200241003602142002200041046a36020c200241106a2002410c6a41c8b4c500108c0421012002200041086a36020c20012002410c6a41c8b4c500108c0421000c8b010b2002200128021841b8b6c500410a2001411c6a28020028020c1105003a001820022001360210200241003a0019200241003602142002200041046a36020c200241106a2002410c6a41c8b4c500108c0421012002200041086a36020c20012002410c6a41c8b4c500108c0421000c8a010b2002200128021841c2b6c500410a2001411c6a28020028020c1105003a001820022001360210200241003a0019200241003602142002200041046a36020c200241106a2002410c6a41c8b4c500108c0421012002200041086a36020c20012002410c6a41c8b4c500108c0421000c89010b2002200128021841ccb6c50041082001411c6a28020028020c1105003a001820022001360210200241003a0019200241003602142002200041046a36020c200241106a2002410c6a41c8b4c500108c0421012002200041086a36020c20012002410c6a41c8b4c500108c0421000c88010b2002200128021841d4b6c50041082001411c6a28020028020c1105003a001820022001360210200241003a0019200241003602142002200041046a36020c200241106a2002410c6a41c8b4c500108c0421012002200041086a36020c20012002410c6a41c8b4c500108c0421000c87010b2002200128021841dcb6c50041082001411c6a28020028020c1105003a001820022001360210200241003a0019200241003602142002200041046a36020c200241106a2002410c6a41c8b4c500108c0421012002200041086a36020c20012002410c6a41c8b4c500108c0421000c86010b2002200128021841e4b6c50041082001411c6a28020028020c1105003a001820022001360210200241003a0019200241003602142002200041046a36020c200241106a2002410c6a41c8b4c500108c0421012002200041086a36020c20012002410c6a41c8b4c500108c0421000c85010b2002200128021841ecb6c50041092001411c6a28020028020c1105003a001820022001360210200241003a0019200241003602142002200041046a36020c200241106a2002410c6a41c8b4c500108c0421012002200041086a36020c20012002410c6a41c8b4c500108c0421000c84010b2002200128021841f5b6c500410a2001411c6a28020028020c1105003a001820022001360210200241003a0019200241003602142002200041046a36020c200241106a2002410c6a41c8b4c500108c0421012002200041086a36020c20012002410c6a41c8b4c500108c0421000c83010b2002200128021841ffb6c50041092001411c6a28020028020c1105003a001820022001360210200241003a0019200241003602142002200041046a36020c200241106a2002410c6a41c8b4c500108c0421012002200041086a36020c20012002410c6a41c8b4c500108c0421000c82010b200220012802184188b7c500410a2001411c6a28020028020c1105003a001820022001360210200241003a0019200241003602142002200041046a36020c200241106a2002410c6a41c8b4c500108c0421012002200041086a36020c20012002410c6a41c8b4c500108c0421000c81010b200220012802184192b7c500410a2001411c6a28020028020c1105003a001820022001360210200241003a0019200241003602142002200041046a36020c200241106a2002410c6a41c8b4c500108c0421012002200041086a36020c20012002410c6a41c8b4c500108c0421000c80010b20022001280218419cb7c500410d2001411c6a28020028020c1105003a001820022001360210200241003a0019200241003602142002200041016a36020c200241106a2002410c6a418cb5c500108c0421000c7f0b2002200128021841a9b7c500410a2001411c6a28020028020c1105003a001820022001360210200241003a0019200241003602142002200041016a36020c200241106a2002410c6a418cb5c500108c0421000c7e0b2002200128021841b3b7c50041082001411c6a28020028020c1105003a001820022001360210200241003a0019200241003602142002200041046a36020c200241106a2002410c6a41bcb7c500108c0421000c7d0b2002200128021841ccb7c50041082001411c6a28020028020c1105003a001820022001360210200241003a0019200241003602142002200041086a36020c200241106a2002410c6a41d4b7c500108c0421000c7c0b2002200128021841e4b7c50041082001411c6a28020028020c1105003a001820022001360210200241003a0019200241003602142002200041046a36020c200241106a2002410c6a41c8b4c500108c0421000c7b0b2002200128021841ecb7c50041082001411c6a28020028020c1105003a001820022001360210200241003a0019200241003602142002200041086a36020c200241106a2002410c6a41f4b7c500108c0421000c7a0b200220012802184184b8c50041062001411c6a28020028020c1105003a001820022001360210200241003a001920024100360214200241106a21000c790b20022001280218418ab8c50041052001411c6a28020028020c1105003a001820022001360210200241003a001920024100360214200241106a21000c780b20022001280218418fb8c50041052001411c6a28020028020c1105003a001820022001360210200241003a001920024100360214200241106a21000c770b200220012802184194b8c50041062001411c6a28020028020c1105003a001820022001360210200241003a001920024100360214200241106a21000c760b20022001280218419ab8c50041062001411c6a28020028020c1105003a001820022001360210200241003a001920024100360214200241106a21000c750b2002200128021841a0b8c50041062001411c6a28020028020c1105003a001820022001360210200241003a001920024100360214200241106a21000c740b2002200128021841a6b8c50041062001411c6a28020028020c1105003a001820022001360210200241003a001920024100360214200241106a21000c730b2002200128021841acb8c50041062001411c6a28020028020c1105003a001820022001360210200241003a001920024100360214200241106a21000c720b2002200128021841b2b8c50041062001411c6a28020028020c1105003a001820022001360210200241003a001920024100360214200241106a21000c710b2002200128021841b8b8c50041062001411c6a28020028020c1105003a001820022001360210200241003a001920024100360214200241106a21000c700b2002200128021841beb8c50041062001411c6a28020028020c1105003a001820022001360210200241003a001920024100360214200241106a21000c6f0b2002200128021841c4b8c50041062001411c6a28020028020c1105003a001820022001360210200241003a001920024100360214200241106a21000c6e0b2002200128021841cab8c50041052001411c6a28020028020c1105003a001820022001360210200241003a001920024100360214200241106a21000c6d0b2002200128021841cfb8c50041052001411c6a28020028020c1105003a001820022001360210200241003a001920024100360214200241106a21000c6c0b2002200128021841d4b8c50041062001411c6a28020028020c1105003a001820022001360210200241003a001920024100360214200241106a21000c6b0b2002200128021841dab8c50041062001411c6a28020028020c1105003a001820022001360210200241003a001920024100360214200241106a21000c6a0b2002200128021841e0b8c50041062001411c6a28020028020c1105003a001820022001360210200241003a001920024100360214200241106a21000c690b2002200128021841e6b8c50041062001411c6a28020028020c1105003a001820022001360210200241003a001920024100360214200241106a21000c680b2002200128021841ecb8c50041062001411c6a28020028020c1105003a001820022001360210200241003a001920024100360214200241106a21000c670b2002200128021841f2b8c50041062001411c6a28020028020c1105003a001820022001360210200241003a001920024100360214200241106a21000c660b2002200128021841f8b8c50041062001411c6a28020028020c1105003a001820022001360210200241003a001920024100360214200241106a21000c650b2002200128021841feb8c50041062001411c6a28020028020c1105003a001820022001360210200241003a001920024100360214200241106a21000c640b200220012802184184b9c50041052001411c6a28020028020c1105003a001820022001360210200241003a001920024100360214200241106a21000c630b200220012802184189b9c50041052001411c6a28020028020c1105003a001820022001360210200241003a001920024100360214200241106a21000c620b20022001280218418eb9c50041052001411c6a28020028020c1105003a001820022001360210200241003a001920024100360214200241106a21000c610b200220012802184193b9c50041052001411c6a28020028020c1105003a001820022001360210200241003a001920024100360214200241106a21000c600b200220012802184198b9c50041052001411c6a28020028020c1105003a001820022001360210200241003a001920024100360214200241106a21000c5f0b20022001280218419db9c50041052001411c6a28020028020c1105003a001820022001360210200241003a001920024100360214200241106a21000c5e0b2002200128021841a2b9c50041052001411c6a28020028020c1105003a001820022001360210200241003a001920024100360214200241106a21000c5d0b2002200128021841a7b9c50041052001411c6a28020028020c1105003a001820022001360210200241003a001920024100360214200241106a21000c5c0b2002200128021841acb9c50041052001411c6a28020028020c1105003a001820022001360210200241003a001920024100360214200241106a21000c5b0b2002200128021841b1b9c50041052001411c6a28020028020c1105003a001820022001360210200241003a001920024100360214200241106a21000c5a0b2002200128021841b6b9c50041052001411c6a28020028020c1105003a001820022001360210200241003a001920024100360214200241106a21000c590b2002200128021841bbb9c50041052001411c6a28020028020c1105003a001820022001360210200241003a001920024100360214200241106a21000c580b2002200128021841c0b9c50041062001411c6a28020028020c1105003a001820022001360210200241003a001920024100360214200241106a21000c570b2002200128021841c6b9c50041062001411c6a28020028020c1105003a001820022001360210200241003a001920024100360214200241106a21000c560b2002200128021841ccb9c50041092001411c6a28020028020c1105003a001820022001360210200241003a001920024100360214200241106a21000c550b2002200128021841d5b9c50041062001411c6a28020028020c1105003a001820022001360210200241003a001920024100360214200241106a21000c540b2002200128021841dbb9c50041062001411c6a28020028020c1105003a001820022001360210200241003a001920024100360214200241106a21000c530b2002200128021841e1b9c50041062001411c6a28020028020c1105003a001820022001360210200241003a001920024100360214200241106a21000c520b2002200128021841e7b9c50041072001411c6a28020028020c1105003a001820022001360210200241003a001920024100360214200241106a21000c510b2002200128021841eeb9c50041072001411c6a28020028020c1105003a001820022001360210200241003a001920024100360214200241106a21000c500b2002200128021841f5b9c50041072001411c6a28020028020c1105003a001820022001360210200241003a001920024100360214200241106a21000c4f0b2002200128021841fcb9c50041072001411c6a28020028020c1105003a001820022001360210200241003a001920024100360214200241106a21000c4e0b200220012802184183bac50041062001411c6a28020028020c1105003a001820022001360210200241003a001920024100360214200241106a21000c4d0b200220012802184189bac50041052001411c6a28020028020c1105003a001820022001360210200241003a001920024100360214200241106a21000c4c0b20022001280218418ebac50041062001411c6a28020028020c1105003a001820022001360210200241003a001920024100360214200241106a21000c4b0b200220012802184194bac50041062001411c6a28020028020c1105003a001820022001360210200241003a001920024100360214200241106a21000c4a0b20022001280218419abac50041072001411c6a28020028020c1105003a001820022001360210200241003a001920024100360214200241106a21000c490b2002200128021841a1bac50041072001411c6a28020028020c1105003a001820022001360210200241003a001920024100360214200241106a21000c480b2002200128021841a8bac50041072001411c6a28020028020c1105003a001820022001360210200241003a001920024100360214200241106a21000c470b2002200128021841afbac50041072001411c6a28020028020c1105003a001820022001360210200241003a001920024100360214200241106a21000c460b2002200128021841b6bac50041062001411c6a28020028020c1105003a001820022001360210200241003a001920024100360214200241106a21000c450b2002200128021841bcbac50041062001411c6a28020028020c1105003a001820022001360210200241003a001920024100360214200241106a21000c440b2002200128021841c2bac50041092001411c6a28020028020c1105003a001820022001360210200241003a001920024100360214200241106a21000c430b2002200128021841cbbac50041062001411c6a28020028020c1105003a001820022001360210200241003a001920024100360214200241106a21000c420b2002200128021841d1bac50041062001411c6a28020028020c1105003a001820022001360210200241003a001920024100360214200241106a21000c410b2002200128021841d7bac50041062001411c6a28020028020c1105003a001820022001360210200241003a001920024100360214200241106a21000c400b2002200128021841ddbac50041072001411c6a28020028020c1105003a001820022001360210200241003a001920024100360214200241106a21000c3f0b2002200128021841e4bac50041072001411c6a28020028020c1105003a001820022001360210200241003a001920024100360214200241106a21000c3e0b2002200128021841ebbac50041072001411c6a28020028020c1105003a001820022001360210200241003a001920024100360214200241106a21000c3d0b2002200128021841f2bac50041072001411c6a28020028020c1105003a001820022001360210200241003a001920024100360214200241106a21000c3c0b2002200128021841f9bac50041062001411c6a28020028020c1105003a001820022001360210200241003a001920024100360214200241106a21000c3b0b2002200128021841ffbac50041052001411c6a28020028020c1105003a001820022001360210200241003a001920024100360214200241106a21000c3a0b200220012802184184bbc50041062001411c6a28020028020c1105003a001820022001360210200241003a001920024100360214200241106a21000c390b20022001280218418abbc50041062001411c6a28020028020c1105003a001820022001360210200241003a001920024100360214200241106a21000c380b200220012802184190bbc50041072001411c6a28020028020c1105003a001820022001360210200241003a001920024100360214200241106a21000c370b200220012802184197bbc50041072001411c6a28020028020c1105003a001820022001360210200241003a001920024100360214200241106a21000c360b20022001280218419ebbc50041072001411c6a28020028020c1105003a001820022001360210200241003a001920024100360214200241106a21000c350b2002200128021841a5bbc50041072001411c6a28020028020c1105003a001820022001360210200241003a001920024100360214200241106a21000c340b2002200128021841acbbc50041062001411c6a28020028020c1105003a001820022001360210200241003a001920024100360214200241106a21000c330b2002200128021841b2bbc50041062001411c6a28020028020c1105003a001820022001360210200241003a001920024100360214200241106a21000c320b2002200128021841b8bbc50041072001411c6a28020028020c1105003a001820022001360210200241003a001920024100360214200241106a21000c310b2002200128021841bfbbc50041082001411c6a28020028020c1105003a001820022001360210200241003a001920024100360214200241106a21000c300b2002200128021841c7bbc50041082001411c6a28020028020c1105003a001820022001360210200241003a001920024100360214200241106a21000c2f0b2002200128021841cfbbc500410a2001411c6a28020028020c1105003a001820022001360210200241003a001920024100360214200241106a21000c2e0b2002200128021841d9bbc50041072001411c6a28020028020c1105003a001820022001360210200241003a001920024100360214200241106a21000c2d0b2002200128021841e0bbc50041062001411c6a28020028020c1105003a001820022001360210200241003a001920024100360214200241106a21000c2c0b2002200128021841e6bbc50041062001411c6a28020028020c1105003a001820022001360210200241003a001920024100360214200241106a21000c2b0b2002200128021841ecbbc50041062001411c6a28020028020c1105003a001820022001360210200241003a001920024100360214200241106a21000c2a0b2002200128021841f2bbc50041062001411c6a28020028020c1105003a001820022001360210200241003a001920024100360214200241106a21000c290b2002200128021841f8bbc50041062001411c6a28020028020c1105003a001820022001360210200241003a001920024100360214200241106a21000c280b2002200128021841febbc50041062001411c6a28020028020c1105003a001820022001360210200241003a001920024100360214200241106a21000c270b200220012802184184bcc500410b2001411c6a28020028020c1105003a001820022001360210200241003a001920024100360214200241106a21000c260b20022001280218418fbcc50041062001411c6a28020028020c1105003a001820022001360210200241003a001920024100360214200241106a21000c250b200220012802184195bcc50041062001411c6a28020028020c1105003a001820022001360210200241003a001920024100360214200241106a21000c240b20022001280218419bbcc50041072001411c6a28020028020c1105003a001820022001360210200241003a001920024100360214200241106a21000c230b2002200128021841a2bcc50041082001411c6a28020028020c1105003a001820022001360210200241003a001920024100360214200241106a21000c220b2002200128021841aabcc50041082001411c6a28020028020c1105003a001820022001360210200241003a001920024100360214200241106a21000c210b2002200128021841b2bcc500410a2001411c6a28020028020c1105003a001820022001360210200241003a001920024100360214200241106a21000c200b2002200128021841bcbcc50041072001411c6a28020028020c1105003a001820022001360210200241003a001920024100360214200241106a21000c1f0b2002200128021841c3bcc50041062001411c6a28020028020c1105003a001820022001360210200241003a001920024100360214200241106a21000c1e0b2002200128021841c9bcc50041062001411c6a28020028020c1105003a001820022001360210200241003a001920024100360214200241106a21000c1d0b2002200128021841cfbcc50041062001411c6a28020028020c1105003a001820022001360210200241003a001920024100360214200241106a21000c1c0b2002200128021841d5bcc50041062001411c6a28020028020c1105003a001820022001360210200241003a001920024100360214200241106a21000c1b0b2002200128021841dbbcc50041062001411c6a28020028020c1105003a001820022001360210200241003a001920024100360214200241106a21000c1a0b2002200128021841e1bcc50041062001411c6a28020028020c1105003a001820022001360210200241003a001920024100360214200241106a21000c190b2002200128021841e7bcc500410b2001411c6a28020028020c1105003a001820022001360210200241003a001920024100360214200241106a21000c180b2002200128021841f2bcc500410a2001411c6a28020028020c1105003a001820022001360210200241003a001920024100360214200241106a21000c170b2002200128021841fcbcc500410c2001411c6a28020028020c1105003a001820022001360210200241003a001920024100360214200241106a21000c160b200220012802184188bdc500410c2001411c6a28020028020c1105003a001820022001360210200241003a001920024100360214200241106a21000c150b200220012802184194bdc500410c2001411c6a28020028020c1105003a001820022001360210200241003a001920024100360214200241106a21000c140b2002200128021841a0bdc500410c2001411c6a28020028020c1105003a001820022001360210200241003a001920024100360214200241106a21000c130b2002200128021841acbdc500410d2001411c6a28020028020c1105003a001820022001360210200241003a001920024100360214200241106a21000c120b2002200128021841b9bdc500410d2001411c6a28020028020c1105003a001820022001360210200241003a001920024100360214200241106a21000c110b2002200128021841c6bdc500410c2001411c6a28020028020c1105003a001820022001360210200241003a001920024100360214200241106a21000c100b2002200128021841d2bdc500410c2001411c6a28020028020c1105003a001820022001360210200241003a001920024100360214200241106a21000c0f0b2002200128021841debdc500410c2001411c6a28020028020c1105003a001820022001360210200241003a001920024100360214200241106a21000c0e0b2002200128021841eabdc500410c2001411c6a28020028020c1105003a001820022001360210200241003a001920024100360214200241106a21000c0d0b2002200128021841f6bdc500410e2001411c6a28020028020c1105003a001820022001360210200241003a001920024100360214200241106a21000c0c0b200220012802184184bec500410e2001411c6a28020028020c1105003a001820022001360210200241003a001920024100360214200241106a21000c0b0b200220012802184192bec500410e2001411c6a28020028020c1105003a001820022001360210200241003a001920024100360214200241106a21000c0a0b2002200128021841a0bec500410e2001411c6a28020028020c1105003a001820022001360210200241003a001920024100360214200241106a21000c090b2002200128021841aebec500410c2001411c6a28020028020c1105003a001820022001360210200241003a001920024100360214200241106a21000c080b2002200128021841babec500410e2001411c6a28020028020c1105003a001820022001360210200241003a001920024100360214200241106a21000c070b2002200128021841c8bec500410e2001411c6a28020028020c1105003a001820022001360210200241003a001920024100360214200241106a21000c060b2002200128021841d6bec500410e2001411c6a28020028020c1105003a001820022001360210200241003a001920024100360214200241106a21000c050b2002200128021841e4bec500410e2001411c6a28020028020c1105003a001820022001360210200241003a001920024100360214200241106a21000c040b2002200128021841f2bec500410d2001411c6a28020028020c1105003a001820022001360210200241003a001920024100360214200241106a21000c030b2002200128021841ffbec50041112001411c6a28020028020c1105003a001820022001360210200241003a001920024100360214200241106a21000c020b200220012802184190bfc50041112001411c6a28020028020c1105003a001820022001360210200241003a001920024100360214200241106a21000c010b2002200128021841a1bfc50041112001411c6a28020028020c1105003a001820022001360210200241003a001920024100360214200241106a21000b20002d00082101024020002802042203450d00200141ff0171210441012101024020040d00024020034101470d0020002d0009450d00200028020022042d00004104710d0041012101200428021841b682c60041012004411c6a28020028020c1105000d010b2000280200220128021841b782c60041012001411c6a28020028020c11050021010b200020013a00080b200241206a2400200141ff01714100470bd00201027f230041106b220224002000280200280200210020012802184196a4c50041052001411c6a28020028020c1105002103200241003a0005200220033a00042002200136020020022000410c6a36020c2002419ba4c500410e2002410c6a41aca4c50010950421012002200036020c200141bca4c50041092002410c6a41c8a4c50010950421012002200041046a36020c200141d8a4c500410c2002410c6a41c8a4c50010950421012002200041086a36020c200141e4a4c500410c2002410c6a41c8a4c5001095041a20022d00042100024020022d0005450d00200041ff0171210141012100024020010d0020022802002200411c6a28020028020c210120002802182103024020002d00004104710d00200341b082c6004102200111050021000c010b200341b282c6004101200111050021000b200220003a00040b200241106a2400200041ff01714100470bdd0302047f057e230041d0006b2205240041012106024020002d00040d0020002d000521070240200028020022082d00004104710d0041012106200828021841f481c60041f181c600200741ff017122071b4102410320071b2008411c6a28020028020c1105000d014101210620002802002208280218200120022008411c6a28020028020c1105000d01410121062000280200220828021841c481c60041022008411c6a28020028020c1105000d0120032000280200200428020c11040021060c010b0240200741ff01710d0041012106200828021841f681c60041032008411c6a28020028020c1105000d01200028020021080b41012106200541013a00172005200541176a360210200829020821092008290210210a200541346a41fc81c600360200200520082902183703082008290220210b2008290228210c200520082d00303a00482008290200210d2005200c3703402005200b3703382005200a370328200520093703202005200d3703182005200541086a360230200541086a2001200210c5040d00200541086a41c481c600410210c5040d002003200541186a200428020c1104000d002005280230419482c6004102200528023428020c11050021060b200041013a0005200020063a0004200541d0006a240020000b865f010b7f23004190016b220324002003200136021c2002280208220441586a2105200241106a2802002206412c6c2101024002400240024002400240024002400240024002400240024002400240024002400240024003402001450d01200141546a2101200541286a21072005412c6a2208210520072d00004104470d000b2006412c6c2101200441586a210503402001450d02200141546a2101200541286a21072005412c6a2209210520072d0000410b470d000b2006412c6c2101200441586a210503402001450d03200141546a2101200541286a21072005412c6a2204210520072d00004102470d000b024041002802c082464105490d002003410136023c20032003411c6a36023841002802c48246210120034188016a41980136020020034180016a42ec80808010370300200341f8006a4125360200200341f0006a4101360200200341e0006a4201370300200341d8006a410a360200200341aba8c50036027c20034186a8c500360274200341ec006a200341386a360200200341a4a5c50036025c200341fca7c5003602542003410536025041c882c60041b8d6c500200141024622011b200341d0006a41b4cac50041cccac50020011b2802101100000b200341106a20081080032003280214200328021c22014d0d03200328021020014102746a2201450d03200341086a20041080030240200328020c200128020022014d0d00200328020820014104746a22010d050b412510272201450d092001411d6a41002900c9a545370000200141186a41002900c4a545370000200141106a41002900bca545370000200141086a41002900b4a545370000200141002900aca545370000200041086a42a5808080d00437020020002001360204200041013602000c120b411310272201450d042001410f6a41002800ffa445360000200141086a41002900f8a445370000200141002900f0a445370000200041086a4293808080b00237020020002001360204200041013602000c110b410f10272201450d04200141076a410029008aa54537000020014100290083a545370000200041086a428f808080f00137020020002001360204200041013602000c100b410f10272201450d04200141076a4100290099a54537000020014100290092a545370000200041086a428f808080f00137020020002001360204200041013602000c0f0b412510272201450d042001411d6a41002900c9a545370000200141186a41002900c4a545370000200141106a41002900bca545370000200141086a41002900b4a545370000200141002900aca545370000200041086a42a5808080d00437020020002001360204200041013602000c0e0b0240200941086a280200200328021c22054b0d00412710272201450d062001411f6a41002900f0a545370000200141186a41002900e9a545370000200141106a41002900e1a545370000200141086a41002900d9a545370000200141002900d1a545370000200041086a42a7808080f00437020020002001360204200041013602000c0e0b20092802002109200341206a41086a420037030020034280808080c00037032020012d000d2107410021012003410036024020032007410447220a36023c2003200a360238200341003a0044024041002802c0824641044b0d00200341d0006a41086a200341386a41086a29030037030020032003290338370350200341d0006a21070c070b2003412936024c2003200341386a36024841002802c48246210120034188016a41cb0036020020034180016a42ec80808010370300200341f8006a4125360200200341f0006a4101360200200341e0006a4201370300200341d0006a41086a2207410a360200200341aba8c50036027c20034186a8c500360274200341ec006a200341c8006a360200200341f8a5c50036025c200341fca7c5003602542003410536025041c882c60041b8d6c500200141024622011b200341d0006a41b4cac50041cccac50020011b280210110000200328022c2108200328022821012007200341386a41086a29030037030020032003290338370350200341d0006a210720082001460d0620032802242101200341d0006a21070c070b41134101102a000b410f4101102a000b410f4101102a000b41254101102a000b41254101102a000b41274101102a000b200141016a22082001490d0520014101742206200820082006491b220841ffffffff00712008470d05200841047422064100480d050240024020010d002006102721010c010b200328022420014104742006102821010b2001450d012003200836022820032001360224200328022c21080b200120084104746a22012007290200370200200141086a200741086a2902003702002003200328022c41016a36022c410021072009200541186c6a2201280214450d022009200541186c6a410c6a2109200141146a2108200341d0006a410472210b410021074100210103400240200328022020074d0d00200341d0006a200341206a4100109804024020032802504101470d00200041013602002000200b2902003702042000410c6a200b41086a2802003602000c060b2007200328022020032802542d000c1b21070b02400240024002400240024002402001200828020022054f0d002003200928020020014104746a2205360234024041002802c082464105490d002003412236023c2003200341346a36023841002802c482462105200341c90136028801200342ec8080801037038001200341aba8c50036027c2003412536027820034186a8c50036027420034101360270200342013703602003419c81c60036025c2003410a360258200341fca7c500360254200341053602502003200341386a36026c41c882c60041b8d6c500200541024622051b200341d0006a41b4cac50041cccac50020051b280210110000200328023421050b024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024020052d000022060eac0102220000002201030405060708090a0b0c0d0e0f1010101010101010101010101010111111111111111111121314141414151616161616161616161615161616161616161616161616161616161616161616161717171818181818181818181818181818181717171818181818181818181818181818181717171717171718181818181818171717171717171818181818181819191919191919191919191919191919191919191919191919020b20052d00012105200320032802203602402003200541044722053602382003200641034720057136023c200341003a0044024041002802c082464105490d002003412936024c2003200341386a36024841002802c482462105200341cb0036028801200342ec8080801037038001200341aba8c50036027c2003412536027820034186a8c5003602742003410136027020034201370360200341f8a5c50036025c2003410a360258200341fca7c500360254200341053602502003200341c8006a36026c41c882c60041b8d6c500200541024622051b200341d0006a41b4cac50041cccac50020051b2802101100000b200341d0006a41086a200341386a41086a2903003703002003200329033837035002400240200328022c22052003280228460d00200328022421060c010b200541016a22062005490d282005410174220c20062006200c491b220c41ffffffff0071200c470d28200c410474220d4100480d280240024020050d00200d102721060c010b20032802242005410474200d102821060b2006450d1d2003200c36022820032006360224200328022c21050b200620054104746a22052003290350370200200541086a200341d0006a41086a2903003702002003200328022c41016a36022c0c210b41002105024041002802c082464105490d000240200328022c2206417f6a220c20064b0d002003280224200c4104746a4100200c2006491b21050b2003412a36024c200320053602382003200341386a36024841002802c482462105200341d30036028801200342ec8080801037038001200341aba8c50036027c2003412536027820034186a8c500360274200341013602702003420137036020034180a6c50036025c2003410a360258200341fca7c500360254200341053602502003200341c8006a36026c41c882c60041b8d6c500200541024622051b200341d0006a41b4cac50041cccac50020051b2802101100000b0240200328022c2205450d0020032005417f6a220536022c200328022420054104746a22052d000c4102470d1a0b411710272201450d1c2001410f6a4100290097a645370000200141086a4100290090a64537000020014100290088a645370000200041086a4297808080f00237020020002001360204200041013602000c250b024041002802c082464105490d0041002802c482462105200341c10036028801200342ec8080801037038001200341aba8c50036027c2003412536027820034186a8c5003602742003410036027020034201370360200341a0a6c50036025c2003410a360258200341fca7c50036025420034105360250200341b8d6c50036026c41c882c60041b8d6c500200541024622051b200341d0006a41b4cac50041cccac50020051b2802101100000b0240200328022c2205417f6a220620054f0d00200620054d0d180b411710272201450d1e2001410f6a4100290097a645370000200141086a4100290090a64537000020014100290088a645370000200041086a4297808080f00237020020002001360204200041013602000c240b200341d0006a200341206a200541046a280200109804024020032802504101470d00200041013602002000200b2902003702042000410c6a200b41086a2802003602000c240b200341d0006a200341206a2003280254280204109a0402402003280250450d0020002003290350370204200041013602002000410c6a200341d8006a2802003602000c240b024041002802c082464105490d0041002802c482462105200341c10036028801200342ec8080801037038001200341aba8c50036027c2003412536027820034186a8c5003602742003410036027020034201370360200341a0a6c50036025c2003410a360258200341fca7c50036025420034105360250200341b8d6c50036026c41c882c60041b8d6c500200541024622051b200341d0006a41b4cac50041cccac50020051b2802101100000b024002400240200328022c2205417f6a220620054f0d00200620054d0d010b4117102722010d0141174101102a000b200328022420064104746a41013a000c0c1f0b2001410f6a4100290097a645370000200141086a4100290090a64537000020014100290088a645370000200041086a4297808080f00237020020002001360204200041013602000c230b200341d0006a200341206a200541046a280200109804024020032802504101470d00200041013602002000200b2902003702042000410c6a200b41086a2802003602000c230b200341d0006a200341206a20032802542802042205109a0402402003280250450d0020002003290350370204200041013602002000410c6a200341d8006a2802003602000c230b200341d0006a200341206a4101109a0402402003280250450d0020002003290350370204200041013602002000410c6a200341d8006a2802003602000c230b20032005360248024041002802c082464105490d002003410136023c2003200341c8006a36023841002802c482462105200341e30036028801200342ec8080801037038001200341aba8c50036027c2003412536027820034186a8c5003602742003410136027020034201370360200341a8a6c50036025c2003410a360258200341fca7c500360254200341053602502003200341386a36026c41c882c60041b8d6c500200541024622051b200341d0006a41b4cac50041cccac50020051b280210110000200328024821050b024002402003280220220620056a220520064f0d00410e102722010d01410e4101102a000b200320053602200c1e0b200141066a41002900b6a645370000200141002900b0a645370000200041086a428e808080e00137020020002001360204200041013602000c220b200341d0006a200341206a2005410c6a280200109804024020032802504101470d00200041013602002000200b2902003702042000410c6a200b41086a2802003602000c220b2003280254280204210c200541086a2802004102742106200541046a280200210502400340024020060d00200341d0006a200341206a200c109a042003280250450d0220002003290350370204200041013602002000410c6a200341d8006a2802003602000c240b200341d0006a200341206a2005280200109804024020032802504101470d00200041013602002000200b2902003702042000410c6a200b41086a2802003602000c240b2006417c6a2106200541046a21052003280254280204200c460d000b412710272201450d1a2001411f6a41002900dda645370000200141186a41002900d6a645370000200141106a41002900cea645370000200141086a41002900c6a645370000200141002900bea645370000200041086a42a7808080f00437020020002001360204200041013602000c220b024041002802c082464105490d0041002802c482462105200341c10036028801200342ec8080801037038001200341aba8c50036027c2003412536027820034186a8c5003602742003410036027020034201370360200341a0a6c50036025c2003410a360258200341fca7c50036025420034105360250200341b8d6c50036026c41c882c60041b8d6c500200541024622051b200341d0006a41b4cac50041cccac50020051b2802101100000b024002400240200328022c2205417f6a220620054f0d00200620054d0d010b4117102722010d0141174101102a000b200328022420064104746a41013a000c0c1d0b2001410f6a4100290097a645370000200141086a4100290090a64537000020014100290088a645370000200041086a4297808080f00237020020002001360204200041013602000c210b200341d0006a200341206a200a109a0402402003280250450d0020002003290350370204200041013602002000410c6a200341d8006a2802003602000c210b024041002802c082464105490d0041002802c482462105200341c10036028801200342ec8080801037038001200341aba8c50036027c2003412536027820034186a8c5003602742003410036027020034201370360200341a0a6c50036025c2003410a360258200341fca7c50036025420034105360250200341b8d6c50036026c41c882c60041b8d6c500200541024622051b200341d0006a41b4cac50041cccac50020051b2802101100000b024002400240200328022c2205417f6a220620054f0d00200620054d0d010b4117102722010d0141174101102a000b200328022420064104746a41013a000c0c1c0b2001410f6a4100290097a645370000200141086a4100290090a64537000020014100290088a645370000200041086a4297808080f00237020020002001360204200041013602000c200b200341d0006a200541046a2802002002109b04024020032802504101470d00200041013602002000200b2902003702042000410c6a200b41086a2802003602000c200b200341d0006a200341206a20032802542205280208109a0402402003280250450d0020002003290350370204200041013602002000410c6a200341d8006a2802003602000c200b200320052d000d4104472205360248024041002802c082464105490d002003410136023c2003200341c8006a36023841002802c482462105200341e30036028801200342ec8080801037038001200341aba8c50036027c2003412536027820034186a8c5003602742003410136027020034201370360200341a8a6c50036025c2003410a360258200341fca7c500360254200341053602502003200341386a36026c41c882c60041b8d6c500200541024622051b200341d0006a41b4cac50041cccac50020051b280210110000200328024821050b024002402003280220220620056a220520064f0d00410e102722010d01410e4101102a000b200320053602200c1b0b200141066a41002900b6a645370000200141002900b0a645370000200041086a428e808080e00137020020002001360204200041013602000c1f0b20032004108003024002402003280204200541046a28020022054d0d002003280200220620054104746a220c0d010b410e10272201450d18200141066a41002900eba645370000200141002900e5a645370000200041086a428e808080e00137020020002001360204200041013602000c1f0b200341d0006a200341206a200620054104746a280208109a0402402003280250450d0020002003290350370204200041013602002000410c6a200341d8006a2802003602000c1f0b2003200c2d000d4104472205360248024041002802c082464105490d002003410136023c2003200341c8006a36023841002802c482462105200341e30036028801200342ec8080801037038001200341aba8c50036027c2003412536027820034186a8c5003602742003410136027020034201370360200341a8a6c50036025c2003410a360258200341fca7c500360254200341053602502003200341386a36026c41c882c60041b8d6c500200541024622051b200341d0006a41b4cac50041cccac50020051b280210110000200328024821050b024002402003280220220620056a220520064f0d00410e102722010d01410e4101102a000b200320053602200c1a0b200141066a41002900b6a645370000200141002900b0a645370000200041086a428e808080e00137020020002001360204200041013602000c1e0b200341d0006a200341206a4101109a042003280250450d1820002003290350370204200041013602002000410c6a200341d8006a2802003602000c1d0b200341d0006a200341206a4102109a0402402003280250450d0020002003290350370204200041013602002000410c6a200341d8006a2802003602000c1d0b41012105200341d0006a200341206a4101109a0402402003280250450d0020002003290350370204200041013602002000410c6a200341d8006a2802003602000c1d0b20034101360248024041002802c082464105490d002003410136023c2003200341c8006a36023841002802c482462105200341e30036028801200342ec8080801037038001200341aba8c50036027c2003412536027820034186a8c5003602742003410136027020034201370360200341a8a6c50036025c2003410a360258200341fca7c500360254200341053602502003200341386a36026c41c882c60041b8d6c500200541024622051b200341d0006a41b4cac50041cccac50020051b280210110000200328024821050b024002402003280220220620056a220520064f0d00410e102722010d01410e4101102a000b200320053602200c180b200141066a41002900b6a645370000200141002900b0a645370000200041086a428e808080e00137020020002001360204200041013602000c1c0b4101210520034101360248024041002802c082464105490d002003410136023c2003200341c8006a36023841002802c482462105200341e30036028801200342ec8080801037038001200341aba8c50036027c2003412536027820034186a8c5003602742003410136027020034201370360200341a8a6c50036025c2003410a360258200341fca7c500360254200341053602502003200341386a36026c41c882c60041b8d6c500200541024622051b200341d0006a41b4cac50041cccac50020051b280210110000200328024821050b024002402003280220220620056a220520064f0d00410e102722010d01410e4101102a000b200320053602200c170b200141066a41002900b6a645370000200141002900b0a645370000200041086a428e808080e00137020020002001360204200041013602000c1b0b200341d0006a200341206a4101109a042003280250450d1520002003290350370204200041013602002000410c6a200341d8006a2802003602000c1a0b41012105200341d0006a200341206a4101109a0402402003280250450d0020002003290350370204200041013602002000410c6a200341d8006a2802003602000c1a0b20034101360248024041002802c082464105490d002003410136023c2003200341c8006a36023841002802c482462105200341e30036028801200342ec8080801037038001200341aba8c50036027c2003412536027820034186a8c5003602742003410136027020034201370360200341a8a6c50036025c2003410a360258200341fca7c500360254200341053602502003200341386a36026c41c882c60041b8d6c500200541024622051b200341d0006a41b4cac50041cccac50020051b280210110000200328024821050b024002402003280220220620056a220520064f0d00410e102722010d01410e4101102a000b200320053602200c150b200141066a41002900b6a645370000200141002900b0a645370000200041086a428e808080e00137020020002001360204200041013602000c190b4101210520034101360248024041002802c082464105490d002003410136023c2003200341c8006a36023841002802c482462105200341e30036028801200342ec8080801037038001200341aba8c50036027c2003412536027820034186a8c5003602742003410136027020034201370360200341a8a6c50036025c2003410a360258200341fca7c500360254200341053602502003200341386a36026c41c882c60041b8d6c500200541024622051b200341d0006a41b4cac50041cccac50020051b280210110000200328024821050b024002402003280220220620056a220520064f0d00410e102722010d01410e4101102a000b200320053602200c140b200141066a41002900b6a645370000200141002900b0a645370000200041086a428e808080e00137020020002001360204200041013602000c180b200341d0006a200341206a4101109a042003280250450d1220002003290350370204200041013602002000410c6a200341d8006a2802003602000c170b41012105200341d0006a200341206a4101109a0402402003280250450d0020002003290350370204200041013602002000410c6a200341d8006a2802003602000c170b20034101360248024041002802c082464105490d002003410136023c2003200341c8006a36023841002802c482462105200341e30036028801200342ec8080801037038001200341aba8c50036027c2003412536027820034186a8c5003602742003410136027020034201370360200341a8a6c50036025c2003410a360258200341fca7c500360254200341053602502003200341386a36026c41c882c60041b8d6c500200541024622051b200341d0006a41b4cac50041cccac50020051b280210110000200328024821050b024002402003280220220620056a220520064f0d00410e102722010d01410e4101102a000b200320053602200c120b200141066a41002900b6a645370000200141002900b0a645370000200041086a428e808080e00137020020002001360204200041013602000c160b200341d0006a200341206a4102109a042003280250450d1020002003290350370204200041013602002000410c6a200341d8006a2802003602000c150b4101210520034101360248024041002802c082464105490d002003410136023c2003200341c8006a36023841002802c482462105200341e30036028801200342ec8080801037038001200341aba8c50036027c2003412536027820034186a8c5003602742003410136027020034201370360200341a8a6c50036025c2003410a360258200341fca7c500360254200341053602502003200341386a36026c41c882c60041b8d6c500200541024622051b200341d0006a41b4cac50041cccac50020051b280210110000200328024821050b024002402003280220220620056a220520064f0d00410e102722010d01410e4101102a000b200320053602200c100b200141066a41002900b6a645370000200141002900b0a645370000200041086a428e808080e00137020020002001360204200041013602000c140b41012105200341d0006a200341206a4101109a0402402003280250450d0020002003290350370204200041013602002000410c6a200341d8006a2802003602000c140b20034101360248024041002802c082464105490d002003410136023c2003200341c8006a36023841002802c482462105200341e30036028801200342ec8080801037038001200341aba8c50036027c2003412536027820034186a8c5003602742003410136027020034201370360200341a8a6c50036025c2003410a360258200341fca7c500360254200341053602502003200341386a36026c41c882c60041b8d6c500200541024622051b200341d0006a41b4cac50041cccac50020051b280210110000200328024821050b024002402003280220220620056a220520064f0d00410e102722010d01410e4101102a000b200320053602200c0f0b200141066a41002900b6a645370000200141002900b0a645370000200041086a428e808080e00137020020002001360204200041013602000c130b4101210520034101360248024041002802c082464105490d002003410136023c2003200341c8006a36023841002802c482462105200341e30036028801200342ec8080801037038001200341aba8c50036027c2003412536027820034186a8c5003602742003410136027020034201370360200341a8a6c50036025c2003410a360258200341fca7c500360254200341053602502003200341386a36026c41c882c60041b8d6c500200541024622051b200341d0006a41b4cac50041cccac50020051b280210110000200328024821050b024002402003280220220620056a220520064f0d00410e102722010d01410e4101102a000b200320053602200c0e0b200141066a41002900b6a645370000200141002900b0a645370000200041086a428e808080e00137020020002001360204200041013602000c120b41012105200341d0006a200341206a4101109a0402402003280250450d0020002003290350370204200041013602002000410c6a200341d8006a2802003602000c120b20034101360248024041002802c082464105490d002003410136023c2003200341c8006a36023841002802c482462105200341e30036028801200342ec8080801037038001200341aba8c50036027c2003412536027820034186a8c5003602742003410136027020034201370360200341a8a6c50036025c2003410a360258200341fca7c500360254200341053602502003200341386a36026c41c882c60041b8d6c500200541024622051b200341d0006a41b4cac50041cccac50020051b280210110000200328024821050b024002402003280220220620056a220520064f0d00410e102722010d01410e4101102a000b200320053602200c0d0b200141066a41002900b6a645370000200141002900b0a645370000200041086a428e808080e00137020020002001360204200041013602000c110b200341d0006a200341206a4102109a0402402003280250450d0020002003290350370204200041013602002000410c6a200341d8006a2802003602000c110b4101210520034101360248024041002802c082464105490d002003410136023c2003200341c8006a36023841002802c482462105200341e30036028801200342ec8080801037038001200341aba8c50036027c2003412536027820034186a8c5003602742003410136027020034201370360200341a8a6c50036025c2003410a360258200341fca7c500360254200341053602502003200341386a36026c41c882c60041b8d6c500200541024622051b200341d0006a41b4cac50041cccac50020051b280210110000200328024821050b024002402003280220220620056a220520064f0d00410e102722010d01410e4101102a000b200320053602200c0c0b200141066a41002900b6a645370000200141002900b0a645370000200041086a428e808080e00137020020002001360204200041013602000c100b41012105200341d0006a200341206a4101109a0402402003280250450d0020002003290350370204200041013602002000410c6a200341d8006a2802003602000c100b20034101360248024041002802c082464105490d002003410136023c2003200341c8006a36023841002802c482462105200341e30036028801200342ec8080801037038001200341aba8c50036027c2003412536027820034186a8c5003602742003410136027020034201370360200341a8a6c50036025c2003410a360258200341fca7c500360254200341053602502003200341386a36026c41c882c60041b8d6c500200541024622051b200341d0006a41b4cac50041cccac50020051b280210110000200328024821050b024002402003280220220620056a220520064f0d00410e102722010d01410e4101102a000b200320053602200c0b0b200141066a41002900b6a645370000200141002900b0a645370000200041086a428e808080e00137020020002001360204200041013602000c0f0b200341d0006a200341206a4102109a0402402003280250450d0020002003290350370204200041013602002000410c6a200341d8006a2802003602000c0f0b4101210520034101360248024041002802c082464105490d002003410136023c2003200341c8006a36023841002802c482462105200341e30036028801200342ec8080801037038001200341aba8c50036027c2003412536027820034186a8c5003602742003410136027020034201370360200341a8a6c50036025c2003410a360258200341fca7c500360254200341053602502003200341386a36026c41c882c60041b8d6c500200541024622051b200341d0006a41b4cac50041cccac50020051b280210110000200328024821050b024002402003280220220620056a220520064f0d00410e102722010d01410e4101102a000b200320053602200c0a0b200141066a41002900b6a645370000200141002900b0a645370000200041086a428e808080e00137020020002001360204200041013602000c0e0b41012105200341d0006a200341206a4101109a0402402003280250450d0020002003290350370204200041013602002000410c6a200341d8006a2802003602000c0e0b20034101360248024041002802c082464105490d002003410136023c2003200341c8006a36023841002802c482462105200341e30036028801200342ec8080801037038001200341aba8c50036027c2003412536027820034186a8c5003602742003410136027020034201370360200341a8a6c50036025c2003410a360258200341fca7c500360254200341053602502003200341386a36026c41c882c60041b8d6c500200541024622051b200341d0006a41b4cac50041cccac50020051b280210110000200328024821050b024002402003280220220620056a220520064f0d00410e102722010d01410e4101102a000b200320053602200c090b200141066a41002900b6a645370000200141002900b0a645370000200041086a428e808080e00137020020002001360204200041013602000c0d0b200328022420064104746a41013a000c0c070b20052802002106200320052802082205360238024041002802c082464105490d002003410136024c2003200341386a36024841002802c482462105200341db0036028801200342ec8080801037038001200341aba8c50036027c2003412536027820034186a8c5003602742003410136027020034201370360200341f4a6c50036025c2003410a360258200341fca7c500360254200341053602502003200341c8006a36026c41c882c60041b8d6c500200541024622051b200341d0006a41b4cac50041cccac50020051b280210110000200328023821050b2003200536022020032006360248024041002802c082464105490d002003410136023c2003200341c8006a36023841002802c482462105200341e30036028801200342ec8080801037038001200341aba8c50036027c2003412536027820034186a8c5003602742003410136027020034201370360200341a8a6c50036025c2003410a360258200341fca7c500360254200341053602502003200341386a36026c41c882c60041b8d6c500200541024622051b200341d0006a41b4cac50041cccac50020051b28021011000020032802202105200328024821060b0240200520066a220620054f0d00410e102722010d0a410e4101102a000b200320063602200c060b41fca6c500200120051037000b200d4104102a000b41174101102a000b41274101102a000b410e4101102a000b41174101102a000b200141016a22012008280200490d000c030b0b20064104102a000b200141066a41002900b6a645370000200141002900b0a645370000200041086a428e808080e00137020020002001360204200041013602000c010b20004100360200200020073602042003280228450d02200328022410290c020b2003280228450d01200328022410290c010b102b000b20034190016a24000bc60201027f230041106b2202240020012802184196a4c50041052001411c6a28020028020c1105002103200241003a0005200220033a00042002200136020020022000410c6a36020c2002419ba4c500410e2002410c6a41aca4c50010950421012002200036020c200141bca4c50041092002410c6a41c8a4c50010950421012002200041046a36020c200141d8a4c500410c2002410c6a41c8a4c50010950421012002200041086a36020c200141e4a4c500410c2002410c6a41c8a4c5001095041a20022d00042100024020022d0005450d00200041ff0171210141012100024020010d0020022802002200411c6a28020028020c210120002802182103024020002d00004104710d00200341b082c6004102200111050021000c010b200341b282c6004101200111050021000b200220003a00040b200241106a2400200041ff01714100470b9b0201027f024002400240024002402001410c6a2802002203417f6a220420034d0d00411610272201450d01200020013602042001410e6a4100290089aa45370000200141086a4100290083aa45370000200141002900fba945370000200041086a4296808080e0023702000c040b0240200420026b220220044d0d00411b10272201450d0220002001360204200141176a41002800a8aa45360000200141106a41002900a1aa45370000200141086a4100290099aa4537000020014100290091aa45370000200041086a429b808080b0033702000c040b200320024d0d022000200128020420024104746a360204200041003602000f0b41164101102a000b411b4101102a000b41acaac500200220031037000b200041013602000bbb0201037f230041106b220224000240024020002802000d00200220012802184186b2c50041042001411c6a28020028020c11050022003a000820022001360200200241003a0009200241003602040c010b20022001280218418ab2c50041042001411c6a28020028020c1105003a000820022001360200200241003a0009200241003602042002200036020c20022002410c6a4190b2c500108c04210120022d0008210020022802042203450d00200041ff0171210441012100024020040d00024020034101470d0020012d0009450d00200128020022042d00004104710d0041012100200428021841b682c60041012004411c6a28020028020c1105000d010b2001280200220028021841b782c60041012000411c6a28020028020c11050021000b200120003a00080b200241106a2400200041ff01714100470bc50401027f230041d0006b2203240020032002360204024041002802c082464105490d002003410136020c2003200341046a36020841002802c482462102200341c8006a41ef00360200200341c0006a42ec80808010370300200341386a4125360200200341306a4101360200200341206a4201370300200341186a410a360200200341aba8c50036023c20034186a8c5003602342003412c6a200341086a360200200341a4a9c50036021c200341fca7c5003602142003410536021041c882c60041b8d6c500200241024622021b200341106a41b4cac50041cccac50020021b280210110000200328020421020b0240024002402002450d00200341106a2001410010980420032802104101470d012000200341106a4104722202290200370200200041086a200241086a2802003602000c020b200041003602000c010b02400240024002402001280200220220032802142204280208460d00200220032802046b220420024d0d02410f102722020d01410f4101102a000b024020042d000c0d00412510272202450d03200042a5808080d004370204200020023602002002411d6a41002900c9a945370000200241186a41002900c4a945370000200241106a41002900bca945370000200241086a41002900b4a945370000200241002900aca9453700000c040b200041003602000c030b2000428f808080f00137020420002002360200200241076a41002900d8a945370000200241002900d1a9453700000c020b20004100360200200120043602000c010b41254101102a000b200341d0006a24000bd809010b7f230041e0006b22032400200320013602202002280208220441586a2105200241106a2802002206412c6c210202400340024020020d00410021070c020b200241546a2102200541286a21072005412c6a2208210520072d00004102470d000b200341186a200810800320032802182107200328021c21020b2002410020071b21092006412c6c2102200441586a2105200741b8d6c50020071b210a02400340024020020d004100210b0c020b200241546a2102200541286a21072005412c6a2208210520072d00004104470d000b200341106a20081080032003280210210b2003280214210c0b2006412c6c2102200441586a2105200b41b8d6c500200b1b210d0240024002400240024002400240024003402002450d01200241546a2102200541286a21072005412c6a2208210520072d00004103470d000b200841086a2802002202450d00200241286c2107200828020041186a2102410021050340200520022d0000456a2105200241286a2102200741586a22070d000b200520014d0d012006412c6c2102200441586a210502400240024003402002450d01200241546a2102200541286a21072005412c6a2208210520072d00004103470d000b200341086a200810800320032802082207200328020c41286c6a2108024003400240024002402008200722026b41f8004b0d0020022008460d0f2002411c6a2105034020022d0018450d02200541286a2105200241286a22022008470d000c100b0b20022d00180d012002411c6a2105200241286a21070c060b2005410c6a21070c050b200241c0006a2d0000450d01200241e8006a2d0000450d03200241a0016a210720024190016a2d00000d000b20024194016a21050c030b200241c4006a2105200241d0006a21070c020b4185aec50041c200104e000b200241ec006a2105200241f8006a21070b2001450d0203402001417f6a21010240024003400240024002402008200722026b41f8004b0d0020022008460d0e2002411c6a2105034020022d0018450d02200541286a2105200241286a22022008460d0f0c000b0b20022d00180d01200241286a210720010d052002411c6a21050c080b2005410c6a21072001450d070c040b200241c0006a2d0000450d02200241e8006a2d0000450d01200241a0016a210720024190016a2d00000d000b20010d0220024194016a21050c050b200241f8006a210720010d01200241ec006a21050c040b200241d0006a210720010d000b200241c4006a21050c020b410021050b200c4100200b1b200120056b22024d0d01200d20024102746a2205450d010b200320052802002202360224200920024d0d01200a20024104746a2202450d0120002002360204410021020c030b200341cc006a41013602002003420237023c200341a4afc5003602382003410136022c2003200341286a3602482003200341206a360228200341d0006a200341386a10e603200341d0006a21020c010b200341cc006a4102360200200341dc006a41013602002003420337023c200341b4afc500360238200341013602542003200341d0006a3602482003200341206a3602582003200341246a360250200341286a200341386a10e603200341286a21020b20022802002105200041086a200229020437020020002005360204410121020b20002002360200200341e0006a24000f0b41c7aec50041dd00104e000bc60902057f017e024020010d00200041ac013a00000f0b02400240024002400240024020012d00002202414f6a41fb004f0d000c010b02400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024020020e312c2c0001022c2c0304052c06072c2c08090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292c0b20012d00012103410221020c2b0b20012d00012103410321020c2a0b20012d00012103410421020c290b200141046a2802002104410721020c270b200141046a2802002104410821020c260b2001280208220541ffffffff03712005470d2720054102742202417f4c0d270240024020020d00410421040c010b200210272204450d290b02402005450d00200128020421022005410274210620042103034020032002280200360200200341046a2103200241046a21022006417c6a22060d000b0b200135020c4220862005ad842107410921020c250b200141046a2802002104410b21020c240b200141046a280200210420012d00012103410c21020c240b200141046a2802002104410f21020c220b200141046a2802002104411021020c210b200141046a2802002104411121020c200b200141046a2802002104411221020c1f0b200141046a2802002104411321020c1e0b200141046a280200210420013502082107411421020c1d0b200141046a280200210420013502082107411521020c1c0b200141046a280200210420013502082107411621020c1b0b200141046a280200210420013502082107411721020c1a0b200141046a280200210420013502082107411821020c190b200141046a280200210420013502082107411921020c180b200141046a280200210420013502082107411a21020c170b200141046a280200210420013502082107411b21020c160b200141046a280200210420013502082107411c21020c150b200141046a280200210420013502082107411d21020c140b200141046a280200210420013502082107411e21020c130b200141046a280200210420013502082107411f21020c120b200141046a280200210420013502082107412021020c110b200141046a280200210420013502082107412121020c100b200141046a280200210420013502082107412221020c0f0b200141046a280200210420013502082107412321020c0e0b200141046a280200210420013502082107412421020c0d0b200141046a280200210420013502082107412521020c0c0b200141046a280200210420013502082107412621020c0b0b200141046a280200210420013502082107412721020c0a0b200141046a280200210420013502082107412821020c090b200141046a280200210420013502082107412921020c080b200141046a280200210420013502082107412a21020c070b20012d00012103412b21020c070b20012d00012103412c21020c060b200141046a2802002104412d21020c040b20012903082107412e21020c020b200141046a2802002104412f21020c020b20012903082107413021020b0b0b200020033a0001200020023a0000200041086a2007370300200041046a20043602000f0b1039000b20024104102a000b8d0301067f230041106b220224000240024002400240200041046a2802002203200041086a28020022046b20012802042205200128020022066b4104762207490d00200028020021030c010b200420076a22062004490d0220034101742205200620062005491b220641ffffffff00712006470d02200641047422054100480d020240024020030d002005102721030c010b200028020020034104742005102821030b2003450d0120002003360200200041046a2006360200200041086a280200210420012802042105200128020021060b0240024020062005470d00410021060c010b2001200641106a3602000b20022006109c04024020022d000041ac01460d00200320044104746a2106034020062002290300370300200641086a200241086a29030037030002400240200128020022052001280204470d00410021050c010b2001200541106a3602000b200441016a2104200641106a210620022005109c0420022d000041ac01470d000b0b200041086a2004360200200241106a24000f0b20054108102a000b102b000b110020002802003502004101200110aa010bea0302057f017e02402001450d00034020002802940321002001417f6a22010d000b0b02402002450d004100210341002101034002400240200120002f01064f0d00200020014105746a220441c4006a2802002105200441386a2802002106200441346a2802002107200141016a21010c010b02400240200028020022010d002003ad210841002104410021010c010b20003301044220862003ad842108410121040b200010292008a72103024002402008422088a7220620012f01064f0d00200121050c010b034002400240200128020022050d002003ad2108410021050c010b200441016a210420013301044220862003ad8421080b200110292008a72103200521012008422088a7220620052f01064f0d000b0b200641027420056a4198036a2802002100200520064105746a220141c4006a2802002105200141386a2802002106200141346a280200210702402004417f6a2201450d00034020002802940321002001417f6a22010d000b0b410021010b20054102460d012002417f6a210202402006450d00200710290b20020d000b0b02402000418883c000460d0020002802002101200010292001450d0020012802002105200110292005450d00024020052802002201450d000340200510292001210520012802002200210120000d000b0b200510290b0b2300200141fd80c60041f880c60020002802002d000022001b4104410520001b10e9030b02000bc60201037f230041206b2202240002400240200028020022002d00004104470d002002200128021841b2bfc50041082001411c6a28020028020c11050022003a001820022001360210200241003a0019200241003602140c010b2002200128021841babfc50041052001411c6a28020028020c1105003a001820022001360210200241003a0019200241003602142002200036020c200241106a2002410c6a41c0bfc500108c04210120022d0018210020022802142203450d00200041ff0171210441012100024020040d00024020034101470d0020012d0009450d00200128020022042d00004104710d0041012100200428021841b682c60041012004411c6a28020028020c1105000d010b2001280200220028021841b782c60041012000411c6a28020028020c11050021000b200120003a00080b200241206a2400200041ff01714100470b890501047f230041d0006b220224002000280200220041046a28020021032000280200210041012104200128021841ba82c60041012001411c6a28020028020c110500210502402003450d0020022000360204024020050d00024020012d0000410471450d0041012104200128021841b882c6004101200128021c28020c1105000d012001280200210541012104200241013a001720022005360218200241fc81c60036023420022001290218370308200220012d00303a00482002200128020436021c200220012902283703402002200129022037033820022001290210370328200220012902083703202002200241176a3602102002200241086a360230200241046a200241186a1080010d012002280230419482c6004102200228023428020c11050021040c010b200241046a200110800121040b024020034101470d00200421050c010b200041046a21002003410274417c6a210320042105034020022000360204200541ff0171210441012105024020040d00024020012802002204410471450d00200241013a001720022004360218200241fc81c60036023420022001290218370308200220012d00303a00482002200128020436021c200220012902283703402002200129022037033820022001290210370328200220012902083703202002200241176a3602102002200241086a360230200241046a200241186a1080010d012002280230419482c6004102200228023428020c11050021050c010b200128021841f481c6004102200128021c28020c1105000d00200241046a200110800121050b200041046a21002003417c6a22030d000b0b41012100024020050d00200128021841b982c6004101200128021c28020c11050021000b200241d0006a240020000b8c0e01087f024020002802082201450d00200028020022022001412c6c6a2103034020022204412c6a21020240024020042d00002200410d4b0d00024002400240024002400240024002400240024002400240024020000e0e0001020304050607080e090a0b0c000b200441086a280200450d0d200441046a28020010290c0d0b0240200441086a280200450d00200441046a28020010290b200441146a280200450d0c200441106a28020010290c0c0b02402004410c6a2802002201450d00200441046a28020021002001410474210103400240200041046a280200450d00200028020010290b200041106a2100200141706a22010d000b0b200441086a280200450d0b200428020410290c0b0b02402004410c6a2802002201450d00200441046a2802002100200141286c210103400240200041046a280200450d00200028020010290b0240200041106a280200450d002000410c6a28020010290b200041286a2100200141586a22010d000b0b200441086a280200450d0a200428020410290c0a0b200441086a280200450d09200441046a28020010290c090b200441086a280200450d08200441046a28020010290c080b200441086a280200450d07200441046a28020010290c070b02402004410c6a2802002200450d00200441046a280200220520004104746a21060340024020052802082201450d0020052802002100200141047421010340024020002d00004109470d00200041086a28020041ffffffff0371450d00200041046a28020010290b200041106a2100200141706a22010d000b0b200541106a21000240200541046a280200450d00200528020010290b2000210520002006470d000b0b200441086a280200450d06200428020410290c060b02402004410c6a2802002201450d00200441046a2802002100200141146c210103400240200041046a280200450d00200028020010290b200041146a21002001416c6a22010d000b0b200441086a280200450d05200428020410290c050b02402004410c6a2802002200450d00200441046a28020022052000411c6c6a2106034002402005410c6a2802002201450d0020052802042100200141047421010340024020002d00004109470d00200041086a28020041ffffffff0371450d00200041046a28020010290b200041106a2100200141706a22010d000b0b0240200541086a280200450d00200528020410290b2005411c6a21000240200541146a280200450d00200528021010290b2000210520002006470d000b0b200441086a280200450d04200428020410290c040b02402004410c6a2802002200450d00200441046a2802002205200041186c6a210603400240200541046a280200450d00200528020010290b0240200541146a2802002201450d00200528020c2100200141047421010340024020002d00004109470d00200041086a28020041ffffffff0371450d00200041046a28020010290b200041106a2100200141706a22010d000b0b200541186a21000240200541106a280200450d00200528020c10290b2000210520002006470d000b0b200441086a280200450d03200428020410290c030b02402004410c6a2802002200450d00200441046a28020022052000411c6c6a2106034002402005410c6a2802002201450d0020052802042100200141047421010340024020002d00004109470d00200041086a28020041ffffffff0371450d00200041046a28020010290b200041106a2100200141706a22010d000b0b0240200541086a280200450d00200528020410290b2005411c6a21000240200541146a280200450d00200528021010290b2000210520002006470d000b0b200441086a280200450d02200428020410290c020b0240200441046a2d0000220041024b0d0002400240024020000e03000102000b2004410c6a280200450d04200441086a28020010290c040b0240200441146a2802002201450d002004410c6a28020021002001410c6c21010340024020002802002205450d00200041046a280200450d00200510290b2000410c6a2100200141746a22010d000b0b200441106a280200450d03200428020c10290c030b0240200441146a2802002200450d002004410c6a280200220720004104746a210803402007220641106a2107024020062802042200450d0002402006410c6a2802002201450d002001410c6c21010340024020002802002205450d00200041046a280200450d00200510290b2000410c6a2100200141746a22010d000b0b200641086a280200450d00200628020410290b20072008470d000b0b200441106a280200450d02200428020c10290c020b2004410c6a280200450d01200441086a28020010290c010b0240200441086a280200450d00200441046a28020010290b0240200441146a2802002200450d00200441186a280200450d00200010290b200441246a280200450d00200441206a28020010290b20022003470d000b0b0bc30201037f23004180016b220224002000280200210002400240024002400240200128020022034110710d0020002d0000210420034120710d012004ad42ff01834101200110aa0121000c020b20002d00002104410021000340200220006a41ff006a2004410f712203413072200341d7006a2003410a491b3a00002000417f6a21002004410476410f7122040d000b20004180016a22044181014f0d022001410141e8d9c5004102200220006a4180016a410020006b10ab0121000c010b410021000340200220006a41ff006a2004410f712203413072200341376a2003410a491b3a00002000417f6a21002004410476410f7122040d000b20004180016a22044181014f0d022001410141e8d9c5004102200220006a4180016a410020006b10ab0121000b20024180016a240020000f0b2004418001103e000b2004418001103e000bd00203027f017e017f23004180016b220224002000280200210002400240024002400240200128020022034110710d002000280200210020034120710d012000ac22042004423f8722047c2004852000417f73411f76200110aa0121000c020b20002802002103410021000340200220006a41ff006a2003410f712205413072200541d7006a2005410a491b3a00002000417f6a2100200341047622030d000b20004180016a22034181014f0d022001410141e8d9c5004102200220006a4180016a410020006b10ab0121000c010b410021030340200220036a41ff006a2000410f712205413072200541376a2005410a491b3a00002003417f6a2103200041047622000d000b20034180016a22004181014f0d022001410141e8d9c5004102200220036a4180016a410020036b10ab0121000b20024180016a240020000f0b2003418001103e000b2000418001103e000bd00202027f027e23004180016b220224002000280200210002400240024002400240200128020022034110710d002000290300210420034120710d0120042004423f8722057c2005852004427f55200110aa0121000c020b20002903002104410021000340200220006a41ff006a2004a7410f712203413072200341d7006a2003410a491b3a00002000417f6a2100200442048822044200520d000b20004180016a22034181014f0d022001410141e8d9c5004102200220006a4180016a410020006b10ab0121000c010b410021000340200220006a41ff006a2004a7410f712203413072200341376a2003410a491b3a00002000417f6a2100200442048822044200520d000b20004180016a22034181014f0d022001410141e8d9c5004102200220006a4180016a410020006b10ab0121000b20024180016a240020000f0b2003418001103e000b2003418001103e000b040041000b02000b02000b2700200028020c200041106a2802001010200041146a3502001022200041186a350200102200000b08002000200110100bcd0701037f024002400240024002400240024002402001413f4b0d0002400240200241046a280200200241086a2802002203460d00200228020021040c010b200341016a22042003490d0820034101742205200420042005491b22054100480d080240024020030d002005102721040c010b200228020020032005102821040b2004450d0220022004360200200241046a2005360200200241086a28020021030b200241086a200341016a360200200420036a20014102743a00000c050b200141808001490d032001418080808004490d020c010b20054101102a000b0240024002400240200241046a280200200241086a2802002203460d00200228020021040c010b200341016a22042003490d0720034101742205200420042005491b22054100480d070240024020030d002005102721040c010b200228020020032005102821040b2004450d0120022004360200200241046a2005360200200241086a28020021030b200241086a2205200341016a360200200420036a41033a000002400240200241046a2802002204200528020022036b4104490d00200228020021040c010b200341046a22052003490d0720044101742203200520052003491b22034100480d070240024020040d002003102721040c010b200228020020042003102821040b2004450d0220022004360200200241046a2003360200200241086a28020021030b200241086a200341046a360200200420036a20013600000c040b20054101102a000b20034101102a000b024002400240200241046a2802002204200241086a28020022036b4104490d00200228020021040c010b200341046a22052003490d0520044101742203200520052003491b22034100480d050240024020040d002003102721040c010b200228020020042003102821040b2004450d0120022004360200200241046a2003360200200241086a28020021030b200241086a200341046a360200200420036a20014102744102723600000c020b20034101102a000b02400240200241046a2802002204200241086a28020022036b4102490d00200228020021040c010b200341026a22052003490d0320044101742203200520052003491b22034100480d030240024020040d002003102721040c010b200228020020042003102821040b2004450d0220022004360200200241046a2003360200200241086a28020021030b200241086a200341026a360200200420036a20014102744101723b00000b024020014103742201450d00200020016a210103402000280200200041046a280200200210c702200041086a22002001470d000b0b0f0b20034101102a000b102b000b841001047f024002400240024002400240024002400240024002400240024020002d0000220241024b0d0002400240024020020e03000102000b02400240200141046a280200200141086a2802002202460d00200128020021030c010b200241016a22032002490d0f20024101742204200320032004491b22044100480d0f0240024020020d002004102721030c010b200128020020022004102821030b2003450d0420012003360200200141046a2004360200200141086a28020021020b200141086a200241016a360200200320026a41003a0000200041086a2802002000410c6a280200200110c7020f0b02400240200141046a280200200141086a2802002202460d00200128020021030c010b200241016a22032002490d0e20024101742204200320032004491b22044100480d0e0240024020020d002004102721030c010b200128020020022004102821030b2003450d0420012003360200200141046a2004360200200141086a28020021020b200141086a2204200241016a360200200320026a41013a000020002d0001210502400240200141046a28020020042802002202460d00200128020021030c010b200241016a22032002490d0e20024101742204200320032004491b22044100480d0e0240024020020d002004102721030c010b200128020020022004102821030b2003450d0520012003360200200141046a2004360200200141086a28020021020b200141086a2204200241016a360200200320026a20053a0000200041086a2802002000410c6a280200200110c702200041146a280200200041186a280200200110c70202400240200141046a28020020042802002202460d00200128020021030c010b200241016a22032002490d0e20024101742204200320032004491b22044100480d0e0240024020020d002004102721030c010b200128020020022004102821030b2003450d0620012003360200200141046a2004360200200141086a28020021020b200141086a200241016a360200200320026a20002d00023a00000f0b02400240200141046a280200200141086a2802002202460d00200128020021030c010b200241016a22032002490d0d20024101742204200320032004491b22044100480d0d0240024020020d002004102721030c010b200128020020022004102821030b2003450d0620012003360200200141046a2004360200200141086a28020021020b200141086a2204200241016a360200200320026a41023a000020002d0001210502400240200141046a28020020042802002202460d00200128020021030c010b200241016a22032002490d0d20024101742204200320032004491b22044100480d0d0240024020020d002004102721030c010b200128020020022004102821030b2003450d0720012003360200200141046a2004360200200141086a28020021020b200141086a200241016a360200200320026a20053a0000200041086a2802002000410c6a280200200110c702200041146a280200200041186a280200200110c702200041206a280200200041246a280200200110c70220002d0002220041044b0d000240024002400240024020000e050001020304000b02400240200141046a280200200141086a2802002200460d00200128020021020c010b200041016a22022000490d1120004101742203200220022003491b22034100480d110240024020000d002003102721020c010b200128020020002003102821020b2002450d0c20012002360200200141046a2003360200200141086a28020021000b200141086a200041016a360200200220006a41003a00000f0b02400240200141046a280200200141086a2802002200460d00200128020021020c010b200041016a22022000490d1020004101742203200220022003491b22034100480d100240024020000d002003102721020c010b200128020020002003102821020b2002450d0c20012002360200200141046a2003360200200141086a28020021000b200141086a200041016a360200200220006a41013a00000f0b02400240200141046a280200200141086a2802002200460d00200128020021020c010b200041016a22022000490d0f20004101742203200220022003491b22034100480d0f0240024020000d002003102721020c010b200128020020002003102821020b2002450d0c20012002360200200141046a2003360200200141086a28020021000b200141086a200041016a360200200220006a41023a00000f0b02400240200141046a280200200141086a2802002200460d00200128020021020c010b200041016a22022000490d0e20004101742203200220022003491b22034100480d0e0240024020000d002003102721020c010b200128020020002003102821020b2002450d0c20012002360200200141046a2003360200200141086a28020021000b200141086a200041016a360200200220006a41033a00000f0b02400240200141046a280200200141086a2802002200460d00200128020021020c010b200041016a22022000490d0d20004101742203200220022003491b22034100480d0d0240024020000d002003102721020c010b200128020020002003102821020b2002450d0c20012002360200200141046a2003360200200141086a28020021000b200141086a200041016a360200200220006a41043a00000b0f0b20044101102a000b20044101102a000b20044101102a000b20044101102a000b20044101102a000b20044101102a000b20034101102a000b20034101102a000b20034101102a000b20034101102a000b20034101102a000b102b000bd50101027f200028020421020240024020002802004101460d00200041086a2802002200200110c6022000450d01200041186c2103200241146a21000340200041706a280200200041746a280200200110c7022000417c6a2802002000280200200110c702200041186a2100200341686a22030d000c020b0b2000410c6a2802002200200110c6022000450d00200041186c2103200241146a21000340200041706a280200200041746a280200200110c7022000417c6a2802002000280200200110c702200041186a2100200341686a22030d000b0b0bc806010a7f230041106b22022400200028020421030240024002400240024020002802004101460d00200041086a2802002200200110c6022000450d01200041d8006c2104410021050340200320056a220041046a280200200041086a280200200110c702200041d4006a2d0000210602400240200141046a2207280200200141086a22082802002209460d002001280200210a0c010b200941016a220a2009490d062009410174220b200a200a200b491b220b4100480d060240024020090d00200b1027210a0c010b20012802002009200b1028210a0b200a450d042001200a3602002007200b360200200828020021090b2008200941016a360200200a20096a20063a00002000410c6a200110ae0402400240200041346a2802004101460d002002200041386a2802002000413c6a28020028020c110000200228020022092002280208200110c7022002280204450d01200910290c010b200041386a280200200041c0006a280200200110c7020b200041c8006a2802002003200541d00041cc00200041c4006a2802004101461b6a6a280200200110ad042004200541d8006a2205470d000c020b0b2000410c6a2802002200200110c6022000450d00200041d8006c2104410021050340200320056a220041046a280200200041086a280200200110c702200041d4006a2d0000210602400240200141046a2207280200200141086a22082802002209460d002001280200210a0c010b200941016a220a2009490d052009410174220b200a200a200b491b220b4100480d050240024020090d00200b1027210a0c010b20012802002009200b1028210a0b200a450d042001200a3602002007200b360200200828020021090b2008200941016a360200200a20096a20063a00002000410c6a200110ae0402400240200041346a2802004101460d002002200041386a2802002000413c6a28020028020c110000200228020022092002280208200110c7022002280204450d01200910290c010b200041386a280200200041c0006a280200200110c7020b200041c8006a2802002003200541d00041cc00200041c4006a2802004101461b6a6a280200200110ad042004200541d8006a2205470d000b0b200241106a24000f0b200b4101102a000b200b4101102a000b102b000b0600200010230b0600200010240b2801017f0240200210232203450d002003200020022001200120024b1b10ce041a200010240b20030b1c01017f0240200010232201450d0020014100200010cd041a0b20010bb10101037f0240024002400240200028020022002802042203200028020822046b2002490d00200028020021030c010b200420026a22052004490d0220034101742204200520052004491b22044100480d020240024020030d002004102721030c010b200028020020032004102821030b2003450d012000200436020420002003360200200028020821040b2000200420026a360208200320046a2001200210ce041a41000f0b20044101102a000b102b000ba70401047f230041106b220224002000280200210002400240024002400240024002402001418001490d002002410036020c2001418010490d0102402001418080044f0d0020022001413f71418001723a000e20022001410676413f71418001723a000d20022001410c76410f7141e001723a000c410321010c040b20022001413f71418001723a000f2002200141127641f001723a000c20022001410676413f71418001723a000e20022001410c76413f71418001723a000d410421010c030b0240200028020822032000280204470d00200341016a22042003490d0620034101742205200420042005491b22044100480d060240024020030d002004102721030c010b200028020020032004102821030b2003450d022000200436020420002003360200200028020821030b200028020020036a20013a00002000200028020841016a3602080c030b20022001413f71418001723a000d20022001410676411f7141c001723a000c410221010c010b20044101102a000b0240024020002802042204200028020822036b2001490d00200028020021040c010b200320016a22052003490d0320044101742203200520052003491b22034100480d030240024020040d002003102721040c010b200028020020042003102821040b2004450d022000200336020420002004360200200028020821030b2000200320016a360208200420036a2002410c6a200110ce041a0b200241106a240041000f0b20034101102a000b102b000b6401017f230041206b2202240020022000280200360204200241086a41106a200141106a290200370300200241086a41086a200141086a29020037030020022001290200370308200241046a4180d3c500200241086a1091042101200241206a240020010b0c0042ebbe8cdadd9294ae070b5401017f024002402001418080c400460d0041012104200028021820012000411c6a2802002802101104000d010b024020020d0041000f0b2000280218200220032000411c6a28020028020c11050021040b20040bcd0801067f230041f0006b220424002004200336020c20042002360208410121052001210602402001418102490d00410020016b2107418002210803400240200820014f0d00200020086a2c000041bf7f4c0d0041002105200821060c020b2008417f6a21064100210520084101460d01200720086a21092006210820094101470d000b0b200420063602142004200036021020044100410520051b36021c200441b8d6c50041ead9c50020051b3602180240024002400240200220014b22080d00200320014b0d00200220034b0d01024002402002450d0020012002460d00200120024d0d01200020026a2c00004140480d010b200321020b200420023602202002450d0220022001460d02200141016a210903400240200220014f0d00200020026a2c000041404e0d040b2002417f6a210820024101460d0420092002462106200821022006450d000c040b0b20042002200320081b360228200441306a41146a4103360200200441c8006a41146a4102360200200441d4006a410236020020044203370234200441f0d9c5003602302004410136024c2004200441c8006a3602402004200441186a3602582004200441106a3602502004200441286a360248200441306a4188dac5001057000b200441e4006a4102360200200441c8006a41146a4102360200200441d4006a4101360200200441306a41146a41043602002004420437023420044198dac5003602302004410136024c2004200441c8006a3602402004200441186a3602602004200441106a36025820042004410c6a3602502004200441086a360248200441306a41b8dac5001057000b200221080b024020082001460d00410121060240024002400240200020086a22092c00002202417f4a0d0041002105200020016a220621010240200941016a2006460d00200941026a210120092d0001413f7121050b2002411f712109200241ff017141df014b0d01200520094106747221010c020b2004200241ff0171360224200441286a21020c020b4100210020062107024020012006460d00200141016a210720012d0000413f7121000b200020054106747221010240200241ff017141f0014f0d0020012009410c747221010c010b41002102024020072006460d0020072d0000413f7121020b20014106742009411274418080f00071722002722201418080c400460d020b2004200136022441012106200441286a21022001418001490d00410221062001418010490d0041034104200141808004491b21060b200420083602282004200620086a36022c200441306a41146a4105360200200441ec006a4102360200200441e4006a4102360200200441c8006a41146a412b360200200441d4006a412c36020020044205370234200441e0dac500360230200420023602582004410136024c2004200441c8006a3602402004200441186a3602682004200441106a3602602004200441246a3602502004200441206a360248200441306a4188dbc5001057000b41c8dac5001058000b7f01037f230041206b2202240002402000280200200110be040d002001411c6a2802002103200128021821042002411c6a4100360200200241b8d6c5003602182002420137020c200241f0dbc50036020820042003200241086a1091040d002000280204200110be042101200241206a240020010f0b200241206a240041010bf00a03037f017e047f410121020240200128021841272001411c6a2802002802101104000d004102210302400240024002402000280200220241776a2200411e4d0d00200241dc00470d010c020b41f400210402400240024020000e1f05010303000303030303030303030303030303030303030303040303030304050b41f20021040c010b41ee0021040b0c020b02400240200210bd04450d00200241017267410276410773ad4280808080d0008421050c010b024002400240200241808004490d000240024002402002418080084f0d0020024180fe0371410876210641e1edc500210041002107200241ff017121040340200041026a2108200720002d000122036a2109024020002d000022002006460d00200020064b0d062009210720082100200841a7eec500470d010c060b20092007490d02200941a6014b0d03200741a7eec5006a2100024003402003450d012003417f6a210320002d00002107200041016a210020072004470d000c080b0b2009210720082100200841a7eec500470d000c050b0b200241ef83384b0d04200241e28b746a41e28d2c490d042002419fa8746a419f18490d04200241dee2746a410e490d04200241feffff0071419ef00a460d04200241a9b2756a4129490d04200241cb91756a410a4d0d0441012103200221040c070b20072009103e000b200941a601107f000b20024180fe0371410876210641b0e8c500210041002107200241ff01712104024002400340200041026a2108200720002d000122036a2109024020002d000022002006460d00200020064b0d03200921072008210020084182e9c500470d010c030b024020092007490d00200941a5024b0d0220074182e9c5006a2100024003402003450d012003417f6a210320002d00002107200041016a210020072004470d000c070b0b200921072008210020084182e9c500470d010c030b0b20072009103e000b200941a502107f000b200241ffff0371210741a7ebc50021034101210402400340200341016a21090240024020032d0000220041187441187522084100480d00200921030c010b200941e1edc500460d02200841ff007141087420032d0001722100200341026a21030b0240200720006b22074100480d0020044101732104200341e1edc500470d010b0b4101210320044101710d040c020b41c8dac5001058000b200241ffff0371210741cdefc50021034101210402400340200341016a21090240024020032d0000220041187441187522084100480d00200921030c010b200941e5f2c500460d02200841ff007141087420032d0001722100200341026a21030b0240200720006b22074100480d0020044101732104200341e5f2c500470d010b0b4101210320044101710d030c010b41c8dac5001058000b200241017267410276410773ad4280808080d0008421050b41032103200221040c010b200221040b03402003210741dc0021004101210241012103024002400240024020070e0401020300010b024002400240024002402005422088a741ff01710e06050403020100050b200542ffffffff8f60834280808080c000842105410321030c060b200542ffffffff8f608342808080803084210541f5002100410321030c050b200542ffffffff8f608342808080802084210541fb002100410321030c040b20042005a72207410274411c7176410f712203413072200341d7006a2003410a491b210002402007450d002005427f7c42ffffffff0f83200542808080807083842105410321030c040b200542ffffffff8f6083428080808010842105410321030c030b200542ffffffff8f6083210541fd002100410321030c020b20012802184127200128021c2802101104000f0b41002103200421000b20012802182000200128021c280210110400450d000b0b20020b950201017f024002402000418010490d00024002400240024002400240200041808004490d002000410c7641706a2201418002490d014188f3c50020014180021037000b200041067641606a220141df074b0d01200141d0dec5006a2d0000220141c9004b0d02200141037441e0f3c5006a21010c060b200141b0e6c5006a2d00004106742000410676413f7172220141ff034b0d02200141b0f8c5006a2d0000220141394b0d03200141037441b0fcc5006a21010c050b41e8f2c500200141e0071037000b41f8f2c500200141ca001037000b4198f3c50020014180041037000b41a8f3c5002001413a1037000b200041037641f8ffffff017141b8dcc5006a21010b200129030042012000413f71ad86834200520ba40201037f23004180016b2202240002400240024002400240200128020022034110710d0020034120710d012000ad4101200110aa0121000c020b410021030340200220036a41ff006a2000410f712204413072200441d7006a2004410a491b3a00002003417f6a2103200041047622000d000b20034180016a22004181014f0d022001410141e8d9c5004102200220036a4180016a410020036b10ab0121000c010b410021030340200220036a41ff006a2000410f712204413072200441376a2004410a491b3a00002003417f6a2103200041047622000d000b20034180016a22004181014f0d022001410141e8d9c5004102200220036a4180016a410020036b10ab0121000b20024180016a240020000f0b2000418001103e000b2000418001103e000b0e0020003502004101200110aa010b1c002001280218418181c600410b2001411c6a28020028020c1105000b1c002001280218418c81c600410e2001411c6a28020028020c1105000b140020002802002001200028020428020c1104000bc30501077f410021040240024020024103712205450d00410420056b2205450d00200220032005200520034b1b22046a210641002105200141ff017121072004210820022109024003400240200620096b41034b0d0041002107200141ff0171210603402008450d04200920076a210a2008417f6a2108200741016a2107200a2d0000220a2006470d000b2005200a200141ff01714641016a4101716a20076a417f6a21050c020b200520092d0000220a2007476a2105200a2007460d012005200941016a2d0000220a2007476a2105200a2007460d012005200941026a2d0000220a2007476a2105200a2007460d012005200941036a2d0000220a2007476a21052008417c6a2108200941046a2109200a2007470d000b0b410121090c010b200141ff017121070240024020034108490d002004200341786a220a4b0d00200741818284086c210502400340200220046a220941046a2802002005732208417f73200841fffdfb776a7120092802002005732209417f73200941fffdfb776a7172418081828478710d01200441086a2204200a4d0d000b0b200420034b0d010b200220046a2109200220036a2102200320046b2108410021050240024003400240200220096b41034b0d0041002107200141ff0171210203402008450d04200920076a210a2008417f6a2108200741016a2107200a2d0000220a2002470d000b200a200141ff01714641016a41017120056a20076a417f6a21050c020b200520092d0000220a2007476a2105200a2007460d012005200941016a2d0000220a2007476a2105200a2007460d012005200941026a2d0000220a2007476a2105200a2007460d012005200941036a2d0000220a2007476a21052008417c6a2108200941046a2109200a2007470d000b0b41012109200520046a21050c020b41002109200520076a20046a21050c010b20042003103e000b20002005360204200020093602000b2701017f2000280200220128020020012802042000280204280200200028020828020010ba04000ba60401077f230041306b220324000240024020020d00410021040c010b200341286a210502400240024002400340024020002802082d0000450d00200028020041ed81c6004104200028020428020c1105000d050b2003410a3602282003428a808080103703202003200236021c200341003602182003200236021420032001360210200341086a410a2001200210c304024002400240024020032802084101470d00200328020c210403402003200420032802186a41016a2204360218024002402004200328022422064f0d00200328021421070c010b200328021422072004490d00200641054f0d072003280210200420066b22086a22092005460d0420092005200610d004450d040b200328021c22092004490d0220072009490d0220032006200341106a6a41176a2d0000200328021020046a200920046b10c3042003280204210420032802004101460d000b0b2003200328021c3602180b200028020841003a0000200221040c010b200028020841013a0000200841016a21040b2000280204210920002802002106024020044520022004467222070d00200220044d0d03200120046a2c000041bf7f4c0d030b200620012004200928020c1105000d04024020070d00200220044d0d04200120046a2c000041bf7f4c0d040b200120046a2101200220046b22020d000b410021040c040b20064104107f000b200120024100200410ba04000b200120022004200210ba04000b410121040b200341306a240020040b02000bfa0101017f230041106b220224002002410036020c0240024002402001418001490d002001418010490d0102402001418080044f0d0020022001413f71418001723a000e20022001410676413f71418001723a000d20022001410c76410f7141e001723a000c410321010c030b20022001413f71418001723a000f2002200141127641f001723a000c20022001410676413f71418001723a000e20022001410c76413f71418001723a000d410421010c020b200220013a000c410121010c010b20022001413f71418001723a000d20022001410676411f7141c001723a000c410221010b20002002410c6a200110c5042101200241106a240020010b6101017f230041206b2202240020022000360204200241086a41106a200141106a290200370300200241086a41086a200141086a29020037030020022001290200370308200241046a419882c600200241086a1091042101200241206a240020010b0e0020002802002001200210c5040b810201017f230041106b22022400200028020021002002410036020c0240024002402001418001490d002001418010490d0102402001418080044f0d0020022001413f71418001723a000e20022001410676413f71418001723a000d20022001410c76410f7141e001723a000c410321010c030b20022001413f71418001723a000f2002200141127641f001723a000c20022001410676413f71418001723a000e20022001410c76413f71418001723a000d410421010c020b200220013a000c410121010c010b20022001413f71418001723a000d20022001410676411f7141c001723a000c410221010b20002002410c6a200110c5042101200241106a240020010b6401017f230041206b2202240020022000280200360204200241086a41106a200141106a290200370300200241086a41086a200141086a29020037030020022001290200370308200241046a419882c600200241086a1091042101200241206a240020010b1c00200128021841bb82c60041052001411c6a28020028020c1105000b2c01017f02402002450d00200021030340200320013a0000200341016a21032002417f6a22020d000b0b20000b3601017f02402002450d00200021030340200320012d00003a0000200341016a2103200141016a21012002417f6a22020d000b0b20000b7101017f0240024020012000490d002002450d01200021030340200320012d00003a0000200141016a2101200341016a21032002417f6a22020d000c020b0b2002450d002001417f6a21012000417f6a21030340200320026a200120026a2d00003a00002002417f6a22020d000b0b20000b4a01037f4100210302402002450d000240034020002d0000220420012d00002205470d01200141016a2101200041016a21002002417f6a2202450d020c000b0b200420056b21030b20030b5701017e02400240200341c000710d002003450d012001410020036b413f71ad8820022003413f71ad220486842102200120048621010c010b20012003413f71ad862102420021010b20002001370300200020023703080b5701017e02400240200341c000710d002003450d0120012003413f71ad2204882002410020036b413f71ad86842101200220048821020c010b20022003413f71ad882101420021020b20002001370300200020023703080b7501027e200020034220882205200142208822067e200320027e7c200420017e7c200342ffffffff0f832203200142ffffffff0f8322017e2204422088200320067e7c22034220887c200342ffffffff0f83200520017e7c22034220887c37030820002003422086200442ffffffff0f83843703000b3e01017f230041106b2205240020052001200220032004410010d604200529030021012000200541086a29030037030820002001370300200541106a24000b4c01017f230041206b22052400200542003703182005420037031020052001200220032004200541106a10d604200529031021012000200529031837030820002001370300200541206a24000be20502037f067e230041306b2206240002400240024002400240024002400240024002402002500d002003500d012004500d02200479a7200279a76b2207413f4b0d0341ff0020076b2108200741016a21070c080b02402004500d0020050d040c060b024002402005450d0020034200510d0620054200370308200520012003823703000c010b20034200510d050b200120038021010c060b2004500d030240024002402001500d0020047b4201510d01200479a7200279a76b2207413e4b0d0241ff0020076b2108200741016a21070c090b02402005450d0020054200370300200520022004823703080b200220048021010c070b02402005450d002005200137030020052004427f7c2002833703080b200220047a423f838821010c060b2005450d040c020b024020037b4201510d0041bf7f200379a7200279a76b22076b2108200741c1006a21070c060b02402005450d002005420037030820052003427f7c2001833703000b20034201510d06200641206a2001200220037aa710d204200641286a2903002102200629032021010c060b2005450d020b2005200137030020052002370308420021010c020b00000b420021010b420021020c010b200620012002200841ff007110d104200641106a20012002200741ff007110d204200641086a2903002102200641106a41086a2903002109200629030021012006290310210a0240024020070d004200210b4200210c0c010b4200210c4200210d03402009420186200a423f8884220b200b427f8520047c200a4201862002423f8884220a427f85220b20037c200b54ad7c423f87220b2004837d200a200b200383220e54ad7d2109200a200e7d210a420020024201862001423f8884842102200d2001420186842101200b420183220b210d2007417f6a22070d000b0b02402005450d002005200a370300200520093703080b200c20024201862001423f8884842102200b20014201868421010b2000200137030020002002370308200641306a24000b0bdb82060200418080c0000bc08206180010001d0000008858110013000000db03000009000000617373657274696f6e206661696c65643a20696e646578203c206c656e0000005000100043000000fb0a00003000000000000000000000002f72757374632f633739386466666163396463386338323337346462343866356234373436393063633665393638362f7372632f6c6962616c6c6f632f7665632e7273005000100043000000070b00002c0000004469676573744974656d206e6f7420657175616c3501100036000000326811005b000000fc0100000500000000000000000000000000000000000000f80010003d000000326811005b0000000302000005000000736869667465642073756666696369656e74206269747320726967687420746f206c656164206f6e6c79206c656164696e67207a65726f733b2071656450726576696f7573206d617463682061726d206d61746368657320616e7974696e67206c657373207468616e20325e33303b20716564003501100036000000326811005b000000c801000005000000000000000000000000000000326811005b000000cf0100000500000076616c69646174696f6e206572726f72c80110007c00000044021000490000007a00000006000000657865632e7072656661625f6d6f64756c652e696e697469616c2063616e27742062652067726561746572207468616e20657865632e7072656661625f6d6f64756c652e6d6178696d756d3b0a09090909090974687573204d656d6f72793a3a6e6577206d757374206e6f74206661696c3b0a0909090909097165642f686f6d652f616e6472652f576f726b62656e63682f706172697479746563682f7375627374726174652f73726d6c2f636f6e7472616374732f7372632f7761736d2f6d6f642e727300000000000000140310000a000000000000000010110002000000000000000000000020031000010000000000000000000000280310000d0000000000000034e81000010000000000000000000000380310000100000000000000000000003c8310000800000000000000400310000400000000000000000000006003100001000000000000004e65774163636f756e740000ab0310001b0000005265617065644163636f756e740000009403100017000000611011000900000061101100090000006a101100070000006a10110007000000680310002c000000205472616e7366657220737563636565646564202866726f6d2c20746f2c2076616c75652c2066656573292e20416e206163636f756e7420776173207265617065642e2041206e6577206163636f756e742077617320637265617465642e76657374696e672062616c616e636520746f6f206869676820746f2073656e642076616c75656163636f756e74206c6971756964697479207265737472696374696f6e732070726576656e74207769746864726177616c62656e6566696369617279206163636f756e74206d757374207072652d6578697374746f6f2066657720667265652066756e647320696e206163636f756e747061796d656e7420776f756c64206b696c6c206163636f756e74000000000000a40410001100000000000000b8041000020000000000000000000000c80410000100000000000000486561727462656174526563656976656400000060e810000b000000160510000b000000d0041000460000002041206e6577206865617274626561742077617320726563656976656420617420746869732060426c6f636b4e756d626572602066726f6d2060417574686f72697479496460417574686f72697479496454696d657374616d702055706461746542616c616e63657320546f74616c49737375616e636554696d657374616d7020526563656e7448696e74737405100031000000a50510004b0000007e0000000400000046696e616c2068696e74206d7573742062652075706461746564206f6e6c79206f6e636520696e2074686520626c6f636b2f686f6d652f616e6472652f576f726b62656e63682f706172697479746563682f7375627374726174652f73726d6c2f66696e616c6974792d747261636b65722f7372632f6c69622e72730806100023000000a50510004b0000007f0000000400000046696e616c697a6564206865696768742061626f766520626c6f636b206e756d62657242616c616e636573204672656542616c616e636542616c616e63657320526573657276656442616c616e636542616c616e636573204c6f636b730000002d00000008000000040000002e0000004765747320616e64206465636f6465732066696e616c206e756d62657220696e686572656e74206461746142616c616e6365732056657374696e6700000000000c07100008000000000000001407100002000000000000000000000044071000170000000000000000000000fc0710000b0000000000000008081000030000000000000000000000500810000d000000000000007472616e7366657200000000b58f10000400000000000000b01d11002300000000000000ee25110005000000000000004d0a1000130000006c0a100036000000386b110000000000a20a100042000000e40a1000480000002c0b100045000000710b10002d000000386b1100000000009e0b100046000000386b1100000000007e1b11000b000000e40b10004c000000300c100033000000630c10005a000000386b110000000000bd0c100013000000386b110000000000d00c100054000000240d10004b0000006f0d100035000000a40d100037000000db0d100056000000386b1100000000001f1c11000c0000007365745f62616c616e63650000000000db2a10000300000000000000b01d11002300000000000000450a100008000000000000004d0a10001300000000000000600a10000c000000000000004d0a100013000000b808100025000000386b110000000000dd0810004800000025091000420000006709100046000000ad0910003a000000386b110000000000e70910002d000000386b1100000000007e1b11000b000000891b110020000000140a1000310000001f1c11000c00000020536574207468652062616c616e636573206f66206120676976656e206163636f756e742e20546869732077696c6c20616c74657220604672656542616c616e63656020616e642060526573657276656442616c616e63656020696e2073746f726167652e2069742077696c6c20616c736f2064656372656173652074686520746f74616c2069737375616e6365206f66207468652073797374656d202860546f74616c49737375616e636560292e20496620746865206e65772066726565206f722072657365727665642062616c616e63652069732062656c6f7720746865206578697374656e7469616c206465706f7369742c2069742077696c6c20726573657420746865206163636f756e74206e6f6e636520286073797374656d3a3a4163636f756e744e6f6e636560292e20546865206469737061746368206f726967696e20666f7220746869732063616c6c2069732060726f6f74602e202d20436f6e7461696e732061206c696d69746564206e756d626572206f6620726561647320616e64207772697465732e6e65775f66726565436f6d706163743c543a3a42616c616e63653e6e65775f7265736572766564205472616e7366657220736f6d65206c697175696420667265652062616c616e636520746f20616e6f74686572206163636f756e742e20607472616e73666572602077696c6c207365742074686520604672656542616c616e636560206f66207468652073656e64657220616e642072656365697665722e2049742077696c6c2064656372656173652074686520746f74616c2069737375616e6365206f66207468652073797374656d2062792074686520605472616e73666572466565602e204966207468652073656e6465722773206163636f756e742069732062656c6f7720746865206578697374656e7469616c206465706f736974206173206120726573756c74206f6620746865207472616e736665722c20746865206163636f756e742077696c6c206265207265617065642e20546865206469737061746368206f726967696e20666f7220746869732063616c6c206d75737420626520605369676e65646020627920746865207472616e736163746f722e202d20446570656e64656e74206f6e20617267756d656e747320627574206e6f7420637269746963616c2c20676976656e2070726f70657220696d706c656d656e746174696f6e7320666f72202020696e70757420636f6e6669672074797065732e205365652072656c617465642066756e6374696f6e732062656c6f772e202d20497420636f6e7461696e732061206c696d69746564206e756d626572206f6620726561647320616e642077726974657320696e7465726e616c6c7920616e64206e6f20636f6d706c657820636f6d7075746174696f6e2e2052656c617465642066756e6374696f6e733a2020202d2060656e737572655f63616e5f77697468647261776020697320616c776179732063616c6c656420696e7465726e616c6c792062757420686173206120626f756e64656420636f6d706c65786974792e2020202d205472616e7366657272696e672062616c616e63657320746f206163636f756e7473207468617420646964206e6f74206578697374206265666f72652077696c6c20636175736520202020202060543a3a4f6e4e65774163636f756e743a3a6f6e5f6e65775f6163636f756e746020746f2062652063616c6c65642e2020202d2052656d6f76696e6720656e6f7567682066756e64732066726f6d20616e206163636f756e742077696c6c2074726967676572202020202060543a3a4475737452656d6f76616c3a3a6f6e5f756e62616c616e6365646020616e642060543a3a4f6e4672656542616c616e63655a65726f3a3a6f6e5f667265655f62616c616e63655f7a65726f602e00000000000000ec0f10000d0000000000000000000000f90f10000a0000000000000000000000000000000000000000000000000000000000000040811100bc101000000000000000000004101000010000000000000001000000000000000c101000070000000101000000000000423111000c00000000000000131010002b0000000000000000000000000000000000000040811100001b100000000000000000004010100001000000000000000000000000000000481010000b0000000101000000000000423111000c00000000000000f90f10000a0000000000000000000000000000000000000040811100bc1010000000000000000000541010000b000000000000000100000000000000ac1010000f0000000101000000000000423111000c00000000000000f90f10000a0000000000000000000000000000000000000040811100bc1010000000000000000000cc1010000b00000000000000010000000000000024111000050000000101000000000000423111000c00000000000000291110002c000000000000000000000000000000000000004081110058111000000000000000000068111000010000000000000001000000546f74616c49737375616e6365543a3a42616c616e636500991610002600000056657374696e6756657374696e675363686564756c653c543a3a42616c616e63652c20543a3a426c6f636b4e756d6265723e000063161000360000004672656542616c616e636500e913100027000000386b1100000000001014100050000000601410005d000000bd14100055000000121510004f0000006115100051000000b215100015000000386b110000000000c7151000570000001e16100045000000526573657276656442616c616e6365002f0000000000000001000000300000009e1110005d000000fb11100027000000386b110000000000221210005b0000007d12100049000000386b110000000000c61210005d000000231310002d000000386b1100000000005013100053000000a3131000460000004c6f636b735665633c42616c616e63654c6f636b3c543a3a42616c616e63652c20543a3a426c6f636b4e756d6265723e3e0000002f000000000000000100000031000000701110002e00000020416e79206c6971756964697479206c6f636b73206f6e20736f6d65206163636f756e742062616c616e6365732e2054686520616d6f756e74206f66207468652062616c616e6365206f66206120676976656e206163636f756e7420746861742069732065787465726e616c6c792072657365727665643b20746869732063616e207374696c6c2067657420736c61736865642c20627574206765747320736c6173686564206c617374206f6620616c6c2e20546869732062616c616e63652069732061202772657365727665272062616c616e63652074686174206f746865722073756273797374656d732075736520696e206f7264657220746f2073657420617369646520746f6b656e73207468617420617265207374696c6c20276f776e65642720627920746865206163636f756e7420686f6c6465722c20627574207768696368206172652073757370656e6461626c652e205768656e20746869732062616c616e63652066616c6c732062656c6f77207468652076616c7565206f6620604578697374656e7469616c4465706f736974602c207468656e2074686973202772657365727665206163636f756e74272069732064656c657465643a207370656369666963616c6c792c2060526573657276656442616c616e6365602e206073797374656d3a3a4163636f756e744e6f6e63656020697320616c736f2064656c6574656420696620604672656542616c616e63656020697320616c736f207a65726f2028697420616c736f206765747320636f6c6c617073656420746f207a65726f2069662069742065766572206265636f6d6573206c657373207468616e20604578697374656e7469616c4465706f736974602e2920546865202766726565272062616c616e6365206f66206120676976656e206163636f756e742e205468697320697320746865206f6e6c792062616c616e63652074686174206d61747465727320696e207465726d73206f66206d6f7374206f7065726174696f6e73206f6e20746f6b656e732e20497420616c6f6e65206973207573656420746f2064657465726d696e65207468652062616c616e6365207768656e20696e2074686520636f6e747261637420657865637574696f6e20656e7669726f6e6d656e742e205768656e20746869732062616c616e63652066616c6c732062656c6f77207468652076616c7565206f6620604578697374656e7469616c4465706f736974602c207468656e20746865202763757272656e74206163636f756e74272069732064656c657465643a207370656369666963616c6c7920604672656542616c616e6365602e20467572746865722c2074686520604f6e4672656542616c616e63655a65726f602063616c6c6261636b20697320696e766f6b65642c20676976696e672061206368616e636520746f2065787465726e616c206d6f64756c657320746f20636c65616e2075702064617461206173736f6369617465642077697468207468652064656c65746564206163636f756e742e206073797374656d3a3a4163636f756e744e6f6e63656020697320616c736f2064656c657465642069662060526573657276656442616c616e63656020697320616c736f207a65726f2028697420616c736f206765747320636f6c6c617073656420746f207a65726f2069662069742065766572206265636f6d6573206c657373207468616e20604578697374656e7469616c4465706f736974602e20496e666f726d6174696f6e20726567617264696e67207468652076657374696e67206f66206120676976656e206163636f756e742e2054686520746f74616c20756e6974732069737375656420696e207468652073797374656d2e0000000000d81710001200000000000000f90f10000a0000000000000040811100ec1710000000000000000000fc171000010000000000000000000000949f10000b00000000000000f90f10000a0000000000000040811100041810000000000000000000a09f1000010000000000000000000000a89f10000b00000000000000f90f10000a0000000000000040811100041810000000000000000000b49f1000010000000000000000000000bc9f10001200000000000000f90f10000a0000000000000040811100041810000000000000000000d09f1000010000000000000000000000d89f10001200000000000000f90f10000a0000000000000040811100141810000000000000000000fc9f100001000000000000004578697374656e7469616c4465706f73697400002f00000000000000010000003200000024181000350000002f0000000000000001000000330000002f00000000000000010000003400000020546865206d696e696d756d20616d6f756e7420726571756972656420746f206b65657020616e206163636f756e74206f70656e2e496d4f6e6c696e6520476f737369704174496d4f6e6c696e652052656365697665644865617274626561747373726d6c2f696d2d6f6e6c696e652d776f726b65722d737461747573576974686472617720686173206265656e20636865636b65642061626f76653b0a090909647565735f6c696d69746564203c2072656e745f627564676574203c2062616c616e6365202d2073756273697374656e6365203c2062616c616e6365202d206578697374656e7469616c5f6465706f7369743b0a09090971656400000000004c191000090000000000000058191000020000000000000000000000386b11000000000000000000686561727462656174000000000000004c1910000900000000000000881910002900000000000000b11910000a00000000000000d5ca1000070000004865617274626561743c543a3a426c6f636b4e756d6265722c20543a3a417574686f7269747949643e5f7369676e61747572650000000000c41a10000800000000000000000000001bf610000e0000000000000000000000000000000000000000000000000000000000000040811100cc1a10000000000000000000386b110000000000000000000100000000000000dc1a10000f0000000000000000000000eb1a1000150000000000000000000000000000000000000000000000000000000000000040811100001b10000000000000000000386b110000000000000000000000000000000000101b1000120000000201010000000000eb1a10001500000000000000221b10000e00000000000000d5ca1000070000000000000040811100301b10000000000000000000386b1100000000000000000001000000476f7373697041742f0000000000000001000000350000004c6173744e6577457261537461727473657373696f6e3a3a53657373696f6e496e6465782f000000000000000100000036000000526563656976656448656172746265617473543a3a417574686f7269747949642f00000000000000010000003100000000000000a83b11000e00000000000000eb1a1000150000000000000040811100781b10000000000000000000c83b110001000000000000002f00000000000000010000003700000054696d657374616d70204f72646572656448696e747354696d657374616d70204d656469616e616c77617973206174206c65617374206f6e6520726563656e742073616d706c653b20716564726563656e7420616e64206f72646572656420636f6e7461696e207468652073616d65206974656d733b20716564000038000000040000000400000039000000881c100043000000a50510004b000000b700000004000000401c100048000000820a00000a000000000000002f72757374632f633739386466666163396463386338323337346462343866356234373436393063633665393638362f7372632f6c6962636f72652f736c6963652f6d6f642e72737072756e696e672064696374617465642062792077696e646f775f73697a6520776869636820697320616c776179732073617475726174656420617420313b207165646e6f7420656e6f75676820667265652066756e6473000000000c1d10000a00000000000000181d1000010000000000000000000000301d1000020000000000000066696e616c5f68696e74000000000000c5351000040000000000000073f3100017000000401d10003d0000007d1d10001b0000002048696e7420746861742074686520617574686f72206f66207468697320626c6f636b207468696e6b732074686520626573742066696e616c697a656420626c6f636b2069732074686520676976656e206e756d6265722e00000000081e10000a000000000000001bf610000e0000000000000040811100141e10000000000000000000241e10000100000000000000000000002c1e10000d000000000000001bf610000e00000000000000408111003c1e100000000000000000004c1e1000010000000000000057696e646f7753697a6500002f00000000000000010000003a0000009b1e1000460000005265706f72744c6174656e63790000002f00000000000000010000003b000000541e100047000000205468652064656c617920616674657220776869636820706f696e74207468696e6773206265636f6d6520737573706963696f75732e2044656661756c7420697320313030302e20546865206e756d626572206f6620726563656e742073616d706c657320746f206b6565702066726f6d207468697320636861696e2e2044656661756c74206973203130312e0000000a68110028000000fc1e1000430000008c010000010000002f686f6d652f616e6472652f576f726b62656e63682f706172697479746563682f7375627374726174652f73726d6c2f62616c616e6365732f7372632f6c69622e727300fc1e1000430000008c01000001000000676f74206f766572666c6f7720616674657220616464696e6720612066656520746f2076616c756500000000282010000b0000000000000018e81000020000000000000000000000342010000100000000000000000000003c201000100000000000000034e810000100000000000000000000004c201000010000000000000000000000542010000c00000000000000a483100001000000000000000000000060201000010000000000000000000000682010000e0000000000000078201000020000000000000000000000882010000100000000000000566f746572526561706564002621100015000000426164526561706572536c6173686564172110000f00000054616c6c7953746172746564e22010003500000054616c6c7946696e616c697a6564000090e810000e00000090e810000e000000902010005200000020412074616c6c792028666f7220617070726f76616c20766f746573206f662073656174287329292068617320656e646564202877697468206f6e65206f72206d6f7265206e6577206d656d62657273292e20412074616c6c792028666f7220617070726f76616c20766f746573206f662073656174287329292068617320737461727465642e20736c6173686564207265617065722072656170656420766f7465722c20726561706572436f756e63696c205265676973746572496e666f4f66436f756e63696c204d656d62657273436f756e63696c204e65787446696e616c697a657022100048000000820a00000a000000436f756e63696c205465726d4475726174696f6e436f756e63696c2050726573656e746174696f6e4475726174696f6e436f756e63696c204c6561646572626f617264007022100048000000880a00000e000000436f756e63696c2043616e64696461746573436f756e63696c20566f746572496e666f4f6647757275206d656469746174696f6e66696e616c697a652063616e206f6e6c792062652063616c6c656420616674657220612074616c6c7920697320737461727465642e436f756e63696c20417070726f76616c734f66436f756e63696c20566f7465727300000000000000000000000000002f72757374632f633739386466666163396463386338323337346462343866356234373436393063633665393638362f7372632f6c6962636f72652f736c6963652f6d6f642e727300000000702410000d0000000000000080241000030000000000000000000000c8241000180000000000000000000000882510001300000000000000802410000300000000000000000000009c251000060000000000000000000000cc2510001300000000000000e0251000040000000000000000000000402610000c0000000000000000000000a02610000d00000000000000b0261000010000000000000000000000c82610000a000000000000000000000018271000100000000000000028271000010000000000000000000000402710000d0000000000000000000000a82710000e00000000000000b827100003000000000000000000000000281000080000000000000000000000402810001100000000000000542810000100000000000000000000006c281000030000000000000000000000842810000d0000000000000094281000010000000000000000000000ac281000040000000000000000000000cc2810001900000000000000e828100001000000000000000000000000291000020000000000000000000000102910001100000000000000e82810000100000000000000000000002429100002000000000000007365745f617070726f76616c7300000000000000b73510000500000000000000bc3510000900000000000000b0a910000500000000000000a02c10001200000000000000c53510000400000000000000c93510000800000085311000580000003931100010000000386b110000000000dd311000300000000d3210004a000000386b11000000000057321000350000008c32100051000000dd3210002c00000009331000530000005c33100062000000be331000600000001e3410001d0000003b341000570000009234100035000000386b110000000000c73410006b000000323510001d000000386b1100000000007e1b11000b0000002e271100080000004f3510002700000076351000410000001f1c11000c00000070726f78795f7365745f617070726f76616c7300d4301000650000003931100010000000386b1100000000007e1b11000b000000493110003c0000001f1c11000c000000726561705f696e6163746976655f766f7465720000000000ab3010000e000000000000004e1c11000c00000000000000db2a10000300000000000000b01d11002300000000000000b930100009000000000000004e1c11000c00000000000000c23010001200000000000000a02c1000120000004a2f100058000000a22f10005c000000fe2f100028000000386b1100000000002630100045000000386b1100000000006b30100040000000386b1100000000007e1b11000b0000002e27110008000000232f1000270000001f1c11000c000000726574726163745f766f74657200000000000000b0a9100005000000000000004e1c11000c000000472e10004b000000386b110000000000922e100042000000386b110000000000d42e10004f000000386b1100000000007e1b11000b0000002e27110008000000232f1000270000001f1c11000c0000007375626d69745f63616e64696461637900000000432e100004000000000000004e1c11000c000000b22c10001e000000386b110000000000d02c100044000000386b110000000000142d1000480000005c2d100051000000ad2d10004c000000f92d10001e000000386b1100000000007e1b11000b000000172e1000180000002f2e1000140000001f1c11000c00000070726573656e745f77696e6e6572000000000000922c10000900000000000000b01d110023000000000000009b2c10000500000000000000f32511001500000000000000b0a910000500000000000000a02c1000120000009e2b100059000000f72b1000680000005f2c10001e000000386b1100000000007e1b11000b0000007d2c1000150000000e7c1000110000001f1c11000c0000007365745f646573697265645f736561747300000000000000f629100005000000000000004e1c11000c000000de2a100059000000372b100052000000892b10001500000072656d6f76655f6d656d62657200000000000000db2a10000300000000000000b01d110023000000fb29100048000000386b110000000000432a1000480000008b2a1000500000007365745f70726573656e746174696f6e5f6475726174696f6e00000000000000f6291000050000000000000073f3100017000000a02910005600000088291000180000007365745f7465726d5f6475726174696f6e0000003429100054000000882910001800000020536574207468652070726573656e746174696f6e206475726174696f6e2e2049662074686572652069732063757272656e74206120766f7465206265696e672070726573656e74656420666f722c2077696c6c20696e766f6b65206066696e616c697a655f766f7465602e20536574207468652070726573656e746174696f6e206475726174696f6e2e2049662074686572652069732063757272656e746c79206120766f7465206265696e672070726573656e74656420666f722c2077696c6c636f756e742052656d6f7665206120706172746963756c6172206d656d6265722066726f6d20746865207365742e20546869732069732065666665637469766520696d6d6564696174656c792e204e6f74653a20412074616c6c792073686f756c642068617070656e20696e7374616e746c7920286966206e6f7420616c726561647920696e20612070726573656e746174696f6e20706572696f642920746f2066696c6c2074686520736561742069662072656d6f76616c206d65616e732074686174207468652064657369726564206d656d6265727320617265206e6f74206d65742e77686f20536574207468652064657369726564206d656d62657220636f756e743b206966206c6f776572207468616e207468652063757272656e7420636f756e742c207468656e2073656174732077696c6c206e6f7420626520757020656c656374696f6e207768656e2074686579206578706972652e204966206d6f72652c207468656e2061206e657720766f74652077696c6c2062652073746172746564206966206f6e65206973206e6f7420616c726561647920696e2070726f67726573732e20436c61696d207468617420607369676e656460206973206f6e65206f662074686520746f702053656c663a3a63617272795f636f756e742829202b2063757272656e745f766f746528292e312063616e646964617465732e204f6e6c7920776f726b73206966207468652060626c6f636b5f6e756d626572203e3d2063757272656e745f766f746528292e306020616e6420603c2063757272656e745f766f746528292e30202b2070726573656e746174696f6e5f6475726174696f6e28296020607369676e6564602073686f756c642068617665206174206c65617374202d204f28766f746572732920636f6d707574652e63616e646964617465746f74616c436f6d706163743c566f7465496e6465783e205375626d6974206f6e6573656c6620666f722063616e6469646163792e204163636f756e74206d757374206861766520656e6f756768207472616e736665727261626c652066756e647320696e20697420746f207061792074686520626f6e642e204e4f54453a20696620606f726967696e602068617320616c72656164792061737369676e656420617070726f76616c7320766961205b607365745f617070726f76616c73605d2c2069742077696c6c204e4f54206861766520616e7920757361626c652066756e647320746f20706173732063616e64696461637920626f6e6420616e64206d75737420666972737420726574726163742e204e6f746520746861742073657474696e6720617070726f76616c732077696c6c206c6f636b2074686520656e746972652062616c616e6365206f662074686520766f74657220756e74696c2072657472616374696f6e206f72206265696e67207265706f727465642e202d20496e646570656e64656e74206f6620696e7075742e202d205468726565204442206368616e6765732e736c6f742052656d6f7665206120766f7465722e20416c6c20766f746573206172652063616e63656c6c656420616e642074686520766f746572206465706f7369742069732072657475726e65642e2054686520696e646578206d7573742062652070726f7669646564206173206578706c61696e656420696e205b60766f7465725f6174605d2066756e6374696f6e2e20416c736f2072656d6f76657320746865206c6f636b206f6e207468652062616c616e6365206f662074686520766f7465722e20536565205b60646f5f7365745f617070726f76616c732829605d2e202d2054776f20666577657220444220656e74726965732c206f6e65204442206368616e67652e2052656d6f7665206120766f7465722e20466f72206974206e6f7420746f206265206120626f6e642d636f6e73756d696e67206e6f2d6f702c20616c6c20617070726f7665642063616e64696461746520696e6469636573206d757374206e6f772062652065697468657220756e72656769737465726564206f72207265676973746572656420746f20612063616e646964617465207468617420726567697374657265642074686520736c6f742061667465722074686520766f7465722067617665207468656972206c61737420617070726f76616c207365742e20426f746820696e6469636573206d7573742062652070726f7669646564206173206578706c61696e656420696e205b60766f7465725f6174605d2066756e6374696f6e2e204d61792062652063616c6c656420627920616e796f6e652e2052657475726e732074686520766f746572206465706f73697420746f20607369676e6564602e7265706f727465725f696e64657877686f5f696e646578617373756d65645f766f74655f696e646578205365742063616e64696461746520617070726f76616c732066726f6d20612070726f78792e20417070726f76616c20736c6f747320737461792076616c6964206173206c6f6e672061732063616e6469646174657320696e2074686f736520736c6f74732061726520726567697374657265642e202d2053616d6520617320607365745f617070726f76616c73602077697468206f6e65206164646974696f6e616c2073746f7261676520726561642e205365742063616e64696461746520617070726f76616c732e20417070726f76616c20736c6f747320737461792076616c6964206173206c6f6e672061732063616e6469646174657320696e2074686f736520736c6f7473204c6f636b732074686520746f74616c2062616c616e6365206f662063616c6c657220696e646566696e6974656c792e204f6e6c79205b60726574726163745f766f746572605d206f72205b60726561705f696e6163746976655f766f746572605d2063616e20756e6c6f636b207468652062616c616e63652e206068696e746020617267756d656e7420697320696e74657270726574656420646966666572656e746c79206261736564206f6e3a202d20696620606f726967696e602069732073657474696e6720617070726f76616c7320666f72207468652066697273742074696d653a2054686520696e6465782077696c6c20626520636865636b656420666f72206265696e6720612076616c6964205f686f6c655f20696e2074686520766f746572206c6973742e2020202d206966207468652068696e7420697320636f72726563746c7920706f696e74696e6720746f206120686f6c652c206e6f206665652069732064656475637465642066726f6d20606f726967696e602e2020202d204f74686572776973652c207468652063616c6c2077696c6c2073756363656564206275742074686520696e6465782069732069676e6f72656420616e642073696d706c792061207075736820746f20746865206c617374206368756e6b2020207769746820667265652073706163652068617070656e732e20496620746865206e65772070757368206361757365732061206e6577206368756e6b20746f20626520637265617465642c20612066656520696e646963617465642062792020205b60566f74696e67466565605d2069732064656475637465642e202d20696620606f726967696e6020697320616c7265616479206120766f7465723a2074686520696e646578205f5f6d7573745f5f2062652076616c696420616e6420706f696e7420746f2074686520636f727265637420706f736974696f6e206f662074686520606f726967696e6020696e207468652063757272656e7420766f74657273206c6973742e204e6f7465207468617420616e7920747261696c696e67206066616c73656020766f74657320696e2060766f746573602069732069676e6f7265643b20496e20617070726f76616c20766f74696e672c206e6f7420766f74696e6720666f7220612063616e64696461746520616e6420766f74696e672066616c73652c2061726520657175616c2e202d2054776f20657874726120444220656e74726965732c206f6e65204442206368616e67652e202d20417267756d656e742060766f74657360206973206c696d6974656420696e206c656e67746820746f206e756d626572206f662063616e646964617465732e766f7465735665633c626f6f6c3e68696e74536574496e64657800000000000000543b10001400000000000000000000001bf610000e00000000000000000000000000000000000000000000000000000000000000408111007c3b10000000000000000000683b100001000000000000000100000000000000703b10000c00000000000000000000001bf610000e00000000000000000000000000000000000000000000000000000000000000408111007c3b100000000000000000008c3b100001000000000000000100000000000000943b10000c0000000000000000000000061111000300000000000000000000000000000000000000000000000000000000000000408111001c4710000000000000000000a03b100001000000000000000100000000000000a0ad1000070000000000000000000000a83b10002300000000000000000000000000000000000000000000000000000000000000408111002c3d10000000000000000000cc3b100004000000000000000100000000000000ec3b1000090000000000000000000000f53b10000900000000000000000000000000000000000000000000000000000000000000408111001c4710000000000000000000003c100001000000000000000100000000000000083c10000b0000000101000000000000133c100018000000000000002b3c10001100000000000000000000000000000000000000408111002c3d100000000000000000003c3c100005000000000000000100000000000000643c10000e0000000101000000000000423111000c00000000000000723c1000100000000000000000000000000000000000000040811100f43d10000000000000000000843c100002000000000000000000000000000000943c10000b0000000101000000000000423111000c000000000000009f3c1000170000000000000000000000000000000000000040811100b83c10000000000000000000c83c100001000000000000000000000000000000d03c1000060000000101000000000000c93510000800000000000000d63c10001900000000000000000000000000000000000000408111002c3d10000000000000000000f03c100001000000000000000100000000000000f83c10000c0000000000000000000000c93510000800000000000000000000000000000000000000000000000000000000000000408111001c4710000000000000000000043d1000010000000000000001000000000000000c3d10000a0000000000000000000000c93510000800000000000000000000000000000000000000000000000000000000000000408111001c4710000000000000000000183d100001000000000000000100000000000000203d10000a0000000000000000000000b11a11001100000000000000000000000000000000000000000000000000000000000000408111002c3d100000000000000000003c3d100001000000000000000100000000000000443d10000e0000000000000000000000061111000300000000000000000000000000000000000000000000000000000000000000408111001c4710000000000000000000543d1000010000000000000001000000000000005c3d10000c0000000000000000000000683d1000280000000000000000000000000000000000000000000000000000000000000040811100903d10000000000000000000a03d100001000000000000000000000000000000a83d10000b0000000000000000000000b33d1000210000000000000000000000000000000000000000000000000000000000000040811100d43d10000000000000000000e43d10000200000000000000000000000000000010011100050000000101000000000000423111000c00000000000000423111000c0000000000000000000000000000000000000040811100f43d100000000000000000002801110002000000000000000000000050726573656e746174696f6e4475726174696f6e534310004f0000005465726d4475726174696f6e2f0000000000000001000000350000002d43100026000000446573697265645365617473f34210003a0000005665633c28543a3a4163636f756e7449642c20543a3a426c6f636b4e756d626572293e00cb4110005e000000294210005c0000008542100054000000d94210001a000000566f7465436f756e74566f7465496e64657800008441100047000000417070726f76616c734f6628543a3a4163636f756e7449642c20536574496e646578295665633c417070726f76616c466c61673e6f40100068000000386b110000000000d740100059000000386b11000000000030411000540000005265676973746572496e666f4f6628566f7465496e6465782c20753332290000fa3f10005f0000005940100016000000566f746572496e666f4f66566f746572496e666f3c42616c616e63654f663c543e3e00002f000000000000000100000036000000d93f100021000000566f746572735665633c4f7074696f6e3c543a3a4163636f756e7449643e3e00963f1000430000004e657874566f746572536574573f10003f000000566f746572436f756e7400003d3f10001a00000043616e6469646174657300002f000000000000000100000031000000213f10001c00000043616e646964617465436f756e740000fd3e1000240000004e65787446696e616c697a6528543a3a426c6f636b4e756d6265722c207533322c205665633c543a3a4163636f756e7449643e292f00000000000000010000003c000000b53e1000480000004c6561646572626f6172645665633c2842616c616e63654f663c543e2c20543a3a4163636f756e744964293e2f00000000000000010000003c000000043e1000670000006b3e10004a0000002f0000000000000001000000360000002047657420746865206c6561646572626f61726420696620776527726520696e207468652070726573656e746174696f6e2070686173652e2054686520666972737420656c656d656e742069732074686520776569676874206f66206561636820656e7472793b204974206d617920626520746865206469726563742073756d6d656420617070726f76616c207374616b65732c206f7220612077656967687465642076657273696f6e206f662069742e20546865206163636f756e747320686f6c64696e672074686520736561747320746861742077696c6c206265636f6d652066726565206f6e20746865206e6578742074616c6c792e2043757272656e74206e756d626572206f66206163746976652063616e64696461746573205468652070726573656e742063616e646964617465206c6973742e2043757272656e74206e756d626572206f6620566f746572732e20746865206e65787420667265652073657420746f2073746f7265206120766f74657220696e2e20546869732077696c6c206b6565702067726f77696e672e205468652070726573656e7420766f746572206c69737420286368756e6b656420616e6420636170706564206174205b60564f5445525f5345545f53495a45605d292e20426173696320696e666f726d6174696f6e2061626f7574206120766f7465722e2054686520766f746520696e64657820616e64206c69737420736c6f742074686174207468652063616e646964617465206077686f60207761732072656769737465726564206f7220604e6f6e6560206966207468657920617265206e6f742063757272656e746c7920726567697374657265642e2041206c697374206f6620766f74657320666f72206561636820766f7465722e2054686520766f746573206172652073746f726564206173206e756d657269632076616c75657320616e642070617273656420696e2061206269742d77697365206d616e6e65722e20496e206f7264657220746f2067657420612068756d616e2d7265616461626c6520726570726573656e746174696f6e2028605665633c626f6f6c3e60292c20757365205b60616c6c5f617070726f76616c735f6f66605d2e20467572746865726d6f72652c206561636820766563746f72206f66207363616c617273206973206368756e6b656420776974682074686520636170206f662060415050524f56414c5f5345545f53495a45602e2054686520746f74616c206e756d626572206f6620766f746520726f756e6473207468617420686176652068617070656e6564206f722061726520696e2070726f67726573732e205468652063757272656e74206d656d626572736869702e205768656e2074686572652773206120766f746520676f696e67206f6e2c20746869732073686f756c64207374696c6c206265207573656420666f7220657865637574697665206d6174746572732e2054686520626c6f636b206e756d62657220287365636f6e6420656c656d656e7420696e20746865207475706c65292069732074686520626c6f636b207468617420746865697220706f736974696f6e2069732061637469766520756e74696c202863616c63756c61746564206279207468652073756d206f662074686520626c6f636b206e756d626572207768656e20746865206d656d6265722077617320656c656374656420616e64207468656972207465726d206475726174696f6e292e204e756d626572206f66206163636f756e747320746861742073686f756c6420636f6e737469747574652074686520636f6c6c6563746976652e20486f77206c6f6e67206561636820706f736974696f6e2069732061637469766520666f722e20486f77206c6f6e6720746f2067697665206561636820746f702063616e64696461746520746f2070726573656e74207468656d73656c7665732061667465722074686520766f746520656e64732e000000000000d44510000d000000000000001d3311000c0000000000000040811100e44510000000000000000000f4451000020000000000000000000000044610000a000000000000001d3311000c0000000000000040811100104610000000000000000000204610000100000000000000000000002846100009000000000000001d3311000c0000000000000040811100344610000000000000000000444610000200000000000000000000005446100014000000000000001d3311000c000000000000004081110068461000000000000000000078461000020000000000000000000000884610000a0000000000000006111100030000000000000040811100944610000000000000000000a4461000020000000000000000000000b44610001300000000000000f53b1000090000000000000040811100c84610000000000000000000d8461000030000000000000000000000b00911000c000000000000001bf610000e0000000000000040811100f0461000000000000000000000471000020000000000000000000000104710000a00000000000000061111000300000000000000408111001c47100000000000000000002c471000050000000000000000000000544710000e0000000000000006111100030000000000000040811100644710000000000000000000744710000100000000000000000000007c471000110000000000000006111100030000000000000040811100904710000000000000000000a0471000010000000000000043616e646964616379426f6e640000002f00000000000000010000003d000000b04b10004e000000fe4b100014000000566f74696e67426f6e6400002f0000000000000001000000320000006e4b100042000000566f74696e674665650000002f00000000000000010000003e000000074b10004a000000514b10001d00000050726573656e74536c617368506572566f7465722f000000000000000100000033000000a34a100045000000e84a10001f0000004361727279436f756e7400002f000000000000000100000037000000354a1000470000007c4a100027000000496e6163746976654772616365506572696f64002f00000000000000010000003f000000984910004c000000e44910004b0000002f4a1000060000002f00000000000000010000004000000046491000490000008f491000090000004465636179526174696f00002f000000000000000100000041000000f34710004d00000040481000410000008148100047000000c84810004a0000001249100034000000564f5445525f5345545f53495a4500002f000000000000000100000042000000cf47100024000000415050524f56414c5f5345545f53495a450000002f000000000000000100000043000000a84710002700000020546865206368756e6b2073697a65206f662074686520617070726f76616c20766563746f722e20546865206368756e6b2073697a65206f662074686520766f74657220766563746f722e20446563617920666163746f72206f6620776569676874207768656e206265696e6720616363756d756c617465642e2049742073686f756c64207479706963616c6c792062652073657420746f205f5f6174206c656173745f5f20606d656d626572736869705f73697a65202d316020746f206b6565702074686520636f6c6c656374697665207365637572652e205768656e2073657420746f20604e602c20697420696e64696361746573206028312f4e295e7460206f66207374616b656420697320646563617965642061742077656967687420696e6372656d656e742073746570206074602e20302077696c6c20726573756c7420696e206e6f20776569676874206265696e6720616464656420617420616c6c20286e6f726d616c20617070726f76616c20766f74696e67292e204120726561736f6e61626c652064656661756c742076616c75652069732032342e20486f77206f6674656e2028696e20626c6f636b732920746f20636865636b20666f72206e657720766f7465732e204120726561736f6e61626c652064656661756c742076616c756520697320313030302e20486f77206d616e7920766f746520696e6469636573206e65656420746f20676f20627920616674657220612074617267657420766f7465722773206c61737420766f7465206265666f726520746865792063616e2062652072656170656420696620746865697220617070726f76616c7320617265206d6f6f742e204120726561736f6e61626c652064656661756c742076616c756520697320312e20486f77206d616e792072756e6e6572732d75702073686f756c64206861766520746865697220617070726f76616c73207065727369737420756e74696c20746865206e65787420766f74652e204120726561736f6e61626c652064656661756c742076616c756520697320322e205468652070756e6973686d656e742c2070657220766f7465722c20696620796f752070726f7669646520616e20696e76616c69642070726573656e746174696f6e2e204120726561736f6e61626c652064656661756c742076616c756520697320312e2054686520616d6f756e74206f662066656520706169642075706f6e206561636820766f7465207375626d697373696f6e2c20756e6c6573732069662074686579207375626d69742061205f686f6c655f20696e64657820616e64207265706c6163652069742e20486f77206d7563682073686f756c64206265206c6f636b656420757020696e206f7264657220746f2062652061626c6520746f207375626d697420766f7465732e20486f77206d7563682073686f756c64206265206c6f636b656420757020696e206f7264657220746f207375626d6974206f6e6527732063616e6469646163792e204120726561736f6e61626c652064656661756c742076616c756520697320392e00000a681100280000002c4c1000440000000b010000010000002f686f6d652f616e6472652f576f726b62656e63682f706172697479746563682f7375627374726174652f73726d6c2f656c656374696f6e732f7372632f6c69622e72732c4c1000440000000b01000001000000436f756e63696c2050726f787963616e6e6f74207265617020647572696e672070726573656e746174696f6e20706572696f647265706f72746572206d757374206265206120766f746572696e76616c6964207265706f7274657220696e646578766f746520696e646578206e6f742063757272656e7463616e6e6f74207265617020647572696e6720677261636520706572696f6474617267657420666f7220696e616374697669747920636c65616e7570206d75737420626520616374697665626164207265706f7274657220696e6465786261642074617267657420696e646578696e76616c69642074617267657420696e64657872657472616374696f6e20696e646578206d69736d6174636872657472616374696f6e20696e64657820696e76616c696463616e6e6f742072657472616374207768656e2070726573656e74696e6763616e6e6f742072657472616374206e6f6e2d766f7465726475706c69636174652063616e646964617465207375626d697373696f6e696e76616c69642063616e64696461746520736c6f7463616e64696461746520686173206e6f7420656e6f7567682066756e647363616e6e6f742070726573656e74206f757473696465206f662070726573656e746174696f6e20706572696f64696e646578206e6f742063757272656e747374616b65206465706f736974656420746f2070726573656e742077696e6e657220616e6420626520616464656420746f206c6561646572626f6172642073686f756c64206265206e6f6e2d7a65726f6c6561646572626f617264206d757374206578697374207768696c652070726573656e742070686173652061637469766570726573656e746572206d75737420686176652073756666696369656e7420736c61736861626c652066756e647370726573656e7465642063616e646964617465206d7573742062652063757272656e7463616e646964617465206e6f7420776f72746879206f66206c6561646572626f61726463616e646964617465206d757374206e6f7420666f726d2061206475706c696361746564206d656d62657220696620656c65637465646475706c69636174652070726573656e746174696f6e696e636f727265637420746f74616c6e6f20617070726f76616c206368616e67657320647572696e672070726573656e746174696f6e20706572696f64696e636f727265637420766f746520696e646578616d6f756e74206f662063616e6469646174657320746f207265636569766520617070726f76616c20766f7465732073686f756c64206265206e6f6e2d7a65726f616d6f756e74206f662063616e64696461746520766f7465732063616e6e6f742065786365656420616d6f756e74206f662063616e64696461746573696e76616c696420766f74657220696e64657877726f6e6720766f74657220696e6465786e657720766f746572206d75737420686176652073756666696369656e742066756e647320746f207061792074686520626f6e6446524e4b00000000000070e710000800000000000000b8511000010000000000000000000000c0511000010000000000000000000000c85110000800000000000000b40f1100010000000000000000000000d0511000010000000000000000000000d85110000700000000000000e0511000030000000000000000000000f8511000010000000000000000000000005210000500000000000000b40f110001000000000000000000000008521000010000000000000000000000105210000800000000000000b40f1100010000000000000000000000185210000100000000000000348910000d000000e95210000e0000005370656e64696e67af5210003a0000004177617264656400348910000d0000006a1011000700000061101100090000008f521000200000004275726e740000006c52100023000000526f6c6c6f766572205210004c000000205370656e64696e67206861732066696e69736865643b20746869732069732074686520616d6f756e74207468617420726f6c6c73206f76657220756e74696c206e657874207370656e642e20536f6d65206f66206f75722066756e64732068617665206265656e206275726e742e20536f6d652066756e64732068617665206265656e20616c6c6f63617465642e205765206861766520656e6465642061207370656e6420706572696f6420616e642077696c6c206e6f7720616c6c6f636174652066756e64732e204e65772070726f706f73616c2e416c69766520636f6e7472616374206f7220746f6d6273746f6e6520616c726561647920657869737473647572696e6720657865637574696f6e0000000a681100280000004c5310004d0000005e000000080000002f686f6d652f616e6472652f576f726b62656e63682f706172697479746563682f7375627374726174652f73726d6c2f636f6e7472616374732f7372632f7761736d2f72756e74696d652e72734772616e64706146696e616c697479205374616c6c656454726561737572792050726f706f73616c730000e0531000190000000054100048000000bb0100002d00000000000000617474656d707420746f20646976696465206279207a65726f000000000000002f72757374632f633739386466666163396463386338323337346462343866356234373436393063633665393638362f7372632f6c6962636f72652f6f70732f61726974682e7273616c726561647920626f72726f776564616c7265616479206d757461626c7920626f72726f7765642f0000000000000001000000440000002f0000000000000001000000450000000a68110028000000a85410004300000084000000010000002f686f6d652f616e6472652f576f726b62656e63682f706172697479746563682f7375627374726174652f73726d6c2f74726561737572792f7372632f6c69622e7273000455100033000000375510004b000000b200000005000000636f6e74726163742073756273797374656d20726573756c74696e6720696e20706f73697469766520696d62616c616e6365212f686f6d652f616e6472652f576f726b62656e63682f706172697479746563682f7375627374726174652f73726d6c2f636f6e7472616374732f7372632f6163636f756e745f64622e7273707265636f6e646974696f6e3a20616c6c20696d706f7274732073686f756c6420626520636865636b656420616761696e737420746865207369676e617475726573206f6620636f72726573706f6e64696e670a09090909090966756e6374696f6e7320646566696e65642062792060646566696e655f656e762160206d6163726f206279207468652075736572206f6620746865206d6163726f3b0a0909090909097369676e617475726573206f662074686573652066756e6374696f6e7320646566696e6564206279206024706172616d73603b0a09090909090963616c6c7320616c77617973206d616465207769746820617267756d656e7473207479706573206f662077686963682061726520646566696e65642062792074686520636f72726573706f6e64696e6720696d706f7274733b0a09090909090974687573207479706573206f6620617267756d656e74732073686f756c6420626520657175616c20746f2074797065206c69737420696e206024706172616d736020616e640a0909090909096c656e677468206f6620617267756d656e74206c69737420616e642024706172616d732073686f756c6420626520657175616c3b0a0909090909097468757320746869732063616e206e6576657220626520604e6f6e65603b0a0909090909097165643b0a09090909090960656d7074795f6f75747075745f627566602069732074616b656e206f6e6c7920686572653b0a09090909606578745f72657475726e602074726170733b0a090909096052756e74696d65602063616e206f6e6c792062652075736564206f6e6c7920666f72206f6e6520657865637574696f6e3b0a090909097165640000000000205810001200000000000000345810000100000000000000000000004c58100001000000000000007265706f72745f6d69736265686176696f720000000000006d5810000700000000000000d5ca1000070000005458100019000000205265706f727420736f6d65206d69736265686176696f722e5f7265706f72744772616e64706146696e616c6974790000000000d0de10000b00000000000000000000003c5a1000230000000000000000000000000000000000000000000000000000000000000040811100d06010000000000000000000605a100001000000000000000100000000000000685a10000500000000000000000000006d5a10001b0000000000000000000000000000000000000000000000000000000000000040811100885a10000000000000000000985a100001000000000000000100000000000000a05a10000d0000000000000000000000ad5a1000230000000000000000000000000000000000000000000000000000000000000040811100145b10000000000000000000d05a100001000000000000000000000000000000d85a10000a00000000000000000000001bf610000e0000000000000000000000000000000000000000000000000000000000000040811100145b10000000000000000000e45a100001000000000000000000000000000000ec5a1000070000000000000000000000f35a1000200000000000000000000000000000000000000000000000000000000000000040811100145b10000000000000000000245b10000100000000000000000000005665633c28417574686f7269747949642c20417574686f72697479576569676874293e00d45b10001b000000537461746553746f72656453746174653c543a3a426c6f636b4e756d6265723e2f000000000000000100000046000000b05b10002400000050656e64696e674368616e676553746f72656450656e64696e674368616e67653c543a3a426c6f636b4e756d6265723e7f5b1000310000004e657874466f726365640000505b10002f0000005374616c6c656428543a3a426c6f636b4e756d6265722c20543a3a426c6f636b4e756d62657229002f0000000000000001000000360000002c5b10002400000020607472756560206966207765206172652063757272656e746c79207374616c6c65642e206e65787420626c6f636b206e756d6265722077686572652077652063616e20666f7263652061206368616e67652e2050656e64696e67206368616e67653a20287369676e616c65642061742c207363686564756c6564206368616e6765292e205374617465206f66207468652063757272656e7420617574686f72697479207365742e205468652063757272656e7420617574686f72697479207365742e0000000000745c10000d00000000000000845c1000020000000000000000000000b45c1000090000000000000000000000fc5c10000f000000000000000c5d1000010000000000000000000000245d10000700000000000000000000005c5d100010000000000000000c5d10000100000000000000000000006c5d1000080000000000000070726f706f73655f7370656e6400000000000000ee2511000500000000000000f325110015000000000000004a5f10000b00000000000000b01d110023000000785e10004b000000c35e10004d000000105f100015000000386b1100000000007e1b11000b0000002e27110008000000f57b100019000000255f1000250000001f1c11000c00000072656a6563745f70726f706f73616c00000000006d5e10000b00000000000000b5a91000160000002e5e10003f000000386b1100000000007e1b11000b0000002e27110008000000f57b100019000000e6f21000100000001f1c11000c000000617070726f76655f70726f706f73616cac5d100057000000035e10002b000000386b1100000000007e1b11000b0000002e27110008000000f57b1000190000000e7c1000110000001f1c11000c00000020417070726f766520612070726f706f73616c2e2041742061206c617465722074696d652c207468652070726f706f73616c2077696c6c20626520616c6c6f636174656420746f207468652062656e656669636961727920616e6420746865206f726967696e616c206465706f7369742077696c6c2062652072657475726e65642e2052656a65637420612070726f706f736564207370656e642e20546865206f726967696e616c206465706f7369742077696c6c20626520736c61736865642e70726f706f73616c5f69642050757420666f727761726420612073756767657374696f6e20666f72207370656e64696e672e2041206465706f7369742070726f706f7274696f6e616c20746f207468652076616c756520697320726573657276656420616e6420736c6173686564206966207468652070726f706f73616c2069732072656a65637465642e2049742069732072657475726e6564206f6e6365207468652070726f706f73616c20697320617761726465642e202d204f6e65204442206368616e67652c206f6e6520657874726120444220656e7472792e62656e65666963696172790000000000000088ad10000d0000000000000000000000348910000d0000000000000000000000000000000000000000000000000000000000000040811100606010000000000000000000706010000100000000000000010000000000000018ad1000090000000101000000000000348910000d00000000000000786010002400000000000000000000000000000000000000408111009c6010000000000000000000ac60100001000000000000000000000000000000b4601000090000000000000000000000bd601000120000000000000000000000000000000000000000000000000000000000000040811100d06010000000000000000000e06010000100000000000000010000002f000000000000000100000041000000456110002900000050726f706f73616c3c543a3a4163636f756e7449642c2042616c616e63654f663c543e3e2f000000000000000100000036000000266110001f000000417070726f76616c735665633c50726f706f73616c496e6465783e002f000000000000000100000031000000e86010003e0000002050726f706f73616c20696e646963657320746861742068617665206265656e20617070726f76656420627574206e6f742079657420617761726465642e2050726f706f73616c7320746861742068617665206265656e206d6164652e204e756d626572206f662070726f706f73616c7320746861742068617665206265656e206d6164652e000000000000506210000c000000000000005c621000070000000000000040811100646210000000000000000000746210000200000000000000000000008462100013000000000000001d3311000c0000000000000040811100986210000000000000000000a8621000010000000000000000000000b06210000b000000000000001bf610000e0000000000000040811100bc6210000000000000000000cc621000010000000000000000000000d462100004000000000000005c621000070000000000000040811100d86210000000000000000000e8621000010000000000000050726f706f73616c426f6e645065726d696c6c002f000000000000000100000047000000a863100055000000fd6310004400000050726f706f73616c426f6e644d696e696d756d002f00000000000000010000003200000056631000520000005370656e64506572696f64002f00000000000000010000004800000034631000220000004275726e2f000000000000000100000049000000f0621000440000002050657263656e74616765206f662073706172652066756e64732028696620616e7929207468617420617265206275726e7420706572207370656e6420706572696f642e20506572696f64206265747765656e2073756363657373697665207370656e64732e204d696e696d756d20616d6f756e74206f662066756e647320746861742073686f756c6420626520706c6163656420696e2061206465706f73697420666f72206d616b696e6720612070726f706f73616c2e204672616374696f6e206f6620612070726f706f73616c27732076616c756520746861742073686f756c6420626520626f6e64656420696e206f7264657220746f20706c616365207468652070726f706f73616c2e20416e2061636365707465642070726f706f73616c2067657473207468657365206261636b2e20412072656a65637465642070726f706f73616c20646f6573206e6f742e4772616e64706146696e616c6974792050656e64696e674368616e67654772616e64706146696e616c697479205374617465496e636f6e73697374656e74207374617465202d20636f756c646e277420736574746c6520696d62616c616e636520666f722066756e6473207370656e74206279207472656173757279000000a854100043000000840000000100000050726f706f73657227732062616c616e636520746f6f206c6f774e6f2070726f706f73616c206174207468617420696e646578002d00000008000000040000004a0000004b00000000000000000000004c00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004772616e64706146696e616c697479204e657874466f726365643a73657373696f6e3a6b65797353657373696f6e2056616c696461746f727353657373696f6e204e6578744b65797373657269616c697a656420617267732073686f756c642062652070726f7669646564206279207468652072756e74696d653b0a090909636f72726563746c792073657269616c697a656420646174612073686f756c6420626520646573657269616c697a61626c653b0a0909097165640000000a681100280000002c601100500000003701000009000000000000000467100008000000000000000c6710000200000000000000000000003c6710000a000000000000007365745f6b657973000000008aca100004000000000000009568100007000000000000009c6810000500000000000000d5ca1000070000008c67100039000000c5671000480000000d68100031000000386b1100000000003e68100035000000386b1100000000007e1b11000b000000736810002200000094f21000160000001f1c11000c0000002053657473207468652073657373696f6e206b6579287329206f66207468652066756e6374696f6e2063616c6c657220746f20606b6579602e20416c6c6f777320616e206163636f756e7420746f20736574206974732073657373696f6e206b6579207072696f7220746f206265636f6d696e6720612076616c696461746f722e205468697320646f65736e27742074616b652065666665637420756e74696c20746865206e6578742073657373696f6e2e20546865206469737061746368206f726967696e206f6620746869732066756e6374696f6e206d757374206265207369676e65642e202d204f286c6f67206e2920696e206e756d626572206f66206163636f756e74732e543a3a4b65797370726f6f6600000000000000c03111000a00000000000000000000000c6b1000130000000000000000000000000000000000000000000000000000000000000040811100ac6b10000000000000000000206b100001000000000000000100000000000000286b10000c0000000000000000000000136511000c0000000000000000000000000000000000000000000000000000000000000040811100346b10000000000000000000446b1000010000000000000001000000000000004c6b1000070000000000000000000000d33311000400000000000000000000000000000000000000000000000000000000000000408111006c6b10000000000000000000546b1000010000000000000001000000000000005c6b10000d0000000000000000000000d33311000400000000000000000000000000000000000000000000000000000000000000408111006c6b100000000000000000007c6b100001000000000000000100000000000000846b10000a00000000000000000000008e6b10001e0000000000000000000000000000000000000000000000000000000000000040811100ac6b10000000000000000000bc6b100002000000000000000100000000000000cc6b1000080000000204010000000000d5ca10000700000000000000d46b10000e0000000000000095681000070000000000000040811100206c10000000000000000000e46b100004000000000000000000000000000000046c1000080000000204010000000000d5ca100007000000000000000c6c10001400000000000000d46b10000e0000000000000040811100206c10000000000000000000306c10000400000000000000000000005665633c543a3a56616c696461746f7249643e00566e10001f00000043757272656e74496e6465782f000000000000000100000041000000386e10001e0000004368616e676564000a6e10002e0000005175657565644368616e6765640000002f000000000000000100000036000000f56d1000150000005175657565644b6579735665633c28543a3a56616c696461746f7249642c20543a3a4b657973293e2f0000000000000001000000310000006e6d10004f000000bd6d1000380000004e6578744b657973543a3a56616c696461746f7249640000476d100027000000386b110000000000996c100056000000ef6c1000580000004b65794f776e6572284b65795479706549642c205665633c75383e292f000000000000000100000036000000506c100049000000386b110000000000996c100056000000ef6c10005800000020546865206f776e6572206f662061206b65792e20546865207365636f6e64206b65792069732074686520604b657954797065496460202b2074686520656e636f646564206b65792e20546865206669727374206b657920697320616c77617973206044454455505f4b45595f5052454649586020746f206861766520616c6c20746865206461746120696e207468652073616d65206272616e6368206f662074686520747269652e20486176696e6720616c6c206461746120696e207468652073616d65206272616e63682073686f756c642070726576656e7420736c6f77696e6720646f776e206f7468657220717565726965732e20546865206e6578742073657373696f6e206b65797320666f7220612076616c696461746f722e2054686520717565756564206b65797320666f7220746865206e6578742073657373696f6e2e205768656e20746865206e6578742073657373696f6e20626567696e732c207468657365206b6579732077696c6c206265207573656420746f2064657465726d696e65207468652076616c696461746f7227732073657373696f6e206b6579732e20517565756564206b657973206368616e6765642e205472756520696620616e797468696e6720686173206368616e67656420696e20746869732073657373696f6e2e2043757272656e7420696e646578206f66207468652073657373696f6e2e205468652063757272656e7420736574206f662076616c696461746f72732e00000000000000b06e10001000000000000000c06e1000050000000000000040811100c86e10000000000000000000d86e1000020000000000000044454455505f4b45595f505245464958265b75385d0000002f00000000000000010000004d000000e86e100059000000416f10000d0000002055736564206173206669727374206b657920666f7220604e6578744b6579736020616e6420604b65794f776e65726020746f2070757420616c6c20746865206461746120696e746f207468652073616d65206272616e6368206f662074686520747269652e00000000000080d1f00840787d01000000000065cd1d23b4cc3a113b5c2301000000d31b421e4fdcba34836c472001000000c75bbd1e52a1fd2e01b4511d010000005feb3f1f1d03952998c57b1a01000000bdb6ca1fa50181245d60c61701000000abd95e20029dc11fec4f3215010000006fadfd2034d5561b086ec01201000000efdba82133aa4017c3a4711001000000eb7a6222fd1b7f132df1460e01000000c1332d23942a1210ad66410c01000000777f0c2408d6f90c5e33620a01000000a3040525591e360ab7a5aa080100000085311d268803c70760341c070100000097465e279f85ac054289b805010000007346d628a4a4e603ce9181040100000019e89b2abe607502ad987903010000009db7d72c54ba5801bb71a30201000000eb88dd2ff4b29000c5cf0202010000000b8c8d349e412700f8d7a5010100000053657373696f6e205175657565644b657973636f6465206973206e6f7420666f756e647072697374696e6520636f6465206973206e6f7420666f756e647468657265206973206e6f7420656e6f7567682067617320666f722073746f72696e672074686520636f646553657373696f6e204b65794f776e65726e6f206173736f6369617465642076616c696461746f7220494420666f72206163636f756e742e72656769737465726564206475706c6963617465206b657966696e616c6e756d46696e616c697a6564206e756d62657220696e686572656e742064617461206e6f7420666f756e640a68110028000000907110003f0000006a000000010000002f686f6d652f616e6472652f576f726b62656e63682f706172697479746563682f7375627374726174652f73726d6c2f7375646f2f7372632f6c69622e7273000a00000014000000f071100048000000820a00000a00000000000000000000002f72757374632f633739386466666163396463386338323337346462343866356234373436393063633665393638362f7372632f6c6962636f72652f736c6963652f6d6f642e72737375646f000000009472100005000000000000009c721000010000000000000000000000a4721000010000000000000000000000ac7210000a0000000000000034e81000010000000000000000000000b872100001000000000000005375646964000000d333110004000000fc721000180000004b65794368616e6765640000c07210003c00000020546865207375646f6572206a757374207377697463686564206964656e746974793b20746865206f6c64206b657920697320737570706c6965642e2041207375646f206a75737420746f6f6b20706c6163652e907110003f0000006a000000010000005375646f204b65796f6e6c79207468652063757272656e74207375646f206b65792063616e206368616e676520746865207375646f206b65796f6e6c79207468652063757272656e74207375646f206b65792063616e207375646f00000000008dcb100006000000000000004e000000000000000000000000000000000000000000000000000000000000004f00000000000000000000000000000050000000000000000000000000000000510000000000000000000000000000004edc100004000000000000005200000000000000000000000000000000000000000000000000000000000000510000000000000000000000020000000000000000000000000000000000000053000000000000000000000000000000f7bd10000900000000000000540000000000000000000000000000000000000000000000000000000000000055000000000000000000000002000000000000000000000000000000000000005600000000000000000000000000000061c110000a000000000000005700000000000000000000000000000000000000000000000000000000000000580000000000000000000000020000000000000000000000000000000000000051000000000000000000000000000000e6b7100007000000000000005900000000000000000000000000000000000000000000000000000000000000510000000000000000000000000000005a00000000000000000000000000000051000000000000000000000000000000f879100008000000000000005b000000000000000000000000000000000000000000000000000000000000005c0000000000000000000000000000005d0000000000000000000000000000005e0000000000000000000000000000004e29110007000000000000005f00000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000006100000000000000000000000000000062000000000000000000000000000000007a100007000000000000006300000000000000000000000000000000000000000000000000000000000000640000000000000000000000000000006500000000000000000000000000000066000000000000000000000000000000f3f910000900000000000000670000000000000000000000000000000000000000000000000000000000000068000000000000000000000000000000690000000000000000000000000000006a000000000000000000000000000000077a100007000000000000006b000000000000000000000000000000000000000000000000000000000000006c0000000000000000000000000000006d000000000000000000000000000000510000000000000000000000000000000e7a100012000000000000006e000000000000000000000000000000000000000000000000000000000000006c0000000000000000000000000000006d00000000000000000000000000000051000000000000000000000000000000207a100009000000000000006f00000000000000000000000000000000000000000000000000000000000000700000000000000000000000000000007100000000000000000000000000000072000000000000000000000000000000297a10000f000000020000000000000000000000000000000000000000000000000000000000000000000000730000000000000000000000020000000000000000000000000000000000000074000000000000000000000000000000387a1000070000000000000075000000000000000000000000000000000000000000000000000000000000007600000000000000000000000000000077000000000000000000000000000000510000000000000000000000000000003f7a100008000000000000007800000000000000000000000000000000000000000000000000000000000000790000000000000000000000000000007a0000000000000000000000000000007b000000000000000000000000000000477a100009000000000000007c000000000000000000000000000000000000000000000000000000000000007d0000000000000000000000000000007e0000000000000000000000000000007f000000000000000000000000000000507a100004000000000000008000000000000000000000000000000000000000000000000000000000000000810000000000000000000000000000008200000000000000000000000000000051000000000000000000000000000000547a100008000000000000008300000000000000000000000000000000000000000000000000000000000000840000000000000000000000000000008500000000000000000000000000000086000000000000000000000042616c616e63657353657373696f6e436f756e63696c546563686e6963616c436f6d6d6974746565456c656374696f6e7346696e616c697479547261636b65724772616e6470615472656173757279436f6e7472616374735375646f496d4f6e6c696e65000000003872100004000000000000007cef1000010000000000000000000000b47a1000090000000000000000000000fc7a10000700000000000000047b10000100000000000000000000001c7b100009000000000000001f7c10004e000000386b110000000000c17b100034000000386b1100000000007e1b11000b0000002e27110008000000f57b1000190000006d7c1000100000001f1c11000c0000007365745f6b657900000000004b1c11000300000000000000b01d110023000000647b10005d000000386b110000000000c17b100034000000386b1100000000007e1b11000b0000002e27110008000000f57b1000190000000e7c1000110000001f1c11000c0000002041757468656e74696361746573207468652063757272656e74207375646f206b657920616e6420736574732074686520676976656e204163636f756e7449642028606e6577602920617320746865206e6577207375646f206b65792e20546865206469737061746368206f726967696e20666f7220746869732063616c6c206d757374206265205f5369676e65645f2e202d204c696d697465642073746f726167652072656164732e202d204f6e65204442206368616e67652e2041757468656e7469636174657320746865207375646f206b657920616e64206469737061746368657320612066756e6374696f6e2063616c6c20776974682060526f6f7460206f726967696e2e202d204e6f204442207772697465732e00000000000000d87c1000030000000000000000000000423111000c0000000000000000000000000000000000000000000000000000000000000040811100dc7c10000000000000000000ec7c10000100000000000000010000004b6579002f000000000000000100000087000000f47c1000210000002054686520604163636f756e74496460206f6620746865207375646f206b65792e4e6f206f74686572206572726f72732061726520616363657074656420616674657220616e2068617264206572726f7221496e686572656e7420776974682073616d65206964656e74696669657220616c726561647920657869737473215468657265206973206f6e6c79206f6e6520666174616c206572726f723b207165640000002d00000008000000040000002e0000007375627374726174652d6e6f64650000df6acb689907609b0200000037e397fc7c91f5e40100000040fe3ad401f8959a03000000d2bc9897eed08f1501000000f78b278be53f454c01000000ed99c5acb25eedf502000000cbca25e39f1423870100000022f09549cb59f9ff010000008d8010001c000000187f100044000000bf000000030000006980100024000000187f100044000000c8000000030000003180100038000000187f100044000000060100002a0000000980100028000000187f1000440000000701000032000000e17f100028000000187f100044000000090100002c000000b57f10002c000000187f100044000000080100004c000000837f100032000000187f10004400000031010000030000005c7f100027000000187f1000440000003901000004000000f07e100028000000187f1000440000003f0100000300000053746f7261676520726f6f74206d757374206d6174636820746861742063616c63756c617465642e2f686f6d652f616e6472652f576f726b62656e63682f706172697479746563682f7375627374726174652f73726d6c2f6578656375746976652f7372632f6c69622e7273446967657374206974656d206d757374206d6174636820746861742063616c63756c617465642e4e756d626572206f6620646967657374206974656d73206d757374206d6174636820746861742063616c63756c617465642e416c6c2065787472696e736963732073686f756c6420686176652074686520636f7272656374206e6f6e636545787472696e736963732073686f756c64206e6f742065786365656420626c6f636b206c696d6974416c6c2065787472696e736963732073686f756c642062652070726f7065726c79207369676e6564416c6c2065787472696e736963732073686f756c6420686176652073656e6465722061626c6520746f2070617920746865697220666565735472616e73616374696f6e207472696520726f6f74206d7573742062652076616c69642e506172656e7420686173682073686f756c642062652076616c69642e626164207369676e617475726520696e2065787472696e73696300418110000d000000268110001b000000e480100042000000bf010000010000002f686f6d652f616e6472652f576f726b62656e63682f706172697479746563682f7375627374726174652f6e6f64652f72756e74696d652f7372632f6c69622e727342616420696e70757420646174612070726f766964656420746f20657865637574655f626c6f636b00005881100010000000696e697469616c697a655f626c6f636b708110000f0000006170706c795f65787472696e736963008881100013000000696e686572656e745f65787472696e7369637300a48110000f000000636865636b5f696e686572656e747300bc8110001400000076616c69646174655f7472616e73616374696f6ed88110000f0000006f6666636861696e5f776f726b657200f0811000160000006772616e6470615f70656e64696e675f6368616e6765000010821000150000006772616e6470615f666f726365645f6368616e6765496e76616c6964206f726967696e00000000003c8310000800000000000000448310000300000000000000000000005c831000010000000000000000000000648310000c0000000000000018e8100002000000000000000000000070831000010000000000000000000000788310000a00000000000000848310000100000000000000000000008c831000010000000000000000000000948310000f00000000000000a4831000010000000000000000000000ac831000010000000000000000000000b48310000a00000000000000c0831000020000000000000000000000d0831000020000000000000000000000e08310000800000000000000e8831000020000000000000000000000f883100001000000000000005472616e73666572611011000900000061101100090000006a101100070000002385100055000000496e7374616e746961746564ec84100037000000436f646553746f72656400005ce8100004000000be8410002e0000005363686564756c65557064617465640006111100030000008e841000300000004469737061746368656400006110110009000000d333110004000000238410004e000000718410001d000000436f6e74726163746110110009000000d5ca100007000000008410002300000020416e206576656e742066726f6d20636f6e7472616374206f66206163636f756e742e20412063616c6c2077617320646973706174636865642066726f6d2074686520676976656e206163636f756e742e2054686520626f6f6c207369676e616c73207768657468657220697420776173207375636365737366756c20657865637574696f6e206f72206e6f742e20547269676765726564207768656e207468652063757272656e74207363686564756c6520697320757064617465642e20436f646520776974682074686520737065636966696564206861736820686173206265656e2073746f7265642e20436f6e7472616374206465706c6f7965642062792061646472657373206174207468652073706563696669656420616464726573732e205472616e736665722068617070656e6564206066726f6d6020746f2060746f60207769746820676976656e206076616c7565602061732070617274206f662061206063616c6c60206f722060637265617465602e64656661756c743a0000000070e71000080000000000000088861000040000000000000000000000a8861000020000000000000000000000b88610000500000000000000c0861000050000000000000000000000e8861000020000000000000000000000f886100008000000000000008483100001000000000000000000000000871000010000000000000000000000088710000b000000000000008483100001000000000000000000000014871000010000000000000000000000f2e7100008000000000000001c8710000200000000000000000000002c871000010000000000000000000000348710000e000000000000001c8710000200000000000000000000004487100001000000000000006110110009000000348910000d0000005ce8100004000000c68810000b000000d1881000530000002489100010000000566f74656400000061101100090000005ce8100004000000d333110004000000c68810000b000000c68810000b0000003e881000420000008088100046000000417070726f7665640d88100031000000446973617070726f76656400d8871000350000005ce8100004000000d33311000400000097871000410000004d656d626572457865637574656400004c8710004b00000020412073696e676c65206d656d6265722064696420736f6d6520616374696f6e3b2060626f6f6c6020697320747275652069662072657475726e656420776974686f7574206572726f722e2041206d6f74696f6e207761732065786563757465643b2060626f6f6c6020697320747275652069662072657475726e656420776974686f7574206572726f722e2041206d6f74696f6e20776173206e6f7420617070726f76656420627920746865207265717569726564207468726573686f6c642e2041206d6f74696f6e2077617320617070726f76656420627920746865207265717569726564207468726573686f6c642e2041206d6f74696f6e2028676976656e20686173682920686173206265656e20766f746564206f6e20627920676976656e206163636f756e742c206c656176696e6720612074616c6c79202879657320766f74657320616e64206e6f20766f74657320676976656e20726573706563746976656c7920617320604d656d626572436f756e7460292e4d656d626572436f756e742041206d6f74696f6e2028676976656e20686173682920686173206265656e2070726f706f7365642028627920676976656e206163636f756e742920776974682061207468726573686f6c642028676976656e20604d656d626572436f756e7460292e50726f706f73616c496e646578436f6e7472616374205072697374696e65436f6465496e7374616e636531436f6c6c656374697665204d656d62657273496e7374616e636532436f6c6c656374697665204d656d62657273436f6e747261637420436f646553746f72616765436f6e747261637420436f6e7472616374496e666f4f66436f6e74726163742047617350726963650a68110028000000e0891000450000007d000000010000002f686f6d652f616e6472652f576f726b62656e63682f706172697479746563682f7375627374726174652f73726d6c2f636f6c6c6563746976652f7372632f6c69622e727300000000000000308b10000f00000000000000408b1000010000000000000000000000588b1000030000000000000000000000708b10000800000000000000788b1000020000000000000000000000a88b1000020000000000000000000000b94711000400000000000000b88b1000040000000000000000000000188c1000070000000000000000000000508c10000600000000000000588c1000040000000000000000000000b88c10000a0000000000000000000000088d10000f00000000000000188d1000020000000000000000000000488d1000050000000000000000000000708d10000a000000000000007c8d1000040000000000000000000000dc8d100006000000000000007570646174655f7363686564756c650000000000fb951000080000000000000003961000080000008b9510002d000000386b110000000000b8951000430000007075745f636f6465000000004d9310000900000000000000569310000c00000000000000879510000400000000000000d5ca100007000000fb94100057000000529510003500000000000000b58f10000400000000000000b01d11002300000000000000ee2511000500000000000000f325110015000000000000004d9310000900000000000000569310000c00000000000000629310000400000000000000d5ca1000070000006693100042000000386b110000000000a89310004a000000f29310002c0000001e941000460000006494100052000000b694100045000000637265617465000000000000449310000900000000000000f325110015000000000000004d9310000900000000000000569310000c00000000000000b98f10000900000000000000c28f10000b00000000000000629310000400000000000000d5ca1000070000002d9110006a000000386b1100000000009791100021000000386b110000000000b8911000500000000892100041000000499210005b000000a492100057000000fb9210002a000000259310001f000000636c61696d5f7375726368617267650000000000b58f10000400000000000000423111000c000000000000000f9110000a000000000000001991100014000000f58f10005c0000005190100045000000386b110000000000969010004e000000e49010002b000000726573746f72655f746f000000000000b58f10000400000000000000423111000c00000000000000b98f10000900000000000000c28f10000b00000000000000cd8f10000e000000000000001d3311000c00000000000000db8f10000500000000000000e08f1000150000000c8e100040000000386b1100000000004c8e10006f000000bb8e10004e000000098f1000640000006d8f10004800000020416c6c6f7773206120636f6e747261637420746f20726573746f7265206120746f6d6273746f6e6520627920676976696e67206974732073746f726167652e2054686520636f6e747261637420746861742077616e747320746f20726573746f72652028692e652e206f726967696e206f66207468652063616c6c2c206f7220606d73672e73656e6465726020696e20536f6c6964697479207465726d73292077696c6c20636f6d70757465206120746f6d6273746f6e652077697468206974732073746f7261676520616e642074686520676976656e20636f64655f686173682e2049662074686520636f6d707574656420746f6d6273746f6e65206d61746368207468652064657374696e6174696f6e206f6e652c207468652064657374696e6174696f6e20636f6e747261637420697320726573746f7265642077697468207468652072656e745f616c6c6f77616e636560207370656369666965642c207768696c6520746865206f726967696e2073656e647320616c6c206974732066756e647320746f207468652064657374696e6174696f6e20616e642069732072656d6f7665642e64657374636f64655f68617368436f6465486173683c543e72656e745f616c6c6f77616e636564656c74615665633c657865633a3a53746f726167654b65793e20416c6c6f777320626c6f636b2070726f64756365727320746f20636c61696d206120736d616c6c2072657761726420666f72206576696374696e67206120636f6e74726163742e204966206120626c6f636b2070726f6475636572206661696c7320746f20646f20736f2c206120726567756c61722075736572732077696c6c20626520616c6c6f77656420746f20636c61696d20746865207265776172642e20496620636f6e7472616374206973206e6f742065766963746564206173206120726573756c74206f6620746869732063616c6c2c206e6f20616374696f6e73206172652074616b656e20616e64207468652073656e646572206973206e6f7420656c696769626c6520666f7220746865207265776172642e6175785f73656e6465724f7074696f6e3c543a3a4163636f756e7449643e20437265617465732061206e657720636f6e74726163742066726f6d207468652060636f646568617368602067656e65726174656420627920607075745f636f6465602c206f7074696f6e616c6c79207472616e7366657272696e6720736f6d652062616c616e63652e204372656174696f6e20697320657865637574656420617320666f6c6c6f77733a202d205468652064657374696e6174696f6e206164647265737320697320636f6d7075746564206261736564206f6e207468652073656e64657220616e642068617368206f662074686520636f64652e202d2054686520736d6172742d636f6e7472616374206163636f756e7420697320637265617465642061742074686520636f6d707574656420616464726573732e202d20546865206063746f725f636f64656020697320657865637574656420696e2074686520636f6e74657874206f6620746865206e65776c792d63726561746564206163636f756e742e204275666665722072657475726e656420202061667465722074686520657865637574696f6e206973207361766564206173207468652060636f646560206f6620746865206163636f756e742e205468617420636f64652077696c6c20626520696e766f6b656420202075706f6e20616e792063616c6c2072656365697665642062792074686973206163636f756e742e202d2054686520636f6e747261637420697320696e697469616c697a65642e656e646f776d656e746761735f6c696d6974436f6d706163743c4761733e64617461204d616b657320612063616c6c20746f20616e206163636f756e742c206f7074696f6e616c6c79207472616e7366657272696e6720736f6d652062616c616e63652e202a20496620746865206163636f756e74206973206120736d6172742d636f6e7472616374206163636f756e742c20746865206173736f63696174656420636f64652077696c6c20626520657865637574656420616e6420616e792076616c75652077696c6c206265207472616e736665727265642e202a20496620746865206163636f756e74206973206120726567756c6172206163636f756e742c20616e792076616c75652077696c6c206265207472616e736665727265642e202a204966206e6f206163636f756e742065786973747320616e64207468652063616c6c2076616c7565206973206e6f74206c657373207468616e20606578697374656e7469616c5f6465706f736974602c206120726567756c6172206163636f756e742077696c6c206265206372656174656420616e6420616e792076616c75652077696c6c206265207472616e736665727265642e2053746f7265732074686520676976656e2062696e617279205761736d20636f646520696e746f2074686520636861696e27732073746f7261676520616e642072657475726e73206974732060636f646568617368602e20596f752063616e20696e7374616e746961746520636f6e747261637473206f6e6c7920776974682073746f72656420636f64652e636f6465205570646174657320746865207363686564756c6520666f72206d65746572696e6720636f6e7472616374732e20546865207363686564756c65206d7573742068617665206120677265617465722076657273696f6e207468616e207468652073746f726564207363686564756c652e7363686564756c655363686564756c650000000000749810000800000000000000000000007c9810000300000000000000000000000000000000000000000000000000000000000000408111000099100000000000000000008098100001000000000000000100000000000000889810000f000000000000000000000003961000080000000000000000000000000000000000000000000000000000000000000040811100989810000000000000000000a898100001000000000000000100000000000000b09810000c0000000101000000000000c28f10000b00000000000000d5ca100007000000000000000000000000000000000000004081110060b010000000000000000000bc98100001000000000000000000000000000000c49810000b0000000101000000000000c28f10000b00000000000000cf98100016000000000000000000000000000000000000004081110060b010000000000000000000e898100001000000000000000000000000000000f09810000e000000000000000000000020cb10000300000000000000000000000000000000000000000000000000000000000000408111000099100000000000000000001099100001000000000000000100000000000000189910000e0000000101000000000000423111000c00000000000000269910000f00000000000000000000000000000000000000408111003899100000000000000000004899100001000000000000000000000000000000509910000800000000000000000000001d3311000c0000000000000000000000000000000000000000000000000000000000000040811100589910000000000000000000689910000100000000000000010000004761735370656e7447617300a49a10002000000043757272656e745363686564756c65002f0000000000000001000000880000007f9a1000250000005072697374696e65436f6465269a100059000000436f646553746f726167657761736d3a3a5072656661625761736d4d6f64756c65000000cd991000590000004163636f756e74436f756e74657200002f000000000000000100000035000000b899100015000000436f6e7472616374496e666f4f66436f6e7472616374496e666f3c543e0000002f00000000000000010000003c0000008e9910002a00000047617350726963652f000000000000000100000089000000709910001e00000020546865207072696365206f66206f6e6520756e6974206f66206761732e2054686520636f6465206173736f6369617465642077697468206120676976656e206163636f756e742e20546865207375627472696520636f756e7465722e2041206d617070696e67206265747765656e20616e206f726967696e616c20636f6465206861736820616e6420696e737472756d656e746564207761736d20636f64652c20726561647920666f7220657865637574696f6e2e2041206d617070696e672066726f6d20616e206f726967696e616c20636f6465206861736820746f20746865206f726967696e616c20636f64652c20756e746f756368656420627920696e737472756d656e746174696f6e2e2043757272656e7420636f7374207363686564756c6520666f7220636f6e7472616374732e20476173207370656e7420736f2066617220696e207468697320626c6f636b2e00000000449e100013000000000000001bf610000e0000000000000040811100589e10000000000000000000689e1000040000000000000000000000889e100010000000000000001d3311000c0000000000000040811100989e10000000000000000000a89e1000010000000000000000000000b09e1000110000000000000006111100030000000000000040811100c49e10000000000000000000d49e1000020000000000000000000000e49e10000b000000000000001d3311000c0000000000000040811100f09e10000000000000000000009f1000010000000000000000000000089f100011000000000000001d3311000c00000000000000408111001c9f100000000000000000002c9f1000070000000000000000000000649f10000f000000000000001d3311000c0000000000000040811100749f10000000000000000000849f1000020000000000000000000000949f10000b000000000000001d3311000c000000000000004081110010a010000000000000000000a09f1000010000000000000000000000a89f10000b000000000000001d3311000c000000000000004081110010a010000000000000000000b49f1000010000000000000000000000bc9f100012000000000000001d3311000c000000000000004081110010a010000000000000000000d09f1000010000000000000000000000d89f100012000000000000001d3311000c0000000000000040811100ec9f10000000000000000000fc9f100001000000000000000000000004a010000b000000000000001d3311000c000000000000004081110010a01000000000000000000020a0100002000000000000000000000030a010000b000000000000007c9810000300000000000000408111005ca0100000000000000000003ca010000200000000000000000000004ca010000d000000000000007c9810000300000000000000408111005ca0100000000000000000006ca010000200000000000000000000007ca0100008000000000000000611110003000000000000004081110084a01000000000000000000094a01000020000000000000000000000a4a010000c0000000000000006111100030000000000000040811100b0a010000000000000000000c0a01000010000000000000000000000c8a010000d000000000000007c981000030000000000000040811100d8a010000000000000000000e8a0100002000000000000005369676e6564436c61696d48616e6469636170002f00000000000000010000008a00000085a6100038000000386b110000000000bda610004300000000a710001a000000546f6d6273746f6e654465706f7369742f00000000000000010000008b00000050a610003500000053746f7261676553697a654f66667365740000002f000000000000000100000043000000d7a510004b00000022a610002e00000052656e7442797465466565002f00000000000000010000008c0000008aa510004d00000052656e744465706f7369744f66667365740000002f00000000000000010000008d00000012a410004100000053a4100016000000386b11000000000069a410005a000000c3a410005600000019a51000530000006ca510001e000000537572636861726765526577617264002f00000000000000010000008e000000bfa3100039000000f8a310001a0000005472616e73666572466565009aa31000250000004372656174696f6e4665650073a31000270000005472616e73616374696f6e4261736546656500003ca31000370000005472616e73616374696f6e4279746546656500002f000000000000000100000034000000f9a2100043000000436f6e7472616374466565002f000000000000000100000033000000a7a210004b000000f2a210000700000043616c6c426173654665650052a210004700000099a210000e000000437265617465426173654665650000002f00000000000000010000003b00000001a21000490000004aa21000080000004d617844657074682f00000000000000010000008f000000aca1100047000000f3a110000e0000004d617856616c756553697a652f0000000000000001000000900000005ea110004e000000426c6f636b4761734c696d69740000002f000000000000000100000091000000f8a010004900000041a110001d00000020546865206d6178696d756d20616d6f756e74206f6620676173207468617420636f756c6420626520657870656e6465642070657220626c6f636b2e204120726561736f6e61626c652064656661756c742076616c75652069732031305f3030305f3030302e20546865206d6178696d756d2073697a65206f6620612073746f726167652076616c756520696e2062797465732e204120726561736f6e61626c652064656661756c74206973203136204b69422e20546865206d6178696d756d206e657374696e67206c6576656c206f6620612063616c6c2f63726561746520737461636b2e204120726561736f6e61626c652064656661756c742076616c7565206973203130302e20546865206261736520666565206368617267656420666f72206372656174696e67206120636f6e74726163742e204120726561736f6e61626c652064656661756c742076616c7565206973203137352e20546865206261736520666565206368617267656420666f722063616c6c696e6720696e746f206120636f6e74726163742e204120726561736f6e61626c652064656661756c742076616c7565206973203133352e205468652066656520726571756972656420746f20637265617465206120636f6e747261637420696e7374616e63652e204120726561736f6e61626c652064656661756c742076616c75652069732032312e205468652066656520746f206265207061696420666f72206d616b696e672061207472616e73616374696f6e3b20746865207065722d6279746520706f7274696f6e2e205468652066656520746f206265207061696420666f72206d616b696e672061207472616e73616374696f6e3b2074686520626173652e205468652066656520726571756972656420746f2063726561746520616e206163636f756e742e205468652066656520726571756972656420746f206d616b652061207472616e736665722e205265776172642074686174206973207265636569766564206279207468652070617274792077686f736520746f75636820686173206c656420746f2072656d6f76616c206f66206120636f6e74726163742e2054686520616d6f756e74206f662066756e6473206120636f6e74726163742073686f756c64206465706f73697420696e206f7264657220746f206f66667365742074686520636f7374206f66206f6e6520627974652e204c6574277320737570706f736520746865206465706f73697420697320312c303030204255202862616c616e636520756e697473292f6279746520616e64207468652072656e7420697320312042552f627974652f6461792c207468656e206120636f6e7472616374207769746820312c3030302c3030302042552074686174207573657320312c303030206279746573206f662073746f7261676520776f756c6420706179206e6f2072656e742e20427574206966207468652062616c616e6365207265647563656420746f203530302c30303020425520616e64207468652073746f7261676520737461796564207468652073616d6520617420312c3030302c207468656e20697420776f756c6420706179203530302042552f6461792e205072696365206f6620612062797465206f662073746f7261676520706572206f6e6520626c6f636b20696e74657276616c2e2053686f756c642062652067726561746572207468616e20302e2053697a65206f66206120636f6e7472616374206174207468652074696d65206f66206372656174696f6e2e205468697320697320612073696d706c652077617920746f20656e73757265207468617420656d70747920636f6e747261637473206576656e7475616c6c7920676574732064656c657465642e20546865206d696e696d756d20616d6f756e7420726571756972656420746f2067656e6572617465206120746f6d6273746f6e652e204e756d626572206f6620626c6f636b2064656c617920616e2065787472696e73696320636c61696d20737572636861726765206861732e205768656e20636c61696d207375726368617267652069732063616c6c656420627920616e2065787472696e736963207468652072656e7420697320636865636b656420666f722063757272656e745f626c6f636b202d2064656c6179496e7374616e636531436f6c6c6563746976652050726f706f73616c73496e7374616e636531436f6c6c65637469766520566f74696e670000000000000004a810000b0000000000000010a8100001000000000000000000000028a8100004000000000000000000000048a81000070000000000000050a8100001000000000000000000000068a8100003000000000000000000000028ed1000070000000000000080a81000020000000000000000000000b0a81000040000000000000000000000e0ed10000400000000000000d0a8100003000000000000000000000018a9100004000000000000007365745f6d656d6265727300000000003fab10000b00000000000000b11a110011000000beaa10005400000012ab100017000000386b11000000000029ab100016000000657865637574650000000000f4f61000080000000000000038aa10001e00000056aa10003d000000386b11000000000093aa10002b000000000000005ff81000090000000000000024aa10001400000000000000f4f61000080000000000000038aa10001e0000007e1b11000b000000d2a9100024000000f6a910002e0000001f1c11000c00000000000000f4f61000080000000000000005f410000700000000000000b0a910000500000000000000b5a910001600000000000000cba910000700000000000000d3331100040000007e1b11000b00000038a91000230000005ba91000550000001f1c11000c000000202d20426f756e6465642073746f72616765207265616420616e64207772697465732e202d2057696c6c20626520736c696768746c792068656176696572206966207468652070726f706f73616c20697320617070726f766564202f20646973617070726f7665642061667465722074686520766f74652e696e646578436f6d706163743c50726f706f73616c496e6465783e617070726f7665202d20426f756e6465642073746f7261676520726561647320616e64207772697465732e202d20417267756d656e7420607468726573686f6c6460206861732062656172696e67206f6e207765696768742e436f6d706163743c4d656d626572436f756e743e426f783c3c542061732054726169743c493e3e3a3a50726f706f73616c3e20446973706174636820612070726f706f73616c2066726f6d2061206d656d626572207573696e672074686520604d656d62657260206f726967696e2e204f726967696e206d7573742062652061206d656d626572206f662074686520636f6c6c6563746976652e205365742074686520636f6c6c6563746976652773206d656d62657273686970206d616e75616c6c7920746f20606e65775f6d656d62657273602e204265206e69636520746f2074686520636861696e20616e642070726f76696465206974207072652d736f727465642e20526571756972657320726f6f74206f726967696e2e6e65775f6d656d62657273496e7374616e636531436f6c6c6563746976650000000000000018ad100009000000000000000000000021ad10000c000000000000000000000000000000000000000000000000000000000000004081110080b01000000000000000000030ad10000100000000000000010000000000000038ad10000a000000010100000000000005f41000070000000000000042ad100019000000000000000000000000000000000000004081110060b0100000000000000000005cad10000100000000000000000000000000000064ad100006000000010100000000000005f4100007000000000000006aad100013000000000000000000000000000000000000004081110060b01000000000000000000080ad10000100000000000000000000000000000088ad10000d00000000000000000000000611110003000000000000000000000000000000000000000000000000000000000000004081110070b01000000000000000000098ad100001000000000000000100000000000000a0ad1000070000000000000000000000b11a110011000000000000000000000000000000000000000000000000000000000000004081110080b010000000000000000000a8ad100001000000000000000100000050726f706f73616c735665633c543a3a486173683e00000070ae10002400000050726f706f73616c4f663c542061732054726169743c493e3e3a3a50726f706f73616c003dae100033000000566f74696e67566f7465733c543a3a4163636f756e7449643e00000010ae10002d00000050726f706f73616c436f756e74000000fead1000120000004d656d6265727300b0ad10004e000000205468652063757272656e74206d656d62657273206f662074686520636f6c6c6563746976652e20546869732069732073746f72656420736f7274656420286a7573742062792076616c7565292e2050726f706f73616c7320736f206661722e20566f746573206f6e206120676976656e2070726f706f73616c2c206966206974206973206f6e676f696e672e2041637475616c2070726f706f73616c20666f72206120676976656e20686173682c20696620697427732063757272656e742e2054686520686173686573206f6620746865206163746976652070726f706f73616c732e496e7374616e636532436f6c6c656374697665000000000018ad100009000000000000000000000021ad10000c000000000000000000000000000000000000000000000000000000000000004081110080b01000000000000000000030ad10000100000000000000010000000000000038ad10000a000000010100000000000005f41000070000000000000042ad100019000000000000000000000000000000000000004081110060b0100000000000000000005cad10000100000000000000000000000000000064ad100006000000010100000000000005f4100007000000000000006aad100013000000000000000000000000000000000000004081110060b01000000000000000000080ad10000100000000000000000000000000000088ad10000d00000000000000000000000611110003000000000000000000000000000000000000000000000000000000000000004081110070b01000000000000000000098ad100001000000000000000100000000000000a0ad1000070000000000000000000000b11a110011000000000000000000000000000000000000000000000000000000000000004081110080b010000000000000000000a8ad10000100000000000000010000002f0000000000000001000000360000002f0000000000000001000000410000002f0000000000000001000000310000000a68110028000000a8b0100044000000b7010000010000002f686f6d652f616e6472652f576f726b62656e63682f706172697479746563682f7375627374726174652f73726d6c2f636f6e7472616374732f7372632f6c69622e7273a8b0100044000000b7010000010000006e6577207363686564756c65206d7573742068617665206120677265617465722076657273696f6e207468616e2063757272656e74496e76616c69642073757263686172676520636c61696d3a206f726967696e206d757374206265207369676e6564206f7220696e686572656e7420616e6420617578696c696172792073656e646572206f6e6c792070726f7669646564206f6e20696e686572656e7443616e6e6f7420726573746f72652066726f6d20696e6578697374696e67206f7220746f6d6273746f6e6520636f6e74726163744f726967696e20547269654964207772697474656e20696e207468652063757272656e7420626c6f636b546f6d6273746f6e657320646f6e2774206d6174636843616e6e6f7420726573746f726520746f20696e6578697374696e67206f7220616c69766520636f6e7472616374e0891000450000007d0000000100000070726f706f736572206e6f742061206d656d6265726475706c69636174652070726f706f73616c73206e6f7420616c6c6f776564496e7374616e636531436f6c6c6563746976652050726f706f73616c4f66496e7374616e636531436f6c6c6563746976652050726f706f73616c436f756e7470726f706f73616c206d757374206578697374766f746572206e6f742061206d656d6265726d69736d61746368656420696e6465786475706c696361746520766f74652069676e6f726564000020b3100048000000880a00000e000000000000002f72757374632f633739386466666163396463386338323337346462343866356234373436393063633665393638362f7372632f6c6962636f72652f736c6963652f6d6f642e7273496e7374616e636532436f6c6c6563746976652050726f706f73616c73496e7374616e636532436f6c6c65637469766520566f74696e67496e7374616e636532436f6c6c6563746976652050726f706f73616c4f66496e7374616e636532436f6c6c6563746976652050726f706f73616c436f756e740000000000000cb410000f000000000000001cb410000200000000000000000000002cb4100004000000000000004e65774163636f756e74496e646578006110110009000000c7b410000c0000004cb4100022000000386b1100000000006eb4100041000000afb41000180000002041206e6577206163636f756e7420696e646578207761732061737369676e65642e2054686973206576656e74206973206e6f7420747269676765726564207768656e20616e206578697374696e6720696e64657820697320726561737369676e656420746f20616e6f7468657220604163636f756e744964602e4163636f756e74496e64657800ecb410002b00000017b5100044000000ff0000000400000054696d657374616d70206d7573742062652075706461746564206f6e636520696e2074686520626c6f636b2f686f6d652f616e6472652f576f726b62656e63682f706172697479746563682f7375627374726174652f73726d6c2f74696d657374616d702f7372632f6c69622e7273626c6f636b2073697a65206c696d697420697320726561636865646f766572666c6f77206d756c7469706c79696e6720676173206c696d6974206279207072696365000000b8b510003000000017b5100044000000f30000000400000054696d657374616d70206d7573742062652075706461746564206f6e6c79206f6e636520696e2074686520626c6f636b00b610004e00000017b5100044000000f40000000400000054696d657374616d70206d75737420696e6372656d656e74206279206174206c65617374203c4d696e696d756d506572696f643e206265747765656e2073657175656e7469616c20626c6f636b7354696d657374616d70204e6f77417574686f727368697020417574686f72496e646963657320456e756d53657400a0b6100019000000c0b6100048000000bb0100002d000000000000000000000000000000617474656d707420746f20646976696465206279207a65726f000000000000002f72757374632f633739386466666163396463386338323337346462343866356234373436393063633665393638362f7372632f6c6962636f72652f6f70732f61726974682e72732d00000008000000040000002e0000000a6811002800000030b71000420000004a000000010000002f686f6d652f616e6472652f576f726b62656e63682f706172697479746563682f7375627374726174652f73726d6c2f696e64696365732f7372632f6c69622e7273000030b71000420000004a00000001000000696e76616c6964206163636f756e7420696e64657854696d657374616d7020746f6f2066617220696e2066757475726520746f206163636570744765747320616e64206465636f6465732074696d657374616d7020696e686572656e742064617461496e646963657300000000000000a0b810000b0000000000000000000000abb810000f0000000000000000000000000000000000000000000000000000000000000040811100bcb810000000000000000000ccb8100001000000000000000100000000000000d4b81000070000000101000000000000abb810000f00000000000000b11a1100110000000000000000000000000000000000000040811100dcb810000000000000000000ecb810000100000000000000010000004e657874456e756d536574543a3a4163636f756e74496e64657800002f0000000000000001000000410000000ab910001f000000456e756d536574002f000000000000000100000031000000f4b81000160000002054686520656e756d65726174696f6e20736574732e20546865206e657874206672656520656e756d65726174696f6e207365742e000000b0b9100048000000880a00000e000000a0b610001900000060b9100047000000e20000000a0000000000000000000000000000002f686f6d652f616e6472652f576f726b62656e63682f706172697479746563682f7375627374726174652f73726d6c2f7374616b696e672f7372632f70687261676d656e2e72730000000000000000002f72757374632f633739386466666163396463386338323337346462343866356234373436393063633665393638362f7372632f6c6962636f72652f736c6963652f6d6f642e7273496e6469636573204e657874456e756d536574417574686f727368697020556e636c65736d656d6f727976616c69646174696f6e3a20696d706f727420656e74727920706f696e747320746f2061206e6f6e2d6578697374656e74207479706543616e6e6f7420696d706f727420676c6f62616c736d6f64756c6520696d706f7274732061206e6f6e2d6578697374656e742066756e6374696f6e6d6f64756c6520696d706f72747320606578745f7072696e746c6e60206275742064656275672066656174757265732064697361626c656443616e6e6f7420696d706f7274207461626c65736d6f64756c652068617320696d706f7274732066726f6d2061206e6f6e2d27656e7627206e616d6573706163654d656d6f727920696d706f7274206d757374206861766520746865206669656c64206e616d6520276d656d6f7279274d756c7469706c65206d656d6f727920696d706f72747320646566696e65644d6178696d756d206e756d626572206f662070616765732073686f756c6420626520616c77617973206465636c617265642e52657175657374656420696e697469616c206e756d626572206f662070616765732073686f756c64206e6f74206578636565642074686520726571756573746564206d6178696d756d4d6178696d756d206e756d626572206f662070616765732073686f756c64206e6f74206578636565642074686520636f6e66696775726564206d6178696d756d2e00000000000044bc1000030000000000000048bc100001000000000000000000000060bc100009000000000000007365740000000000e2bd10000300000000000000e5bd100012000000a8bc100016000000386b110000000000bebc10005600000014bd100036000000386b1100000000004abd1000510000009bbd100011000000386b110000000000acbd10003600000020536574207468652063757272656e742074696d652e20546869732063616c6c2073686f756c6420626520696e766f6b65642065786163746c79206f6e63652070657220626c6f636b2e2049742077696c6c2070616e6963206174207468652066696e616c697a6174696f6e2070686173652c20696620746869732063616c6c206861736e2774206265656e20696e766f6b656420627920746861742074696d652e205468652074696d657374616d702073686f756c642062652067726561746572207468616e207468652070726576696f7573206f6e652062792074686520616d6f756e742073706563696669656420627920604d696e696d756d506572696f64602e20546865206469737061746368206f726967696e20666f7220746869732063616c6c206d7573742062652060496e686572656e74602e6e6f77436f6d706163743c543a3a4d6f6d656e743e54696d657374616d7000000000b0be100003000000000000000000000095e31000090000000000000000000000000000000000000000000000000000000000000040811100b4be10000000000000000000c4be100001000000000000000100000000000000ccbe1000090000000000000000000000d3331100040000000000000000000000000000000000000000000000000000000000000040811100f8c210000000000000000000d8be10000100000000000000010000004e6f77002f0000000000000001000000350000000dbf100024000000446964557064617465000000e0be10002d00000020446964207468652074696d657374616d7020676574207570646174656420696e207468697320626c6f636b3f2043757272656e742074696d6520666f72207468652063757272656e7420626c6f636b2e000000000000006cbf10000d0000000000000095e310000900000000000000408111007cbf100000000000000000008cbf100004000000000000004d696e696d756d506572696f640000002f000000000000000100000092000000acbf10005a00000006c010005a00000060c0100059000000b9c010001c00000020546865206d696e696d756d20706572696f64206265747765656e20626c6f636b732e204265776172652074686174207468697320697320646966666572656e7420746f20746865202a65787065637465642a20706572696f6420746861742074686520626c6f636b2070726f64756374696f6e206170706172617475732070726f76696465732e20596f75722063686f73656e20636f6e73656e7375732073797374656d2077696c6c2067656e6572616c6c7920776f726b2077697468207468697320746f2064657465726d696e6520612073656e7369626c6520626c6f636b2074696d652e20652e672e20466f7220417572612c2069742077696c6c20626520646f75626c65207468697320706572696f64206f6e2064656661756c742073657474696e67732e0000000000000004c110000a0000000000000010c1100001000000000000000000000028c1100001000000000000007365745f756e636c657300000000000049c110000a0000000000000053c110000e00000030c11000190000002050726f76696465206120736574206f6620756e636c65732e6e65775f756e636c65735665633c543a3a4865616465723e417574686f7273686970000000000074c210000600000000000000000000007ac210003a0000000000000000000000000000000000000000000000000000000000000040811100b4c210000000000000000000c4c2100001000000000000000100000000000000ccc21000060000000000000000000000423111000c0000000000000000000000000000000000000000000000000000000000000040811100d4c210000000000000000000e4c2100001000000000000000000000000000000ecc210000c0000000000000000000000d3331100040000000000000000000000000000000000000000000000000000000000000040811100f8c21000000000000000000008c31000010000000000000001000000556e636c65735665633c556e636c65456e7472794974656d3c543a3a426c6f636b4e756d6265722c20543a3a486173682c20543a3a4163636f756e7449643e3e2f00000000000000010000003100000058c3100007000000417574686f7200002f0000000000000001000000360000003fc3100019000000446964536574556e636c65732f00000000000000010000003600000010c310002f000000205768657468657220756e636c6573207765726520616c72656164792073657420696e207468697320626c6f636b2e20417574686f72206f662063757272656e7420626c6f636b2e20556e636c657300b0b9100048000000820a00000a000000556e636c657320616c72656164792073657420696e20626c6f636b2e756e636c652069732067656e65736973756e636c657320746f6f206869676820696e20636861696e756e636c6520706172656e74206e6f7420696e20636861696e756e636c65206e6f7420726563656e7420656e6f75676820746f20626520696e636c75646564756e636c6520616c726561647920696e636c75646564626164206f726967696e3a20657870656374656420746f206265206e6f206f726967696e626164206f726967696e3a20657870656374656420746f206265206120726f6f74206f726967696e626164206f726967696e3a20657870656374656420746f2062652061207369676e6564206f726967696e3a65787472696e7369635f696e64657873746f72616765206973206e6f74206e756c6c2c207468657265666f7265206d75737420626520612076616c696420747970650000e0c410001900000000c5100048000000420100000e00000000000000617474656d707420746f20646976696465206279207a65726f000000000000002f686f6d652f616e6472652f576f726b62656e63682f706172697479746563682f7375627374726174652f636f72652f73722d7072696d6974697665732f7372632f6c69622e727360c510000e0000006ec5100048000000400100004a0000006578706c696369742070616e69632f686f6d652f616e6472652f576f726b62656e63682f706172697479746563682f7375627374726174652f636f72652f73722d7072696d6974697665732f7372632f6c69622e7273000060c510000e0000006ec5100048000000410100004a000000e8c51000340000001cc6100045000000ac0000000300000074686520766563746f7220697320616c7761797320636c65617265643b2069742773207772697474656e206f6e6c79206f6e63652f686f6d652f616e6472652f576f726b62656e63682f706172697479746563682f7375627374726174652f73726d6c2f636f6e7472616374732f7372632f657865632e72730000002f000000000000000100000093000000940000009500000096000000970000009800000053797374656d204e756d62657253797374656d2045787472696e73696373526f6f7453797374656d2044696765737453797374656d20426c6f636b4861736853797374656d204163636f756e744e6f6e636500000a68110028000000f4c610003f0000009d000000010000002f686f6d652f616e6472652f576f726b62656e63682f706172697479746563682f7375627374726174652f73726d6c2f626162652f7372632f6c69622e7273000a681100280000004cc7100041000000dd000000010000002f686f6d652f616e6472652f576f726b62656e63682f706172697479746563682f7375627374726174652f73726d6c2f73797374656d2f7372632f6c69622e7273000000f4c610003f0000009d0000000100000074696d657374616d702073657420696e20626c6f636b20646f65736e2774206d6174636820736c6f7420696e207365616c53797374656d20506172656e744861736853797374656d2052616e646f6d4d6174657269616c0030c8100048000000880a00000e00000053797374656d204576656e747353797374656d204576656e74546f706963730000000000000000002f72757374632f633739386466666163396463386338323337346462343866356234373436393063633665393638362f7372632f6c6962636f72652f736c6963652f6d6f642e72730000000080c910000a00000000000000386b11000000000000000000000000008cc9100001000000000000000000000094c9100006000000000000009cc91000010000000000000000000000b4c91000010000000000000000000000bcc910000e00000000000000ccc91000010000000000000000000000e4c91000010000000000000000000000ecc910000800000000000000f4c910000100000000000000000000000cca100001000000000000000000000014ca10000b0000000000000020ca100001000000000000000000000038ca100001000000000000000000000040ca10000c000000000000004cca100001000000000000000000000064ca1000010000000000000066696c6c5f626c6f636b000045cb10004800000072656d61726b0000000000003ecb10000700000000000000d5ca10000700000023cb10001b0000007365745f686561705f70616765730000000000001bcb1000050000000000000020cb100003000000dcca10003f0000007365745f636f6465000000004b1c11000300000000000000d5ca100007000000c3ca1000120000007365745f73746f726167650000000000b1ca10000500000000000000b6ca10000d00000096ca10001b0000006b696c6c5f73746f72616765000000008aca100004000000000000008eca1000080000006cca10001e000000204b696c6c20736f6d65206974656d732066726f6d2073746f726167652e6b6579735665633c4b65793e2053657420736f6d65206974656d73206f662073746f726167652e6974656d735665633c4b657956616c75653e2053657420746865206e657720636f64652e5665633c75383e2053657420746865206e756d626572206f6620706167657320696e2074686520576562417373656d626c7920656e7669726f6e6d656e74277320686561702e7061676573753634204d616b6520736f6d65206f6e2d636861696e2072656d61726b2e5f72656d61726b20412062696720646973706174636820746861742077696c6c20646973616c6c6f7720616e79206f74686572207472616e73616374696f6e20746f20626520696e636c756465642e53797374656d0000000000bcd010000c0000000101000000000000423111000c00000000000000c8d0100008000000000000000000000000000000000000004081110048df10000000000000000000d0d0100001000000000000000100000000000000d8d010000e00000000000000000000000611110003000000000000000000000000000000000000000000000000000000000000004081110024d110000000000000000000e8d0100001000000000000000000000000000000f0d0100013000000000000000000000003d1100006000000000000000000000000000000000000000000000000000000000000004081110024d1100000000000000000000cd110000100000000000000000000000000000014d110001000000000000000000000000611110003000000000000000000000000000000000000000000000000000000000000004081110024d11000000000000000000034d11000010000000000000000000000000000003cd1100014000000000000000000000050d1100010000000000000000000000000000000000000000000000000000000000000004081110048df1000000000000000000060d110000200000000000000010000000000000070d110000900000001010000000000001bf610000e0000000000000005f4100007000000000000000000000000000000000000004081110020d2100000000000000000007cd110000100000000000000010000000000000084d110000d0000000101000000000000061111000300000000000000d5ca100007000000000000000000000000000000000000004081110094d110000000000000000000a4d1100001000000000000000100000000000000acd110000e0000000000000000000000bad11000120000000000000000000000000000000000000000000000000000000000000040811100ccd110000000000000000000dcd1100002000000000000000100000000000000ecd110000600000000000000000000001bf610000e000000000000000000000000000000000000000000000000000000000000004081110048df10000000000000000000f4d1100001000000000000000100000000000000fcd110000a000000000000000000000005f4100007000000000000000000000000000000000000000000000000000000000000004081110020d21000000000000000000008d210000100000000000000010000000000000010d210000e000000000000000000000005f4100007000000000000000000000000000000000000000000000000000000000000004081110020d21000000000000000000030d210000100000000000000010000000000000038d210000600000000000000000000003ed210000b00000000000000000000000000000000000000000000000000000000000000408111004cd2100000000000000000005cd210000100000000000000010000000000000064d210000600000000000000000000006ad2100023000000000000000000000000000000000000000000000000000000000000004081110090d210000000000000000000a0d2100001000000000000000100000000000000a8d210000a0000000000000000000000b2d210000a0000000000000000000000000000000000000000000000000000000000000040811100bcd210000000000000000000ccd2100001000000000000000100000000000000d4d210000b0000000201010000000000dfd21000020000000000000005f410000700000000000000e1d21000210000000000000040811100fcde1000000000000000000004d310000d00000000000000010000004163636f756e744e6f6e6365543a3a496e646578b1d910001f00000045787472696e736963436f756e74000083d910002e000000416c6c45787472696e736963735765696768745765696768740000003ed9100045000000416c6c45787472696e736963734c656e2f000000000000000100000036000000eed81000500000004e6578745765696768744d756c7469706c6965725765696768744d756c7469706c6965727ad8100059000000d3d810001b000000426c6f636b4861736800000054d810002600000045787472696e736963446174610000002f00000000000000010000003100000005d810004f00000052616e646f6d4d6174657269616c2869382c205665633c543a3a486173683e292f00000000000000010000009900000048d7100069000000b1d71000540000004e756d626572000006d7100042000000506172656e74486173680000ead610001c00000045787472696e73696373526f6f7400002f00000000000000010000009a000000a5d61000450000004469676573744469676573744f663c543e0000002f00000000000000010000003100000069d610003c0000004576656e74735665633c4576656e745265636f72643c543a3a4576656e742c20543a3a486173683e3e0000002f00000000000000010000003100000041d61000280000004576656e74436f756e744576656e74496e6465782f00000000000000010000004100000013d610002e0000004576656e74546f7069637328295665633c28543a3a426c6f636b4e756d6265722c204576656e74496e646578293e00006cd3100049000000b5d3100025000000386b110000000000dad310004b00000025d410002a000000386b1100000000004fd4100054000000a3d4100051000000f4d4100039000000386b1100000000002dd510005300000080d5100053000000d3d5100040000000204d617070696e67206265747765656e206120746f7069632028726570726573656e74656420627920543a3a486173682920616e64206120766563746f72206f6620696e6465786573206f66206576656e747320696e2074686520603c4576656e74733c543e3e60206c6973742e20546865206669727374206b657920736572766573206e6f20707572706f73652e2054686973206669656c64206973206465636c6172656420617320646f75626c655f6d6170206a75737420666f7220636f6e76656e69656e6365206f66207573696e67206072656d6f76655f707265666978602e20416c6c20746f70696320766563746f727320686176652064657465726d696e69737469632073746f72616765206c6f636174696f6e7320646570656e64696e67206f6e2074686520746f7069632e205468697320616c6c6f7773206c696768742d636c69656e747320746f206c6576657261676520746865206368616e67657320747269652073746f7261676520747261636b696e67206d656368616e69736d20616e6420696e2063617365206f66206368616e67657320666574636820746865206c697374206f66206576656e7473206f6620696e7465726573742e205468652076616c756520686173207468652074797065206028543a3a426c6f636b4e756d6265722c204576656e74496e646578296020626563617573652069662077652075736564206f6e6c79206a7573742074686520604576656e74496e64657860207468656e20696e20636173652069662074686520746f70696320686173207468652073616d6520636f6e74656e7473206f6e20746865206e65787420626c6f636b206e6f206e6f74696669636174696f6e2077696c6c20626520747269676765726564207468757320746865206576656e74206d69676874206265206c6f73742e20546865206e756d626572206f66206576656e747320696e2074686520604576656e74733c543e60206c6973742e204576656e7473206465706f736974656420666f72207468652063757272656e7420626c6f636b2e20446967657374206f66207468652063757272656e7420626c6f636b2c20616c736f2070617274206f662074686520626c6f636b206865616465722e2045787472696e7369637320726f6f74206f66207468652063757272656e7420626c6f636b2c20616c736f2070617274206f662074686520626c6f636b206865616465722e2048617368206f66207468652070726576696f757320626c6f636b2e205468652063757272656e7420626c6f636b206e756d626572206265696e672070726f6365737365642e205365742062792060657865637574655f626c6f636b602e20536572696573206f6620626c6f636b20686561646572732066726f6d20746865206c61737420383120626c6f636b73207468617420616374732061732072616e646f6d2073656564206d6174657269616c2e205468697320697320617272616e67656420617320612072696e6720627566666572207769746820746865206069386020707265666978206265696e672074686520696e64657820696e746f20746865206056656360206f6620746865206f6c6465737420686173682e2045787472696e73696373206461746120666f72207468652063757272656e7420626c6f636b20286d61707320616e2065787472696e736963277320696e64657820746f206974732064617461292e204d6170206f6620626c6f636b206e756d6265727320746f20626c6f636b206861736865732e20546865206e65787420776569676874206d756c7469706c6965722e20546869732073686f756c6420626520757064617465642061742074686520656e64206f66206561636820626c6f636b206261736564206f6e207468652073617475726174696f6e206c6576656c2028776569676874292e20546f74616c206c656e6774682028696e2062797465732920666f7220616c6c2065787472696e736963732070757420746f6765746865722c20666f72207468652063757272656e7420626c6f636b2e20546f74616c2077656967687420666f7220616c6c2065787472696e736963732070757420746f6765746865722c20666f72207468652063757272656e7420626c6f636b2e20546f74616c2065787472696e7369637320636f756e7420666f72207468652063757272656e7420626c6f636b2e2045787472696e73696373206e6f6e636520666f72206163636f756e74732e53657373696f6e20486973746f726963616c53657373696f6e7365706f636820696e64696365732077696c6c206e6576657220726561636820325e3634206265666f726520746865206465617468206f662074686520756e6976657273653b20716564000000000000000000000000000000000000000000000000000000000000000072656163686564206d6178696d756d2064657074682c2063616e6e6f7420637265617465009b00000018000000040000009c0000009d0000009e0000009f000000a0000000a10000006e6f7420656e6f7567682067617320746f20706179206261736520696e7374616e7469617465206665656e6f7420656e6f7567682067617320746f20706179207472616e736665722066656562616c616e636520746f6f206c6f7720746f2073656e642076616c756576616c756520746f6f206c6f7720746f20637265617465206163636f756e7464657374696e6174696f6e2062616c616e636520746f6f206869676820746f20726563656976652076616c756572656163686564206d6178696d756d2064657074682c2063616e6e6f74206d616b6520612063616c6c6e6f7420656e6f7567682067617320746f2070617920626173652063616c6c20666565636f6e747261637420686173206265656e206576696374656470726576696f75732f6e657874206f6e6c7920636f6e7461696e206578697374696e6720656e74697265733b20776520656e756d6572617465207573696e67206e6578743b20656e747279206578697374733b207165640000004cc7100041000000dd000000010000003a6865617070616765733a636f64657472616e73616374696f6e20626972746820626c6f636b20616e6369656e7442616265000000000000bcde10000a000000000000000000000020cb100003000000000000000000000000000000000000000000000000000000000000004081110048df10000000000000000000c8de100001000000000000000100000000000000d0de10000b0000000000000000000000dbde10001e0000000000000000000000000000000000000000000000000000000000000040811100fcde100000000000000000000cdf10000100000000000000010000000000000014df10000e000000000000000000000020cb100003000000000000000000000000000000000000000000000000000000000000004081110048df1000000000000000000024df1000030000000000000001000000000000003cdf10000b000000000000000000000020cb100003000000000000000000000000000000000000000000000000000000000000004081110048df1000000000000000000058df10000100000000000000010000000000000060df10000a00000000000000000000006adf1000080000000000000000000000000000000000000000000000000000000000000040811100f0df1000000000000000000074df10000a000000000000000100000000000000c4df10000e00000000000000000000006adf1000080000000000000000000000000000000000000000000000000000000000000040811100f0df10000000000000000000d4df100001000000000000000100000000000000dcdf10001100000000000000000000006adf1000080000000000000000000000000000000000000000000000000000000000000040811100f0df1000000000000000000000e0100001000000000000000100000045706f6368496e6465780000cde2100015000000417574686f7269746965735665633c28417574686f7269747949642c2042616265576569676874293e0000002f000000000000000100000031000000b2e210001b00000045706f63685374617274536c6f74000019e210004000000059e210003e00000097e210001b00000043757272656e74536c6f74002f00000000000000010000003500000004e210001500000052616e646f6d6e6573735b75383b2033325d00003ee010002e000000386b1100000000006ce010000b000000386b11000000000077e0100041000000b8e010003e000000f6e01000450000003be110004500000080e1100041000000c1e11000430000004e65787452616e646f6d6e657373000027e0100017000000556e646572436f6e737472756374696f6e0000002f0000000000000001000000a200000008e010001f0000002052616e646f6d6e65737320756e64657220636f6e737472756374696f6e2e204e6578742065706f63682072616e646f6d6e6573732e205468652065706f63682072616e646f6d6e65737320666f7220746865202a63757272656e742a2065706f63682e20232053656375726974792054686973204d555354204e4f54206265207573656420666f722067616d626c696e672c2061732069742063616e20626520696e666c75656e6365642062792061206d616c6963696f75732076616c696461746f7220696e207468652073686f7274207465726d2e204974204d4159206265207573656420696e206d616e792063727970746f677261706869632070726f746f636f6c732c20686f77657665722c20736f206c6f6e67206173206f6e652072656d656d626572732074686174207468697320286c696b652065766572797468696e6720656c7365206f6e2d636861696e29206974206973207075626c69632e20466f72206578616d706c652c2069742063616e20626520757365642077686572652061206e756d626572206973206e656564656420746861742063616e6e6f742068617665206265656e2063686f73656e20627920616e206164766572736172792c20666f7220707572706f7365732073756368206173207075626c69632d636f696e207a65726f2d6b6e6f776c656467652070726f6f66732e2043757272656e7420736c6f74206e756d6265722e20536c6f74206174207768696368207468652063757272656e742065706f636820737461727465642e20497420697320706f737369626c652074686174206e6f20626c6f636b2077617320617574686f7265642061742074686520676976656e20736c6f7420616e64207468652065706f6368206368616e676520776173207369676e616c6c6564206c61746572207468616e20746869732e2043757272656e742065706f636820617574686f7269746965732e2043757272656e742065706f636820696e6465782e00000000000054e310000d0000000000000020cb100003000000000000004081110064e31000000000000000000074e3100002000000000000000000000084e31000110000000000000095e31000090000000000000040811100a0e310000000000000000000b0e31000050000000000000045706f63684475726174696f6e0000002f0000000000000001000000a300000008e51000430000004be510003f0000004578706563746564426c6f636b54696d65543a3a4d6f6d656e7400002f0000000000000001000000a4000000d8e310004100000019e41000440000005de41000410000009ee4100042000000e0e410002800000020546865206578706563746564206176657261676520626c6f636b2074696d6520617420776869636820424142452073686f756c64206265206372656174696e6720626c6f636b732e2053696e636520424142452069732070726f626162696c6973746963206974206973206e6f74207472697669616c20746f20666967757265206f7574207768617420746865206578706563746564206176657261676520626c6f636b2074696d652073686f756c64206265206261736564206f6e2074686520736c6f74206475726174696f6e20616e642074686520736563757269747920706172616d657465722060636020287768657265206031202d20636020726570726573656e7473207468652070726f626162696c697479206f66206120736c6f74206265696e6720656d707479292e20546865206e756d626572206f66202a2a736c6f74732a2a207468617420616e2065706f63682074616b65732e20576520636f75706c652073657373696f6e7320746f2065706f6368732c20692e652e2077652073746172742061206e65772073657373696f6e206f6e636520746865206e65772065706f636820626567696e732e00000000000070e71000080000000000000078e71000020000000000000000000000386b110000000000000000000000000088e71000060000000000000090e71000030000000000000000000000386b1100000000000000000000000000a8e710000e00000000000000386b1100000000000000000000000000386b1100000000000000000000000000b6e710000700000000000000c0e71000020000000000000000000000386b1100000000000000000000000000d0e710000600000000000000d8e71000010000000000000000000000386b1100000000000000000000000000e0e710000900000000000000d8e71000010000000000000000000000386b1100000000000000000000000000e9e710000900000000000000d8e71000010000000000000000000000386b1100000000000000000000000000f2e710000800000000000000fce71000020000000000000000000000386b11000000000000000000000000000ce81000090000000000000018e81000020000000000000000000000386b110000000000000000000000000028e810000b0000000000000034e81000010000000000000000000000386b11000000000000000000000000003ce81000060000000000000044e81000030000000000000000000000386b1100000000000000000050726f706f73656487e81000090000006a101100070000005461626c6564000087e81000090000006a1011000700000090e810000e00000045787465726e616c5461626c6564537461727465640000006be810000f0000007ae810000d00000050617373656400006be810000f0000004e6f7450617373656443616e63656c6c6564457865637574656400006be810000f000000d33311000400000044656c65676174656400000061101100090000006110110009000000556e64656c6567617465640061101100090000005665746f6564000061101100090000005ce810000400000060e810000b00000048617368426c6f636b4e756d6265725265666572656e64756d496e646578566f74655468726573686f6c6450726f70496e6465785665633c4163636f756e7449643e44656d6f637261637920566f74654f6644656d6f63726163792044656c65676174696f6e7344656d6f6372616379205265666572656e64756d496e666f4f6644656d6f6372616379204465706f7369744f6644656d6f6372616379204469737061746368517565756544656d6f637261637920566f74657273466f7268656164206f662044656d6f63726163792044656c65676174696f6e7344656d6f6372616379205075626c696350726f7073c0e9100048000000880a00000e0000004e6f207075626c69632070726f706f73616c732077616974696e6743616e6e6f7420696e6a6563742061207265666572656e64756d207468617420656e6473206561726c696572207468616e2070726563656564696e67207265666572656e64756d00002f72757374632f633739386466666163396463386338323337346462343866356234373436393063633665393638362f7372632f6c6962636f72652f736c6963652f6d6f642e727344656d6f6372616379204e65787445787465726e616c4e6f2065787465726e616c2070726f706f73616c2077616974696e6700000000000028ed1000070000000000000030ed100002000000000000000000000060ed100006000000000000000000000090ed1000060000000000000098ed1000010000000000000000000000b0ed1000060000000000000000000000e0ed10000400000000000000e4ed100002000000000000000000000014ee10000700000000000000000000004cee10000a00000000000000e4ed100002000000000000000000000058ee100007000000000000000000000090ee10001100000000000000a4ee100004000000000000000000000004ef100006000000000000000000000034ef1000100000000000000044ef10000100000000000000000000005cef10000200000000000000000000006cef100010000000000000007cef100001000000000000000000000094ef1000020000000000000000000000a4ef100019000000000000007cef1000010000000000000000000000c0ef1000020000000000000000000000d0ef10000d00000000000000e0ef100003000000000000000000000028f0100008000000000000000000000068f010000d0000000000000078f0100001000000000000000000000090f0100001000000000000000000000098f010001100000000000000acf01000010000000000000000000000c4f01000010000000000000000000000ccf010000d00000000000000dcf0100003000000000000000000000024f110000100000000000000000000002cf11000090000000000000038f1100001000000000000000000000050f1100005000000000000000000000078f110000c00000000000000386b110000000000000000000000000084f11000050000000000000000000000acf110000c0000000000000038f11000010000000000000000000000b8f11000050000000000000000000000e0f110000800000000000000e8f1100002000000000000000000000018f2100005000000000000000000000040f210000a00000000000000386b11000000000000000000000000004cf21000050000000000000070726f706f73650000000000f4f610000800000000000000fcf610001000000000000000ee2511000500000000000000f32511001500000099f9100028000000386b1100000000007e1b11000b0000002e27110008000000d3f91000200000001f1c11000c0000007365636f6e64000000000000f4f610000800000000000000c1f910001200000099f9100028000000386b1100000000007e1b11000b0000002e27110008000000d4251100100000001f1c11000c000000766f746500000000c0f31000090000000000000093f310001800000000000000e0ed1000040000000000000095f910000400000019f910004d00000066f910002f000000386b1100000000007e1b11000b0000002e27110008000000faf810001f0000001f1c11000c00000070726f78795f766f7465000068f8100054000000bcf810003e000000386b1100000000007e1b11000b0000002e27110008000000faf810001f0000001f1c11000c000000656d657267656e63795f70726f706f736500000000000000f4f610000800000000000000fcf6100010000000000000005ff8100009000000000000007ae810000d000000000000000ef610000d000000000000001bf610000e0000000000000029f6100005000000000000001bf610000e00000060f7100022000000386b11000000000082f7100058000000daf7100046000000386b11000000000020f810003f000000656d657267656e63795f63616e63656c00000000c0f3100009000000000000006be810000f0000000cf7100054000000e8f610000c00000065787465726e616c5f70726f706f736500000000f4f610000800000000000000fcf61000100000009cf610004c000000e8f610000c00000065787465726e616c5f70726f706f73655f6d616a6f726974790000002ef610005600000084f610001800000065787465726e616c5f7075736800000000000000f8f310000d0000000000000005f4100007000000000000000ef610000d000000000000001bf610000e0000000000000029f6100005000000000000001bf610000e0000000cf410005400000060f4100059000000b9f410003b000000386b110000000000f4f410003e00000032f510004b0000007df5100055000000d2f510003c0000007665746f5f65787465726e616c00000000000000f8f310000d0000000000000005f4100007000000c9f310002f00000063616e63656c5f7265666572656e64756d00000000000000c0f31000090000000000000093f3100018000000abf310001500000063616e63656c5f717565756564000000000000006ff31000040000000000000073f3100017000000000000008af3100005000000000000004e1c11000c000000000000008ff31000040000000000000093f310001800000047f31000280000007365745f70726f78790000000000000042f310000500000000000000423111000c0000001cf3100026000000386b1100000000007e1b11000b00000094f21000160000001f1c11000c00000072657369676e5f70726f7879f6f2100026000000386b1100000000007e1b11000b000000e6f21000100000001f1c11000c00000072656d6f76655f70726f7879c0f2100026000000386b1100000000007e1b11000b000000e6f21000100000001f1c11000c00000064656c656761746500000000aaf210000200000000000000423111000c00000000000000acf210000a00000000000000b6f210000a00000085f210000f000000386b1100000000007e1b11000b00000094f21000160000001f1c11000c000000756e64656c6567617465000074f2100011000000386b1100000000007e1b11000b0000002e271100080000001f1c11000c00000020556e64656c656761746520766f74652e2044656c656761746520766f74652e202d204f6e6520657874726120444220656e7472792e746f636f6e76696374696f6e436f6e76696374696f6e20436c656172207468652070726f78792e2043616c6c6564206279207468652073746173682e202d204f6e6520444220636c6561722e20436c656172207468652070726f78792e2043616c6c6564206279207468652070726f78792e205370656369667920612070726f78792e2043616c6c6564206279207468652073746173682e70726f78792043616e63656c20612070726f706f73616c2071756575656420666f7220656e6163746d656e742e7768656e436f6d706163743c543a3a426c6f636b4e756d6265723e776869636877686174436f6d706163743c5265666572656e64756d496e6465783e2052656d6f76652061207265666572656e64756d2e7265665f696e646578205665746f20616e6420626c61636b6c697374207468652065787465726e616c2070726f706f73616c20686173682e70726f706f73616c5f68617368543a3a48617368205363686564756c65207468652063757272656e746c792065787465726e616c6c792d70726f706f736564206d616a6f726974792d63617272696573207265666572656e64756d20746f206265207461626c656420696d6d6564696174656c792e204966207468657265206973206e6f2065787465726e616c6c792d70726f706f736564207265666572656e64756d2063757272656e746c792c206f72206966207468657265206973206f6e6520627574206974206973206e6f742061206d616a6f726974792d63617272696573207265666572656e64756d207468656e206974206661696c732e202d206070726f706f73616c5f68617368603a205468652068617368206f66207468652063757272656e742065787465726e616c2070726f706f73616c2e202d2060766f74696e675f706572696f64603a2054686520706572696f64207468617420697320616c6c6f77656420666f7220766f74696e67206f6e20746869732070726f706f73616c2e202d206064656c6179603a20546865206e756d626572206f6620626c6f636b20616674657220766f74696e672068617320656e64656420696e20617070726f76616c20616e6420746869732073686f756c64206265202020656e61637465642e20496e6372656173656420746f2060456d657267656e6379566f74696e67506572696f646020696620746f6f206c6f772e766f74696e675f706572696f64543a3a426c6f636b4e756d62657264656c6179205363686564756c652061206d616a6f726974792d63617272696573207265666572656e64756d20746f206265207461626c6564206e657874206f6e6365206974206973206c6567616c20746f207363686564756c6520616e2065787465726e616c207265666572656e64756d2e205363686564756c652061207265666572656e64756d20746f206265207461626c6564206f6e6365206974206973206c6567616c20746f207363686564756c6520616e2065787465726e616c207265666572656e64756d2e70726f706f73616c426f783c543a3a50726f706f73616c3e205363686564756c6520616e20656d657267656e63792063616e63656c6c6174696f6e206f662061207265666572656e64756d2e2043616e6e6f742068617070656e20747769636520746f207468652073616d65205363686564756c6520616e20656d657267656e6379207265666572656e64756d2e20546869732077696c6c206372656174652061206e6577207265666572656e64756d20666f7220746865206070726f706f73616c602c20617070726f766564206173206c6f6e6720617320636f756e74656420766f7465732065786365656420607468726573686f6c646020616e642c20696620617070726f7665642c20656e61637465642061667465722074686520676976656e206064656c6179602e204974206d61792062652063616c6c65642066726f6d206569746865722074686520526f6f74206f722074686520456d657267656e6379206f726967696e2e7468726573686f6c6420566f746520696e2061207265666572656e64756d206f6e20626568616c66206f6620612073746173682e2049662060766f74652e69735f6179652829602c2074686520766f746520697320746f20656e616374207468652070726f706f73616c3b20206f7468657277697365206974206973206120766f746520746f206b65657020746865207374617475732071756f2e202d204f6e65204442206368616e67652c206f6e6520444220656e7472792e20566f746520696e2061207265666572656e64756d2e2049662060766f74652e69735f6179652829602c2074686520766f746520697320746f20656e616374207468652070726f706f73616c3b206f7468657277697365206974206973206120766f746520746f206b65657020746865207374617475732071756f2e566f74652050726f706f736520612073656e73697469766520616374696f6e20746f2062652074616b656e2e436f6d706163743c50726f70496e6465783e202d2054776f204442206368616e6765732c206f6e6520444220656e7472792e44656d6f63726163790000000024ff10000f000000000000000000000087e81000090000000000000000000000000000000000000000000000000000000000000040811100e4ff1000000000000000000034ff1000010000000000000001000000000000003cff10000b000000000000000000000047ff10002b0000000000000000000000000000000000000000000000000000000000000040811100a0001100000000000000000074ff1000010000000000000001000000000000007cff100009000000010100000000000087e81000090000000000000085ff1000210000000000000000000000000000000000000040811100a8ff10000000000000000000b8ff100001000000000000000000000000000000c0ff10000f00000000000000000000006be810000f0000000000000000000000000000000000000000000000000000000000000040811100e4ff10000000000000000000d0ff100001000000000000000100000000000000d8ff10000900000000000000000000006be810000f0000000000000000000000000000000000000000000000000000000000000040811100e4ff10000000000000000000f4ff100001000000000000000100000000000000fcff10001000000001010000000000006be810000f000000000000000c0011002d00000000000000000000000000000000000000408111001801110000000000000000003c00110001000000000000000000000000000000440011000d00000001010000000000001bf610000e00000000000000510011002b00000000000000000000000000000000000000408111007c00110000000000000000008c00110001000000000000000100000000000000940011000900000001010000000000006be810000f00000000000000b11a1100110000000000000000000000000000000000000040811100a00011000000000000000000b000110001000000000000000100000000000000b8001100060000000101000000000000be0011001f0000000000000095f91000040000000000000000000000000000000000000040811100e00011000000000000000000f00011000400000000000000010000000000000010011100050000000101000000000000423111000c00000000000000423111000c00000000000000000000000000000000000000408111001801110000000000000000002801110002000000000000000000000000000000380111000b0000000101010000000000423111000c00000000000000430111001a0000000000000000000000000000000000000040811100600111000000000000000000700111000100000000000000010000000000000078011100150000000000000000000000d33311000400000000000000000000000000000000000000000000000000000000000000408111005402110000000000000000009001110002000000000000000100000000000000a00111000c0000000000000000000000ac0111001c0000000000000000000000000000000000000000000000000000000000000040811100c80111000000000000000000d801110004000000000000000000000000000000f801110009000000010100000000000005f410000700000000000000010211002300000000000000000000000000000000000000408111002402110000000000000000003402110002000000000000000000000000000000440211000d000000010100000000000005f410000700000000000000d3331100040000000000000000000000000000000000000040811100540211000000000000000000640211000100000000000000010000005075626c696350726f70436f756e7400d40711003d0000005075626c696350726f70735665633c2850726f70496e6465782c20543a3a50726f706f73616c2c20543a3a4163636f756e744964293e0000b4071100200000004465706f7369744f662842616c616e63654f663c543e2c205665633c543a3a4163636f756e7449643e2900002f00000000000000010000003c00000093071100210000005265666572656e64756d436f756e7400470711004c0000004e65787454616c6c790000002f00000000000000010000004100000015071100320000005265666572656e64756d496e666f4f66285265666572656e64756d496e666f3c543a3a426c6f636b4e756d6265722c20543a3a50726f706f73616c3e29000000e80611002d000000446973706174636851756575655665633c4f7074696f6e3c28543a3a50726f706f73616c2c205265666572656e64756d496e646578293e3e2f000000000000000100000031000000b806110030000000566f74657273466f720000002f0000000000000001000000310000008f06110029000000566f74654f66285265666572656e64756d496e6465782c20543a3a4163636f756e744964290000002f0000000000000001000000360000005005110058000000a805110053000000fb05110057000000520611003d00000050726f78790000002f000000000000000100000036000000e20411004c0000002e0511002200000044656c65676174696f6e7328543a3a4163636f756e7449642c20436f6e76696374696f6e290000002f0000000000000001000000a500000092041100500000004c6173745461626c656457617345787465726e616c0000003204110056000000880411000a0000004e65787445787465726e616c28543a3a50726f706f73616c2c20566f74655468726573686f6c64292f0000000000000001000000a600000044031100560000009a03110055000000ef03110029000000180411001a000000426c61636b6c69737428543a3a426c6f636b4e756d6265722c205665633c543a3a4163636f756e7449643e292f00000000000000010000003c000000b6021100540000000a0311003a00000043616e63656c6c6174696f6e730000002f0000000000000001000000360000006c0211004a000000205265636f7264206f6620616c6c2070726f706f73616c7320746861742068617665206265656e207375626a65637420746f20656d657267656e63792063616e63656c6c6174696f6e2e2041207265636f7264206f662077686f207665746f656420776861742e204d6170732070726f706f73616c206861736820746f206120706f737369626c65206578697374656e7420626c6f636b206e756d6265722028756e74696c207768656e206974206d6179206e6f742062652072657375626d69747465642920616e642077686f207665746f65642069742e20546865207265666572656e64756d20746f206265207461626c6564207768656e6576657220697420776f756c642062652076616c696420746f207461626c6520616e2065787465726e616c2070726f706f73616c2e20546869732068617070656e73207768656e2061207265666572656e64756d206e6565647320746f206265207461626c656420616e64206f6e65206f662074776f20636f6e646974696f6e7320617265206d65743a202d20604c6173745461626c656457617345787465726e616c60206973206066616c7365603b206f72202d20605075626c696350726f70736020697320656d7074792e205472756520696620746865206c617374207265666572656e64756d207461626c656420776173207375626d69747465642065787465726e616c6c792e2046616c7365206966206974207761732061207075626c69632070726f706f73616c2e2047657420746865206163636f756e742028616e64206c6f636b20706572696f64732920746f20776869636820616e6f74686572206163636f756e742069732064656c65676174696e6720766f74652e2057686f2069732061626c6520746f20766f746520666f722077686f6d2e2056616c7565206973207468652066756e642d686f6c64696e67206163636f756e742c206b65792069732074686520766f74652d7472616e73616374696f6e2d73656e64696e67206163636f756e742e204765742074686520766f746520696e206120676976656e207265666572656e64756d206f66206120706172746963756c617220766f7465722e2054686520726573756c74206973206d65616e696e6766756c206f6e6c792069662060766f746572735f666f726020696e636c756465732074686520766f746572207768656e2063616c6c6564207769746820746865207265666572656e64756d2028796f75276c6c20676574207468652064656661756c742060566f7465602076616c7565206f7468657277697365292e20496620796f7520646f6e27742077616e7420746f20636865636b2060766f746572735f666f72602c207468656e20796f752063616e20616c736f20636865636b20666f722073696d706c65206578697374656e636520776974682060566f74654f663a3a657869737473602066697273742e204765742074686520766f7465727320666f72207468652063757272656e742070726f706f73616c2e205175657565206f66207375636365737366756c207265666572656e646120746f20626520646973706174636865642e20496e666f726d6174696f6e20636f6e6365726e696e6720616e7920676976656e207265666572656e64756d2e20546865206e657874207265666572656e64756d20696e64657820746861742073686f756c642062652074616c6c6965642e20546865206e6578742066726565207265666572656e64756d20696e6465782c20616b6120746865206e756d626572206f66207265666572656e6461207374617274656420736f206661722e2054686f73652077686f2068617665206c6f636b65642061206465706f7369742e20546865207075626c69632070726f706f73616c732e20556e736f727465642e20546865206e756d626572206f6620287075626c6963292070726f706f73616c7320746861742068617665206265656e206d61646520736f206661722e00000000000000640911000f000000000000001bf610000e00000000000000408111003c0a11000000000000000000740911000500000000000000000000009c0911000c000000000000001bf610000e0000000000000040811100bc0911000000000000000000a8091100010000000000000000000000b00911000c000000000000001bf610000e0000000000000040811100bc0911000000000000000000cc091100010000000000000000000000d40911000e000000000000001d3311000c0000000000000040811100e40911000000000000000000f4091100010000000000000000000000fc09110015000000000000001bf610000e0000000000000040811100140a11000000000000000000240a11000100000000000000000000002c0a11000d000000000000001bf610000e00000000000000408111003c0a110000000000000000004c0a11000100000000000000456e6163746d656e74506572696f64009b0b11005c000000386b110000000000f70b11004c000000430c11005a0000009d0c1100270000004c61756e6368506572696f64620b110039000000566f74696e67506572696f642f0000000000000001000000a7000000340b11002e0000004d696e696d756d4465706f73697400002f0000000000000001000000a8000000e70a11004d000000456d657267656e6379566f74696e67506572696f640000002f0000000000000001000000a9000000ac0a11003b000000436f6f6c6f6666506572696f640000002f0000000000000001000000aa000000540a11005800000020506572696f6420696e20626c6f636b7320776865726520616e2065787465726e616c2070726f706f73616c206d6179206e6f742062652072652d7375626d6974746564206166746572206265696e67207665746f65642e204d696e696d756d20766f74696e6720706572696f6420616c6c6f77656420666f7220616e20656d657267656e6379207265666572656e64756d2e20546865206d696e696d756d20616d6f756e7420746f20626520757365642061732061206465706f73697420666f722061207075626c6963207265666572656e64756d2070726f706f73616c2e20486f77206f6674656e2028696e20626c6f636b732920746f20636865636b20666f72206e657720766f7465732e20486f77206f6674656e2028696e20626c6f636b7329206e6577207075626c6963207265666572656e646120617265206c61756e636865642e20546865206d696e696d756d20706572696f64206f66206c6f636b696e6720616e642074686520706572696f64206265747765656e20612070726f706f73616c206265696e6720617070726f76656420616e6420656e61637465642e2049742073686f756c642067656e6572616c6c792062652061206c6974746c65206d6f7265207468616e2074686520756e7374616b6520706572696f6420746f20656e73757265207468617420766f74696e67207374616b657273206861766520616e206f70706f7274756e69747920746f2072656d6f7665207468656d73656c7665732066726f6d207468652073797374656d20696e207468652063617365207768657265207468657920617265206f6e20746865206c6f73696e672073696465206f66206120766f74652e0a68110028000000dc0c1100440000004b010000010000002f686f6d652f616e6472652f576f726b62656e63682f706172697479746563682f7375627374726174652f73726d6c2f64656d6f63726163792f7372632f6c69622e7273dc0c1100440000004b0100000100000076616c756520746f6f206c6f7770726f706f73657227732062616c616e636520746f6f206c6f7763616e206f6e6c79207365636f6e6420616e206578697374696e672070726f706f73616c7365636f6e64657227732062616c616e636520746f6f206c6f776e6f7420612070726f787944656d6f63726163792043616e63656c6c6174696f6e7370726f706f73616c207374696c6c20626c61636b6c697374656470726f706f73616c20616c7265616479206d616465696e76616c696420686173686e6578742065787465726e616c2070726f706f73616c206e6f742073696d706c65206d616a6f726974796e6f2070726f706f73616c206d61646544656d6f637261637920426c61636b6c6973746e6f2065787465726e616c2070726f706f73616c756e6b6e6f776e2070726f706f73616c6964656e74697479206d6179206e6f74207665746f20612070726f706f73616c20747769636544656d6f63726163792050726f7879616c726561647920612070726f787977726f6e672070726f78796e6f742064656c656761746564756e6b6e6f776e20696e64657863616e6e6f742063616e63656c207468652073616d652070726f706f73616c20747769636570726f706f73616c206e6f7420666f756e64766f746520676976656e20666f7220696e76616c6964207265666572656e64756d2e00000000000000ac0f11000600000000000000b40f1100010000000000000000000000bc0f1100010000000000000000000000c40f11000e00000000000000d40f1100020000000000000000000000e40f1100020000000000000000000000f40f11000c000000000000000010110002000000000000000000000010101100010000000000000052657761726400006a1011000700000009111100380000004f66666c696e655761726e696e670000611011000900000006111100030000007110110052000000c3101100430000004f66666c696e65536c61736861101100090000006a101100070000001810110049000000204f6e652076616c696461746f722028616e6420697473206e6f6d696e61746f72732920686173206265656e20736c61736865642062792074686520676976656e20616d6f756e742e4163636f756e74496442616c616e6365204f6e652076616c696461746f722028616e6420697473206e6f6d696e61746f72732920686173206265656e20676976656e20616e206f66666c696e652d7761726e696e6720286974206973207374696c6c2077697468696e20697473206772616365292e205468652061636372756564206e756d626572206f6620736c6173686573206973207265636f726465642c20746f6f2e75333220416c6c2076616c696461746f72732068617665206265656e2072657761726465642062792074686520676976656e2062616c616e63652e5374616b696e6720426f6e6465645374616b696e672043757272656e7445726153746172745374616b696e67204e6f6d696e61746f72735374616b696e672056616c696461746f72735374616b696e67205374616b6572735374616b696e67204c65646765725374616b696e672050617965655374616b696e6720536c617368436f756e7468656164206f66205374616b696e67204e6f6d696e61746f72734c696e6b616765206973207570646174656420696e206361736520656e7472792069732072656d6f7665643b20697420616c7761797320706f696e747320746f206578697374696e67206b6579733b2071656468656164206f66205374616b696e672056616c696461746f7273000000000000008c141100040000000000000090141100030000000000000000000000d81411000f0000000000000000000000501511000a000000000000005c151100010000000000000000000000741511000e0000000000000000000000e41511000600000000000000ec15110001000000000000000000000004161100170000000000000000000000bc1611001100000000000000386b1100000000000000000000000000d016110010000000000000000000000050171100080000000000000058171100010000000000000000000000701711000b0000000000000000000000c81711000800000000000000d0171100010000000000000000000000e81711000b0000000000000000000000401811000500000000000000386b1100000000000000000000000000481811000b0000000000000000000000a01811000900000000000000ac181100010000000000000000000000c41811000b00000000000000000000001c1911000e000000000000002c191100010000000000000000000000441911000b00000000000000000000009c1911001300000000000000b0191100010000000000000000000000c8191100010000000000000000000000d01911000d00000000000000386b1100000000000000000000000000e0191100080000000000000000000000201a11001700000000000000b0191100010000000000000000000000381a1100010000000000000000000000401a11001100000000000000541a11000100000000000000000000006c1a11000100000000000000626f6e6400000000a61d11000a00000000000000b01d11002300000000000000ee2511000500000000000000f32511001500000000000000281e110005000000000000002d1e11001100000044271100590000009d27110021000000386b110000000000be27110054000000386b1100000000001228110049000000386b1100000000007e1b11000b0000005b281100350000002e27110008000000902811001a000000386b110000000000aa2811005b00000005291100490000001f1c11000c000000626f6e645f6578747261000000000000362711000e00000000000000f3251100150000000826110059000000612611000d000000386b1100000000006e26110054000000c2261100590000001b27110013000000386b110000000000bf1c110055000000386b1100000000007e1b11000b000000141d11003a0000002e27110008000000d4251100100000001f1c11000c000000756e626f6e64000000000000ee2511000500000000000000f325110015000000ff211100550000005422110040000000942211004d000000386b110000000000e1221100520000003323110030000000386b110000000000632311004f000000b22311004f000000012411003f000000386b110000000000d31d110055000000386b1100000000004024110026000000386b1100000000007e1b11000b00000066241100500000004e1d110026000000b6241100590000000f2511005c0000006b25110069000000d425110010000000e42511000a00000077697468647261775f756e626f6e646564000000f81f11004b000000386b110000000000432011004d0000009020110013000000386b110000000000d31d110055000000386b110000000000a32011001b000000386b1100000000007e1b11000b000000be201100550000001321110051000000642111003d000000a12111005e000000741d1100320000001f1c11000c00000076616c696461746500000000d71f11000500000000000000dc1f11001c0000009d1f11003a000000386b110000000000881c110037000000386b110000000000d31d110055000000386b1100000000007e1b11000b000000141d11003a0000004e1d110026000000741d1100320000001f1c11000c0000006e6f6d696e617465000000006e1f11000700000000000000751f110028000000851e110044000000386b110000000000881c110037000000386b110000000000d31d110055000000386b1100000000007e1b11000b000000c91e110049000000121f110026000000381f1100360000001f1c11000c0000006368696c6c0000003e1e110032000000386b110000000000881c110037000000386b110000000000d31d110055000000386b1100000000007e1b11000b000000141d11003a000000701e110015000000741d1100320000001f1c11000c0000007365745f706179656500000000000000281e110005000000000000002d1e1100110000005a1c11002e000000386b110000000000881c110037000000386b110000000000d31d110055000000386b1100000000007e1b11000b000000141d11003a0000004e1d110026000000741d1100320000001f1c11000c0000007365745f636f6e74726f6c6c6572000000000000a61d11000a00000000000000b01d1100230000005a1c11002e000000386b110000000000881c110037000000386b110000000000bf1c110055000000386b1100000000007e1b11000b000000141d11003a0000004e1d110026000000741d1100320000001f1c11000c0000007365745f76616c696461746f725f636f756e7400000000004b1c110003000000000000004e1c11000c0000002b1c110020000000666f7263655f6e65775f657261000000e61a11004f000000351b110049000000386b1100000000007e1b11000b000000891b110020000000a91b110045000000ee1b1100310000001f1c11000c0000007365745f6f66666c696e655f736c6173685f677261636500c21a1100240000007365745f696e76756c6e657261626c657300000000000000a71a11000a00000000000000b11a110011000000741a11003300000020536574207468652076616c696461746f72732077686f2063616e6e6f7420626520736c61736865642028696620616e79292e76616c696461746f72735665633c543a3a4163636f756e7449643e2053657420746865206f66666c696e6520736c61736820677261636520706572696f642e20466f72636520746865726520746f2062652061206e6577206572612e205468697320616c736f20666f726365732061206e65772073657373696f6e20696d6d6564696174656c792061667465722e20606170706c795f72657761726473602073686f756c64206265207472756520666f722076616c696461746f727320746f20676574207468652073657373696f6e207265776172642e2023203c7765696768743e202d20496e646570656e64656e74206f662074686520617267756d656e74732e202d205472696767657273207468652050687261676d656e20656c656374696f6e2e20457870656e7369766520627574206e6f7420757365722d636f6e74726f6c6c65642e202d20446570656e6473206f6e2073746174653a20604f287c65646765737c202a207c76616c696461746f72737c29602e2023203c2f7765696768743e2054686520696465616c206e756d626572206f662076616c696461746f72732e6e6577436f6d706163743c7533323e202852652d2973657420746865207061796d656e742074617267657420666f72206120636f6e74726f6c6c65722e20456666656374732077696c6c2062652066656c742061742074686520626567696e6e696e67206f6620746865206e657874206572612e20546865206469737061746368206f726967696e20666f7220746869732063616c6c206d757374206265205f5369676e65645f206279207468652073746173682c206e6f742074686520636f6e74726f6c6c65722e202d20496e646570656e64656e74206f662074686520617267756d656e74732e20496e7369676e69666963616e7420636f6d706c65786974792e202d20436f6e7461696e732061206c696d69746564206e756d626572206f662072656164732e202d2057726974657320617265206c696d6974656420746f2074686520606f726967696e60206163636f756e74206b65792e636f6e74726f6c6c65723c543a3a4c6f6f6b7570206173205374617469634c6f6f6b75703e3a3a536f7572636520546865206469737061746368206f726967696e20666f7220746869732063616c6c206d757374206265205f5369676e65645f2062792074686520636f6e74726f6c6c65722c206e6f74207468652073746173682e706179656552657761726444657374696e6174696f6e204465636c617265206e6f2064657369726520746f206569746865722076616c6964617465206f72206e6f6d696e6174652e202d20436f6e7461696e73206f6e6520726561642e204465636c617265207468652064657369726520746f206e6f6d696e6174652060746172676574736020666f7220746865206f726967696e20636f6e74726f6c6c65722e202d20546865207472616e73616374696f6e277320636f6d706c65786974792069732070726f706f7274696f6e616c20746f207468652073697a65206f66206074617267657473602c2077686963682069732063617070656420617420604d41585f4e4f4d494e4154494f4e53602e202d20426f74682074686520726561647320616e642077726974657320666f6c6c6f7720612073696d696c6172207061747465726e2e746172676574735665633c3c543a3a4c6f6f6b7570206173205374617469634c6f6f6b75703e3a3a536f757263653e204465636c617265207468652064657369726520746f2076616c696461746520666f7220746865206f726967696e20636f6e74726f6c6c65722e707265667356616c696461746f7250726566733c42616c616e63654f663c543e3e2052656d6f766520616e7920756e6c6f636b6564206368756e6b732066726f6d207468652060756e6c6f636b696e67602071756575652066726f6d206f7572206d616e6167656d656e742e205468697320657373656e7469616c6c7920667265657320757020746861742062616c616e636520746f206265207573656420627920746865207374617368206163636f756e7420746f20646f2077686174657665722069742077616e74732e2053656520616c736f205b6043616c6c3a3a756e626f6e64605d2e202d20436f756c6420626520646570656e64656e74206f6e2074686520606f726967696e6020617267756d656e7420616e6420686f77206d7563682060756e6c6f636b696e6760206368756e6b732065786973742e2020497420696d706c6965732060636f6e736f6c69646174655f756e6c6f636b656460207768696368206c6f6f7073206f76657220604c65646765722e756e6c6f636b696e67602c2077686963682069732020696e6469726563746c7920757365722d636f6e74726f6c6c65642e20536565205b60756e626f6e64605d20666f72206d6f72652064657461696c2e202d20436f6e7461696e732061206c696d69746564206e756d626572206f662072656164732c20796574207468652073697a65206f6620776869636820636f756c64206265206c61726765206261736564206f6e20606c6564676572602e205363686564756c65206120706f7274696f6e206f662074686520737461736820746f20626520756e6c6f636b656420726561647920666f72207472616e73666572206f75742061667465722074686520626f6e6420706572696f6420656e64732e2049662074686973206c656176657320616e20616d6f756e74206163746976656c7920626f6e646564206c657373207468616e20543a3a43757272656e63793a3a6578697374656e7469616c5f6465706f73697428292c207468656e20697420697320696e6372656173656420746f207468652066756c6c20616d6f756e742e204f6e63652074686520756e6c6f636b20706572696f6420697320646f6e652c20796f752063616e2063616c6c206077697468647261775f756e626f6e6465646020746f2061637475616c6c79206d6f7665207468652066756e6473206f7574206f66206d616e6167656d656e7420726561647920666f72207472616e736665722e204e6f206d6f7265207468616e2061206c696d69746564206e756d626572206f6620756e6c6f636b696e67206368756e6b73202873656520604d41585f554e4c4f434b494e475f4348554e4b5360292063616e20636f2d657869737473206174207468652073616d652074696d652e20496e207468617420636173652c205b6043616c6c3a3a77697468647261775f756e626f6e646564605d206e65656420746f2062652063616c6c656420666972737420746f2072656d6f766520736f6d65206f6620746865206368756e6b732028696620706f737369626c65292e2053656520616c736f205b6043616c6c3a3a77697468647261775f756e626f6e646564605d2e202d20496e646570656e64656e74206f662074686520617267756d656e74732e204c696d697465642062757420706f74656e7469616c6c79206578706c6f697461626c6520636f6d706c65786974792e202d20456163682063616c6c20287265717569726573207468652072656d61696e646572206f662074686520626f6e6465642062616c616e636520746f2062652061626f766520606d696e696d756d5f62616c616e6365602920202077696c6c2063617573652061206e657720656e74727920746f20626520696e73657274656420696e746f206120766563746f722028604c65646765722e756e6c6f636b696e676029206b65707420696e2073746f726167652e202020546865206f6e6c792077617920746f20636c65616e207468652061666f72656d656e74696f6e65642073746f72616765206974656d20697320616c736f20757365722d636f6e74726f6c6c656420766961206077697468647261775f756e626f6e646564602e202d204f6e6520444220656e7472792e203c2f7765696768743e76616c7565436f6d706163743c42616c616e63654f663c543e3e2041646420736f6d6520657874726120616d6f756e742074686174206861766520617070656172656420696e207468652073746173682060667265655f62616c616e63656020696e746f207468652062616c616e636520757020666f72207374616b696e672e20557365207468697320696620746865726520617265206164646974696f6e616c2066756e647320696e20796f7572207374617368206163636f756e74207468617420796f75207769736820746f20626f6e642e20556e6c696b65205b60626f6e64605d206f72205b60756e626f6e64605d20746869732066756e6374696f6e20646f6573206e6f7420696d706f736520616e79206c696d69746174696f6e206f6e2074686520616d6f756e7420746861742063616e2062652061646465642e202d204f2831292e6d61785f6164646974696f6e616c2054616b6520746865206f726967696e206163636f756e74206173206120737461736820616e64206c6f636b207570206076616c756560206f66206974732062616c616e63652e2060636f6e74726f6c6c6572602077696c6c20626520746865206163636f756e74207468617420636f6e74726f6c732069742e206076616c756560206d757374206265206d6f7265207468616e2074686520606578697374656e7469616c5f6465706f7369746020646566696e656420696e207468652042616c616e636573206d6f64756c652e20546865206469737061746368206f726967696e20666f7220746869732063616c6c206d757374206265205f5369676e65645f20627920746865207374617368206163636f756e742e202d20496e646570656e64656e74206f662074686520617267756d656e74732e204d6f64657261746520636f6d706c65786974792e202d20546872656520657874726120444220656e74726965732e204e4f54453a2054776f206f66207468652073746f726167652077726974657320286053656c663a3a626f6e646564602c206053656c663a3a7061796565602920617265205f6e657665725f20636c65616e656420756e6c6573732074686520606f726967696e602066616c6c732062656c6f77205f6578697374656e7469616c206465706f7369745f20616e6420676574732072656d6f76656420617320647573742e5374616b696e6700000000000000903011000e000000000000000000000006111100030000000000000000000000000000000000000000000000000000000000000040811100603311000000000000000000a030110001000000000000000100000000000000a830110015000000000000000000000006111100030000000000000000000000000000000000000000000000000000000000000040811100c03011000000000000000000d030110001000000000000000100000000000000f40f11000c0000000000000000000000d8301100070000000000000000000000000000000000000000000000000000000000000040811100e03011000000000000000000f030110001000000000000000100000000000000f8301100110000000000000000000000061111000300000000000000000000000000000000000000000000000000000000000000408111006033110000000000000000000c31110001000000000000000100000000000000143111000d0000000000000000000000b11a110011000000000000000000000000000000000000000000000000000000000000004081110018341100000000000000000024311100030000000000000001000000000000003c311100060000000101000000000000423111000c00000000000000423111000c0000000000000000000000000000000000000040811100883111000000000000000000503111000100000000000000000000000000000058311100060000000101000000000000423111000c000000000000005e3111002900000000000000000000000000000000000000408111008831110000000000000000009831110001000000000000000000000000000000a0311100050000000101000000000000423111000c000000000000002d1e1100110000000000000000000000000000000000000040811100a83111000000000000000000b831110001000000000000000100000000000000c03111000a0000000101010000000000423111000c00000000000000dc1f11001c0000000000000000000000000000000000000040811100cc3111000000000000000000dc31110001000000000000000100000000000000e43111000a0000000101010000000000423111000c00000000000000b11a1100110000000000000000000000000000000000000040811100183411000000000000000000f031110001000000000000000100000000000000f8311100070000000101000000000000423111000c00000000000000ff3111002400000000000000000000000000000000000000408111002432110000000000000000003432110004000000000000000100000000000000543211000e0000000000000000000000b11a110011000000000000000000000000000000000000000000000000000000000000004081110018341100000000000000000064321100010000000000000001000000000000006c3211000a0000000000000000000000763211000800000000000000000000000000000000000000000000000000000000000000408111006033110000000000000000008032110001000000000000000100000000000000883211000f0000000000000000000000973211000b0000000000000000000000000000000000000000000000000000000000000040811100a43211000000000000000000b432110001000000000000000100000000000000bc3211001b0000000000000000000000136511000c0000000000000000000000000000000000000000000000000000000000000040811100603311000000000000000000d832110001000000000000000100000000000000e0321100110000000000000000000000f13211000a0000000000000000000000000000000000000000000000000000000000000040811100fc32110000000000000000000c33110001000000000000000100000000000000143311000900000000000000000000001d3311000c00000000000000000000000000000000000000000000000000000000000000408111002c33110000000000000000003c33110003000000000000000100000000000000543311000a0000000101000000000000423111000c00000000000000061111000300000000000000000000000000000000000000408111006033110000000000000000007033110002000000000000000100000000000000803311000f00000000000000000000008f331100280000000000000000000000000000000000000000000000000000000000000040811100183411000000000000000000b833110002000000000000000100000000000000c83311000b0000000000000000000000d3331100040000000000000000000000000000000000000000000000000000000000000040811100d83311000000000000000000e833110001000000000000000100000000000000f03311000a0000000000000000000000fa3311001d00000000000000000000000000000000000000000000000000000000000000408111001834110000000000000000002834110001000000000000000100000056616c696461746f72436f756e7400000e3b11002a0000004d696e696d756d56616c696461746f72436f756e740000002f0000000000000001000000ab000000be3a11005000000050657262696c6c002f0000000000000001000000ac0000006a3a1100540000004f66666c696e65536c61736847726163650000001c3a11004e000000496e76756c6e657261626c657300000048391100560000009e39110053000000f13911002b000000426f6e646564543a3a4163636f756e744964000008391100400000004c65646765725374616b696e674c65646765723c543a3a4163636f756e7449642c2042616c616e63654f663c543e3e002f000000000000000100000036000000b73811005100000050617965650000002f0000000000000001000000360000007e3811003900000056616c696461746f727300002f0000000000000001000000ad0000002d381100510000004e6f6d696e61746f72730000d4371100590000005374616b6572734578706f737572653c543a3a4163636f756e7449642c2042616c616e63654f663c543e3e002f0000000000000001000000ae00000017371100530000006a37110046000000386b110000000000b03711002400000043757272656e74456c65637465640000d83611003f00000043757272656e74457261457261496e6465780000c13611001700000043757272656e7445726153746172744d6f6d656e744f663c543e00002f000000000000000100000035000000a33611001e00000043757272656e74457261537461727453657373696f6e496e646578006f3611003400000043757272656e744572615265776172647345726152657761726473002f0000000000000001000000af0000002c36110043000000536c6f745374616b6542616c616e63654f663c543e0000002f000000000000000100000030000000b03511004c000000386b110000000000fc35110030000000536c617368436f756e7400002f0000000000000001000000410000003c35110057000000933511001d000000526563656e746c794f66666c696e655665633c28543a3a4163636f756e7449642c20543a3a426c6f636b4e756d6265722c20753332293e00c0341100550000001535110027000000466f7263654e6577457261626f6f6c002f0000000000000001000000360000007934110047000000426f6e646564457261735665633c28457261496e6465782c2053657373696f6e496e646578293e002f00000000000000010000003100000030341100490000002041206d617070696e672066726f6d207374696c6c2d626f6e646564206572617320746f207468652066697273742073657373696f6e20696e646578206f662074686174206572612e205472756520696620746865206e6578742073657373696f6e206368616e67652077696c6c2062652061206e657720657261207265676172646c657373206f6620696e6465782e204d6f737420726563656e742060524543454e545f4f46464c494e455f434f554e546020696e7374616e6365732e202857686f206974207761732c207768656e20697420776173207265706f727465642c20686f77206d616e7920696e7374616e63657320746865792077657265206f66666c696e6520666f72292e20546865206e756d626572206f662074696d6573206120676976656e2076616c696461746f7220686173206265656e207265706f72746564206f66666c696e652e205468697320676574732064656372656d656e746564206279206f6e652065616368206572612074686174207061737365732e2054686520616d6f756e74206f662062616c616e6365206163746976656c79206174207374616b6520666f7220656163682076616c696461746f7220736c6f742c2063757272656e746c792e2054686973206973207573656420746f20646572697665207265776172647320616e642070756e6973686d656e74732e205265776172647320666f72207468652063757272656e74206572612e205573696e6720696e6469636573206f662063757272656e7420656c6563746564207365742e205468652073657373696f6e20696e646578206174207768696368207468652063757272656e742065726120737461727465642e20546865207374617274206f66207468652063757272656e74206572612e205468652063757272656e742065726120696e6465782e205468652063757272656e746c7920656c65637465642076616c696461746f7220736574206b65796564206279207374617368206163636f756e742049442e204e6f6d696e61746f727320666f72206120706172746963756c6172206163636f756e74207468617420697320696e20616374696f6e207269676874206e6f772e20596f752063616e27742069746572617465207468726f7567682076616c696461746f727320686572652c2062757420796f752063616e2066696e64207468656d20696e207468652053657373696f6e206d6f64756c652e2054686973206973206b6579656420627920746865207374617368206163636f756e742e20546865206d61702066726f6d206e6f6d696e61746f72207374617368206b657920746f2074686520736574206f66207374617368206b657973206f6620616c6c2076616c696461746f727320746f206e6f6d696e6174652e20546865206d61702066726f6d202877616e6e616265292076616c696461746f72207374617368206b657920746f2074686520707265666572656e636573206f6620746861742076616c696461746f722e2057686572652074686520726577617264207061796d656e742073686f756c64206265206d6164652e204b657965642062792073746173682e204d61702066726f6d20616c6c2028756e6c6f636b6564292022636f6e74726f6c6c657222206163636f756e747320746f2074686520696e666f20726567617264696e6720746865207374616b696e672e204d61702066726f6d20616c6c206c6f636b65642022737461736822206163636f756e747320746f2074686520636f6e74726f6c6c6572206163636f756e742e20416e792076616c696461746f72732074686174206d6179206e6576657220626520736c6173686564206f7220666f726369626c79206b69636b65642e20497427732061205665632073696e63652074686579277265206561737920746f20696e697469616c697a6520616e642074686520706572666f726d616e636520686974206973206d696e696d616c2028776520657870656374206e6f206d6f7265207468616e20666f757220696e76756c6e657261626c65732920616e64207265737472696374656420746f20746573746e6574732e204e756d626572206f6620696e7374616e636573206f66206f66666c696e65207265706f727473206265666f726520736c617368696e6720626567696e7320666f722076616c696461746f72732e20536c6173682c207065722076616c696461746f7220746861742069732074616b656e20666f72207468652066697273742074696d6520746865792061726520666f756e6420746f206265206f66666c696e652e204d696e696d756d206e756d626572206f66207374616b696e67207061727469636970616e7473206265666f726520656d657267656e637920636f6e646974696f6e732061726520696d706f7365642e2054686520696465616c206e756d626572206f66207374616b696e67207061727469636970616e74732e00000000a83b11000e00000000000000136511000c0000000000000040811100b83b11000000000000000000c83b1100010000000000000000000000d03b11000f0000000000000076321100080000000000000040811100e03b11000000000000000000f03b1100010000000000000053657373696f6e7350657245726100002f000000000000000100000037000000313c11001c000000426f6e64696e674475726174696f6e002f0000000000000001000000b0000000f83b110039000000204e756d626572206f6620657261732074686174207374616b65642066756e6473206d7573742072656d61696e20626f6e64656420666f722e204e756d626572206f662073657373696f6e7320706572206572612e5374616b696e672043757272656e74456c656374656400803c110048000000880a00000e0000000000000000000000000000002f72757374632f633739386466666163396463386338323337346462343866356234373436393063633665393638362f7372632f6c6962636f72652f736c6963652f6d6f642e72735374616b696e6720536c6f745374616b65000000003e110019000000203e110048000000bb0100002d000000b10000002800000004000000b2000000b30000000000000000000000b40000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000617474656d707420746f20646976696465206279207a65726f000000000000002f72757374632f633739386466666163396463386338323337346462343866356234373436393063633665393638362f7372632f6c6962636f72652f6f70732f61726974682e72730a68110028000000803e1100420000009f020000010000002f686f6d652f616e6472652f576f726b62656e63682f706172697479746563682f7375627374726174652f73726d6c2f7374616b696e672f7372632f6c69622e727300009040110023000000664011002a000000803e1100420000009f02000001000000636f6e74726f6c6c657220616c72656164792070616972656463616e206e6f7420626f6e6420776974682076616c7565206c657373207468616e206d696e696d756d2062616c616e6365737461736820616c726561647920626f6e6465646e6f74206120636f6e74726f6c6c65726e6f74206120737461736863616e206e6f74207363686564756c65206d6f726520756e6c6f636b206368756e6b73756e7374616b65207468726573686f6c6420746f6f206c617267650a09090909090909096865616420697320736574207768656e20666972737420656c656d656e7420697320696e73657274656420616e6420756e736574207768656e206c61737420656c656d656e742069732072656d6f7665643b0a09090909090909096966206865616420697320536f6d65207468656e20697420706f696e747320746f206578697374696e67206b65793b207165640a09090909090909746172676574732063616e6e6f7420626520656d7074795374616b696e6720496e76756c6e657261626c6573696e7465726e616c206572726f723a20656e746572656420756e726561636861626c6520636f64653a205f5f5068616e746f6d4974656d2073686f756c64206e6576657220626520757365642e007041110048000000ab010000230000007041110048000000ac01000023000000494111001c000000646c110018000000df0300000d0000000041110049000000870200001d000000000000002f72757374632f633739386466666163396463386338323337346462343866356234373436393063633665393638362f7372632f6c6962636f72652f736c6963652f736f72742e7273617373657274696f6e206661696c65643a206d6964203c3d206c656e00000000000000000000002f72757374632f633739386466666163396463386338323337346462343866356234373436393063633665393638362f7372632f6c6962636f72652f736c6963652f6d6f642e727300411100490000009d0000003a0000000041110049000000a4000000300000004f6666636861696e206572726f723a207375626d697474696e67207472616e73616374696f6e206661696c6564214f6666636861696e206572726f723a206465636f64696e6720417574686f726974794964206661696c6564214f6666636861696e206572726f723a206465636f64696e6720576f726b6572537461747573206661696c6564214f6666636861696e206572726f723a2065787472696e736963206372656174696f6e206661696c6564214f6666636861696e206572726f723a207369676e696e67206661696c6564214f6666636861696e206572726f723a206665746368696e67206e6574776f726b207374617465206661696c656421496d4f6e6c696e65204c6173744e6577457261537461727454726561737572792050726f706f73616c436f756e74547265617375727920417070726f76616c73000000000000010000000200000004000000080000001000000044656d6f6372616379205075626c696350726f70436f756e7444656d6f6372616379205265666572656e64756d436f756e7444656d6f6372616379204e65787454616c6c7944656d6f6372616379204c6173745461626c656457617345787465726e616c746f6f206d616e7920696e737472756374696f6e73000000c44311002400000059691100170000004102000009000000547269656420746f20736872696e6b20746f2061206c6172676572206361706163697479436f6e7472616374204761735370656e74436f6e74726163742043757272656e745363686564756c65436f6e7472616374204163636f756e74436f756e7465726578745f7365745f73746f726167656578745f6765745f73746f726167656578745f63616c6c6578745f6372656174656578745f72657475726e6578745f63616c6c65726578745f616464726573736578745f6761735f70726963656578745f6761735f6c6566746578745f62616c616e63656578745f76616c75655f7472616e736665727265646578745f72616e646f6d6578745f6e6f776578745f64697370617463685f63616c6c6578745f736372617463685f73697a656578745f736372617463685f636f70796578745f6465706f7369745f6576656e746578745f7365745f72656e745f616c6c6f77616e63656578745f72656e745f616c6c6f77616e63656578745f7072696e746c6e6578745f626c6f636b5f6e756d6265724e6f6e2d656d7074792066756e6374696f6e20626f64792065787065637465640000264611000f000000354611000200000037461100030000009845110030000000c84511005e0000007d00000005000000617373657274696f6e206661696c65643a20636f6e746578742e6672616d655f737461636b2e69735f656d70747928292f686f6d652f616e6472652f2e636172676f2f72656769737472792f7372632f6769746875622e636f6d2d316563633632393964623965633832332f7761736d692d76616c69646174696f6e2d302e312e302f7372632f66756e632e7273417420696e737472756374696f6e202840293a2052657475726e207479706573206c656e6774682073686f756c642062652030206f72203143616e2774206465636f6465207761736d20636f64654d6f64756c65206973206e6f742076616c69646d6f64756c65206465636c6172657320696e7465726e616c206d656d6f72796d756c7469706c65207461626c6573206465636c617265647461626c652065786365656473206d6178696d756d2073697a6520616c6c6f776564757365206f6620666c6f6174696e6720706f696e74207479706520696e2066756e6374696f6e20747970657320697320666f7262696464656e757365206f6620666c6f6174696e6720706f696e74207479706520696e206c6f63616c7320697320666f7262696464656e757365206f6620666c6f6174696e6720706f696e74207479706520696e20676c6f62616c7320697320666f7262696464656e67617320696e737472756d656e746174696f6e206661696c6564737461636b2068656967687420696e737472756d656e746174696f6e206661696c656463616c6c6465706c6f796465706c6f792066756e6374696f6e2069736e2774206578706f72746564756e6b6e6f776e206578706f72743a20657870656374696e67206f6e6c79206465706c6f7920616e642063616c6c2066756e6374696f6e7366756e6374696f6e206861732061206e6f6e2d6578697374656e7420747970656578706f72742072656665727320746f206e6f6e2d6578697374656e742066756e6374696f6e657870656374656420612066756e6374696f6e656e74727920706f696e7420706f696e747320746f20616e20696d706f727465642066756e6374696f6e656e74727920706f696e74206861732077726f6e67207369676e617475726563616c6c2066756e6374696f6e2069736e2774206578706f727465646572726f722073657269616c697a696e6720696e737472756d656e746564206d6f64756c65b44a11001e000000d24a11001f00000066756e6374696f6e5f73656374696f6e5f6c656e20213d20303b2071656466756e6374696f6e5f73656374696f6e5f6c656e20213d20303b2066756e6374696f6e5f73656374696f6e5f6c656e203d3d20636f64655f73656374696f6e5f6c656e3b2071656400009a4a11001a000000754a11000a0000007f4a11001b00000073746172742066756e6374696f6e20657870656374656420746f20686176652074797065205b5d202d3e205b5d000000644a110011000000444a110020000000244a110020000000fc491100280000007365676d656e74206f66667365742073686f756c642072657475726e20493332746f6f206d616e79206d656d6f727920726567696f6e7320696e20696e6465782073706163653a20746f6f206d616e79207461626c657320696e20696e6465782073706163653a20747279696e6720746f20696d706f7274206d757461626c6520676c6f62616c206475706c6963617465206578706f72742046756e6374696f6e20232072656164696e672f76616c69646174696f6e206572726f723a204d697373696e6720626f647920666f722066756e6374696f6e206c656e677468206f662066756e6374696f6e2073656374696f6e206973202c207768696c65206c656e206f6620636f64652073656374696f6e20697320000000104b11001c0000002c4b11005a0000004d00000028000000ffffffff48617368207461626c65206361706163697479206f766572666c6f772f686f6d652f616e6472652f2e636172676f2f72656769737472792f7372632f6769746875622e636f6d2d316563633632393964623965633832332f6861736862726f776e2d302e312e382f7372632f7261772f6d6f642e72736d616b655f746f705f6672616d655f706f6c796d6f72706869632069732063616c6c6564207769746820656d707479206672616d6520737461636b000000b50000000c00000004000000b6000000746869732066756e6374696f6e2063616e27742062652063616c6c6564207769746820656d707479206672616d6520737461636b4d6973706c6163656420656c736520696e737472756374696f6e00004c4d110047000000934d110005000000104d110037000000474d110005000000dd4c110017000000d44c110009000000264f110014000000bc4c110018000000d44c110009000000264f1100140000008c4c11001d000000a94c1100130000003781110001000000546f6f206c61726765206d656d6f727920616c69676e6d656e7420325e20286578706563746564206174206d6f737420547279696e6720746f2075706461746520676c6f62616c20206f66207479706520547279696e6720746f20757064617465206c6f63616c20416e79537065636966696300380000000400000004000000b70000004c6162656c7320696e2062725f7461626c6520706f696e747320746f20626c6f636b206f6620646966666572656e742074797065733a2020616e6420496620626c6f636b20776974686f757420656c736520726571756972656420746f2068617665204e6f526573756c7420626c6f636b20747970652e2042757420697420686173202074797065a84d110018000000c04d11000b000000556e657870656374656420737461636b20686569676874202c20657870656374656420547279696e6720746f2061636365737320706172656e74206672616d6520737461636b2076616c7565732e0000084e1100170000001f4e11001600000045787065637465642076616c7565206f66207479706520206f6e20746f70206f6620737461636b2e20476f7420000000404e110007000000537461636b3a200000000100ca4e110024000000a04e110006000000a64e11000e000000b44e1100160000007c4e110024000000a04e1100060000006d6178696d756d206d656d6f72792073697a65206d757374206265206174206d6f7374202070616765736d6178696d756d206c696d697420206973206c657373207468616e206d696e696d756d20696e697469616c206d656d6f72792073697a65206d757374206265206174206d6f7374200000004f110026000000264f110014000000547279696e6720746f20696e697469616c697a65207661726961626c65206f6620747970652020776974682076616c7565206f66207479706520496e69742065787072657373696f6e2073686f756c6420616c776179732062652077697468206c656e67746820324e6f6e20636f6e7374616e74206f70636f646520696e20696e69742065787072d14f110007000000e34f110022000000d14f110007000000d84f11000b00000045787072657373696f6e20646f65736e277420656e647320776974682060656e6460206f70636f6465476c6f62616c20206973206d757461626c6520646f65736e277420657869737473206f72206e6f742079657420646566696e65640000001850110010000000285011000f0000004d656d6f727920617420696e6465782020646f65736e27742065786973747300485011000f000000285011000f0000005461626c6520617420696e6465782000f957110012000000285011000f000000785011000e000000285011000f0000005479706520617420696e646578200000e650110010000000285011000f000000b850110010000000d85011000e000000b850110010000000c850110010000000457870656374656420676c6f62616c2020746f20626520696d6d757461626c6520746f206265206d757461626c65476c6f62616c20617420696e646578206e6f6e2d656d70747920737461636b206578706563746564000020511100200000004051110012000000747279696e6720746f206765742076616c756520617420706f736974696f6e20206f6e20737461636b206f662073697a6520636865636b656420636f75706c65206f66206c696e65732061626f7665007851110015000000657863656564656420737461636b206c696d697420000000380000000400000004000000b80000004c6f63616c732072616e6765206e6f7420696e2033322d6269742072616e6765d851110022000000fa511100150000000f52110007000000547279696e6720746f20616363657373206c6f63616c207769746820696e64657820207768656e20746865726520617265206f6e6c7920206c6f63616c734672616d6569735f706f6c796d6f7270686963000000380000000400000004000000b9000000656e645f61726974790000003800000004000000040000001d0000006272616e63685f617269747973746172745f6865696768744e6f2066756e6374696f6e2073656374696f6e4e6f20636f64652073656374696f6e4e6f20747970652073656374696f6e000000945511000a00000046756e6374696f6e206973206e6f7420666f756e6420696e2066756e632073656374696f6e46756e6374696f6e20626f647920666f722074686520696e6465782069736e277420666f756e64885511000c000000f05411000b000000737461636b206d757374206265206e6f6e2d656d70747900e55411000b0000009e54110006000000737461636b206f766572666c6f774172697479206f6620616c6c206a756d702d74617267657473206d75737420626520657175616c54797065206e6f7420666f756e64009754110007000000905311006c000000c800000011000000000000002f686f6d652f616e6472652f2e636172676f2f72656769737472792f7372632f6769746875622e636f6d2d316563633632393964623965633832332f707761736d2d7574696c732d302e362e322f7372632f737461636b5f6865696768742f6d61785f6865696768742e72736d61785f686569676874707761736d5f7574696c733a3a737461636b5f6865696768743a3a6d61785f6865696768742f686f6d652f616e6472652f2e636172676f2f72656769737472792f7372632f6769746875622e636f6d2d316563633632393964623965633832332f707761736d2d7574696c732d302e362e322f7372632f737461636b5f6865696768742f6d61785f6865696768742e72737472756e633a20707573683a20e054110005000000747279696e6720746f20706f70206d6f72652076616c756573207468616e20707573686564737461636b20756e646572666c6f77706f703a20756e726561636861626c65706f705f6672616d653a20636f6e74726f6c20737461636b20697320656d707479636f6e74726f6c20737461636b206f75742d6f662d626f756e64734055110048000000820a00000a000000000000002f72757374632f633739386466666163396463386338323337346462343866356234373436393063633665393638362f7372632f6c6962636f72652f736c6963652f6d6f642e7273707573685f6672616d653a2066756e635f6964783a2066756e635f737461636b5f636f7374732069736e27742079657420636f6d70757465643b0a0909090944696420796f752063616c6c2060636f6d707574655f737461636b5f636f737473603f546869732073686f756c64206265206120696e646578206f66206120646566696e65642066756e6374696f6e44756520746f2076616c69646174696f6e20636f64652073656374696f6e2073686f756c642065786973747346756e6374696f6e20626f6479206973206f7574206f6620626f756e6473a0561100650000002301000017000000785611002500000043616c6c20746f2066756e6374696f6e2074686174206f75742d6f662d626f756e64733a200000002f686f6d652f616e6472652f2e636172676f2f72656769737472792f7372632f6769746875622e636f6d2d316563633632393964623965633832332f707761736d2d7574696c732d302e362e322f7372632f737461636b5f6865696768742f6d6f642e727366756e6374696f6e20696d706f727420636f756e74206973206e6f74207a65726f3b20696d706f72742073656374696f6e206d757374206578697374733b2071656466756e635f696478206973206c657373207468616e2066756e6374696f6e20696d706f72747320636f756e743b0a090909096e74682066756e6374696f6e20696d706f7274206d7573742062652060536f6d65603b0a09090909716564f9571100120000000b5811000f000000cc5711000a000000d657110014000000ea5711000f0000005369676e61747572652020287370656369666965642062792066756e6320292069736e277420646566696e656446756e6374696f6e20617420696e64657820206973206e6f7420646566696e6564656e76676173305811005800000088000000160000002f686f6d652f616e6472652f2e636172676f2f72656769737472792f7372632f6769746875622e636f6d2d316563633632393964623965633832332f707761736d2d7574696c732d302e362e322f7372632f6761732e72737372632f6c6962616c6c6f632f7665632e727300b45811001c0000008858110013000000c604000009000000617373657274696f6e206661696c65643a20656e64203c3d206c656ee85811001e0000008858110013000000b303000009000000617373657274696f6e206661696c65643a20696e646578203c3d206c656e4e6f6e65536f6d650000380000000400000004000000ba000000e559110012000000f75911000c0000006066756e635f696478602073686f756c6420636f6d652066726f6d20606e6565645f7468756e6b73603b0a09090909606e6565645f7468756e6b736020697320706f70756c617465642077697468207468652073616d65206974656d73207468617420696e20607265706c6163656d656e745f6d6170603b0a090909097165644174207468697320706f696e7420616e20696e646578206d7573742062652061737369676e656420746f2065616368207468756e6b66756e6374696f6e207769746820696478202069736e277420666f756e644636345265696e74657270726574493634556e726561636861626c654e6f70426c6f636b00380000000400000004000000bb0000004c6f6f704966456c7365456e644272003800000004000000040000001d0000004272496642725461626c6500380000000400000004000000bc00000052657475726e43616c6c43616c6c496e6469726563740000380000000400000004000000bd00000044726f7053656c6563744765744c6f63616c5365744c6f63616c5465654c6f63616c476574476c6f62616c536574476c6f62616c4933324c6f61644936344c6f61644633324c6f61644636344c6f61644933324c6f616438534933324c6f616438554933324c6f61643136534933324c6f61643136554936344c6f616438534936344c6f616438554936344c6f61643136534936344c6f61643136554936344c6f61643332534936344c6f616433325549333253746f726549363453746f726546333253746f726546363453746f726549333253746f72653849333253746f7265313649363453746f72653849363453746f7265313649363453746f7265333243757272656e744d656d6f727947726f774d656d6f7279493332436f6e737400380000000400000004000000be000000493634436f6e7374380000000400000004000000bf000000463332436f6e7374463634436f6e73743800000004000000040000000400000049333245717a49333245714933324e654933324c74534933324c74554933324774534933324774554933324c65534933324c655549333247655349333247655549363445717a49363445714936344e654936344c74534936344c74554936344774534936344774554936344c65534936344c655549363447655349363447655546333245714633324e654633324c7446333247744633324c65463332476546363445714636344e654636344c7446363447744636344c654636344765493332436c7a49333243747a493332506f70636e744933324164644933325375624933324d756c493332446976534933324469765549333252656d5349333252656d55493332416e644933324f72493332586f7249333253686c4933325368725349333253687255493332526f746c493332526f7472493634436c7a49363443747a493634506f70636e744936344164644936345375624936344d756c493634446976534936344469765549363452656d5349363452656d55493634416e644936344f72493634586f7249363453686c4936345368725349363453687255493634526f746c493634526f74724633324162734633324e65674633324365696c463332466c6f6f724633325472756e634633324e656172657374463332537172744633324164644633325375624633324d756c4633324469764633324d696e4633324d6178463332436f70797369676e4636344162734636344e65674636344365696c463634466c6f6f724636345472756e634636344e656172657374463634537172744636344164644636345375624636344d756c4636344469764636344d696e4636344d6178463634436f70797369676e493332577261704936344933325472756e63534633324933325472756e63554633324933325472756e63534636344933325472756e6355463634493634457874656e6453493332493634457874656e64554933324936345472756e63534633324936345472756e63554633324936345472756e63534636344936345472756e6355463634463332436f6e7665727453493332463332436f6e7665727455493332463332436f6e7665727453493634463332436f6e766572745549363446333244656d6f7465463634463634436f6e7665727453493332463634436f6e7665727455493332463634436f6e7665727453493634463634436f6e766572745549363446363450726f6d6f74654633324933325265696e746572707265744633324936345265696e746572707265744636344633325265696e746572707265744933324e6f526573756c7456616c756500380000000400000004000000b7000000463634493332493634463332496e76616c696444617461547261696c696e6744617461556e6578706563746564456f66086011000b000000492f4f204572726f723a20000a681100280000002c6011005000000087000000090000002f686f6d652f616e6472652f576f726b62656e63682f706172697479746563682f7375627374726174652f636f72652f73722d73616e64626f782f7372632f2e2e2f776974686f75745f7374642e72730a681100280000002c601100500000009000000009000000436f756e63696c20446573697265645365617473436f756e63696c20566f7465436f756e74436f756e63696c204e657874566f746572536574436f756e63696c20566f746572436f756e74436f756e63696c2043616e646964617465436f756e74000000000000007c6111000e000000000000008c611100010000000000000000000000946111000100000000000000000000009c6111000600000000000000386b1100000000000000000000000000a4611100010000000000000000000000ac6111000700000000000000386b1100000000000000000000000000b461110001000000000000004e6577417574686f72697469657300002f621100170000000b621100240000005061757365640000e461110027000000526573756d656400bc611100280000002043757272656e7420617574686f726974792073657420686173206265656e20726573756d65642e2043757272656e7420617574686f726974792073657420686173206265656e207061757365642e204e657720617574686f726974792073657420686173206265656e206170706c6965642e5665633c28417574686f7269747949642c20753634293e4772616e64706146696e616c69747920417574686f72697469657354696d657374616d7020496e697469616c697a656462616265736c6f74436f756c64206e6f74206465636f64652072657175657374656420696e686572656e742074797065214241424520696e686572656e742064617461206e6f7420666f756e64426162652045706f6368496e6465784261626520417574686f726974696573426162652045706f63685374617274536c6f74426162652043757272656e74536c6f74426162652052616e646f6d6e65737342616265204e65787452616e646f6d6e6573734261626520556e646572436f6e737472756374696f6e5374616b696e672056616c696461746f72436f756e745374616b696e67204d696e696d756d56616c696461746f72436f756e745374616b696e67204f66666c696e65536c61736847726163655374616b696e672043757272656e744572615374616b696e672043757272656e74457261537461727453657373696f6e496e6465785374616b696e672043757272656e74457261526577617264735374616b696e6720466f7263654e65774572615374616b696e6720426f6e64656445726173417574686f727368697020446964536574556e636c657353657373696f6e2043757272656e74496e64657853657373696f6e204368616e67656453657373696f6e205175657565644368616e6765640000000000786411000a00000000000000846411000100000000000000000000008c64110002000000000000004e657753657373696f6e0000136511000c0000009c64110055000000f164110022000000204e65772073657373696f6e206861732068617070656e65642e204e6f746520746861742074686520617267756d656e74206973207468652073657373696f6e20696e6465782c206e6f742074686520626c6f636b206e756d626572206173207468652074797065206d6967687420737567676573742e53657373696f6e496e64657853657373696f6e2053746f72656452616e676500002f0000000000000001000000c0000000c1000000c20000002f0000000000000001000000c0000000c1000000c200000074696d737461703054696d657374616d7020696e686572656e742064617461206973206e6f742070726f76696465642e496e76616c69642074696d657374616d7020696e686572656e74206461746120656e636f64696e672e54696d657374616d702044696455706461746500000000286611001000000000000000386b110000000000000000000000000038661100010000000000000000000000406611000f00000000000000386b110000000000000000000000000050661100010000000000000045787472696e736963537563636573736d6611002500000045787472696e7369634661696c656400586611001500000020416e2065787472696e736963206661696c65642e20416e2065787472696e73696320636f6d706c65746564207375636365737366756c6c792e53797374656d2045787472696e736963436f756e7453797374656d20416c6c45787472696e7369637357656967687453797374656d20416c6c45787472696e736963734c656e53797374656d204e6578745765696768744d756c7469706c69657253797374656d2045787472696e7369634461746153797374656d204576656e74436f756e7448617368206e6f7420657175616c0000406711001900000060671100500000005800000022000000617474656d707420746f20646976696465206279207a65726f000000000000002f686f6d652f616e6472652f576f726b62656e63682f706172697479746563682f7375627374726174652f636f72652f73722d7072696d6974697665732f7372632f67656e657269632f6572612e72736578745f6368696c645f73746f726167655f726f6f74206e657665722072657475726e73207533323a3a6d61785f76616c75653b2071656452756e74696d65206d656d6f7279206578686175737465642e2041626f7274696e67696e7465726e616c206572726f723a20656e746572656420756e726561636861626c6520636f64652f686f6d652f616e6472652f2e636172676f2f72656769737472792f7372632f6769746875622e636f6d2d316563633632393964623965633832332f7061726974792d636f6465632d342e312e332f7372632f636f6465632e7273000000a86811002d000000d56811000c000000e168110003000000617373657274696f6e206661696c65643a2060286c656674203d3d20726967687429600a20206c6566743a2060602c0a2072696768743a2060603a20ec6811003400000064657374696e6174696f6e20616e6420736f7572636520736c69636573206861766520646966666572656e74206c656e67746873646c110018000000470800000900000048691100110000005969110017000000ed020000050000006361706163697479206f766572666c6f777372632f6c6962616c6c6f632f7261775f7665632e7273e0691100460000006301000013000000380000000400000004000000c3000000c4000000c50000006120666f726d617474696e6720747261697420696d706c656d656e746174696f6e2072657475726e656420616e206572726f72002f0000000000000001000000c6000000000000002f72757374632f633739386466666163396463386338323337346462343866356234373436393063633665393638362f7372632f6c6962636f72652f666d742f6d6f642e7273010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002020202020202020202020202020202020202020202020202020202020203030303030303030303030303030303040404040400000000000000000000000000486b110020000000686b1100120000002f0000000000000001000000c7000000696e646578206f7574206f6620626f756e64733a20746865206c656e20697320206275742074686520696e64657820697320303030313032303330343035303630373038303931303131313231333134313531363137313831393230323132323233323432353236323732383239333033313332333333343335333633373338333934303431343234333434343534363437343834393530353135323533353435353536353735383539363036313632363336343635363636373638363937303731373237333734373537363737373837393830383138323833383438353836383738383839393039313932393339343935393639373938393900007c6c110006000000826c110022000000646c110018000000040a0000050000007372632f6c6962636f72652f736c6963652f6d6f642e7273696e64657820206f7574206f662072616e676520666f7220736c696365206f66206c656e67746820c46c110016000000da6c11000d000000646c1100180000000a0a000005000000736c69636520696e64657820737461727473206174202062757420656e6473206174206030785b2e2e2e5d00ae6d11000b0000006280110016000000e76c110001000000986d110016000000e307000009000000408011000e0000004e801100040000005280110010000000e76c110001000000986d110016000000e707000005000000008011002b0000002b801100150000007a01000015000000ae6d11000b000000b96d110026000000df6d110008000000e76d110006000000e76c110001000000986d110016000000f4070000050000007372632f6c6962636f72652f7374722f6d6f642e72736279746520696e64657820206973206e6f742061206368617220626f756e646172793b20697420697320696e7369646520202862797465732029206f662060000000366e110002000000206e1100160000005404000011000000206e110016000000480400002800000000000000000000007372632f6c6962636f72652f666d742f6d6f642e72732e2e000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ffffffffffffffffffffffffffff00000000000000000000000000000000000000000000000000000000000000000000f8030000000000000000000000000000000000000000000000000000000000000000feffffffffbfb6000000000000000000ff070000000000f8ffff0000010000000000000000000000c09f9f3d0000000002000000ffffff0700000000000000000000c0ff01000000000000f80f20e07911004a000000307c110000020000307e11003a00000000010203040506070809080a0b0c0d0e0f10111213140215161718191a1b1c1d1e1f2002020202020202020202210202020202020202020202020202222324252602270228020202292a2b022c2d2e2f300202310202023202020202020202023302023402020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202023502360237020202020202020238023902020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202023a3b3c020202023d02023e3f4041424344454602020247020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202024802020202020202020202024902020202023b020001020202020302020202040205060202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020207020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020200010305050606030706080809110a1c0b190c140d120e0d0f0410031212130916011705180219031a071c021d011f1620032b042c022d0b2e01300331023201a702a902aa04ab08fa02fb05fd04fe03ff09ad78798b8da23057588b8c901c1ddd0e0f4b4cfbfc2e2f3f5c5d5fb5e2848d8e9192a9b1babbc5c6c9cadee4e5ff00041112293134373a3b3d494a5d848e92a9b1b4babbc6cacecfe4e500040d0e11122931343a3b4546494a5e646584919b9dc9cecf0d112945495764658d91a9b4babbc5c9dfe4e5f0040d1145496465808184b2bcbebfd5d7f0f183858ba4a6bebfc5c7cecfdadb4898bdcdc6cecf494e4f57595e5f898e8fb1b6b7bfc1c6c7d71116175b5cf6f7feff800d6d71dedf0e0f1f6e6f1c1d5f7d7eaeafbbbcfa16171e1f46474e4f585a5c5e7e7fb5c5d4d5dcf0f1f572738f747596972f5f262e2fa7afb7bfc7cfd7df9a409798308f1fc0c1ceff4e4f5a5b07080f10272feeef6e6f373d3f42459091feff536775c8c9d0d1d8d9e7feff00205f2282df048244081b04061181ac0e80ab351e1580e003190801042f043404070301070607110a500f1207550802041c0a090308030703020303030c0405030b06010e15053a0311070605100757070207150d500443032d03010411060f0c3a041d255f206d046a2580c80582b0031a0682fd035907150b1709140c140c6a060a061a0659072b05460a2c040c040103310b2c041a060b0380ac060a061f414c042d0374083c030f033c0738082b0582ff1118082f112d032010210f808c048297190b158894052f053b07020e180980b030740c80d61a0c0580ff0580b605240c9bc60ad23010848d033709815c1480b80880c73035040a06380846080c06740b1e035a0459098083181c0a16094808808a06aba40c170431a10481da26070c050580a511816d1078282a064c04808d0480be031b030f0d0006010103010402080809020a050b02100111041205131114021502170219041c051d0824016a036b02bc02d102d40cd509d602d702da01e005e102e802ee20f004f906fa020c273b3e4e4f8f9e9e9f060709363d3e56f3d0d104141836375657bd35cecfe01287898e9e040d0e11122931343a4546494a4e4f64655a5cb6b71b1ca8a9d8d909379091a8070a3b3e66698f926f5feeef5a629a9b2728559da0a1a3a4a7a8adbabcc4060b0c151d3a3f4551a6a7cccda007191a22253e3fc5c604202325262833383a484a4c50535556585a5c5e606365666b73787d7f8aa4aaafb0c0d00c72a3a4cbcc6e6f5e227b0503042d036504012f2e80821d03310f1c0424091e052b0544040e2a80aa06240424042808340b018090813709160a088098390363080930160521031b05014038044b052f040a070907402027040c0936033a051a07040c07504937330d33072e080a81261f808128082a808617094e041e0f430e19070a0647092709750b3f412a063b050a0651060105100305808b602048080a80a65e22450b0a060d1339070a362c041080c03c64530c0180a0451b4808531d398107460a1d03474937030e080a0639070a81361980c7320d839b66750b80c48abc842f8fd18247a1b98239072a040260260a460a28051382b05b654b0439071140041c97f80882f3a50d811f3103110408818c89046b050d03090710936080f60a73086e1746809a140c570919808781470385420f1585502b80d52d031a040281703a0501850080d7294c040a04028311444c3d80c23c06010455051b3402810e2c04640c560a0d035d033d391d0d2c040907020e06809a83d60a0d030b05740c59070c140c0438080a0628081e527703310380a60c14040305030d06856a000000c0791100200000002700000019000000c0791100200000002800000020000000c0791100200000002a00000019000000c0791100200000002b00000018000000c0791100200000002c0000002000000000000000000000007372632f6c6962636f72652f756e69636f64652f626f6f6c5f747269652e72730000c0fbef3e00000000000e0000000000000000000000000000f8fffbffffff0700000000000014fe21fe000c00000002000000000000501e2080000c00004006000000000000108639020000002300be2100000c0000fc02000000000000d01e20c0000c0000000400000000000040012080000000000011000000000000c0c13d60000c0000000200000000000090443060000c00000003000000000000581e2080000c00000000845c8000000000000000000000f207807f000000000000000000000000f21f003f000000000000000000030000a002000000000000fe7fdfe0fffeffffff1f40000000000000000000000000e0fd66000000c301001e006420002000000000000000e00000000000001c0000001c0000000c0000000c00000000000000b03f40fe0f200000000000380000000000006000000000020000000000008701040e00008009000000000000407fe51ff89f000000000000ff7f0f0000000000f0170400000000f80f00030000003c3b00000000000040a303000000000000f0cf000000f7fffd211003fffffffffffffffb00100000000000000000ffffffff01000000000000800300000000000000008000000000ffffffff0000000000fc00000000000600000000000000000080f73f000000c0000000000000000000000300440800006000000030000000ffff038000000000c03f000080ff030000000000070000000000c833000000002000000000000000007e660008100000000000100000000000009dc1020000000030400000000000202100000000004000000000ffff0000ffff00000000000000000001000000020003000000000000000000000000000000000000000000000000000004000005000000000000000006000000000000000007000008090a000b0c0d0e0f000010111200001314151600001718191a1b001c0000001d0000000000001e1f202100000000002200230024252600000000270000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002829000000000000000000000000000000002a2b0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002c0000000000000000000000000000000000002d2e00002f0000000000000000000000000000000000000000000000000000000000003031320000000000000000000000000000000000000000003300000029000000000000340000000000000000000000000000000000000000000000350036000000000000000000000000000000000000000000000000000037380000383838390000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000200000000001000000000000000000c0076ef0000000000087000000006000000000000000f0000000c0ff01000000000002000000000000ff7f0000000000008003000000000078060700000080ef1f000000000000000800030000000000c07f001e000000000000000000000080d34000000080f8070000030000000000005801008000c01f1f0000000000000000ff5c00004000000000000000000000f9a50d000000000000000000000000803cb00100003000000000000000000000f8a70100000000000000000000000028bf00000000e0bc0f0000000000000080ff060000f00c01000000fe0700000000f87980007e0e0000000000fc7f03000000000000000000007fbf0000fcfffffc6d000000000000007eb4bf000000000000000000a3000000000000000000000018000000000000001f000000000000007f0000800000000000000080070000000000000000600000000000000000a0c307f8e70f0000003c00001c00000000000000ffffffffffff7ff8ffffffffff1f2000100000f8feff00007ffffff9db0700000000000000f0000000007f0000000000f00700000000000000000000ffffffffffffffffffffffffffffffffffff000063616c6c656420604f7074696f6e3a3a756e77726170282960206f6e206120604e6f6e65602076616c75657372632f6c6962636f72652f6f7074696f6e2e7273626567696e203c3d20656e642028203c3d2029207768656e20736c6963696e672060206973206f7574206f6620626f756e6473206f66206066616c736574727565426f72726f774572726f72426f72726f774d75744572726f720000386b1100000000002b801100150000008e04000005000000386b110000000000c4801100020000003a200000d8801100150000003c040000050000007372632f6c6962636f72652f726573756c742e727320202020207b202c20207b0a000000c80000000c00000004000000c9000000ca000000cb0000002c0a0000380000000400000004000000cc000000cd000000ce000000207d7d28280a2c290a5d5b4572726f720041c082c6000b08000000000000000000d79003046e616d6501ce9003d704000e6578745f626c616b65325f323536011f6578745f6765745f616c6c6f63617465645f6368696c645f73746f7261676502176578745f636c6561725f6368696c645f73746f72616765030f6578745f7365745f73746f72616765040c6578745f74776f785f31323805196578745f6765745f616c6c6f63617465645f73746f7261676506166578745f73616e64626f785f6d656d6f72795f6e6577071b6578745f73616e64626f785f6d656d6f72795f74656172646f776e08176578745f73616e64626f785f696e7374616e746961746509126578745f73616e64626f785f696e766f6b650a1d6578745f73616e64626f785f696e7374616e63655f74656172646f776e0b146578745f6765745f73746f726167655f696e746f0c116578745f636c6561725f73746f726167650d166578745f6b696c6c5f6368696c645f73746f726167650e106578745f636c6561725f7072656669780f166578745f6368696c645f73746f726167655f726f6f74100e6578745f7072696e745f7574663811156578745f7365745f6368696c645f73746f7261676512166578745f73616e64626f785f6d656d6f72795f67657413166578745f73616e64626f785f6d656d6f72795f73657414126578745f737232353531395f76657269667915126578745f656432353531395f766572696679160d6578745f7072696e745f68657817156578745f6c6f63616c5f73746f726167655f67657418216578745f6c6f63616c5f73746f726167655f636f6d706172655f616e645f736574190a6578745f7075626b65791a116578745f6e6574776f726b5f73746174651b086578745f7369676e1c166578745f7375626d69745f7472616e73616374696f6e1d156578745f6c6f63616c5f73746f726167655f7365741e106578745f73746f726167655f726f6f741f186578745f73746f726167655f6368616e6765735f726f6f74200b6578745f74776f785f363421236578745f626c616b65325f3235365f656e756d6572617465645f747269655f726f6f74220d6578745f7072696e745f6e756d230a6578745f6d616c6c6f6324086578745f6672656525693c636f72653a3a697465723a3a61646170746572733a3a46696c7465724d61703c492c463e20617320636f72653a3a697465723a3a7472616974733a3a6974657261746f723a3a4974657261746f723e3a3a6e6578743a3a686135376361333065383863303365303426693c616c6c6f633a3a7665633a3a5665633c543e20617320616c6c6f633a3a7665633a3a53706563457874656e643c542c616c6c6f633a3a7665633a3a496e746f497465723c543e3e3e3a3a737065635f657874656e643a3a6833373139666330653134623738636436270c5f5f727573745f616c6c6f63280e5f5f727573745f7265616c6c6f63290e5f5f727573745f6465616c6c6f632a08727573745f6f6f6d2b34616c6c6f633a3a7261775f7665633a3a63617061636974795f6f766572666c6f773a3a68336430333339633338393539363364642c693c616c6c6f633a3a7665633a3a5665633c543e20617320616c6c6f633a3a7665633a3a53706563457874656e643c542c616c6c6f633a3a7665633a3a496e746f497465723c543e3e3e3a3a737065635f657874656e643a3a68666465363930626535643534353335662d4e3c616c6c6f633a3a7665633a3a5665633c543e206173207061726974795f636f6465633a3a636f6465633a3a4465636f64653e3a3a6465636f64653a3a68313930363035356636656634383237362e5d3c7061726974795f636f6465633a3a636f6465633a3a436f6d706163743c7533323e206173207061726974795f636f6465633a3a636f6465633a3a4465636f64653e3a3a6465636f64653a3a68323435356333626435643931376463372f3d7061726974795f636f6465633a3a636f6465633a3a456e636f64653a3a7573696e675f656e636f6465643a3a683830383935343231326364636362353530633c7061726974795f636f6465633a3a636f6465633a3a436f6d706163745265663c7533323e206173207061726974795f636f6465633a3a636f6465633a3a456e636f64653e3a3a656e636f64655f746f3a3a6861653539633130346438353133613637313d7061726974795f636f6465633a3a636f6465633a3a456e636f64653a3a7573696e675f656e636f6465643a3a6861326361663333656666326237333732327c6e6f64655f72756e74696d653a3a5f494d504c5f454e434f44455f464f525f43616c6c3a3a3c696d706c207061726974795f636f6465633a3a636f6465633a3a456e636f646520666f72206e6f64655f72756e74696d653a3a43616c6c3e3a3a656e636f64655f746f3a3a6835633263313064386662343437643537333d7061726974795f636f6465633a3a636f6465633a3a456e636f64653a3a7573696e675f656e636f6465643a3a6861376564663762316162326163643437343d7061726974795f636f6465633a3a636f6465633a3a456e636f64653a3a7573696e675f656e636f6465643a3a6866613865343765633933663536666432353d7061726974795f636f6465633a3a636f6465633a3a456e636f64653a3a7573696e675f656e636f6465643a3a6866616630326139373163346561326261362d616c6c6f633a3a7665633a3a5665633c543e3a3a72657461696e3a3a68313264383737303031386466653032333736636f72653a3a70616e69636b696e673a3a70616e69635f626f756e64735f636865636b3a3a683863356337376530636566356239316638443c616c6c6f633a3a7665633a3a5665633c543e20617320636f72653a3a636c6f6e653a3a436c6f6e653e3a3a636c6f6e653a3a68343262303431353366346265353836383948616c6c6f633a3a7261775f7665633a3a5261775665633c542c413e3a3a616c6c6f636174655f696e3a3a7b7b636c6f737572657d7d3a3a68303161313636363462353235323061643a4b3c616c6c6f633a3a7665633a3a496e746f497465723c543e20617320636f72653a3a6f70733a3a64726f703a3a44726f703e3a3a64726f703a3a68663764316263323333653933356434373b4e3c616c6c6f633a3a7665633a3a5665633c543e206173207061726974795f636f6465633a3a636f6465633a3a4465636f64653e3a3a6465636f64653a3a68326461353465626366663537666563623c796e6f64655f72756e74696d653a3a5f494d504c5f4445434f44455f464f525f43616c6c3a3a3c696d706c207061726974795f636f6465633a3a636f6465633a3a4465636f646520666f72206e6f64655f72756e74696d653a3a43616c6c3e3a3a6465636f64653a3a68393636393230613235616638643962363d30636f72653a3a7074723a3a7265616c5f64726f705f696e5f706c6163653a3a68343861333664316238316265333563653e36636f72653a3a736c6963653a3a736c6963655f696e6465785f6f726465725f6661696c3a3a68356364313639613635616238353965393f4e3c616c6c6f633a3a7665633a3a5665633c543e206173207061726974795f636f6465633a3a636f6465633a3a4465636f64653e3a3a6465636f64653a3a6833363566626164393361653031316662404e3c616c6c6f633a3a7665633a3a5665633c543e206173207061726974795f636f6465633a3a636f6465633a3a4465636f64653e3a3a6465636f64653a3a6837316361626362323361376461623764414e3c616c6c6f633a3a7665633a3a5665633c543e206173207061726974795f636f6465633a3a636f6465633a3a4465636f64653e3a3a6465636f64653a3a6837366163313032323131663866333733424e3c616c6c6f633a3a7665633a3a5665633c543e206173207061726974795f636f6465633a3a636f6465633a3a4465636f64653e3a3a6465636f64653a3a6837366432313166353166623965376535434e3c616c6c6f633a3a7665633a3a5665633c543e206173207061726974795f636f6465633a3a636f6465633a3a4465636f64653e3a3a6465636f64653a3a6838356533343365643362656139623361444f3c616c6c6f633a3a7665633a3a5665633c75383e206173207061726974795f636f6465633a3a636f6465633a3a4465636f64653e3a3a6465636f64653a3a6839653666323565383838303562306638454e3c616c6c6f633a3a7665633a3a5665633c543e206173207061726974795f636f6465633a3a636f6465633a3a4465636f64653e3a3a6465636f64653a3a6838653162663830323038623436323862464e3c616c6c6f633a3a7665633a3a5665633c543e206173207061726974795f636f6465633a3a636f6465633a3a4465636f64653e3a3a6465636f64653a3a6861656661353936643166623837656439474e3c616c6c6f633a3a7665633a3a5665633c543e206173207061726974795f636f6465633a3a636f6465633a3a4465636f64653e3a3a6465636f64653a3a6862616338653862656565356632616538484e3c616c6c6f633a3a7665633a3a5665633c543e206173207061726974795f636f6465633a3a636f6465633a3a4465636f64653e3a3a6465636f64653a3a68663366396461396132336437353666354999013c73725f7072696d6974697665733a3a67656e657269633a3a756e636865636b65645f65787472696e7369633a3a556e636865636b656445787472696e7369633c416464726573732c43616c6c2c5369676e61747572652c45787472613e206173207061726974795f636f6465633a3a636f6465633a3a4465636f64653e3a3a6465636f64653a3a68383635343265656636313566636131354a513c616c6c6f633a3a7665633a3a5665633c543e20617320616c6c6f633a3a7665633a3a53706563457874656e643c542c493e3e3a3a66726f6d5f697465723a3a68356130336335333262653737623464394b513c616c6c6f633a3a7665633a3a5665633c543e20617320616c6c6f633a3a7665633a3a53706563457874656e643c542c493e3e3a3a66726f6d5f697465723a3a68383163363735636233376362643435384c513c616c6c6f633a3a7665633a3a5665633c543e20617320616c6c6f633a3a7665633a3a53706563457874656e643c542c493e3e3a3a66726f6d5f697465723a3a68636637353230666433393733623732394d3373726d6c5f7374616b696e673a3a4d6f64756c653c543e3a3a7374616b6572733a3a68613032373064313462303632633031664e2e636f72653a3a6f7074696f6e3a3a6578706563745f6661696c65643a3a68643935376630653162613762346162644f6c3c73725f7072696d6974697665733a3a67656e657269633a3a6469676573743a3a4469676573744974656d3c486173683e206173207061726974795f636f6465633a3a636f6465633a3a456e636f64653e3a3a656e636f64653a3a683530626630633838373135643038613150723c73726d6c5f696e64696365733a3a616464726573733a3a416464726573733c4163636f756e7449642c4163636f756e74496e6465783e206173207061726974795f636f6465633a3a636f6465633a3a4465636f64653e3a3a6465636f64653a3a683432346533633966643965353666383051753c73726d6c5f696e64696365733a3a616464726573733a3a416464726573733c4163636f756e7449642c4163636f756e74496e6465783e206173207061726974795f636f6465633a3a636f6465633a3a456e636f64653e3a3a656e636f64655f746f3a3a6836303438386636313863323464616261525d3c7061726974795f636f6465633a3a636f6465633a3a436f6d706163743c7536343e206173207061726974795f636f6465633a3a636f6465633a3a4465636f64653e3a3a6465636f64653a3a6830363032666566393830393762343861535e3c7061726974795f636f6465633a3a636f6465633a3a436f6d706163743c753132383e206173207061726974795f636f6465633a3a636f6465633a3a4465636f64653e3a3a6465636f64653a3a683366333530343539333033356663666354633c7061726974795f636f6465633a3a636f6465633a3a436f6d706163745265663c7536343e206173207061726974795f636f6465633a3a636f6465633a3a456e636f64653e3a3a656e636f64655f746f3a3a683038643361663639353837313639653555443c636f72653a3a666d743a3a417267756d656e747320617320636f72653a3a666d743a3a446973706c61793e3a3a666d743a3a686566323037386633376634356236613156303c265420617320636f72653a3a666d743a3a44656275673e3a3a666d743a3a6838306262653634343531326431353032572d636f72653a3a70616e69636b696e673a3a70616e69635f666d743a3a68626563663738613764313663316663655829636f72653a3a70616e69636b696e673a3a70616e69633a3a683861643532323536383465376335666159643c7061726974795f636f6465633a3a636f6465633a3a436f6d706163745265663c753132383e206173207061726974795f636f6465633a3a636f6465633a3a456e636f64653e3a3a656e636f64655f746f3a3a68646262326435373236386334653436375a303c265420617320636f72653a3a666d743a3a44656275673e3a3a666d743a3a68306663393031333831336461313064325b3d7061726974795f636f6465633a3a636f6465633a3a456e636f64653a3a7573696e675f656e636f6465643a3a68383831313733353133393938363536355c3d7061726974795f636f6465633a3a636f6465633a3a456e636f64653a3a7573696e675f656e636f6465643a3a68663565393639663138373231616135665d367061726974795f636f6465633a3a636f6465633a3a456e636f64653a3a656e636f64653a3a68633433653166343632633166303232365e4473726d6c5f737570706f72743a3a7472616974733a3a5369676e6564496d62616c616e63653c422c503e3a3a6d657267653a3a68393961636662653066623534346133385f4e73725f7072696d6974697665733a3a67656e657269633a3a6469676573743a3a4469676573743c486173683e3a3a636f6e766572745f66697273743a3a6864663130346139623139623564343238607a3c636f72653a3a697465723a3a61646170746572733a3a46696c7465724d61703c492c463e20617320636f72653a3a697465723a3a7472616974733a3a6974657261746f723a3a4974657261746f723e3a3a7472795f666f6c643a3a7b7b636c6f737572657d7d3a3a686464386166653364373833613466363561bc017375627374726174655f7072696d6974697665733a3a6f6666636861696e3a3a5f494d504c5f454e434f44455f464f525f4f70617175654e6574776f726b53746174653a3a3c696d706c207061726974795f636f6465633a3a636f6465633a3a456e636f646520666f72207375627374726174655f7072696d6974697665733a3a6f6666636861696e3a3a4f70617175654e6574776f726b53746174653e3a3a656e636f64655f746f3a3a683864653337646339656532636163646662593c73726d6c5f636f6e7472616374733a3a7761736d3a3a5761736d566d2061732073726d6c5f636f6e7472616374733a3a657865633a3a566d3c543e3e3a3a657865637574653a3a683765333337393936323566663435303863663c73726d6c5f636f6e7472616374733a3a7761736d3a3a5761736d566d2061732073726d6c5f636f6e7472616374733a3a657865633a3a566d3c543e3e3a3a657865637574653a3a7b7b636c6f737572657d7d3a3a6864363435393936323564393661643362647d3c73726d6c5f636f6e7472616374733a3a7761736d3a3a72756e74696d653a3a456e762061732073726d6c5f636f6e7472616374733a3a7761736d3a3a656e765f6465663a3a46756e6374696f6e496d706c50726f76696465723c453e3e3a3a696d706c733a3a6761733a3a68613365643138333131633165303431656589013c73726d6c5f636f6e7472616374733a3a7761736d3a3a72756e74696d653a3a456e762061732073726d6c5f636f6e7472616374733a3a7761736d3a3a656e765f6465663a3a46756e6374696f6e496d706c50726f76696465723c453e3e3a3a696d706c733a3a6578745f7365745f73746f726167653a3a68643532333765626565386262646162346689013c73726d6c5f636f6e7472616374733a3a7761736d3a3a72756e74696d653a3a456e762061732073726d6c5f636f6e7472616374733a3a7761736d3a3a656e765f6465663a3a46756e6374696f6e496d706c50726f76696465723c453e3e3a3a696d706c733a3a6578745f6765745f73746f726167653a3a68373830316462666232383639633365396782013c73726d6c5f636f6e7472616374733a3a7761736d3a3a72756e74696d653a3a456e762061732073726d6c5f636f6e7472616374733a3a7761736d3a3a656e765f6465663a3a46756e6374696f6e496d706c50726f76696465723c453e3e3a3a696d706c733a3a6578745f63616c6c3a3a68613836663537336437383362323836346884013c73726d6c5f636f6e7472616374733a3a7761736d3a3a72756e74696d653a3a456e762061732073726d6c5f636f6e7472616374733a3a7761736d3a3a656e765f6465663a3a46756e6374696f6e496d706c50726f76696465723c453e3e3a3a696d706c733a3a6578745f6372656174653a3a68326132393766353731373666386361326984013c73726d6c5f636f6e7472616374733a3a7761736d3a3a72756e74696d653a3a456e762061732073726d6c5f636f6e7472616374733a3a7761736d3a3a656e765f6465663a3a46756e6374696f6e496d706c50726f76696465723c453e3e3a3a696d706c733a3a6578745f72657475726e3a3a68356466383631343361653432386562366a84013c73726d6c5f636f6e7472616374733a3a7761736d3a3a72756e74696d653a3a456e762061732073726d6c5f636f6e7472616374733a3a7761736d3a3a656e765f6465663a3a46756e6374696f6e496d706c50726f76696465723c453e3e3a3a696d706c733a3a6578745f63616c6c65723a3a68386132303764613038646361303032386b85013c73726d6c5f636f6e7472616374733a3a7761736d3a3a72756e74696d653a3a456e762061732073726d6c5f636f6e7472616374733a3a7761736d3a3a656e765f6465663a3a46756e6374696f6e496d706c50726f76696465723c453e3e3a3a696d706c733a3a6578745f616464726573733a3a68393631313338353961323437343534396c87013c73726d6c5f636f6e7472616374733a3a7761736d3a3a72756e74696d653a3a456e762061732073726d6c5f636f6e7472616374733a3a7761736d3a3a656e765f6465663a3a46756e6374696f6e496d706c50726f76696465723c453e3e3a3a696d706c733a3a6578745f6761735f70726963653a3a68663338646437666630316265323433666d86013c73726d6c5f636f6e7472616374733a3a7761736d3a3a72756e74696d653a3a456e762061732073726d6c5f636f6e7472616374733a3a7761736d3a3a656e765f6465663a3a46756e6374696f6e496d706c50726f76696465723c453e3e3a3a696d706c733a3a6578745f6761735f6c6566743a3a68653238626430613136333234663737636e85013c73726d6c5f636f6e7472616374733a3a7761736d3a3a72756e74696d653a3a456e762061732073726d6c5f636f6e7472616374733a3a7761736d3a3a656e765f6465663a3a46756e6374696f6e496d706c50726f76696465723c453e3e3a3a696d706c733a3a6578745f62616c616e63653a3a68633235333030353435363561303231616f8f013c73726d6c5f636f6e7472616374733a3a7761736d3a3a72756e74696d653a3a456e762061732073726d6c5f636f6e7472616374733a3a7761736d3a3a656e765f6465663a3a46756e6374696f6e496d706c50726f76696465723c453e3e3a3a696d706c733a3a6578745f76616c75655f7472616e736665727265643a3a68373239396531613762306235393139397084013c73726d6c5f636f6e7472616374733a3a7761736d3a3a72756e74696d653a3a456e762061732073726d6c5f636f6e7472616374733a3a7761736d3a3a656e765f6465663a3a46756e6374696f6e496d706c50726f76696465723c453e3e3a3a696d706c733a3a6578745f72616e646f6d3a3a68386230343966393830626561396630347181013c73726d6c5f636f6e7472616374733a3a7761736d3a3a72756e74696d653a3a456e762061732073726d6c5f636f6e7472616374733a3a7761736d3a3a656e765f6465663a3a46756e6374696f6e496d706c50726f76696465723c453e3e3a3a696d706c733a3a6578745f6e6f773a3a6863356634376663366532666365326363728b013c73726d6c5f636f6e7472616374733a3a7761736d3a3a72756e74696d653a3a456e762061732073726d6c5f636f6e7472616374733a3a7761736d3a3a656e765f6465663a3a46756e6374696f6e496d706c50726f76696465723c453e3e3a3a696d706c733a3a6578745f64697370617463685f63616c6c3a3a6839366164373461323632303534303837738a013c73726d6c5f636f6e7472616374733a3a7761736d3a3a72756e74696d653a3a456e762061732073726d6c5f636f6e7472616374733a3a7761736d3a3a656e765f6465663a3a46756e6374696f6e496d706c50726f76696465723c453e3e3a3a696d706c733a3a6578745f736372617463685f73697a653a3a6864363536323266343863303236666239748a013c73726d6c5f636f6e7472616374733a3a7761736d3a3a72756e74696d653a3a456e762061732073726d6c5f636f6e7472616374733a3a7761736d3a3a656e765f6465663a3a46756e6374696f6e496d706c50726f76696465723c453e3e3a3a696d706c733a3a6578745f736372617463685f636f70793a3a6866623732393936366436646236353066758b013c73726d6c5f636f6e7472616374733a3a7761736d3a3a72756e74696d653a3a456e762061732073726d6c5f636f6e7472616374733a3a7761736d3a3a656e765f6465663a3a46756e6374696f6e496d706c50726f76696465723c453e3e3a3a696d706c733a3a6578745f6465706f7369745f6576656e743a3a68633864333539353230333061333532307690013c73726d6c5f636f6e7472616374733a3a7761736d3a3a72756e74696d653a3a456e762061732073726d6c5f636f6e7472616374733a3a7761736d3a3a656e765f6465663a3a46756e6374696f6e496d706c50726f76696465723c453e3e3a3a696d706c733a3a6578745f7365745f72656e745f616c6c6f77616e63653a3a6865346536313364303366316231626364778c013c73726d6c5f636f6e7472616374733a3a7761736d3a3a72756e74696d653a3a456e762061732073726d6c5f636f6e7472616374733a3a7761736d3a3a656e765f6465663a3a46756e6374696f6e496d706c50726f76696465723c453e3e3a3a696d706c733a3a6578745f72656e745f616c6c6f77616e63653a3a68353239636230386335303534313937367885013c73726d6c5f636f6e7472616374733a3a7761736d3a3a72756e74696d653a3a456e762061732073726d6c5f636f6e7472616374733a3a7761736d3a3a656e765f6465663a3a46756e6374696f6e496d706c50726f76696465723c453e3e3a3a696d706c733a3a6578745f7072696e746c6e3a3a6836623535393535386661346339653736798a013c73726d6c5f636f6e7472616374733a3a7761736d3a3a72756e74696d653a3a456e762061732073726d6c5f636f6e7472616374733a3a7761736d3a3a656e765f6465663a3a46756e6374696f6e496d706c50726f76696465723c453e3e3a3a696d706c733a3a6578745f626c6f636b5f6e756d6265723a3a68316365326162663363373165346338657a3273725f73616e64626f783a3a696d703a3a64697370617463685f7468756e6b3a3a68356134386464313632363132383634357b4573726d6c5f636f6e7472616374733a3a7761736d3a3a72756e74696d653a3a746f5f657865637574696f6e5f726573756c743a3a68366565343861623838353831666630307c135f5f727573745f616c6c6f635f7a65726f65647da7017375627374726174655f7072696d6974697665733a3a73616e64626f783a3a5f494d504c5f4445434f44455f464f525f547970656456616c75653a3a3c696d706c207061726974795f636f6465633a3a636f6465633a3a4465636f646520666f72207375627374726174655f7072696d6974697665733a3a73616e64626f783a3a547970656456616c75653e3a3a6465636f64653a3a68343530373665613734316439633232317e643c7061726974795f636f6465633a3a636f6465633a3a436f6d706163743c7533323e206173207061726974795f636f6465633a3a636f6465633a3a456e636f64653e3a3a7573696e675f656e636f6465643a3a68303930356635623465623032383638317f34636f72653a3a736c6963653a3a736c6963655f696e6465785f6c656e5f6661696c3a3a68666661376637663531656636613535368001303c265420617320636f72653a3a666d743a3a44656275673e3a3a666d743a3a68303333356131383037343065326233648101303c265420617320636f72653a3a666d743a3a44656275673e3a3a666d743a3a68613432353462303530376636356239388201313c73747220617320636f72653a3a666d743a3a44656275673e3a3a666d743a3a6834336239616334336136363337613934830189013c73726d6c5f62616c616e6365733a3a4d6f64756c653c542c493e2061732073726d6c5f737570706f72743a3a7472616974733a3a43757272656e63793c3c542061732073726d6c5f73797374656d3a3a54726169743e3a3a4163636f756e7449643e3e3a3a6465706f7369745f6372656174696e673a3a686433613133633364616236393537616384013573726d6c5f737570706f72743a3a73746f726167653a3a6861736865643a3a6765743a3a686261616264646563653365626462363885018d013c73726d6c5f62616c616e6365733a3a4d6f64756c653c542c493e2061732073726d6c5f737570706f72743a3a7472616974733a3a43757272656e63793c3c542061732073726d6c5f73797374656d3a3a54726169743e3a3a4163636f756e7449643e3e3a3a6d616b655f667265655f62616c616e63655f62653a3a683563616137313734316335333937353386013573726d6c5f737570706f72743a3a73746f726167653a3a6861736865643a3a6765743a3a683464373234623632323533336661633887017f3c73726d6c5f696e64696365733a3a4d6f64756c653c543e2061732073726d6c5f73797374656d3a3a4f6e4e65774163636f756e743c3c542061732073726d6c5f73797374656d3a3a54726169743e3a3a4163636f756e7449643e3e3a3a6f6e5f6e65775f6163636f756e743a3a686465373063346364396166633432623988014073726d6c5f73797374656d3a3a4d6f64756c653c543e3a3a6465706f7369745f6576656e745f696e64657865643a3a686433643562663333343338323266626289013f73726d6c5f62616c616e6365733a3a4d6f64756c653c542c493e3a3a7365745f667265655f62616c616e63653a3a68373837306238356533356562373234328a013873726d6c5f737570706f72743a3a73746f726167653a3a756e6861736865643a3a74616b653a3a68653364393136363537613365336232368b013673726d6c5f7374616b696e673a3a4d6f64756c653c543e3a3a6b696c6c5f73746173683a3a68363338323138363461313337653137398c01453c552061732073726d6c5f737570706f72743a3a73746f726167653a3a53746f726167654d61703c4b2c563e3e3a3a6765743a3a68393061613361653732633833656639338d01d5013c73726d6c5f73657373696f6e3a3a4e6578744b6579733c543e2061732073726d6c5f737570706f72743a3a73746f726167653a3a756e6861736865643a3a67656e657261746f723a3a53746f72616765446f75626c654d61703c616c6c6f633a3a7665633a3a5665633c75383e2c3c542061732073726d6c5f73657373696f6e3a3a54726169743e3a3a56616c696461746f7249642c3c542061732073726d6c5f73657373696f6e3a3a54726169743e3a3a4b6579733e3e3a3a6b65795f666f723a3a68316239363465623039623463346132308e013773726d6c5f737570706f72743a3a73746f726167653a3a756e6861736865643a3a6765743a3a68633766633938653035376633333530628f01cf013c73726d6c5f73657373696f6e3a3a4b65794f776e65723c543e2061732073726d6c5f737570706f72743a3a73746f726167653a3a756e6861736865643a3a67656e657261746f723a3a53746f72616765446f75626c654d61703c616c6c6f633a3a7665633a3a5665633c75383e2c287533322c20616c6c6f633a3a7665633a3a5665633c75383e292c3c542061732073726d6c5f73657373696f6e3a3a54726169743e3a3a56616c696461746f7249643e3e3a3a6b65795f666f723a3a6832353734656439663437656665366662900181013c73726d6c5f62616c616e6365733a3a4d6f64756c653c542c493e2061732073726d6c5f737570706f72743a3a7472616974733a3a43757272656e63793c3c542061732073726d6c5f73797374656d3a3a54726169743e3a3a4163636f756e7449643e3e3a3a77697468647261773a3a683765636562373662383465393430366691018c013c73726d6c5f62616c616e6365733a3a4d6f64756c653c542c493e2061732073726d6c5f737570706f72743a3a7472616974733a3a43757272656e63793c3c542061732073726d6c5f73797374656d3a3a54726169743e3a3a4163636f756e7449643e3e3a3a656e737572655f63616e5f77697468647261773a3a683935333330336237353137646136643992013e73726d6c5f62616c616e6365733a3a4d6f64756c653c542c493e3a3a76657374696e675f62616c616e63653a3a683038396261373831343933393664343293013473726d6c5f62616c616e6365733a3a4d6f64756c653c542c493e3a3a6c6f636b733a3a683864613465376434306434633132323094013573726d6c5f737570706f72743a3a73746f726167653a3a6861736865643a3a6765743a3a6862343536656135666434613534336564950186013c73726d6c5f62616c616e6365733a3a4d6f64756c653c542c493e2061732073726d6c5f737570706f72743a3a7472616974733a3a43757272656e63793c3c542061732073726d6c5f73797374656d3a3a54726169743e3a3a4163636f756e7449643e3e3a3a746f74616c5f62616c616e63653a3a68376534653632323434633361613564659601653c73726d6c5f62616c616e6365733a3a54616b65466565733c542c493e2061732073725f7072696d6974697665733a3a7472616974733a3a5369676e6564457874656e73696f6e3e3a3a76616c69646174653a3a683137353630656536396263363164333797014b73725f7072696d6974697665733a3a7472616974733a3a4163636f756e744964436f6e76657273696f6e3a3a696e746f5f6163636f756e743a3a686437643561323437653936343338323398013573726d6c5f617574686f72736869703a3a4d6f64756c653c543e3a3a617574686f723a3a683339353630386434306535366633363899013d73726d6c5f62616c616e6365733a3a4d6f64756c653c542c493e3a3a63616c6c5f66756e6374696f6e733a3a68386630396366306366633562363166329a013f73726d6c5f62616c616e6365733a3a4d6f64756c653c542c493e3a3a73746f726167655f6d657461646174613a3a68366338316362376438353434333664639b016f3c73726d6c5f62616c616e6365733a3a5f5f476574427974655374727563744672656542616c616e63653c542c493e2061732073726d6c5f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a68363634653735366135323539653534659c014373726d6c5f62616c616e6365733a3a4d6f64756c653c542c493e3a3a7365745f72657365727665645f62616c616e63653a3a68373633383762663065306136613933399d014873726d6c5f62616c616e6365733a3a4d6f64756c653c542c493e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a68363163646335643166613233316130619e01593c552061732073726d6c5f737570706f72743a3a73746f726167653a3a53746f72616765446f75626c654d61703c4b312c4b322c563e3e3a3a72656d6f76655f7072656669783a3a68666332656331616339616533373238659f018e013c73726d6c5f62616c616e6365733a3a4d6f64756c653c542c493e2061732073726d6c5f737570706f72743a3a7472616974733a3a43757272656e63793c3c542061732073726d6c5f73797374656d3a3a54726169743e3a3a4163636f756e7449643e3e3a3a6465706f7369745f696e746f5f6578697374696e673a3a6836343734656565626631616462323833a0014273726d6c5f636f6e7472616374733a3a72656e743a3a7472795f65766963745f6f725f616e645f7061795f72656e743a3a6838393064333938626561646466353532a101483c552061732073726d6c5f737570706f72743a3a73746f726167653a3a53746f726167654d61703c4b2c563e3e3a3a696e736572743a3a6864373666326632313961373465366630a2012e636f72653a3a726573756c743a3a756e777261705f6661696c65643a3a6837613261353064316536613633333539a3013c73726d6c5f696d5f6f6e6c696e653a3a4d6f64756c653c543e3a3a63616c6c5f66756e6374696f6e733a3a6835326137393065313637653833353630a4013e73726d6c5f696d5f6f6e6c696e653a3a4d6f64756c653c543e3a3a73746f726167655f6d657461646174613a3a6837653761323665343030333039643361a5014773726d6c5f696d5f6f6e6c696e653a3a4d6f64756c653c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a6863393961633631393662646166633363a6018c013c73726d6c5f62616c616e6365733a3a4d6f64756c653c542c493e2061732073726d6c5f737570706f72743a3a7472616974733a3a4c6f636b61626c6543757272656e63793c3c542061732073726d6c5f73797374656d3a3a54726169743e3a3a4163636f756e7449643e3e3a3a657874656e645f6c6f636b3a3a6836663666396631663235363035646265a701483c552061732073726d6c5f737570706f72743a3a73746f726167653a3a53746f726167654d61703c4b2c563e3e3a3a696e736572743a3a6839643635656336376635656131633538a80189013c73726d6c5f62616c616e6365733a3a4d6f64756c653c542c493e2061732073726d6c5f737570706f72743a3a7472616974733a3a4c6f636b61626c6543757272656e63793c3c542061732073726d6c5f73797374656d3a3a54726169743e3a3a4163636f756e7449643e3e3a3a7365745f6c6f636b3a3a6831376262623835373466386234353634a90149636f72653a3a666d743a3a6e756d3a3a3c696d706c20636f72653a3a666d743a3a446562756720666f72207573697a653e3a3a666d743a3a6863623838333863316264623130623561aa012f636f72653a3a666d743a3a6e756d3a3a696d703a3a666d745f7536343a3a6839663433396331306235306661323566ab0135636f72653a3a666d743a3a466f726d61747465723a3a7061645f696e74656772616c3a3a6838303465663539383063333530396330ac018a013c73726d6c5f62616c616e6365733a3a4d6f64756c653c542c493e2061732073726d6c5f737570706f72743a3a7472616974733a3a52657365727661626c6543757272656e63793c3c542061732073726d6c5f73797374656d3a3a54726169743e3a3a4163636f756e7449643e3e3a3a726573657276653a3a6832666663656134306236326365313862ad018c013c73726d6c5f62616c616e6365733a3a4d6f64756c653c542c493e2061732073726d6c5f737570706f72743a3a7472616974733a3a52657365727661626c6543757272656e63793c3c542061732073726d6c5f73797374656d3a3a54726169743e3a3a4163636f756e7449643e3e3a3a756e726573657276653a3a6835303762386634643561356339336231ae014373726d6c5f66696e616c6974795f747261636b65723a3a4d6f64756c653c543e3a3a63616c6c5f66756e6374696f6e733a3a6835353135623762323533613661313033af014e73726d6c5f66696e616c6974795f747261636b65723a3a4d6f64756c653c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a6863353237363563363832333466303030b0019c013c73726d6c5f66696e616c6974795f747261636b65723a3a4d6f64756c653c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a57696e646f7753697a6544656661756c74427974654765747465723c543e2061732073726d6c5f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6865326138353762393238303937326531b101493c73726d6c5f696d5f6f6e6c696e653a3a43616c6c3c543e20617320636f72653a3a636c6f6e653a3a436c6f6e653e3a3a636c6f6e653a3a6830643964303130633531373464376137b201c6013c73726d6c5f696d5f6f6e6c696e653a3a5265636569766564486561727462656174733c543e2061732073726d6c5f737570706f72743a3a73746f726167653a3a756e6861736865643a3a67656e657261746f723a3a53746f72616765446f75626c654d61703c7533322c3c542061732073726d6c5f696d5f6f6e6c696e653a3a54726169743e3a3a417574686f7269747949642c616c6c6f633a3a7665633a3a5665633c75383e3e3e3a3a6b65795f666f723a3a6839666162343066636163363438666538b3013d7061726974795f636f6465633a3a636f6465633a3a456e636f64653a3a7573696e675f656e636f6465643a3a6835636338646430373363316466383730b4018c013c73726d6c5f656c656374696f6e733a3a4d6f64756c653c543e2061732073725f7072696d6974697665733a3a7472616974733a3a4f6e496e697469616c697a653c3c542061732073726d6c5f73797374656d3a3a54726169743e3a3a426c6f636b4e756d6265723e3e3a3a6f6e5f696e697469616c697a653a3a6862353162313535666137343830656531b5013573726d6c5f737570706f72743a3a73746f726167653a3a6861736865643a3a6765743a3a6835636365313535316465373165343638b6014073726d6c5f656c656374696f6e733a3a4d6f64756c653c543e3a3a63616e6469646174655f7265675f696e666f3a3a6832373433366465363333363863636664b7013873726d6c5f656c656374696f6e733a3a4d6f64756c653c543e3a3a616c6c5f766f746572733a3a6865376465623636613036333563346364b8013a73726d6c5f656c656374696f6e733a3a4d6f64756c653c543e3a3a617070726f76616c735f6f663a3a6862356366623966646431326362343134b901ab023c73726d6c5f656c656374696f6e733a3a566f746572496e666f4f663c543e2061732073726d6c5f737570706f72743a3a73746f726167653a3a6861736865643a3a67656e657261746f723a3a53746f726167654d61703c3c542061732073726d6c5f73797374656d3a3a54726169743e3a3a4163636f756e7449642c73726d6c5f656c656374696f6e733a3a566f746572496e666f3c3c3c542061732073726d6c5f656c656374696f6e733a3a54726169743e3a3a43757272656e63792061732073726d6c5f737570706f72743a3a7472616974733a3a43757272656e63793c3c542061732073726d6c5f73797374656d3a3a54726169743e3a3a4163636f756e7449643e3e3a3a42616c616e63653e3e3e3a3a6765743a3a6831326661383262363539366434343230ba018e013c73726d6c5f636f6c6c6563746976653a3a4d6f64756c653c542c493e2061732073726d6c5f737570706f72743a3a7472616974733a3a4368616e67654d656d626572733c3c542061732073726d6c5f73797374656d3a3a54726169743e3a3a4163636f756e7449643e3e3a3a6368616e67655f6d656d626572733a3a6863656133623466363866353031346137bb013773726d6c5f737570706f72743a3a73746f726167653a3a756e6861736865643a3a6765743a3a6837366535353966323933386565373462bc01bc013c73726d6c5f656c656374696f6e733a3a566f746572733c543e2061732073726d6c5f737570706f72743a3a73746f726167653a3a6861736865643a3a67656e657261746f723a3a53746f726167654d61703c7533322c616c6c6f633a3a7665633a3a5665633c636f72653a3a6f7074696f6e3a3a4f7074696f6e3c3c542061732073726d6c5f73797374656d3a3a54726169743e3a3a4163636f756e7449643e3e3e3e3a3a6765743a3a6831656136663334656630636666373762bd013c73726d6c5f656c656374696f6e733a3a4d6f64756c653c543e3a3a63616c6c5f66756e6374696f6e733a3a6832386162326161326664313362653432be013e73726d6c5f656c656374696f6e733a3a4d6f64756c653c543e3a3a73746f726167655f6d657461646174613a3a6838396534323930613036383532316361bf01713c73726d6c5f656c656374696f6e733a3a5f5f4765744279746553747275637443616e646964617465436f756e743c543e2061732073726d6c5f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6834353035376464383562306231303133c0014773726d6c5f656c656374696f6e733a3a4d6f64756c653c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a6836393765613834396437376665333936c10199013c73726d6c5f656c656374696f6e733a3a4d6f64756c653c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a564f5445525f5345545f53495a4544656661756c74427974654765747465723c543e2061732073726d6c5f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6839666233326632353861666432393464c20197013c73726d6c5f656c656374696f6e733a3a4d6f64756c653c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a566f74696e67506572696f6444656661756c74427974654765747465723c543e2061732073726d6c5f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6864323236346132656331623566666433c3019e013c73726d6c5f656c656374696f6e733a3a4d6f64756c653c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a496e6163746976654772616365506572696f6444656661756c74427974654765747465723c543e2061732073726d6c5f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6834343861363466376433346165346563c40195013c73726d6c5f656c656374696f6e733a3a4d6f64756c653c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a4361727279436f756e7444656661756c74427974654765747465723c543e2061732073726d6c5f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6833323038376632623932366330353438c50194013c73726d6c5f656c656374696f6e733a3a4d6f64756c653c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a566f74696e6746656544656661756c74427974654765747465723c543e2061732073726d6c5f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6862666235346331666336643035383166c60195013c73726d6c5f656c656374696f6e733a3a4d6f64756c653c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a566f74696e67426f6e6444656661756c74427974654765747465723c543e2061732073726d6c5f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6835396333333633306664303535383639c70198013c73726d6c5f656c656374696f6e733a3a4d6f64756c653c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a43616e646964616379426f6e6444656661756c74427974654765747465723c543e2061732073726d6c5f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6835306436353364353736306636663333c801493c73726d6c5f656c656374696f6e733a3a43616c6c3c543e20617320636f72653a3a636c6f6e653a3a436c6f6e653e3a3a636c6f6e653a3a6862313838373164656434333234353339c9015d3c73726d6c5f656c656374696f6e733a3a43616c6c3c543e2061732073725f7072696d6974697665733a3a7472616974733a3a446973706174636861626c653e3a3a64697370617463683a3a6865623237373936363537376332616332ca01323c265420617320636f72653a3a666d743a3a446973706c61793e3a3a666d743a3a6831666533363132333331313638633334cb013e73726d6c5f656c656374696f6e733a3a4d6f64756c653c543e3a3a646f5f7365745f617070726f76616c733a3a6831623765636666336534616135336566cc013473726d6c5f696e64696365733a3a4d6f64756c653c543e3a3a656e756d5f7365743a3a6866613936323364346331613731636561cd013a73726d6c5f656c656374696f6e733a3a4d6f64756c653c543e3a3a72656d6f76655f766f7465723a3a6839646330343430376563653138376565ce01483c552061732073726d6c5f737570706f72743a3a73746f726167653a3a53746f726167654d61703c4b2c563e3e3a3a696e736572743a3a6834346562313437633932326265303632cf01793c73726d6c5f636f6e7472616374733a3a6163636f756e745f64623a3a4469726563744163636f756e7444622061732073726d6c5f636f6e7472616374733a3a6163636f756e745f64623a3a4163636f756e7444623c543e3e3a3a6765745f62616c616e63653a3a6832663762353865313534386536353861d001793c73726d6c5f636f6e7472616374733a3a6163636f756e745f64623a3a4469726563744163636f756e7444622061732073726d6c5f636f6e7472616374733a3a6163636f756e745f64623a3a4163636f756e7444623c543e3e3a3a6765745f73746f726167653a3a6866343935363530383330653161313765d1017b3c73726d6c5f636f6e7472616374733a3a6163636f756e745f64623a3a4469726563744163636f756e7444622061732073726d6c5f636f6e7472616374733a3a6163636f756e745f64623a3a4163636f756e7444623c543e3e3a3a6765745f636f64655f686173683a3a6866643430616431306566633961633266d2017d3c73726d6c5f636f6e7472616374733a3a6163636f756e745f64623a3a4469726563744163636f756e7444622061732073726d6c5f636f6e7472616374733a3a6163636f756e745f64623a3a4163636f756e7444623c543e3e3a3a636f6e74726163745f6578697374733a3a6863303037346238366565616666666133d30180013c73726d6c5f636f6e7472616374733a3a6163636f756e745f64623a3a4469726563744163636f756e7444622061732073726d6c5f636f6e7472616374733a3a6163636f756e745f64623a3a4163636f756e7444623c543e3e3a3a6765745f72656e745f616c6c6f77616e63653a3a6864393037393837623738363764356263d401743c73726d6c5f636f6e7472616374733a3a6163636f756e745f64623a3a4469726563744163636f756e7444622061732073726d6c5f636f6e7472616374733a3a6163636f756e745f64623a3a4163636f756e7444623c543e3e3a3a636f6d6d69743a3a6865636138346635343737616165636630d501723c616c6c6f633a3a636f6c6c656374696f6e733a3a62747265653a3a6d61703a3a496e746f497465723c4b2c563e20617320636f72653a3a697465723a3a7472616974733a3a6974657261746f723a3a4974657261746f723e3a3a6e6578743a3a6832666162346632393762633738393362d601613c616c6c6f633a3a636f6c6c656374696f6e733a3a62747265653a3a6d61703a3a496e746f497465723c4b2c563e20617320636f72653a3a6f70733a3a64726f703a3a44726f703e3a3a64726f703a3a6833343835613264643835383431636332d701723c616c6c6f633a3a636f6c6c656374696f6e733a3a62747265653a3a6d61703a3a496e746f497465723c4b2c563e20617320636f72653a3a697465723a3a7472616974733a3a6974657261746f723a3a4974657261746f723e3a3a6e6578743a3a6839656363306337636437383038323737d801483c552061732073726d6c5f737570706f72743a3a73746f726167653a3a53746f726167654d61703c4b2c563e3e3a3a696e736572743a3a6837363131623933613539323766346231d901613c616c6c6f633a3a636f6c6c656374696f6e733a3a62747265653a3a6d61703a3a496e746f497465723c4b2c563e20617320636f72653a3a6f70733a3a64726f703a3a44726f703e3a3a64726f703a3a6863646339396163383037623662316336da014d73726d6c5f636f6e7472616374733a3a657865633a3a457865637574696f6e436f6e746578743c542c562c4c3e3a3a696e7374616e74696174653a3a6832386263643136653763303735623063db013173726d6c5f73797374656d3a3a4d6f64756c653c543e3a3a72616e646f6d3a3a6835626633356265346662393261616566dc0127636f72653a3a7374723a3a66726f6d5f757466383a3a6830386430613533636364333636383366dd017d3c73726d6c5f636f6e7472616374733a3a6163636f756e745f64623a3a4f7665726c61794163636f756e7444623c543e2061732073726d6c5f636f6e7472616374733a3a6163636f756e745f64623a3a4163636f756e7444623c543e3e3a3a6765745f73746f726167653a3a6835303462306465336135333763313630de014b616c6c6f633a3a636f6c6c656374696f6e733a3a62747265653a3a6d61703a3a566163616e74456e7472793c4b2c563e3a3a696e736572743a3a6838346466386135383335633337333363df0148616c6c6f633a3a636f6c6c656374696f6e733a3a62747265653a3a6d61703a3a42547265654d61703c4b2c563e3a3a696e736572743a3a6830613564653661326333656633346165e0012d636f72653a3a736c6963653a3a736f72743a3a726563757273653a3a6865616138303137356633383063613361e1014673726d6c5f636f6e7472616374733a3a657865633a3a457865637574696f6e436f6e746578743c542c562c4c3e3a3a63616c6c3a3a6861303336313832306535346562393361e2017d3c73726d6c5f636f6e7472616374733a3a6163636f756e745f64623a3a4f7665726c61794163636f756e7444623c543e2061732073726d6c5f636f6e7472616374733a3a6163636f756e745f64623a3a4163636f756e7444623c543e3e3a3a6765745f62616c616e63653a3a6832656534383537613666386661386334e3017f3c73726d6c5f636f6e7472616374733a3a6163636f756e745f64623a3a4f7665726c61794163636f756e7444623c543e2061732073726d6c5f636f6e7472616374733a3a6163636f756e745f64623a3a4163636f756e7444623c543e3e3a3a6765745f636f64655f686173683a3a6865616365323935303530343734363264e40181013c73726d6c5f636f6e7472616374733a3a6163636f756e745f64623a3a4f7665726c61794163636f756e7444623c543e2061732073726d6c5f636f6e7472616374733a3a6163636f756e745f64623a3a4163636f756e7444623c543e3e3a3a636f6e74726163745f6578697374733a3a6839626533333032656563316461643338e50184013c73726d6c5f636f6e7472616374733a3a6163636f756e745f64623a3a4f7665726c61794163636f756e7444623c543e2061732073726d6c5f636f6e7472616374733a3a6163636f756e745f64623a3a4163636f756e7444623c543e3e3a3a6765745f72656e745f616c6c6f77616e63653a3a6837666339623464643564653636666165e601783c73726d6c5f636f6e7472616374733a3a6163636f756e745f64623a3a4f7665726c61794163636f756e7444623c543e2061732073726d6c5f636f6e7472616374733a3a6163636f756e745f64623a3a4163636f756e7444623c543e3e3a3a636f6d6d69743a3a6838356631373164656563363033336438e701367061726974795f636f6465633a3a636f6465633a3a456e636f64653a3a656e636f64653a3a6865366538646366383963393164383733e8013a73726d6c5f6772616e6470613a3a4d6f64756c653c543e3a3a63616c6c5f66756e6374696f6e733a3a6835313661376532386333333139343162e9013c73726d6c5f6772616e6470613a3a4d6f64756c653c543e3a3a73746f726167655f6d657461646174613a3a6835396665663231653832316339333063ea01663c73726d6c5f6772616e6470613a3a5f5f4765744279746553747275637453746174653c543e2061732073726d6c5f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6837636539336431333136393762366139eb014173726d6c5f737570706f72743a3a7472616974733a3a496d62616c616e63653a3a6d617962655f73756273756d653a3a6861393365353238393933316362383966ec013b73726d6c5f74726561737572793a3a4d6f64756c653c543e3a3a63616c6c5f66756e6374696f6e733a3a6864316463633936373665393831316535ed013d73726d6c5f74726561737572793a3a4d6f64756c653c543e3a3a73746f726167655f6d657461646174613a3a6862653963626362376434633964363963ee014673726d6c5f74726561737572793a3a4d6f64756c653c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a6835333132373733363164353661346664ef018e013c73726d6c5f74726561737572793a3a4d6f64756c653c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a4275726e44656661756c74427974654765747465723c543e2061732073726d6c5f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6836306564613365323036363061346138f00195013c73726d6c5f74726561737572793a3a4d6f64756c653c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a5370656e64506572696f6444656661756c74427974654765747465723c543e2061732073726d6c5f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6863623665323938376635303361653937f10196013c73726d6c5f74726561737572793a3a4d6f64756c653c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a50726f706f73616c426f6e6444656661756c74427974654765747465723c543e2061732073726d6c5f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6834633263343366353835343865633133f2013673726d6c5f74726561737572793a3a4d6f64756c653c543e3a3a70726f706f73616c733a3a6837353937346665653933353466353965f3013773726d6c5f737570706f72743a3a73746f726167653a3a756e6861736865643a3a6765743a3a6837626461616565326462313031336137f4014f73726d6c5f636f6e7472616374733a3a6163636f756e745f64623a3a4f7665726c61794163636f756e7444623c543e3a3a7365745f62616c616e63653a3a6833383666633233353830333065353239f5015c3c73726d6c5f74726561737572793a3a43616c6c3c543e2061732073725f7072696d6974697665733a3a7472616974733a3a446973706174636861626c653e3a3a64697370617463683a3a6835303363326164363635633065383333f6013b73726d6c5f6772616e6470613a3a4d6f64756c653c543e3a3a7363686564756c655f6368616e67653a3a6832633035326438376533663134326634f70130636f72653a3a7074723a3a7265616c5f64726f705f696e5f706c6163653a3a6834353035636165666339373038373732f801633c636f72653a3a697465723a3a61646170746572733a3a4d61703c492c463e20617320636f72653a3a697465723a3a7472616974733a3a6974657261746f723a3a4974657261746f723e3a3a6e6578743a3a6830353463613161343333316134343562f901683c636f72653a3a697465723a3a61646170746572733a3a4d61703c492c463e20617320636f72653a3a697465723a3a7472616974733a3a6974657261746f723a3a4974657261746f723e3a3a73697a655f68696e743a3a6835346530646462616330383561633239fa013e636f72653a3a697465723a3a7472616974733a3a6974657261746f723a3a4974657261746f723a3a6e74683a3a6831623935356631303935383134306330fb01693c616c6c6f633a3a636f6c6c656374696f6e733a3a62747265653a3a6d61703a3a42547265654d61703c4b2c563e206173207061726974795f636f6465633a3a636f6465633a3a4465636f64653e3a3a6465636f64653a3a6862303434633932643539306564396465fc01613c616c6c6f633a3a636f6c6c656374696f6e733a3a62747265653a3a6d61703a3a42547265654d61703c4b2c563e20617320636f72653a3a6f70733a3a64726f703a3a44726f703e3a3a64726f703a3a6839623462643566353137353466323766fd014b616c6c6f633a3a636f6c6c656374696f6e733a3a62747265653a3a6d61703a3a566163616e74456e7472793c4b2c563e3a3a696e736572743a3a6838633162393638623437653339643037fe01aa017375627374726174655f7072696d6974697665733a3a73616e64626f783a3a5f494d504c5f454e434f44455f464f525f547970656456616c75653a3a3c696d706c207061726974795f636f6465633a3a636f6465633a3a456e636f646520666f72207375627374726174655f7072696d6974697665733a3a73616e64626f783a3a547970656456616c75653e3a3a656e636f64655f746f3a3a6838663038613532313138663338346335ff013a73726d6c5f73657373696f6e3a3a4d6f64756c653c543e3a3a63616c6c5f66756e6374696f6e733a3a683834376431616439393133353538633780023c73726d6c5f73657373696f6e3a3a4d6f64756c653c543e3a3a73746f726167655f6d657461646174613a3a683434313938383563633762383063623781024573726d6c5f73657373696f6e3a3a4d6f64756c653c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a6831653962326534666561326361353039820299013c73726d6c5f73657373696f6e3a3a4d6f64756c653c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a44454455505f4b45595f50524546495844656661756c74427974654765747465723c543e2061732073726d6c5f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a686639643163336137393264633134353083028c013c73726d6c5f737570706f72743a3a73746f726167653a3a6861736865643a3a67656e657261746f723a3a54776f783634436f6e6361742061732073726d6c5f737570706f72743a3a73746f726167653a3a6861736865643a3a67656e657261746f723a3a53746f726167654861736865723e3a3a686173683a3a683164626261313264323064653436316184023973726d6c5f636f6e7472616374733a3a7761736d3a3a636f64655f63616368653a3a6c6f61643a3a683264643638373532626636626134376585024273726d6c5f636f6e7472616374733a3a7761736d3a3a707265706172653a3a707265706172655f636f6e74726163743a3a68306335343562343937666534366438628602a5013c73725f7072696d6974697665733a3a67656e657269633a3a756e636865636b65645f65787472696e7369633a3a556e636865636b656445787472696e7369633c416464726573732c43616c6c2c5369676e61747572652c45787472613e2061732073725f7072696d6974697665733a3a7472616974733a3a436865636b61626c653c4c6f6f6b75703e3e3a3a636865636b3a3a68666538656361633632383338353936328702b3013c73726d6c5f73797374656d3a3a426c6f636b486173683c543e2061732073726d6c5f737570706f72743a3a73746f726167653a3a6861736865643a3a67656e657261746f723a3a53746f726167654d61703c3c542061732073726d6c5f73797374656d3a3a54726169743e3a3a426c6f636b4e756d6265722c3c542061732073726d6c5f73797374656d3a3a54726169743e3a3a486173683e3e3a3a6765743a3a68343431663362346533343335343861358802cf017375627374726174655f636f6e73656e7375735f626162655f7072696d6974697665733a3a6469676573743a3a5f494d504c5f4445434f44455f464f525f526177426162655072654469676573743a3a3c696d706c207061726974795f636f6465633a3a636f6465633a3a4465636f646520666f72207375627374726174655f636f6e73656e7375735f626162655f7072696d6974697665733a3a6469676573743a3a526177426162655072654469676573743e3a3a6465636f64653a3a683037313535396534633038343031363689023573726d6c5f737570706f72743a3a73746f726167653a3a6861736865643a3a6765743a3a68393666656334636533303439306538668a023673726d6c5f737570706f72743a3a73746f726167653a3a6861736865643a3a74616b653a3a68366231633530646430346231333463628b02673c636f72653a3a697465723a3a61646170746572733a3a4d61703c492c463e20617320636f72653a3a697465723a3a7472616974733a3a6974657261746f723a3a4974657261746f723e3a3a7472795f666f6c643a3a68323233383038663965353761356432338c023273726d6c5f7374616b696e673a3a4d6f64756c653c543e3a3a626f6e6465643a3a68386434613934326262666536326333618d02c9023c73726d6c5f7374616b696e673a3a4c65646765723c543e2061732073726d6c5f737570706f72743a3a73746f726167653a3a6861736865643a3a67656e657261746f723a3a53746f726167654d61703c3c542061732073726d6c5f73797374656d3a3a54726169743e3a3a4163636f756e7449642c73726d6c5f7374616b696e673a3a5374616b696e674c65646765723c3c542061732073726d6c5f73797374656d3a3a54726169743e3a3a4163636f756e7449642c3c3c542061732073726d6c5f7374616b696e673a3a54726169743e3a3a43757272656e63792061732073726d6c5f737570706f72743a3a7472616974733a3a43757272656e63793c3c542061732073726d6c5f73797374656d3a3a54726169743e3a3a4163636f756e7449643e3e3a3a42616c616e63653e3e3e3a3a6765743a3a68373038356335343662636132396435658e026f3c73725f7072696d6974697665733a3a67656e657269633a3a6865616465723a3a4865616465723c4e756d6265722c486173683e206173207061726974795f636f6465633a3a636f6465633a3a4465636f64653e3a3a6465636f64653a3a68393162623365343663353534323132398f02800173726d6c5f64656d6f63726163793a3a5f494d504c5f4445434f44455f464f525f43616c6c3a3a3c696d706c207061726974795f636f6465633a3a636f6465633a3a4465636f646520666f722073726d6c5f64656d6f63726163793a3a43616c6c3c543e3e3a3a6465636f64653a3a68653736633238363934363832396632309002840173726d6c5f636f6c6c6563746976653a3a5f494d504c5f4445434f44455f464f525f43616c6c3a3a3c696d706c207061726974795f636f6465633a3a636f6465633a3a4465636f646520666f722073726d6c5f636f6c6c6563746976653a3a43616c6c3c542c493e3e3a3a6465636f64653a3a68653231663834313361313066313634669102800173726d6c5f636f6e7472616374733a3a5f494d504c5f4445434f44455f464f525f43616c6c3a3a3c696d706c207061726974795f636f6465633a3a636f6465633a3a4465636f646520666f722073726d6c5f636f6e7472616374733a3a43616c6c3c543e3e3a3a6465636f64653a3a68366163336136623765636339306135359202870173726d6c5f636f6c6c6563746976653a3a5f494d504c5f454e434f44455f464f525f43616c6c3a3a3c696d706c207061726974795f636f6465633a3a636f6465633a3a456e636f646520666f722073726d6c5f636f6c6c6563746976653a3a43616c6c3c542c493e3e3a3a656e636f64655f746f3a3a68323335653561653030363565396561349302880173726d6c5f636f6e7472616374733a3a5f494d504c5f454e434f44455f464f525f5363686564756c653a3a3c696d706c207061726974795f636f6465633a3a636f6465633a3a456e636f646520666f722073726d6c5f636f6e7472616374733a3a5363686564756c653e3a3a656e636f64655f746f3a3a686562633839646631373665653164653894022b616c6c6f633a3a736c6963653a3a6d657267655f736f72743a3a68313463626638636433356132306266319502443c6e6f64655f72756e74696d653a3a43616c6c20617320636f72653a3a636c6f6e653a3a436c6f6e653e3a3a636c6f6e653a3a68363865366439316135393139346230319602463c73726d6c5f73797374656d3a3a43616c6c3c543e20617320636f72653a3a636c6f6e653a3a436c6f6e653e3a3a636c6f6e653a3a68386266663463613331373663343263639702443c73726d6c5f626162653a3a43616c6c3c543e20617320636f72653a3a636c6f6e653a3a436c6f6e653e3a3a636c6f6e653a3a68663664393738646663633837376133659802473c73726d6c5f696e64696365733a3a43616c6c3c543e20617320636f72653a3a636c6f6e653a3a436c6f6e653e3a3a636c6f6e653a3a68313663623861346338646234313334349902473c73726d6c5f7374616b696e673a3a43616c6c3c543e20617320636f72653a3a636c6f6e653a3a436c6f6e653e3a3a636c6f6e653a3a68373666633963373334666261336461359a02493c73726d6c5f64656d6f63726163793a3a43616c6c3c543e20617320636f72653a3a636c6f6e653a3a436c6f6e653e3a3a636c6f6e653a3a68303431353366306437383936366461329b024c3c73726d6c5f636f6c6c6563746976653a3a43616c6c3c542c493e20617320636f72653a3a636c6f6e653a3a436c6f6e653e3a3a636c6f6e653a3a68326666376631336164376163353738649c02493c73726d6c5f636f6e7472616374733a3a43616c6c3c543e20617320636f72653a3a636c6f6e653a3a436c6f6e653e3a3a636c6f6e653a3a68333135656332616632303137313131659d027e6e6f64655f72756e74696d653a3a5f494d504c5f454e434f44455f464f525f4576656e743a3a3c696d706c207061726974795f636f6465633a3a636f6465633a3a456e636f646520666f72206e6f64655f72756e74696d653a3a4576656e743e3a3a656e636f64655f746f3a3a68643763656231616366303439653433329e029c0173726d6c5f636f6c6c6563746976653a3a5f494d504c5f454e434f44455f464f525f5261774576656e743a3a3c696d706c207061726974795f636f6465633a3a636f6465633a3a456e636f646520666f722073726d6c5f636f6c6c6563746976653a3a5261774576656e743c486173682c4163636f756e7449642c493e3e3a3a656e636f64655f746f3a3a68386634353235316432393239363762389f023e6e6f64655f72756e74696d653a3a52756e74696d653a3a5f5f6d6f64756c655f6576656e74735f7375646f3a3a6830386133316462373566343330376236a002406e6f64655f72756e74696d653a3a52756e74696d653a3a5f5f6d6f64756c655f6576656e74735f73797374656d3a3a6864613235613331643933323561306635a102416e6f64655f72756e74696d653a3a52756e74696d653a3a5f5f6d6f64756c655f6576656e74735f696e64696365733a3a6830646162326362666463313439353061a202426e6f64655f72756e74696d653a3a52756e74696d653a3a5f5f6d6f64756c655f6576656e74735f62616c616e6365733a3a6838323134323562646137346134663963a302416e6f64655f72756e74696d653a3a52756e74696d653a3a5f5f6d6f64756c655f6576656e74735f7374616b696e673a3a6839613264663133306238666132323335a402416e6f64655f72756e74696d653a3a52756e74696d653a3a5f5f6d6f64756c655f6576656e74735f73657373696f6e3a3a6831656130653737366464353437353263a502436e6f64655f72756e74696d653a3a52756e74696d653a3a5f5f6d6f64756c655f6576656e74735f64656d6f63726163793a3a6864303336633430386134353234373864a6024e6e6f64655f72756e74696d653a3a52756e74696d653a3a5f5f6d6f64756c655f6576656e74735f636f6c6c6563746976655f496e7374616e6365313a3a6832396437623861636430646431663531a702436e6f64655f72756e74696d653a3a52756e74696d653a3a5f5f6d6f64756c655f6576656e74735f656c656374696f6e733a3a6864316262316639616565353031323836a802416e6f64655f72756e74696d653a3a52756e74696d653a3a5f5f6d6f64756c655f6576656e74735f6772616e6470613a3a6839363135363934636266656563346462a902426e6f64655f72756e74696d653a3a52756e74696d653a3a5f5f6d6f64756c655f6576656e74735f74726561737572793a3a6866326661643637386264666634373730aa02436e6f64655f72756e74696d653a3a52756e74696d653a3a5f5f6d6f64756c655f6576656e74735f636f6e7472616374733a3a6865636666393337666661353935366132ab02436e6f64655f72756e74696d653a3a52756e74696d653a3a5f5f6d6f64756c655f6576656e74735f696d5f6f6e6c696e653a3a6865396637336636353965323164343131ac02653c6e6f64655f72756e74696d653a3a43616c6c2061732073725f7072696d6974697665733a3a776569676874733a3a4765744469737061746368496e666f3e3a3a6765745f64697370617463685f696e666f3a3a6865366434613766316565633561663865ad02583c6e6f64655f72756e74696d653a3a43616c6c2061732073725f7072696d6974697665733a3a7472616974733a3a446973706174636861626c653e3a3a64697370617463683a3a6862353331636238353865323938363930ae02583c73726d6c5f626162653a3a43616c6c3c543e2061732073725f7072696d6974697665733a3a7472616974733a3a446973706174636861626c653e3a3a64697370617463683a3a6863353536316237633731306632633539af025e3c73726d6c5f617574686f72736869703a3a43616c6c3c543e2061732073725f7072696d6974697665733a3a7472616974733a3a446973706174636861626c653e3a3a64697370617463683a3a6832646632666438336632656164396338b0025b3c73726d6c5f696e64696365733a3a43616c6c3c543e2061732073725f7072696d6974697665733a3a7472616974733a3a446973706174636861626c653e3a3a64697370617463683a3a6862376666346265626463386465616132b1025b3c73726d6c5f7374616b696e673a3a43616c6c3c543e2061732073725f7072696d6974697665733a3a7472616974733a3a446973706174636861626c653e3a3a64697370617463683a3a6832303035636562333032366431636664b2025d3c73726d6c5f64656d6f63726163793a3a43616c6c3c543e2061732073725f7072696d6974697665733a3a7472616974733a3a446973706174636861626c653e3a3a64697370617463683a3a6838656636323030356664393836613861b302603c73726d6c5f636f6c6c6563746976653a3a43616c6c3c542c493e2061732073725f7072696d6974697665733a3a7472616974733a3a446973706174636861626c653e3a3a64697370617463683a3a6863366537316138333437616237393437b402603c73726d6c5f636f6c6c6563746976653a3a43616c6c3c542c493e2061732073725f7072696d6974697665733a3a7472616974733a3a446973706174636861626c653e3a3a64697370617463683a3a6863623464333939326163376432636533b5025d3c73726d6c5f636f6e7472616374733a3a43616c6c3c543e2061732073725f7072696d6974697665733a3a7472616974733a3a446973706174636861626c653e3a3a64697370617463683a3a6835356337656461323135336366373732b6023973726d6c5f7375646f3a3a4d6f64756c653c543e3a3a73746f726167655f6d657461646174613a3a6865366235396363376330656539613636b7023773726d6c5f7375646f3a3a4d6f64756c653c543e3a3a63616c6c5f66756e6374696f6e733a3a6833366437346636343139653935303735b802613c73726d6c5f7375646f3a3a5f5f476574427974655374727563744b65793c543e2061732073726d6c5f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6830653237323634646338323863393962b9027173726d6c5f6578656375746976653a3a4578656375746976653c53797374656d2c426c6f636b2c436f6e746578742c556e7369676e656456616c696461746f722c416c6c4d6f64756c65733e3a3a696e697469616c697a655f626c6f636b3a3a6830343433383838616235343662356438ba023773726d6c5f737570706f72743a3a73746f726167653a3a756e6861736865643a3a6765743a3a6832613339366565346635393436316338bb0286013c28412c20422c20432c20442c20452c20462c20472c20482c20492c204a2c204b2c204c2c204d2c204e2c204f2c20502c2051292061732073725f7072696d6974697665733a3a7472616974733a3a4f6e496e697469616c697a653c4e756d6265723e3e3a3a6f6e5f696e697469616c697a653a3a6862643866356436373132643933333864bc027973726d6c5f6578656375746976653a3a4578656375746976653c53797374656d2c426c6f636b2c436f6e746578742c556e7369676e656456616c696461746f722c416c6c4d6f64756c65733e3a3a6170706c795f65787472696e7369635f776974685f6c656e3a3a6837666661346335666566636666356439bd020c436f72655f76657273696f6ebe0212436f72655f657865637574655f626c6f636bbf024173725f7072696d6974697665733a3a67656e657269633a3a656e636f64655f776974685f7665635f7072656669783a3a6861343833323533633862386230396162c0026c3c73725f7072696d6974697665733a3a7472616974733a3a426c616b6554776f3235362061732073725f7072696d6974697665733a3a7472616974733a3a486173683e3a3a656e756d6572617465645f747269655f726f6f743a3a6835613864386165636232643332343062c1023873726d6c5f737570706f72743a3a73746f726167653a3a756e6861736865643a3a74616b653a3a6862306162646235623134643465353630c20282013c28412c20422c20432c20442c20452c20462c20472c20482c20492c204a2c204b2c204c2c204d2c204e2c204f2c20502c2051292061732073725f7072696d6974697665733a3a7472616974733a3a4f6e46696e616c697a653c4e756d6265723e3e3a3a6f6e5f66696e616c697a653a3a6834613038313634316331363332643861c3023373726d6c5f73797374656d3a3a4d6f64756c653c543e3a3a66696e616c697a653a3a6863353864366166643031653665613764c40215436f72655f696e697469616c697a655f626c6f636bc502114d657461646174615f6d65746164617461c602603c7061726974795f636f6465633a3a636f6465633a3a436f6d706163743c7533323e206173207061726974795f636f6465633a3a636f6465633a3a456e636f64653e3a3a656e636f64655f746f3a3a6862313136333934333262366238323036c702433c5b75385d206173207061726974795f636f6465633a3a636f6465633a3a456e636f64653e3a3a656e636f64655f746f3a3a6865326333656130663331616664363434c802623c73726d6c5f6d657461646174613a3a4465636f6465446966666572656e743c422c4f3e206173207061726974795f636f6465633a3a636f6465633a3a456e636f64653e3a3a656e636f64655f746f3a3a6865383930373662353839373366393932c902623c73726d6c5f6d657461646174613a3a4465636f6465446966666572656e743c422c4f3e206173207061726974795f636f6465633a3a636f6465633a3a456e636f64653e3a3a656e636f64655f746f3a3a6831326337313436376537633230336666ca02623c73726d6c5f6d657461646174613a3a4465636f6465446966666572656e743c422c4f3e206173207061726974795f636f6465633a3a636f6465633a3a456e636f64653e3a3a656e636f64655f746f3a3a6866356463356164333636313531353030cb02623c73726d6c5f6d657461646174613a3a4465636f6465446966666572656e743c422c4f3e206173207061726974795f636f6465633a3a636f6465633a3a456e636f64653e3a3a656e636f64655f746f3a3a6835623233303931303264376564333539cc021c426c6f636b4275696c6465725f6170706c795f65787472696e736963cd021b426c6f636b4275696c6465725f66696e616c697a655f626c6f636bce0220426c6f636b4275696c6465725f696e686572656e745f65787472696e73696373cf023873726d6c5f74696d657374616d703a3a657874726163745f696e686572656e745f646174613a3a6861663838366238613533323434616164d0021c426c6f636b4275696c6465725f636865636b5f696e686572656e7473d10218426c6f636b4275696c6465725f72616e646f6d5f73656564d2022b5461676765645472616e73616374696f6e51756575655f76616c69646174655f7472616e73616374696f6ed3025673725f7072696d6974697665733a3a7472616e73616374696f6e5f76616c69646974793a3a56616c69645472616e73616374696f6e3a3a636f6d62696e655f776974683a3a6831333237373835313963356563373134d402214f6666636861696e576f726b65724170695f6f6666636861696e5f776f726b6572d502214772616e6470614170695f6772616e6470615f70656e64696e675f6368616e6765d602204772616e6470614170695f6772616e6470615f666f726365645f6368616e6765d7021e4772616e6470614170695f6772616e6470615f617574686f726974696573d80214426162654170695f737461727475705f64617461d9020d426162654170695f65706f6368da0218436f6e73656e7375734170695f617574686f726974696573db023d7061726974795f636f6465633a3a636f6465633a3a456e636f64653a3a7573696e675f656e636f6465643a3a6830626630326362356431343231643563dc023d7061726974795f636f6465633a3a636f6465633a3a456e636f64653a3a7573696e675f656e636f6465643a3a6833326332313137616131313964646462dd02be0173726d6c5f636f6e7472616374733a3a5f494d504c5f454e434f44455f464f525f526177416c697665436f6e7472616374496e666f3a3a3c696d706c207061726974795f636f6465633a3a636f6465633a3a456e636f646520666f722073726d6c5f636f6e7472616374733a3a526177416c697665436f6e7472616374496e666f3c436f6465486173682c42616c616e63652c426c6f636b4e756d6265723e3e3a3a656e636f64655f746f3a3a6830333031396235396230633565303563de023c73726d6c5f636f6e7472616374733a3a4d6f64756c653c543e3a3a63616c6c5f66756e6374696f6e733a3a6835653738313263326535383766336138df023e73726d6c5f636f6e7472616374733a3a4d6f64756c653c543e3a3a73746f726167655f6d657461646174613a3a6832653332306130366534306263373333e00230636f72653a3a7074723a3a7265616c5f64726f705f696e5f706c6163653a3a6830303138366630366366636233393965e1026b3c73726d6c5f636f6e7472616374733a3a5f5f4765744279746553747275637447617350726963653c543e2061732073726d6c5f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6831323937653934626234623331393138e202713c73726d6c5f636f6e7472616374733a3a5f5f47657442797465537472756374436f6e7472616374496e666f4f663c543e2061732073726d6c5f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6831356663633937373139383066663961e302723c73726d6c5f636f6e7472616374733a3a5f5f4765744279746553747275637443757272656e745363686564756c653c543e2061732073726d6c5f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6830373336343365316532386638386636e4024773726d6c5f636f6e7472616374733a3a4d6f64756c653c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a6830303134653761653838393666656431e50298013c73726d6c5f636f6e7472616374733a3a4d6f64756c653c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a426c6f636b4761734c696d697444656661756c74427974654765747465723c543e2061732073726d6c5f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6836323933353364633134333962386431e60297013c73726d6c5f636f6e7472616374733a3a4d6f64756c653c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a4d617856616c756553697a6544656661756c74427974654765747465723c543e2061732073726d6c5f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6831363531353935303832653862363433e70293013c73726d6c5f636f6e7472616374733a3a4d6f64756c653c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a4d6178446570746844656661756c74427974654765747465723c543e2061732073726d6c5f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6833633730323537643734663966303434e80296013c73726d6c5f636f6e7472616374733a3a4d6f64756c653c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a43616c6c4261736546656544656661756c74427974654765747465723c543e2061732073726d6c5f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6837643534633062333230353030386132e90296013c73726d6c5f636f6e7472616374733a3a4d6f64756c653c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a436f6e747261637446656544656661756c74427974654765747465723c543e2061732073726d6c5f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6831383738366232346535343339303562ea029d013c73726d6c5f636f6e7472616374733a3a4d6f64756c653c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a5472616e73616374696f6e4279746546656544656661756c74427974654765747465723c543e2061732073726d6c5f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6864323130333138383966623833626166eb029a013c73726d6c5f636f6e7472616374733a3a4d6f64756c653c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a53757263686172676552657761726444656661756c74427974654765747465723c543e2061732073726d6c5f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6839643636363739303462633066303161ec029c013c73726d6c5f636f6e7472616374733a3a4d6f64756c653c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a52656e744465706f7369744f666673657444656661756c74427974654765747465723c543e2061732073726d6c5f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6837303438303530373033373134653739ed0296013c73726d6c5f636f6e7472616374733a3a4d6f64756c653c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a52656e744279746546656544656661756c74427974654765747465723c543e2061732073726d6c5f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6839653032303039643933303461333136ee029c013c73726d6c5f636f6e7472616374733a3a4d6f64756c653c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a53746f7261676553697a654f666673657444656661756c74427974654765747465723c543e2061732073726d6c5f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6836653631633863663736303163666534ef029b013c73726d6c5f636f6e7472616374733a3a4d6f64756c653c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a546f6d6273746f6e654465706f73697444656661756c74427974654765747465723c543e2061732073726d6c5f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6839376335613137306432663734346430f0029e013c73726d6c5f636f6e7472616374733a3a4d6f64756c653c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a5369676e6564436c61696d48616e646963617044656661756c74427974654765747465723c543e2061732073726d6c5f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6833326135613063303533336232346537f102850173726d6c5f636f6e7472616374733a3a5f494d504c5f4445434f44455f464f525f5363686564756c653a3a3c696d706c207061726974795f636f6465633a3a636f6465633a3a4465636f646520666f722073726d6c5f636f6e7472616374733a3a5363686564756c653e3a3a6465636f64653a3a6831383266623166313336663762316166f202cc013c73726d6c5f636f6c6c6563746976653a3a566f74696e673c542c493e2061732073726d6c5f737570706f72743a3a73746f726167653a3a6861736865643a3a67656e657261746f723a3a53746f726167654d61703c3c542061732073726d6c5f73797374656d3a3a54726169743e3a3a486173682c73726d6c5f636f6c6c6563746976653a3a566f7465733c3c542061732073726d6c5f73797374656d3a3a54726169743e3a3a4163636f756e7449643e3e3e3a3a6765743a3a6837643339613135396634613638326239f3028c0173726d6c5f636f6c6c6563746976653a3a5f494d504c5f4445434f44455f464f525f566f7465733a3a3c696d706c207061726974795f636f6465633a3a636f6465633a3a4465636f646520666f722073726d6c5f636f6c6c6563746976653a3a566f7465733c4163636f756e7449643e3e3a3a6465636f64653a3a6832643432393434303730333636636233f4023f73726d6c5f636f6c6c6563746976653a3a4d6f64756c653c542c493e3a3a63616c6c5f66756e6374696f6e733a3a6835323366313938366530646630643836f5024173726d6c5f636f6c6c6563746976653a3a4d6f64756c653c542c493e3a3a73746f726167655f6d657461646174613a3a6832653365636438323863383739393535f6024173726d6c5f636f6c6c6563746976653a3a4d6f64756c653c542c493e3a3a73746f726167655f6d657461646174613a3a6837336431363862656265313532663737f702463c616c6c6f633a3a626f7865643a3a426f783c543e20617320636f72653a3a636c6f6e653a3a436c6f6e653e3a3a636c6f6e653a3a6830643762653937613330343763653735f8023973726d6c5f636f6e7472616374733a3a6761733a3a726566756e645f756e757365645f6761733a3a6838313866393632316339316230343537f90234636f72653a3a736c6963653a3a3c696d706c205b545d3e3a3a636f6e7461696e733a3a6831303365623135656535646564646531fa023873726d6c5f737570706f72743a3a73746f726167653a3a756e6861736865643a3a74616b653a3a6830383262663632343263306632623461fb02cc013c73726d6c5f636f6c6c6563746976653a3a566f74696e673c542c493e2061732073726d6c5f737570706f72743a3a73746f726167653a3a6861736865643a3a67656e657261746f723a3a53746f726167654d61703c3c542061732073726d6c5f73797374656d3a3a54726169743e3a3a486173682c73726d6c5f636f6c6c6563746976653a3a566f7465733c3c542061732073726d6c5f73797374656d3a3a54726169743e3a3a4163636f756e7449643e3e3e3a3a6765743a3a6861656437373063336565313436653663fc026f7061726974795f636f6465633a3a636f6465633a3a696e6e65725f7475706c655f696d706c3a3a3c696d706c207061726974795f636f6465633a3a636f6465633a3a4465636f646520666f7220284a2c204b293e3a3a6465636f64653a3a6861643334666633636666366665316235fd023c73726d6c5f696e64696365733a3a4d6f64756c653c543e3a3a73746f726167655f6d657461646174613a3a6862336662666537393032306265393735fe02483c552061732073726d6c5f737570706f72743a3a73746f726167653a3a53746f726167654d61703c4b2c563e3e3a3a696e736572743a3a6834386165363866363430643637633930ff024573726d6c5f636f6e7472616374733a3a7761736d3a3a707265706172653a3a436f6e74726163744d6f64756c653a3a6e65773a3a68373437356366353665323338356534318003467061726974795f7761736d3a3a656c656d656e74733a3a73656374696f6e3a3a436f646553656374696f6e3a3a626f646965733a3a6833326461336131663335633534626538810348616c6c6f633a3a636f6c6c656374696f6e733a3a62747265653a3a6d61703a3a42547265654d61703c4b2c563e3a3a696e736572743a3a683637346166653166306130323465343082033c7061726974795f7761736d3a3a6275696c6465723a3a6d6f64756c653a3a66726f6d5f6d6f64756c653a3a68336630636663326637346565656337618303537061726974795f7761736d3a3a6275696c6465723a3a6d6f64756c653a3a4d6f64756c654275696c6465723c463e3a3a7265736f6c76655f747970655f7265663a3a68383163333338666361303832363762378403a9017061726974795f7761736d3a3a6275696c6465723a3a6d6f64756c653a3a3c696d706c20636f72653a3a636f6e766572743a3a46726f6d3c7061726974795f7761736d3a3a6275696c6465723a3a6d6f64756c653a3a4d6f64756c6553636166666f6c643e20666f72207061726974795f7761736d3a3a656c656d656e74733a3a6d6f64756c653a3a4d6f64756c653e3a3a66726f6d3a3a686664643761346163616662643161303785033a707761736d5f7574696c733a3a72756c65733a3a496e737472756374696f6e547970653a3a6f703a3a686633303131633431356339376365353886032d616c6c6f633a3a7665633a3a5665633c543e3a3a696e736572743a3a68363636643938316464366132376430638703507061726974795f7761736d3a3a6275696c6465723a3a6d6f64756c653a3a4d6f64756c654275696c6465723c463e3a3a707573685f66756e6374696f6e3a3a6862613763333530303062636130303664880330636f72653a3a7074723a3a7265616c5f64726f705f696e5f706c6163653a3a683932363665303964363138393234383089033c707761736d5f7574696c733a3a737461636b5f6865696768743a3a696e6a6563745f6c696d697465723a3a68333739383539653330333963393636388a036b3c7061726974795f7761736d3a3a656c656d656e74733a3a73656374696f6e3a3a53656374696f6e206173207061726974795f7761736d3a3a656c656d656e74733a3a53657269616c697a653e3a3a73657269616c697a653a3a68623164636337303363343663623964638b033c73726d6c5f74696d657374616d703a3a4d6f64756c653c543e3a3a63616c6c5f66756e6374696f6e733a3a68623635383930326631373535393638638c033e73726d6c5f74696d657374616d703a3a4d6f64756c653c543e3a3a73746f726167655f6d657461646174613a3a68663835666539373737653832616264358d03703c73726d6c5f617574686f72736869703a3a5f5f47657442797465537472756374446964536574556e636c65733c543e2061732073726d6c5f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a68343130303364663439323339376665318e034773726d6c5f74696d657374616d703a3a4d6f64756c653c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a68333034663035323735396230316264348f0398013c73726d6c5f74696d657374616d703a3a4d6f64756c653c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a4d696e696d756d506572696f6444656661756c74427974654765747465723c543e2061732073726d6c5f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a686239363539613438323161636661376490033d73726d6c5f617574686f72736869703a3a4d6f64756c653c543e3a3a63616c6c5f66756e6374696f6e733a3a683130663030303861393865653633333791033f73726d6c5f617574686f72736869703a3a4d6f64756c653c543e3a3a73746f726167655f6d657461646174613a3a68663765613765666566616631393237359203423c5b545d206173207061726974795f636f6465633a3a636f6465633a3a456e636f64653e3a3a656e636f64655f746f3a3a68663965633961656539353233393630339303f0013c73726d6c5f7374616b696e673a3a5f5f6c696e6b65645f6d61705f64657461696c735f666f725f6e6f6d696e61746f72735f646f5f6e6f745f7573653a3a456e756d657261746f723c532c3c542061732073726d6c5f73797374656d3a3a54726169743e3a3a4163636f756e7449642c28616c6c6f633a3a7665633a3a5665633c3c542061732073726d6c5f73797374656d3a3a54726169743e3a3a4163636f756e7449643e2c2054293e20617320636f72653a3a697465723a3a7472616974733a3a6974657261746f723a3a4974657261746f723e3a3a6e6578743a3a68663836376561643438393337303834339403b20173726d6c5f7374616b696e673a3a5f494d504c5f4445434f44455f464f525f5f5f4c696e6b616765466f724e6f6d696e61746f7273446f4e6f745573653a3a3c696d706c207061726974795f636f6465633a3a636f6465633a3a4465636f646520666f722073726d6c5f7374616b696e673a3a5f5f4c696e6b616765466f724e6f6d696e61746f7273446f4e6f745573653c4b65793e3e3a3a6465636f64653a3a686566626161663766313061613930656195036a636f72653a3a6f70733a3a66756e6374696f6e3a3a696d706c733a3a3c696d706c20636f72653a3a6f70733a3a66756e6374696f6e3a3a466e4f6e63653c413e20666f7220266d757420463e3a3a63616c6c5f6f6e63653a3a683136363036366137303432666462353096034a73726d6c5f7374616b696e673a3a4d6f64756c653c543e3a3a6164645f7265776172645f706f696e74735f746f5f76616c696461746f723a3a683735656331323130653264613130363497033673726d6c5f73797374656d3a3a4d6f64756c653c543e3a3a6465706f7369745f6c6f673a3a686133343062373339343239343636396698038d0173726d6c5f73797374656d3a3a5f494d504c5f454e434f44455f464f525f4576656e745265636f72643a3a3c696d706c207061726974795f636f6465633a3a636f6465633a3a456e636f646520666f722073726d6c5f73797374656d3a3a4576656e745265636f72643c452c543e3e3a3a656e636f64655f746f3a3a6831383165303465376138323761633563990330636f72653a3a7074723a3a7265616c5f64726f705f696e5f706c6163653a3a68396130643239356566333862333764399a033973726d6c5f73797374656d3a3a4d6f64756c653c543e3a3a63616c6c5f66756e6374696f6e733a3a68626338333337653864313264346236349b033b73726d6c5f73797374656d3a3a4d6f64756c653c543e3a3a73746f726167655f6d657461646174613a3a68386563303065326165306565653331659c03693c73726d6c5f73797374656d3a3a5f5f47657442797465537472756374426c6f636b486173683c543e2061732073726d6c5f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a68356632616561336465623162303632369d036e3c73726d6c5f73797374656d3a3a5f5f4765744279746553747275637452616e646f6d4d6174657269616c3c543e2061732073726d6c5f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a68613438386465323261623362626564359e034473726d6c5f73797374656d3a3a4d6f64756c653c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a68303539396532356662316566326537339f033873726d6c5f737570706f72743a3a73746f726167653a3a756e6861736865643a3a74616b653a3a6837356266613036323466393030326231a0035373725f7072696d6974697665733a3a50657262696c6c3a3a66726f6d5f726174696f6e616c5f617070726f78696d6174696f6e3a3a7b7b636c6f737572657d7d3a3a6837346130386235616561303662323764a1035373725f7072696d6974697665733a3a50657262696c6c3a3a66726f6d5f726174696f6e616c5f617070726f78696d6174696f6e3a3a7b7b636c6f737572657d7d3a3a6865383661363338393838616435346161a2033173726d6c5f636f6e7472616374733a3a657865633a3a7472616e736665723a3a6862663830353466313834383466353839a30330636f72653a3a7074723a3a7265616c5f64726f705f696e5f706c6163653a3a6861666139633866303530303439646130a40386013c73726d6c5f7374616b696e673a3a4d6f64756c653c543e2061732073726d6c5f73657373696f6e3a3a4f6e53657373696f6e456e64696e673c3c542061732073726d6c5f73797374656d3a3a54726169743e3a3a4163636f756e7449643e3e3a3a6f6e5f73657373696f6e5f656e64696e673a3a6832613234666264303663303234333532a5033d73726d6c5f64656d6f63726163793a3a4d6f64756c653c543e3a3a6c61756e63685f65787465726e616c3a3a6833356531373132666666373466393063a6033b73726d6c5f64656d6f63726163793a3a4d6f64756c653c543e3a3a6c61756e63685f7075626c69633a3a6863383234336161666464663737653334a7033d73726d6c5f64656d6f63726163793a3a4d6f64756c653c543e3a3a7265666572656e64756d5f696e666f3a3a6838313864663962306133383239316334a803a9013c73726d6c5f64656d6f63726163793a3a566f74657273466f723c543e2061732073726d6c5f737570706f72743a3a73746f726167653a3a6861736865643a3a67656e657261746f723a3a53746f726167654d61703c7533322c616c6c6f633a3a7665633a3a5665633c3c542061732073726d6c5f73797374656d3a3a54726169743e3a3a4163636f756e7449643e3e3e3a3a6765743a3a6834613163653538373963373732656365a9033573726d6c5f64656d6f63726163793a3a4d6f64756c653c543e3a3a766f74655f6f663a3a6861366663323631343066353861643433aa033d73726d6c5f64656d6f63726163793a3a4d6f64756c653c543e3a3a64656c6567617465645f766f7465733a3a6866636666623734373361373837333534ab033e73726d6c5f64656d6f63726163793a3a4d6f64756c653c543e3a3a636c6561725f7265666572656e64756d3a3a6836633962383630386238383461313433ac03ef013c73726d6c5f64656d6f63726163793a3a446973706174636851756575653c543e2061732073726d6c5f737570706f72743a3a73746f726167653a3a6861736865643a3a67656e657261746f723a3a53746f726167654d61703c3c542061732073726d6c5f73797374656d3a3a54726169743e3a3a426c6f636b4e756d6265722c616c6c6f633a3a7665633a3a5665633c636f72653a3a6f7074696f6e3a3a4f7074696f6e3c283c542061732073726d6c5f64656d6f63726163793a3a54726169743e3a3a50726f706f73616c2c20753332293e3e3e3e3a3a6765743a3a6839623362646538623237313239353830ad0380023c73726d6c5f64656d6f63726163793a3a5f5f6c696e6b65645f6d61705f64657461696c735f666f725f64656c65676174696f6e735f646f5f6e6f745f7573653a3a456e756d657261746f723c532c3c542061732073726d6c5f73797374656d3a3a54726169743e3a3a4163636f756e7449642c28283c542061732073726d6c5f73797374656d3a3a54726169743e3a3a4163636f756e7449642c2073726d6c5f64656d6f63726163793a3a436f6e76696374696f6e292c2054293e20617320636f72653a3a697465723a3a7472616974733a3a6974657261746f723a3a4974657261746f723e3a3a6e6578743a3a6830376136373464663562323934383331ae03d0023c73726d6c5f7374616b696e673a3a5f5f6c696e6b65645f6d61705f64657461696c735f666f725f76616c696461746f72735f646f5f6e6f745f7573653a3a456e756d657261746f723c532c3c542061732073726d6c5f73797374656d3a3a54726169743e3a3a4163636f756e7449642c2873726d6c5f7374616b696e673a3a56616c696461746f7250726566733c3c3c542061732073726d6c5f7374616b696e673a3a54726169743e3a3a43757272656e63792061732073726d6c5f737570706f72743a3a7472616974733a3a43757272656e63793c3c542061732073726d6c5f73797374656d3a3a54726169743e3a3a4163636f756e7449643e3e3a3a42616c616e63653e2c2054293e20617320636f72653a3a697465723a3a7472616974733a3a6974657261746f723a3a4974657261746f723e3a3a6e6578743a3a6833316131666565343761333837613666af036f7061726974795f636f6465633a3a636f6465633a3a696e6e65725f7475706c655f696d706c3a3a3c696d706c207061726974795f636f6465633a3a636f6465633a3a4465636f646520666f7220284a2c204b293e3a3a6465636f64653a3a6865656561636265623434343731336162b0033973726d6c5f626162653a3a4d6f64756c653c543e3a3a73746f726167655f6d657461646174613a3a6831613733373937373165363531313763b103683c73726d6c5f626162653a3a5f5f4765744279746553747275637452616e646f6d6e6573733c543e2061732073726d6c5f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6830313132633334653937373838386530b2034273726d6c5f626162653a3a4d6f64756c653c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a6864653837393762623036323933663036b30397013c73726d6c5f626162653a3a4d6f64756c653c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a4578706563746564426c6f636b54696d6544656661756c74427974654765747465723c543e2061732073726d6c5f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6837636434663762376361666466653533b40393013c73726d6c5f626162653a3a4d6f64756c653c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a45706f63684475726174696f6e44656661756c74427974654765747465723c543e2061732073726d6c5f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6861633339313932336630646561303562b5033f73726d6c5f64656d6f63726163793a3a4d6f64756c653c543e3a3a696e6a6563745f7265666572656e64756d3a3a6864336565376466366531343632366162b6033873726d6c5f64656d6f63726163793a3a4d6f64756c653c543e3a3a6465706f7369745f6f663a3a6837626664333464323134343062343535b7033c73726d6c5f64656d6f63726163793a3a4d6f64756c653c543e3a3a63616c6c5f66756e6374696f6e733a3a6839623865373439303362613166616237b8033e73726d6c5f64656d6f63726163793a3a4d6f64756c653c543e3a3a73746f726167655f6d657461646174613a3a6866646263633263346636383265306163b9036f3c73726d6c5f64656d6f63726163793a3a5f5f476574427974655374727563744e65787445787465726e616c3c543e2061732073726d6c5f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6836376437386435646631303632323731ba036e3c73726d6c5f64656d6f63726163793a3a5f5f4765744279746553747275637444656c65676174696f6e733c543e2061732073726d6c5f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6834323930336365663137353532346361bb03703c73726d6c5f64656d6f63726163793a3a5f5f47657442797465537472756374446973706174636851756575653c543e2061732073726d6c5f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6835646562366164353830366265346539bc034773726d6c5f64656d6f63726163793a3a4d6f64756c653c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a6865333836303831323234393138383538bd0398013c73726d6c5f64656d6f63726163793a3a4d6f64756c653c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a436f6f6c6f6666506572696f6444656661756c74427974654765747465723c543e2061732073726d6c5f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6830623839323664386236623263313030be03a0013c73726d6c5f64656d6f63726163793a3a4d6f64756c653c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a456d657267656e6379566f74696e67506572696f6444656661756c74427974654765747465723c543e2061732073726d6c5f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6864643936336531386630643539383861bf0399013c73726d6c5f64656d6f63726163793a3a4d6f64756c653c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a4d696e696d756d4465706f73697444656661756c74427974654765747465723c543e2061732073726d6c5f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6839633266363034646662653561616232c00397013c73726d6c5f64656d6f63726163793a3a4d6f64756c653c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a4c61756e6368506572696f6444656661756c74427974654765747465723c543e2061732073726d6c5f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6837393135616137323139326261653861c103443c6e6f64655f72756e74696d653a3a43616c6c20617320636f72653a3a636c6f6e653a3a436c6f6e653e3a3a636c6f6e653a3a6836386536643931613539313934623031c203483c552061732073726d6c5f737570706f72743a3a73746f726167653a3a53746f726167654d61703c4b2c563e3e3a3a696e736572743a3a6835323464656336313866386533363731c303b5013c73726d6c5f64656d6f63726163793a3a50726f78793c543e2061732073726d6c5f737570706f72743a3a73746f726167653a3a6861736865643a3a67656e657261746f723a3a53746f726167654d61703c3c542061732073726d6c5f73797374656d3a3a54726169743e3a3a4163636f756e7449642c3c542061732073726d6c5f73797374656d3a3a54726169743e3a3a4163636f756e7449643e3e3a3a6765743a3a6831633631616464346133306331626537c4033573726d6c5f64656d6f63726163793a3a4d6f64756c653c543e3a3a646f5f766f74653a3a6862373137353137303439343332326261c503ef013c73726d6c5f64656d6f63726163793a3a426c61636b6c6973743c543e2061732073726d6c5f737570706f72743a3a73746f726167653a3a6861736865643a3a67656e657261746f723a3a53746f726167654d61703c3c542061732073726d6c5f73797374656d3a3a54726169743e3a3a486173682c283c542061732073726d6c5f73797374656d3a3a54726169743e3a3a426c6f636b4e756d6265722c20616c6c6f633a3a7665633a3a5665633c3c542061732073726d6c5f73797374656d3a3a54726169743e3a3a4163636f756e7449643e293e3e3a3a6765743a3a6865393534653832303430646532383064c603b50173726d6c5f7374616b696e673a3a5f494d504c5f454e434f44455f464f525f5f5f4c696e6b616765466f724e6f6d696e61746f7273446f4e6f745573653a3a3c696d706c207061726974795f636f6465633a3a636f6465633a3a456e636f646520666f722073726d6c5f7374616b696e673a3a5f5f4c696e6b616765466f724e6f6d696e61746f7273446f4e6f745573653c4b65793e3e3a3a656e636f64655f746f3a3a6833393463653862336266643631386531c7033d7061726974795f636f6465633a3a636f6465633a3a456e636f64653a3a7573696e675f656e636f6465643a3a6832623333333738623965336532616637c8033d7061726974795f636f6465633a3a636f6465633a3a456e636f64653a3a7573696e675f656e636f6465643a3a6836386433646164383736643865623336c903483c552061732073726d6c5f737570706f72743a3a73746f726167653a3a53746f726167654d61703c4b2c563e3e3a3a72656d6f76653a3a6862633938373830303863333662653266ca03483c552061732073726d6c5f737570706f72743a3a73746f726167653a3a53746f726167654d61703c4b2c563e3e3a3a72656d6f76653a3a6837623837323939626164376666626165cb033a73726d6c5f7374616b696e673a3a4d6f64756c653c543e3a3a63616c6c5f66756e6374696f6e733a3a6831303835663934326165613066666435cc033c73726d6c5f7374616b696e673a3a4d6f64756c653c543e3a3a73746f726167655f6d657461646174613a3a6831653964613665663737636163653537cd03723c73726d6c5f7374616b696e673a3a5f5f4765744279746553747275637443757272656e74457261526577617264733c543e2061732073726d6c5f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6864616431343838363463326230643566ce03703c73726d6c5f7374616b696e673a3a5f5f4765744279746553747275637443757272656e7445726153746172743c543e2061732073726d6c5f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6832353861326566303936323932613339cf03683c73726d6c5f7374616b696e673a3a5f5f476574427974655374727563745374616b6572733c543e2061732073726d6c5f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6833393533663133633365306439616438d0036b3c73726d6c5f7374616b696e673a3a5f5f4765744279746553747275637456616c696461746f72733c543e2061732073726d6c5f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6834303432353238653931353637613536d1036d3c73726d6c5f7374616b696e673a3a5f5f476574427974655374727563744f66666c696e65536c6173683c543e2061732073726d6c5f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6835376230323932323131336530373366d203763c73726d6c5f7374616b696e673a3a5f5f476574427974655374727563744d696e696d756d56616c696461746f72436f756e743c543e2061732073726d6c5f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6832393237623461376534303233303233d3039e0173726d6c5f7374616b696e673a3a5f494d504c5f4445434f44455f464f525f5374616b696e674c65646765723a3a3c696d706c207061726974795f636f6465633a3a636f6465633a3a4465636f646520666f722073726d6c5f7374616b696e673a3a5374616b696e674c65646765723c4163636f756e7449642c42616c616e63653e3e3a3a6465636f64653a3a6837393139373261393137633237353836d4034573726d6c5f7374616b696e673a3a4d6f64756c653c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a6831326164313066663466363966303438d50398013c73726d6c5f7374616b696e673a3a4d6f64756c653c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a426f6e64696e674475726174696f6e44656661756c74427974654765747465723c543e2061732073726d6c5f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6836366661303833353962306264623630d6033773726d6c5f7374616b696e673a3a4d6f64756c653c543e3a3a6d616b655f7061796f75743a3a6836633933613435616433323637343635d70344636f72653a3a697465723a3a7472616974733a3a6974657261746f723a3a4974657261746f723a3a73697a655f68696e743a3a6832663966333337663331346430346261d8033973726d6c5f7374616b696e673a3a4d6f64756c653c543e3a3a7570646174655f6c65646765723a3a6835323066333937386264646232376661d90330636f72653a3a7074723a3a7265616c5f64726f705f696e5f706c6163653a3a6832383162643565356463633363633865da033e636f72653a3a697465723a3a7472616974733a3a6974657261746f723a3a4974657261746f723a3a6e74683a3a6862653062383765616639383834363763db0334636f72653a3a736c6963653a3a736f72743a3a627265616b5f7061747465726e733a3a6836316630353339376265346165306436dc032e636f72653a3a736c6963653a3a736f72743a3a68656170736f72743a3a6865656163363335353030636638613332dd033c636f72653a3a736c6963653a3a736f72743a3a7061727469616c5f696e73657274696f6e5f736f72743a3a6861386333323331343935333633336265de03683c7061726974795f7761736d3a3a656c656d656e74733a3a6f70733a3a496e697445787072206173207061726974795f7761736d3a3a656c656d656e74733a3a53657269616c697a653e3a3a73657269616c697a653a3a6832326536303831316239376361613731df036b3c7061726974795f7761736d3a3a656c656d656e74733a3a6f70733a3a496e737472756374696f6e206173207061726974795f7761736d3a3a656c656d656e74733a3a53657269616c697a653e3a3a73657269616c697a653a3a6833313464396364336663323362303032e0037d3c7061726974795f7761736d3a3a656c656d656e74733a3a7072696d6974697665733a3a436f756e7465644c6973745772697465723c492c543e206173207061726974795f7761736d3a3a656c656d656e74733a3a53657269616c697a653e3a3a73657269616c697a653a3a6838343235363463313864343366306565e1036f3c7061726974795f7761736d3a3a656c656d656e74733a3a7072696d6974697665733a3a566172496e743332206173207061726974795f7761736d3a3a656c656d656e74733a3a53657269616c697a653e3a3a73657269616c697a653a3a6834653832343164633166393264306465e2036f3c7061726974795f7761736d3a3a656c656d656e74733a3a7072696d6974697665733a3a566172496e743634206173207061726974795f7761736d3a3a656c656d656e74733a3a53657269616c697a653e3a3a73657269616c697a653a3a6831366430333464363864636137656264e3036c3c7061726974795f7761736d3a3a656c656d656e74733a3a6f70733a3a496e697445787072206173207061726974795f7761736d3a3a656c656d656e74733a3a446573657269616c697a653e3a3a646573657269616c697a653a3a6830336336396535656266353063313036e4036f3c7061726974795f7761736d3a3a656c656d656e74733a3a6f70733a3a496e737472756374696f6e206173207061726974795f7761736d3a3a656c656d656e74733a3a446573657269616c697a653e3a3a646573657269616c697a653a3a6862626263366232363139386264373031e503443c7061726974795f7761736d3a3a696f3a3a4572726f7220617320636f72653a3a666d743a3a44656275673e3a3a666d743a3a6839313834613132386161616566393339e60325616c6c6f633a3a666d743a3a666f726d61743a3a6830316632616438366163393537313166e703793c7061726974795f7761736d3a3a656c656d656e74733a3a7072696d6974697665733a3a436f756e7465644c6973743c543e206173207061726974795f7761736d3a3a656c656d656e74733a3a446573657269616c697a653e3a3a646573657269616c697a653a3a6863326538613330646462656461613462e8036b3c7061726974795f7761736d3a3a656c656d656e74733a3a6f70733a3a496e737472756374696f6e206173207061726974795f7761736d3a3a656c656d656e74733a3a53657269616c697a653e3a3a73657269616c697a653a3a6832306434326237363961666331303963e9032c636f72653a3a666d743a3a466f726d61747465723a3a7061643a3a6861366438393436643533653864653566ea03713c7061726974795f7761736d3a3a656c656d656e74733a3a696e6465785f6d61703a3a496e6465784d61703c543e206173207061726974795f7761736d3a3a656c656d656e74733a3a53657269616c697a653e3a3a73657269616c697a653a3a6830313964323733313537306237653565eb03783c7061726974795f7761736d3a3a656c656d656e74733a3a696d706f72745f656e7472793a3a526573697a61626c654c696d697473206173207061726974795f7761736d3a3a656c656d656e74733a3a53657269616c697a653e3a3a73657269616c697a653a3a6866313935616364666237303034356435ec037c3c7061726974795f7761736d3a3a656c656d656e74733a3a696d706f72745f656e7472793a3a526573697a61626c654c696d697473206173207061726974795f7761736d3a3a656c656d656e74733a3a446573657269616c697a653e3a3a646573657269616c697a653a3a6862376632633030343763366262323131ed0382017061726974795f7761736d3a3a656c656d656e74733a3a7072696d6974697665733a3a3c696d706c207061726974795f7761736d3a3a656c656d656e74733a3a53657269616c697a6520666f7220616c6c6f633a3a737472696e673a3a537472696e673e3a3a73657269616c697a653a3a6863303933363734393566363861636234ee0386017061726974795f7761736d3a3a656c656d656e74733a3a7072696d6974697665733a3a3c696d706c207061726974795f7761736d3a3a656c656d656e74733a3a446573657269616c697a6520666f7220616c6c6f633a3a737472696e673a3a537472696e673e3a3a646573657269616c697a653a3a6836326535643235666332313139663161ef03323c265420617320636f72653a3a666d743a3a446973706c61793e3a3a666d743a3a6835353664376238663535366263363963f003743c7061726974795f7761736d3a3a656c656d656e74733a3a7072696d6974697665733a3a56617255696e743332206173207061726974795f7761736d3a3a656c656d656e74733a3a446573657269616c697a653e3a3a646573657269616c697a653a3a6839666632356462616530336539636139f103713c7061726974795f7761736d3a3a656c656d656e74733a3a73656374696f6e3a3a437573746f6d53656374696f6e206173207061726974795f7761736d3a3a656c656d656e74733a3a53657269616c697a653e3a3a73657269616c697a653a3a6866386261353830386362663033336237f2036f3c7061726974795f7761736d3a3a656c656d656e74733a3a73656374696f6e3a3a53656374696f6e206173207061726974795f7761736d3a3a656c656d656e74733a3a446573657269616c697a653e3a3a646573657269616c697a653a3a6831383061393939346363313364656166f303457061726974795f7761736d3a3a656c656d656e74733a3a73656374696f6e3a3a53656374696f6e5265616465723a3a6e65773a3a6833343661393063316433323836303565f4034e636f72653a3a666d743a3a6e756d3a3a696d703a3a3c696d706c20636f72653a3a666d743a3a446973706c617920666f72207533323e3a3a666d743a3a6838636363623736663163326366313235f503397761736d695f76616c69646174696f6e3a3a76616c69646174655f6d656d6f72795f747970653a3a6834616434666439623033616666656132f603347761736d695f76616c69646174696f6e3a3a657870725f636f6e73745f747970653a3a6833376565666538356536656134653533f703553c7061726974795f7761736d3a3a656c656d656e74733a3a74797065733a3a56616c75655479706520617320636f72653a3a666d743a3a44656275673e3a3a666d743a3a6837663965313062313761383235343565f8034a7761736d695f76616c69646174696f6e3a3a66756e633a3a46756e6374696f6e56616c69646174696f6e436f6e746578743a3a737465703a3a6834383364653935633161363461363563f903473c7761736d695f76616c69646174696f6e3a3a4572726f7220617320636f72653a3a666d743a3a446973706c61793e3a3a666d743a3a6832643737393163616533616639343330fa03303c265420617320636f72653a3a666d743a3a44656275673e3a3a666d743a3a6839343166666162333261613238643834fb03416861736862726f776e3a3a7261773a3a5261775461626c653c543e3a3a7472795f776974685f63617061636974793a3a6839316131643832316165666561623462fc033e6861736862726f776e3a3a7261773a3a5261775461626c653c543e3a3a726573657276655f7265686173683a3a6866376632653563623862643162646665fd03457061726974795f7761736d3a3a656c656d656e74733a3a7365676d656e743a3a446174615365676d656e743a3a76616c75653a3a6866646634393463363530663965333032fe0337616c6c6f633a3a7261775f7665633a3a5261775665633c542c413e3a3a726573657276653a3a6836636266366564636435643764353661ff033b636f72653a3a736c6963653a3a3c696d706c205b545d3e3a3a636f70795f66726f6d5f736c6963653a3a68656134643838343239623565386631648004347761736d695f76616c69646174696f6e3a3a66756e633a3a706f705f76616c75653a3a68333962623464666565633865336163668104347761736d695f76616c69646174696f6e3a3a66756e633a3a706f705f6c6162656c3a3a68306265623663623063666264383362368204407761736d695f76616c69646174696f6e3a3a7574696c3a3a4c6f63616c733a3a747970655f6f665f6c6f63616c3a3a68303962316539316364663361323835638304543c7761736d695f76616c69646174696f6e3a3a66756e633a3a537461636b56616c75655479706520617320636f72653a3a666d743a3a44656275673e3a3a666d743a3a68353262373862613035393164313065378404537761736d695f76616c69646174696f6e3a3a66756e633a3a46756e6374696f6e56616c69646174696f6e436f6e746578743a3a76616c69646174655f6c6f61643a3a68643631653439363063383835366639338504547761736d695f76616c69646174696f6e3a3a66756e633a3a46756e6374696f6e56616c69646174696f6e436f6e746578743a3a76616c69646174655f73746f72653a3a68366264383738653965643435643134308604557761736d695f76616c69646174696f6e3a3a66756e633a3a46756e6374696f6e56616c69646174696f6e436f6e746578743a3a76616c69646174655f746573746f703a3a68656263623265346236356235623331398704547761736d695f76616c69646174696f6e3a3a66756e633a3a46756e6374696f6e56616c69646174696f6e436f6e746578743a3a76616c69646174655f72656c6f703a3a68313065643039346235616632313966358804537761736d695f76616c69646174696f6e3a3a66756e633a3a46756e6374696f6e56616c69646174696f6e436f6e746578743a3a76616c69646174655f756e6f703a3a68633437663530396438376362323431338904547761736d695f76616c69646174696f6e3a3a66756e633a3a46756e6374696f6e56616c69646174696f6e436f6e746578743a3a76616c69646174655f62696e6f703a3a68623338343266346139323966303364388a04547761736d695f76616c69646174696f6e3a3a66756e633a3a46756e6374696f6e56616c69646174696f6e436f6e746578743a3a76616c69646174655f6376746f703a3a68613836306461386336626537623066638b04553c7061726974795f7761736d3a3a656c656d656e74733a3a74797065733a3a426c6f636b5479706520617320636f72653a3a666d743a3a44656275673e3a3a666d743a3a68626334663039353163653636626333668c0439636f72653a3a666d743a3a6275696c646572733a3a44656275675475706c653a3a6669656c643a3a68386332653034306164313637313634348d0430636f72653a3a7074723a3a7265616c5f64726f705f696e5f706c6163653a3a68383833663961613434376433663434308e04303c265420617320636f72653a3a666d743a3a44656275673e3a3a666d743a3a68306562333530386131623964616565388f04303c265420617320636f72653a3a666d743a3a44656275673e3a3a666d743a3a68656636633035343338663334333237369004453c616c6c6f633a3a737472696e673a3a537472696e6720617320636f72653a3a666d743a3a446973706c61793e3a3a666d743a3a6830656338366664346535303535646566910423636f72653a3a666d743a3a77726974653a3a683263633535663738336132376161303292044c3c7761736d695f76616c69646174696f6e3a3a737461636b3a3a4572726f7220617320636f72653a3a666d743a3a44656275673e3a3a666d743a3a68376434363565363939343931383362339304553c7061726974795f7761736d3a3a656c656d656e74733a3a6f70733a3a496e737472756374696f6e20617320636f72653a3a666d743a3a44656275673e3a3a666d743a3a68343430663131396233306364383366329404303c265420617320636f72653a3a666d743a3a44656275673e3a3a666d743a3a683438373734633565333934323833323495043a636f72653a3a666d743a3a6275696c646572733a3a44656275675374727563743a3a6669656c643a3a6866326565303137626435353664666261960441707761736d5f7574696c733a3a737461636b5f6865696768743a3a6d61785f6865696768743a3a636f6d707574653a3a686535663861303461646332383866313297045a3c707761736d5f7574696c733a3a737461636b5f6865696768743a3a6d61785f6865696768743a3a4672616d6520617320636f72653a3a666d743a3a44656275673e3a3a666d743a3a6835626662636630363963393830393335980446707761736d5f7574696c733a3a737461636b5f6865696768743a3a6d61785f6865696768743a3a537461636b3a3a6672616d653a3a68646534363765613166633434376439399904453c636f72653a3a6f7074696f6e3a3a4f7074696f6e3c543e20617320636f72653a3a666d743a3a44656275673e3a3a666d743a3a68623165623465333239306362663264349a044b707761736d5f7574696c733a3a737461636b5f6865696768743a3a6d61785f6865696768743a3a537461636b3a3a706f705f76616c7565733a3a68393230303336623534326131353238309b043f707761736d5f7574696c733a3a737461636b5f6865696768743a3a7265736f6c76655f66756e635f747970653a3a68336130383337643331383738633936629c0433636f72653a3a6f7074696f6e3a3a4f7074696f6e3c26543e3a3a636c6f6e65643a3a68373433326438386565653331353766649d04533c616c6c6f633a3a7665633a3a5665633c543e20617320616c6c6f633a3a7665633a3a53706563457874656e643c542c493e3e3a3a737065635f657874656e643a3a68643630376234663532626135343434669e04323c265420617320636f72653a3a666d743a3a446973706c61793e3a3a666d743a3a68643466343861626239346363326466629f04613c616c6c6f633a3a636f6c6c656374696f6e733a3a62747265653a3a6d61703a3a42547265654d61703c4b2c563e20617320636f72653a3a6f70733a3a64726f703a3a44726f703e3a3a64726f703a3a6831326332376662386135316161323330a004303c265420617320636f72653a3a666d743a3a44656275673e3a3a666d743a3a6830376435323632303134396236393730a10430636f72653a3a7074723a3a7265616c5f64726f705f696e5f706c6163653a3a6830383334383934613965313131343030a204303c265420617320636f72653a3a666d743a3a44656275673e3a3a666d743a3a6838393930636134353936346432353538a304303c265420617320636f72653a3a666d743a3a44656275673e3a3a666d743a3a6864303639363464626265306635333034a404463c616c6c6f633a3a7665633a3a5665633c543e20617320636f72653a3a6f70733a3a64726f703a3a44726f703e3a3a64726f703a3a6833363230363132373936373366363831a504303c265420617320636f72653a3a666d743a3a44656275673e3a3a666d743a3a6837666638363233383562363432343436a604303c265420617320636f72653a3a666d743a3a44656275673e3a3a666d743a3a6838306664323863366234313432386138a704303c265420617320636f72653a3a666d743a3a44656275673e3a3a666d743a3a6862333333346337346662323765343063a804383c6c6f673a3a4e6f704c6f67676572206173206c6f673a3a4c6f673e3a3a656e61626c65643a3a6862356632376432643432633533313963a904343c6c6f673a3a4e6f704c6f67676572206173206c6f673a3a4c6f673e3a3a6c6f673a3a6864333732633038613461626365636263aa04363c6c6f673a3a4e6f704c6f67676572206173206c6f673a3a4c6f673e3a3a666c7573683a3a6835653133333330613631633430366531ab0411727573745f626567696e5f756e77696e64ac044e73725f696f3a3a696d703a3a6578743a3a65787465726e5f66756e6374696f6e735f686f73745f696d706c3a3a6578745f7072696e745f757466383a3a6863343839343937333162663664613538ad04423c5b545d206173207061726974795f636f6465633a3a636f6465633a3a456e636f64653e3a3a656e636f64655f746f3a3a6864646337663435393064333731386164ae04960173726d6c5f6d657461646174613a3a5f494d504c5f454e434f44455f464f525f53746f72616765456e747279547970653a3a3c696d706c207061726974795f636f6465633a3a636f6465633a3a456e636f646520666f722073726d6c5f6d657461646174613a3a53746f72616765456e747279547970653e3a3a656e636f64655f746f3a3a6861633536353632656363626263383462af04623c73726d6c5f6d657461646174613a3a4465636f6465446966666572656e743c422c4f3e206173207061726974795f636f6465633a3a636f6465633a3a456e636f64653e3a3a656e636f64655f746f3a3a6834626364303631653731303631316333b004623c73726d6c5f6d657461646174613a3a4465636f6465446966666572656e743c422c4f3e206173207061726974795f636f6465633a3a636f6465633a3a456e636f64653e3a3a656e636f64655f746f3a3a6833646134366334313938313066326233b1040a5f5f72675f616c6c6f63b2040c5f5f72675f6465616c6c6f63b3040c5f5f72675f7265616c6c6f63b404115f5f72675f616c6c6f635f7a65726f6564b5043a3c266d7574205720617320636f72653a3a666d743a3a57726974653e3a3a77726974655f7374723a3a6839386630383364646366336530643539b6043b3c266d7574205720617320636f72653a3a666d743a3a57726974653e3a3a77726974655f636861723a3a6861623731346430333235303038653933b7043a3c266d7574205720617320636f72653a3a666d743a3a57726974653e3a3a77726974655f666d743a3a6838356462616235393333346166386562b804313c5420617320636f72653a3a616e793a3a416e793e3a3a747970655f69643a3a6838373362326233636138386434383161b90443636f72653a3a666d743a3a466f726d61747465723a3a7061645f696e74656772616c3a3a77726974655f7072656669783a3a6866353332373965323066353236636366ba042e636f72653a3a7374723a3a736c6963655f6572726f725f6661696c3a3a6865653139323635326330646133653662bb044a3c636f72653a3a6f70733a3a72616e67653a3a52616e67653c4964783e20617320636f72653a3a666d743a3a44656275673e3a3a666d743a3a6831353934666636313964313766353962bc04323c6368617220617320636f72653a3a666d743a3a44656275673e3a3a666d743a3a6837663466306566323134623135303866bd043d636f72653a3a756e69636f64653a3a626f6f6c5f747269653a3a426f6f6c547269653a3a6c6f6f6b75703a3a6833333765663538373237613238613566be044e636f72653a3a666d743a3a6e756d3a3a3c696d706c20636f72653a3a666d743a3a446562756720666f72207573697a653e3a3a666d743a3a68636238383338633162646231306235612e32343337bf0434636f72653a3a666d743a3a417267756d656e7456313a3a73686f775f7573697a653a3a6834343432343361643936333761656136c004453c636f72653a3a63656c6c3a3a426f72726f774572726f7220617320636f72653a3a666d743a3a44656275673e3a3a666d743a3a6839663861393035663061343166626565c104483c636f72653a3a63656c6c3a3a426f72726f774d75744572726f7220617320636f72653a3a666d743a3a44656275673e3a3a666d743a3a6833623163616232626333636335643662c204303c265420617320636f72653a3a666d743a3a44656275673e3a3a666d743a3a6837306365383064366362336331373736c3042e636f72653a3a736c6963653a3a6d656d6368723a3a6d656d6368723a3a6834653434386337323966353035343930c4048001636f72653a3a7374723a3a7472616974733a3a3c696d706c20636f72653a3a736c6963653a3a536c696365496e6465783c7374723e20666f7220636f72653a3a6f70733a3a72616e67653a3a52616e67653c7573697a653e3e3a3a696e6465783a3a7b7b636c6f737572657d7d3a3a6865376338616134366434653933636435c504533c636f72653a3a666d743a3a6275696c646572733a3a5061644164617074657220617320636f72653a3a666d743a3a57726974653e3a3a77726974655f7374723a3a6831303966653662636331366463343332c60430636f72653a3a7074723a3a7265616c5f64726f705f696e5f706c6163653a3a6863616233653737643232336562623862c7042f636f72653a3a666d743a3a57726974653a3a77726974655f636861723a3a6866353335666333343735643839373963c8042e636f72653a3a666d743a3a57726974653a3a77726974655f666d743a3a6838396132343964633663626538643835c9043a3c266d7574205720617320636f72653a3a666d743a3a57726974653e3a3a77726974655f7374723a3a6839643838613837643735393063376538ca043b3c266d7574205720617320636f72653a3a666d743a3a57726974653e3a3a77726974655f636861723a3a6863626539656365346539623261666163cb043a3c266d7574205720617320636f72653a3a666d743a3a57726974653e3a3a77726974655f666d743a3a6836383566373362343736636232376133cc043e3c636f72653a3a666d743a3a4572726f7220617320636f72653a3a666d743a3a44656275673e3a3a666d743a3a6863616638613466613733323737393335cd04066d656d736574ce04066d656d637079cf04076d656d6d6f7665d004066d656d636d70d104095f5f6173686c746933d204095f5f6c736872746933d304085f5f6d756c746933d404095f5f75646976746933d504095f5f756d6f64746933d6040c5f5f756469766d6f64746934005f0970726f64756365727302086c616e677561676502045275737400045275737404323031380c70726f6365737365642d62790105727573746325312e33382e302d6e696768746c79202863373938646666616320323031392d30372d323729", - "0x3ae31af9a378162eb2736f26855c9ad8": "0x4545454545454545454545454545454545454545454545454545454545454545", - "0x1ba14d232d3c301a93e35f55e3d7aef2d98dbb9cc0ce48f457b81b421e0f704d": "0x0000c16ff28623000000000000000000", - "0xf14d23a9d4492a1efc9194e257b3c3d9": "0x00000000", - "0x90e2849b965314409e8bc00011f3004f": "0x04000000", - "0xeecb67c20ca6cc8ba4d4434687f61309": "0x109becad03e6dcac03cee07edebca5475314861492cdfc96a2144a67bbe969933201000000000000007932cff431e748892fa48e10c63c17d30f80ca42e4de3921e641249cd7fa3c2f01000000000000005633b70b80a6c8bb16270f82cca6d56b27ed7b76c8fd5af2986a25a4788ce44001000000000000003919132b851ef0fd2dae42a7e734fe547af5a6b809006100f48944d7fae8e8ef0100000000000000", - "0x50a63a871aced22e88ee6466fe5aa5d9": "0x9ee5e5bdc0ec239eb164f865ecc345ce4c88e76ee002e0f7e318097347471809", - "0x686f6c72b7b80bad8dba022335cb7c9e4556ac7ea200008da8046e3178eb89c1": "0x0f0000c16ff286230f0000c16ff2862300", - "0x8f9a319405d14f3953657373696f6e204b65794f776e6572343a73657373696f6e3a6b657973f409469434914add1f77b486e5d845d79fb97e50667a4fd4066fc59fc02b72ff": "0x9c7a2ee14e565db0c69f78c7b4cd839fbf52b607d867e9e9c5a79042898a0d12", - "0x637414312dac3b280120bf15b4f66cee": "0x00000000", - "0xfd0cbba69a04d769ddcdbb15f5123c98041978f5241f33f78f62b48e3a02b740": "0x047374616b696e67200000c16ff28623000000000000000000ffffffffffffffff0e", - "0x78f4ad73d6b7279f8d06f359e363c829": "0x0000a49d8fc957363600000000000000", - "0x92f53c21a80e624b3c606bc8ec0ce2a3003c4fe385bed33998bf4dc79b8970f2": "0x547ff0ab649283a7ae01dbc2eb73932eba2fb09075e9485ff369082a2ff38d650f0000c16ff286230f0000c16ff2862300", - "0x77eef9fb1f954bfb3bbe274f703f6d00": "0x00000000", - "0x3a65787472696e7369635f696e646578": "0x00000000", - "0x8f9a319405d14f3953657373696f6e204b65794f776e6572343a73657373696f6e3a6b657973424b9d3c8374bdf058222242204c46ade91b3190a50218823d53e9814b9557f0": "0x9c7a2ee14e565db0c69f78c7b4cd839fbf52b607d867e9e9c5a79042898a0d12", - "0x8cb577756012d928f17362e0741f9f2c": "0x0100000000000000", - "0x775f52f99da6e72a0984c26ae28fbfcd": "0x0000000000000000", - "0xccea67b51b4fa33ecbff70a8977ad91d9c60d620f3ab5ac9626dea15cde023b7": "0x0f0000c16ff286230f0000c16ff2862300", - "0x3a686561707061676573": "0x0800000000000000", - "0xc1fdc3d212357bc2fa98f2a77b941f0c": "0x10f26cdb14b5aec7b2789fd5ca80f979cef3761897ae1f37ffb3e154cbcc1c2663547ff0ab649283a7ae01dbc2eb73932eba2fb09075e9485ff369082a2ff38d6568655684472b743e456907b398d3a44c113f189e56d1bbfd55e889e295dfde789c7a2ee14e565db0c69f78c7b4cd839fbf52b607d867e9e9c5a79042898a0d12", - "0x68c8d2f39c4605e65218c22c5664917047e4900c797b7dd33999d94213c75049": "0x047374616b696e67200000c16ff28623000000000000000000ffffffffffffffff0e", - "0x52b963fbdb3d6e1b03808fc20071f07f": "0x0027060000000000", - "0x886726f904d8372fdabb7707870c2fad": "0x106e7e4eb42cbd2e0ab4cae8708ce5509580b8c04d11f6758dbf686d50fe9f91060100000000000000482dbd7297a39fa145c570552249c2ca9dd47e281f0c500c971b59c9dcdcd82e0100000000000000482a3389a6cf42d8ed83888cfd920fec738ea30f97e44699ada7323f08c3380a010000000000000000299981a2b92f878baaf5dbeba5c18d4e70f2a1fcd9c61b32ea18daf38f43780100000000000000", - "0xa8e78ad25e03ac0281ec709fd3f128efb7e112239d0a7c3e1c86375109bff334": "0x4545454545454545454545454545454545454545454545454545454545454545", - "0xc1bc13c775b3406279618b05c28523cb": "0x00", - "0x0c41b62474c49057a4476d0b96853c6d44e9c86c5fa130b0da3831c5eef546a0": "0x00", - "0xbf18c0c65fb39f32ee7c8016685c0a6056f8f924192efb2655be9a692d0b03b6": "0x00", - "0xd368b9d9bb1cc910c9a2b8e5d0f5f2fc": "0x0000c16ff28623000000000000000000", - "0xe026dd082e3158e72eb7c985fc8bac4f": "0x4038000000000000", - "0xbde3e43a2a348359d103d64bc95928146bdd9ae3490e26da38d2e4d19c137507": "0x0000a0dec5adc9353600000000000000", - "0x4664fb5d4e16f894df23cadb3faaa9a6": "0x04000000", - "0x8f9a319405d14f3953657373696f6e204b65794f776e6572343a73657373696f6e3a6b6579732a2afb49dfe38fc8b2b25f22f4b0d6acccac7d6d1b5fa7cd3852ad4dfabbcb6f": "0x547ff0ab649283a7ae01dbc2eb73932eba2fb09075e9485ff369082a2ff38d65", - "0xf4adb4c4f708c4b753657373696f6e204e6578744b657973343a73657373696f6e3a6b657973711590f60a214f6f06502eb29dd14f55aa04e72e2fa12c098ba4fa5a00c57fa9": "0x7932cff431e748892fa48e10c63c17d30f80ca42e4de3921e641249cd7fa3c2f482dbd7297a39fa145c570552249c2ca9dd47e281f0c500c971b59c9dcdcd82e", - "0x040ff70c23416b89ce6afb75ee0d362e": "0x00000000", - "0xa5e869ecc1b914a6b0cf5f02b874f5eb90f1739fbd3edd01e5835d1517fd9f72": "0x781ead1e2fa9ccb74b44c19d29cb2a7a4b5be3972927ae98cd3877523976a276", - "0xf7327f83450f4e54b29a411237312742": "0x00", - "0x7e6064dc0e78ffebb59b3053826a9467": "0x109c7a2ee14e565db0c69f78c7b4cd839fbf52b607d867e9e9c5a79042898a0d1268655684472b743e456907b398d3a44c113f189e56d1bbfd55e889e295dfde78547ff0ab649283a7ae01dbc2eb73932eba2fb09075e9485ff369082a2ff38d65f26cdb14b5aec7b2789fd5ca80f979cef3761897ae1f37ffb3e154cbcc1c2663", - "0x717a2ee9c64ad3424e10e4461ec08296": "0x0000000001000000000000000100000000000000010000000000000001000000000000000100000000000000010000000000000001000000000000008700000000000000af0000000000000001000000000000000100000000000000040000000000010010000000004000000020000000", - "0xf186665804ca50670311307912458ce448d82cb96e7e4fe71df38c283a8720f4": "0x9c7a2ee14e565db0c69f78c7b4cd839fbf52b607d867e9e9c5a79042898a0d120f0000c16ff286230f0000c16ff2862300", - "0x6e4ab2ac5a7cf9b1829eacc84a75bde0804be01fc31c9419ea72407f50a33384": "0xf26cdb14b5aec7b2789fd5ca80f979cef3761897ae1f37ffb3e154cbcc1c2663" - }, - { - }] + "raw": [ + { + "0x8f9a319405d14f3953657373696f6e204b65794f776e6572343a73657373696f6e3a6b6579730a299be621974fd19374a88f1dddd8442b21db25d2c923907dda6af815b657fe": "0xf26cdb14b5aec7b2789fd5ca80f979cef3761897ae1f37ffb3e154cbcc1c2663", + "0xd368b9d9bb1cc910c9a2b8e5d0f5f2fc": "0xf6ffc06ff28623000000000000000000", + "0x8f9a319405d14f3953657373696f6e204b65794f776e6572343a73657373696f6e3a6b6579731143fa96e07eb73af3db3a1b057d18899f864e6fc5d2f905f9296ca641565564": "0x9c7a2ee14e565db0c69f78c7b4cd839fbf52b607d867e9e9c5a79042898a0d12", + "0x8f9a319405d14f3953657373696f6e204b65794f776e6572343a73657373696f6e3a6b65797397dddc7aba561f16ac00da4bae75ab812aa7b81418bebdab74425f0d6aa31cee": "0x547ff0ab649283a7ae01dbc2eb73932eba2fb09075e9485ff369082a2ff38d65", + "0xbde3e43a2a348359d103d64bc95928146bdd9ae3490e26da38d2e4d19c137507": "0x0000a0dec5adc9353600000000000000", + "0x8f9a319405d14f3953657373696f6e204b65794f776e6572343a73657373696f6e3a6b65797340944475c781bbdc9726766a78b1964888e039600b1c865c62586ab8f98c171e": "0x547ff0ab649283a7ae01dbc2eb73932eba2fb09075e9485ff369082a2ff38d65", + "0xf186665804ca50670311307912458ce448d82cb96e7e4fe71df38c283a8720f4": "0x9c7a2ee14e565db0c69f78c7b4cd839fbf52b607d867e9e9c5a79042898a0d120f0000c16ff286230f0000c16ff2862300", + "0x50a63a871aced22e88ee6466fe5aa5d9": "0x9ee5e5bdc0ec239eb164f865ecc345ce4c88e76ee002e0f7e318097347471809", + "0xaf837bb0dec545e1b97d62ed037898d1": "0x1000299981a2b92f878baaf5dbeba5c18d4e70f2a1fcd9c61b32ea18daf38f4378482a3389a6cf42d8ed83888cfd920fec738ea30f97e44699ada7323f08c3380a482dbd7297a39fa145c570552249c2ca9dd47e281f0c500c971b59c9dcdcd82e6e7e4eb42cbd2e0ab4cae8708ce5509580b8c04d11f6758dbf686d50fe9f9106", + "0xe026dd082e3158e72eb7c985fc8bac4f": "0x80700000", + "0xb49a6659ec27619e87dd18e11b6838c0": "0x00", + "0x7c79972b34b7e51bdd5f168ba3accd35fbec396be75dfad19dd1121327f1a1ad": "0x000168655684472b743e456907b398d3a44c113f189e56d1bbfd55e889e295dfde7800", + "0x8f9a319405d14f3953657373696f6e204b65794f776e6572343a73657373696f6e3a6b65797399a2fc4b1339e668345bac7e1aadd1a834b90939a4ea40b64f30433a1d475817": "0x9c7a2ee14e565db0c69f78c7b4cd839fbf52b607d867e9e9c5a79042898a0d12", + "0xbc3717660105a864bd63dcd430de64128d58bd0917fa8dd75aee827cf086e19c": "0x0000c16ff28623000000000000000000", + "0x8f9a319405d14f3953657373696f6e204b65794f776e6572343a73657373696f6e3a6b6579732c1312343dce08149336968907c27cc602536aaf7a2b105d6fa07058a3803d31": "0xf26cdb14b5aec7b2789fd5ca80f979cef3761897ae1f37ffb3e154cbcc1c2663", + "0x72143961950b9317e15506626c4524c4": "0x1000299981a2b92f878baaf5dbeba5c18d4e70f2a1fcd9c61b32ea18daf38f4378482a3389a6cf42d8ed83888cfd920fec738ea30f97e44699ada7323f08c3380a482dbd7297a39fa145c570552249c2ca9dd47e281f0c500c971b59c9dcdcd82e6e7e4eb42cbd2e0ab4cae8708ce5509580b8c04d11f6758dbf686d50fe9f9106", + "0x9651d20f401bfac47731a01d6eba33b4": "0x00000000", + "0x8f9a319405d14f3953657373696f6e204b65794f776e6572343a73657373696f6e3a6b657973dc4036f96ca26a30da6d8637ca1431896c1069bf172c419e98dc08109e7b23b5": "0x68655684472b743e456907b398d3a44c113f189e56d1bbfd55e889e295dfde78", + "0xf14d23a9d4492a1efc9194e257b3c3d9": "0x00000000", + "0x90e2849b965314409e8bc00011f3004f": "0x04000000", + "0x52b963fbdb3d6e1b03808fc20071f07f": "0x004e0c00", + "0x87e6cbd186029472cea8c1748f99126b": "0x00000000", + "0x717a2ee9c64ad3424e10e4461ec08296": "0x0000000001000000000000000100000000000000010000000000000001000000000000000100000000000000010000000000000001000000000000008700000000000000af0000000000000001000000000000000100000000000000040000000000010010000000004000000020000000", + "0xeecb67c20ca6cc8ba4d4434687f61309": "0x103919132b851ef0fd2dae42a7e734fe547af5a6b809006100f48944d7fae8e8ef01000000000000005633b70b80a6c8bb16270f82cca6d56b27ed7b76c8fd5af2986a25a4788ce44001000000000000007932cff431e748892fa48e10c63c17d30f80ca42e4de3921e641249cd7fa3c2f01000000000000009becad03e6dcac03cee07edebca5475314861492cdfc96a2144a67bbe96993320100000000000000", + "0x154ebcb2c318b2e1c23e43e65aea27cd1348c4c5157502d7669a31c7635019cc": "0x9e42241d7cd91d001773b0b616d523dd80e13c6c2cab860b1234ef1b9ffc1526", + "0x633daafcb669e97549c1b9d65660881016f969040bc16171709159437c31294a": "0x0ff6ffc06ff286230ff6ffc06ff2862300", + "0xfacbe054606f2488121046f9c5539d98": "0x00", + "0x0c41b62474c49057a4476d0b96853c6d44e9c86c5fa130b0da3831c5eef546a0": "0x00", + "0xc1bc13c775b3406279618b05c28523cb": "0x00", + "0xf4adb4c4f708c4b753657373696f6e204e6578744b657973343a73657373696f6e3a6b657973711590f60a214f6f06502eb29dd14f55aa04e72e2fa12c098ba4fa5a00c57fa9": "0x7932cff431e748892fa48e10c63c17d30f80ca42e4de3921e641249cd7fa3c2f482dbd7297a39fa145c570552249c2ca9dd47e281f0c500c971b59c9dcdcd82e482dbd7297a39fa145c570552249c2ca9dd47e281f0c500c971b59c9dcdcd82e", + "0x75f6361fd25fec35714be80f2d9870af8c92e73cb6d299ba4774f5b0ad842275": "0x00", + "0x579ab55d37b1220812be3c3df29d4858": "0x00000000", + "0x4e62513de81454ce76df887573f7f98b101eb4585b1485a222b7db599f4e93e2": "0x047374616b696e67200000c16ff28623000000000000000000ffffffff0f", + "0xa902f1f0ef97177b8df9f9fd413768e7": "0x00000000", + "0x8f9a319405d14f3953657373696f6e204b65794f776e6572343a73657373696f6e3a6b657973be035f25cd43adc80f1dcf505f5ffd158d1592ab3719f354a256a4c3b7571934": "0x547ff0ab649283a7ae01dbc2eb73932eba2fb09075e9485ff369082a2ff38d65", + "0x1ba14d232d3c301a93e35f55e3d7aef2d98dbb9cc0ce48f457b81b421e0f704d": "0x0000c16ff28623000000000000000000", + "0x2dce29f1a768624dc5343063cb77f77d": "0x07000000", + "0xa978690c6b811e943721dbb6cb9b6246": "0x0000000000000000", + "0x8b4621d5f16433d6024b5a31547c59ee24e749e051dbb4bc7e64502f2a4f62fb": "0x66bc1e5d275da50b72b15de072a2468a5ad414919ca9054d2695767cf650012f", + "0x8cb577756012d928f17362e0741f9f2c": "0x01000000", + "0xc63b8a0db7e72fd87c88d8dcf4777b883f86728613c57148c4e5cdceb05b7a1a": "0x0001f26cdb14b5aec7b2789fd5ca80f979cef3761897ae1f37ffb3e154cbcc1c26630168655684472b743e456907b398d3a44c113f189e56d1bbfd55e889e295dfde78", + "0x637414312dac3b280120bf15b4f66cee": "0x00000000", + "0xbf18c0c65fb39f32ee7c8016685c0a6056f8f924192efb2655be9a692d0b03b6": "0x00", + "0x3a636f6465": "0x0061736d01000000019f022660037f7f7f017f60027f7f017f60027f7f0060017f0060057f7f7f7f7f0060037f7f7f0060047f7f7f7f0060017f017e60057f7f7f7f7f017f60067f7f7f7f7f7f0060047f7f7f7f017f60017e0060067f7f7f7f7f7f017f60087f7f7f7f7f7f7f7f017f6000017f60077f7f7f7f7f7f7f017f60017f017f60027f7f017e60000060037e7f7f017f60047f7f7e7e0060077f7f7e7e7f7f7f0060087f7f7f7f7f7e7e7f0060057f7f7f7e7e0060077f7f7f7e7e7f7f0060037f7e7e0060057f7f7e7e7f0060077f7e7e7f7f7f7f0060067f7f7e7e7f7f0060077f7f7f7f7f7e7e0060047f7f7f7f017e6000017e60077f7f7f7e7e7e7f0060067f7f7f7e7e7f0060037f7e7f0060047f7e7e7f0060057f7e7e7e7e0060067f7e7e7e7e7f0002af082803656e760e6578745f626c616b65325f323536000503656e761f6578745f6765745f616c6c6f63617465645f6368696c645f73746f72616765000803656e76176578745f636c6561725f6368696c645f73746f72616765000603656e76146578745f6765745f73746f726167655f696e746f000803656e76166578745f6b696c6c5f6368696c645f73746f72616765000203656e76156578745f7365745f6368696c645f73746f72616765000903656e76196578745f6765745f616c6c6f63617465645f73746f72616765000003656e760f6578745f7365745f73746f72616765000603656e760c6578745f74776f785f313238000503656e76116578745f636c6561725f73746f72616765000203656e76126578745f737232353531395f766572696679000a03656e760e6578745f7072696e745f75746638000203656e760d6578745f7072696e745f6e756d000b03656e76166578745f6368696c645f73746f726167655f726f6f74000003656e76106578745f636c6561725f707265666978000203656e76166578745f73616e64626f785f6d656d6f72795f6e6577000103656e761b6578745f73616e64626f785f6d656d6f72795f74656172646f776e000303656e76176578745f73616e64626f785f696e7374616e7469617465000c03656e76126578745f73616e64626f785f696e766f6b65000d03656e761d6578745f73616e64626f785f696e7374616e63655f74656172646f776e000303656e76106578745f73746f726167655f726f6f74000303656e76186578745f73746f726167655f6368616e6765735f726f6f74000003656e76126578745f656432353531395f766572696679000a03656e76166578745f73616e64626f785f6d656d6f72795f676574000a03656e76166578745f73616e64626f785f6d656d6f72795f736574000a03656e760d6578745f7072696e745f686578000203656e76106578745f69735f76616c696461746f72000e03656e76156578745f6c6f63616c5f73746f726167655f676574000a03656e76216578745f6c6f63616c5f73746f726167655f636f6d706172655f616e645f736574000f03656e76116578745f6e6574776f726b5f7374617465001003656e76106578745f737232353531395f7369676e000803656e76166578745f7375626d69745f7472616e73616374696f6e000103656e76156578745f6c6f63616c5f73746f726167655f736574000403656e76146578745f656432353531395f67656e6572617465000603656e76146578745f737232353531395f67656e6572617465000603656e76236578745f626c616b65325f3235365f656e756d6572617465645f747269655f726f6f74000603656e760a6578745f6d616c6c6f63001003656e76086578745f66726565000303656e76176578745f737232353531395f7075626c69635f6b657973000103656e760b6578745f74776f785f3634000503fd04fb0410100303000010101112030205001202060001010201021303070c0a0200060101011001010101010201060305030001010001010800010001010101010102030203030202020202020203020202020202020202020202020202020502020202050304050205010205020202140303020e02020303030202020201020102020405020202020202020202030202150101160509021706030505180602030202020205050505000314141212030212120501030303030303030303030303030303020202020202020502020202051202020303120e050502020502141406060505050502020205171919120503020302031a02020202021b020303030203140303051c1905050202020502050201010303020202020503020203020202060605030302020302020202020202021d0206030302020303030205020503030302020202020312020206020202030202050205060202051206090606060606060606060606060606060606060606060606061e02020203030203021f1203020302020505020203030302020203030202030303050510120202020202120202030202031010020202040302060202020303030203030202010a020202020202030b03030202030202020202020202020220030321060202020102010602030505020202030302021111021111050202111111021111110511031111111111111111030303030202020202020202030214020204020303020202020302020202020a0101010101010102010101010102010105020102050503050202010101050501010205050405220202020505040202050303030302020204020201050102060501050606050501040405050505060303010101000000002323242424250407017001de01de0105030100120619037f01418080c0000b7f004188b1c6000b7f004188b1c6000b078d0518066d656d6f72790200195f5f696e6469726563745f66756e6374696f6e5f7461626c6501000a5f5f646174615f656e6403010b5f5f686561705f62617365030209686173685f7465737400300c436f72655f76657273696f6e008c0412436f72655f657865637574655f626c6f636b008d0415436f72655f696e697469616c697a655f626c6f636b008f04114d657461646174615f6d657461646174610090041c426c6f636b4275696c6465725f6170706c795f65787472696e7369630094041b426c6f636b4275696c6465725f66696e616c697a655f626c6f636b00950420426c6f636b4275696c6465725f696e686572656e745f65787472696e736963730096041c426c6f636b4275696c6465725f636865636b5f696e686572656e747300980418426c6f636b4275696c6465725f72616e646f6d5f736565640099042b5461676765645472616e73616374696f6e51756575655f76616c69646174655f7472616e73616374696f6e009a04214f6666636861696e576f726b65724170695f6f6666636861696e5f776f726b6572009c041e4772616e6470614170695f6772616e6470615f617574686f726974696573009e0415426162654170695f636f6e66696775726174696f6e009f0421417574686f72697479446973636f766572794170695f617574686f72697469657300a0041a417574686f72697479446973636f766572794170695f7369676e00a1041c417574686f72697479446973636f766572794170695f76657269667900a2041d4163636f756e744e6f6e63654170695f6163636f756e745f6e6f6e636500a30411436f6e7472616374734170695f63616c6c00a4042153657373696f6e4b6579735f67656e65726174655f73657373696f6e5f6b65797300a50409a403010041010bdd013d4c5147e50448495ea201a401fd02ff0280038103820383038403850386038703880389038a038b038c038d038e038f0390039103920393039403950396039703d801ca04d0048605d2048205e604d804e204d4044f8c05d10497059405393a3b8901644155565758595a5b6160636566678a018b018d018e01900192014e4d9d03be04b301be01a701bf01a801b601c001bb01f20262ad03ac03d901b103a203a403d503d403d6039c039b03c403da01a202a002db01a402a904a804dc01b204dc02db02dd01dd02ba04b904de01bf04b603b503df01b703c802c702e001cb02d903d803e101b602b702d802d702e201e302e202e301e402e703e603e401ea0389048804e501a702a602e601b201e701a302cd02ef03f003c902b402b502b902b802ca02bb04d202d102d002cf02ce02cc02f303d902ac04de02e802e702e502f602f402f702f302f502a303a603a503b003af03ae03d703e903e803f403f203f103ee03ed03ec03eb038a04af04ae04ad04ab04aa04b304bd04bc04c304c204c104c004cc04ce04cb04c904c704c804cf04e104d5049505980596050ac3c540fb040600200010290b0600200010240b06002000102b0b0600200010250b0a00200020012002102d0b2801017f0240200210242203450d002003200020022001200120024b1b109a051a200010250b20030b06002000102f0b1c01017f0240200010242201450d002001410020001099051a0b20010bfa0202017f037e230041206b220224002001ad42adfed5e4d485fda8d8007e42c3007c210302400240024002400240200141084b0d00200141014b0d0120010d02420021040c030b0240200141104b0d00200241106a2000290000200385420042adfed5e4d485fda8d8004200109f05200241186a29030020022903107c200120006a41786a2900008521040c040b200120006a41786a2900002105200321040340200029000020048542adfed5e4d485fda8d8007e42178942adfed5e4d485fda8d8007e2003852103200041086a2100200442cf829ebbefefde82147c2104200141786a220141084b0d000b200320058521040c030b0240200141034b0d00200120006a417e6a33000042108620003300008420038521040c030b200120006a417c6a35000042208620003500008420038521040c020b200031000021040b200420038521040b20022004420042adfed5e4d485fda8d8004200109f05200241086a290300210420022903002103200241206a2400200420037c0b0a00418080c0001032000b5b02017f037e230041306b220124002000290208210220002902102103200029020021042001420437031020014201370204200120043703182001200141186a36020020012003370328200120023703202001200141206a103e000b870301067f230041306b2202240020012802002103024002402001280204220441037422050d00410021060c010b200341046a2107410021060340200728020020066a2106200741086a2107200541786a22050d000b0b024002400240024002400240200141146a2802000d00200621070c010b024020040d0041ac80c000410041001034000b024002402006410f4b0d002003280204450d010b200620066a220720064f0d010b4101210541002107200241086a21060c010b2007417f4c0d01200241086a2106024020070d0041012105410021070c010b200710282205450d020b200241003602102002200736020c200220053602082002200241086a360214200241186a41106a200141106a290200370300200241186a41086a200141086a29020037030020022001290200370318200241146a41bc80c000200241186a10350d0220002006290200370200200041086a200641086a280200360200200241306a24000f0b1036000b200741011037000b41d480c0004133200241186a418881c0001038000b6c01017f230041306b2203240020032002360204200320013602002003411c6a41023602002003412c6a41013602002003420237020c200341e883c000360208200341013602242003200341206a360218200320033602282003200341046a360220200341086a2000103e000bbd0801087f230041c0006b22032400200341246a2001360200200341346a200241146a2802002204360200200341033a00382003412c6a2002280210220520044103746a36020020034280808080800437030820032000360220410021062003410036021820034100360210200320053602302003200536022802400240024002400240200228020822070d0020022802002108200228020422092004200420094b1b220a450d0141012104200020082802002008280204200128020c1100000d04200841086a210241012106034002402005280200200341086a200541046a280200110100450d00410121040c060b2006200a4f0d02200241046a210020022802002101200541086a2105200241086a210241012104200641016a2106200328022020012000280200200328022428020c110000450d000c050b0b20022802002108200228020422092002410c6a2802002205200520094b1b220a450d0041012104200020082802002008280204200128020c1100000d03200741106a2105200841086a21024101210603402003200541786a28020036020c2003200541106a2d00003a003820032005417c6a28020036020841002101410021040240024002400240200541086a2802000e0400010203000b2005410c6a2802002100410121040c020b02402005410c6a2802002207200328023422044f0d0041002104200328023020074103746a22072802044102470d0220072802002802002100410121040c020b41a089c000200720041034000b4100210420032802282207200328022c460d002003200741086a3602284100210420072802044102470d0020072802002802002100410121040b2003200036021420032004360210024002400240024002400240024020052802000e0404010006040b20032802282200200328022c470d010c050b200541046a2802002200200328023422044f0d01200328023020004103746a22002802044102470d04200028020028020021040c030b2003200041086a36022820002802044102470d03200028020028020021040c020b41a089c000200020041034000b200541046a28020021040b410121010b2003200436021c2003200136021802400240200541706a2802004101460d0020032802282204200328022c460d042003200441086a3602280c010b200541746a2802002204200328023422004f0d04200328023020044103746a21040b02402004280200200341086a200441046a280200110100450d00410121040c050b2006200a4f0d01200241046a210020022802002101200541246a2105200241086a210241012104200641016a2106200328022020012000280200200328022428020c110000450d000c040b0b0240200920064d0d00410121042003280220200820064103746a22052802002005280204200328022428020c1100000d030b410021040c020b41f087c0001032000b41b089c000200420001034000b200341c0006a240020040b05001031000b0e0041a6f4c500412210e70400000b810101017f230041c0006b220424002004200136020c2004200036020820042003360214200420023602102004412c6a41023602002004413c6a41033602002004420237021c200441b8c2c200360218200441043602342004200441306a3602282004200441106a3602382004200441086a360230200441186a4188afc000103e000bb10101037f0240024002400240200028020022002802042203200028020822046b2002490d00200028020021030c010b200420026a22052004490d02200341017422042005200420054b1b22044100480d020240024020030d002004102821030c010b200028020020032004102c21030b2003450d012000200436020420002003360200200028020821040b2000200420026a360208200320046a20012002109a051a41000f0b200441011037000b1031000ba70401047f230041106b220224002000280200210002400240024002400240024002402001418001490d002002410036020c2001418010490d0102402001418080044f0d0020022001413f71418001723a000e20022001410676413f71418001723a000d20022001410c76410f7141e001723a000c410321010c040b20022001413f71418001723a000f2002200141127641f001723a000c20022001410676413f71418001723a000e20022001410c76413f71418001723a000d410421010c030b0240200028020822032000280204470d00200341016a22042003490d06200341017422052004200520044b1b22044100480d060240024020030d002004102821030c010b200028020020032004102c21030b2003450d022000200436020420002003360200200028020821030b200028020020036a20013a00002000200028020841016a3602080c030b20022001413f71418001723a000d20022001410676411f7141c001723a000c410221010c010b200441011037000b0240024020002802042204200028020822036b2001490d00200028020021040c010b200320016a22052003490d03200441017422032005200320054b1b22034100480d030240024020040d002003102821040c010b200028020020042003102c21040b2004450d022000200336020420002004360200200028020821030b2000200320016a360208200420036a2002410c6a2001109a051a0b200241106a240041000f0b200341011037000b1031000b6301017f230041206b2202240020022000280200360204200241086a41106a200141106a290200370300200241086a41086a200141086a29020037030020022001290200370308200241046a41bc80c000200241086a10352101200241206a240020010b6f01017f230041306b2202240020022001360204200220003602002002411c6a41023602002002412c6a41013602002002420237020c2002418486c000360208200241013602242002200241206a3602182002200241046a36022820022002360220200241086a419486c000103e000b0d00200035020041012001103f0b4702017f017e230041206b2202240020012902002103200241146a20012902083702002002200337020c20022000360208200241f883c0003602042002410136020020021040000bd40203027f017e037f230041306b22032400412721040240024020004290ce005a0d00200021050c010b412721040340200341096a20046a2206417c6a200020004290ce0080220542f0b17f7e7ca7220741ffff037141e4006e220841017441ba84c0006a2f00003b00002006417e6a2008419c7f6c20076a41ffff037141017441ba84c0006a2f00003b00002004417c6a2104200042ffc1d72f5621062005210020060d000b0b02402005a7220641e3004c0d00200341096a2004417e6a22046a2005a7220741ffff037141e4006e2206419c7f6c20076a41ffff037141017441ba84c0006a2f00003b00000b024002402006410a480d00200341096a2004417e6a22046a200641017441ba84c0006a2f00003b00000c010b200341096a2004417f6a22046a200641306a3a00000b2002200141b8aec6004100200341096a20046a412720046b10422104200341306a240020040b6601017f230041c0006b220124002001200036020c200141346a410136020020014201370224200141b0aec6003602202001410536023c2001200141386a36023020012001410c6a360238200141106a200141206a10332001280210200128021810e70400000b0d0042c8dfc497e99ce988eb000be00501057f024002402001450d00412b418080c4002000280200220641017122011b2107200120056a21080c010b200541016a210820002802002106412d21070b0240024020064104710d00410021020c010b4100210902402003450d002003210a200221010340200920012d000041c00171418001466a2109200141016a2101200a417f6a220a0d000b0b200820036a20096b21080b410121010240024020002802084101460d00200020072002200310430d012000280218200420052000411c6a28020028020c1100000f0b02402000410c6a280200220920084b0d00200020072002200310430d012000280218200420052000411c6a28020028020c1100000f0b0240024020064108710d00200920086b210941002101024002400240410120002d0030220a200a4103461b0e0402000100020b20092101410021090c010b20094101762101200941016a41017621090b200141016a210103402001417f6a2201450d0220002802182000280204200028021c280210110100450d000b41010f0b41012101200041013a003020004130360204200020072002200310430d01200920086b210941002101024002400240410120002d0030220a200a4103461b0e0402000100020b20092101410021090c010b20094101762101200941016a41017621090b200141016a2101024003402001417f6a2201450d0120002802182000280204200028021c280210110100450d000b41010f0b2000280204210a41012101200028021820042005200028021c28020c1100000d01200941016a2109200028021c210320002802182100034002402009417f6a22090d0041000f0b410121012000200a2003280210110100450d000c020b0b2000280204210a41012101200020072002200310430d00200028021820042005200028021c28020c1100000d00200941016a2109200028021c210320002802182100034002402009417f6a22090d0041000f0b410121012000200a2003280210110100450d000b0b20010b5401017f024002402001418080c400460d0041012104200028021820012000411c6a2802002802101101000d010b024020020d0041000f0b2000280218200220032000411c6a28020028020c11000021040b20040b6f01017f230041306b2202240020022001360204200220003602002002411c6a41023602002002412c6a41013602002002420237020c200241cc86c000360208200241013602242002200241206a3602182002200241046a36022820022002360220200241086a41dc86c000103e000b8307010c7f200028021021030240024002400240200028020822044101460d0020030d012000280218200120022000411c6a28020028020c11000021030c030b2003450d010b0240024020020d00410021020c010b200120026a2105200041146a28020041016a21064100210720012103200121080340200341016a210902400240024020032c0000220a417f4a0d000240024020092005470d004100210b200521030c010b20032d0001413f71210b200341026a220921030b200a411f71210c0240200a41ff0171220a41df014b0d00200b200c41067472210a0c020b0240024020032005470d004100210d2005210e0c010b20032d0000413f71210d200341016a2209210e0b200d200b41067472210b0240200a41f0014f0d00200b200c410c7472210a0c020b02400240200e2005470d004100210a200921030c010b200e41016a2103200e2d0000413f71210a0b200b410674200c411274418080f0007172200a72220a418080c400470d020c040b200a41ff0171210a0b200921030b02402006417f6a2206450d00200720086b20036a21072003210820052003470d010c020b0b200a418080c400460d00024002402007450d0020072002460d0041002103200720024f0d01200120076a2c00004140480d010b200121030b2007200220031b21022003200120031b21010b20040d002000280218200120022000411c6a28020028020c1100000f0b4100210902402002450d002002210a200121030340200920032d000041c00171418001466a2109200341016a2103200a417f6a220a0d000b0b0240200220096b200028020c2206490d002000280218200120022000411c6a28020028020c1100000f0b410021074100210902402002450d00410021092002210a200121030340200920032d000041c00171418001466a2109200341016a2103200a417f6a220a0d000b0b200920026b20066a210a024002400240410020002d0030220320034103461b0e0402000100020b200a21074100210a0c010b200a4101762107200a41016a410176210a0b200741016a2103024003402003417f6a2203450d0120002802182000280204200028021c280210110100450d000b41010f0b2000280204210941012103200028021820012002200028021c28020c1100000d00200a41016a2103200028021c210a20002802182100034002402003417f6a22030d0041000f0b20002009200a280210110100450d000b41010f0b20030bcd0801067f230041f0006b220424002004200336020c20042002360208410121052001210602402001418102490d00410020016b2107418002210803400240200820014f0d00200020086a2c000041bf7f4c0d0041002105200821060c020b2008417f6a21064100210520084101460d01200720086a21092006210820094101470d000b0b200420063602142004200036021020044100410520051b36021c200441b8aec600419287c00020051b3602180240024002400240200220014b22080d00200320014b0d00200220034b0d01024002402002450d0020012002460d00200120024d0d01200020026a2c00004140480d010b200321020b200420023602202002450d0220022001460d02200141016a210903400240200220014f0d00200020026a2c000041404e0d040b2002417f6a210820024101460d0420092002462106200821022006450d000c040b0b20042002200320081b360228200441306a41146a4103360200200441c8006a41146a4104360200200441d4006a4104360200200442033702342004419887c0003602302004410136024c2004200441c8006a3602402004200441186a3602582004200441106a3602502004200441286a360248200441306a41b087c000103e000b200441e4006a4104360200200441c8006a41146a4104360200200441d4006a4101360200200441306a41146a410436020020044204370234200441c087c0003602302004410136024c2004200441c8006a3602402004200441186a3602602004200441106a36025820042004410c6a3602502004200441086a360248200441306a41e087c000103e000b200221080b024020082001460d00410121060240024002400240200020086a22092c00002202417f4a0d0041002105200020016a220621010240200941016a2006460d00200941026a210120092d0001413f7121050b2002411f712109200241ff017141df014b0d01200520094106747221010c020b2004200241ff0171360224200441286a21020c020b4100210020062107024020012006460d00200141016a210720012d0000413f7121000b200020054106747221010240200241ff017141f0014f0d0020012009410c747221010c010b41002102024020072006460d0020072d0000413f7121020b20014106742009411274418080f00071722002722201418080c400460d020b2004200136022441012106200441286a21022001418001490d00410221062001418010490d0041034104200141808004491b21060b200420083602282004200620086a36022c200441306a41146a4105360200200441ec006a4104360200200441e4006a4104360200200441c8006a41146a4106360200200441d4006a4107360200200442053702342004418888c000360230200420023602582004410136024c2004200441c8006a3602402004200441186a3602682004200441106a3602602004200441246a3602502004200441206a360248200441306a41b088c000103e000b41f087c0001032000b100020012000280200200028020410450b6c01037f230041206b22022400024020002001104b0d002001411c6a280200210320012802182104200242043703182002420137020c2002419889c00036020820042003200241086a10350d00200041046a2001104b2101200241206a240020010f0b200241206a240041010bd90a02077f017e410121020240200128021841272001411c6a2802002802101101000d0041022103024002400240024002402000280200220241776a2200411e4d0d00200241dc00470d010c020b41f40021040240024020000e1f05010202000202020202020202020202020202020202020202030202020203050b41f20021040c040b41ee0021040c030b02400240024002400240024002402002104a0d00024002400240024002400240200241808004490d00200241808008490d0120024190fc476a4190fc0b490d0a200241e28b746a41e28d2c490d0a2002419fa8746a419f18490d0a200241dee2746a410e490d0a200241feffff0071419ef00a460d0a200241a9b2756a4129490d0a200241cb91756a410a4d0d0a410121030c0e0b20024180fe0371410876210541d095c000210041002106200241ff017121040340200041026a2107200620002d000122036a2108024020002d000022002005460d00200020054b0d092008210620072100200741a296c000470d010c090b20082006490d02200841a5024b0d03200641a296c0006a2100024003402003450d012003417f6a210320002d00002106200041016a210020062004470d000c0c0b0b2008210620072100200741a296c000470d000c080b0b20024180fe0371410876210541819bc000210041002106200241ff017121040340200041026a2107200620002d000122036a2108024020002d000022002005460d00200020054b0d072008210620072100200741c79bc000470d010c070b20082006490d03200841a6014b0d04200641c79bc0006a2100024003402003450d012003417f6a210320002d00002106200041016a210020062004470d000c0b0b0b2008210620072100200741c79bc000470d000c060b0b200620081044000b200841a502103c000b200620081044000b200841a601103c000b200241017267410276410773ad4280808080d0008421090c040b200241ffff0371210441ed9cc00021034101210002400340200341016a21080240024020032d0000220641187441187522074100480d00200821030c010b20084185a0c000460d02200741ff007141087420032d0001722106200341026a21030b200420066b22044100480d032000410173210020034185a0c000470d000c030b0b41f087c0001032000b200241ffff0371210441c798c0002103410121000340200341016a21080240024020032d0000220641187441187522074100480d00200821030c010b200841819bc000460d05200741ff007141087420032d0001722106200341026a21030b200420066b22044100480d0120004101732100200341819bc000470d000b0b4101210320004101710d030b200241017267410276410773ad4280808080d0008421090b410321030c020b41f087c0001032000b0b200221040b03402003210641dc0021004101210241012103024002400240024020060e0401020300010b024002400240024002402009422088a741ff01710e06050403020100050b200942ffffffff8f60834280808080c000842109410321030c060b200942ffffffff8f608342808080803084210941f5002100410321030c050b200942ffffffff8f608342808080802084210941fb002100410321030c040b20042009a72206410274411c7176410f712203413072200341d7006a2003410a491b210002402006450d002009427f7c42ffffffff0f83200942808080807083842109410321030c040b200942ffffffff8f6083428080808010842109410321030c030b200942ffffffff8f6083210941fd002100410321030c020b20012802184127200128021c2802101101000f0b41002103200421000b20012802182000200128021c280210110100450d000b0b20020b950201017f024002402000418010490d00024002400240024002400240200041808004490d002000410c7641706a2201418002490d0141a8a0c00020014180021034000b200041067641606a220141df074b0d01200141f08bc0006a2d0000220141c9004b0d0220014103744180a1c0006a21010c060b200141d093c0006a2d00004106742000410676413f7172220141ff034b0d02200141d0a5c0006a2d0000220141394b0d03200141037441d0a9c0006a21010c050b4188a0c000200141e0071034000b4198a0c000200141ca001034000b41b8a0c00020014180041034000b41c8a0c0002001413a1034000b200041037641f8ffffff017141d889c0006a21010b200129030042012000413f71ad86834200520baf0201037f23004180016b2202240002400240024002400240200128020022034110710d002000280200210420034120710d012004ad41012001103f21000c020b20002802002104410021000340200220006a41ff006a2004410f712203413072200341d7006a2003410a491b3a00002000417f6a2100200441047622040d000b20004180016a22044181014f0d0220014101419087c0004102200220006a4180016a410020006b104221000c010b410021000340200220006a41ff006a2004410f712203413072200341376a2003410a491b3a00002000417f6a2100200441047622040d000b20004180016a22044181014f0d0220014101419087c0004102200220006a4180016a410020006b104221000b20024180016a240020000f0b20044180011044000b20044180011044000b0d00200035020041012001103f0b1c00200128021841a1aec000410b2001411c6a28020028020c1100000b1c00200128021841acaec000410e2001411c6a28020028020c1100000b6901037f230041206b220224002001411c6a280200210320012802182104200241086a41106a2000280200220141106a290200370300200241086a41086a200141086a2902003703002002200129020037030820042003200241086a10352101200241206a240020010b5e01017f230041306b220224002002200136020c20022000360208200241246a410136020020024201370214200241b0aec6003602102002410436022c2002200241286a3602202002200241086a360228200241106a41f8aec000103e000b140020002802002001200028020428020c1101000bc30501077f410021040240024020024103712205450d00410420056b2205450d00200220032005200520034b1b22046a210641002105200141ff017121072004210820022109024003400240200620096b41034b0d0041002107200141ff0171210603402008450d04200920076a210a2008417f6a2108200741016a2107200a2d0000220a2006470d000b2005200a200141ff01714641016a4101716a20076a417f6a21050c020b200520092d0000220a2007476a2105200a2007460d012005200941016a2d0000220a2007476a2105200a2007460d012005200941026a2d0000220a2007476a2105200a2007460d012005200941036a2d0000220a2007476a21052008417c6a2108200941046a2109200a2007470d000b0b410121090c010b200141ff017121070240024020034108490d002004200341786a220a4b0d00200741818284086c210502400340200220046a220941046a2802002005732208417f73200841fffdfb776a7120092802002005732209417f73200941fffdfb776a7172418081828478710d01200441086a2204200a4d0d000b0b200420034b0d010b200220046a2109200220036a2102200320046b2108410021050240024003400240200220096b41034b0d0041002107200141ff0171210203402008450d04200920076a210a2008417f6a2108200741016a2107200a2d0000220a2002470d000b200a200141ff01714641016a41017120056a20076a417f6a21050c020b200520092d0000220a2007476a2105200a2007460d012005200941016a2d0000220a2007476a2105200a2007460d012005200941026a2d0000220a2007476a2105200a2007460d012005200941036a2d0000220a2007476a21052008417c6a2108200941046a2109200a2007470d000b0b41012109200520046a21050c020b41002109200520076a20046a21050c010b200420031044000b20002005360204200020093602000b2601017f200028020022012802002001280204200028020428020020002802082802001046000b850804057f017e017f017e02400240024002402002450d00410020016b410020014103711b2103200241796a4100200241074b1b210441002105034002400240200120056a2d000022064118744118752207417f4a0d0042808080801021080240200641e681c0006a2d0000417e6a220941024d0d0042808080808020210a0c070b0240024002400240024020090e03000102000b200541016a22062002490d024200210a0c090b4200210a200541016a220920024f0d08200120096a2d0000210902400240200641a07e6a2206410d4b0d000240024020060e0e0002020202020202020202020201000b200941e0017141a001460d0242808080808020210a0c0c0b02402009411874411875417f4c0d0042808080808020210a0c0c0b200941ff017141a001490d0142808080808020210a0c0b0b02402007411f6a41ff0171410b4b0d0002402009411874411875417f4c0d0042808080808020210a0c0c0b200941ff017141c001490d0142808080808020210a0c0b0b0240200941ff017141bf014d0d0042808080808020210a0c0b0b0240200741fe017141ee01460d0042808080808020210a0c0b0b2009411874411875417f4c0d0042808080808020210a0c0a0b42002108200541026a220620024f0d09200120066a2d000041c00171418001460d020c070b4200210a200541016a220920024f0d07200120096a2d0000210902400240200641907e6a220641044b0d000240024020060e050002020201000b200941f0006a41ff01714130490d0242808080808020210a0c0b0b02402009411874411875417f4c0d0042808080808020210a0c0b0b200941ff0171419001490d0142808080808020210a0c0a0b0240200941ff017141bf014d0d0042808080808020210a0c0a0b02402007410f6a41ff017141024d0d0042808080808020210a0c0a0b2009411874411875417f4c0d0042808080808020210a0c090b200541026a220620024f0d07200120066a2d000041c00171418001470d0642002108200541036a220620024f0d08200120066a2d000041c00171418001460d01428080808080e000210a42808080801021080c080b42808080808020210a4280808080102108200120066a2d000041c00171418001470d070b200641016a21050c010b0240200320056b4103710d000240200520044f0d000340200120056a220641046a280200200628020072418081828478710d01200541086a22052004490d000b0b200520024f0d010340200120056a2c00004100480d022002200541016a2205470d000c040b0b200541016a21050b20052002490d000b0b20002001360204200041086a2002360200200041003602000f0b428080808080c000210a42808080801021080c010b420021080b2000200a2008842005ad84370204200041013602000b02000ba20401077f230041306b220324000240024020020d00410021040c010b200341286a210502400240024002400340024020002802082d0000450d00200028020041e4afc0004104200028020428020c1100000d050b2003410a3602282003428a808080103703202003200236021c200341003602182003200236021420032001360210200341086a410a200120021052024002400240024020032802084101470d00200328020c210403402003200420032802186a41016a2204360218024002402004200328022422064f0d00200328021421070c010b200328021422072004490d00200641054f0d072003280210200420066b22086a22092005460d04200920052006109c05450d040b200328021c22092004490d0220072009490d0220032006200341106a6a41176a2d0000200328021020046a200920046b10522003280204210420032802004101460d000b0b2003200328021c3602180b200028020841003a0000200221040c010b200028020841013a0000200841016a21040b2000280204210920002802002106024020044520022004467222070d00200220044d0d03200120046a2c000041bf7f4c0d030b200620012004200928020c1100000d04024020070d00200220044d0d04200120046a2c000041bf7f4c0d040b200120046a2101200220046b22020d000b410021040c040b20064104103c000b20012002410020041046000b20012002200420021046000b410121040b200341306a240020040bf90101017f230041106b220224002002410036020c0240024002402001418001490d002001418010490d0102402001418080044f0d0020022001413f71418001723a000e20022001410676413f71418001723a000d20022001410c76410f7141e001723a000c410321010c030b20022001413f71418001723a000f2002200141127641f001723a000c20022001410676413f71418001723a000e20022001410c76413f71418001723a000d410421010c020b200220013a000c410121010c010b20022001413f71418001723a000d20022001410676411f7141c001723a000c410221010b20002002410c6a200110562101200241106a240020010b6001017f230041206b2202240020022000360204200241086a41106a200141106a290200370300200241086a41086a200141086a29020037030020022001290200370308200241046a41ccafc000200241086a10352101200241206a240020010b0d0020002802002001200210560b800201017f230041106b22022400200028020021002002410036020c0240024002402001418001490d002001418010490d0102402001418080044f0d0020022001413f71418001723a000e20022001410676413f71418001723a000d20022001410c76410f7141e001723a000c410321010c030b20022001413f71418001723a000f2002200141127641f001723a000c20022001410676413f71418001723a000e20022001410c76413f71418001723a000d410421010c020b200220013a000c410121010c010b20022001413f71418001723a000d20022001410676411f7141c001723a000c410221010b20002002410c6a200110562101200241106a240020010b6301017f230041206b2202240020022000280200360204200241086a41106a200141106a290200370300200241086a41086a200141086a29020037030020022001290200370308200241046a41ccafc000200241086a10352101200241206a240020010bdb0302047f057e230041d0006b2205240041012106024020002d00040d0020002d000521070240200028020022082d00004104710d0041012106200828021841caafc00041e8afc000200741ff017122071b4102410320071b2008411c6a28020028020c1100000d014101210620002802002208280218200120022008411c6a28020028020c1100000d01410121062000280200220828021841b9a8c40041022008411c6a28020028020c1100000d0120032000280200200428020c11010021060c010b0240200741ff01710d0041012106200828021841ebafc00041032008411c6a28020028020c1100000d01200028020021080b41012106200541013a00172005200541176a360210200829020821092008290210210a200541346a41b0afc000360200200520082902183703082008290220210b2008290228210c200520082d00303a00482008290200210d2005200c3703402005200b3703382005200a370328200520093703202005200d3703182005200541086a360230200541086a2001200210560d00200541086a41b9a8c400410210560d002003200541186a200428020c1101000d00200528023041c8afc0004102200528023428020c11000021060b200041013a0005200020063a0004200541d0006a240020000bf30202047f057e230041d0006b2203240041012104024020002d00080d00200028020421050240200028020022062d00004104710d0041012104200628021841caafc00041f1afc00020051b4102410120051b2006411c6a28020028020c1100000d0120012000280200200228020c11010021040c010b024020050d0041012104200628021841f2afc00041022006411c6a28020028020c1100000d01200028020021060b41012104200341013a00172003200341176a3602102006290208210720062902102108200341346a41b0afc00036020020032006290218370308200629022021092006290228210a200320062d00303a00482006290200210b2003200a3703402003200937033820032008370328200320073703202003200b3703182003200341086a3602302001200341186a200228020c1101000d00200328023041c8afc0004102200328023428020c11000021040b200020043a00082000200028020441016a360204200341d0006a240020000b6401027f230041206b220224002001411c6a280200210320012802182101200241086a41106a200041106a290200370300200241086a41086a200041086a2902003703002002200029020037030820012003200241086a10352100200241206a240020000bb50f020d7f017e230041206b220324004101210402400240200228021841222002411c6a2802002802101101000d000240024020010d00410021050c010b200020016a21062000210741002105410021080240034020072109200741016a210a02400240024020072c0000220b417f4a0d0002400240200a2006470d004100210c200621070c010b20072d0001413f71210c200741026a220a21070b200b411f7121040240200b41ff0171220b41df014b0d00200c200441067472210b0c020b0240024020072006470d004100210d2006210e0c010b20072d0000413f71210d200741016a220a210e0b200d200c41067472210c0240200b41f0014f0d00200c2004410c7472210b0c020b02400240200e2006470d004100210b200a21070c010b200e41016a2107200e2d0000413f71210b0b200c4106742004411274418080f0007172200b72220b418080c400470d020c040b200b41ff0171210b0b200a21070b4102210a024002400240024002400240200b41776a220c411e4d0d00200b41dc00470d010c020b41f400210e02400240200c0e1f05010202000202020202020202020202020202020202020202030202020203050b41f200210e0c040b41ee00210e0c030b02400240200b104a0d00024002400240024002400240024002400240200b41808004490d00200b41808008490d01200b4190fc476a4190fc0b490d09200b41e28b746a41e28d2c490d09200b419fa8746a419f18490d09200b41dee2746a410e490d09200b41feffff0071419ef00a460d09200b41a9b2756a4129490d09200b41cb91756a410a4d0d090c0e0b200b4180fe0371410876210f41d095c000210c410021040340200c41026a210d2004200c2d0001220a6a210e0240200c2d0000220c200f460d00200c200f4b0d08200e2104200d210c200d41a296c000470d010c080b200e2004490d02200e41a5024b0d03200441a296c0006a210c02400340200a450d01200a417f6a210a200c2d00002104200c41016a210c2004200b41ff0171470d000c0b0b0b200e2104200d210c200d41a296c000470d000c070b0b200b4180fe0371410876210f41819bc000210c410021040340200c41026a210d2004200c2d0001220a6a210e0240200c2d0000220c200f460d00200c200f4b0d06200e2104200d210c200d41c79bc000470d010c060b200e2004490d03200e41a6014b0d04200441c79bc0006a210c02400340200a450d01200a417f6a210a200c2d00002104200c41016a210c2004200b41ff0171470d000c0a0b0b200e2104200d210c200d41c79bc000470d000c050b0b2004200e1044000b200e41a502103c000b2004200e1044000b200e41a601103c000b200b41ffff0371210e41ed9cc000210a4101210c02400340200a41016a210d02400240200a2d00002204411874411875220f4100480d00200d210a0c010b200d4185a0c000460d02200f41ff0071410874200a2d0001722104200a41026a210a0b200e20046b220e4100480d03200c410173210c200a4185a0c000470d000c030b0b41f087c0001032000b200b41ffff0371210e41c798c000210a4101210c0340200a41016a210d02400240200a2d00002204411874411875220f4100480d00200d210a0c010b200d41819bc000460d04200f41ff0071410874200a2d0001722104200a41026a210a0b200e20046b220e4100480d01200c410173210c200a41819bc000470d000b0b200c4101710d050b200b41017267410276410773ad4280808080d0008421104103210a0c020b41f087c0001032000b0b200b210e0b2003200136020420032000360200200320053602082003200836020c0240024020082005490d0002402005450d0020052001460d00200520014f0d01200020056a2c000041bf7f4c0d010b02402008450d0020082001460d00200820014f0d01200020086a2c000041bf7f4c0d010b2002280218200020056a200820056b200228021c28020c110000450d01410121040c060b20032003410c6a3602182003200341086a36021420032003360210200341106a1053000b0340200a210c4101210441dc0021054101210a024002400240024002400240200c0e0402010500020b02400240024002402010422088a741ff01710e06050302010006050b201042ffffffff8f60834280808080308421104103210a41f50021050c070b201042ffffffff8f60834280808080208421104103210a41fb0021050c060b200e2010a7220c410274411c7176410f71220a413072200a41d7006a200a410a491b21050240200c450d002010427f7c42ffffffff0f832010428080808070838421100c050b201042ffffffff8f60834280808080108421100c040b201042ffffffff8f608321104103210a41fd0021050c040b4100210a200e21050c030b4101210a0240200b418001490d004102210a200b418010490d0041034104200b41808004491b210a0b200a20086a21050c040b201042ffffffff8f60834280808080c0008421100b4103210a0b20022802182005200228021c2802101101000d050c000b0b200820096b20076a210820062007470d000b0b2005450d0020052001460d00200520014f0d02200020056a2c000041bf7f4c0d020b410121042002280218200020056a200120056b200228021c28020c1100000d0020022802184122200228021c28021011010021040b200341206a240020040f0b20002001200520011046000bc00201037f23004180016b220224002000280200210002400240024002400240200128020022034110710d0020002d0000210420034120710d012004ad42ff018341012001103f21000c020b20002d00002104410021000340200220006a41ff006a2004410f712203413072200341d7006a2003410a491b3a00002000417f6a21002004410476410f7122040d000b20004180016a22044181014f0d0220014101419087c0004102200220006a4180016a410020006b104221000c010b410021000340200220006a41ff006a2004410f712203413072200341376a2003410a491b3a00002000417f6a21002004410476410f7122040d000b20004180016a22044181014f0d0220014101419087c0004102200220006a4180016a410020006b104221000b20024180016a240020000f0b20044180011044000b20044180011044000b0b0020002802002001104b0b800201027f230041106b2202240020012802184198b0c00041092001411c6a28020028020c1100002103200241003a0005200220033a0004200220013602002002200036020c200241a1b0c000410b2002410c6a41f8afc000105c21012002200041046a36020c200141acb0c00041092002410c6a41b8b0c000105c1a20022d00042101024020022d0005450d00200141ff0171210041012101024020000d0020022802002201411c6a28020028020c210020012802182103024020012d00004104710d00200341eeafc0004102200011000021010c010b200341f0afc0004101200011000021010b200220013a00040b200241106a2400200141ff01714100470bb50201027f230041106b2202240002400240200028020022002d00004101460d00200128021841e0e2c50041042001411c6a28020028020c11000021010c010b2002200128021841e4e2c50041042001411c6a28020028020c1100003a000820022001360200200241003a0009200241003602042002200041016a36020c20022002410c6a4188b0c000105d1a20022d00082101024020022802042203450d00200141ff0171210041012101024020000d00024020034101470d0020022d000941ff0171450d00200228020022002d00004104710d0041012101200028021841f4afc00041012000411c6a28020028020c1100000d010b2002280200220128021841c8a4c60041012001411c6a28020028020c11000021010b200220013a00080b200141ff017141004721010b200241106a240020010b1c00200128021841b8aec60041052001411c6a28020028020c1100000b040041000b02000b02000b9e10020a7f017e23004180016b2202240002400240024020012802042203200128020022046b41e100490d000240024003402001200441206a3602002001280208220341186a280200210520032802102106200241e0006a41186a22034200370300200241e0006a41106a22074200370300200241e0006a41086a220842003703002002420037036020044120200241e0006a1000200241106a41186a22092003290300370300200241106a41106a220a2007290300370300200241106a41086a220b2008290300370300200220022903603703102002410036026020062005200241106a4120200241e0006a10012106024020022802602205417f460d0020022005360258200220053602542002200636025020012802082201280218210320012802102101200241e0006a41186a22074200370300200241e0006a41106a22084200370300200241e0006a41086a220942003703002002420037036020044120200241e0006a1000200241306a41186a2007290300370300200241306a41106a2008290300370300200241306a41086a20092903003703002002200229036037033020012003200241306a41201002200241086a2002280258360200200220022903503703000c050b20012001280200220441206a3602002001280208220541186a2802002106200528021021052003420037030020074200370300200842003703002002420037036020044120200241e0006a100020092003290300370300200a2007290300370300200b2008290300370300200220022903603703102002410036026020052006200241106a4120200241e0006a10012106024020022802602205417f470d0020012001280200220441206a3602002001280208220541186a2802002106200528021021052003420037030020074200370300200842003703002002420037036020044120200241e0006a100020092003290300370300200a2007290300370300200b2008290300370300200220022903603703102002410036026020052006200241106a4120200241e0006a1001210620022802602205417f470d0320012001280200220441206a3602002001280208220541186a2802002106200528021021052003420037030020074200370300200842003703002002420037036020044120200241e0006a100020092003290300370300200a2007290300370300200b2008290300370300200220022903603703102002410036026020052006200241106a4120200241e0006a1001210720022802602203417f470d0220012802042203200128020022046b41e0004b0d010c040b0b20022005360258200220053602542002200636025020012802082201280218210320012802102101200241e0006a41186a22074200370300200241e0006a41106a22084200370300200241e0006a41086a220942003703002002420037036020044120200241e0006a1000200241306a41186a2007290300370300200241306a41106a2008290300370300200241306a41086a20092903003703002002200229036037033020012003200241306a41201002200241086a2002280258360200200220022903503703000c030b20022003360258200220033602542002200736025020012802082201280218210320012802102101200241e0006a41186a22074200370300200241e0006a41106a22084200370300200241e0006a41086a220942003703002002420037036020044120200241e0006a1000200241306a41186a2007290300370300200241306a41106a2008290300370300200241306a41086a20092903003703002002200229036037033020012003200241306a41201002200241086a2002280258360200200220022903503703000c020b20022005360258200220053602542002200636025020012802082201280218210320012802102101200241e0006a41186a22074200370300200241e0006a41106a22084200370300200241e0006a41086a220942003703002002420037036020044120200241e0006a1000200241306a41186a2007290300370300200241306a41106a2008290300370300200241306a41086a20092903003703002002200229036037033020012003200241306a41201002200241086a2002280258360200200220022903503703000c010b024020042003460d0003402001200441206a3602002001280208220341186a280200210720032802102103200241e0006a41186a22084200370300200241e0006a41106a22094200370300200241e0006a41086a220a42003703002002420037036020044120200241e0006a1000200241106a41186a2008290300370300200241106a41106a2009290300370300200241106a41086a200a290300370300200220022903603703102002410036026020032007200241106a4120200241e0006a10012107024020022802602203417f460d0020022003360258200220033602542002200736025020012802082201280218210320012802102101200241e0006a41186a22074200370300200241e0006a41106a22084200370300200241e0006a41086a220942003703002002420037036020044120200241e0006a1000200241306a41186a2007290300370300200241306a41106a2008290300370300200241306a41086a20092903003703002002200229036037033020012003200241306a41201002200241086a2002280258360200200220022903503703000c030b200128020022042001280204470d000b0b200041003602000c010b200241e0006a41086a2002220141086a280200220336020020022001290200220c370360200020043602002000200c3702042000410c6a20033602000b20024180016a24000b950201057f230041e0026b22012400024020002802082202200028020c460d00200141b0016a4101722103200141d8016a210403402000200241b0016a36020820022d00002105200141b0016a200241016a41af01109a051a20054103460d01200141016a200141b0016a41af01109a051a200120053a00b0012003200141016a41af01109a051a02400240200541014b0d000240024020050e020001000b024020012802b801450d0020012802b401102a0b20012d00c0014105490d0220012802e801450d0220012802e401102a0c020b2004106a0c010b200128029802450d00200128029402102a0b20002802082202200028020c470d000b0b02402000280204450d002000280200102a0b200141e0026a24000baa0b01057f02402000280200220141124b0d00024002400240024002400240024002400240024002400240024020010e13000d0d010d0d020304050607080d090d0a0b0c000b0240200041086a280200220141054b0d0002400240024020010e06101000100102100b200041106a280200450d0f2000410c6a280200102a0f0b200041106a280200450d0e2000410c6a280200102a0f0b0240200041146a2802002202450d002000410c6a2802002101200241186c210203400240200141046a280200450d002001280200102a0b0240200141106a280200450d002001410c6a280200102a0b200141186a2101200241686a22020d000b0b200041106a280200450d0d200028020c102a0f0b0240200041146a2802002202450d002000410c6a28020021012002410c6c210203400240200141046a280200450d002001280200102a0b2001410c6a2101200241746a22020d000b0b200041106a280200450d0c200028020c102a0f0b02402000410c6a2802002201450d0020002802042203200141f0006c6a2104034002402003410c6a2802002202450d0020032802042101200241246c210203400240024020012d0000220541034b0d0002400240024020050e0404000102040b2001410c6a280200450d03200141086a280200102a0c030b2001410c6a280200450d02200141086a280200102a0c020b2001410c6a280200450d01200141086a280200102a0c010b200141086a280200450d00200141046a280200102a0b200141246a21012002415c6a22020d000b0b200341f0006a21010240200341086a280200450d002003280204102a0b2001210320012004470d000b0b200041086a280200450d0b2000280204102a0f0b0240200041086a2d00002201410c4b0d0020014106470d0b200041106a280200450d0b2000410c6a280200102a0f0b200041106a280200450d0a2000410c6a280200102a0f0b200041086a280200450d092000280204102a0f0b200041086a2d0000417f6a220141074b0d08024002400240024020010e08000c0c0c0c010203000b2000410c6a2201280200106a2001280200102a0f0b2000410c6a2201280200106a2001280200102a0f0b2000410c6a2201280200106a2001280200102a0f0b2000410c6a2201280200106a2001280200102a0f0b20002d0004417f6a220141024b0d0702400240024020010e03000102000b2000410c6a280200450d09200041086a280200102a0f0b200041086a2201280200106a2001280200102a0f0b2000410c6a2201280200106a2001280200102a0f0b20002d0004417f6a220141024b0d0602400240024020010e03000102000b2000410c6a280200450d08200041086a280200102a0f0b200041086a2201280200106a2001280200102a0f0b2000410c6a2201280200106a2001280200102a0f0b200041086a280200417f6a220141014b0d050240024020010e020001000b200041106a280200450d062000410c6a280200102a0f0b200041106a280200450d052000410c6a280200102a0f0b20002d00044104490d042000410c6a280200450d04200041086a280200102a0c040b200041086a280200450d032000280204102a0f0b200041086a2d0000417e6a220141024b0d0202400240024020010e03000102000b200041106a280200450d042000410c6a280200102a0f0b200041346a280200450d03200041306a280200102a0f0b200041306a280200450d022000412c6a280200102a0f0b02402000280204220141024b0d00024020010e03030003030b200041086a2201280200106a2001280200102a0f0b2000412c6a2201280200106a2001280200102a0f0b02402000410c6a280200450d00200041086a280200102a0b02402000411c6a2802002202450d00200041146a28020021012002410c6c210203400240200141046a280200450d002001280200102a0b2001410c6a2101200241746a22020d000b0b200041186a280200450d002000280214102a0f0b0b960301097f230041106b2202240002400240024002400240024020012802042203450d00200128020022042d0000210520012003417f6a22063602042001200441016a3602002006450d0020042d0001210720012003417e6a22063602042001200441026a3602002006450d0020042d0002210820012003417d6a22063602042001200441036a3602002006450d0020042d0003210620012003417c6a3602042001200441046a360200200241086a2001106c20022802080d022001280204200228020c2204490d022004417f4c0d0302400240024020040d004101210341010d010c050b2004102e2203450d0120012802042004490d03200320012802002004109a0521092001280204220a2004490d062001200a20046b3602042001200128020020046a3602002009450d040b20002004360208200020033602042000410c6a2004360200200020074108742005722008411074722006411874723602000c060b200441011037000b200041003602040c040b2003102a0b200041003602040c020b1036000b2004200a1044000b200241106a24000bcf0201067f0240024020012802042202450d00200128020022032d0000210420012002417f6a2205360204410121062001200341016a3602000240200441037122074103460d0002400240024020070e03000102000b20044102762107410021060c040b41012106024020050d000c040b20032d0001210520012002417e6a3602042001200341026a3602002005410874200472220141ffff0371418002490d03200141fcff03714102762107410021060c030b20054103490d01200341036a2d0000210620032f0001210720012002417c6a3602042001200341046a3602002007200641107472410874200472220141027621072001418080044921060c020b0240200441034d0d000c020b20054104490d012003280001210720012002417b6a3602042001200341056a36020020074180808080044921060c010b410121060b20002007360204200020063602000baf04010a7f230041d0006b2202240020022001106c0240024002400240024020022802000d00200128020422034160712204417f4c0d022002280204210502400240200341057622060d00410121070c010b200410282207450d040b02402005450d00410021080340200241003a00482008220941016a21082001280204417f6a21034100210402400240024003402003417f460d01200241286a20046a2001280200220a2d00003a0000200120033602042001200a41016a3602002002200441016a220a3a00482003417f6a2103200a2104200a4120470d000b200241086a41186a2204200241286a41186a290300370300200241086a41106a220a200241286a41106a290300370300200241086a41086a220b200241286a41086a2903003703002002200229032837030820062009470d020240200941017422032008200320084b1b220641ffffff3f712006470d002006410574220341004e0d020b1031000b0240200441ff0171450d00200241003a00480b200041003602002006450d052007102a0c050b0240024020090d002003102821070c010b200720094105742003102c21070b2007450d070b200720094105746a22032002290308370000200341186a2004290300370000200341106a200a290300370000200341086a200b29030037000020082005470d000b0b2000200636020420002007360200200041086a20053602000c010b200041003602000b200241d0006a24000f0b1036000b200441011037000b200341011037000b9203010a7f200041086a220228020021034100210420024100360200024002402003450d004100210541002106410021044100210702400340024002402004450d00200741057421080340200720034f0d062001200028020022096b2008460d02200920086a220a20014120109c05450d020240200620076a220b20034f0d00200920056a20086a2209200a290000370000200941186a200a41186a290000370000200941106a200a41106a290000370000200941086a200a41086a290000370000200841206a2108200741016a22072003490d010c050b0b41c4b2c000200b20031034000b200028020020074105746a21080340200720034f0d0520012008460d01200820014120109c05450d01200841206a2108200741016a22072003490d000b410021040c030b200541606a21052006417f6a2106200441016a2104200741016a22072003490d000b0b2004450d00200320074d0d00200028020020074105746a220820044105746b2008200320076b410574109b051a0b2002200320046b3602000f0b41e8b1c000200720031034000bfe0203017f017e0b7f024002400240024020012802082202ad42187e2203422088a70d002003a72204417f4c0d00200128020021050240024020040d00410421060c010b200410282206450d020b0240024020020d00410021070c010b2005200241186c6a210841002107200621010340200541086a2802002204417f4c0d02200528020021090240024020040d004101210a4100210b0c010b2004210b20041028220a450d050b200a20092004109a05210a200541146a2802002209417f4c0d022005410c6a280200210c0240024020090d004100210d4101210e0c010b2009210d20091028220e450d060b200e200c2009109a05210c200141146a2009360200200141106a200d3602002001410c6a200c360200200141086a2004360200200141046a200b3602002001200a360200200141186a2101200741016a2107200541186a22052008470d000b0b2000200736020820002002360204200020063602000f0b1036000b200441041037000b200441011037000b200941011037000bc90a03027f017e1c7f230041f0006b22022400024002400240024002400240024020012802082203ad42f0007e2204422088a70d002004a72205417f4c0d00200128020021060240024020050d00410421070c010b200510282207450d020b0240024020030d00410021080c010b2006200341f0006c6a2109410021082007210a0340200241c0006a41086a220b200641186a290000370300200241c0006a41106a220c200641206a290000370300200241c0006a41186a220d200641286a290000370300200241206a41086a220e200641386a29000037030020062900102104200241206a41106a220f200641c0006a290000370300200241206a41186a2210200641c8006a290000370300200241186a2211200641e8006a290000370300200241106a2212200641e0006a290000370300200241086a2213200641d8006a290000370300200220043703402002200629003037032020022006290050370300200628020c2214ad42247e2204422088a70d022004a72201417f4c0d0220062802002115200628020421160240024020010d00410421170c010b200110282217450d050b0240024020140d00410021180c010b201441246c211941002105410021180340024002400240024002400240201620056a22012d00000e050001020304000b2002200141146a2900003703602002200141196a290000370065200141056a2f0000200141076a2d000041107472211a200141106a280000211b2001410c6a280000211c200141086a280000211d200141016a280000211e4100211f0c040b200141106a280200221b417f4c0d08200141086a2802002120200141016a280000211e4101211f0240201b0d004100211c4101211d41012020201b109a051a0c040b201b211c201b1028221d450d0b201d2020201b109a051a0c030b200141106a280200221b417f4c0d07200141086a280200211f200141016a280000211e02400240201b0d004100211c4101211d0c010b201b211c201b1028221d450d0c0b201d201f201b109a051a4102211f0c020b200141106a280200221b417f4c0d06200141086a280200211f200141016a280000211e02400240201b0d004100211c4101211d0c010b201b211c201b1028221d450d0c0b201d201f201b109a051a4103211f0c010b2001410c6a280200221c417f4c0d05200141046a280200210102400240201c0d004101211a4100211d0c010b201c211d201c1028221a450d0c0b201a2001201c109a052201411874211e2001410876211a4104211f0b201720056a2201201f3a0000200141076a201a4110763a0000200141056a201a3b0000200141106a201b3600002001410c6a201c360000200141086a201d360000200141016a201e360000200141146a20022903603702002001411c6a200241e0006a41086a290300370200201841016a21182019200541246a2205470d000b0b200a2017360204200a410c6a2018360200200a41086a2014360200200a2002290340370210200a41186a200b290300370200200a2015360200200a2002290320370230200a41206a200c290300370200200a41286a200d290300370200200a41386a200e290300370200200a41c0006a200f290300370200200a41c8006a2010290300370200200a41e8006a2011290300370200200a41e0006a2012290300370200200a41d8006a2013290300370200200a2002290300370250200841016a2108200a41f0006a210a200641f0006a22062009470d000b0b200020083602082000200336020420002007360200200241f0006a24000f0b1036000b200541041037000b200141041037000b201b41011037000b201b41011037000b201b41011037000b201c41011037000b890203017f017e077f02400240024020012802082202ad420c7e2203422088a70d002003a72204417f4c0d00200128020021050240024020040d00410421060c010b200410282206450d020b0240024020020d00410021070c010b20052002410c6c6a210841002107200621040340200541086a2802002201417f4c0d02200528020021090240024020010d004101210a0c010b20011028220a450d050b200a20092001109a052109200441086a2001360200200441046a2001360200200420093602002004410c6a2104200741016a21072005410c6a22052008470d000b0b2000200736020820002002360204200020063602000f0b1036000b200441041037000b200141011037000bd70201037f024020002802082201450d002000280200220020014188016c6a2102200041f8006a2100034002400240200041887f6a22012d00002203410e4b0d00024002400240024020030e0f050505050500050501050205030505050b200041907f6a2d00004101470d042000419c7f6a280200450d04200041987f6a280200102a0c040b2000418c7f6a2d00004103470d030240200041947f6a280200450d00200041907f6a280200102a0b200041a07f6a280200450d032000419c7f6a280200102a0c030b2000418c7f6a2802000d02200041947f6a280200450d02200041907f6a280200102a0c020b200041907f6a2d00004105490d01200041b87f6a280200450d01200041b47f6a280200102a0c010b200041907f6a280200450d002000418c7f6a280200102a0b0240200141fc006a280200450d002000280200102a0b20004188016a210020014188016a2002470d000b0b0baf04010a7f230041d0006b2202240020022001106c0240024002400240024020022802000d00200128020422034160712204417f4c0d022002280204210502400240200341057622060d00410121070c010b200410282207450d040b02402005450d00410021080340200241003a00482008220941016a21082001280204417f6a21034100210402400240024003402003417f460d01200241286a20046a2001280200220a2d00003a0000200120033602042001200a41016a3602002002200441016a220a3a00482003417f6a2103200a2104200a4120470d000b200241086a41186a2204200241286a41186a290300370300200241086a41106a220a200241286a41106a290300370300200241086a41086a220b200241286a41086a2903003703002002200229032837030820062009470d020240200941017422032008200320084b1b220641ffffff3f712006470d002006410574220341004e0d020b1031000b0240200441ff0171450d00200241003a00480b200041003602002006450d052007102a0c050b0240024020090d002003102821070c010b200720094105742003102c21070b2007450d070b200720094105746a22032002290308370000200341186a2004290300370000200341106a200a290300370000200341086a200b29030037000020082005470d000b0b2000200636020420002007360200200041086a20053602000c010b200041003602000b200241d0006a24000f0b1036000b200441011037000b200341011037000b8a06030a7f037e017f23004190016b2202240020022001106c0240024002400240024020022802000d00200128020441216e220341216c2204417f4c0d01200228020421050240024020040d00410121060c010b200410282206450d030b02402005450d0041002107034020012802042208450d05200128020022092d0000210420012008417f6a220a3602042001200941016a360200200441014b0d054100210b0240024020040e020100010b41002104200241003a0088012008417e6a210803400240200a2004470d00200441ff0171450d08200241003a0088010c080b200241e8006a20046a200920046a220b41016a2d00003a0000200120083602042001200b41026a3602002002200441016a220b3a0088012008417f6a2108200b2104200b4120470d000b200241c8006a41186a200241e8006a41186a290300370300200241c8006a41106a200241e8006a41106a290300370300200241c8006a41086a200241e8006a41086a290300370300200220022903683703484101210b0b200741016a2108200241286a41186a200241c8006a41186a290300220c370300200241286a41106a200241c8006a41106a290300220d370300200241286a41086a200241c8006a41086a290300220e370300200241086a41086a2209200e370300200241086a41106a220a200d370300200241086a41186a220f200c37030020022002290348220c3703282002200c370308024020032007470d000240200741017422042008200420084b1b2203ad42217e220c422088a70d00200ca722044100480d000240024020070d002004102821060c010b2006200741216c2004102c21060b20060d01200441011037000b1031000b2006200741216c6a2204200b3a000020042002290308370001200441096a2009290300370000200441116a200a290300370000200441196a200f2903003700002008210720082005470d000b0b2000200336020420002006360200200041086a20053602000c040b200041003602000c030b1036000b200441011037000b200041003602002003450d002006102a0b20024190016a24000bc902010a7f230041106b22022400200241086a2001106c0240024020022802080d00024020012802042203417f4c0d00200228020c210402400240024020030d00410121050c010b200310282205450d010b02402004450d004100210641002107034002400240024020012802042208450d00200741016a21092001280200220a2d0000210b20012008417f6a3602042001200a41016a36020020072003460d010c020b200041003602002003450d072005102a0c070b024020062009200620094b1b22034100480d000240024020070d002003102821050c010b200520072003102c21050b20050d01200341011037000b1031000b200520076a200b3a0000200641026a21062009210720042009470d000b0b2000200336020420002005360200200041086a20043602000c030b200341011037000b1036000b200041003602000b200241106a24000b990a02137f017e230041e0006b22022400200241086a2001106c0240024020022802080d000240200128020441246e220341246c2204417f4c0d00200228020c210502400240024020040d00410421060c010b200410282206450d010b02400240024020050d00410021040c010b2002412d6a2107200241cb006a220841056a21094100210a4100210b0340024002402001280204220c450d002001280200220d2d000021042001200c417f6a220e3602042001200d41016a360200200441064b0d00024002400240024002400240024020040e0700070107030402000b20022001106c20022802000d0620012802042002280204220c490d06200c417f4c0d0c024002400240200c0d004101210441010d010c090b200c102e2204450d012001280204200c490d0620042001280200200c109a05210f2001280204220d200c490d072001200d200c6b36020420012001280200200c6a360200200f450d080b200241206a41086a200241386a41086a290200370300200220022902383703202004410876210f4104210d200c210e201041ffffff0771200441187472221021110c080b200c41011037000b41002104200241003a0058200c417e6a210c03400240200e2004470d00200441ff0171450d07200241003a00580c070b200241386a20046a200d20046a220f41016a2d00003a00002001200c3602042001200f41026a3602002002200441016a220f3a0058200c417f6a210c200f2104200f4120470d000b2002200829000037032020022009290000370025200228004721122002280043210e200228003f210c2002280238211120022f013c210420022d003e210f200741026a200241356a41026a2d00003a0000200720022f00353b00002004200f41107472210f4100210d0c060b200241386a2001106b200228023c220c450d04200228024421122002280240210e200228023821114101210d0c050b200241386a2001106b200228023c220c450d03200228024421122002280240210e200228023821114102210d0c040b200241386a2001106b200228023c220c450d02200228024421122002280240210e200228023821114103210d0c030b2004102a0c010b200c200d1044000b200041003602000240200b450d002006210403400240024020042d0000220141034b0d0002400240024020010e0404000102040b2004410c6a280200450d03200441086a280200102a0c030b2004410c6a280200450d02200441086a280200102a0c020b2004410c6a280200450d01200441086a280200102a0c010b200441086a280200450d00200441046a280200102a0b200441246a2104200a415c6a220a0d000b0b2003450d072006102a0c070b200241106a41086a2213200241206a41086a290300370300200220022903203703100240200b2003470d0002400240200341016a22042003490d00200341017422142004201420044b1b2204ad42247e2215422088a70d002015a7221441004e0d010b1031000b0240024020030d002014102821060c010b2006200341246c2014102c21060b2006450d03200421030b2006200b41246c6a220420123600102004200e36000c2004200c3600082004200f3b0005200420113600012004200d3a0000200441076a200f4110763a0000200420022903103700142004411c6a2013290300370000200a41246a210a200b41016a2204210b20042005470d000b0b2000200336020420002006360200200041086a20043602000c040b201441041037000b200441041037000b1036000b200041003602000b200241e0006a24000bb906020c7f047e230041b0016b2202240020022001106c02400240024002400240024020022802000d00200128020441286e220341286c2204417f4c0d02200228020421050240024020040d00410821060c010b200410282206450d040b02402005450d00410021070340200241003a00a8012007220841016a210720012802042109417f210a4100210402400240024002400240034020092004460d0120024188016a20046a2001280200220b2d00003a000020012009200a6a3602042001200b41016a3602002002200441016a220c3a00a801200a417f6a210a200c2104200c4120470d000b200241e8006a41186a220420024188016a41186a290300370300200241e8006a41106a220a20024188016a41106a290300370300200241e8006a41086a220d20024188016a41086a29030037030020022002290388013703682009200c6b220c41074d0d01200b290001210e2001200b41096a3602002001200c41786a360204200241286a41086a200d290300220f370300200241286a41106a200a2903002210370300200241286a41186a20042903002211370300200241086a41086a220a200f370300200241086a41106a220c2010370300200241086a41186a2209201137030020022002290368220f3703282002200f37030820032008470d04200841017422042007200420074b1b2203ad42287e220f422088a70d0c200fa722044100480d0c20080d022004102821060c030b200441ff0171450d00200241003a00a8010b200241286a41186a200241c8006a41186a290300370300200241286a41106a200241c8006a41106a290300370300200241286a41086a200241c8006a41086a29030037030020022002290348370328200041003602002003450d062006102a0c060b2006200841286c2004102c21060b2006450d070b2006200841286c6a22042002290308370300200a290300210f200c2903002110200929030021112004200e370320200441186a2011370300200441106a2010370300200441086a200f37030020072005470d000b0b2000200336020420002006360200200041086a20053602000c010b200041003602000b200241b0016a24000f0b1036000b200441081037000b200441081037000b1031000bf80404097f027e027f017e230041d0006b2202240020022001106c024002400240024002400240024020022802000d00200128020441306e220341306c2204417f4c0d01200228020421050240024020040d00410821060c010b200410282206450d030b02402005450d00410021070340200128020422084110490d07200741016a21092001280200220a41086a290000210b200a290000210c2001200a41106a3602002001200841706a220d36020441002104200241003a00482008416f6a210803400240200d2004470d00200441ff0171450d09200241003a00480c090b200241286a20046a200a20046a220e41106a2d00003a0000200120083602042001200e41116a3602002002200441016a220e3a00482008417f6a2108200e2104200e4120470d000b200241086a41186a2208200241286a41186a290300370300200241086a41106a220e200241286a41106a290300370300200241086a41086a220a200241286a41086a29030037030020022002290328370308024020032007470d00200741017422042009200420094b1b2203ad42307e220f422088a70d07200fa722044100480d070240024020070d002004102821060c010b2006200741306c2004102c21060b2006450d060b2006200741306c6a2204200b3703082004200c37030020042002290308370310200441186a200a290300370300200441206a200e290300370300200441286a20082903003703002009210720092005470d000b0b2000200336020420002006360200200041086a20053602000c060b200041003602000c050b1036000b200441081037000b200441081037000b1031000b200041003602002003450d002006102a0b200241d0006a24000ba40303087f017e017f230041d0046b22022400200241086a2001106c02400240024002400240024020022802080d00200128020441a0026e220341a0026c2204417f4c0d02200228020c21050240024020040d00410821060c010b200410282206450d040b024002402005450d004100210741002104410021080340200241b0026a2001107a2002290398034203510d02200841016a2109200241106a200241b0026a41a002109a051a024020082003470d0020072009200720094b1b2203ad42a0027e220a422088a70d09200aa7220b4100480d090240024020080d00200b102821060c010b20062004200b102c21060b2006450d080b200620046a200241106a41a002109a051a200741026a2107200441a0026a21042009210820052009470d000b0b2000200336020420002006360200200041086a20053602000c020b2000410036020002402008450d0020064198016a210903402009106a200941a0026a2109200441e07d6a22040d000b0b2003450d012006102a0c010b200041003602000b200241d0046a24000f0b1036000b200441081037000b200b41081037000b1031000bae0c04047f017e097f067e23004180066b22022400200241286a2001106c02400240024002400240024020022802280d000240200228022c2203450d0003402003417f6a22030d000b0b20012802042203450d01200128020022042d0000210520012003417f6a3602042001200441016a36020002400240200541ff00714103470d0020054118744118754100480d01420221060c060b200042033703680c060b20024198046a200110a50120022d0098044102460d02200241f0036a41206a20024198046a41206a280200360200200241f0036a41186a20024198046a41186a290300370300200241f0036a41106a20024198046a41106a290300370300200241f0036a41086a20024198046a41086a29030037030020022002290398043703f00341002103200241003a00c00220012802042107417f2105024002400240034020072003460d0120024180026a20036a200128020022082d00003a00002001200720056a3602042001200841016a3602002002200341016a22043a00c0022005417f6a210520042103200441c000470d000b200241c0056a41386a220320024180026a41386a290300370300200241c0056a41306a220920024180026a41306a290300370300200241c0056a41286a220a20024180026a41286a290300370300200241c0056a41206a220b20024180026a41206a290300370300200241c0056a41186a220c20024180026a41186a290300370300200241c0056a41106a220d20024180026a41106a290300370300200241c0056a41086a220e20024180026a41086a29030037030020022002290380023703c005200441ff017141c000490d0520024180056a41386a220f200329030037030020024180056a41306a2009290300220637030020024180056a41286a200a290300221037030020024180056a41206a200b290300221137030020024180056a41186a200c290300221237030020024180056a41106a200d290300221337030020024180056a41086a200e2903002214370300200220022903c005221537038005200241c0046a41306a2006370300200241c0046a41286a2010370300200241c0046a41206a2011370300200241c0046a41186a2012370300200241c0046a41106a2013370300200241c0046a41086a2014370300200241c0046a41386a200f290300370300200220153703c00420072004460d05200831000121112001200720056a3602042001200841026a360200201150450d01420021060c020b200341ff0171450d04200241003a00c0020c040b2007417f6a2004460d03200831000221122001200841036a3602002001200720046b417e6a36020442022011420f838622104204540d034201210620124208862011844204882010420c882211420120114201561b7e221120105a0d030b200241206a2001106c20022802200d0220022802242105200241086a2001109f012002290308a70d02200241086a41106a290300211320022903102112200241e8026a41206a200241f0036a41206a280200360200200241e8026a41186a200241f0036a41186a290300370300200241e8026a41106a200241f0036a41106a290300370300200241e8026a41086a200241f0036a41086a29030037030020024194036a200241c0046a41086a2903003702002002419c036a200241c0046a41106a290300370200200241a4036a200241c0046a41186a290300370200200241ac036a200241c0046a41206a290300370200200241b4036a200241e8046a290300370200200241bc036a200241f0046a290300370200200241c4036a200241f8046a290300370200200220022903f0033703e802200220022903c00437028c0320024180026a200241e8026a41e800109a051a0c030b200042033703680c040b200042033703680c030b420221060b20024198016a20024180026a41e800109a051a024020064202520d00200042033703680c020b200241306a20024198016a41e800109a051a0b200241e8026a2001108101024020022802e8024113460d002000200241306a41e800109a0522034188016a201337030020034180016a201237030020034190016a2005360200200341f8006a2011370300200320103703702003200637036820034198016a200241e8026a418801109a051a0c010b200042033703680b20024180066a24000bfb1002147f037e230041c0026b22022400200241086a2001106c0240024020022802080d000240200128020441c4006e220341c4006c2204417f4c0d00200228020c210502400240024020040d00410421060c010b200410282206450d010b024002402005450d0020024198026a410772210741002108034002400240024002400240024020012802042209450d002001280200220a2d0000210420012009417f6a220b3602042001200a41016a360200200441014b0d000240024020040e020001000b200b41034d0d01200a280001210c20012009417b6a3602042001200a41056a360200200241d4016a41026a200241d8016a41026a2d00003a0000200241b8016a41086a200241f8016a41086a290200370300200241b8016a41106a200241f8016a41106a290200370300200241b8016a41186a200241f8016a41186a2d00003a000020024198016a41086a20024198026a41086a29010037030020024198016a41106a20024198026a41106a29010037030020024198016a41186a20024198026a41186a290100370300200220022f00d8013b01d401200220022902f8013703b801200220022901980237039801200220022f01f4013b0196014100210d0c030b4100210e200241003a00b8022009417e6a210d03400240200b200e2204470d000240200441ff0171450d00200241003a00b8020b4102210d0c040b20024198026a20046a200a20046a220e41016a2d00003a00002001200d3602042001200e41026a3602002002200441016a220e3a00b802200d417f6a210d200e4120470d000b200241f4016a41026a220f20022d009a023a0000200241d8016a41086a2210200741086a290000370300200241d8016a41106a2211200741106a290000370300200241d8016a41186a2212200741186a2d00003a0000200220022f0198023b01f401200220072900003703d801200b200e460d01200228009b022113200a200e6a220a41016a2d0000210b2001200d3602042001200a41026a360200200b41014b0d014100211402400240200b0e020100010b4100210d200241003a00b802200e20096b41026a210b200920046b417c6a210403400240200b200d6a0d00200d41ff0171450d04200241003a00b8020c040b20024198026a200d6a200a200d6a220e41026a2d00003a0000200120043602042001200e41036a3602002002200d41016a220e3a00b8022004417f6a2104200e210d200e4120470d000b200241f8016a41186a20024198026a41186a290300370300200241f8016a41106a20024198026a41106a290300370300200241f8016a41086a20024198026a41086a29030037030020022002290398023703f801410121140b20024198016a41186a200241f8016a41186a29030037030020024198016a41106a200241f8016a41106a29030037030020024198016a41086a200241f8016a41086a290300370300200241d4016a41026a200f2d00003a0000200241b8016a41086a2010290300370300200241b8016a41106a2011290300370300200241b8016a41186a20122d00003a0000200220022903f80137039801200220022f01f4013b01d401200220022903d8013703b8014101210d201421152013210c0c020b20024192016a41026a200241d4016a41026a2d00003a0000200241f8006a41086a200241b8016a41086a290300370300200241f8006a41106a200241b8016a41106a290300370300200241f8006a41186a200241b8016a41186a2d00003a0000200241d8006a41086a20024198016a41086a290300370300200241d8006a41106a20024198016a41106a290300370300200241d8006a41186a20024198016a41186a290300370300200220022f01d4013b019201200220022903b8013703782002200229039801370358200220022f0196013b01560c020b4102210d0b20024192016a41026a2204200241d4016a41026a2d00003a0000200241f8006a41086a220a200241b8016a41086a290300370300200241f8006a41106a220b200241b8016a41106a290300370300200241f8006a41186a2209200241b8016a41186a2d00003a0000200241d8006a41086a220f20024198016a41086a290300370300200241d8006a41106a221020024198016a41106a290300370300200241d8006a41186a221120024198016a41186a290300370300200220022f01d4013b019201200220022903b8013703782002200229039801370358200220022f0196013b0156200d4102460d00200841016a210e200241d2006a41026a221220042d00003a0000200241386a41086a2213200a290300370300200241386a41106a220a200b290300370300200241386a41186a220b20092d00003a0000200241186a41086a2209200f290300370300200241186a41106a220f2010290300370300200241186a41186a22102011290300370300200220022f0192013b01522002200229037837033820022002290358370318200220022f01563b011620032008470d02024020084101742204200e2004200e4b1b2203ad42c4007e2216422088a70d002016a7220441004e0d020b1031000b200041003602002003450d082006102a0c080b0240024020080d002004102821060c010b2006200841c4006c2004102c21060b2006450d030b2006200841c4006c6a2204200d3a00002004200c360004200441036a20122d00003a0000200420022f01523b0001200b2d0000210d200a29030021162013290300211720022903382118200420153a002120042018370008200441106a2017370000200441186a2016370000200441206a200d3a00002004413a6a2010290300370000200441326a200f2903003700002004412a6a200929030037000020042002290318370022200420022f01163b0042200e2108200e2005470d000b0b2000200336020420002006360200200041086a20053602000c040b200441041037000b200441041037000b1036000b200041003602000b200241c0026a24000baf04010a7f230041d0006b2202240020022001106c0240024002400240024020022802000d00200128020422034160712204417f4c0d022002280204210502400240200341057622060d00410121070c010b200410282207450d040b02402005450d00410021080340200241003a00482008220941016a21082001280204417f6a21034100210402400240024003402003417f460d01200241286a20046a2001280200220a2d00003a0000200120033602042001200a41016a3602002002200441016a220a3a00482003417f6a2103200a2104200a4120470d000b200241086a41186a2204200241286a41186a290300370300200241086a41106a220a200241286a41106a290300370300200241086a41086a220b200241286a41086a2903003703002002200229032837030820062009470d020240200941017422032008200320084b1b220641ffffff3f712006470d002006410574220341004e0d020b1031000b0240200441ff0171450d00200241003a00480b200041003602002006450d052007102a0c050b0240024020090d002003102821070c010b200720094105742003102c21070b2007450d070b200720094105746a22032002290308370000200341186a2004290300370000200341106a200a290300370000200341086a200b29030037000020082005470d000b0b2000200636020420002007360200200041086a20053602000c010b200041003602000b200241d0006a24000f0b1036000b200441011037000b200341011037000bb005020c7f037e230041f0006b2202240020022001106c0240024002400240024020022802000d00200128020441246e220341246c2204417f4c0d02200228020421050240024020040d00410421060c010b200410282206450d040b02402005450d00410021070340200241003a00682007220841016a210720012802042109417f210a410021040240024002400240034020092004460d01200241c8006a20046a2001280200220b2d00003a000020012009200a6a3602042001200b41016a3602002002200441016a220c3a0068200a417f6a210a200c2104200c4120470d000b200241286a41186a2204200241c8006a41186a290300370300200241286a41106a220a200241c8006a41106a290300370300200241286a41086a220d200241c8006a41086a290300370300200220022903483703282009200c6b220c4104490d01200b28000121092001200b41056a3602002001200c417c6a360204200241086a41086a220c200d290300370300200241086a41106a220b200a290300370300200241086a41186a220a20042903003703002002200229032837030820032008470d030240200841017422042007200420074b1b2203ad42247e220e422088a70d00200ea7220441004e0d030b1031000b200441ff0171450d00200241003a00680b200041003602002003450d052006102a0c050b0240024020080d002004102821060c010b2006200841246c2004102c21060b2006450d070b2006200841246c6a22042002290308370200200c290300210e200b290300210f200a290300211020042009360220200441186a2010370200200441106a200f370200200441086a200e37020020072005470d000b0b2000200336020420002006360200200041086a20053602000c010b200041003602000b200241f0006a24000f0b1036000b200441041037000b200441041037000be60403087f017e017f230041f0016b22022400200241086a2001106c02400240024002400240024020022802080d00200128020441f0006e220341f0006c2204417f4c0d02200228020c21050240024020040d00410421060c010b200410282206450d040b024002402005450d00410021074100210841002109034020024180016a2001107f200228028401450d02200941016a2104200241106a20024180016a41f000109a051a024020092003470d0020072004200720044b1b2203ad42f0007e220a422088a70d09200aa7220b4100480d090240024020090d00200b102821060c010b20062008200b102c21060b2006450d080b200620086a200241106a41f000109a051a200741026a2107200841f0006a21082004210920052004470d000b0b2000200336020420002006360200200041086a20053602000c020b2000410036020002402009450d00200620086a210120062107034002402007410c6a2802002209450d0020072802042104200941246c210903400240024020042d0000220841034b0d0002400240024020080e0404000102040b2004410c6a280200450d03200441086a280200102a0c030b2004410c6a280200450d02200441086a280200102a0c020b2004410c6a280200450d01200441086a280200102a0c010b200441086a280200450d00200441046a280200102a0b200441246a21042009415c6a22090d000b0b200741f0006a21040240200741086a280200450d002007280204102a0b2004210720012004470d000b0b2003450d012006102a0c010b200041003602000b200241f0016a24000f0b1036000b200441041037000b200b41041037000b1031000b9f0a03077f037e057f230041d0026b2202240041002103200241003a00c8022001280204417f6a210402400240024003402004417f460d01200241a8026a20036a200128020022052d00003a0000200120043602042001200541016a3602002002200341016a22053a00c8022004417f6a21042005210320054120470d000b200241e8006a41086a200241a8026a41086a290300370300200241e8006a41106a200241a8026a41106a290300370300200241e8006a41186a200241a8026a41186a290300370300200220022903a80237036820022001106c2002280200450d01200041003602040c020b0240200341ff0171450d00200241003a00c8020b200041003602040c010b2002280204210641002104200241003a00c80220012802042107417f21030240034020072004460d01200241a8026a20046a200128020022082d00003a00002001200720036a3602042001200841016a3602002002200441016a22053a00c8022003417f6a21032005210420054120470d000b200241a8016a41086a200241a8026a41086a2903002209370300200241a8016a41106a200241a8026a41106a290300220a370300200241a8016a41186a200241a8026a41186a290300220b37030020024188016a41086a200937030020024188016a41106a200a37030020024188016a41186a200b370300200220022903a80222093703a801200220093703880141002104200241003a00c802200720056b210c200720036a210303400240200c2004470d000240200441ff0171450d00200241003a00c8020b200041003602040c030b200241a8026a20046a200820046a220541016a2d00003a0000200120033602042001200541026a3602002002200441016a22053a00c8022003417f6a21032005210420054120470d000b200241e8016a41086a200241a8026a41086a2903002209370300200241e8016a41106a200241a8026a41106a290300220a370300200241e8016a41186a200241a8026a41186a290300220b370300200241c8016a41086a22042009370300200241c8016a41106a2203200a370300200241c8016a41186a2205200b370300200220022903a80222093703e801200220093703c801200241a8026a20011076024020022802a8022201450d00200241c8006a41086a2208200241e8006a41086a290300370300200241c8006a41106a2207200241e8006a41106a290300370300200241c8006a41186a220c200241e8006a41186a290300370300200241286a41086a220d20024188016a41086a290300370300200241286a41106a220e20024188016a41106a290300370300200241286a41186a220f20024188016a41186a29030037030020022002290368370348200220022903880137032820022902ac022109200241086a41186a22102005290300370300200241086a41106a22052003290300370300200241086a41086a22032004290300370300200220022903c801370308200020093702082000200136020420002006360200200041106a2002290348370200200041186a2008290300370200200041206a2007290300370200200041286a200c290300370200200041306a2002290328370200200041386a200d290300370200200041c0006a200e290300370200200041c8006a200f290300370200200041e8006a2010290300370200200041e0006a2005290300370200200041d8006a2003290300370200200041d0006a20022903083702000c020b200041003602040c010b0240200441ff0171450d00200241003a00c8020b200041003602040b200241d0026a24000b9505020c7f017e230041b0056b22022400200241086a2001106c0240024002400240024020022802080d0020012802044190016e22034190016c2204417f4c0d02200228020c21050240024020040d00410821060c010b200410282206450d040b02402005450d00200241a0036a410472210741002108410021044100210903400240024002402001280204220a450d002001280200220b2d0000210c2001200a417f6a3602042001200b41016a360200200c41014b0d004113210a024002400240200c0e020100010b200241a8046a200110810120022802a8044113460d02200241a0036a200241a8046a418801109a051a2001280204220c4104490d012001280200220a280000210d2001200c417c6a3602042001200a41046a36020020022802a003210a2002419c026a2007418401109a051a200a4113460d0220024198016a2002419c026a418401109a051a200a4114460d020b200941016a210c200241146a20024198016a418401109a051a20092003470d0302402008200c2008200c4b1b2203ad4290017e220e422088a70d00200ea7220b41004e0d030b1031000b200241a0036a106a0b2000410036020002402009450d00200621010340024020012802004113460d002001106a0b20014190016a2101200441f07e6a22040d000b0b2003450d052006102a0c050b0240024020090d00200b102821060c010b20062004200b102c21060b2006450d070b200620046a2209200a360200200941046a200241146a418401109a051a20094188016a200d360200200841026a210820044190016a2104200c21092005200c470d000b0b2000200336020420002006360200200041086a20053602000c010b200041003602000b200241b0056a24000f0b1036000b200441081037000b200b41081037000bf3910107087f017e067f087e087f017e017f230041f0096b2202240002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024020012802042203450d00200128020022042d0000210520012003417f6a22063602042001200441016a360200200541144b0d16200141046a210720050e150102030405060708090a0b0c0d0e0f101112131415010b200041133602000c4c0b02402006450d0020042d0001210620012003417e6a22083602042001200441026a360200200641054b0d004101210902400240024002400240024020060e06510001020304510b20022001106c20022802000d05200128020420022802042204490d052004417f4c0d1e02400240024020040d00410121050c010b2004102e2205450d0120072802002004490d06200520012802002004109a051a200128020422032004490d212001200320046b3602042001200128020020046a3602000b2005450d062004ad220a422086200a84210a410221090c510b200441011037000b20084108490d042004290002210a2001200341766a36020420012004410a6a360200410321090c4f0b200241086a2001106c20022802080d032001280204200228020c2204490d032004417f4c0d1c02400240024020040d00410121050c010b2004102e2205450d0120072802002004490d04200520012802002004109a051a200128020422032004490d202001200320046b3602042001200128020020046a3602000b2005450d042004ad220a422086200a84210a410421090c4f0b200441011037000b200241206a2001106c20022802200d02200728020041186e220b41186c2204417f4c0d1b2002280224210c0240024020040d00410421050c010b200410282205450d1f0b0240200c450d004100210d41002106410021080340200241186a2001106c02400240024020022802180d002001280204200228021c2204490d002004417f4c0d2002400240024020040d004101210e0c010b2004102e220e450d3920072802002004490d01200e20012802002004109a051a200128020422032004490d262001200320046b3602042001200128020020046a3602000b200241106a2001106c024020022802100d00200128020420022802142203490d002003417f4c0d22024002400240024020030d004101210f0c010b2003102e220f450d0120072802002003490d02200f20012802002003109a051a200128020422092003490d2a2001200920036b3602042001200128020020036a3602000b200841016a21092008200b470d06200d2009200d20094b1b220bad42187e220a422088a70d55200aa7221041004e0d050c550b200341011037000b200f102a0b2004450d010b200e102a0b02402008450d002005210103400240200141046a280200450d002001280200102a0b0240200141106a280200450d002001410c6a280200102a0b200141186a2101200641686a22060d000b0b200b0d050c060b0240024020080d002010102821050c010b200520062010102c21050b2005450d240b200520066a2208200e360200200841146a2003ad220a3e02002008410c6a200a422086200fad84370200200841046a2004ad220a422086200a84370200200d41026a210d200641186a210620092108200c2009470d000b0b2005450d02200cad422086200bad84210a410521090c4d0b200241306a2001106c20022802300d012007280200410c6e220e410c6c2204417f4c0d1a2002280234210f0240024020040d00410421050c010b200410282205450d220b024002400240200f450d004100210841002103410021090340200241286a2001106c20022802280d032001280204200228022c2204490d032004417f4c0d1e0240024020040d004101210d0c010b2004102e220d450d3720072802002004490d03200d20012802002004109a051a200128020422062004490d272001200620046b3602042001200128020020046a3602000b200941016a210602402009200e470d0020082006200820064b1b220ead420c7e220a422088a70d50200aa7220b4100480d500240024020090d00200b102821050c010b20052003200b102c21050b2005450d280b200520036a2209200d360200200941086a2004360200200941046a2004360200200841026a21082003410c6a210320062109200f2006470d000b0b2005450d03200fad422086200ead84210a410621090c4e0b200d102a0b02402009450d002005210103400240200141046a280200450d002001280200102a0b2001410c6a2101200341746a22030d000b0b200e450d010b2005102a0b200041133602000c4b0b02402006450d0020012003417e6a3602042001200441026a3602000b200041133602000c4a0b02402006450d0020042d0001210520012003417e6a3602042001200441026a36020020050d00200241386a2001109e012002290338a70d002002290340210a20004102360200200041086a200a370300200041106a200241e8086a41f800109a051a0c4a0b200041133602000c490b02402006450d0020042d0001210520012003417e6a3602042001200441026a36020020050d00200241e0076a2001107e20022802e00722010d130b200041133602000c480b02402006450d0020012003417e6a3602042001200441026a3602000b200041133602000c470b02402006450d0020042d0001210520012003417e6a3602042001200441026a360200200541024b0d00024002400240024020050e03000102000b200241e8086a200110a50120022d00e8084102460d0320024184096a290200210a200241fc086a2902002111200241e8086a41106a2802002107200241f4086a2802002104200241f0086a280200210320022802ec08210520022802e8082106200241c8006a2001109f0120022802480d03200241c8006a41106a290300211241012101200229035021130c020b200241e8086a200110a50120022d00e8084102460d02200241e0076a41086a20024180096a290300370300200241e0076a41106a20024188096a2802003602002002200241e8086a41106a2903003703e007200241f4086a2802002104200241e8086a41086a280200210320022802ec08210520022802e8082106200241f8006a2001109f012002290378a70d02200241f8006a41106a29030021122002290380012113200241e0006a2001109f012002290360a70d02200241e0006a41106a290300211420022903682115200241a8056a41106a200241e0076a41106a280200360200200241a8056a41086a200241e0076a41086a290300370300200220022903e00722163703a805200241b4056a290200210a20022902ac0521112016a7210741022101420021160c010b200241e8086a200110a50120022d00e8084102460d0120024184096a290200210a200241fc086a2902002111200241e8086a41106a22092802002107200241f4086a2802002104200241e8086a41086a2208280200210320022802ec08210520022802e8082106200241e8086a200110a50120022d00e8084102460d01200241e0076a41206a220d200241e8086a41206a280200360200200241e0076a41186a220e200241e8086a41186a290300370300200241e0076a41106a2009290300370300200241e0076a41086a2008290300370300200220022903e8083703e00720024190016a2001109f01200229039001a70d0120024190016a41106a29030021172002290398012118200241e8076a2903002112200241f0076a2903002115200e2903002114200d350200211620022903e0072113410321010b20004105360200200041e0006a2017370200200041d8006a2018370200200041c8006a2014370200200041c0006a2015370200200041386a2012370200200041306a2013370200200041286a200a370200200041206a2011370200200041d0006a20163702002000411c6a2007360200200041186a2004360200200041146a2003360200200041106a20053602002000410c6a2006360200200041086a2001360200200041e8006a200229038806370300200041f0006a20024188066a41086a290300370300200041f8006a20024188066a41106a29030037030020004180016a20024188066a41186a2903003703000c470b200041133602000c460b2006450d4120042d0001210520012003417e6a22193602042001200441026a3602002005410c4b0d41410421104100211a4100211b02400240024002400240024002400240024002400240024020050e0d0001024e030405060708090a0b000b200241e0076a200110a50120022d00e0074102460d4c200241ec076a290200211120024180086a280200210b200241ff076a2d00002108200241fe076a2d0000210d200241fd076a2d0000210c200241f9076a2800002104200241f5076a280000210f200241f4076a2d0000210e20022902e407210a20022802e0072106200241a8016a2001109f0120022903a801a70d4c20072802002203450d4c200241b8016a290300211320022903b0012112200128020022052d0000210920012003417f6a360204410121102001200541016a36020020094103492201450d4c200441807e71410020011b211b2004410020011b211a0c4d0b200241c0016a2001109f0120022903c001a70d4b200241d0016a290300211120022903c801210a410221104100211b0c4c0b200241d8016a2001109f0120022903d801a70d4a200241e8016a290300211120022903e001210a410321104100210c4100211a4100211b0c4b0b200241f0016a2001109f0120022903f001a70d4920024180026a290300211120022903f801210a410521104100211b0c4a0b20024188026a2001106c2002280288020d48200728020041246e221c41246c2204417f4c0d19200228028c02211d0240024020040d00410421060c010b200410282206450d240b0240201d450d0041232105200241f0076a211e41002107410021040340200241e0076a200110a501024020022d00e00722094102470d00201c450d4b2006102a0c4b0b200441016a2103201e290300210a20022903e807211120022d008308210820022d008208210d20022d008108210e20022800fd07210f20022800f907210b20022d00f807210c20022802e407211020022d00e307211b20022d00e207211920022d00e107211f02402004201c470d0020072003200720034b1b221cad42247e2212422088a70d4d2012a722204100480d4d0240024020040d002020102821060c010b20062005415d6a2020102c21060b2006450d270b200620056a220420083a0000200441656a2208200a370008200820113700002004417f6a200d3a00002004417e6a200e3a00002004417a6a200f360000200441766a200b360000200441756a200c3a0000200441616a2010360000200441606a201b3a00002004415f6a20193a00002004415e6a201f3a00002004415d6a20093a0000200741026a2107200541246a210520032104201d2003470d000b0b2006450d48201dad422086201cad84210a42002111410621104100211b0c490b410721104100211b0c480b2019450d4620042d0002210920012003417d6a3602042001200441036a360200200941034f0d46410821104100211b0c470b200241e0076a200110a50120022d00e0074102460d45200241f9076a280000221a41807e71211b200241ec076a290200211120024180086a280200210b200241ff076a2d00002108200241fe076a2d0000210d200241fd076a2d0000210c200241f5076a280000210f200241f4076a2d0000210e20022902e407210a20022802e0072106410921100c460b20024190026a2001106c2002280290020d442002280294022106410a21104100211b0c450b410b21104100211b0c440b410c21104100211b0c430b200241e0076a2001106d20022802e0072206450d4120022902e407210a42002111410d21104100211b0c420b02402006450d0020042d0001210520012003417e6a3602042001200441026a36020020050d00200241e8086a200110e80120022d00e8084101460d00200241e0076a200241e8086a41017241e000109a051a20024198026a2001106c2002280298020d002001280204200228029c022204490d002004417f4c0d12024002400240024020040d004101210341010d010c040b2004102e2203450d0120072802002004490d02200320012802002004109a052105200128020422062004490d212001200620046b3602042001200128020020046a3602002005450d030b20024188066a200241e0076a41e000109a051a200241a8056a20024188066a41e000109a051a2000410c6a2004360200200041086a20043602002000200336020420004107360200200041106a200241a8056a41e000109a051a20004180016a20024188076a41106a290300370300200041f8006a20024188076a41086a290300370300200041f0006a2002290388073703000c470b200441011037000b2003102a0b200041133602000c440b2006450d3e20042d0001210520012003417e6a221d3602042001200441026a360200200541104b0d3e410e211a4100211c024002400240024002400240024002400240024002400240024002400240024020050e11000102030405060708090a0b0c4d0d0e0f000b200241e0076a200110810120022802e0074113460d4d200241e8086a200241e0076a418801109a051a41880110282206450d382006200241e8086a418801109a052104200241a0026a2001109f01024020022903a002a7450d002004106a2004102a0c4e0b200241b0026a290300210a2004411876211c20022903a8022211422088a7211f2011a7211b4101211a0c4c0b200241b8026a2001106c20022802b8020d4c20022802bc022206411876211c4102211a0c4a0b200241c0026a2001106c20022802c0020d4b20072802002204450d4b20022802c4022106200128020022052d0000210320012004417f6a3602042001200541016a360200200341ff0071220d41064b0d4b2006411876211c200341077621084103211a0c480b200241c8026a2001106c20022802c8020d4a20072802002204450d4a20022802cc022106200128020022052d0000210320012004417f6a3602042001200541016a360200200341ff0071220d41064b0d4a2006411876211c200341077621084104211a0c470b201d4104490d492004280002210620012003417a6a3602042001200441066a3602002006411876211c4105211a0c470b200241e0076a200110810120022802e0074113460d48200241e8086a200241e0076a418801109a051a41880110282206450d342006200241e8086a418801109a05411876211c4106211a0c460b200241e0076a200110810120022802e0074113460d47200241e8086a200241e0076a418801109a051a41880110282206450d342006200241e8086a418801109a05411876211c4107211a0c450b200241e0076a200110810120022802e0074113460d46200241e8086a200241e0076a418801109a051a41880110282206450d342006200241e8086a418801109a05411876211c4108211a0c440b41002105200241003a0088092003417e6a2109417d21060340024020092005470d00200541ff0171450d47200241003a0088090c470b200241e8086a20056a200420056a220741026a2d00003a00002001200320066a3602042001200741036a3602002002200541016a22073a0088092006417f6a21062007210520074120470d000b200241b0056a2205200241f1086a290000370300200241a8056a41106a200241f9086a290000370300200241bf056a220620024180096a290000370000200220022900e908220a3703a805200320076b2203417e6a4104490d4520022d00ac05210920022f01aa05210d200241b5056a330000211120023500b105211220052d0000211b20022f01ae05211a200241bd056a3100002113200241bb056a330000211620023500b705211820022d00e80821082006280000210f20022d00ad05211c20022d00a905211020022800c305210b20022d00be05210e200420076a220441026a280000210c20012003417a6a22053602042001200441066a220736020020054104490d45200d2009411074722106200aa7210d200728000021192001200341766a36020420012004410a6a36020020182016201342108684422086844208862012201142208684221142ffffffffffff3f83221242288884210a2012421886201a201b41107472ad42ffffff078384a7211b2011420888a7211f4109211a0c440b41002105200241003a0088092003417e6a21072003417d6a21030340024020072005470d00200541ff0171450d46200241003a0088090c460b200241e8086a20056a200420056a220641026a2d00003a0000200120033602042001200641036a3602002002200541016a22063a0088092003417f6a21032006210520064120470d000b200241b0056a200241f1086a290000370300200241bf056a220120024180096a290000370000200241a8056a41106a200241f9086a290000370300200220022900e90822113703a80520022f01aa0520022d00ac0541107472210620022901ae052212422088a7211f20022d00e80821082001280000210f200241b6056a290100210a20022d00ad05211c20022d00a905211020022800c305210b20022d00be05210e2011a7210d2012a7211b410a211a0c430b200241d0026a2001106c20022802d0020d4320022802d4022206411876211c410b211a0c410b200241e8026a2001106c20022802e8020d4220022802ec022106200241e0026a2001106c20022802e0020d4220022802e402211b200241d8026a2001106c20022802d8020d4220022802dc02211f2006411876211c410c211a0c410b41002105200241003a0088092003417e6a21072003417d6a21030340024020072005470d00200541ff0171450d43200241003a0088090c430b200241e8086a20056a200420056a220641026a2d00003a0000200120033602042001200641036a3602002002200541016a22063a0088092003417f6a21032006210520064120470d000b200241b0056a200241f1086a290000370300200241bf056a220120024180096a290000370000200241a8056a41106a200241f9086a290000370300200220022900e90822113703a80520022f01aa0520022d00ac0541107472210620022901ae052212422088a7211f20022d00e80821082001280000210f200241b6056a290100210a20022d00ad05211c20022d00a905211020022800c305210b20022d00be05210e2011a7210d2012a7211b410d211a0c400b41002105200241003a0088092003417e6a21072003417d6a21030340024020072005470d00200541ff0171450d42200241003a0088090c420b200241e8086a20056a200420056a220641026a2d00003a0000200120033602042001200641036a3602002002200541016a22063a0088092003417f6a21032006210520064120470d000b200241b0056a2201200241f1086a290000370300200241a8056a41106a200241f9086a290000370300200241bf056a220420024180096a290000370000200220022900e90822123703a80520023500b705200241bb056a330000200241bd056a310000421086844220868442088620023500b105200241b5056a33000042208684221142288884210a201142188620023301ae0520013100004210868484a7211b20022f01aa0520022d00ac054110747221062011420888a7211f20022d00e80821082004280000210f20022d00ad05211c20022d00a905211020022800c305210b20022d00be05210e2012a7210d410f211a0c3f0b41002105200241003a0088092003417e6a21092003417d6a21060340024020092005470d00200541ff0171450d41200241003a0088090c410b200241e8086a20056a200420056a220741026a2d00003a0000200120063602042001200741036a3602002002200541016a22073a0088092006417f6a21062007210520074120470d000b200241b0056a200241f1086a290000370300200241b8056a200241f9086a290000370300200241bf056a220520024180096a290000370000200220022900e908220a3703a805200241d8076a41046a20022d00ac053a0000200241e8066a41046a200241b5056a2f00003b01002002200a3e02d807200220022800b1053602e8062003417e6a2007460d3f20022d00e808210820022800ad05211c2005290000211120022900b705210a200420076a220441026a2d00002109200120063602042001200441036a360200200941064b0d3f20024190076a200241e8066a41046a2f01003b0100200220022802d807220d3602d007200220022802e80636028c072002201c360288072002200a37019207200a423888201142088684a7210e4110211a20022f01d207200241d8076a41046a2d00004110747221062011422088a7210b2002290089072212422088a7211f20024191076a290000210a20022d00d10721102011a7210f2012a7211b0c3e0b4111211a0c3d0b200241e0076a200110e90120022d00e0074105470d0d200041133602000c420b200241e0076a200110e90120022d00e0074105470d0d200041133602000c410b2006450d3720042d0001210520012003417e6a3602042001200441026a360200200541094b0d37024002400240024002400240024002400240024020050e0a00010203040506070809000b200241e0076a2001107520022802e0072204450d40200241e8076a280200210520022802e4072103200241f0026a2001106c024020022802f002450d0020030d400c410b0240200728020022094104490d0020022802f402210620012802002208280000210720012009417c6a220d3602042001200841046a360200200d4110490d002008410c6a29000021122008290004211320012009416c6a3602042001200841146a360200410121010c3f0b20030d3f0c400b200241e0076a2001107520022802e0072204450d3f200241e8076a280200210520022802e4072103200241f8026a2001106c024020022802f802450d002003450d400c3f0b0240200728020022094104490d0020022802fc02210620012802002208280000210720012009417c6a220d3602042001200841046a360200200d4110490d002008410c6a29000021122008290004211320012009416c6a3602042001200841146a360200410221010c3e0b20030d3e0c3f0b20024190036a2001106c2002280290030d3e2002280294032104200241e0076a200110a50120022d00e0074102460d3e20024188066a41086a200241f8076a29030037030020024188066a41106a20024180086a2802003602002002200241e0076a41106a29030037038806200241ec076a2802002107200241e0076a41086a280200210620022802e407210520022802e007210320024188036a2001106c2002280288030d3e200228028c03210920024180036a2001106c2002280280030d3e20024198066a280200210820024190066a29030021122002290388062113200228028403ad210a42002111410321010c3c0b20024198036a2001106c2002280298030d3d41042101200228029c0321040c3b0b200241a0036a2001106c20022802a0030d3c4105210120022802a40321040c3a0b200241e0076a200110a50120022d00e0074102460d3b20024188066a41086a200241f8076a29030037030020024188066a41106a20024180086a2802003602002002200241e0076a41106a29030037038806200241e0076a41086a290300211620022903e0072118200241b0036a2001109f0120022903b003a70d3b200241b0036a41106a290300211120022903b803210a200241a8036a2001106c20022802a8030d3b20022802ac032108200241a8056a41106a20024188066a41106a280200360200200241a8056a41086a20024188066a41086a290300370300200220022903880622173703a8052018422088a721032016422088a72106200241b4056a290200211220022902ac0521132017a721072018a721042016a72105410621010c390b200241c8036a2001106c20022802c8030d3a4107210120022802cc0321040c380b200241e0076a200110a50120022d00e0074102460d39200241fc076a2902002112200241f4076a2902002113200241f0076a2802002107200241ec076a280200210641082101200241e0076a41086a280200210520022802e407210320022802e00721040c370b200241d0036a2001106c20022802d0030d384109210120022802d40321040c360b200241d8036a2001106c20022802d8030d37410a210120022802dc0321040c350b2006450d3320042d0001210520012003417e6a3602042001200441026a360200200541034b0d33024002400240024020050e0400010203000b41002105200241003a0080082003417e6a21072003417d6a21030340024020072005470d00200541ff0171450d38200241003a0080080c380b200241e0076a20056a200420056a220641026a2d00003a0000200120033602042001200641036a3602002002200541016a22063a0080082003417f6a21032006210520064120470d000b200241a8056a41106a200241f1076a290000370300200241b0056a200241e0076a41096a290000220a370300200241bf056a2201200241e0076a41186a290000370000200241e8066a41096a200a370000200241e8066a41106a200241b7056a290000370000200220022d00e007220d3a00e806200220022900e1073700e9062001280000210f20022800c305210b20022800ef06220c411876211020022800eb062201411876210820022d00ff06211b20022900f706211220022800f306211a20022d00ea06211920022d00e906211f4101211c0c350b41002105200241003a0080082003417e6a21072003417d6a21030340024020072005470d00200541ff0171450d37200241003a0080080c370b200241e0076a20056a200420056a220641026a2d00003a0000200120033602042001200641036a3602002002200541016a22063a0080082003417f6a21032006210520064120470d000b200241b0056a200241e9076a290000370300200241bf056a2204200241e0076a41186a290000370000200241a8056a41106a200241f1076a290000370300200220022900e107220a3703a80520022f01aa0520022d00ac0541107472210120022901ae052211a7220c41187621102011422088a7211a20022d00e007210d2004280000210f200241b6056a290100211220022d00ad05210820022d00a905211920022800c305210b20022d00be05211b200aa7211f4102211c0c340b41002105200241003a008008410220036b21092003417d6a210603400240200920056a0d00200541ff0171450d36200241003a0080080c360b200241e0076a20056a200420056a220741026a2d00003a0000200120063602042001200741036a3602002002200541016a22073a0080082006417f6a21062007210520074120470d000b200241b0056a200241e9076a290000370300200241b8056a200241f1076a290000370300200241bf056a2205200241f8076a290000370000200220022900e107220a3703a805200241d8076a41046a20022d00ac053a0000200241e8066a41046a200241b5056a2f00003b01002002200a3e02d807200220022800b1053602e80620022d00e007210d20022800ad0521082005290000211320022900b705211241002105200241003a008008200420076a2109200720036b41026a210303400240200320056a0d00200541ff0171450d36200241003a0080080c360b200241e0076a20056a200920056a220441026a2d00003a0000200120063602042001200441036a3602002002200541016a22043a0080082006417f6a21062004210520044120470d000b200241bf056a2201200241f8076a290000370000200241a8056a41106a200241f1076a290000370300200241a8056a41086a2203200241e9076a290000370300200220022900e10722163703a80520022d00e007210420012800002109200241bb056a3300002111200241bd056a3100002118200241b5056a330000210a2003310000211720022801aa05210620022d00a905210520022800c305210e20022d00be05210720023500b705211520023500b105211420023301ae052121200241d0076a41046a2201200241d8076a41046a2d00003a0000200220022802d8073602d007200220083602880720024188076a41086a200241e8066a41046a2f01003b0100200220022802e80636028c0720022012370192072002419a076a20133701002014200a422086842214421886202120174210868484210a201520112018421086844220868442088620144228888421112012423888201342088684a7211b2008410876210c20022f01d20720012d00004110747221012013422088a7210b2002290091072112200228008d07211a20022d008c07211020022d00d107211920022d00d007211f2016a721032013a7210f4103211c0c330b200241e0076a2001106d20022802e0072201450d3320022802e407220c411876211020014118762108200241e8076a280200211a4104211c0c320b024002402006450d0020042d0001210520012003417e6a3602042001200441026a36020020050d00200241e0036a2001106c20022802e003450d010b200041133602000c3f0b20022802e40321012000410d36020020002001360204200041086a200241e8086a418001109a051a0c3e0b02402006450d0020042d0001210520012003417e6a3602042001200441026a36020020050d00200241e8036a2001106c20022802e8030d00200128020420022802ec032204490d002004417f4c0d0b024002400240024020040d00410121030c010b2004102e2203450d0120072802002004490d02200320012802002004109a051a200128020422052004490d1b2001200520046b3602042001200128020020046a3602000b2003450d02200020033602042000410e360200200041086a2004ad220a422086200a84370200200041106a200241e8086a41f800109a051a0c400b200441011037000b2003102a0b200041133602000c3d0b02402006450d0020042d0001210520012003417e6a3602042001200441026a360200200541024b0d0002400240024020050e03000102000b200241f0036a2001109f0120022903f003a70d0220024180046a290300210a20022903f8032111200241e0076a200110a50120022d00e0074102460d02200241fc076a2902002112200241f4076a2902002113200241f0076a2802002101200241ec076a2802002104200241e8076a280200210320022802e407210520022802e0072106410121070c310b20024188046a2001106c2002280288040d0141022107200228028c0421060c300b20024190046a2001106c2002280290040d004103210720022802940421060c2f0b200041133602000c3c0b02402006450d0020042d0001210520012003417e6a3602042001200441026a360200200541044b0d0002400240024002400240024002400240024020050e050001020607000b200241e8086a200110ea0120022d00d8094102460d08200241e8076a20024198096a290300370300200241f0076a200241a0096a29030037030020022002290390093703e0072002418c096a280200210b20024184096a2802002104200241fd086a2800002108200241f9086a280000210d200228028809211b20022d008309210520022d008209210620022d008109210f20022d00f808210e20022903f008210a20022903e8082111200241d8096a2903002113200241b8096a2903002116200241c5096a2800002101200241c1096a280000210320022903d009211820022903b009211720022802cc09210720022d00cb09210c20022d00ca09211f20022d00c909211c20022d00c009211d20022903a8092112410121220c020b200241a0046a2001109e0120022903a004a70d0720022903a804210a20024198046a2001106c2002280298040d072001280204200228029c042204490d072004417f4c0d1002400240024020040d00410121090c010b2004102e2209450d0120072802002004490d08200920012802002004109a051a200128020422032004490d202001200320046b3602042001200128020020046a3602000b2009450d082004ad22114220862011842111200241e0076a41106a200241e8086a41106a290300370300200241e0076a41086a200241e8086a41086a290300370300200220022903e8083703e007410221220c350b200441011037000b200241e8086a200110a50120022d00e8084102460d06200241f4086a290200210a20024188096a280200210420024187096a2d0000210520024186096a2d0000210620024185096a2d0000210f20024181096a2800002108200241fd086a280000210d200241fc086a2d0000210e20022902ec08211120022802e8082109200241c8046a2001109f0120022903c804a70d06200241d8046a290300211320022903d0042116200241b8046a2001109e0120022903b804a70d0620022903c0042112200241b0046a2001106c20022802b0040d06200128020420022802b404220b490d06200b417f4c0d0f02400240200b0d004101211b41010d010c080b200b102e221b450d022007280200200b490d03201b2001280200200b109a05210320012802042207200b490d1f20012007200b6b36020420012001280200200b6a3602002003450d070b200241f0076a2013370300200220163703e8072002200b3602e007410321220b0c320b200b41011037000b201b102a0c030b200241f8046a2001109f0120022903f804a70d0220024188056a290300210a2002290380052111200241e8046a2001109e0120022903e804a70d0220022903f004211241002103200241003a0088092007280200417f6a21040240024002400240024003402004417f460d01200241e8086a20036a200128020022052d00003a0000200120043602042001200541016a3602002002200341016a22053a0088092004417f6a21042005210320054120470d000b20024190076a200241e8086a410e6a290100221337030020024198076a200241e8086a41166a2204290100370300200241a0076a20024186096a2f01003b0100200241e8066a410e6a2013370100200241e8066a41166a20042f01003b0100200220022d00e80822103a00e806200220022800e9083600e906200220022d00ed083a00ed06200220022901ee0822133701ee062002201337038807200228019e072108200228019a07210d200241e0046a2001106c20022802e0040d07200128020420022802e404220b490d07200b417f4c0d10200b0d01410121040c020b200341ff0171450d06200241003a0088090c060b200b102e2204450d012007280200200b490d0220042001280200200b109a051a20012802042203200b490d1e20012003200b6b36020420012001280200200b6a3602000b2004450d04200220113703e007200220123703f0072002200a3703e807200241f7066a290000210a20022900ef06211120022d00ff06210e20022800eb06210920022d00ea06211a20022d00e906211941042122200b211b0c310b200b41011037000b2004102a0c020b41002105200241003a0088092003417e6a21092003417d6a21060340024020092005470d00200541ff0171450d03200241003a0088090c030b200241e8086a20056a200420056a220741026a2d00003a0000200120063602042001200741036a3602002002200541016a22073a0088092006417f6a21062007210520074120470d000b2003417e6a2007460d01200241f7086a290000210a20022900ef08211120022d00e808211020022d00e908211920022d00ea08211a20022800eb08210920022d00ff08210e200228028009210d2002280284092108200420076a220c41026a2d0000211f200120063602042001200c41036a360200201f41014b0d014100210f02400240201f0e020100010b41002104200241003a008809200720036b41036a2106200320076b417c6a210303400240200620046a0d00200441ff0171450d04200241003a0088090c040b200241e8086a20046a200c20046a220541036a2d00003a0000200120033602042001200541046a3602002002200441016a22053a0088092003417f6a21032005210420054120470d000b200241b0056a200241f1086a290000370300200241b8056a200241f9086a290000370300200241bf056a220120024180096a290000370000200220022900e90822123703a805200241d8076a41046a20022d00ac053a0000200241e8066a41046a2203200241b5056a2f00003b0100200220123e02d807200220022800b1053602e80620022d00e808210620022800ad05211b2001290000211320022900b705211220022802e806210b20022800d907210420022d00d8072105200220032f01003b0188074101210f0b200241ea076a2013370100200241f6076a200241ce076a2f01003b0100200220022f0188073b01e007200220123701e207200220022801ca073601f207410521220c2e0b2009102a0b200041133602000c3b0b2006450d2a20042d0001210520012003417e6a3602042001200441026a360200200541024b0d2a0240024002400240024020050e03000102000b200241e0076a200110810120022802e0074113470d020c2e0b200241e8086a200110a5014102210120022d00e8084102460d2d200241a8056a41106a20024188096a280200360200200241a8056a41086a20024180096a2903003703002002200241e8086a41106a29030022123703a80520022903e8082213422088a72103200241e8086a41086a2903002216422088a72105200241b4056a290200210a20022902ac0521112013a721042012a721062016a721070c020b200241e8086a200110a50120022d00e8084102460d2c20024184096a290200210a200241fc086a2902002111200241f8086a2802002106200241f4086a2802002105200241f0086a280200210720022802ec08210320022802e8082104200241e0076a200110810120022802e0074113460d2c200241e8086a200241e0076a418801109a051a41880110282209450d1b2009200241e8086a418801109a051a410321010c010b200241e8086a200241e0076a418801109a051a41880110282204450d192004200241e8086a418801109a051a410121010b2000200136020420004111360200200041246a200a3702002000411c6a20113702002000412c6a2009360200200041186a2006360200200041146a2005360200200041106a20073602002000410c6a2003360200200041086a2004360200200041306a20024188066a41d800109a051a0c3a0b2006450d2820042d0001210520012003417e6a22063602042001200441026a36020020050d2820064104490d282004280002210b20012003417a6a3602042001200441066a360200200241a0056a2001106c20022802a0050d28200128020420022802a4052205490d282005417f4c0d060240024020050d004101210c41010d010c2a0b2005102e220c450d2520072802002005490d28200c20012802002005109a052104200128020422032005490d1a2001200320056b3602042001200128020020056a3602002004450d290b20024198056a2001106c2002280298050d262007280200410c6e220f410c6c2204417f4c0d06200228029c0521100240024020040d004104210e0c010b20041028220e450d1b0b0240024002400240024002402010450d00410021084100210341002109034020024190056a2001106c2002280290050d0320012802042002280294052204490d032004417f4c0d0d0240024020040d004101210d0c010b2004102e220d450d2b20072802002004490d03200d20012802002004109a051a200128020422062004490d232001200620046b3602042001200128020020046a3602000b200941016a210602402009200f470d0020082006200820064b1b220fad420c7e220a422088a70d3f200aa7221b4100480d3f0240024020090d00201b1028210e0c010b200e2003201b102c210e0b200e450d240b200e20036a2209200d360200200941046a2004ad220a422086200a84370200200841026a21082003410c6a21032006210920102006470d000b0b200e450d2b200c450d2d200728020022034104490d0220012802002207280000210820012003417c6a22043602042001200741046a36020020044104490d032007280004210d2001200341786a22093602042001200741086a36020041002104200241003a00a809200341776a2103034020092004460d05200241e8086a20046a200720046a220641086a2d00003a0000200120033602042001200641096a3602002002200441016a22063a00a8092003417f6a210320062104200641c000470d000b200241e0076a41386a2201200241e8086a41386a290300370300200241e0076a41306a2204200241e8086a41306a290300370300200241e0076a41286a2203200241e8086a41286a290300370300200241e0076a41206a2207200241e8086a41206a290300370300200241e0076a41186a2209200241e8086a41186a290300370300200241e0076a41106a221b200241e8086a41106a290300370300200241e0076a41086a221a200241e8086a41086a290300370300200220022903e8083703e007200641ff017141c000490d2a20024188066a41386a2206200129030037030020024188066a41306a2004290300220a37030020024188066a41286a2003290300221137030020024188066a41206a2007290300221237030020024188066a41186a2009290300221337030020024188066a41106a201b290300221637030020024188066a41086a201a2903002218370300200220022903e007221737038806200241a8056a41306a200a370300200241a8056a41286a2011370300200241a8056a41206a2012370300200241a8056a41186a2013370300200241a8056a41106a2016370300200241a8056a41086a2018370300200241a8056a41386a2006290300370300200220173703a805200c450d2d20024188076a41386a2201200241a8056a41386a29030037030020024188076a41306a2204200241a8056a41306a29030037030020024188076a41286a2203200241a8056a41286a29030037030020024188076a41206a2206200241a8056a41206a29030037030020024188076a41186a2207200241a8056a41186a29030037030020024188076a41106a2209200241a8056a41106a29030037030020024188076a41086a221b200241a8056a41086a290300370300200220022903a80537038807200041246a200d360200200041206a20083602002000411c6a2010360200200041186a200f360200200041146a200e360200200041106a20053602002000410c6a2005360200200041086a200c3602002000200b36020420004112360200200041286a200229038807370200200041306a201b290300370200200041386a2009290300370200200041c0006a2007290300370200200041c8006a2006290300370200200041d0006a2003290300370200200041d8006a2004290300370200200041e0006a200129030037020020004180016a200241e8066a41186a290300370300200041f8006a200241e8066a41106a290300370300200041f0006a200241e8066a41086a290300370300200041e8006a20022903e8063703000c3e0b200d102a0b02402009450d00200e210103400240200141046a280200450d002001280200102a0b2001410c6a2101200341746a22030d000b0b200f450d29200e102a0c290b02402005450d00200c102a0b02402010450d002010410c6c2104200e210103400240200141046a280200450d002001280200102a0b2001410c6a2101200441746a22040d000b0b200f450d2a200e102a0c2a0b02402005450d00200c102a0b02402010450d002010410c6c2104200e210103400240200141046a280200450d002001280200102a0b2001410c6a2101200441746a22040d000b0b200f450d29200e102a0c290b200441ff0171450d25200241003a00a8090c250b02402006450d0020012003417e6a3602042001200441026a3602000b200041133602000c380b02402006450d0020012003417e6a3602042001200441026a3602000b200041133602000c370b200041133602000c360b200041086a20022902e4073702002000200136020420004103360200200041106a200241e8086a41f800109a051a0c350b20024188066a41206a200241e0076a41206a290300220a37030020024188066a41186a200241e0076a41186a290300221137030020024188066a41106a200241e0076a41106a290300221237030020024188066a41086a200241e0076a41086a2903002213370300200220022903e00722163703880620004109360200200020163702042000410c6a2013370200200041146a20123702002000411c6a2011370200200041246a200a3702002000412c6a200241e8086a41dc00109a051a0c340b20024188066a41206a200241e0076a41206a290300220a37030020024188066a41186a200241e0076a41186a290300221137030020024188066a41106a200241e0076a41106a290300221237030020024188066a41086a200241e0076a41086a2903002213370300200220022903e0072216370388062000410a360200200020163702042000410c6a2013370200200041146a20123702002000411c6a2011370200200041246a200a3702002000412c6a200241e8086a41dc00109a051a0c330b1036000b200420031044000b200420031044000b200441041037000b200420031044000b200320091044000b201041041037000b200441041037000b200420061044000b200b41041037000b200441041037000b202041041037000b200420061044000b200420051044000b200420031044000b200b20071044000b200b20031044000b41880141081037000b41880141081037000b200520031044000b200441041037000b200420061044000b201b41041037000b200441011037000b200441011037000b41880141081037000b41880141081037000b41880141081037000b41880141081037000b200441011037000b200541011037000b02402005450d00200c102a0b02402010450d002010410c6c2104200e210103400240200141046a280200450d002001280200102a0b2001410c6a2101200441746a22040d000b0b200f450d02200e102a0c020b2005450d010b200c102a0b200041133602000c100b200041133602000c0f0b20024188066a41106a221e200241e0076a41106a29030037030020024188066a41086a2220200241e0076a41086a290300370300200220022903e00737038806200041346a200b360200200041306a201b3602002000412c6a2004360200200020053a002b200020063a002a2000200f3a0029200041256a2008360000200041216a200d360000200041206a200e3a0000200041186a200a370200200041106a20113700002000410c6a20093600002000201a3a000b200020193a000a200020103a0009200041086a20223a000020004110360200200041d0006a2012370200200041e9006a2003360000200041ed006a2001360000200041f4006a2007360200200041f8006a201837020020004180016a20133702002000200c3a00732000201f3a00722000201c3a0071200041e8006a201d3a0000200041d8006a2017370200200041e0006a2016370200200041386a200229038806370200200041c0006a2020290300370200200041c8006a201e2903003702000c0e0b2000410f360200200041386a200a370200200041306a2011370200200041286a2012370200200041206a20133702002000411c6a2001360200200041186a2004360200200041146a2003360200200041106a20053602002000410c6a2006360200200041086a2007360200200041c0006a200241e8086a41c800109a051a0c0d0b2000200e3600412000200936003d200020053a0027200020033a0026200020043a0025200020193a00072000201f3a00062000200d3a00052000201c3a00042000410c360200200041346a20113700002000412c6a200a3700002000413c6a20073a0000200041286a2006360000200041216a200b3600002000411d6a200f3600002000411c6a201b3a0000200041146a2012370000200041106a201a3600002000410c6a2010411874200c41ffffff077172360000200041086a2008411874200141ffffff07717236000020004180016a200241a0096a290300370300200041f8006a20024198096a290300370300200041f0006a200241e8086a41286a290300370300200041e8006a20024188096a290300370300200041e0006a200241e8086a41186a290300370300200041d8006a200241e8086a41106a290300370300200041d0006a200241e8086a41086a290300370300200041c8006a20022903e8083703000c0c0b200041133602000c0b0b2000410b360200200041c0006a2011370200200041386a200a370200200041286a2012370200200041206a2013370200200041346a2009360200200041306a20083602002000411c6a2007360200200041186a2006360200200041146a2005360200200041106a20033602002000410c6a2004360200200041086a2001360200200041c8006a20022903e808370300200041d0006a200241e8086a41086a290300370300200041d8006a200241e8086a41106a290300370300200041e0006a200241e8086a41186a290300370300200041e8006a200241e8086a41206a290300370300200041f0006a200241e8086a41286a290300370300200041f8006a200241e8086a41306a29030037030020004180016a200241e8086a41386a2903003703000c0a0b2004102a0b200041133602000c080b4100211f4200210a0c010b4100211f4200210a0b200020093a0029200020103a000b2000200d3a000a200020083a000920004108360200200041186a200a370200200041346a4100360200200041306a20193602002000412c6a200c360200200041256a200b360000200041216a200f360000200041206a200e3a0000200041086a201a3a00002000410c6a201c411874200641ffffff077172360200200041106a201fad422086201bad84370200200041386a20024188066a41d000109a051a0c050b200041133602000c040b200041133602000c030b200020083a002b2000200d3a002a2000200c3a0029200020093a000920004106360200200041386a2013370200200041306a2012370200200041186a2011370200200041106a200a3702002000412c6a200b360200200041216a200f360000200041206a200e3a00002000410c6a2006360200200041086a20103a0000200041256a201b201a41ff017172360000200041c0006a200241e8086a41c800109a051a0c020b1031000b20004100360200200041106a200a3702002000410c6a2005360200200041086a2009360200200041186a200241e8086a41f000109a051a0b200241f0096a24000bf602010b7f230041106b22022400200241086a2001106c0240024002400240024020022802080d0020012802042203417c712204417f4c0d02200228020c210502400240200341027622060d00410421070c010b200410282207450d040b02402005450d0041002108410021094100210403400240024002402001280204220a4104490d00200441016a21032001280200220b280000210c2001200a417c6a3602042001200b41046a36020020042006470d02024020082003200820034b1b220641ffffffff03712006470d002006410274220a41004e0d020b1031000b200041003602002006450d052007102a0c050b0240024020040d00200a102821070c010b20072009200a102c21070b2007450d070b200720096a200c360200200841026a2108200941046a21092003210420052003470d000b0b2000200636020420002007360200200041086a20053602000c010b200041003602000b200241106a24000f0b1036000b200441041037000b200a41041037000bbf0701107f230041f0006b22032400200341206a2001200228020c22041102000240024020032802200d002000410036020820004201370200200120022802001103002002280204450d012001102a0c010b200341c8006a41106a200341206a41106a290300370300200341c8006a41086a200341206a41086a290300370300200341c8006a41186a200341206a41186a290300370300200341c8006a41206a200341206a41206a280200360200200341086a200341d4006a290200370300200341106a200341dc006a290200370300200341186a200341e4006a290200370300200320032903203703482003200329024c370300200341c8006a2001200228021022051102000240417f2003280248220641016a220720072006491b220641ffffff3f712006470d0020064105742207417f4c0d004101210841012109024002402007450d00200710282209450d010b20092003290300370000200941186a200341186a220a290300370000200941106a200341106a220b290300370000200941086a200341086a220c290300370000200341206a200120041102000240024020032802200d002006210d0c010b200341c8006a41047221074120210e410121080340200341c8006a41206a200341206a41206a280200360200200341c8006a41186a220f200341206a41186a290300370300200341c8006a41106a2210200341206a41106a290300370300200341c8006a41086a2211200341206a41086a29030037030020032003290320370348200c200741086a290000370300200b200741106a290000370300200a200741186a29000037030020032007290000370300200f200a2903003703002010200b2903003703002011200c290300370300200320032903003703480240024020082006460d002006210d0c010b200341206a2001200511020002402006417f2003280220220d41016a22122012200d491b6a220d2006490d0020064101742212200d2012200d4b1b220d41ffffff3f71200d470d00200d41057422124100480d000240024020060d002012102821090c010b200920064105742012102c21090b20090d01201241011037000b1031000b2009200e6a22062003290348370000200641186a200f290300370000200641106a2010290300370000200641086a2011290300370000200341206a20012004110200200e41206a210e200841016a2108200d210620032802200d000b0b2001200228020011030002402002280204450d002001102a0b200020083602082000200d360204200020093602000c020b200741011037000b1036000b200341f0006a24000bad08040c7f017e057f037e23004180016b22022400024002400240200141086a220328020022042001410c6a2802002205460d002001280210220628020021072006280208220841014b210903402003200441206a220a360200200241e0006a41186a200441186a290000370300200241e0006a41106a200441106a290000370300200241e0006a41086a200441086a29000037030020022004290000370360410021040240024020090d0020080e020401040b2008210b0340200b410176220c20046a220d20042007200d4105746a200241e0006a4120109c054101481b2104200b200c6b220b41014b0d000b0b200720044105746a200241e0006a4120109c050d02200a2104200a2005470d000b0b20004100360208200042013702002001280204450d012001280200102a0c010b200241c0006a41086a2204200241e0006a41086a290300370300200241c0006a41106a220b200241e0006a41106a290300370300200241c0006a41186a220c200241e0006a41186a29030037030020022002290360220e3703002002200e370340024041201028220f450d00200f2002290340370000200f41186a200c290300370000200f41106a200b290300370000200f41086a2004290300370000200128020421102001280200211102400240200a2005470d0041012112410121130c010b41012112410121130340200628020821032006280200210702400340200241e0006a41186a2208200a41186a290000370300200241e0006a41106a2209200a41106a290000370300200241e0006a41086a2201200a41086a2900003703002002200a290000370360200a41206a210a4100210402400240200341014b0d0020030e020301030b2003210b0340200b410176220c20046a220d20042007200d4105746a200241e0006a4120109c054101481b2104200b200c6b220b41014b0d000b0b200720044105746a200241e0006a4120109c050d01200a2005470d000c030b0b200241c0006a41086a2001290300220e370300200241c0006a41106a20092903002214370300200241c0006a41186a20082903002215370300200220022903602216370340200241186a220b2015370300200241106a220c2014370300200241086a220d200e37030020022016370300024020132012470d000240201241016a22042012490d00201241017422072004200720044b1b221341ffffff3f712013470d00201341057422044100480d000240024020120d0020041028210f0c010b200f20124105742004102c210f0b200f0d01200441011037000b1031000b200f20124105746a22042002290300370000200441186a200b290300370000200441106a200c290300370000200441086a200d290300370000201241016a2112200a2005470d000b0b02402010450d002011102a0b20002012360208200020133602042000200f3602000c010b412041011037000b20024180016a24000bce0401057f23004180016b2202240002400240024020012802042203200128020022046b41e100490d0003402001200441206a360200200241206a2004108601024020022802602204450d00200241206a21010c030b20012001280200220441206a360200200241206a2004108601024020022802602204450d00200241206a21010c030b20012001280200220441206a360200200241206a2004108601024020022802602204450d00200241206a21010c030b20012001280200220441206a360200200241206a2004108601024020022802602204450d00200241206a21010c030b20012802042203200128020022046b41e0004b0d000b0b024020042003460d0003402001200441206a360200200241206a2004108601024020022802602204450d00200241206a21010c030b200128020022042001280204470d000b0b200041003602400c010b20002001290300370300200041386a200141386a290300370300200041306a200141306a290300370300200041286a200141286a290300370300200041206a200141206a290300370300200041186a200141186a290300370300200041106a200141106a290300370300200041086a200141086a290300370300200241086a2203200141cc006a290200370300200241106a2205200141d4006a290200370300200241186a2206200141dc006a2802003602002002200141c4006a2902003703002000200436024020002002290300370244200041cc006a2003290300370200200041d4006a2005290300370200200041dc006a20062802003602000b20024180016a24000bf00c030c7f017e067f230041a0026b22022400024002400240411010282203450d002003410029008ab740370000200341086a4100290092b7403700002002429080808080023702e401200220033602e0012002200241e0016a3602a0012001200241a0016a10c80120022802e001210320022802e8012101200241f8006a41186a22044200370300200241f8006a41106a22054200370300200241f8006a41086a220642003703002002420037037820032001200241f8006a1000200241d8006a41186a2004290300370300200241d8006a41106a2005290300370300200241d8006a41086a200629030037030020022002290378370358024020022802e401450d0020022802e001102a0b200241003602e001200241d8006a4120200241e0016a1006210420022802e0012205417f460d012004450d012002200536029c01200220043602980141002103200241003a0038024002400340024020052003470d002002410036029c01200341ff0171450d02200241003a00380c020b200241186a20036a200420036a22012d00003a00002002200141016a360298012002200341016a22013a00382001210320014120470d000b200241f8006a41086a2206200241186a41086a2207290300370300200241f8006a41106a2208200241186a41106a2209290300370300200241f8006a41186a220a200241186a41186a220b290300370300200220022903183703782002200520016b36029c01200241186a20024198016a10d40120022802382203450d00200241e0016a41186a220c200a290300370300200241e0016a41106a220a2008290300370300200241e0016a41086a220d2006290300370300200241e0016a41286a22062007290300370300200241e0016a41306a22072009290300370300200241e0016a41386a2208200b290300370300200220022903783703e00120022002290318370380022002413c6a2802002101200241186a41286a2209290300210e200241a0016a41086a200d290300370300200241a0016a41106a200a290300370300200241a0016a41186a200c290300370300200241a0016a41206a220a200229038002370300200241a0016a41286a220b2006290300370300200241a0016a41306a220c2007290300370300200241a0016a41386a220d2008290300370300200220022903e0013703a001200241186a20024198016a106d20022802180d012001450d002003102a0b41c4d1c3004133200241a0016a419cd9c3001038000b200241f8006a41086a220f200241186a41086a2210280200360200200241e0016a41086a2211200241a0016a41086a290300370300200241e0016a41106a2212200241a0016a41106a290300370300200241e0016a41186a2213200241a0016a41186a290300370300200241e0016a41206a2214200a2903003703002006200b2903003703002007200c2903003703002008200d29030037030020022002290318370378200220022903a0013703e00120102011290300370300200241186a41106a2012290300370300200241186a41186a2013290300370300200241186a41206a201429030037030020092006290300370300200241186a41306a2007290300370300200241186a41386a2008290300370300200241086a41086a200f280200360200200220022903e001370318200220022903783703082005450d022004102a0c020b411041011037000b410021030b200241e0016a41086a2204200241186a41086a290300370300200241e0016a41106a2205200241186a41106a290300370300200241e0016a41186a2206200241186a41186a290300370300200241e0016a41206a2207200241186a41206a290300370300200241e0016a41286a2208200241186a41286a290300370300200241e0016a41306a2209200241186a41306a290300370300200241e0016a41386a220a200241186a41386a290300370300200220022903183703e001200241a0016a41086a220b200241086a41086a280200360200200220022903083703a00102402003450d00200020022903e00137030020002001360244200041c8006a200e370200200041386a200a290300370300200041306a2009290300370300200041286a2008290300370300200041206a2007290300370300200041186a2006290300370300200041106a2005290300370300200041086a2004290300370300200041d8006a200b280200360200200041d0006a20022903a0013702000b20002003360240200241a0026a24000bb00705077f037e097f017e017f23004180016b22022400024002400240200141086a220328020022042001410c6a2802002205460d0020012802102106200241f4006a2107034020032004220841206a2204360200200841086a2903002109200841106a290300210a2008290300210b200241e0006a41186a200841186a290300370300200241e0006a41106a200a370300200241e0006a41086a20093703002002200b3703600240200aa720062802004d0d002001280214220c2007460d002007290000200c290000520d030b20052004470d000b0b20004100360208200042083702002001280204450d012001280200102a0c010b200241086a2204200241e0006a41086a290300370300200241106a2203200241e0006a41106a290300370300200241186a2207200241e0006a41186a29030037030020022002290360220a3703202002200a3703000240024002400240024041201028220d450d00200d2002290300370300200d41186a2007290300370300200d41106a2003290300370300200d41086a20042903003703002001280204210e2001280200210f200541606a2008460d03200841206a2110200541606a2111200241f4006a21014101211241012113200d21140340200c2001460d042010210802400340200241e0006a41186a2204200841186a290300370300200241e0006a41106a2203200841106a290300220a370300200241e0006a41086a2207200841086a290300370300200220082903003703600240200aa720062802004d0d002001290000200c290000520d020b2005200841206a2208470d000c070b0b200241206a41086a2007290300220a370300200241206a41106a20032903002209370300200241206a41186a2004290300220b3703002002200229036022153703202004200b370300200320093703002007200a37030020022015370360024020132012470d00201241016a22132012490d04201241017422102013201020134b1b221341ffffff3f712013470d04201341057422104100480d040240024020120d002010102821140c010b201420124105742010102c21140b2014450d030b200841206a2110201420124105746a22162002290360370300201641186a2004290300370300201641106a2003290300370300201641086a2007290300370300201241016a211220112008470d000c050b0b412041081037000b201041081037000b1031000b4101211241012113200d21140b0240200e450d00200f102a0b2000201236020820002013360204200020143602000b20024180016a24000bed0704067f017e0a7f027e230041f0006b22032400200341206a2001200228020c22041102000240024020032802200d002000410036020820004208370200200120022802001103002002280204450d012001102a0c010b200341c8006a41106a200341206a41106a290300370300200341c8006a41086a200341206a41086a290300370300200341c8006a41186a200341206a41186a290300370300200341c8006a41206a200341206a41206a280200360200200341086a200341d4006a290200370300200341106a200341dc006a290200370300200341186a200341e4006a290200370300200320032903203703482003200329024c370300200341c8006a2001200228021022051102000240024002400240417f2003280248220641016a220720072006491b2208ad42287e2209422088a70d002009a72206417f4c0d000240024020060d004108210a4108210b0c010b20061028220a450d02200a210b0b200a2003290300370300200a41186a200341186a220c290300370300200a41106a200341106a220d290300370300200a41086a200341086a290300370300200b4201370320200341206a200120041102000240024020032802200d004101210e0c010b200341c8006a410472210641c800210f4101210e0340200341c8006a41206a200341206a41206a280200360200200341c8006a41186a2210200341206a41186a290300370300200341c8006a41106a2211200341206a41106a290300370300200341c8006a41086a2212200341206a41086a29030037030020032003290320370348200341086a2207200641086a290200370300200d200641106a290200370300200c200641186a290200370300200320062902003703002010200c2903003703002011200d29030037030020122007290300370300200320032903003703480240200e2008470d00200341206a200120051102002008417f2003280220220741016a221320132007491b6a22072008490d06200841017422132007201320074b1b2213ad42287e2209422088a70d062009a722074100480d060240024020080d0020071028210a0c010b200a200841286c2007102c210a0b200a450d05200a210b201321080b200b200f6a221341606a2207200329034837030020122903002109201129030021142010290300211520134201370300200741186a2015370300200741106a2014370300200741086a2009370300200341206a20012004110200200f41286a210f200e41016a210e20032802200d000b0b2001200228020011030002402002280204450d002001102a0b2000200e360208200020083602042000200b3602000c040b1036000b200641081037000b200741081037000b1031000b200341f0006a24000b02000bef0101057f230041c0006b220524000240024020030d00200041003602000c010b2003280208210620032802002103200541206a41186a22074200370300200541206a41106a22084200370300200541206a41086a220942003703002005420037032020044120200541206a1000200541186a2007290300370300200541106a2008290300370300200541086a200929030037030020052005290320370300200541003602202003200620054120200541206a10012104024020052802202203417f460d002000200336020420002004360200200041086a20033602000c010b200041003602000b200541c0006a24000baf0201027f23004190016b2203240020032002108c010240024020032d000022024102470d00200041003a00000c010b200341e0006a200341286a290300370300200341e8006a200341306a290300370300200341d8006a41186a200341386a290300370300200341d8006a41206a200341c0006a290300370300200341d8006a41286a200341c8006a290300370300200341d8006a41306a200341d0006a2802003602002003200341206a29030037035802402002450d00200041003a00000c010b2003411c6a2802002102200341186a28020021042000200329026c370001200041013a0000200041196a20034184016a290200370000200041116a200341fc006a290200370000200041096a200341d8006a411c6a2902003700002002450d002004102a0b20034190016a24000bd60201057f230041d0016b220224000240411710282203450d00200341002900f1d8433700002003410f6a4100290080d943370000200341086a41002900f9d84337000020024297808080f00237027c200220033602782001200241f8006a108f01200228028001210320022802782101200241186a22044200370300200241106a22054200370300200241086a22064200370300200242003703002001200320021000200241d8006a41186a2004290300370300200241d8006a41106a2005290300370300200241d8006a41086a2006290300370300200220022903003703580240200228027c450d002002280278102a0b2002200241d8006a10960220022d00002103200241f8006a200241017241d700109a051a0240024020034102470d00200041023a00000c010b200020033a0000200041016a200241f8006a41d700109a051a0b200241d0016a24000f0b411741011037000b870102017f037e230041e0006b22032400200341086a2002108c010240024020032d000822024102470d00420021040c010b2002410173ad2104200341186a2903002105200341106a290300210620020d00200341246a280200450d00200341206a280200102a0b2000200637030820002004370300200041106a2005370300200341e0006a24000b940201057f230041d0006b220224000240411710282203450d00200341002900f1d8433700002003410f6a4100290080d943370000200341086a41002900f9d84337000020024297808080f002370224200220033602202001200241206a108f012002280228210320022802202101200241306a41186a22044200370300200241306a41106a22054200370300200241306a41086a220642003703002002420037033020012003200241306a1000200241186a2004290300370300200241106a2005290300370300200241086a20062903003703002002200229033037030002402002280224450d002002280220102a0b2002412041014100410010032103200241d0006a24002003417f470f0b411741011037000b952801057f02400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240200141046a2202280200200141086a22032802002204460d00200128020021050c010b200441016a22052004490d21200441017422062005200620054b1b22064100480d210240024020040d002006102821050c010b200128020020042006102c21050b2005450d0120012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d00003a000002400240200228020020032802002204460d00200128020021050c010b200441016a22052004490d21200441017422062005200620054b1b22064100480d210240024020040d002006102821050c010b200128020020042006102c21050b2005450d0220012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d00013a000002400240200228020020032802002204460d00200128020021050c010b200441016a22052004490d21200441017422062005200620054b1b22064100480d210240024020040d002006102821050c010b200128020020042006102c21050b2005450d0320012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d00023a000002400240200228020020032802002204460d00200128020021050c010b200441016a22052004490d21200441017422062005200620054b1b22064100480d210240024020040d002006102821050c010b200128020020042006102c21050b2005450d0420012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d00033a000002400240200228020020032802002204460d00200128020021050c010b200441016a22052004490d21200441017422062005200620054b1b22064100480d210240024020040d002006102821050c010b200128020020042006102c21050b2005450d0520012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d00043a000002400240200228020020032802002204460d00200128020021050c010b200441016a22052004490d21200441017422062005200620054b1b22064100480d210240024020040d002006102821050c010b200128020020042006102c21050b2005450d0620012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d00053a000002400240200228020020032802002204460d00200128020021050c010b200441016a22052004490d21200441017422062005200620054b1b22064100480d210240024020040d002006102821050c010b200128020020042006102c21050b2005450d0720012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d00063a000002400240200228020020032802002204460d00200128020021050c010b200441016a22052004490d21200441017422062005200620054b1b22064100480d210240024020040d002006102821050c010b200128020020042006102c21050b2005450d0820012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d00073a000002400240200228020020032802002204460d00200128020021050c010b200441016a22052004490d21200441017422062005200620054b1b22064100480d210240024020040d002006102821050c010b200128020020042006102c21050b2005450d0920012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d00083a000002400240200228020020032802002204460d00200128020021050c010b200441016a22052004490d21200441017422062005200620054b1b22064100480d210240024020040d002006102821050c010b200128020020042006102c21050b2005450d0a20012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d00093a000002400240200228020020032802002204460d00200128020021050c010b200441016a22052004490d21200441017422062005200620054b1b22064100480d210240024020040d002006102821050c010b200128020020042006102c21050b2005450d0b20012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d000a3a000002400240200228020020032802002204460d00200128020021050c010b200441016a22052004490d21200441017422062005200620054b1b22064100480d210240024020040d002006102821050c010b200128020020042006102c21050b2005450d0c20012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d000b3a000002400240200228020020032802002204460d00200128020021050c010b200441016a22052004490d21200441017422062005200620054b1b22064100480d210240024020040d002006102821050c010b200128020020042006102c21050b2005450d0d20012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d000c3a000002400240200228020020032802002204460d00200128020021050c010b200441016a22052004490d21200441017422062005200620054b1b22064100480d210240024020040d002006102821050c010b200128020020042006102c21050b2005450d0e20012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d000d3a000002400240200228020020032802002204460d00200128020021050c010b200441016a22052004490d21200441017422062005200620054b1b22064100480d210240024020040d002006102821050c010b200128020020042006102c21050b2005450d0f20012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d000e3a000002400240200228020020032802002204460d00200128020021050c010b200441016a22052004490d21200441017422062005200620054b1b22064100480d210240024020040d002006102821050c010b200128020020042006102c21050b2005450d1020012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d000f3a000002400240200228020020032802002204460d00200128020021050c010b200441016a22052004490d21200441017422062005200620054b1b22064100480d210240024020040d002006102821050c010b200128020020042006102c21050b2005450d1120012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d00103a000002400240200228020020032802002204460d00200128020021050c010b200441016a22052004490d21200441017422062005200620054b1b22064100480d210240024020040d002006102821050c010b200128020020042006102c21050b2005450d1220012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d00113a000002400240200228020020032802002204460d00200128020021050c010b200441016a22052004490d21200441017422062005200620054b1b22064100480d210240024020040d002006102821050c010b200128020020042006102c21050b2005450d1320012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d00123a000002400240200228020020032802002204460d00200128020021050c010b200441016a22052004490d21200441017422062005200620054b1b22064100480d210240024020040d002006102821050c010b200128020020042006102c21050b2005450d1420012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d00133a000002400240200228020020032802002204460d00200128020021050c010b200441016a22052004490d21200441017422062005200620054b1b22064100480d210240024020040d002006102821050c010b200128020020042006102c21050b2005450d1520012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d00143a000002400240200228020020032802002204460d00200128020021050c010b200441016a22052004490d21200441017422062005200620054b1b22064100480d210240024020040d002006102821050c010b200128020020042006102c21050b2005450d1620012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d00153a000002400240200228020020032802002204460d00200128020021050c010b200441016a22052004490d21200441017422062005200620054b1b22064100480d210240024020040d002006102821050c010b200128020020042006102c21050b2005450d1720012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d00163a000002400240200228020020032802002204460d00200128020021050c010b200441016a22052004490d21200441017422062005200620054b1b22064100480d210240024020040d002006102821050c010b200128020020042006102c21050b2005450d1820012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d00173a000002400240200228020020032802002204460d00200128020021050c010b200441016a22052004490d21200441017422062005200620054b1b22064100480d210240024020040d002006102821050c010b200128020020042006102c21050b2005450d1920012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d00183a000002400240200228020020032802002204460d00200128020021050c010b200441016a22052004490d21200441017422062005200620054b1b22064100480d210240024020040d002006102821050c010b200128020020042006102c21050b2005450d1a20012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d00193a000002400240200228020020032802002204460d00200128020021050c010b200441016a22052004490d21200441017422062005200620054b1b22064100480d210240024020040d002006102821050c010b200128020020042006102c21050b2005450d1b20012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d001a3a000002400240200228020020032802002204460d00200128020021050c010b200441016a22052004490d21200441017422062005200620054b1b22064100480d210240024020040d002006102821050c010b200128020020042006102c21050b2005450d1c20012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d001b3a000002400240200228020020032802002204460d00200128020021050c010b200441016a22052004490d21200441017422062005200620054b1b22064100480d210240024020040d002006102821050c010b200128020020042006102c21050b2005450d1d20012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d001c3a000002400240200228020020032802002204460d00200128020021050c010b200441016a22052004490d21200441017422062005200620054b1b22064100480d210240024020040d002006102821050c010b200128020020042006102c21050b2005450d1e20012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d001d3a000002400240200228020020032802002204460d00200128020021050c010b200441016a22052004490d21200441017422062005200620054b1b22064100480d210240024020040d002006102821050c010b200128020020042006102c21050b2005450d1f20012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d001e3a000002400240200228020020032802002202460d00200128020021040c010b200241016a22042002490d21200241017422052004200520044b1b22054100480d210240024020020d002005102821040c010b200128020020022005102c21040b2004450d2020012004360200200141046a2005360200200141086a28020021020b2003200241016a360200200420026a20002d001f3a00000f0b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200541011037000b1031000b3802017f017e230041106b2203240020032002109101200329030021042000200341086a29030037030820002004370300200341106a24000bf40202057f027e230041d0006b2202240002400240411410282203450d00200341002900cfe140370000200341106a41002800dfe140360000200341086a41002900d7e14037000020024294808080c002370224200220033602202001200241206a108f012002280228210320022802202101200241306a41186a22044200370300200241306a41106a22054200370300200241306a41086a220642003703002002420037033020012003200241306a1000200241186a2004290300370300200241106a2005290300370300200241086a20062903003703002002200229033037030002402002280224450d002002280220102a0b2002410036023020024120200241306a100621030240024020022802302201417f470d0042002107420021080c010b20014110490d02200341086a2900002108200329000021072003102a0b2000200737030020002008370308200241d0006a24000f0b411441011037000b41c4d1c3004133200241306a419cd9c3001038000bbc200b067f017e0d7f067e047f037e017f027e0d7f027e067f230041c0046b22022400200241186a42003703002002420037031020024200370308200128020821032001280200210402400240200128020422050d00200421010c010b2005210620042101034020012802880b21012006417f6a22060d000b0340200420042f01064102746a41880b6a28020021042005417f6a22050d000b0b200241106a21072002413c6a20042f0106360200200241206a41186a4100360200200241346a2004360200200220033602402002410036023020024200370328200220013602242002410036022020024188016a200241206a109301024002400240024020022903a80122084202510d00200241bc016a210920024188016a412c6a210a20024188016a410472210b200241e5016a210c20024188016a41086a2103200241e8026a412c6a210d200241e8026a41106a210e200241b8016a210f200241d0016a21100340200241e8006a41186a220620024188016a41186a2201290300370300200241e8006a41106a221120024188016a41106a2204290300370300200241e8006a41086a22122003290300370300200241c8006a41086a2213200c41086a290000370300200241c8006a41106a2214200c41106a290000370300200241c8006a41186a2215200c41186a29000037030020022002290388013703682002200c290000370348200f29030021162010290300211720022903b001211820022903c801211920022903c001211a20022903d801211b20022802e001211c20022d00e401211d20022d008502210520024188026a41186a200629030037030020024188026a41106a201129030037030020024188026a41086a20122903003703002002200229036837038802200241a8026a41186a22122015290300370300200241a8026a41106a221e2014290300370300200241a8026a41086a221f2013290300370300200220022903483703a8020240024002402005ad42ff0183200820085022061b4201520d0020024188016a20024188026a4200201820061b4200201620061b10940120042903002120200229039001211820022d00a00121062002290388012121200241086a41106a221129030021082002290310211602400240024002400240024020022903084201510d0020214200510d022016201856200820205620082020511b0d04202020087d2018201654ad7d2121201820167d21220c010b20214200510d02427f200820207c201620187c22182016542213ad7c22162013201620085420162008511b22131b2121427f201820131b21220b420121080c030b427f200820207c201620187c22182016542213ad7c22162013201620085420162008511b22131b2121427f201820131b2122420021080c020b202020087d2018201654ad7d200820207d2016201854ad7d20182016562020200856202020085122131b22141b2121201820167d201620187d20141b21222018201658202020085820131bad21080c010b200820207d2016201854ad7d2121201620187d2122420021080b201120213703002002202237031020022008370308200641ff01710d010b024002400240201d41ff0171222341014622060d00200541ff01710d00201c201aa772450d010b20024188016a20024188026a108c010240024020022d0088012211417f6a221341014b0d00024020130e020002000b20110d0420022802a401450d0420022802a001102a0c040b200241c8026a41086a200941086a290200370300200241c8026a41106a200941106a290200370300200241c8026a41186a200941186a290200370300200220092902003703c80220042903002124200229039001212520022802dc01212620022802b801212720022802b401212820022802b001212920022802ac01212a20022802a801212b20022802a401212c20022802a001212d0c020b4102212820110d0120022802a401450d0120022802a001102a0c010b201ba7210402400240201b422088a722050d00200421010c010b2005210620042101034020012802ec0321012006417f6a22060d000b0340200420042f01064102746a41ec036a28020021042005417f6a22050d000b0b2002201c3602a801200241003602a001200241003602980120024200370390012002200136028c0120024100360288012002200436029c01200220042f01063602a40120024188016a1095010c020b4102212e02400240024002400240024002400240024020284102460d00202b417f4c0d0102400240202b0d004100212f410121300c010b202b212f202b10282230450d030b2030202d202b109a051a2001200241c8026a41186a2903003703002004200241c8026a41106a2903003703002003200241c8026a41086a290300370300200220022903c802370388012028410146212e202b2131202a2132202521332024213420292135202721360b200241b8036a41186a22372001290300370300200241b8036a41106a22382004290300370300200241b8036a41086a22392003290300370300200241a0046a41086a221d201f290300370300200241a0046a41106a2214201e290300370300200241a0046a41186a2215201229030037030020022002290388013703b803200220022903a8023703a004200541ff0171450d030c020b1036000b202b41011037000b202e4102460d0120302031100420060d0320024188026a109601202f450d022030102a0c020b202e4102460d00200d20022903b803370200200d41086a2039290300370200200d41106a2038290300370200200d41186a2037290300370200200220333703e80220022036360290032002202e36028c032002203536028803200220323602840320022031360280032002202f3602fc02200220303602f802200220343703f0022035213a2033212020342121203221110c030b2006450d004108211120024188016a20024188026a109701109801213a200e41086a20024188016a41086a280200360200200e200229038801370200200d20022903a004370100200d41086a200241a0046a41086a290300370100200d41106a2014290300370100200d41186a2015290300370100427f21202002427f3703f0022002427f3703e80220024108360284034100212e2002410036028c032002203a36028803427f21210c020b20284102460d020240202c0d004100212c0c030b202d102a0c020b4108211120024188016a20024188026a109701109801213a200e41086a20024188016a41086a280200360200200e200229038801370200200d20022903a004370100200d41086a200241a0046a41086a290300370100200d41106a2014290300370100200d41186a2015290300370100427f21202002427f3703f0022002427f3703e80220024108360284034100212e2002410036028c032002203a360288030240202f450d002030102a427f21200b427f21210b0240201a4201520d00200220193703e802200220173703f00220192120201721210b02402023450d00200d20022903a802370000200d41186a2012290300370000200d41106a201e290300370000200d41086a201f2903003700000b0240201c450d0010980121054101212e2002410136028c0320022005360290030b201ba7210502400240201b422088a722120d00200521060c010b2012211320052106034020062802ec0321062013417f6a22130d000b0340200520052f01064102746a41ec036a28020021052012417f6a22120d000b0b20052f010621122002201c3602d803200220123602d403200241003602d003200220053602cc03200241003602c803200242003703c003200220063602bc03200241003602b80320024188016a200241b8036a10990102402002280288014101470d00200228028003211320022802f802211c0340200241e0036a41186a200b41186a2902002208370300200241e0036a41106a200b41106a290200221b370300200241e0036a41086a200b41086a29020022163703002002200b29020022183703e00320022802ac01210520022802b001211e20022802b401210620024180046a41186a200837030020024180046a41106a201b37030020024180046a41086a20163703002002201837038004200142003703002004420037030020034200370300200242003703880120024180046a412020024188016a10002015200129030037030020142004290300370300201d200329030037030020022002290388013703a0042002410036028801201c2013200241a0046a412020024188016a1001211f02402002280288012212417f460d00201120126b21112012450d00201f102a0b0240024020050d00200142003703002004420037030020034200370300200242003703880120024180046a412020024188016a10002015200129030037030020142004290300370300201d200329030037030020022002290388013703a004201c2013200241a0046a412010020c010b200142003703002004420037030020034200370300200242003703880120024180046a412020024188016a10002015200129030037030020142004290300370300201d200329030037030020022002290388013703a004201c2013200241a0046a4120200520061005201120066a2111201e450d002005102a0b20024188016a200241b8036a1099012002280288014101460d000b20022011360284030b200241b8036a1095012037200241c8026a41186a2903003703002038200241c8026a41106a2903003703002039200241c8026a41086a290300370300200220022903c8023703b8030240024020284102460d00200a20022903b803370200200a41086a2039290300370200200a41106a2038290300370200200a41186a20372903003702002002202537038801200220273602b001200220283602ac01200220293602a8012002202a3602a4012002202c36029c012002202d36029801200220263602d40120022024370390012002202b3602a001410121040240202b200228028003470d0002400240202d20022802f8022201460d00202d2001202b109c050d02202a2011470d020c010b202a2011470d010b200a200d4120109c050d0020252020852024202185844200520d002029203a470d0002402028202e470d004100210420284101470d012027200228029003460d010b410121040b0240202c450d00202d102a0b20044102460d002004450d010b2003200241e8026a41d000109a051a200241003a00880120024188026a20024188016a109a010c020b20022802fc02450d0120022802f802102a0c010b201ba7210402400240201b422088a722050d00200421010c010b2005210620042101034020012802ec0321012006417f6a22060d000b0340200420042f01064102746a41ec036a28020021042005417f6a22050d000b0b2002201c3602a801200241003602a001200241003602980120024200370390012002200136028c0120024100360288012002200436029c01200220042f01063602a40120024188016a1095010b20024188016a200241206a10930120022903a80122084202520d000b20022903082108200241206a109b012008500d010c020b200241206a109b010b02402002290310200241186a29030084500d0041f4b5c0001032000b20022903084200520d00200220073602880120024188016a109c010c010b200220073602880120024188016a109d010b200241c0046a24000bf90503087f017e017f23004180026b2202240002400240024020012802202203450d0020012003417f6a36022020012802082104200128020c2203200128020422052f01064f0d01200241186a2206200520034105746a220741206a290000370300200241106a2208200741186a290000370300200241086a2209200741106a2900003703002002200741086a290000370300200241206a2005200341e0006c6a41e8026a41e000109a051a2001200341016a36020c200120043602082001200536020420024180016a41186a200629030037030020024180016a41106a200829030037030020024180016a41086a2009290300370300200220022903003703800120024180016a41206a200241206a41e000109a051a200020024180016a418001109a051a0c020b200042023703200c010b2001280200210702400240200528020022030d002004ad210a410021030c010b200741016a210720053301044220862004ad84210a0b2005102a200aa7210402400240200a422088a7220620032f01064f0d00200321050c010b034002400240200328020022050d002004ad210a410021050c010b200741016a210720033301044220862004ad84210a0b2003102a200aa7210420052103200a422088a7220620052f01064f0d000b0b200241186a2208200520064105746a220341206a290000370300200241106a2209200341186a290000370300200241086a220b200341106a2900003703002002200341086a290000370300200241206a2005200641e0006c6a41e8026a41e000109a051a200641027420056a418c0b6a280200210302402007417f6a2205450d00034020032802880b21032005417f6a22050d000b0b2001410036020c20012004360208200120033602042001410036020020024180016a41186a200829030037030020024180016a41106a200929030037030020024180016a41086a200b290300370300200220022903003703800120024180016a41206a200241206a41e000109a051a200020024180016a418001109a051a0b20024180026a24000ba90703067f027e017f230041a0016b220424000240024002400240411410282205450d00200541002900cfe140370000200541106a41002800dfe140360000200541086a41002900d7e14037000020044294808080c002370224200420053602202001200441206a108f012004280228210520042802202106200441306a41186a22074200370300200441306a41106a22084200370300200441306a41086a220942003703002004420037033020062005200441306a1000200441186a2007290300370300200441106a2008290300370300200441086a20092903003703002004200429033037030002402004280224450d002004280220102a0b2004410036023020044120200441306a100621050240024020042802302206417f470d004200210a4200210b0c010b20064110490d02200541086a290000210b2005290000210a2005102a0b0240200242ffffe883b1de1656200342005220035022051b0d00200a200b844200520d0020004200370300200041013a0018200041106a4200370300200041086a42003703000c040b4101210602402002428080e983b1de1654410020051b0d00411410282205450d0341002106200541002900cfe140370000200541106a41002800dfe140360000200541086a41002900d7e14037000020044294808080c002370224200420053602202001200441206a108f012004280228210520042802202107200441306a41186a22084200370300200441306a41106a22094200370300200441306a41086a220c42003703002004420037033020072005200441306a1000200441186a2008290300370300200441106a2009290300370300200441086a200c2903003703002004200429033037030002402004280224450d002004280220102a0b200441204101410041001003417f470d002001109302200441e8006a2003370300200441e0006a200237030041002106200441306a41086a41003a0000200441396a2001290000370000200441c1006a200141086a290000370000200441c9006a200141106a290000370000200441d1006a200141186a290000370000200441023a003041014100200441306a10cc010b200120022003108f02200041106a200b20037d200a200254ad7d2003200b7d2002200a54ad7d200a200256200b200356200b2003511b22051b3703002000200a20027d2002200a7d20051b370308200020063a001820002005ad3703000c030b411441011037000b41c4d1c3004133200441306a419cd9c3001038000b411441011037000b200441a0016a24000bb00101037f230041306b2201240020012000109901024020012802004101470d000340024020012802242202450d002001280228450d002002102a0b2001200010990120012802004101460d000b0b02402000280204220241f8b9c000460d00200228020021032002102a2003450d00200328020021002003102a2000450d00024020002802002202450d0003402000102a2002210020022802002203210220030d000b0b2000102a0b200141306a24000b870201057f230041d0006b220124000240411710282202450d00200241002900f1d8433700002002410f6a4100290080d943370000200241086a41002900f9d84337000020014297808080f002370224200120023602202000200141206a108f012001280228210220012802202100200141306a41186a22034200370300200141306a41106a22044200370300200141306a41086a220542003703002001420037033020002002200141306a1000200141186a2003290300370300200141106a2004290300370300200141086a20052903003703002001200129033037030002402001280224450d002001280220102a0b200141201009200141d0006a24000f0b411741011037000ba60603037f017e017f230041c0006b22022400200241206a41086a220342003703002002420037032041d8fec5004117200241206a1008200241086a2003290300370300200220022903203703002002410036022020024110200241206a1006210302400240024002400240024020022802202204417f470d00420121050c010b024020030d00420121050c010b20044108490d01200329000021052003102a200542017c21050b200241206a41086a220342003703002002420037032041d8fec5004117200241206a1008200241086a2003290300370300200220022903203703002002200537032020024110200241206a41081007412010282203450d0120032001290000370000200341186a200141186a290000370000200341106a200141106a290000370000200341086a200141086a2900003700002003412041c000102c2201450d0220012005370020200241206a41186a22034200370300200241206a41106a22044200370300200241206a41086a220642003703002002420037032020014128200241206a1000200241186a2003290300370300200241106a2004290300370300200241086a200629030037030020022002290320370300413710282203450d03200342bac6a1cbc68dd9aff300370000200342f4dec98bf6ac999de400370008200341e5cc85ab073600102003413a3a0016200341ece8013b001420032002290300370017200320022f01083b001f2003200228010a360021200320022f010e3b0025200320022d00103a0027200320022d00113a0028200320022d00123a0029200320022d00133a002a200320022d00143a002b200320022d00153a002c200320022d00163a002d200320022d00173a002e200320022d00183a002f200320022d00193a0030200320022d001a3a0031200320022d001b3a0032200320022d001c3a0033200320022d001d3a0034200320022d001e3a0035200320022d001f3a0036200041ed93c40041c593c4006b410f6a36020820004137360204200020033602002001102a200241c0006a24000f0b41c4d1c3004133200241206a419cd9c3001038000b412041011037000b41c00041011037000b413741011037000ba70101047f230041206b22002400200041106a41086a220142003703002000420037031041d9efc200410d200041106a1008200041086a200129030037030020002000290310370300410021022000410036021020004110200041106a100621010240024020002802102203417f460d002001450d0020034104490d01200128000021022001102a0b200041206a240020020f0b41c4d1c3004133200041106a419cd9c3001038000bdd0605057f047e017f017e047f23004190016b2202240002400240024020012802202203450d0020012003417f6a36022020012802082104200128020c2203200128020422052f01064f0d01200241e0006a41186a200520034105746a220641206a2900002207370300200241e0006a41106a200641186a2900002208370300200241e0006a41086a200641106a29000022093703002002200641086a290000220a370360200241306a41086a20052003410c6c6a220641f0026a280200220b360200200641e8026a290200210c2001200341016a36020c20012004360208200120053602042002200c3703302000200a3702042000410c6a2009370200200041146a20083702002000411c6a2007370200200041246a200c3702002000412c6a200b360200200041013602000c020b200041003602000c010b2001280200210602400240200528020022030d002004ad210c410021030c010b200641016a210620053301044220862004ad84210c0b2005102a200ca7210402400240200c422088a7220b20032f01064f0d00200321050c010b034002400240200328020022050d002004ad210c410021050c010b200641016a210620033301044220862004ad84210c0b2003102a200ca7210420052103200c422088a7220b20052f01064f0d000b0b200241306a41186a220d2005200b4105746a220341206a290000370300200241306a41106a220e200341186a290000370300200241306a41086a220f200341106a2900003703002002200341086a290000370330200241d0006a41086a22102005200b410c6c6a220341f0026a2802003602002002200341e8026a290200370350200b41027420056a41f0036a280200210302402006417f6a2205450d00034020032802ec0321032005417f6a22050d000b0b2001410036020c200120043602082001200336020420014100360200200241e0006a41186a200d290300220c370300200241e0006a41106a200e2903002207370300200241e0006a41086a200f290300220837030020024188016a201028020022033602002000200229033022093702042000410c6a2008370200200041146a20073702002000411c6a200c370200200041246a2002290350220c3702002000412c6a2003360200200220093703602002200c37038001200041013602000b20024190016a24000ba70201057f230041d0006b220224000240411710282203450d00200341002900f1d8433700002003410f6a4100290080d943370000200341086a41002900f9d84337000020024297808080f002370224200220033602202000200241206a108f012002280228210320022802202100200241306a41186a22044200370300200241306a41106a22054200370300200241306a41086a220642003703002002420037033020002003200241306a1000200241186a2004290300370300200241106a2005290300370300200241086a20062903003703002002200229033037030002402002280224450d002002280220102a0b2002200110e203024020012d00000d002001411c6a280200450d00200141186a280200102a0b200241d0006a24000f0b411741011037000bca0201067f230041b0016b22012400200141086a2000109301024020012903284202510d000340200128026021022001280258210302400240200128025c22040d00200321050c010b2004210620032105034020052802ec0321052006417f6a22060d000b0340200320032f01064102746a41ec036a28020021032004417f6a22040d000b0b200120023602a801200141003602a001200141003602980120014200370390012001200536028c0120014100360288012001200336029c01200120032f01063602a40120014188016a109501200141086a200010930120012903284202520d000b0b02402000280204220341f8b9c000460d00200328020021042003102a2004450d00200428020021052004102a2005450d00024020052802002203450d0003402005102a2003210520032802002204210320040d000b0b2005102a0b200141b0016a24000bcf0204017f017e027f037e230041206b2201240042002102200141106a41086a220342003703002001420037031041ace1c0004116200141106a1008200141086a2003290300370300200120012903103703002001410036021020014110200141106a1006210302400240024020012802102204417f470d00420021050c010b20044110490d01200341086a2900002105200329000021022003102a0b2000280200220341086a290300210620032903002107200141106a41086a220342003703002001420037031041ace1c0004116200141106a1008200141086a2003290300370300200120012903103703002001427f200520067c200220077c22062002542203ad7c22022003200220055420022005511b22031b3703182001427f200620031b37031020014110200141106a41101007200141206a24000f0b41c4d1c3004133200141106a419cd9c3001038000bd00204017f017e027f037e230041206b2201240042002102200141106a41086a220342003703002001420037031041ace1c0004116200141106a1008200141086a2003290300370300200120012903103703002001410036021020014110200141106a1006210302400240024020012802102204417f470d00420021050c010b20044110490d01200341086a2900002105200329000021022003102a0b2000280200220341086a290300210620032903002107200141106a41086a220342003703002001420037031041ace1c0004116200141106a1008200141086a20032903003703002001200129031037030020014200200520067d2002200754ad7d2206200220077d2207200256200620055620062005511b22031b37031820014200200720031b37031020014110200141106a41101007200141206a24000f0b41c4d1c3004133200141106a419cd9c3001038000bb50404057f017e017f017e0240024020012802042202450d00200128020022032d0000210420012002417f6a22053602042001200341016a3602000240200441037122064103460d00024002400240024020060e03000102000b2004410276ad21070c020b41012106024020050d000c050b20032d0001210520012002417e6a3602042001200341026a3602002005410874200472220141ffff0371418002490d04200141fcff0371410276ad21070c010b410121060240200541034f0d000c040b200341036a2d0000210520032f0001210820012002417c6a3602042001200341046a3602002008200541107472410874200472220141808004490d032001410276ad21070b410021060c020b02402004410276220841044b0d000240024020080e050002020201000b20054104490d022003350001210720012002417b6a3602042001200341056a36020020074280808080045421060c030b20054108490d01200329000121072001200241776a3602042001200341096a3602002007428080808080808080015421060c020b200841046a220541084b0d002002417e6a2102200341026a2103410021044200210741012106034002402002417f470d000c030b2003417f6a310000210920012002360204200120033602002002417f6a2102200341016a210320092004410374413871ad862007842107200441016a220441ff01712005490d000b2007427f412820084103746b413871ad885821060c010b410121060b2000200737030820002006ad3703000bde0506067f017e017f017e017f017e230041206b220224000240024020012802042203450d00200128020022042d0000210520012003417f6a22063602042001200441016a360200024002400240200541037122074103460d0002400240024020070e03000102000b2005410276ad21080c040b410121072006450d0220042d0001210620012003417e6a3602042001200441026a3602002006410874200572220141ffff0371418002490d02200141fcff0371410276ad21080c030b4101210720064103490d01200441036a2d0000210620042f0001210920012003417c6a3602042001200441046a3602002009200641107472410874200572220141808004490d012001410276ad21080c020b024020054102762209410c4b0d0002400240024020090e0d00030303010303030303030302000b20064104490d052004350001210820012003417b6a3602042001200441056a36020020084280808080045421074200210a0c060b20064108490d04200429000121082001200341776a3602042001200441096a3602002008428080808080808080015421074200210a0c050b20064110490d03200441096a290000210a2004290001210820012003416f6a3602042001200441116a360200200a428080808080808080015421070c040b200941046a220641104b0d022003417e6a2103200441026a21044100210541012107200241186a210b420021084200210a03402003417f460d01200241106a2004417f6a3100004200200541037441f80071109d0520012003360204200120043602002003417f6a2103200441016a2104200b290300200a84210a20022903102008842108200541016a220541ff01712006490d000b2002427f427f41e80020094103746b41f80071109e052008200229030058200a200241086a290300220c58200a200c511b21070c030b0c020b4200210a410021070c010b410121070b20002008370308200041106a200a37030020002007ad370300200241206a24000b9e0701037f02400240024002400240024020002802002202413f4b0d0002400240200141046a280200200141086a2802002200460d00200128020021030c010b200041016a22032000490d06200041017422042003200420034b1b22044100480d060240024020000d002004102821030c010b200128020020002004102c21030b2003450d0220012003360200200141046a2004360200200141086a28020021000b200141086a200041016a360200200320006a20024102743a00000f0b200241808001490d032002418080808004490d020c010b200441011037000b0240024002400240200141046a280200200141086a2802002202460d00200128020021030c010b200241016a22032002490d05200241017422042003200420034b1b22044100480d050240024020020d002004102821030c010b200128020020022004102c21030b2003450d0120012003360200200141046a2004360200200141086a28020021020b200141086a2204200241016a360200200320026a41033a00002000280200210302400240200141046a2802002202200428020022006b4104490d00200128020021020c010b200041046a22042000490d05200241017422002004200020044b1b22004100480d050240024020020d002000102821020c010b200128020020022000102c21020b2002450d0220012002360200200141046a2000360200200141086a28020021000b200141086a200041046a360200200220006a20033600000f0b200441011037000b200041011037000b024002400240200141046a2802002203200141086a28020022006b4104490d00200128020021030c010b200041046a22042000490d03200341017422002004200020044b1b22004100480d030240024020030d002000102821030c010b200128020020032000102c21030b2003450d0120012003360200200141046a2000360200200141086a28020021000b200141086a200041046a360200200320006a20024102744102723600000f0b200041011037000b024002400240200141046a2802002203200141086a28020022006b4102490d00200128020021030c010b200041026a22042000490d02200341017422002004200020044b1b22004100480d020240024020030d002000102821030c010b200128020020032000102c21030b2003450d0120012003360200200141046a2000360200200141086a28020021000b200141086a200041026a360200200320006a20024102744101723b00000f0b200041011037000b1031000bac0903017f017e057f230041e0006b220224000240024002400240024002400240024002400240024020002903002203423f560d0002400240200141046a280200200141086a2802002200460d00200128020021040c010b200041016a22042000490d0b200041017422052004200520044b1b22054100480d0b0240024020000d002005102821040c010b200128020020002005102c21040b2004450d0220012004360200200141046a2005360200200141086a28020021000b200141086a200041016a360200200420006a2003a74102743a00000c080b200342808001540d062003428080808004540d054108200379a741037622056b4104490d0402400240200141046a280200200141086a2802002204460d00200128020021060c010b200441016a22072004490d0a200441017422062007200620074b1b22074100480d0a0240024020040d002007102821060c010b200128020020042007102c21060b2006450d0220012006360200200141046a2007360200200141086a28020021040b200141086a2207200441016a360200200620046a411320054102746b3a0000200220002903002203370308200541786a2104200141046a2106034002400240200628020020072802002200460d00200128020021050c010b200041016a22052000490d0b200041017422082005200820054b1b22084100480d0b0240024020000d002008102821050c010b200128020020002008102c21050b2005450d042001200536020020062008360200200728020021000b2007200041016a360200200520006a2003a73a000020034208882103200441016a22002004492105200021042005450d000b20022003370308200350450d030c070b200541011037000b200741011037000b200841011037000b200241286a41146a4108360200200241346a4109360200200241106a41146a41033602002002200241086a360240200241f8b9c00036024420024203370214200241c8afc6003602102002410936022c200242043703582002420137024c20024180bac0003602482002200241286a3602202002200241c8006a3602382002200241c4006a3602302002200241c0006a360228200241106a4188bac000103e000b41dcb9c0001032000b024002400240200141046a2802002204200141086a28020022006b4104490d00200128020021040c010b200041046a22052000490d05200441017422002005200020054b1b22004100480d050240024020040d002000102821040c010b200128020020042000102c21040b2004450d0120012004360200200141046a2000360200200141086a28020021000b200141086a200041046a360200200420006a2003a74102744102723600000c020b200041011037000b02400240200141046a2802002204200141086a28020022006b4102490d00200128020021040c010b200041026a22052000490d03200441017422002005200020054b1b22004100480d030240024020040d002000102821040c010b200128020020042000102c21040b2004450d0220012004360200200141046a2000360200200141086a28020021000b200141086a200041026a360200200420006a2003a74102744101723b00000b200241e0006a24000f0b200041011037000b1031000bbf0202027f017e23004180016b220224002000280200210002400240024002400240200128020022034110710d002000290300210420034120710d01200441012001103f21000c020b20002903002104410021000340200220006a41ff006a2004a7410f712203413072200341d7006a2003410a491b3a00002000417f6a2100200442048822044200520d000b20004180016a22034181014f0d0220014101419087c0004102200220006a4180016a410020006b104221000c010b410021000340200220006a41ff006a2004a7410f712203413072200341376a2003410a491b3a00002000417f6a2100200442048822044200520d000b20004180016a22034181014f0d0220014101419087c0004102200220006a4180016a410020006b104221000b20024180016a240020000f0b20034180011044000b20034180011044000b800a03017f027e057f230041e0006b2202240002400240024002400240024002400240024002400240200028020022002903002203423f56200041086a290300220442005220045022051b0d0002400240200141046a280200200141086a2802002200460d00200128020021050c010b200041016a22052000490d0b200041017422062005200620054b1b22064100480d0b0240024020000d002006102821050c010b200128020020002006102c21050b2005450d0220012005360200200141046a2006360200200141086a28020021000b200141086a200041016a360200200520006a2003a74102743a00000c080b20034280800154410020051b0d06200342808080800454410020051b0d05411020047920037942c0007c20044200521ba741037622066b4104490d0402400240200141046a280200200141086a2802002205460d00200128020021070c010b200541016a22082005490d0a200541017422072008200720084b1b22084100480d0a0240024020050d002008102821070c010b200128020020052008102c21070b2007450d0220012007360200200141046a2008360200200141086a28020021050b200141086a2208200541016a360200200720056a413320064102746b3a0000200029030021032002200041086a290300220437030820022003370300200641706a2105200141046a2107034002400240200728020020082802002200460d00200128020021060c010b200041016a22062000490d0b200041017422092006200920064b1b22094100480d0b0240024020000d002009102821060c010b200128020020002009102c21060b2006450d042001200636020020072009360200200828020021000b2008200041016a360200200620006a2003a73a00002003420888200442388684210320044208882104200541016a22002005492106200021052006450d000b2002200337030020022004370308200320048450450d030c070b200641011037000b200841011037000b200941011037000b200241286a41146a4108360200200241346a410a360200200241106a41146a410336020020022002360240200241a8bbc00036024420024203370214200241c8afc6003602102002410a36022c200242043703582002420137024c20024180bac0003602482002200241286a3602202002200241c8006a3602382002200241c4006a3602302002200241c0006a360228200241106a41b8bbc000103e000b418cbbc0001032000b024002400240200141046a2802002205200141086a28020022006b4104490d00200128020021050c010b200041046a22062000490d05200541017422002006200020064b1b22004100480d050240024020050d002000102821050c010b200128020020052000102c21050b2005450d0120012005360200200141046a2000360200200141086a28020021000b200141086a200041046a360200200520006a2003a74102744102723600000c020b200041011037000b02400240200141046a2802002205200141086a28020022006b4102490d00200128020021050c010b200041026a22062000490d03200541017422002006200020064b1b22004100480d030240024020050d002000102821050c010b200128020020052000102c21050b2005450d0220012005360200200141046a2000360200200141086a28020021000b200141086a200041026a360200200520006a2003a74102744101723b00000b200241e0006a24000f0b200041011037000b1031000b810605027f027e017f027e027f230041a0016b220224002000280200210002400240024002400240024002400240200128020022034110710d00200041086a29030021042000290300210520034120710d0220054290ce005441002004501b450d012005a72103412721000c060b200041086a2903002105200029030021044180012100024003402000450d01200241206a20006a417f6a2004a7410f712203413072200341d7006a2003410a491b3a00002000417f6a210020044204882005423c8684220420054204882205844200520d000b0b20004181014f0d0220014101419087c0004102200241206a20006a41800120006b104221000c060b41272100200241186a21060340200241106a200520044290ce00420010a0052002200229031022072006290300220842f0b17f427f109f05200241206a20006a2203417c6a200520022903007ca7220941ffff037141e4006e220a41017441ba84c0006a2f00003b00002003417e6a200a419c7f6c20096a41ffff037141017441ba84c0006a2f00003b0000200542ffc1d72f56210320044200522109200450210a2000417c6a2100200721052008210420032009200a1b0d000c040b0b4180012100024003402000450d01200241206a20006a417f6a2005a7410f712203413072200341376a2003410a491b3a00002000417f6a210020054204882004423c8684220520044204882204844200520d000b0b20004181014f0d0120014101419087c0004102200241206a20006a41800120006b104221000c040b20004180011044000b20004180011044000b2007a721030b02400240200341e3004a0d00200321090c010b200241206a2000417e6a22006a2003200341ffff037141e4006e2209419c7f6c6a41ffff037141017441ba84c0006a2f00003b00000b024002402009410a480d00200241206a2000417e6a22006a200941017441ba84c0006a2f00003b00000c010b200241206a2000417f6a22006a200941306a3a00000b2001410141b8aec6004100200241206a20006a412720006b104221000b200241a0016a240020000bf40601067f230041f0006b21020240024002400240024002400240024002400240024020012802042203450d00200128020022042d0000210520012003417f6a2206360204410121072001200441016a360200200541f001490d0a200541847e6a220541034b0d0420050e0401020803010b200041023a00000f0b20064102490d0320042f0001210520012003417d6a3602042001200441036a360200200541ef014b0d04200041023a00000f0b20064104490d042004280001210520012003417b6a3602042001200441056a36020041012107200541ffff034b0d07200041023a00000f0b41002105200241003a00682003417f6a21062003417e6a210302400340024020062005470d000240200541ff0171450d00200241003a00680b410121010c020b200241c8006a20056a200420056a220741016a2d00003a0000200120033602042001200741026a3602002002200541016a22073a00682003417f6a21032007210520074120470d000b200241c6006a20022d004a3a0000200241306a200241d7006a290000370300200241386a200241df006a290000370300200241c0006a200241e7006a2d00003a0000200220022f01483b01442002200229004f370328200228004b2105410021010b200241246a41026a2203200241c4006a41026a2d00003a0000200241086a41086a2207200241286a41086a290300370300200241086a41106a2204200241286a41106a290300370300200241086a41186a2206200241286a41186a2d00003a0000200220022f01443b0124200220022903283703082001450d05200041023a00000f0b200041023a00000f0b200041023a00000f0b410121070c030b200041023a00000f0b0240200641044f0d00200041023a00000f0b200041023a000020012003417b6a3602042001200441056a3602000f0b200241286a41026a20032d00003a0000200241c8006a41086a2007290300370300200241c8006a41106a2004290300370300200241c8006a41186a20062d00003a0000200220022f01243b012820022002290308370348410021070b200020073a0000200020022f01283b0001200041046a2005360200200041086a2002290348370200200041036a2002412a6a2d00003a0000200041106a200241c8006a41086a290300370200200041186a200241c8006a41106a290300370200200041206a200241c8006a41186a2802003602000bb30801037f0240024002400240024002400240024020002d00004101460d0002400240200141046a280200200141086a2802002202460d00200128020021030c010b200241016a22032002490d08200241017422042003200420034b1b22044100480d080240024020020d002004102821030c010b200128020020022004102c21030b2003450d0220012003360200200141046a2004360200200141086a28020021020b200141086a200241016a360200200320026a41ff013a0000200041016a2001108f010f0b0240024002400240200041046a280200220241ffff034b0d00200241ef014b0d03200141046a280200200141086a2802002200460d01200128020021030c020b02400240200141046a280200200141086a2802002200460d00200128020021030c010b200041016a22032000490d0a200041017422042003200420034b1b22044100480d0a0240024020000d002004102821030c010b200128020020002004102c21030b2003450d0520012003360200200141046a2004360200200141086a28020021000b200141086a2204200041016a360200200320006a41fd013a000002400240200141046a2802002203200428020022006b4104490d00200128020021030c010b200041046a22042000490d0a200341017422002004200020044b1b22004100480d0a0240024020030d002000102821030c010b200128020020032000102c21030b2003450d0620012003360200200141046a2000360200200141086a28020021000b200141086a200041046a360200200320006a20023600000f0b200041016a22032000490d08200041017422042003200420034b1b22044100480d080240024020000d002004102821030c010b200128020020002004102c21030b2003450d0520012003360200200141046a2004360200200141086a28020021000b200141086a200041016a360200200320006a20023a00000f0b02400240200141046a280200200141086a2802002200460d00200128020021030c010b200041016a22032000490d07200041017422042003200420034b1b22044100480d070240024020000d002004102821030c010b200128020020002004102c21030b2003450d0520012003360200200141046a2004360200200141086a28020021000b200141086a2204200041016a360200200320006a41fc013a000002400240200141046a2802002203200428020022006b4102490d00200128020021030c010b200041026a22042000490d07200341017422002004200020044b1b22004100480d070240024020030d002000102821030c010b200128020020032000102c21030b2003450d0620012003360200200141046a2000360200200141086a28020021000b200141086a200041026a360200200320006a20023b00000f0b200441011037000b200441011037000b200041011037000b200441011037000b200441011037000b200041011037000b1031000bd80402097f017e230041106b22052400024002400240200128020041016a220641004c0d0020012006360200200141046a2106200141086a28020021070240024003402006280200220841086a210920082f0106220a41057421064100210b0240024003402006450d01200220094120109c05220c450d02200641606a2106200b41016a210b200941206a2109200c417f4a0d000b200b417f6a210a0b2007450d022007417f6a21072008200a4102746a41880b6a21060c010b0b2008200b41e0006c6a22094198036a2106200941e8026a210d2009419c036a2802002107024003402006280200220841086a210920082f0106220a41057421064100210b0240024003402006450d01200420094120109c05220c450d02200641606a2106200b41016a210b200941206a2109200c417f4a0d000b200b417f6a210a0b024020070d004100210c0c030b2007417f6a21072008200a4102746a41ec036a21060c010b0b4101210c0240200841e8026a200b410c6c6a2206280200220b0d00410021060c010b20062802082209417f4c0d040240024020090d0020054200370300410121060c010b200910282206450d0620054100360204200520093602000b200520093602042006200b2009109a051a2005290300210e0b02400240200d2d005d450d0020064100200c1b21060c010b200c450d010b2000200e370204200020063602000c010b20002001280210200220032004200141146a28020028020c1104000b20012001280200417f6a360200200541106a24000f0b41b8b8c0004118200541086a41e0b8c0001038000b1036000b200941011037000bfc0202097f037e230041206b220324000240200128020041016a220441004c0d0020012004360200200141046a2105200141086a28020021060240024003402005280200220741086a210820072f0106220941057421054100210a0240024003402005450d01200220084120109c05220b450d02200541606a2105200a41016a210a200841206a2108200b417f4a0d000b200a417f6a21090b2006450d022006417f6a2106200720094102746a41880b6a21050c010b0b2007200a41e0006c6a22054190036a290300210c20054188036a290300210d20054180036a290300210e0240200541c5036a2d00000d00200ea721054201210e2005450d010c020b200e4202520d010b200320012802102002200141146a280200280214110500200341106a290300210c200128020021042003290308210d2003290300210e0b20012004417f6a360200200041106a200c3703002000200d3703082000200e370300200341206a24000f0b41b8b8c0004118200341186a41e0b8c0001038000bd70501037f024002400240024002400240024020002d00004101460d0002400240200141046a280200200141086a2802002202460d00200128020021030c010b200241016a22032002490d07200241017422042003200420034b1b22044100480d070240024020020d002004102821030c010b200128020020022004102c21030b2003450d0320012003360200200141046a2004360200200141086a28020021020b200141086a200241016a360200200320026a41003a00000c010b02400240200141046a280200200141086a2802002202460d00200128020021030c010b200241016a22032002490d06200241017422042003200420034b1b22044100480d060240024020020d002004102821030c010b200128020020022004102c21030b2003450d0320012003360200200141046a2004360200200141086a28020021020b200141086a200241016a360200200320026a41013a0000200041016a2001108f010b024020002d00214101460d0002400240200141046a280200200141086a2802002200460d00200128020021020c010b200041016a22022000490d06200041017422032002200320024b1b22034100480d060240024020000d002003102821020c010b200128020020002003102c21020b2002450d0420012002360200200141046a2003360200200141086a28020021000b200141086a200041016a360200200220006a41003a00000f0b02400240200141046a280200200141086a2802002202460d00200128020021030c010b200241016a22032002490d05200241017422042003200420034b1b22044100480d050240024020020d002004102821030c010b200128020020022004102c21030b2003450d0420012003360200200141046a2004360200200141086a28020021020b200141086a200241016a360200200320026a41013a0000200041226a2001108f010f0b200441011037000b200441011037000b200341011037000b200441011037000b1031000bbf0501047f200141046a2802002102200141086a28020021030240024002400240024002400240200028020022040d000240024020022003460d00200128020021020c010b200341016a22022003490d07200341017422042002200420024b1b22044100480d070240024020030d002004102821020c010b200128020020032004102c21020b2002450d0320012002360200200141046a2004360200200141086a28020021030b200141086a200341016a360200200220036a41003a00000c010b0240024020022003460d00200128020021020c010b200341016a22022003490d06200341017422052002200520024b1b22054100480d060240024020030d002005102821020c010b200128020020032005102c21020b2002450d0320012002360200200141046a2005360200200141086a28020021030b200141086a200341016a360200200220036a41013a000020042001108f010b200141046a2802002102200141086a28020021030240200028020422040d000240024020022003460d00200128020021000c010b200341016a22002003490d06200341017422022000200220004b1b22024100480d060240024020030d002002102821000c010b200128020020032002102c21000b2000450d0420012000360200200141046a2002360200200141086a28020021030b200141086a200341016a360200200020036a41003a00000f0b0240024020022003460d00200128020021000c010b200341016a22002003490d05200341017422022000200220004b1b22024100480d050240024020030d002002102821000c010b200128020020032002102c21000b2000450d0420012000360200200141046a2002360200200141086a28020021030b200141086a200341016a360200200020036a41013a000020042001108f010f0b200441011037000b200541011037000b200241011037000b200241011037000b1031000b860a05037f047e057f027e047f230022022103200241c0016b41607122022400200141186a220429000021052004200229039801370000200129001021062001200229039001370010200129000821072001200229038801370008200241003a00800120012900002108200120022903800137000020022005370378200220063703702002200737036820022008370360200141206a2d0000210420024180016a41176a2209200537000020024180016a41106a220a200229007137030020024180016a41086a220b2002290069370300200220022900613703800102402008a741ff01714101460d0020004200370300200324000f0b200241186a41176a2009290000370000200241186a41106a200a290300370300200241186a41086a200b2903003703002002200229038001370318200220043a0037200241386a200241186a10ac012002410036028001200241386a412020024180016a1006210c02400240200228028001220d417f460d002002200d36025c2002200c3602582002200241d8006a109f012002290300a70d01200228025c2204450d01200241106a290300210e2002290308210f20022004417f6a220a36025c20022002280258221041016a220b36025820102d0000220441014b0d01410021110240024020040e020100010b4100210403400240200a2004470d002002410036025c0c040b2002201020046a41026a360258200441016a2209210420094120470d000b2002200a20096b220a36025c41012111201020096a41016a210b0b200a450d012002200a417f6a220a36025c2002200b41016a360258200b2d0000220941014b0d01410021040240024020090e020100010b41002104200241003a00a00103400240200a2004470d002002410036025c200441ff0171450d04200241003a00a0010c040b20024180016a20046a200b20046a220941016a2d00003a00002002200941026a3602582002200441016a22093a00a0012009210420094120470d000b200241e0006a41086a20024180016a41086a290300370300200241e0006a41106a20024180016a41106a290300370300200241e0006a41186a20024180016a41186a29030037030020022002290380013703602002200a20096b36025c410121040b20024180016a41186a2209200241e0006a41186a220a29030037030020024180016a41106a220b200241e0006a41106a221029030037030020024180016a41086a2212200241e0006a41086a2213290300370300200220022903603703800120114102460d01200a20092903003703002010200b2903003703002013201229030037030020022002290380013703600240200d450d00200c102a0b20024180016a41186a200241e0006a41186a2209290300220537030020024180016a41106a200241e0006a41106a220a290300220837030020024180016a41086a200241e0006a41086a220b29030022063703002002200229036022073703800120092005370300200a2008370300200b200637030020022007370360200120043a000020012007370001200141096a2006370000200141116a2008370000200141196a2005370000200041306a200e370300200041286a200f3703002000420137030020002002290318370008200041106a200241186a41086a290300370000200041186a200241186a41106a290300370000200041206a200241186a41186a290300370000200324000f0b41c9b4c00041dd001050000b41c4d1c3004133200241b8016a419cd9c3001038000bfc0101057f230041306b220224000240411210282203450d00200341002900c1ae44370000200341106a41002f00d1ae443b0000200341086a41002900c9ae4437000020024292808080a0023702042002200336020020012002108f012002280208210320022802002101200241106a41186a22044200370300200241106a41106a22054200370300200241106a41086a220642003703002002420037031020012003200241106a1000200041186a2004290300370000200041106a2005290300370000200041086a20062903003700002000200229031037000002402002280204450d002002280200102a0b200241306a24000f0b411241011037000b910a03037f047e0c7f230022022103200241c0016b41607122022400200141186a220429000021052004200229039801370000200129001021062001200229039001370010200129000821072001200229038801370008200241003a00800120012900002108200120022903800137000020022005370378200220063703702002200737036820022008370360200141206a2d0000210420024180016a41176a2209200537000020024180016a41106a220a200229007137030020024180016a41086a220b2002290069370300200220022900613703800102402008a741ff01714101460d0020004100360220200324000f0b200241086a41176a2009290000370000200241086a41106a200a290300370300200241086a41086a200b2903003703002002200229038001370308200220043a0027200241286a200241086a10ae012002410036028001200241286a412020024180016a1006210c024002400240200228028001220d417f460d002002200d36024c2002200c360248200241d0006a200241c8006a106d2002280250220e450d022002280254210f200228024c2204450d01200241d8006a280200211020022004417f6a220a36024c20022002280248221141016a220b36024820112d0000220441014b0d01410021120240024020040e020100010b4100210403400240200a2004470d002002410036024c0c040b2002201120046a41026a360248200441016a2209210420094120470d000b2002200a20096b220a36024c41012112201120096a41016a210b0b200a450d012002200a417f6a220a36024c2002200b41016a360248200b2d0000220941014b0d01410021040240024020090e020100010b41002104200241003a00a00103400240200a2004470d002002410036024c200441ff0171450d04200241003a00a0010c040b20024180016a20046a200b20046a220941016a2d00003a00002002200941026a3602482002200441016a22093a00a0012009210420094120470d000b200241e0006a41086a20024180016a41086a290300370300200241e0006a41106a20024180016a41106a290300370300200241e0006a41186a20024180016a41186a29030037030020022002290380013703602002200a20096b36024c410121040b20024180016a41186a2209200241e0006a41186a220a29030037030020024180016a41106a220b200241e0006a41106a221129030037030020024180016a41086a2213200241e0006a41086a2214290300370300200220022903603703800120124102460d02200a20092903003703002011200b2903003703002014201329030037030020022002290380013703600240200d450d00200c102a0b20024180016a41186a200241e0006a41186a2209290300220537030020024180016a41106a200241e0006a41106a220a290300220837030020024180016a41086a200241e0006a41086a220b29030022063703002002200229036022073703800120092005370300200a2008370300200b200637030020022007370360200120043a000020012007370001200141096a2006370000200141116a2008370000200141196a2005370000200041286a20103602002000200f3602242000200e36022020002002290308370000200041086a200241086a41086a290300370000200041106a200241086a41106a290300370000200041186a200241086a41186a290300370000200324000f0b41c9b4c00041dd001050000b200f450d00200e102a0b41c4d1c3004133200241d0006a419cd9c3001038000bfc0101057f230041306b220224000240411210282203450d0020034100290095ae44370000200341106a41002f00a5ae443b0000200341086a410029009dae4437000020024292808080a0023702042002200336020020012002108f012002280208210320022802002101200241106a41186a22044200370300200241106a41106a22054200370300200241106a41086a220642003703002002420037031020012003200241106a1000200041186a2004290300370000200041106a2005290300370000200041086a20062903003700002000200229031037000002402002280204450d002002280200102a0b200241306a24000f0b411241011037000bfe0703037f047e0a7f23002202210320024180036b41607122022400200141186a220429000021052004200229039802370000200129001021062001200229039002370010200129000821072001200229038802370008200241003a0080022001290000210820012002290380023700002002200537039801200220063703900120022007370388012002200837038001200141206a2d0000210420024180026a41176a2209200537000020024180026a41106a220a20022900910137030020024180026a41086a220b20022900890137030020022002290081013703800202402008a741ff01714101460d00200041073a0040200324000f0b200241186a41176a2009290000370000200241186a41106a200a290300370300200241186a41086a200b2903003703002002200229038002370318200220043a0037200241e0006a200241186a10b0012002410036028002200241e0006a412020024180026a1006210c0240200228028002220d417f460d002002200d36023c2002200c36023820024180026a200241386a10b101024020022d00a1024102460d00200241d8016a41206a220420024180026a41206a2d00003a0000200241d8016a41186a220920024180026a41186a220e290300370300200241d8016a41106a220a20024180026a41106a220f290300370300200241d8016a41086a220b20024180026a41086a221029030037030020022002290380023703d80120024180016a200241a2026a41c100109a051a0240200d450d00200c102a0b200241386a41206a220d20042d00003a0000200241386a41186a220c2009290300370300200241386a41106a2211200a290300370300200241386a41086a2212200b290300370300200220022903d80137033820024180026a20024180016a41c100109a051a2004200d2d00003a00002009200c290300370300200a2011290300370300200b2012290300370300200220022903383703d80120024180016a20024180026a41c100109a051a200141206a20024180016a41c0006a2d00003a0000200141186a20024180016a41386a290000370000200141106a20024180016a41306a290000370000200141086a20024180016a41286a290000370000200120022900a001370000200e200241186a41186a290300370300200f200241186a41106a2903003703002010200241186a41086a290300370300200220022903183703800220024180026a41286a200b29030037030020024180026a41306a200a29030037030020024180026a41386a200929030037030020024180026a41c0006a20042d00003a0000200220022903d8013703a002200020024180026a41c100109a051a200324000f0b41c4d1c300413320024180016a419cd9c3001038000b41c9b4c00041dd001050000bfc0101057f230041306b220224000240411510282203450d00200341002900d088453700002003410d6a41002900dd8845370000200341086a41002900d8884537000020024295808080d0023702042002200336020020012002108f012002280208210320022802002101200241106a41186a22044200370300200241106a41106a22054200370300200241106a41086a220642003703002002420037031020012003200241106a1000200041186a2004290300370000200041106a2005290300370000200041086a20062903003700002000200229031037000002402002280204450d002002280200102a0b200241306a24000f0b411541011037000bd30b03097f017e017f23004190026b2202240041002103200241003a00880220012802042204417d6a2105417f21060240024002400240024002400240034020042003460d01200241e8016a20036a200128020022072d00003a00002001200420066a3602042001200741016a3602002002200341016a22083a0088022005417f6a21052006417f6a21062008210320084120470d000b200241c8016a41186a200241e8016a41186a290300370300200241c8016a41106a200241e8016a41106a290300370300200241c8016a41086a200241e8016a41086a290300370300200220022903e8013703c80120042008460d0120072d000121092001200420066a3602042001200741026a360200200941074f0d01200241086a41186a200241c8016a41186a290300370300200241086a41106a200241c8016a41106a290300370300200241086a41086a200241c8016a41086a290300370300200220022903c8013703082004417f6a2008460d0520072d000221032001200741036a220a3602002001200420086b2206417e6a2208360204200341014b0d0520030e020302030b200341ff0171450d00200241003a0088020b200041023a00210c040b41002103200241003a0088022006417e6a2104417d21080340024020042003470d00200341ff0171450d04200241003a0088020c040b200241e8016a20036a200720036a220641036a2d00003a00002001200520036b3602042001200641046a3602002002200341016a22063a0088022008417f6a21082006210320064120470d000b200241a8016a41086a200241e8016a41086a290300220b37030020024188016a41186a200241e8016a41186a29030037030020024188016a41106a200241e8016a41106a29030037030020024188016a41086a200b370300200220022903e801220b3703a8012002200b370388014101210c200520066b41016a2108200720066a41036a210a0c010b4100210c0b200241e8006a41186a20024188016a41186a290300370300200241e8006a41106a20024188016a41106a290300370300200241e8006a41086a20024188016a41086a29030037030020022002290388013703682008450d00200a2d0000210320012008417f6a3602042001200a41016a360200200341014b0d00410021060240024020030e020100010b41002103200241003a0088022008417f6a21042008417e6a21060340024020042003470d00200341ff0171450d03200241003a0088020c030b200241e8016a20036a200a20036a220841016a2d00003a0000200120063602042001200841026a3602002002200341016a22083a0088022006417f6a21062008210320084120470d000b200241a8016a41086a200241e8016a41086a290300220b37030020024188016a41186a200241e8016a41186a29030037030020024188016a41106a200241e8016a41106a29030037030020024188016a41086a200b370300200220022903e801220b3703a8012002200b37038801410121060b200241286a41186a220320024188016a41186a290300370300200241286a41106a220120024188016a41106a290300370300200241286a41086a220820024188016a41086a290300370300200241c8006a41086a2204200241e8006a41086a290300370300200241c8006a41106a2205200241e8006a41106a290300370300200241c8006a41186a2207200241e8006a41186a290300370300200220022903880137032820022002290368370348200041186a200241086a41186a290300370000200041106a200241086a41106a290300370000200041086a200241086a41086a290300370000200020022903083700002000200c3a0021200020093a0020200041c2006a20063a0000200020022903483700222000412a6a2004290300370000200041326a20052903003700002000413a6a2007290300370000200041c3006a2002290328370000200041cb006a2008290300370000200041d3006a2001290300370000200041db006a20032903003700000c010b200041023a00210b20024190026a24000b340020004197dbc00036020420004100360200200041146a4103360200200041106a41bcbcc000360200200041086a42083702000b5201027f230041106b2202240002404104102822030d00410441011037000b20024204370204200220033602004100200210b401200041086a200228020836020020002002290300370200200241106a24000b920701037f0240024002400240024002402000413f4b0d0002400240200141046a280200200141086a2802002202460d00200128020021030c010b200241016a22032002490d06200241017422042003200420034b1b22044100480d060240024020020d002004102821030c010b200128020020022004102c21030b2003450d0220012003360200200141046a2004360200200141086a28020021020b200141086a200241016a360200200320026a20004102743a00000f0b200041808001490d032000418080808004490d020c010b200441011037000b0240024002400240200141046a280200200141086a2802002202460d00200128020021030c010b200241016a22032002490d05200241017422042003200420034b1b22044100480d050240024020020d002004102821030c010b200128020020022004102c21030b2003450d0120012003360200200141046a2004360200200141086a28020021020b200141086a2204200241016a360200200320026a41033a000002400240200141046a2802002203200428020022026b4104490d00200128020021030c010b200241046a22042002490d05200341017422022004200220044b1b22024100480d050240024020030d002002102821030c010b200128020020032002102c21030b2003450d0220012003360200200141046a2002360200200141086a28020021020b200141086a200241046a360200200320026a20003600000f0b200441011037000b200241011037000b024002400240200141046a2802002203200141086a28020022026b4104490d00200128020021030c010b200241046a22042002490d03200341017422022004200220044b1b22024100480d030240024020030d002002102821030c010b200128020020032002102c21030b2003450d0120012003360200200141046a2002360200200141086a28020021020b200141086a200241046a360200200320026a20004102744102723600000f0b200241011037000b024002400240200141046a2802002203200141086a28020022026b4102490d00200128020021030c010b200241026a22042002490d02200341017422022004200220044b1b22024100480d020240024020030d002002102821030c010b200128020020032002102c21030b2003450d0120012003360200200141046a2002360200200141086a28020021020b200141086a200241026a360200200320026a20004102744101723b00000f0b200241011037000b1031000bd82504027f027e087f037e230041b00d6b220724000240024002402001280230200128024022082802b801460d002004420020042903082209200841c0006a2903007d220a200a20095622081b3703082008450d0120004188c5c00036020420004101360200200041086a412a3602002000410c6a2006290200370200200041146a200641086a2802003602000c020b200041f3c3c00036020420004101360200200041086a41293602002000410c6a2006290200370200200041146a200641086a2802003602000c010b200741186a41186a200141e8006a290000370300200741186a41106a200141e0006a290000370300200741186a41086a200141d8006a290000370300200720012900503703182006280208210b20062802002108200741b0026a41186a220c4200370300200741b0026a41106a220d4200370300200741b0026a41086a220e4200370300200742003703b0022008200b200741b0026a1000200741d00a6a41186a200c290300370300200741d00a6a41106a200d290300370300200741d00a6a41086a200e290300370300200720072903b0023703d00a0240024002400240024002400240024002400240412010282208450d0020082005290000370000200841186a200541186a290000370000200841106a200541106a290000370000200841086a200541086a2900003700002008412041c000102c2208450d01200820072903d00a370020200841386a200741d00a6a41186a290300370000200841306a200741d00a6a41106a290300370000200841286a200741d00a6a41086a290300370000200841c000418001102c2208450d0220082007290318370040200841d8006a200741186a41186a290300370000200841d0006a200741186a41106a290300370000200841c8006a200741186a41086a290300370000200741b0026a41186a220c4200370300200741b0026a41106a220d4200370300200741b0026a41086a220e4200370300200742003703b002200841e000200741b0026a1000200741386a41186a220f200c290300370300200741386a41106a220c200d290300370300200741386a41086a220d200e290300370300200720072903b0023703382008102a20062902002109200741d8006a41d8006a200d290300370300200741d8006a41e0006a200c290300370300200741c0016a200f29030037030020074194016a410036020020074184016a419cc4c000360200200741f8006a4200370300200741f4006a221041f8b9c00036020020072001360260200741d8006a41286a200141186a2211360200200720072903383703a8012007420837028c012007410036027020074100360264200720012802483602a00120072001290340370398012007200128023041016a360288012001290300210a2007200128024c3602a4012007200a370358200741c8016a41186a200541186a290000370300200741c8016a41106a200541106a290000370300200741c8016a41086a200541086a29000037030020074101360270200720052900003703c8012011200741386a10b601210620072007280270417f6a2208360270024020060d0020080d042007417f36027020074190026a41186a200741386a41186a29030037030020074190026a41106a200741386a41106a29030037030020074190026a41086a200741386a41086a2903003703002007200729033837039002024002402007280274220e41f8b9c000460d002007280278210f0c010b4100210f200741d00a6a410041e0021099051a200741b0026a410041a0081099051a41880b1028220e450d06200e41003b0106200e4100360200200e41086a200741d00a6a41e002109a051a200e41e8026a200741b0026a41a008109a051a200741003602782007200e3602740b024002400340200e41086a2108200e2f0106221241057421064100210c0240024003402006450d0120074190026a20084120109c05220d450d02200641606a2106200c41016a210c200841206a2108200d417f4a0d000b200c417f6a21120b200f450d02200f417f6a210f200e20124102746a41880b6a280200210e0c010b0b200e200c41e0006c6a41e8026a21060c010b200741f0016a41186a20074190026a41186a290300220a370300200741f0016a41106a20074190026a41106a2903002213370300200741f0016a41086a20074190026a41086a2903002214370300200720072903900222153703f001200741ec0a6a2014370200200741d00a6a41246a2013370200200741fc0a6a200a3702002007200741d8006a41246a3602e00a200720123602dc0a200720103602d80a2007200e3602d40a200741003602d00a200720153702e40a200741e4026a4200370200200741003a00ec02200742003703b002200741003a008d03200741f8b9c0003602e002200742003703c802200741d00a6a200741b0026a10b70121060b200741e0016a290300210a20064201370318200641013a003c200641286a427f370300200641206a427f3703002006413d6a20072903c801370000200641d5006a200a370000200641cd006a200741d8016a290300370000200641c5006a200741d0016a2903003700002007200728027041016a360270200741106a20044101200741186a200741386a20022003200741d8006a10b8012007280210220e0d06200741b0026a200520072802a00128020010b901024020072802b0024101470d002009422088a72106200741b8026a280200210520072802b402210e2009a721010c0b0b20074190026a41186a200741b0026a410472220641186a2802002208360200200741d00a6a41106a200641086a290200370300200741d00a6a41186a200641106a290200370300200741f00a6a2008360200200741063602d40a200741b38dc6003602d00a200720062902003703d80a200728029c0121062007200741d8006a3602c8022007290358210a20072802a4012108200741d8026a200741186a41086a290300370300200741e0026a200741186a41106a290300370300200741e8026a200741186a41186a290300370300200720033703b802200720023703b002200720083602cc022007200a3703c002200720072903183703d0022007200b3602f801200720093703f00120074190026a2006200741d00a6a200741b0026a200741f0016a200410ba012007419c026a290200210220074190026a41086a2802002112200728029402210f02402007280290024101470d002002422088a72106200741a4026a280200210b2002a7210120122105200f210e0c0a0b200728027041016a220b41004c0d072007200b360270200728027821040240024003402010280200220541086a210820052f0106220e41057421064100210c0240024003402006450d01200741386a20084120109c05220d450d02200641606a2106200c41016a210c200841206a2108200d417f4a0d000b200c417f6a210e0b2004450d022004417f6a21042005200e4102746a41880b6a21100c010b0b2005200c41e0006c6a220641c5036a310000200641e8026a290300220320035022081ba7450d004200200641f8026a29030020081b21034200200641f0026a29030020081b21090c010b2007200728028001200741386a20072802840128021c110500200741086a2903002103200729030021092007280270210b0b2007200b417f6a3602702009200728029801220629037854200320064180016a29030022095420032009511b450d082002a7210b41c0c4c000210e411e2105200f2101201221060c090b2009422088a721062009a7210141dec4c000210e412a21050c090b412041011037000b41c00041011037000b41800141011037000b41a8b8c0004110200741b0026a41d0b8c0001038000b41880b41081037000b200728021421052009422088a721062009a721010c030b41b8b8c0004118200741b0026a41e0b8c0001038000b20074190026a41086a2208200741186a41086a29030037030020074190026a41106a220c200741186a41106a29030037030020074190026a41186a220d200741186a41186a290300370300200741f0016a41086a2205200741386a41086a290300370300200741f0016a41106a2204200741386a41106a290300370300200741f0016a41186a220e200741386a41186a2903003703002007200729031837039002200720072903383703f00102400240024002402007280294012206200728029001470d00200641016a220b2006490d0320064101742210200b2010200b4b1b2210ad42b0017e2203422088a70d032003a7220b4100480d030240024020060d00200b102821060c010b200728028c01200641b0016c200b102c21060b2006450d0120072010360290012007200636028c0120072802940121060b200728028c01200641b0016c6a220641003a0000200620072f00ed013b0001200641013a00102006410036000c200642013700042006200729039002370011200620072903f001370031200641036a200741ef016a2d00003a0000200641196a2008290300370000200641216a200c290300370000200641296a200d290300370000200641396a2005290300370000200641c1006a2004290300370000200641c9006a200e290300370000200641e0006a200741d7016a290000370000200641d9006a200741c8016a41086a290000370000200620072900c801370051200641e8006a200741b0026a41c800109a051a200720072802940141016a2208360294010240200741d00a6a41186a280200450d00200741e40a6a280200102a20072802940121080b200728029001210e200728028c012105200728027c210b2007280278210d2007280274210602402007280264220c450d00200741e8006a280200450d00200c102a0b0240024020024280808080f01f8350450d002007200b3602b8022007200d3602b402200720063602b0022011200741b0026a10bb012007200e3602b402200720053602b00220072005200841b0016c22086a22043602bc0202400240200141386a280200220c2001413c6a28020022066b200841b0016d220d490d002001280234210c0c010b2006200d6a220e2006490d05200c4101742206200e2006200e4b1b2206ad42b0017e2203422088a70d052003a7220e4100480d0502400240200c0d00200e1028210c0c010b2001280234200c41b0016c200e102c210c0b200c450d042001200c360234200141386a20063602002001413c6a28020021060b200c200641b0016c6a20052008109a051a2001413c6a22062006280200200d6a360200200720043602b802200741b0026a10690c010b02402008450d00200841b0016c210441002108034002400240200520086a220c2d0000220141014b0d000240024020010e020001000b0240200c41086a280200450d00200c41046a280200102a0b200c41106a2d00004105490d02200c41386a280200450d02200c41346a280200102a0c020b200c41286a106a0c010b200c41e8006a280200450d00200c41e4006a280200102a0b2004200841b0016a2208470d000b0b0240200e450d002005102a0b02400240200d0d00200621080c010b200d210c20062108034020082802880b2108200c417f6a220c0d000b0340200620062f01064102746a41880b6a2802002106200d417f6a220d0d000b0b200741cc026a20062f0106360200200741c8026a4100360200200741c4026a20063602002007200b3602d002200741003602c002200742003703b802200720083602b402200741003602b002200741b0026a109b010b20002007290338370004200041003602002000412c6a2002370200200041286a2012360200200041246a200f3602002000411c6a200741d0006a290300370000200041146a200741c8006a2903003700002000410c6a200741c0006a2903003700000c050b200b41081037000b200e41081037000b1031000b200741e80a6a280200450d00200741e40a6a280200102a0b024020072802642208450d00200741e8006a280200450d002008102a0b2006ad2102200728027c21042007280274210602400240200728027822080d002006210c0c010b2008210d2006210c0340200c2802880b210c200d417f6a220d0d000b0340200620062f01064102746a41880b6a28020021062008417f6a22080d000b0b200242208621022001ad2103200741cc026a20062f010636020041002108200741c8026a4100360200200741c4026a2006360200200720043602d002200741003602c002200742003703b8022007200c3602b402200741003602b002200741b0026a109b0102402007280294012206450d00200728028c01210d200641b0016c2101034002400240200d20086a22062d0000220c41014b0d0002400240200c0e020001000b0240200641086a280200450d00200641046a280200102a0b200641106a2d00004105490d02200641386a280200450d02200641346a280200102a0c020b200641286a106a0c010b200641e8006a280200450d00200641e4006a280200102a0b2001200841b0016a2208470d000b0b200220038421020240200728029001450d00200728028c01102a0b2000200e36020420004101360200200041146a200b3602002000410c6a2002370200200041086a20053602000b200741b00d6a24000bb80201097f230041106b220224000240200028020041016a220341004c0d0020002003360200200041046a2104200041086a280200210502400240024003402004280200220641086a210720062f010622084105742104410021090240024003402004450d01200120074120109c05220a450d02200441606a2104200941016a2109200741206a2107200a417f4a0d000b2009417f6a21080b2005450d022005417f6a2105200620084102746a41880b6a21040c010b0b2006200941e0006c6a220441a4036a2d000022074101410220074101461b200441c5036a2d00001b22044102470d010b20002802102001200041146a2802002802181101002104200028020021030c010b200441014621040b20002003417f6a360200200241106a240020040f0b41b8b8c0004118200241086a41e0b8c0001038000b8f1901187f230041d0116b2202240020002802102203200328020041016a360200200028020c21042000280208210520002802042103200241206a41186a22062000412c6a290000370300200241206a41106a2207200041246a290000370300200241206a41086a22082000411c6a29000037030020022000290014370320200241a0026a200141e000109a051a024002400240024020032f01062201410b490d00200241b0036a410041e0021099051a20024198066a410041a0081099051a0240024041880b10282209450d00200941003b010620094100360200200941086a200241b0036a41e002109a052101200941e8026a20024198066a41a008109a052106200220032f00c8013b01ac032002200341ca016a2d00003a00ae03200220032900db01370398032002200341e0016a29000037009d03200341cb016a280000210a200341cf016a280000210b200341d3016a280000210c200341d7016a280000210d20024198066a200341a8076a41e000109a051a2001200341e8016a20032f010641796a2200410574109a052101200620034188086a200041e0006c109a052106200341063b0106200920003b0106200220022f01ac033b019403200220022d00ae033a0096032002200229039803370380032002200229009d0337008503200241b0036a20024198066a41e000109a051a0240024020044107490d00200441057420016a41c07e6a2001200441796a22074105746a2201200041ffff037120076b410574109b051a200141186a200241206a41186a290300370000200141106a200241206a41106a290300370000200141086a200241206a41086a29030037000020012002290320370000200441e0006c20066a220041c07b6a200041e07a6a220e200941066a22002f010020076b41e0006c109b051a200e200241a0026a41e000109a051a0c010b200341086a20044105746a220141206a2001200341066a22002f010020046b410574109b051a200141186a200241206a41186a290300370000200141106a200241206a41106a290300370000200141086a200241206a41086a29030037000020012002290320370000200341e8026a200441e0006c6a220e41e0006a200e20002f010020046b41e0006c109b051a200e200241a0026a41e000109a051a0b20024188026a41026a220420022d0096033a0000200020002f010041016a3b0100200220022f0194033b01880220022002290380033703800120022002290085033700850120024190016a200241b0036a41e000109a051a2002411c6a41026a220f20042d00003a0000200220022f0188023b011c2002200229038001370308200220022900850137000d200241206a20024190016a41e000109a051a20032802002206450d0320032f0104211020024198066a410272211103402002419c026a41026a2212200f2d00003a0000200220022f011c3b019c0220022002290308370388022002200229000d37008d02200241a0026a200241206a41e000109a051a201041ffff0371210702400240024020062f01062203410b490d002011410041b20b1099051a41b80b10282201450d0520014100360200200141046a20024198066a41b40b109a051a200220062f00c8013b01ac032002200641ca016a2d00003a00ae03200220062900db01370398032002200641e0016a29000037009d03200641cb016a2800002113200641cf016a2800002114200641d3016a2800002115200641d7016a280000211620024198066a200641a8076a41e000109a051a200141086a200641e8016a20062f0106220041796a2203410574109a052117200141e8026a20064188086a200341e0006c109a052118200141880b6a200641a40b6a2000417a6a2208410274109a052119200641063b0106200120033b010602402008450d00410021032019210003402000280200220420033b010420042001360200200041046a21002008200341016a2203470d000b0b200241b0036a20024198066a41e000109a051a200220022d00ae0322033a009603200220022f01ac0322003b0194032002200229009d033700850320022002290398033703800320024194066a41026a220820033a0000200220003b01940620022002290380033703800120022002290085033700850120024198066a200241b0036a41e000109a051a201041ffff037122004107490d0120172007417a6a22044105746a2017200741796a22034105746a220020012f010620036b410574109b051a200041186a200229008d023700002000200d36000f2000200c36000b2000200b3600072000200a360003200041026a20122d00003a0000200020022f019c023b00002000200229038802370013200741e0006c20186a220041c07b6a200041e07a6a220020012f010620036b41e0006c109b051a2000200241a0026a41e000109a051a200120012f010641016a22003b01062007410274220a20196a416c6a201920044102746a2210200041ffff0371220720046b410274109b051a2010200936020020072004490d022001200a6a41f00a6a2100034020002802002204200341016a22033b010420042001360200200041046a210020032007490d000c030b0b200641086a2200200741016a22044105746a200020074105746a2200200320076b2201410574109b051a2000200d36000f2000200c36000b2000200b3600072000200a360003200041026a2002419c026a41026a2d00003a0000200020022f019c023b00002000200229038802370013200041186a200229008d023700002006200741e0006c6a220041c8036a200041e8026a2200200141e0006c109b051a2000200241a0026a41e000109a051a2006200341016a22033b01062007410274200641880b6a22006a41086a200020044102746a2200200341ffff037120046b410274109b051a20002009360200201041ffff037120062f010622034f0d07200920043b010420092006360200200420034f0d072003417f6a210120062004417f6a22034102746a41900b6a2100034020002802002204200341026a3b010420042006360200200041046a21002001200341016a2203470d000c080b0b200641086a2203200741016a22044105746a200320074105746a220320062f0106221020076b2219410574109b051a2003200d36000f2003200c36000b2003200b3600072003200a360003200341026a20122d00003a0000200320022f019c023b00002003200229038802370013200341186a200229008d02370000200641e8026a200741e0006c6a220341e0006a2003201941e0006c109b051a2003200241a0026a41e000109a051a2006201041016a22033b010620074102742219200641880b6a22106a41086a201020044102746a2210200341ffff037120046b410274109b051a20102009360200200020062f010622044f0d00200620196a418c0b6a2103034020032802002200200741016a22073b010420002006360200200341046a210320042007470d000b0b20024184026a41026a220320082d00003a0000200220022f0194063b01840220022002290380013703f00120022002290085013700f50120024190016a20024198066a41e000109a051a200f20032d00003a0000200220022f0184023b011c200220022903f001370308200220022900f50137000d200241206a20024190016a41e000109a051a0240200628020022030d002013210a2016210d2015210c2014210b200121090c050b20062f010421102013210a2016210d2015210c2014210b20032106200121090c000b0b41880b41081037000b41b80b41081037000b200320044105746a220041286a200041086a2210200120046b410574109b051a200041206a2006290300370000200041186a2007290300370000200041106a2008290300370000201020022903203700002003200441e0006c6a220041c8036a200041e8026a220e20032f010620046b41e0006c109b051a200e200241a0026a41e000109a051a200320032f010641016a3b01060c010b20024198066a410272410041b20b1099051a41b80b10282203450d0120034100360200200341046a20024198066a41b40b109a051a2003200528020022003602880b200520033602002005200528020441016a360204200041003b010420002003360200200320032f010622044105746a220041086a20022f011c3b00002000410a6a2002411c6a41026a2d00003a0000200041176a200d360000200041136a200c3600002000410f6a200b3600002000410b6a200a3600002000411b6a2002290308370000200041206a200229000d3700002003200441e0006c6a41e8026a200241206a41e000109a051a200341880b6a200441016a22004102746a2009360200200320003b0106200920003b0104200920033602000b200241d0116a2400200e0f0b41b80b41081037000b9f19020a7f087e230041800c6b220824000240024002400240024002400240024002400240200728021841016a220941004c0d0020072009360218200741206a280200210a2007411c6a220b210c024002400340200c280200220d41086a210e200d2f0106220f410574210c41002110024002400340200c450d012004200e4120109c052211450d02200c41606a210c201041016a2110200e41206a210e2011417f4a0d000b2010417f6a210f0b200a450d02200a417f6a210a200d200f4102746a41880b6a210c0c010b0b200d201041e0006c6a220c41c5036a310000200c41e8026a2903002212201250220e1ba7450d004200200c41f8026a290300200e1b21134200200c41f0026a290300200e1b21140c010b200841286a200741286a28020020042007412c6a28020028021c110500200841306a290300211320072802182109200829032821140b20072009417f6a360218200141186a29030021122007280240210c20012903102115024002400240024041004101410220142013842216501b20021b0e03010200010b200c41a8016a210c0c020b200c4188016a210c0c010b200c4198016a210c0b20152012844200510d01200841186a200c290300200c41086a2903002015201210a00520014200200129030822122008290318427f200841186a41086a290300501b7d22152015201256220c1b3703080240200c450d0041b2c5c000210c4122210e0c0a0b200728021841016a220141004c0d02200720013602182007280220210a200b210c024002400340200c280200220d41086a210e200d2f0106220f410574210c41002110024002400340200c450d012003200e4120109c052211450d02200c41606a210c201041016a2110200e41206a210e2011417f4a0d000b2010417f6a210f0b200a450d02200a417f6a210a200d200f4102746a41880b6a210c0c010b0b200d201041e0006c6a220c41c5036a310000200c41e8026a2903002212201250220e1ba7450d004200200c41f8026a290300200e1b21124200200c41f0026a290300200e1b21150c010b200841086a200741286a28020020032007412c6a28020028021c110500200841106a290300211220072802182101200829030821150b20072001417f6a3602180240201520057d2217201556201220067d2015200554ad7d221520125620152012511b4101470d00419893c100210c411d210e0c0a0b024020164200520d002007280240220c290378200556200c4180016a290300221220065620122006511b450d0041e293c100210c411f210e0c0a0b2008200341022017201510bc0102402008280200220c450d002008280204210e0c0a0b0240201420057c2216201454220c201320067c200cad7c221220135420122013511b450d0041b593c100210c412d210e0c0a0b4100210c024020032004470d000c0a0b0240200320044120109c050d000c0a0b20072802180d032007417f360218200841e0006a41186a200341186a290000370300200841e0006a41106a200341106a290000370300200841e0006a41086a200341086a2900003703002008200329000037036002400240200728021c221141f8b9c000460d002007280220210a0c010b4100210a200841a0096a410041e0021099051a20084180016a410041a0081099051a41880b10282211450d05201141003b010620114100360200201141086a200841a0096a41e002109a051a201141e8026a20084180016a41a008109a051a200741003602202007201136021c0b02400240034020112f0106220f410574210d4100210c4100210e02400340200d200c460d01200841e0006a2011200c6a41086a4120109c052210450d03200c41206a210c200e41016a210e2010417f4a0d000b200e417f6a210f0b0240200a450d00200a417f6a210a2011200f4102746a41880b6a28020021110c010b0b200841c0006a41186a200841e0006a41186a2903002213370300200841c0006a41106a200841e0006a41106a2903002214370300200841c0006a41086a200841e0006a41086a2903002218370300200820082903602219370340200841bc096a2018370200200841a0096a41246a2014370200200841cc096a20133702002008200741246a22013602b0092008200f3602ac092008200b3602a809200820113602a409200841003602a009200820193702b409200841b4016a4200370200200841bc016a41003a0000200841f8b9c0003602b00120084200370398012008420037038001200841003a00dd01200841a0096a20084180016a10b701210c0c010b20084198016a420037030020084194016a41f8b9c000360200200841003602a00120084100360290012008420037038801200841f8b9c000360284012008410036028001200741246a21012011200e41e0006c6a41e8026a210c20084180016a1095010b200c41106a2015370300200c2017370308200c420137030020072007280218220c41016a220e360218200e200c4f0d052007417f360218200841e0006a41186a200441186a290000370300200841e0006a41106a200441106a290000370300200841e0006a41086a200441086a2900003703002008200429000037036002400240200728021c221141f8b9c000460d002007280220210a0c010b4100210a200841a0096a410041e0021099051a20084180016a410041a0081099051a41880b10282211450d07201141003b010620114100360200201141086a200841a0096a41e002109a051a201141e8026a20084180016a41a008109a051a200741003602202007201136021c0b02400240034020112f0106220f410574210d4100210c4100210e02400340200d200c460d01200841e0006a2011200c6a41086a4120109c052210450d03200c41206a210c200e41016a210e2010417f4a0d000b200e417f6a210f0b0240200a450d00200a417f6a210a2011200f4102746a41880b6a28020021110c010b0b200841c0006a41186a200841e0006a41186a2903002215370300200841c0006a41106a200841e0006a41106a2903002213370300200841c0006a41086a200841e0006a41086a2903002214370300200820082903602217370340200841bc096a2014370200200841c4096a2013370200200841cc096a2015370200200820013602b0092008200f3602ac092008200b3602a809200820113602a409200841003602a009200820173702b409200841b4016a4200370200200841bc016a41003a0000200841f8b9c0003602b00120084200370398012008420037038001200841003a00dd01200841a0096a20084180016a10b701210c0c010b20084198016a420037030020084194016a41f8b9c000360200200841003602a00120084100360290012008420037038801200841f8b9c0003602840120084100360280012011200e41e0006c6a41e8026a210c20084180016a1095010b200c41106a2012370300200c2016370308200c42013703002007200728021841016a360218200841a0096a41086a2210200341086a290000370300200841a0096a41106a2211200341106a290000370300200841a0096a41186a220d200341186a290000370300200841e0006a41086a220a200441086a290000370300200841e0006a41106a220f200441106a290000370300200841e0006a41186a2201200441186a290000370300200820032900003703a0092008200429000037036002402007413c6a280200220e200741386a280200470d00200e41016a220c200e490d09200e4101742204200c2004200c4b1b2203ad42b0017e2212422088a70d092012a722044100480d0902400240200e0d0020041028210c0c010b2007280234200e41b0016c2004102c210c0b200c450d082007200c360234200741386a2003360200200728023c210e0b4100210c2007280234200e41b0016c6a220e41003a0000200e20082f003d3b0001200e4200370008200e4101360004200e20082903a009370011200e2008290360370031200e41036a2008413f6a2d00003a0000200e41106a41003a0000200e41196a2010290300370000200e41216a2011290300370000200e41296a200d290300370000200e41396a200a290300370000200e41c1006a200f290300370000200e41c9006a2001290300370000200e2005370358200e41e0006a2006370300200e41d4006a200841c0006a41036a280000360000200e2008280040360051200e41e8006a20084180016a41c800109a051a2007200728023c41016a36023c0c090b41b8b8c000411820084180016a41e0b8c0001038000b419cb7c0001032000b41b8b8c000411820084180016a41e0b8c0001038000b41a8b8c000411020084180016a41d0b8c0001038000b41880b41081037000b41a8b8c000411020084180016a41d0b8c0001038000b41880b41081037000b200441081037000b1031000b2000200e3602042000200c360200200841800c6a24000bb011030b7f017e047f230041b0016b220324000240024002400240024002400240024002400240411410282204450d00200441002900ddd843370000200441106a41002800edd843360000200441086a41002900e5d84337000020034294808080c00237023c200320043602382003200341386a36028001200120034180016a10c801200328023821042003280240210520034180016a41186a2206420037030020034180016a41106a2207420037030020034180016a41086a2208420037030020034200370380012004200520034180016a1000200341d8006a41186a2006290300370300200341d8006a41106a2007290300370300200341d8006a41086a200829030037030020032003290380013703580240200328023c450d002003280238102a0b2003410036028001200341d8006a412020034180016a100621062003280280012209417f460d032006450d0320032009360284012003200636028001200341286a20034180016a106c20032802280d02200328022c2105200341206a20034180016a106c20032802200d0220032802242108200341186a20034180016a106c20032802180d022003280284012204450d02200328021c210a20032004417f6a360284012003200328028001220441016a3602800120042d0000220441014b0d024100210b0240024020040e020100010b4101210b0b200341106a20034180016a106c20032802100d02200328028401220c20032802142204490d022004417f4c0d050240024020040d00410121070c010b2004102e2207450d022007200328028001220d2004109a051a2003200c20046b360284012003200d20046a360280010b2007450d02200341a0016a41026a220c200341386a41026a220d2d00003a0000200320032f00383b01a00102402009450d002006102a0b200d200c2d000022063a0000200341346a41026a20063a0000200320032f01a00122063b0138200320063b0134410021060c040b411441011037000b200441011037000b41c4d1c3004133200341386a419cd9c3001038000b4101210641d2bfc2002105411121084102210b0b200341306a41026a2209200341346a41026a220c2d00003a0000200320032f01343b013002402006450d002000200536020420004101360200200041086a20083602000c050b200c20092d00003a0000200320032f01303b013402400240200228025820054b0d002004210620042102200721090c010b411510282205450d02200541002900c8d8433700002005410d6a41002900d5d843370000200541086a41002900d0d84337000020034295808080d00237023c200320053602382003200341386a36028001200120034180016a10c801200328023821052003280240210620034180016a41186a2208420037030020034180016a41106a2209420037030020034180016a41086a220b420037030020034200370380012005200620034180016a1000200341d8006a41186a2008290300370300200341d8006a41106a2009290300370300200341d8006a41086a200b29030037030020032003290380013703580240200328023c450d002003280238102a0b2003410036028001200341d8006a412020034180016a100621060240024002402003280280012208417f460d002006450d0020032008360284012003200636028001200341086a20034180016a106c02400240024020032802080d002003280284012209200328020c2205490d002005417f4c0d070240024020050d004101210c0c010b2005102e220c450d02200c200328028001220b2005109a051a2003200920056b360284012003200b20056a360280010b200c0d020b41c4d1c3004133200341386a419cd9c3001038000b200541011037000b2005ad220e422086200e84210e02402008450d002006102a0b20034180016a200c200e422088a7200210f802200ea7210d20034180016a41086a280200210820032802840121052003280280014101470d022000200536020420004101360200200041086a2008360200200d450d01200c102a0c010b200041e3bfc20036020420004101360200200041086a411a3602000b2004450d062007102a0c060b200341d8006a41026a220f2003419f016a2d00003a0000200320032f009d013b01582003419c016a2d0000210b20034198016a280200210620034194016a280200210220034190016a28020021092003418c016a280200210a02402004450d002007102a0b200341346a41026a200f2d00003a0000200320032f01583b01342006417f4c0d010240024020060d0041002107410121040c010b20062107200610282204450d040b200420092006109a05210f200341386a41146a2006360200200341386a41106a20073602002003200a3602402003200836023c200320053602382003200f3602442003200b41ff01714101463a0050411410282204450d04200441002900ddd843370000200441106a41002800edd843360000200441086a41002900e5d84337000020034294808080c0023702a401200320043602a0012003200341a0016a36028001200120034180016a10c80120032802a001210420032802a801210120034180016a41186a2210420037030020034180016a41106a2211420037030020034180016a41086a2212420037030020034200370380012004200120034180016a1000200341d8006a41186a2010290300370300200341d8006a41106a2011290300370300200341d8006a41086a20122903003703002003200329038001370358024020032802a401450d0020032802a001102a0b20034120360284012003200341d8006a36028001200341386a20034180016a10f90202402007450d00200f102a0b200d450d00200c102a0b20002005360204200020032f01343b001d200041003602002000411c6a200b3a0000200041186a2006360200200041146a2002360200200041106a20093602002000410c6a200a360200200041086a20083602002000411f6a200341366a2d00003a00000c040b1036000b411541011037000b200641011037000b411441011037000b200341b0016a24000b821d02097f017e230041e0006b22062400024002402002410c6a280200200241106a280200100f2207417f460d00410c102822080d01410c41041037000b10fc02000b200820073602082008428180808010370200200641186a420037030020064280808080c0003703102006420437030802400240024002400240024002400240024002400240024002400240024002402008280200220741016a220941014d0d00200820093602002007417e460d002008200741026a3602000240200628021c22072006280218470d00200741016a22092007490d0b2007410174220a2009200a20094b1b220941ffffffff03712009470d0b2009410274220b4100480d0b0240024020070d00200b1028210a0c010b20062802142007410274200b102c210a0b200a450d02200620093602182006200a3602140b200628021420074102746a20083602002006200628021c41016a36021c2008280208210b410310282209450d02200941026a41002d00fae2453a0000200941002f00f8e2453b000041061028220a450d03200a41046a41002f00cf8f443b0000200a41002800cb8f44360000024020062802102207200628020c470d00200741016a220c2007490d0b2007410174220d200c200d200c4b1b220c41ffffff3f71200c470d0b200c410574220e4100480d0b0240024020070d00200e1028210d0c010b20062802082007410574200e102c210d0b200d450d052006200c36020c2006200d3602080b200628020820074105746a220741013602182007200a36020c2007428380808030370204200720093602002007411c6a200b360200200741106a4286808080e0003702002006200628021041016a36021020082008280200417f6a2207360200024020070d002008280208101020082008280204417f6a220736020420070d002008102a0b200641086a41f8e2c500410341effec5004103410b10fe02200641086a41f8e2c500410341f2fec500410f410c10fe02200641086a41f8e2c50041034181ffc500410f410d10fe02200641086a41f8e2c50041034190ffc5004108410e10fe02200641086a41f8e2c50041034198ffc500410f410f10fe02200641086a41f8e2c500410341a7ffc500410a411010fe02200641086a41f8e2c500410341b1ffc500410a411110fe02200641086a41f8e2c500410341bbffc500410b411210fe02200641086a41f8e2c500410341c6ffc500410d411310fe02200641086a41f8e2c500410341d3ffc500410c411410fe02200641086a41f8e2c500410341dfffc500410b411510fe02200641086a41f8e2c500410341eaffc5004115411610fe02200641086a41f8e2c500410341ffffc500410a411710fe02200641086a41f8e2c5004103418980c6004107411810fe02200641086a41f8e2c5004103419080c6004113411910fe02200641086a41f8e2c500410341a380c6004111411a10fe02200641086a41f8e2c500410341b480c600410e411b10fe02200641086a41f8e2c500410341c280c6004110411c10fe02200641086a41f8e2c500410341d280c6004110411d10fe02200641086a41f8e2c500410341e280c6004111411e10fe02200641086a41f8e2c500410341f380c6004111411f10fe02200641086a41f8e2c5004103418481c6004116412010fe02200641086a41f8e2c5004103419a81c6004112412110fe02200641086a41f8e2c500410341ac81c600410b412210fe02200641086a41f8e2c500410341b781c6004110412310fe02200641206a410c6a200441086a280200360200200620033602204100210d2006410036023c20062005360238200620083602342006200429020037022420062001280200360230200241146a280200210b2002411c6a280200210c200628020821072006280210210820064100360258200642013703502008200641d0006a10b40102402008450d00200720084105746a2105034020072802002104200741086a2802002208200641d0006a10b401024002402006280254220a200628025822096b2008490d002006280250210a0c010b200920086a22012009490d0d200a41017422032001200320014b1b22014100480d0d02400240200a0d0020011028210a0c010b2006280250200a2001102c210a0b200a450d08200620013602542006200a3602500b2006200920086a360258200a20096a20042008109a051a2007410c6a2802002103200741146a280200220a200641d0006a10b4010240024020062802542209200628025822046b200a490d00200628025021080c010b2004200a6a22082004490d0d200941017422012008200120084b1b22014100480d0d0240024020090d002001102821080c010b200628025020092001102c21080b2008450d092006200136025420062008360250200121090b20062004200a6a2201360258200820046a2003200a109a051a02400240200741186a2802004101460d000240024020092001460d002009210a0c010b200941016a220a2009490d0f20094101742204200a2004200a4b1b220a4100480d0f0240024020090d00200a102821080c010b20082009200a102c21080b2008450d0c2006200a360254200620083602500b2006200141016a2209360258200820016a41013a000020062007411c6a2802002204360248200641c8006a21010c010b0240024020092001460d002009210a0c010b200941016a220a2009490d0e20094101742204200a2004200a4b1b220a4100480d0e0240024020090d00200a102821080c010b20082009200a102c21080b2008450d0c2006200a360254200620083602500b2006200141016a2209360258200820016a41023a000020062007411c6a2802002204360248200641c8006a21010b0240200a20096b41034b0d00200941046a22042009490d0d200a41017422032004200320044b1b22044100480d0d02400240200a0d002004102821080c010b2008200a2004102c21080b2008450d0c2006200436025420062008360250200128020021040b2006200941046a360258200820096a2004360000200741206a22072005470d000b0b2006280254210302404124200b200c2006280250220e2006280258200641206a1011220b41036a220841024b0d000240024020080e03000201000b4102210d0b41012104024020030d000c110b200e102a0c100b200628021c220541ffffffff03712005470d0b20054102742207417f4c0d0b200628021421080240024020070d004104210c0c010b20071028220c450d0d0b0240024020050d004100210a0c010b200541027421044100210a200c210703402008280200220928020041016a220141014d0d022009200136020020072009360200200a41016a210a200741046a2107200841046a21082004417c6a22040d000b0b02402003450d00200e102a0b200228020421092002280200210420064100360258200642013703504100200641d0006a10b401200628025821012006280254210220062802502107410a102e2208450d0d0240024002400240200b20042009200720012008410a200641206a101241036a220941034b0d004101210420090e0402000001020b41a8c7c2001032000b2006410936024c410121042006200841016a36024820082d0000220941014b0d01410421010240024020090e020100010b200641d0006a200641c8006a109803200628025022014104460d02200628025421030b410021040b2008102a2002450d0f2007102a0c0f0b2008102a024020020d000c0f0b2007102a0c0e0b00000b200b41041037000b410341011037000b410641011037000b200e41041037000b200141011037000b200141011037000b200a41011037000b200a41011037000b200441011037000b1031000b1036000b200741041037000b410a41011037000b200b10130240200a450d00200a4102742107200c21080340200828020022092009280200417f6a3602000240200828020022092802000d0020092802081010200828020022092009280204417f6a360204200828020022092802040d002009102a0b200841046a21082007417c6a22070d000b0b4102210d2005450d00200c102a0b200641206a41086a28020021072006280234210820062802242109024002400240024002400240024002400240200628023c220a0d002006412c6a290200210f20040d04200141044b0d0320010e050203030301020b2000200a36020420004100360200200041106a41003a0000200041086a200641c0006a29030037020002402007450d002009102a0b20082008280200417f6a220736020020070d072008280208101020082008280204417f6a22073602042007450d060c070b2000200936020441002109200041106a41003a00002000410c6a4100360200200041086a20073602000c040b20002009360204200041106a20033a00002000410c6a200f3e0200200041086a2007360200410021090c030b200041aa9cc400360204200041146a200f3e0200200041106a20073602002000410c6a2009360200200041086a41113602000c010b0240200d450d00200041cb9cc400360204200041146a200f3e0200200041106a20073602002000410c6a2009360200200041086a41103602000c010b200041bb9cc400360204200041146a200f3e0200200041106a20073602002000410c6a2009360200200041086a41103602000b410121090b2000200936020020082008280200417f6a220736020020070d012008280208101020082008280204417f6a220736020420070d010b2008102a0b024020062802102207450d00200628020821082007410574210703400240200841046a280200450d002008280200102a0b0240200841106a280200450d002008410c6a280200102a0b200841206a2108200741606a22070d000b0b0240200628020c450d002006280208102a0b0240200628021c2207450d0020062802142108200741027421070340200828020022092009280200417f6a3602000240200828020022092802000d0020092802081010200828020022092009280204417f6a360204200828020022092802040d002009102a0b200841046a21082007417c6a22070d000b0b02402006280218450d002006280214102a0b200641e0006a24000b8a1409057f017e0c7f047e037f017e037f047e097f230041f00c6b22022400024020002802000d002000417f360200200128020821032001280200210402400240200128020422050d00200421010c010b2005210620042101034020012802880b21012006417f6a22060d000b0340200420042f01064102746a41880b6a28020021042005417f6a22050d000b0b2002411c6a20042f0106360200200241186a4100360200200241146a20043602002002200336022020024100360210200242003703082002200136020420024100360200200241f0016a2002109301024020022903900222074202510d002000410c6a2108200041046a2109200241900a6a41146a210a200241900a6a41206a210b200241f0016a4104722103200241f0016a413d6a210c200241cd026a210d200241b8026a210e200241f0016a41306a210f200241f0016a41286a21100340200241c8006a41086a2204200241f0016a41086a2211290300370300200241c8006a41106a2201200241f0016a41106a2212290300370300200241c8006a41186a2205200241f0016a41186a2213290300370300200220022903f001370348200e2903002114200f290300211520022903b0022116200229039802211720022f01ee02211820022d00ed02211920022d00cc02211a20022903a802211b20022802c002211c20022802c402211d20022802c802211e200241286a41186a200d41186a290000221f370300200241286a41106a200d41106a2900002220370300200241286a41086a200d41086a29000022213703002002200d2900002222370328200241e8006a41186a2223201f370300200241e8006a41106a22242020370300200241e8006a41086a222520213703002002202237036820024188016a41186a2226200529030037030020024188016a41106a2227200129030037030020024188016a41086a222820042903003703002002200229034837038801024002400240024002402009280200222941f8b9c000460d002000280208212a0c010b200241900a6a410041e0021099051a200241f0016a410041a0081099051a41880b10282229450d014100212a202941003b010620294100360200202941086a200241900a6a41e002109a051a202941e8026a200241f0016a41a008109a051a20004100360208200020293602040b0340202941086a210120292f0106222b410574210441002105024003402004450d0120024188016a20014120109c052206450d04200441606a2104200541016a2105200141206a21012006417f4a0d000b2005417f6a212b0b0240202a450d00202a417f6a212a2029202b4102746a41880b6a28020021290c010b0b200241c0016a41186a2026290300221f370300200241c0016a41106a20272903002220370300200241c0016a41086a20282903002221370300200220022903880122223703c001200a2022370200200a41086a2021370200200a41106a2020370200200a41186a201f370200200220083602a00a2002202b36029c0a200220093602980a200220293602940a200241003602900a20102014370300201220153703002002201637039002200220173703f8012002201a3a00ac022002201e3602a8022002201d3602a4022002201c3602a0022002201b37038802200220073703f001200c2002290368370000200c41086a2025290300370000200c41106a2024290300370000200c41186a2023290300370000200220183b01ce02200220193a00cd02200241900a6a200241f0016a10b7011a0c020b41880b41081037000b202941e8026a200541e0006c6a2129024020194101710d0020292029290300200720075022041b37030020292029290308201720041b370308202941106a22012001290300201520041b370300200241900a6a41186a22062023290300370300200241900a6a41106a222a2024290300370300200241900a6a41086a222b2025290300370300200220022903683703900a20292d003c21012013202941d5006a22052900003703002012202941cd006a22192900003703002011202941c5006a222329000037030020022029413d6a22242900003703f0012028200241900a6a200241f0016a201a41ff0171410146221a1b220441086a2900003703002027200441106a2900003703002026200441186a2900003703002002200429000037038801202941012001201a1b3a003c2024200229038801370000202320282903003700002019202729030037000020052026290300370000202920162029290320201ba722041b370320202941286a22012014200129030020041b3703002029201b202929031820041b37031802400240201d0d00201c21040c010b201d2101201c2104034020042802ec0321042001417f6a22010d000b0340201c201c2f01064102746a41ec036a280200211c201d417f6a221d0d000b0b201c2f010621012002201e3602a801200220013602a401200241003602a0012002201c36029c01200241003602980120024200370390012002200436028c012002410036028801200241f0016a20024188016a109901024020022802f0014101470d00202941306a211c0340200241900a6a41286a200341286a280200360200200b200341206a2902003703002006200341186a2204290200370300202a200341106a2201290200370300202b200341086a2205290200370300200220032902003703900a200241c0016a41186a2004290000370300200241c0016a41106a2001290000370300200241c0016a41086a2005290000370300200220032900003703c001200241e0016a41086a200b41086a2802003602002002200b2902003703e001200241b0016a201c200241c0016a200241e0016a10bd01024020022802b001450d0020022802b4012204450d0020022802b801450d002004102a0b200241f0016a20024188016a10990120022802f0014101460d000b0b20024188016a1095010c010b202941386a212b202941306a212a202928023821262029280230210402400240202941346a28020022050d00200421010c010b2005210620042101034020012802ec0321012006417f6a22060d000b0340200420042f01064102746a41ec036a28020021042005417f6a22050d000b0b200220263602900220024100360288022002410036028002200242003703f801200220013602f401200241003602f0012002200436028402200220042f010636028c02200241f0016a109501202941286a201437030020292016370320202941106a2015370300202920173703082029201b37031820292007370300202a201d360204202a201c360200202b201e3602002029201a3a003c2029413d6a2002290368370000202941c5006a2025290300370000202941cd006a2024290300370000202941d5006a2023290300370000202920183b015e202920193a005d0b200241f0016a200210930120022903900222074202520d000b0b2002109b012000200028020041016a360200200241f00c6a24000f0b41a8b8c0004110200241f0016a41d0b8c0001038000bf00203027f017e037f230041306b22052400024002400240200241ff0171417e6a220641024b0d000240024020060e03000201000b200520011099022005290300200358200541086a290300220720045820072004511b0d010c020b200541106a20011099022005290310200356200541186a290300220720045620072004511b0d010b200541206a2001109a020240200528022822010d0002402005280224450d002005280220102a0b410021010c020b200141057421061098012108200528022421092005280220220a2101024002400240034002402008200141106a2802004f0d002001290300200358200141086a290300220720045820072004511b0d002001411c6a2d000020027141ff0171200241ff0171460d020b200141206a2101200641606a22060d000b4100210120090d010c020b4184dfc00021012009450d010b200a102a0b413121060c010b41dedec0002101412621060b2000200636020420002001360200200541306a24000bc31e03087f037e127f23004180076b22042400200441e0006a41186a200241186a290000370300200441e0006a41106a200241106a290000370300200441e0006a41086a200241086a290000370300200420022900003703600240024002400240024002400240024002402001280200220541f8b9c000460d00200128020421060c010b41002106200441e8026a410041e0021099051a200441c0016a41004184011099051a41ec0310282205450d01200541003b010620054100360200200541086a200441e8026a41e002109a051a200541e8026a200441c0016a418401109a051a20014100360204200120053602000b02400340200541086a2107200541066a210820052f0106220941057421024100210a0240024003402002450d01200441e0006a20074120109c05220b450d02200241606a2102200a41016a210a200741206a2107200b417f4a0d000b200a417f6a21090b2006450d022006417f6a2106200520094102746a41ec036a28020021050c010b0b200441e8026a41086a22022005200a410c6c6a220741f0026a220a2802003602002004200741e8026a22072902003703e80220072003290200370200200a200341086a280200360200200441c0016a41086a20022802002202360200200420042903e802220c3703c0012000410c6a20023602002000200c370204200041013602000c060b200441086a41186a220b200441e0006a41186a2202290300370300200441086a41106a200441e0006a41106a2207290300220c370300200441086a41086a200441e0006a41086a220a290300220d37030020042004290360220e3703082001200128020841016a3602082007200c370300200a200d3703002002200b2903003703002004200e370360200441d8026a41086a2206200341086a280200360200200420032902003703d802024020082f01002203410b490d00200441e8026a410041e0021099051a200441c0016a41004184011099051a41ec031028220f450d02200f41003b0106200f4100360200200f41086a200441e8026a41e002109a052107200f41e8026a200441c0016a418401109a05210a200441e8026a41086a220b200541b8036a280200360200200420052900db013703a8012004200541e0016a2900003700ad01200420052902b0033703e802200420052f00c8013b01bc012004200541ca016a2d00003a00be01200541cb016a2800002110200541cf016a2800002111200541d3016a2800002112200541d7016a28000021132007200541e8016a20052f010641796a2202410574109a052107200a200541bc036a2002410c6c109a05210a200541063b0106200f20023b0106200420042f01bc013b01a401200420042d00be013a00a601200420042903a8013703c001200420042900ad013700c501200441286a41086a200b280200360200200420042903e8023703280240024020094107490d00200941057420076a41c07e6a2007200941796a220b4105746a2207200241ffff0371200b6b410574109b051a200741186a200441e0006a41186a290300370000200741106a200441e0006a41106a290300370000200741086a200441e0006a41086a290300370000200720042903603700002009410c6c200a6a220241b87f6a200241ac7f6a2202200f41066a22082f0100200b6b410c6c109b051a200241086a200441d8026a41086a280200360200200220042903d8023702000c010b200541086a20094105746a220241206a200220082f010020096b410574109b051a200241186a200441e0006a41186a290300370000200241106a200441e0006a41106a290300370000200241086a200441e0006a41086a29030037000020022004290360370000200541e8026a2009410c6c6a2202410c6a200220082f010020096b410c6c109b051a200241086a200441d8026a41086a280200360200200220042903d8023702000b200820082f010041016a3b010020044198016a41026a220220042d00a6013a0000200441c8026a41086a2214200441286a41086a280200360200200420042f01a4013b019801200420042903c001370350200420042900c501370055200420042903283703c8022004413c6a41026a221520022d00003a0000200420042f0198013b013c2004200429005537002d20042004290350370328200441c0006a41086a22162014280200360200200420042903c80237034020052802002206450d0420052f01042103200441e8026a4102722117034020044194016a41026a221820152d00003a0000200420042f013c3b019401200420042903283703602004200429002d37006520044198016a41086a221920162802003602002004200429034037039801200341ffff0371210502400240024020062f01062202410b490d00201741004196041099051a419c041028220b450d07200b4100360200200b41046a200441e8026a419804109a051a200420062f00c8013b01bc012004200641ca016a2d00003a00be012004200641db016a2900003703a8012004200641e0016a2900003700ad01200641cb016a280000211a200641cf016a280000211b200641d3016a280000211c200641d7016a280000211d200441e8026a41086a221e200641b8036a2802003602002004200641b0036a2902003703e802200b41086a200641e8016a20062f0106220741796a2202410574109a05211f200b41e8026a200641bc036a2002410c6c109a052120200b41ec036a20064188046a2007417a6a2209410274109a052108200641063b0106200b20023b010602402009450d00410021022008210703402007280200220a20023b0104200a200b360200200741046a21072009200241016a2202470d000b0b200441d8026a41086a2202201e280200360200200420042d00be0122073a00a601200420042f01bc01220a3b01a401200420042903a8013703c001200420042900ad013700c501200420042903e8023703d802200441c4026a41026a220920073a00002004200a3b01c402200420042903c0013703e802200420042900c5013700ed0220142002280200360200200420042903d8023703c802200341ffff037122074107490d01201f2005417a6a220a4105746a201f200541796a22024105746a2207200b2f010620026b410574109b051a200741186a20042900653700002007201336000f2007201236000b2007201136000720072010360003200741026a20182d00003a0000200720042f0194013b0000200720042903603700132005410c6c20206a220741b87f6a200741ac7f6a2207200b2f0106220320026b410c6c109b051a200741086a20192802003602002007200429039801370200200b200341016a22073b01062005410274221020086a416c6a2008200a4102746a2203200741ffff03712205200a6b410274109b051a2003200f3602002005200a490d02200b20106a41d4036a210703402007280200220a200241016a22023b0104200a200b360200200741046a210720022005490d000c030b0b200641086a2207200541016a220a4105746a200720054105746a2207200220056b410574109b051a200741186a20042900653700002007201336000f2007201236000b2007201136000720072010360003200741026a20044194016a41026a2d00003a0000200720042f0194013b00002007200429036037001320062005410c6c6a220241f4026a200241e8026a220720062f0106220b20056b410c6c109b051a200241f0026a20044198016a41086a28020036020020072004290398013702002006200b41016a22023b01062005410274200641ec036a22076a41086a2007200a4102746a2207200241ffff0371220b200a6b410274109b051a2007200f360200200341ffff0371200b4f0d082006200a417f6a22024102746a41f0036a210703402007280200220a200241016a22023b0104200a2006360200200741046a21072002200b490d000c090b0b200641086a2202200541016a22034105746a200220054105746a220220062f010620056b410574109b051a200241186a20042900653700002002201336000f2002201236000b2002201136000720022010360003200241026a20182d00003a0000200220042f0194013b000020022004290360370013200641e8026a2005410c6c6a2202410c6a200220062f0106220a20056b410c6c109b051a200241086a201928020036020020022004290398013702002006200a41016a22023b010620054102742210200641ec036a220a6a41086a200a20034102746a2208200241ffff0371220a20036b410274109b051a2008200f3602002007200a4f0d00200620106a41f0036a2102034020022802002207200541016a22053b010420072006360200200241046a2102200a2005470d000b0b20044190016a41026a220220092d00003a000020044180016a41086a22072014280200360200200420042f01c402220a3b019001200420042903e802370350200420042900ed02370055200420042903c80237038001201520022d00003a00002004200a3b013c2004200429005537002d200420042903503703282016200728020036020020042004290380013703400240200628020022020d00201a2110201d2113201c2112201b2111200b210f0c060b20062f01042103201a2110201d2113201c2112201b211120022106200b210f0c000b0b200520094105746a220b41286a200b41086a2201200320096b410574109b051a200b41206a2002290300370000200b41186a2007290300370000200b41106a200a2903003700002001200429036037000020052009410c6c6a220241f4026a200241e8026a220720052f010620096b410c6c109b051a200241f0026a2006280200360200200720042903d802370200200520052f010641016a3b01060c040b41ec0341041037000b41ec0341041037000b419c0441041037000b200441e8026a41027241004196041099051a419c0410282202450d0220024100360200200241046a200441e8026a419804109a051a2002200128020022073602ec03200120023602002001200128020441016a360204200741003b010420072002360200200220022f0106220a4105746a220741086a20042f013c3b00002007410a6a2004413c6a41026a2d00003a0000200741176a2013360000200741136a20123600002007410f6a20113600002007410b6a20103600002007411b6a2004290328370000200741206a200429002d3700002002200a410c6c6a220741f0026a200441c0006a41086a280200360200200741e8026a2004290340370200200241ec036a200a41016a22074102746a200f360200200220073b0106200f20073b0104200f20023602000b200041003602000b20044180076a24000f0b419c0441041037000bc50101057f230041306b220124002000410c6a28020021022000280204210302400240200041086a28020022040d00200321000c010b2004210520032100034020002802880b21002005417f6a22050d000b0340200320032f01064102746a41880b6a28020021032004417f6a22040d000b0b200141246a20032f0106360200200141206a41003602002001411c6a20033602002001200236022820014100360218200142003703102001200036020c20014100360208200141086a109b01200141306a24000bcb0401097f230041c0006b220324000240200128020041016a220441004c0d0020012004360200200141046a2105200141086a280200210602400240024003402005280200220741086a210820072f0106220941057421054100210a0240024003402005450d01200220084120109c05220b450d02200541606a2105200a41016a210a200841206a2108200b417f4a0d000b200a417f6a21090b2006450d022006417f6a2106200720094102746a41880b6a21050c010b0b2007200a41e0006c6a220841e8026a210502400240200841c5036a2d00000d00200341206a41086a220a200541c5006a290000370300200341206a41106a220b200541cd006a290000370300200341206a41186a2207200541d5006a29000037030020032005413d6a2900003703204102210820052d003c4101470d01200341186a2007290300370300200341106a200b290300370300200341086a200a29030037030020032003290320370300410121080c010b200341086a200541c5006a290000370300200341106a200541cd006a290000370300200341186a200541d5006a29000037030020032005413d6a29000037030020052d003c21080b200841ff01714102470d010b200020012802102002200141146a280200280210110500200128020021040c010b200020083a000020002003290300370001200041096a200341086a290300370000200041116a200341106a290300370000200041196a200341186a2903003700000b20012004417f6a360200200341c0006a24000f0b41b8b8c0004118200341206a41e0b8c0001038000be80202097f027e230041206b220324000240200128020041016a220441004c0d0020012004360200200141046a2105200141086a28020021060240024003402005280200220741086a210820072f0106220941057421054100210a0240024003402005450d01200220084120109c05220b450d02200541606a2105200a41016a210a200841206a2108200b417f4a0d000b200a417f6a21090b2006450d022006417f6a2106200720094102746a41880b6a21050c010b0b2007200a41e0006c6a220541c5036a310000200541e8026a290300220c200c5022081ba7450d004200200541f8026a29030020081b210c4200200541f0026a29030020081b210d0c010b200341086a20012802102002200141146a28020028021c110500200341106a290300210c200128020021042003290308210d0b20012004417f6a3602002000200c3703082000200d370300200341206a24000f0b41b8b8c0004118200341186a41e0b8c0001038000ba62a020c7f037e230022072108200741800f6b41607122072400200720043703382007200337033020072005360244024002400240024002402001280230200128024022092802b801460d002005420020052903082203200941386a2903007d2204200420035622091b37030820090d0120074180046a20024100410110c201200741a4046a280200210a200741a0046a280200210b20072d008804220541037122094103460d0220090e03030203030b200041d4c5c00036020420004101360200200041086a41293602002000410c6a2006290200370200200041146a200641086a2802003602000c030b200041fdc5c00036020420004101360200200041086a41233602002000410c6a2006290200370200200041146a200641086a280200360200200824000f0b200041a0c6c00036020420004101360200200041086a41193602002000410c6a2006290200370200200041146a200641086a28020036020020050d01200a450d01200b102a200824000f0b200741a8046a2802002109200741c8006a41186a220c200141e8006a290000370300200741c8006a41106a220d200141e0006a290000370300200741c8006a41086a220e200141d8006a290000370300200720012900503703484100210f4100211002400240024002400240024002400240024002400240024002400240024020050d002009417f4c0d010240024020090d002007420037038004410121100c010b200910282210450d03200741003602840420072009360280040b20072009360284042010200b2009109a051a2007290380042103200a450d00200b102a0b200741a4016a410036020020074194016a419cc4c000360200200741e8006a41206a420037030020074184016a41f8b9c000360200200741e8006a41106a2003370300200741e8006a41d8006a200241086a290000370300200741e8006a41e0006a200241106a290000370300200741e8006a41e8006a200241186a29000037030020072001360270200741e8006a41286a200141186a22113602002007420837029c01200741003602800120072010360274200720022900003703b801200720012802483602b001200720012903403703a8012007200128023041016a36029801200129030021032007200128024c3602b40120072003370368200741d8016a41206a200e290300370300200741d8016a41286a200d29030037030020074188026a200c290300370300200741ec016a200641086a280200360200200720023602e001200720072903483703f001200720062902003702e4012007200741c4006a3602dc012007200741306a3602d8010240024020072903302203200741306a41086a290300220484500d00200741286a20072802444100200741f0016a200220032004200741e8006a10b801200728022822060d01200728028001210f20072802e00121020b200f41016a220d41004c0d03200741d8016a41186a210e200741e4016a210f2007200d36028001200741e8006a41206a280200210a20074184016a2212210602400240024003402006280200220b41086a2105200b2f0106220c4105742106410021090240024003402006450d01200220054120109c052210450d02200641606a2106200941016a2109200541206a21052010417f4a0d000b2009417f6a210c0b200a450d02200a417f6a210a200b200c4102746a41880b6a21060c010b0b200b200941e0006c6a220541e8026a210602400240200541c5036a2d00000d0020074180046a41086a2209200641c5006a29000037030020074180046a41106a2210200641cd006a29000037030020074180046a41186a220b200641d5006a29000037030020072006413d6a290000370380044102210520062d003c4101470d01200741a00c6a41186a200b290300370300200741a00c6a41106a2010290300370300200741a00c6a41086a200929030037030020072007290380043703a00c410121050c010b200741a80c6a200641c5006a290000370300200741b00c6a200641cd006a290000370300200741b80c6a200641d5006a29000037030020072006413d6a2900003703a00c20062d003c21050b200541ff01714102470d010b20074190026a2007280290012002200728029401280210110500200728028001210d20072d00900221050c010b20074199026a200741a80c6a290300370000200741a1026a200741b00c6a290300370000200741a9026a200741b80c6a290300370000200720053a009002200720072903a00c370091020b2007200d417f6a360280014101210a0240200541ff01714101470d00200741b8026a41186a200741a9026a290000370300200741b8026a41106a200741a1026a290000370300200741b8026a41086a20074199026a29000037030020072007290091023703b80220074180046a200741b8026a20072802b00128020010b90102402007280280044101470d0020072902e4012203422088a7210520074180046a41086a28020021092007280284042106200741ec016a28020021102003a721020c100b200741a00c6a41186a220520074180046a410472220641186a2802002209360200200741d8026a41106a200641086a290200370300200741d8026a41186a200641106a290200370300200741f8026a2009360200200741043602dc02200741af8dc6003602d802200720062902003703e00220072802ac0121062005200e41186a2900002203370300200741a00c6a41106a200e41106a2900002204370300200741a00c6a41086a2205200e41086a2900002213370300200741a8046a2013370300200741b0046a2004370300200741b8046a20033703002007200e29000022033703a00c200720033703a00420072802d801220941086a29030021032007200741e8006a36029804200929030021042007290368211320072802b4012109200720033703880420072004370380042007200936029c0420072013370390042005200f41086a2802003602002007200f2902003703a00c200741e0036a2006200741d8026a20074180046a200741a00c6a20072802dc0128020010ba01200741ec036a2902002103200741e0036a41086a280200210c20072802e403210a024020072802e0034101470d002003422088a72105200741f4036a28020021102003a72102200c2109200a21060c0f0b20072802800141016a220f41004c0d0520072802e00121022007200f36028001200728028801210d201221060240024003402006280200220b41086a2105200b2f0106220e4105742106410021090240024003402006450d01200220054120109c052210450d02200641606a2106200941016a2109200541206a21052010417f4a0d000b2009417f6a210e0b200d450d02200d417f6a210d200b200e4102746a41880b6a21060c010b0b200b200941e0006c6a220641c5036a310000200641e8026a290300220420045022051ba7450d004200200641f8026a29030020051b21044200200641f0026a29030020051b21130c010b200741186a200728029001200220072802940128021c110500200741206a290300210420072903182113200728028001210f0b2007200f417f6a221036028001201320072802a801220629037854200420064180016a29030022135420042013511b0d060c070b4100210c420021030240200741e8016a280200450d0020072802e401102a0b420021040c070b200728022c210920072902e4012203422088a721052003a72102200741ec016a28020021100c0d0b1036000b200941011037000b41b8b8c000411820074180046a41e0b8c0001038000b41b8b8c000411820074180046a41e0b8c0001038000b20072802702206450d020240024020072802e0012205200641d0006a2209460d00200920054120109c05450d00034020062802082206450d022005200641d0006a2209460d01200920054120109c050d000b0b2003a7211041b9c6c000210641372109200c2105200a21020c080b20100d032007417f36028001200741003a00bc03200742003702b403200741013a009d03200741f8b9c0003602b003200741e0036a41186a200541186a290000370300200741e0036a41106a200541106a290000370300200741e0036a41086a200541086a290000370300200720052900003703e00302400240200728028401221041f8b9c000460d00200728028801210b0c010b200741a00c6a410041e0021099051a20074180046a410041a0081099051a41880b10282210450d054100210b201041003b010620104100360200201041086a200741a00c6a41e002109a051a201041e8026a20074180046a41a008109a051a200741003602880120072010360284010b02400240034020102f0106220d4105742102410021064100210502400240034020022006460d01200741e0036a201020066a41086a4120109c052209450d02200641206a2106200541016a21052009417f4a0d000b2005417f6a210d0b200b450d02200b417f6a210b2010200d4102746a41880b6a28020021100c010b0b2010200541e0006c6a22064190036a20072903a80337030020064188036a20072903a003370300200641c0036a200729039803370000200641b8036a200729039003370000200641b0036a200729038803370000200641a8036a20072903800337000020064180036a4200370300200641e8026a2205290300211320054200370300200641a0036a22052802002102200520072903b80337030020064198036a22062903002104200620072903b0033703002004a721062004422088a721050c010b200741c0036a41186a200741e0036a41186a2903002204370300200741c0036a41106a200741e0036a41106a2903002213370300200741c0036a41086a200741e0036a41086a2903002214370300200720072903e00322153703c003200741bc0c6a2014370200200741a00c6a41246a2013370200200741cc0c6a20043702002007200741e8006a41246a3602b00c2007200d3602ac0c200720123602a80c200720103602a40c200741003602a00c200720153702b40c20074180046a41186a42003703002007420037038004200741b8046a20072903b803370300200741b0046a20072903b003370300200741a8046a20072903a803370300200741a0046a20072903a003370300200741d8046a200729039803370300200741d0046a200729039003370300200741c8046a200729038803370300200741c0046a200729038003370300200741a00c6a20074180046a10b7011a420221130b024020134202510d000240024020050d00200621090c010b2005211020062109034020092802ec0321092010417f6a22100d000b0340200620062f01064102746a41ec036a28020021062005417f6a22050d000b0b2007419c046a20062f010636020020074198046a410036020020074194046a2006360200200720023602a004200741003602900420074200370388042007200936028404200741003602800420074180046a1095010b200720072802800141016a360280010b0240200741f0026a280200450d00200741ec026a280200102a0b200342ffffffff0f83210420034280808080708321030b20072802a401210520072802a001210d200728029c01210b200728028c01210e20072802880121102007280284012106024020072802742209450d00200741f8006a280200450d002009102a0b200420038421040240024020034280808080f01f8350450d002007200e3602880420072010360284042007200636028004201120074180046a10bb012007200d360284042007200b360280042007200b200541b0016c22056a220236028c0402400240200141386a28020022092001413c6a28020022066b200541b0016d2210490d00200128023421090c010b200620106a220d2006490d0720094101742206200d2006200d4b1b2206ad42b0017e2203422088a70d072003a7220d4100480d070240024020090d00200d102821090c010b2001280234200941b0016c200d102c21090b2009450d0620012009360234200141386a20063602002001413c6a28020021060b2009200641b0016c6a200b2005109a051a2001413c6a2206200628020020106a360200200720023602880420074180046a10692000410c6a2004370200200041086a200c3602002000200a3602040c010b2000200a3602042000410c6a2004370200200041086a200c36020002402005450d00200541b0016c210141002105034002400240200b20056a22092d0000220241014b0d000240024020020e020001000b0240200941086a280200450d00200941046a280200102a0b200941106a2d00004105490d02200941386a280200450d02200941346a280200102a0c020b200941286a106a0c010b200941e8006a280200450d00200941e4006a280200102a0b2001200541b0016a2205470d000b0b0240200d450d00200b102a0b0240024020100d00200621050c010b2010210920062105034020052802880b21052009417f6a22090d000b0340200620062f01064102746a41880b6a28020021062010417f6a22100d000b0b2007419c046a20062f010636020020074198046a410036020020074194046a20063602002007200e3602a004200741003602900420074200370388042007200536028404200741003602800420074180046a109b010b20004100360200200824000f0b41f0c6c00041321050000b41a8b8c000411020074180046a41d0b8c0001038000b41880b41081037000b200d41081037000b1031000b200741f0026a280200450d00200741ec026a280200102a0b2000200636020420004101360200200041146a2010360200200041086a20093602002000410c6a2005ad4220862002ad84370200024020072802742206450d00200741f8006a280200450d002006102a0b200741e8006a411c6a2802002106200728028c0121000240024020072802880122050d00200621090c010b2005211020062109034020092802880b21092010417f6a22100d000b0340200620062f01064102746a41880b6a28020021062005417f6a22050d000b0b20074180046a411c6a20062f01063602004100210520074198046a410036020020074194046a2006360200200720003602a004200741003602900420074200370388042007200936028404200741003602800420074180046a109b01024020072802a4012206450d00200728029c012110200641b0016c2100034002400240201020056a22062d0000220941014b0d000240024020090e020001000b0240200641086a280200450d00200641046a280200102a0b200641106a2d00004105490d02200641386a280200450d02200641346a280200102a0c020b200641286a106a0c010b200641e8006a280200450d00200641e4006a280200102a0b2000200541b0016a2205470d000b0b20072802a001450d00200728029c01102a200824000f0b200824000b871304057f027e0a7f077e230041f0026b22042400200441d0006a2001108c010240024020042d00502205417f6a41ff017141024f0d00200041003a0000200041086a200441d0006a41d800109a051a0c010b200441a8016a41086a2206200441d0006a413c6a290200370300200441a8016a41106a2207200441d0006a41c4006a290200370300200441a8016a41186a2208200441d0006a41cc006a2902003703002004200441d0006a41346a2902003703a801200441d0006a41106a2903002109200441d0006a41086a290300210a200441d0006a41306a280200210b200441d0006a412c6a280200210c200441d0006a41246a280200210d200441d0006a41206a280200210e200441ec006a280200210f200441d0006a41186a2802002110200441d0006a41d4006a2802002111200441d0006a41286a28020021120240024002400240024002400240024002400240024041004100109801221320026b2202200220134b1b220220126b2214201420024b1b2214450d00200441c0006a2001109101200441306a20042903402215200441c0006a41086a2903002216428080a8ec85afd1b101420010a0054200200dad2217200429033022187d221920192017564200200441306a41086a2903002017201854ad7c7d22174200522017501b22021b22184200201720021b221784500d042015428080d287e2bc2d5441002016501b0d01200441186a2014ad420020182017109f05200441086a2004290318200441186a41086a290300428080e983b1de164200109f05200441286a20014108420020152015428080aef89dc3527c2217200a200a201756200920162017201554ad7c427f7c22175620092017511b22021b22182004290308221920182019542017200920021b2218200441086a41086a29030022175420182017511b22021b221a7d221b201b20155620162018201720021b22187d2015201a54ad7d221520165620152016511b22141b4200201520141b10bc010240024020042802280d000240024020020d002003450d010b20044188026a2001201a201841081098022004280288024101460d08200420044198026a2903003703f001200420044188026a41086a2903003703e8012004200441e8016a3602880220044188026a109d010b20020d0020030d01200041003a0008200041023a0000200041186a2009370000200041106a200a370000200041386a200b360000200041346a200c360000200041306a20123600002000412c6a200d360000200041286a200e360000200041246a200f360000200041206a20103600002000413c6a20042903a801370000200041c4006a200441b0016a290300370000200041cc006a200441a8016a41106a290300370000200041d4006a200441a8016a41186a290300370000200041dc006a2011360000200541037122004103460d0520000e030d05050d0b20044100360288022010200e20044188026a100d21142004280288022213417f460d07200441e8016a41186a200441a8016a41186a290300370300200441e8016a41106a200441a8016a41106a290300370300200441e8016a41086a200441a8016a41086a290300370300200420042903a8013703e801200441003602e802200442013703e00220142013200441e0026a10b2020240024020042802e402220320042802e802220d6b4120490d00200d41206a211220042802e00221020c010b200d41206a2212200d490d0a200341017422022012200220124b1b220b4100480d0a0240024020030d00200b102821020c010b20042802e0022003200b102c21020b2002450d092004200b3602e402200420023602e002200b21030b200420123602e8022002200d6a220d20042903e801370000200d41086a200441e8016a41086a290300370000200d41106a200441e8016a41106a290300370000200d41186a200441e8016a41186a29030037000020044188026a41186a220d420037030020044188026a41106a220b420037030020044188026a41086a220c420037030020044200370388022002201220044188026a1000200441c8016a41186a2212200d290300370300200441c8016a41106a220d200b290300370300200441c8016a41086a220b200c29030037030020042004290388023703c80102402003450d002002102a0b200441a1026a201229030037000020044199026a200d29030037000020044191026a200b290300370000200420042903c80137008902200441013a008802200120044188026a10b3022010200e1004200041013a0000200041086a20044188026a41d800109a051a2013450d032014102a0c030b200441b8026a200b360200200441b4026a200c360200200441b0026a2013360200200441ac026a200d360200200441a8026a200e360200200441a4026a200f36020020044188026a41186a2010360200200441bc026a20042903a801370200200441c4026a200441a8016a41086a290300370200200441cc026a200441a8016a41106a290300370200200441d4026a200441a8016a41186a29030037020020044188026a41106a200920177d200a201954ad7d370300200441003a0088022004200a20197d37039002200120044188026a10b302200041023a0000200041086a20044188026a41d800109a051a0c090b200041003a0008200041003a0000200041186a2009370000200041106a200a370000200041386a200b360000200041346a200c360000200041306a20123600002000412c6a200d360000200041286a200e360000200041246a200f360000200041206a20103600002000413c6a20042903a801370000200041c4006a2006290300370000200041cc006a2007290300370000200041d4006a2008290300370000200041dc006a20113600000c080b20011096012010200e1004200041023a0008200041013a00000b200f450d062010102a0c060b200f450d070c060b200041003a0008200041003a0000200041186a2009370000200041106a200a370000200041386a200b360000200041346a200c360000200041306a20123600002000412c6a200d360000200041286a200e360000200041246a200f360000200041206a20103600002000413c6a20042903a801370000200041c4006a200441b0016a290300370000200041cc006a200441a8016a41106a290300370000200041d4006a200441a8016a41186a290300370000200041dc006a20113600000c040b2004200429028c023703e80141f896c10041fe00200441e8016a41f897c1001038000b41eef3c50041381050000b200b41011037000b1031000b0240200541037122004103460d0020000e03020000020b200f450d010b2010102a0b200441f0026a24000be20d03047f017e027f230041106b2202240020024100360208200242013703000240024002400240024002400240024002400240024002400240024002402001280200220341044b0d000240024002400240024020030e050001020304000b410110282203450d05200242818080801037020420022003360200200341013a0000200128020421042001410c6a2802002203200210b40102402003450d002004200341286c6a2105034020042002108f01200441206a29030021060240024020022802042207200228020822036b4108490d00200228020021070c010b200341086a22082003490d15200741017422032008200320084b1b22034100480d150240024020070d002003102821070c010b200228020020072003102c21070b2007450d092002200336020420022007360200200228020821030b2002200341086a360208200720036a20063700002005200441286a2204470d000b0b200141106a28020021070240024020022802042204200228020822036b4104490d00200228020021040c010b200341046a22082003490d13200441017422032008200320084b1b22034100480d130240024020040d002003102821040c010b200228020020042003102c21040b2004450d082002200336020420022004360200200228020821030b2002200341046a360208200420036a20073600000c040b410110282203450d07200242818080801037020420022003360200200341023a0000200128020421070240024020022802042204200228020822036b4104490d00200228020021040c010b200341046a22082003490d12200441017422052008200520084b1b22084100480d120240024020040d002008102821040c010b200228020020042008102c21040b2004450d0920022008360204200220043602000b2002200341046a360208200420036a200736000020012802082104200141106a2802002203200210b40102402003450d002004200341286c6a2105034020042002108f01200441206a29030021060240024020022802042207200228020822036b4108490d00200228020021070c010b200341086a22082003490d14200741017422032008200320084b1b22034100480d140240024020070d002003102821070c010b200228020020072003102c21070b2007450d0c2002200336020420022007360200200228020821030b2002200341086a360208200720036a20063700002005200441286a2204470d000b0b200141146a28020021070240024020022802042204200228020822036b4104490d00200228020021040c010b200341046a22082003490d12200441017422032008200320084b1b22034100480d120240024020040d002003102821040c010b200228020020042003102c21040b2004450d0b2002200336020420022004360200200228020821030b2002200341046a360208200420036a20073600000c030b410110282203450d0a200242818080801037020420022003360200200341033a0000200141086a29030021060240024020022802042207200228020822036b4108490d00200341086a2104200228020021070c010b200341086a22042003490d11200741017422082004200820044b1b22084100480d110240024020070d002008102821070c010b200228020020072008102c21070b2007450d0c20022008360204200220073602000b20022004360208200720036a20063700000c020b410110282203450d0b200242818080801037020420022003360200200341043a0000200128020421070240024020022802042204200228020822036b4104490d00200228020021040c010b200341046a22082003490d10200441017422012008200120084b1b22084100480d100240024020040d002008102821040c010b200228020020042008102c21040b2004450d0d20022008360204200220043602000b2002200341046a360208200420036a20073600000c010b410110282203450d0c200242818080801037020420022003360200200341053a0000200128020421080240024020022802042207200228020822036b4104490d00200341046a2104200228020021070c010b200341046a22042003490d0f200741017422012004200120044b1b22014100480d0f0240024020070d002001102821070c010b200228020020072001102c21070b2007450d0e20022001360204200220073602000b20022004360208200720036a20083600000b20002002290300370200200041086a200241086a280200360200200241106a24000f0b410141011037000b200341011037000b200341011037000b410141011037000b200841011037000b200341011037000b200341011037000b410141011037000b200841011037000b410141011037000b200841011037000b410141011037000b200141011037000b1031000bfb0101077f230041106b220124002001410036020820014201370300200110c40120012802042102200128020021030240024002400240200041046a2802002204200041086a28020022056b20012802082206490d00200028020021040c010b200520066a22072005490d02200441017422052007200520074b1b22054100480d020240024020040d002005102821040c010b200028020020042005102c21040b2004450d0120002004360200200041046a2005360200200041086a28020021050b200041086a200520066a360200200420056a20032006109a051a02402002450d002003102a0b200141106a24000f0b200541011037000b1031000ba5900108027f017e0b7f037e2f7f027e057f0e7e23004190106b220224000240024002400240024002400240024002400240024002400240200141106a2802002203ad42d0007e2204422088a70d002004a72205417f4c0d00200128020821060240024002400240024002400240024020050d00410821070c010b200510282207450d010b0240024020030d00410021080c010b2006200341d0006c6a2109410021082007210a0340200241c8046a41186a220b200641186a290300370300200241c8046a41106a220c200641106a290300370300200241c8046a41086a220d200641086a290300370300200220062903003703c8042006280248220ead42307e2204422088a70d082004a7220f417f4c0d08200641386a2903002104200641286a290300211020062903302111200629032021122006280240210502400240200f0d00410821130c010b200f10282213450d040b200641d0006a210602400240200e0d00410021140c010b2005200e41306c6a2115410021142013210f0340200f2005290300370300200f200541086a290300370308200f41106a200541106a290300370300200f41186a200541186a290300370300200f41206a200541206a290300370300200f41286a200541286a290300370300200f41306a210f201441016a2114200541306a22052015470d000b0b200a2012370320200a20022903c804370300200a41386a2004370300200a41306a2011370300200a41286a2010370300200a41c8006a2014360200200a41c4006a200e360200200a41c0006a2013360200200a41186a200b290300370300200a41106a200c290300370300200a41086a200d290300370300200841016a2108200a41d0006a210a20062009470d000b0b200028020821162000280204211720002802002118200128020421192001280200210b41041028221a450d02201a200b36000020024284808080c0003702bc072002201a3602b807411b10282205450d03200541176a41002800f39646360000200541106a41002900ec9646370000200541086a41002900e49646370000200541002900dc96463700002002429b808080b00337028c08200220053602880841a2c7c00020024188086a10c601200228029008210f2002280288082105200241c8046a41186a22144200370300200241c8046a41106a22154200370300200241c8046a41086a22064200370300200242003703c8042005200f200241c8046a1000200241b00f6a41186a2014290300370300200241b00f6a41106a2015290300370300200241b00f6a41086a2006290300370300200220022903c8043703b00f0240200228028c08450d002005102a0b2002410036028808200241b00f6a412020024188086a100621142002280288082215417f460d042014450d042002201536028c082002201436028808200241d0026a20024188086a106c02400240024020022802d0020d00200228028c08220620022802d402220f490d00200f417f4c0d0902400240200f0d00410121050c010b200f102e2205450d022005200228028808220a200f109a051a20022006200f6b36028c082002200a200f6a360288080b20050d020b41c4d1c3004133200241f8056a419cd9c3001038000b200f41011037000b200fad220442208620048421042015450d052014102a0c050b200541081037000b200f41081037000b410441011037000b411b41011037000b410021050b20022005410120051b22133602b00f20022004420020051b22104220883e02b40f200241c8026a200241b00f6a106c20022802cc02210e41002106024020022802c8020d0020022802b40f220541246e220a41246c220f417f4c0d0102400240024002400240200f0d00410421060c010b200f10282206450d010b200e450d034100210c034020054104490d03200c41016a210d20022005417c6a22143602b40f200220022802b00f221541046a3602b00f2015280000210941002105200241003a00a8080340024020142005470d00200241003602b40f200541ff0171450d05200241003a00a8080c050b20024188086a20056a201520056a220f41046a2d00003a00002002200f41056a3602b00f2002200541016a220f3a00a808200f2105200f4120470d000b200241c8046a41086a221520024188086a41086a290300370300200241c8046a41106a220020024188086a41106a290300370300200241c8046a41186a221b20024188086a41186a29030037030020022002290388083703c80420022014200f6b22053602b40f0240200a200c470d00200c410174220f200d200f200d4b1b220aad42247e2204422088a70d122004a7220f4100480d1202400240200c0d00200f102821060c010b2006200c41246c200f102c21060b2006450d030b2006200c41246c6a220f2009360200200f20022903c804370204200f410c6a2015290300370200200f41146a2000290300370200200f411c6a201b290300370200200d210c200d200e470d000c040b0b200f41041037000b200f41041037000b0240200a0d00410021060c010b2006102a410021060b200241b00f6a200241b8076a10c70120022802b80f210f20022802b00f210520024100360288082005200f20024188086a1006210f024002402002280288082214417f460d00200f450d00200220143602dc062002200f3602d80620024188086a200241d8066a106d0240200228028808221c450d00200229028c0821042014450d02200f102a0c020b41c4d1c3004133200241f8056a419cd9c3001038000b420021044101211c0b024020022802b40f450d002005102a0b2004422088211102402010a7450d002013102a0b200e410020061b211d200a410020061b211e2006410420061b210c2011a7211f2004a72120200242003702dc02200241f8b9c0003602d8022007200841d0006c6a21210240024020080d00200721130c010b200241b8036a41306a212220024188086a410c6a212320164101742205201641ffffff3f712224200520244b1b222541ffffff3f71202547212620254105742127202420164721282016410574222941606a41057641016a212a20024188086a41306a212b20024188086a41206a212c20024188086a410272212d20024198056a41046a212e20024188086a41c0006a212f200241b00f6a41106a2130200241b8076a4104722131200241b8036a41c4006a21322018201820296a4621332007211302400240034020024188086a41386a22062013220541386a290300370300202b200541306a29030037030020024188086a41286a220a200541286a290300370300202c200541206a29030037030020024188086a41186a2234200541186a29030037030020024188086a41106a2235200541106a29030037030020024188086a41086a2236200541086a290300370300200241b00f6a41086a221b200541cc006a28020036020020022005290300370388082002200541c4006a2902003703b00f200541d0006a2113200541c0006a2802002205450d03200241f8026a41386a220f2006290300370300200241f8026a41306a2214202b290300370300200241f8026a41286a2215200a290300370300200241f8026a41206a220e202c290300370300200241f8026a41186a220d2034290300370300200241f8026a41106a22092035290300370300200241f8026a41086a22002036290300370300200241e8026a41086a2237201b28020036020020022002290388083703f802200220022903b00f3703e802200241b8036a41386a2238200f29030037030020222014290300370300200241b8036a41286a22392015290300370300200241b8036a41206a2215200e290300370300200241b8036a41186a223a200d290300370300200241b8036a41106a223b2009290300370300200241b8036a41086a223c2000290300370300200220022903f8023703b803200220053602f803203220022903e802370200203241086a20372802003602000240024002400240024002400240410410282214450d002014200b360000202341002900a2c740370000202341086a41002900aac74037000020024284808080c00037028c0820022014360288082002200241b8036a3602a408410810282205450d01200242083702b40f200220053602b00f2023200241b00f6a10c6014104200241b00f6a10b4010240024020022802b40f220f20022802b80f22056b4104490d0020022802b00f210f0c010b200541046a220e2005490d18200f4101742205200e2005200e4b1b22054100480d1802400240200f0d0020051028210f0c010b20022802b00f200f2005102c210f0b200f450d03200220053602b40f2002200f3602b00f20022802b80f21050b2002200541046a3602b80f200f20056a2014280000360000200241b8036a200241b00f6a108f01200220153602b807200241b8076a200241b00f6a10a301200220223602b807200241b8076a200241b00f6a10a30120022802f8032105200228028004220f200241b00f6a10b4010240200f450d00200f41306c210f0340200541106a200241b00f6a108f01200220053602b807200541306a2105200241b8076a200241b00f6a10a301200f41506a220f0d000b0b20022802b40f210f20022802b80f211520022802b00f2105200241c8046a41186a220d4200370300200241c8046a41106a22094200370300200241c8046a41086a22004200370300200242003703c80420052015200241c8046a100020024188046a41186a223d200d29030037030020024188046a41106a223e200929030037030020024188046a41086a223f2000290300370300200220022903c804370388040240200f450d002005102a0b2014102a411010282205450d032005410029008ab7402204370000200541086a4100290092b740221037000020024290808080800237028c082002200536028808200220024188086a3602b80720024188046a200241b8076a10c8012002280288082105200228029008210f200d42003703002009420037030020004200370300200242003703c8042005200f200241c8046a1000200241b00f6a41186a2240200d29030037030020302009290300370300201b2000290300370300200220022903c8043703b00f0240200228028c08450d00200228028808102a0b200241b00f6a41204101410041001003417f460d050c040b410441011037000b410841011037000b200541011037000b411041011037000b20022802fc03450d0120022802f803102a0c010b200241a8046a41186a2241203a290300370300200241a8046a41106a223a203b290300370300200241a8046a41086a223b203c290300370300200220022903b8033703a804200228028004220ead42307e2211422088a70d052011a7220f417f4c0d05203829030021112039290300211220022903e803214220022903d803214320022802f8032105024002400240024002400240024002400240024002400240200f0d00410821370c010b200f10282237450d010b02400240200e0d00410021140c010b2005200e41306c6a2115410021142037210f0340200f2005290300370300200f200541086a290300370308200f41106a200541106a290300370300200f41186a200541186a290300370300200f41206a200541206a290300370300200f41286a200541286a290300370300200f41306a210f201441016a2114200541306a22052015470d000b0b200241b00f6a41386a2011370300200241b00f6a41286a2012370300204020412903003703002030203a290300370300201b203b290300370300200220423703e00f200220433703d00f200220022903a8043703b00f200220143602f80f2002200e3602f40f200220373602f00f0240024020022802d802220541f8b9c000460d0020022802dc02210f0c010b20024188086a410041f0061099051a41f80610282205450d024100210f200541003b010620054100360200200541086a20024188086a41f006109a051a200241003602dc02200220053602d8020b2002200536028c082002200f360288082002200241d8026a36029008200241b8076a20024188086a200241b00f6a10c901024020022802b8074101470d00202f20312902003702002036203041086a2903003703002035203041106a2903003703002034203041186a290300370300202c203041206a290300370300200a203041286a290300370300202b203041306a2903003703002006203041386a290300370300202f41086a203141086a290200370200200220302903003703880820022802bc0f2115202e41086a220f201b280200360200202e20022903b00f370200200241c8046a20024188086a41d000109a051a200241a8056a200241c8046a41d000109a051a200220022802e00241016a3602e00220022802f005214120022802f405211420022802ec052105200241d8066a41086a22442000290300370300200241d8066a41106a220e2009290300370300200241d8066a41186a2237200d290300370300200241d8066a41206a2239200241c8046a41206a290300370300200241d8066a41286a223a200241c8046a41286a290300370300200241d8066a41306a223b200241c8046a41306a290300370300200241d8066a41386a223c200241c8046a41386a290300370300200241c8066a41086a2245200f280200360200200220022903c8043703d8062002202e2902003703c80620052f01062238410b490d0520024188086a410041f0061099051a41f80610282238450d03203841003b010620384100360200203841086a20024188086a41f006109a05210f20024188086a4108200541086a2246200541f8b9c0004622471b224841e0036a41d000109a051a200f204841b0046a20052f010641796a224841d0006c109a05210f200541063b0106203820483b0106200241b00f6a20024188086a41d000109a051a0240024020144107490d00201441d0006c4108200f203841f8b9c0004622061b6a220f41a07c6a200f41d07b6a220f4100204841ffff037120061b20146b41d0006c41b0046a109b051a200f201536020c200f41086a2045280200360200200f20022903c806370300200f20022903d806370310200f41186a2044290300370300200f41206a200e290300370300200f41286a2037290300370300200f41306a2039290300370300200f41386a203a290300370300200f41c0006a203b290300370300200f41c8006a203c290300370300203820382f010641016a3b01060c010b4108210f200241a8076a41086a200241c8066a41086a28020036020020024188086a41086a200241d8066a41086a2903003703002035200e29030037030020342037290300370300202c2039290300370300200a203a290300370300202b203b2903003703002006203c290300370300200220022903c8063703a807200220022903d80637038808024002402047450d004100210e0c010b20052f0106210e2046210f0b200f201441d0006c6a220f41d0006a200f200e20146b41d0006c109b051a200f201536020c200f41086a200241a8076a41086a280200360200200f20022903a807370300200f200229038808370310200f41186a2036290300370300200f41206a2035290300370300200f41286a2034290300370300200f41306a202c290300370300200f41386a200a290300370300200f41c0006a202b290300370300200f41c8006a2006290300370300200520052f010641016a3b01060b200241b8076a200241b00f6a41d000109a051a200241f8056a200241b8076a41d000109a051a2005280200220e450d0620052f010421370340200241d8066a200241f8056a41d000109a051a203741ffff0371210602400240024002400240200e2f01062205410b490d00202d410041a2071099051a41a80710282215450d0a20154100360200201541046a20024188086a41a407109a051a20024188086a4108200e41086a223b200e41f8b9c00046223c1b220541e0036a41d000109a051a201541086a223a200541b0046a200e2f0106220541796a220f41d0006c109a051a201541f8066a200e4194076a2005417a6a220a410274109a052139200e41063b01062015200f3b01060240200a450d00410021052039210f0340200f280200221420053b010420142015360200200f41046a210f200a200541016a2205470d000b0b200241b00f6a20024188086a41d000109a051a200241b8076a200241b00f6a41d000109a051a203741ffff037122054107490d0320024188086a200241d8066a41d000109a051a200641796a210541f8b9c0002114201541f8b9c000470d014108213a4100210a0c020b4108200e41086a200e41f8b9c0004622141b200641d0006c6a220f41d0006a200f4100200520141b20066b41d0006c109b051a200f200241d8066a41d000109a051a200e200e2f010641016a220f3b01062006410274200e41f8066a22146a41086a2014200641016a22054102746a2214200f41ffff0371220f20056b410274109b051a201420383602002006200f4f0d0c203820053b01042038200e3602002005200f4f0d0c200f417f6a2115200e2005417f6a22054102746a4180076a210f0340200f2802002214200541026a3b01042014200e360200200f41046a210f2015200541016a2205470d000c0d0b0b20152f0106210a201521140b203a2006417a6a220f41d0006c6a203a200541d0006c6a2237200a20056b41d0006c109b051a203720024188086a41d000109a051a201520152f010641016a220a3b01062006410274223720396a416c6a2039200f4102746a2206200a41ffff0371200f6b410274109b051a20062038360200200f20142f010622064b0d01201520376a41e0066a210f0340200f2802002214200541016a22053b010420142015360200200f41046a210f20052006490d000c020b0b200e41f8066a210f20024188086a200241d8066a41d000109a051a02400240203c450d004108213b4100210a0c010b200e2f0106210a0b203b200641d0006c6a221441d0006a2014200a20066b41d0006c109b051a201420024188086a41d000109a051a200e200e2f010641016a22143b010620064102742237200f6a41086a200f200641016a220a4102746a220f201441ffff0371200a6b410274109b051a200f20383602002005200e2f010622144f0d00200e20376a41fc066a210503402005280200220f200641016a22063b0104200f200e360200200541046a210520142006470d000b0b200241f8056a200241b8076a41d000109a051a0240200e28020022050d00201521380c080b200e2f010421372005210e201521380c000b0b20024198056a41086a203141086a2902003703002002203129020037039805200e450d062037102a0c060b200f41081037000b41f80641081037000b41f80641081037000b41a80741081037000b4108200541086a200541f8b9c0004622061b201441d0006c6a220f41d0006a200f4100203820061b20146b41d0006c109b051a200f201536020c200f41086a2045280200360200200f20022903c806370300200f20022903d806370310200f41186a2044290300370300200f41206a200e290300370300200f41286a2037290300370300200f41306a2039290300370300200f41386a203a290300370300200f41c0006a203b290300370300200f41c8006a203c290300370300200520052f010641016a3b01060c010b202d410041a2071099051a41a80710282205450d0120054100360200200541046a20024188086a41a407109a051a20052041280200220f3602f806204120053602002041204128020441016a360204200f41003b0104200f20053602004108200541086a200541f8b9c000461b20052f0106220f41d0006c6a200241f8056a41d000109a051a200541f8066a200f41016a220f4102746a2038360200200520052f010641016a3b01062038200f3b0104203820053602000b200241b00f6a200241b8036a41d000109a051a20280d082029417f4c0d080240024020290d00410121150c010b202910282215450d020b024020162024490d00201621060c030b20262027410048720d140240024020160d002027102821150c010b201520292027102c21150b2025210620150d02202741011037000b41a80741081037000b202941011037000b024002402033450d00410021050c010b20292114201521052018210f03402005200f290000370000200541186a200f41186a290000370000200541106a200f41106a290000370000200541086a200f41086a290000370000200541206a2105200f41206a210f201441606a22140d000b202a21050b20024188086a200241b00f6a41d000109a051a200220053602e008200220063602dc08200220153602d808024002400240411010282205450d0020052004370000200541086a20103700002002429080808080023702bc07200220053602b8072002200241b8076a3602d80620024188046a200241d8066a10c80120022802b807210520022802c007210f200d42003703002009420037030020004200370300200242003703c8042005200f200241c8046a10002040200d29030037030020302009290300370300201b2000290300370300200220022903c8043703b00f024020022802bc07450d0020022802b807102a0b200241003602c007200242013703b80720024188086a200241b8076a108f012002202c3602d806200241d8066a200241b8076a10a3012002202b3602d806200241d8066a200241b8076a10a30120022802c808210520022802d008220f200241b8076a10b4010240200f450d00200f41306c210f0340200541106a200241b8076a108f01200220053602d806200541306a2105200241d8066a200241b8076a10a301200f41506a220f0d000b0b20022802d808210520022802e008220f200241b8076a10b4010240200f450d00200f410574210f03402005200241b8076a108f01200541206a2105200f41606a220f0d000b0b20022802bc072105200241b00f6a412020022802b807220f20022802c007100702402005450d00200f102a0b024020022802cc08450d0020022802c808102a0b024020022802dc08450d0020022802d808102a0b200241b8076a41186a2206203d290300370300200241b8076a41106a220a203e290300370300200241b8076a41086a220e203f29030037030020022002290388043703b807410021050240201d41014b0d000240201d0e020003000b203420062903003703002035200a2903003703002036200e290300370300200220022903b80737038808410021050c030b201d210f03402005200f410176221420056a2215200c201541246c6a280200200b4b1b2105200f20146b220f41014b0d000c020b0b411041011037000b0240200c200541246c6a280200220f200b460d002005200f200b496a21050b203420062903003703002035200a2903003703002036200e290300370300200220022903b80737038808201d20054f0d0041f8b0c0001032000b0240201d201e470d00201d41016a220f201d490d12201d4101742214200f2014200f4b1b221ead42247e2204422088a70d122004a7220f4100480d1202400240201d0d00200f1028210c0c010b200c201d41246c200f102c210c0b200c450d030b200c200541246c6a220f41246a200f201d20056b41246c109b051a200f200b360200200f411c6a2034290300370200200f41146a2035290300370200200f410c6a2036290300370200200f200229038808370204204020062903003703002030200a290300370300201b200e290300370300200220022903b8073703b00f0240201f2020470d00201f41016a2205201f490d12201f410174220f2005200f20054b1b222041ffffff3f712020470d12202041057422054100480d1202400240201f0d0020051028211c0c010b201c201f4105742005102c211c0b201c450d040b201d41016a211d201c201f4105746a220520022903b00f370000200541186a2040290300370000200541106a2030290300370000200541086a201b290300370000201f41016a211f0b20132021470d000b202121130c020b200f41041037000b200541011037000b024020132021460d002007200841d0006c6a21140340201341c0006a280200220f450d01201341d0006a21050240201341c4006a280200450d00200f102a0b2005211320142005470d000b0b02402003450d002007102a0b0240024002400240024002400240024002400240024020022802e0020d0020022802d80220022802dc02410010ca01201a102a02402020450d00201c102a0b0240201e450d00200c102a0b2017450d012018102a0c010b2002201c3602d8062002201c201f4105746a3602dc06200241b00f6a200241d8066a10850102400240200241f00f6a2802000d004108210841002109410021230c010b20024188086a200241b00f6a41e000109a051a41e00010282208450d03200820024188086a41e000109a051a200220022903d8063703b807200241b00f6a200241b8076a1085010240200241f00f6a2802000d0041012109410121230c010b4102210f41e00021054101210941012123034020024188086a200241b00f6a41e000109a051a024020092023470d00200941016a22142009490d19200f2014200f20144b1b2223ad42e0007e2204422088a70d192004a722144100480d190240024020090d002014102821080c010b200820052014102c21080b2008450d060b200820056a20024188086a41e000109a051a200f41026a210f200541e0006a2105200941016a2109200241b00f6a200241b8076a10850120022802f00f0d000b0b200241a8086a201d360200200241a4086a201e36020020024198086a201fad4220862020ad843703002002201c3602940820024284808080c00037028c082002201a360288082002200c3602a008200241003602b80f200242013703b00f201d200241b00f6a10b4010240201d450d00200c201d41246c6a210a200c210f0340200f28020021150240024020022802b40f221420022802b80f22056b4104490d0020022802b00f21140c010b200541046a22062005490d19201441017422052006200520064b1b22054100480d190240024020140d002005102821140c010b20022802b00f20142005102c21140b2014450d07200220053602b40f200220143602b00f20022802b80f21050b2002200541046a3602b80f201420056a20153600002002200241b00f6a3602b807200f41046a200241b8076a10c801200f41246a220f200a470d000b0b20022802b80f211420022802b40f211520022802b00f210f411b10282205450d05200541176a41002800f39646360000200541106a41002900ec9646370000200541086a41002900e49646370000200541002900dc96463700002002429b808080b0033702bc07200220053602b80741a2c7c000200241b8076a10c60120022802c007210620022802b8072105200241c8046a41186a220a4200370300200241c8046a41106a220e4200370300200241c8046a41086a22134200370300200242003703c80420052006200241c8046a1000200241b00f6a41186a200a290300370300200241b00f6a41106a200e290300370300200241b00f6a41086a2013290300370300200220022903c8043703b00f024020022802bc07450d002005102a0b200241203602bc072002200241b00f6a3602b807200f2014200241b8076a10cb0102402015450d00200f102a0b200241b8076a20024188086a10c70120022802c007211520022802b8072114200241003602b80f200242013703b00f201f200241b00f6a10b4010240201f450d00201f410574210f201c210503402002200241b00f6a3602d8062005200241d8066a10c801200541206a2105200f41606a220f0d000b0b20022802b40f21052014201520022802b00f220f20022802b80f100702402005450d00200f102a0b024020022802bc07450d002014102a0b201a102a02402020450d00201c102a0b0240201e450d00200c102a0b20022802d802210520022902dc02210402402017450d002018102a0b20050d010b20012802082114024020012802102205450d00200541d0006c210f201441c0006a210503400240200541046a280200450d002005280200102a0b200541d0006a2105200f41b07f6a220f0d000b0b2001410c6a280200450d142014102a0c140b200220043702bc03200220053602b803410410282205450d042005200b36000020024190086a4284808080c00037030020024198086a41002900a2c740370300200241a0086a41002900aac7403703002002200536028c082002410f3a0088084101410020024188086a10cc012019418094ebdc036e22054101200541014b1b220520194b0d052019200941036c417d6a220f200f20194b1b20056ead428094ebdc037e201920056ead221080a741146e2215211420092004422088a76b220f0d060c070b41e00041081037000b201441081037000b200541011037000b411b41011037000b410441011037000b41acaac3001032000b2002418094ebdc0336028c082002418094ebdc03201941002009200f6b2214201420094b1b41036c417d6a2214201420194b1b20056ead428094ebdc037e201080a741146e22056bad4100201520056b2205200520154b1bad7e428094ebdc0380a722053602880820024188086a2005418094ebdc034b4102746a28020021140b200941e0006c220541e0006e2129410021130240024020050d0041042138410021290c010b2029410274220610282238450d020b0240200820056a2008460d000240200f0d00200941e0006c210f4100211320382105034020052014360200201341016a2113200541046a2105200f41a07f6a220f0d000c020b0b2008200941e0006c6a2106200941057441606a210a203821052008210f0340200220022802b8033602b40f200220022802bc033602b00f2002200241b8036a3602b80f20024188086a200241b00f6a200f10c9012005201420152002280288084101461b360200200541046a21052006200f41e0006a220f470d000b200a41057641016a21130b20024188086a41086a220542003703002002420037038808419e9dc600411b20024188086a1008200241b00f6a41086a200529030037030020022002290388083703b00f4100211b2002410036028808200241b00f6a411020024188086a100621050240200228028808220f417f460d002005450d00200f4104490d032005280000211b2005102a0b20024188086a41086a22054200370300200242003703880841bb9cc600411220024188086a1008200241b00f6a41086a200529030037030020022002290388083703b00f4100213b2002410036028808200241b00f6a411020024188086a100621050240200228028808220f417f460d002005450d00200f4104490d042005280000213b2005102a0b411710282205450d042005410f6a41002900d3fe44370000200541086a41002900ccfe44370000200541002900c4fe4437000020054117412e102c2205450d052005203b36001742002149200241f8056a41186a220f4200370300200241f8056a41106a22144200370300200241f8056a41086a22154200370300200242003703f8052005411b200241f8056a1000200241a8056a41186a200f290300370300200241a8056a41106a2014290300370300200241a8056a41086a2015290300370300200220022903f8053703a8052005102a2002410036028808200241a8056a412020024188086a100621002002280288082230417f460d092000450d09200220303602fc02200220003602f802200241c0026a200241f8026a106c20022802c0020d0820022802fc0222154140712205417f4c0d0020022802c402210d024002402015410676220e0d004108211d0c010b20051028221d450d070b0240200d450d004100210a0340200241003a00a808200a220641016a210a41002105024002400240034020152005460d0120024188086a20056a20022802f80222142d00003a00002002201441016a3602f8022002200541016a220f3a00a808200f2105200f4120470d000b200241f8056a41186a220520024188086a41186a290300370300200241f8056a41106a220b20024188086a41106a290300370300200241f8056a41086a220c20024188086a41086a29030037030020022002290388083703f8052015200f6b220f4110490d012002201441116a3602f802200f41706a410f4b0d02200f41706a210f0c010b0240200541ff0171450d00200241003a00a8080b4100210f0b200241b8076a41086a200241b00f6a41086a290300370300200220022903b00f3703b8072002200f3602fc02200e450d0b201d102a0c0b0b201441096a290000210420142900012110200241b8076a41086a2215200c290300370300200241b8076a41106a220c200b290300370300200241b8076a41186a220b20052903003703002002201441216a3602f802200220022903f80522113703b00f200220113703b807201441196a290000211120142900112112200241d8066a41186a2214200b290300370300200241d8066a41106a220b200c290300370300200241d8066a41086a220c2015290300370300200220022903b8073703d8060240200e2006470d0020064101742205200a2005200a4b1b220e41ffffff1f71200e470d0f200e41067422054100480d0f0240024020060d0020051028211d0c010b201d20064106742005102c211d0b201d450d0a0b200f41606a2115201d20064106746a220520123703102005200437030820052010370300200541186a2011370300200520022903d806370320200541286a200c290300370300200541306a200b290300370300200541386a2014290300370300200a200d470d000b2002200f41606a3602fc020b201d450d08200dad422086200ead84214902402030450d002000102a0b2049422088a7210f2049a7210e0c0a0b1036000b200641041037000b41c4d1c3004133200241f8056a419cd9c3001038000b41c4d1c3004133200241f8056a419cd9c3001038000b411741011037000b412e41011037000b200541081037000b200541081037000b41c4d1c3004133200241f8056a419cd9c3001038000b4108211d4100210f4100210e0b0240024020132009200920134b1b221f0d004200214a4200214b0c010b200241b00f6a4105722122200241b8076a41036a213920024188086a410572213220024188086a41086a2113201bad214c20024191086a2135200241e8016a41186a213a2008210b4200214a4200214b41002130034020134200370300200242003703880841c8ffc400411520024188086a1008200241b00f6a41086a2236201329030037030020022002290388083703b00f2002410036028808200241b00f6a411020024188086a100621140240024002400240024002400240024002400240024002400240024002400240024002400240200228028808220f417f460d002002200f3602bc07200220143602b80720024188086a200241b8076a106d2002280288082205450d02200229028c082104200f450d012014102a0c010b42002104410121050b20052004422088a72008203041e0006c6a220f10cd01211402402004a7450d002005102a0b20140d10200241b0026a200f41206a22342903002204203441086a222c290300428094ebdc03420010a005200241a0026a20022903b0022210200241b0026a41086a29030022114280ec94a37c427f109f0520024190026a20102011203820304102746a35020022124200109f0520022903900222102012200420022903a0027c7e428094ebdc038042ffffffff0f837c220420024190026a41086a2903002004201054ad7c2210844200510d1020134200370300200242003703880841c785c200411220024188086a100820024198056a41086a220c2013290300370300200220022903880837039805200241003602880820024198056a411020024188086a10062105024002402002280288082214417f460d002005450d00200220143602b40f200220053602b00f20024188086a200241b00f6a106d2002280288082237450d03200229028c0821122014450d012005102a0c010b41012137420021120b20372012422088a74105746a21064100211420372105024003400240200620056b41e0004b0d004102212b20052006460d080340200b2005460d0320142005200f4120109c0522154100476a21142015450d032006200541206a2205470d000c090b0b2005200f460d0120142005200f4120109c0522154100476a21142015450d01200541206a2215200f460d0120142015200f4120109c0522154100476a21142015450d01200541c0006a2215200f460d0120142015200f4120109c0522154100476a21142015450d01200541e0006a2215200f460d0120142015200f4120109c0522154100476a211420054180016a210520150d000b0b20134200370300200242003703880841bd99c600411a20024188086a1008200c2013290300370300200220022903880837039805200241003602880820024198056a411020024188086a100621052002280288082206417f460d032005450d03200220063602b40f200220053602b00f20024188086a200241b00f6a1082012002280288082215450d02200229028c0821112006450d042005102a0c040b41c4d1c3004133200241f8056a419cd9c3001038000b41c4d1c3004133200241f8056a419cd9c3001038000b41c4d1c3004133200241f8056a419cd9c3001038000b410021150b2015410420151b21004100210502400240024002402011420020151b22114220882242a7220e41014b0d00200e0e020201020b200e2115034020052015410176220620056a220a20142000200a4102746a280200491b2105201520066b221541014b0d000b0b4100212b02402014200020054102746a2802002215470d00410021400c020b2005201420154b6a21050b20134200370300200242003703880841c785c200411220024188086a1008200c2013290300370300200220022903880837039805200241003602880820024198056a411020024188086a1006210602400240200228028808220a417f470d00410021150c010b024020060d00410021150c010b2002200a36028c08200220063602880820024188026a20024188086a106c024002402002280288020d00200228028c0221150c010b410021150b200a450d002006102a0b20152015418094ebdc036e22064180ec94a37c6c6aad4280fd87d1007e428094ebdc038021432005200e4b0d020240200e2011a7470d00200e41016a2215200e490d11200e410174220a20152015200a491b221541ffffffff03712015470d112015410274220a4100480d1102400240200e0d00200a102821000c010b2000200e410274200a102c21000b2000450d042015ad21110b200020054102746a221541046a2015200e20056b410274109b051a2015201436020041012140201142ffffffff0f83200e41016a2205ad2242422086842111200520064180fd87d1006c2043a76a4b212b0b20134200370300200242003703880841bd99c600411a20024188086a1008200c20132903003703002002200229038808370398050240024020000d0020024198056a411010090c010b200241003602900820024201370388082042a7221520024188086a10b4010240024020150d00200228029008210c200228028c08210e20022802880821150c010b410020022802900822056b2106200020154102746a211b200228028c08210e2000210a0340200a280200210d02400240200e20066a4104490d0020022802880821150c010b200541046a22152005490d13200e410174220c2015200c20154b1b220c4100480d1302400240200e0d00200c102821150c010b200228028808200e200c102c21150b2015450d072002200c36028c082002201536028808200c210e0b2002200541046a220c36029008201520056a200d3600002006417c6a2106200c2105201b200a41046a220a470d000b0b2011a7210520024198056a41102015200c10070240200e450d002015102a0b2005450d002000102a0b2040450d00200241023602b00f20022014ad3703b80f20024188086a200241b00f6a10c301203941086a221520132802003600002039200229038808370000203220022900b807370000203241076a200241b8076a41076a2206290000370000200241c6a4b9da0436008908200241023a00880820024188086a10ce012002201436028c082002410136028808200241003602b80f200242013703b00f410110282205450d04200220053602b00f200520022802b80f22146a41023a0000200241013602b40f2002201441016a22053602b80f200228028c08210a02400240410020146b4104490d0020022802b00f21140c010b200541046a22142005490d10410141017422052014200520144b1b22054100480d100240024041010d002005102821140c010b20022802b00f41012005102c21140b2014450d06200220053602b40f200220143602b00f20022802b80f21050b2002200541046a3602b80f201420056a200a360000200241d8066a41086a20022802b80f2205360200200220022903b00f22113703d8062015200536000020392011370000202220022900b807370000202241076a2006290000370000200241c28289aa043600b10f200241023a00b00f200241b00f6a10ce012002280288080d00200228029008450d00200228028c08102a0b02402012a7450d002037102a0b0240202b4102460d00202b410171450d00201342003703002002420037038808418e9dc600411020024188086a10082036201329030037030020022002290388083703b00f410110282205450d06200541013a0000200241b00f6a41102005410110072005102a0b202c2903002212201020342903002243200454201220105420122010511b22051b214d2043200420051b214e024002402049422088224fa722060d0042002110420021040c010b20064106742114201d41206a21054200211042002104034002400240200b2005460d002005200f4120109c050d010b427f2004200541706a221541086a2903007c201020152903007c22112010542215ad7c22102015201020045420102004511b22151b2104427f201120151b21100b200541c0006a2105201441406a22140d000b0b200241e8016a200f204e4200200f290330221120107d22422042201156200f41386a290300224220047d2011201054ad7d220420425620042042511b22051b22102010204e564200200420051b2204204d562004204d511b22051b2210204d200420051b220410cf01200241e8016a41086a290300215020022903e80121510240204e201020022903f80122527d22537d2254204d2004203a2903007d2010205254ad7d22557d204e205354ad7d225284500d00204320117d2210201220427d2043201154ad7d220484500d00200f2802482214450d00200f2802402205201441306c6a2115200241c8016a20542052428094ebdc03420010a005200241d8016a20102004428094ebdc03420010a005200241b8016a20022903c8012252200241c8016a41086a29030022564280ec94a37c427f109f05200241d8016a41086a2903002211420020022903d801224242015620114200522011501b22141b21122042420120141b2142205420022903b8017c21540340200241a8016a2010200529030022112011201056200541086a290300221120045620112004511b22141b2004201120141b2042201210a00520022903a8012243428080808010544100200241a8016a41086a290300501b450d0820024198016a201020042042201210a005200229039801221142808080801054410020024198016a41086a290300501b450d092011a7450d0a200241e8006a20522056204342ffffffff0f83428094ebdc037e201142ffffffff0f838042ffffffff0f8322114200109f05200241f8006a200541106a20022903682243201120547e428094ebdc038042ffffffff0f837c2211200241e8006a41086a2903002011204354ad7c10cf01427f2050200241f8006a41086a2903007c205120022903787c22432051542214ad7c22112014201120505420112050511b22141b2150427f204320141b2151200541306a22052015470d000b0b200241a8056a41186a2215200f41186a220a290300370300200241a8056a41106a220e200f41106a220c290300370300200241a8056a41086a220d200f41086a22002903003703002002200f2903003703a8050240024020062049a7460d00200621140c010b200641016a22052006490d0f204fa72214410174221b20052005201b491b220541ffffff1f712005470d0f2005410674221b4100480d0f0240024020060d00201b1028211d0c010b201d2014410674201b102c211d0b201d450d0a2005ad21490b200241d8006a20512050428094ebdc03420010a005200241c8006a20022903582204200241d8006a41086a29030022104280ec94a37c427f109f05200241386a20042010204c4200109f05201d20144106746a220520533703102005204d3703082005204e370300200541186a2055370300200520022903a805370320200541286a200d290300370300200541306a200e290300370300200541386a2015290300370300200241013a009008200241033a008808200a2900002104200c290000211020002900002111200f290000211220024188086a41386a204d37030020352012370000203541086a2011370000203541106a2010370000203541186a20043700002002204e3703b8084101410020024188086a10cc01204942ffffffff0f83201441016aad4220868421490240024020022903382210205120022903487c204c7e428094ebdc038042ffffffff0f837c2204200241386a41086a2903002004201054ad7c221084500d00200f41d8006a28020022050d010b427f204b20507c204a20517c2210204a542205ad7c220420052004204b542004204b511b22051b214b427f201020051b214a0c0b0b200241286a200420512051200456205020105620502010511b22141b22542010205020141b224d2005ad420010a00520054105742114200f2802502105200241286a41086a29030021522002290328215620542112204d21420340200241186a2005205620122012205656204220525620422052511b220f1b220420522042200f1b221010d00120024188086a41106a2010200241186a41086a29030022437d20042002290318221154ad7d204320107d2011200454ad7d201120045820432010582043201051220f1b22151b3703002002200420117d201120047d20151b37039008200220112004562043201056200f1b220fad37038808204220107d21102012200454ad211102400240200f0d00200220133602b00f200241b00f6a109d010c010b200220133602b00f200241b00f6a109c010b201020117d2142201220047d2112200541206a2105201441606a22140d000b427f427f204b20427c204a20127c2210204a542205ad7c220420052004204b542004204b511b22051b22042050204d7d2051205454ad7d7c427f201020051b2210205120547d7c22112010542205ad7c22102005201020045420102004511b22051b214b427f201120051b214a0c0a0b41f8b0c0001032000b200a41041037000b200c41011037000b410141011037000b200541011037000b410141011037000b10d101000b10d201000b41acaac3001032000b201b41081037000b200b41e0006a210b203041016a2230201f490d000b2049422088a7210f2049a7210e0b024002400240024002400240411710282205450d002005410f6a41002900d3fe44370000200541086a41002900ccfe44370000200541002900c4fe4437000020054117412e102c2205450d012005203b360017200241f8056a41186a22144200370300200241f8056a41106a22154200370300200241f8056a41086a22064200370300200242003703f8052005411b200241f8056a1000200241a8056a41186a2014290300370300200241a8056a41106a2015290300370300200241a8056a41086a2006290300370300200220022903f8053703a8052005102a20024100360290082002420137038808200f20024188086a10b401200f450d02200f410674210a201d21050340200541206a20024188086a108f01200541086a29030021042005290300211002400240200228028c08221420022802900822156b4110490d00200228028808210f0c010b201541106a220f2015490d0920144101742215200f2015200f4b1b22064100480d090240024020140d0020061028210f0c010b20022802880820142006102c210f0b200f450d052002200636028c082002200f360288082002280290082115200621140b200f20156a22062004370008200620103700002002201541106a221536029008200541186a2903002104200541106a290300211002400240201420156b410f4d0d00201421060c010b201541106a22062015490d09201441017422152006201520064b1b22064100480d090240024020140d0020061028210f0c010b200f20142006102c210f0b200f450d062002200636028c082002200f3602880820022802900821150b200541c0006a2105200f20156a22142004370008201420103700002002201541106a221436029008200a41406a220a0d000c060b0b411741011037000b412e41011037000b2002280290082114200228028c082106200228028808210f0c020b200641011037000b200641011037000b200241a8056a4120200f2014100702402006450d00200f102a0b0240200e450d00201d102a0b20024188086a10d301200241086a20024188086a204a204b10d001200241c00f6a204b200241086a41086a29030022107d204a2002290308220454ad7d2010204b7d2004204a54ad7d2004204a582010204b582010204b5122051b220f1b3703002002204a20047d2004204a7d200f1b3703b80f20022004204a562010204b5620051b2205ad3703b00f200241b00f6a41086a210f0240024020050d002002200f3602b807200241b8076a109d010c010b2002200f3602b807200241b8076a109c010b02402029450d002038102a0b02402009450d00200941e0006c210f200841d4006a210503400240200541706a280200450d002005416c6a280200102a0b02402005280200450d002005417c6a280200102a0b200541e0006a2105200f41a07f6a220f0d000b0b02402023450d002008102a0b20022802b80320022802bc0320022802c00310ca0120012802082114024020012802102205450d00200541d0006c210f201441c0006a210503400240200541046a280200450d002005280200102a0b200541d0006a2105200f41b07f6a220f0d000b0b2001410c6a280200450d002014102a0b20024190106a24000f0b1031000b8c1501037f0240024002400240024002400240024002400240024002400240024002400240024002400240200141046a280200200141086a2802002202460d00200128020021030c010b200241016a22032002490d11200241017422042003200420034b1b22044100480d110240024020020d002004102821030c010b200128020020022004102c21030b2003450d0120012003360200200141046a2004360200200141086a28020021020b200141086a2204200241016a360200200320026a20002d00003a000002400240200141046a28020020042802002202460d00200128020021030c010b200241016a22032002490d11200241017422042003200420034b1b22044100480d110240024020020d002004102821030c010b200128020020022004102c21030b2003450d0220012003360200200141046a2004360200200141086a28020021020b200141086a2204200241016a360200200320026a20002d00013a000002400240200141046a28020020042802002202460d00200128020021030c010b200241016a22032002490d11200241017422042003200420034b1b22044100480d110240024020020d002004102821030c010b200128020020022004102c21030b2003450d0320012003360200200141046a2004360200200141086a28020021020b200141086a2204200241016a360200200320026a20002d00023a000002400240200141046a28020020042802002202460d00200128020021030c010b200241016a22032002490d11200241017422042003200420034b1b22044100480d110240024020020d002004102821030c010b200128020020022004102c21030b2003450d0420012003360200200141046a2004360200200141086a28020021020b200141086a2204200241016a360200200320026a20002d00033a000002400240200141046a28020020042802002202460d00200128020021030c010b200241016a22032002490d11200241017422042003200420034b1b22044100480d110240024020020d002004102821030c010b200128020020022004102c21030b2003450d0520012003360200200141046a2004360200200141086a28020021020b200141086a2204200241016a360200200320026a20002d00043a000002400240200141046a28020020042802002202460d00200128020021030c010b200241016a22032002490d11200241017422042003200420034b1b22044100480d110240024020020d002004102821030c010b200128020020022004102c21030b2003450d0620012003360200200141046a2004360200200141086a28020021020b200141086a2204200241016a360200200320026a20002d00053a000002400240200141046a28020020042802002202460d00200128020021030c010b200241016a22032002490d11200241017422042003200420034b1b22044100480d110240024020020d002004102821030c010b200128020020022004102c21030b2003450d0720012003360200200141046a2004360200200141086a28020021020b200141086a2204200241016a360200200320026a20002d00063a000002400240200141046a28020020042802002202460d00200128020021030c010b200241016a22032002490d11200241017422042003200420034b1b22044100480d110240024020020d002004102821030c010b200128020020022004102c21030b2003450d0820012003360200200141046a2004360200200141086a28020021020b200141086a2204200241016a360200200320026a20002d00073a000002400240200141046a28020020042802002202460d00200128020021030c010b200241016a22032002490d11200241017422042003200420034b1b22044100480d110240024020020d002004102821030c010b200128020020022004102c21030b2003450d0920012003360200200141046a2004360200200141086a28020021020b200141086a2204200241016a360200200320026a20002d00083a000002400240200141046a28020020042802002202460d00200128020021030c010b200241016a22032002490d11200241017422042003200420034b1b22044100480d110240024020020d002004102821030c010b200128020020022004102c21030b2003450d0a20012003360200200141046a2004360200200141086a28020021020b200141086a2204200241016a360200200320026a20002d00093a000002400240200141046a28020020042802002202460d00200128020021030c010b200241016a22032002490d11200241017422042003200420034b1b22044100480d110240024020020d002004102821030c010b200128020020022004102c21030b2003450d0b20012003360200200141046a2004360200200141086a28020021020b200141086a2204200241016a360200200320026a20002d000a3a000002400240200141046a28020020042802002202460d00200128020021030c010b200241016a22032002490d11200241017422042003200420034b1b22044100480d110240024020020d002004102821030c010b200128020020022004102c21030b2003450d0c20012003360200200141046a2004360200200141086a28020021020b200141086a2204200241016a360200200320026a20002d000b3a000002400240200141046a28020020042802002202460d00200128020021030c010b200241016a22032002490d11200241017422042003200420034b1b22044100480d110240024020020d002004102821030c010b200128020020022004102c21030b2003450d0d20012003360200200141046a2004360200200141086a28020021020b200141086a2204200241016a360200200320026a20002d000c3a000002400240200141046a28020020042802002202460d00200128020021030c010b200241016a22032002490d11200241017422042003200420034b1b22044100480d110240024020020d002004102821030c010b200128020020022004102c21030b2003450d0e20012003360200200141046a2004360200200141086a28020021020b200141086a2204200241016a360200200320026a20002d000d3a000002400240200141046a28020020042802002202460d00200128020021030c010b200241016a22032002490d11200241017422042003200420034b1b22044100480d110240024020020d002004102821030c010b200128020020022004102c21030b2003450d0f20012003360200200141046a2004360200200141086a28020021020b200141086a2204200241016a360200200320026a20002d000e3a000002400240200141046a28020020042802002202460d00200128020021030c010b200241016a22032002490d11200241017422042003200420034b1b22044100480d110240024020020d002004102821030c010b200128020020022004102c21030b2003450d1020012003360200200141046a2004360200200141086a28020021020b200141086a200241016a360200200320026a20002d000f3a00000f0b200441011037000b200441011037000b200441011037000b200441011037000b200441011037000b200441011037000b200441011037000b200441011037000b200441011037000b200441011037000b200441011037000b200441011037000b200441011037000b200441011037000b200441011037000b200441011037000b1031000bba0601087f230041d0006b220224000240024002400240024002400240411f10282203450d00200341176a41002900c9c740370000200341106a41002900c2c740370000200341086a41002900bac740370000200341002900b2c7403700002002429f808080f0033702242002200336022041a2c7c000200241206a10c6012002280228210420022802202103200241306a41186a22054200370300200241306a41106a22064200370300200241306a41086a220742003703002002420037033020032004200241306a1000200241186a2005290300370300200241106a2006290300370300200241086a20072903003703002002200229033037030002402002280224450d002003102a0b412010282203450d0120032002290300370000200341186a200241186a290300370000200341106a200241106a290300370000200341086a200241086a2903003700002001280208220441046a2205417f4c0d02200128020021070240024020050d00410121010c010b200510282201450d040b2002410036023820022005360234200220013602302004200241306a10b4010240024020022802342206200228023822016b2004490d00200228023021050c010b200120046a22052001490d06200641017422082005200820054b1b22084100480d060240024020060d002008102821050c010b200228023020062008102c21050b2005450d052002200836023420022005360230200821060b200520016a20072004109a051a200241306a41186a22074200370300200241306a41106a22084200370300200241306a41086a22094200370300200242003703302005200120046a200241306a1000200241186a2007290300370300200241106a2008290300370300200241086a20092903003703002002200229033037030002402006450d002005102a0b2003412041c000102c2203450d0620032002290300370020200341386a200241186a290300370000200341306a200241106a290300370000200341286a200241086a290300370000200042c0808080800837020420002003360200200241d0006a24000f0b411f41011037000b412041011037000b1036000b200541011037000b200841011037000b1031000b41c00041011037000bba0501037f02400240024002400240024002400240410110282202450d00200220002d00003a0000200241014102102c2202450d01200220002d00013a0001200241024104102c2202450d02200220002d00023a0002200220002d00033a0003200241044108102c2202450d03200220002d00043a0004200220002d00053a0005200220002d00063a0006200220002d00073a0007200241084110102c2202450d04200220002d00083a0008200220002d00093a0009200220002d000a3a000a200220002d000b3a000b200220002d000c3a000c200220002d000d3a000d200220002d000e3a000e200220002d000f3a000f200241104120102c2202450d05200220002d00103a0010200220002d00113a0011200220002d00123a0012200220002d00133a0013200220002d00143a0014200220002d00153a0015200220002d00163a0016200220002d00173a0017200220002d00183a0018200220002d00193a0019200220002d001a3a001a200220002d001b3a001b200220002d001c3a001c200220002d001d3a001d200220002d001e3a001e200220002d001f3a001f024002402001280200220041046a2802002203200041086a28020022016b4120490d00200028020021030c010b200141206a22042001490d08200341017422012004200120044b1b22014100480d080240024020030d002001102821030c010b200028020020032001102c21030b2003450d0720002003360200200041046a2001360200200041086a28020021010b200041086a200141206a360200200320016a220041186a200241186a290000370000200041106a200241106a290000370000200041086a200241086a290000370000200020022900003700002002102a0f0b410141011037000b410241011037000b410441011037000b410841011037000b411041011037000b412041011037000b200141011037000b1031000b9705060a7f047e037f027e047f027e200128020821032001280204210420012802002105200241386a2106200241286a2107034002400240200441f8b9c000462208450d00410021094108210a4108210b0c010b20042f01062109200441086a220a210b0b200b200941d0006c6a210c2006290300210d2007290300210e2002290330210f2002290320211020022802482111200228024021124100210b0240024002400340200b21090240200a200c470d0002402008450d00410021090c030b20042f010621090c020b024002402002200a4120109c05220b450d00417f4101200b4100481b21130c010b417f2010200a290320221485200e200a41286a290300221585844200522010201454200e201554200e2015511b1b22130d00417f200f200a41306a290300221485200d200a41386a29030022158584420052200f201454200d201554200d2015511b1b22130d00200a41c8006a28020022162011201120164b1b2117200a280240210b417f21182012211903400240201841016a22182017490d00417f201120164720112016491b21130c020b0240201941106a200b41106a4120109c052213450d00417f410120134100481b21130c020b2019290300221a200b290300221b54201941086a2903002215200b41086a29030022145420152014511b0d03200b41306a210b201941306a211941012113201a201b85201520148584500d000b0b200941016a210b200a41d0006a210a0240201341016a0e03020001020b0b4100210a0c010b20050d014101210a410021050b200020053602042000200a360200200041106a20093602002000410c6a2003360200200041086a20043602000f0b2001200336020820012005417f6a22053602002001200420094102746a41f8066a28020022043602040c000b0bee0303047f017e017f02402001450d00034020002802f80621002001417f6a22010d000b0b02402002450d004100210341002101034002400240200120002f01064f0d004108200041086a200041f8b9c000461b200141d0006c6a22042802442105200441c0006a2802002106200141016a21010c010b02400240200028020022010d002003ad210741002104410021010c010b20003301044220862003ad842107410121040b2000102a2007a72103024002402007422088a7220820012f01064f0d00200121000c010b034002400240200128020022000d002003ad2107410021000c010b200441016a210420013301044220862003ad8421070b2001102a2007a72103200021012007422088a7220820002f01064f0d000b0b4108200041086a200041f8b9c000461b200841d0006c6a22012802442105200141c0006a2802002106200841027420006a41fc066a280200210002402004417f6a2201450d00034020002802f80621002001417f6a22010d000b0b410021010b2006450d012002417f6a210202402005450d002006102a0b20020d000b0b0240200041f8b9c000460d00200028020021012000102a2001450d00200128020021002001102a2000450d00024020002802002201450d0003402000102a2001210020012802002203210120030d000b0b2000102a0b0b9d0201057f230041106b220324000240024002400240200141046a2204417f4c0d000240024020040d00410121050c010b200410282205450d020b2003410036020820032004360204200320053602002001200310b4010240024020032802042206200328020822056b2001490d00200328020021040c010b200520016a22042005490d04200641017422072004200720044b1b22074100480d040240024020060d002007102821040c010b200328020020062007102c21040b2004450d032003200736020420032004360200200721060b200420056a20002001109a051a200228020020022802042004200520016a100702402006450d002004102a0b200341106a24000f0b1036000b200441011037000b200741011037000b1031000bcd1f03087f047e017f230041a0036b2203240020034100360288014188e8c200411020034188016a10062104024002402003280288012205417f460d002004450d00024020054104490d00200428000021062004102a410021070c020b41c4d1c300413320034188016a419cd9c3001038000b410121070b0240024002400240024002400240024002400240024020010d004101210841002105410021090c010b200141057422044100480d07200410282208450d012001410574220941606a410576210a2008210420002105034020034188016a41186a200541186a290000220b37030020034188016a41106a200541106a290000220c37030020034188016a41086a200541086a290000220d37030020032005290000220e37038801200441186a200b370000200441106a200c370000200441086a200d3700002004200e370000200441206a2104200541206a2105200941606a22090d000b200a41016a2109200121050b200341f4006a2006360200200320073602702003200241f000109a0522044180016a2009360200200441fc006a20053602002004200836027820044190026a41086a22054200370300200442003703900241eea0c600411120044190026a1008200441b0026a41086a200529030037030020042004290390023703b0022004410036028801200441b0026a411020044188016a10062105024002400240024002400240024002402004280288012203417f470d00410021080c010b024020050d00410021080c010b20034104490d01200528000021082005102a0b0240200841016a22032008490d0020044190026a41086a22054200370300200442003703900241eea0c600411120044190026a1008200441b0026a41086a2209200529030037030020042004290390023703b0022004200336028801200441b0026a411020044188016a4104100720044188016a2004418801109a051a20054200370300200442003703900241d4f2c200410d20044190026a10082009200529030037030020042004290390023703b0022004410036029002200441b0026a411020044190026a10062103024002402004280290022205417f460d002005210920030d010b2004410036028003200442083703f80220044100360298022004420137039002410020044190026a10b401200428029802210520042802940221092004280290022103200441f8026a10720b200420053602c802200420093602c402200420033602c002024002402005450d0020044190026a20032005410110d6022004280290024101470d0120042802c402450d0c20042802c002102a0c0c0b4101200441c0026a10b40120044188016a200441c0026a10aa030c090b200428029402210202402004419c026a280200220520044198026a2802002203460d0020042802c802200520036b6a22094188016a2207417f4c0d100240024020070d00410121060c010b200710282206450d040b200420073602d402200420063602d002200420093602d8022004200441d0026a36029002200220044190026a200510d70120092005490d0420042802d80222022009490d0520042802c80222022003490d0620042802d002210720042802c00221062004200920056b22093602dc022004200220036b22023602940320092002470d07200720056a200620036a2009109a051a20044188016a200441d0026a10aa0320042802d802210320042802d402210920042802d002210520042802c402450d0a20042802c002102a0c0a0b2004200441c0026a36029002200220044190026a200310d70120044188016a200441c0026a10aa030c080b200410ab030c0b0b41c4d1c300413320044188016a419cd9c3001038000b200741011037000b200520091044000b20092002103c000b200320021044000b200441f8026a41146a410836020020044184036a4125360200200441e0026a41146a4103360200200442033702e402200441c8afc6003602e002200441253602fc022004200441dc026a36029803200420044194036a36029c03200442043703a00220044201370294022004419cb0c600360290022004200441f8026a3602f002200420044190026a3602880320042004419c036a36028003200420044198036a3602f802200441e0026a41d8b0c600103e000b200441011037000b20042802c802210320042802c402210920042802c00221050b20050d010b20044188016a10ab030c010b200441b0026a411020052003100702402009450d002005102a0b20044188016a10ab0320044190026a41086a22054200370300200442003703900241d9efc200410d20044190026a1008200441b0026a41086a200529030037030020042004290390023703b0024100210f2004410036028801200441b0026a411020044188016a1006210502402004280288012203417f460d002005450d0020034104490d032005280000210f2005102a0b2001450d002001410574210a02400340200420083602d4022004200f3602d0020240024002400240024002400240024002400240024002400240024002400240411210282205450d00200541106a41002f00f1f2423b0000200541086a41002900e9f242370000200541002900e1f24237000020044188016a41186a2203420037030020044188016a41106a2209420037030020044188016a41086a2201420037030020044200370388012005411220044188016a100020044190026a41186a2202200329030037030020044190026a41106a2207200929030037030020044190026a41086a220620012903003703002004200429038801370390022005102a412010282205450d012005200429039002370000200541186a2002290300370000200541106a2007290300370000200541086a200629030037000020044188016a200010e0022005412041c000102c2205450d022005200429008801370020200541386a2003290000370000200541306a2009290000370000200541286a20012900003700002004410036028801200541c00020044188016a10062109024002402004280288012201417f460d00200121030c010b20044100360290012004420137038801410020044188016a10b4012004280290012103200428028c01210120042802880121090b200420033602b802200420013602b402200420093602b002024002400240024002402003450d0020044188016a20092003410110d6022004280288014101460d04200428028c01210220042802940122032004280290012209460d0320042802b802200320096b6a220141086a2207417f4c0d1a20070d01410121060c020b4101200441b0026a10b40120042802d00221010240024020042802b402220920042802b80222036b4104490d0020042802b00221090c010b200341046a22022003490d18200941017422032002200320024b1b22034100480d180240024020090d002003102821090c010b20042802b00220092003102c21090b2009450d08200420033602b402200420093602b00220042802b80221030b2004200341046a3602b802200920036a200136000020042802d40221010240024020042802b402220920042802b80222036b4104490d0020042802b00221090c010b200341046a22022003490d18200941017422032002200320024b1b22034100480d180240024020090d002003102821090c010b20042802b00220092003102c21090b2009450d09200420033602b402200420093602b00220042802b80221030b2004200341046a3602b802200920036a20013600000c120b200710282206450d080b200420073602e402200420063602e002200420013602e8022004200441e0026a36028801200220044188016a200310d70120012003490d0820042802e80222022001490d0920042802b80222022009490d0a20042802e002210720042802b00221062004200120036b2201360294032004200220096b22023602980320012002470d0b200720036a200620096a2001109a051a20042802d00221010240024020042802e402220920042802e80222036b4104490d0020042802e00221090c010b200341046a22022003490d16200941017422032002200320024b1b22034100480d160240024020090d002003102821090c010b20042802e00220092003102c21090b2009450d0d200420033602e402200420093602e00220042802e80221030b2004200341046a3602e802200920036a200136000020042802d40221010240024020042802e402220920042802e80222036b4104490d0020042802e00221090c010b200341046a22022003490d16200941017422032002200320024b1b22034100480d160240024020090d002003102821090c010b20042802e00220092003102c21090b2009450d0e200420033602e402200420093602e00220042802e80221030b2004200341046a3602e802200920036a200136000020042802e802210920042802e402210120042802e002210320042802b402450d1120042802b002102a0c110b2004200441b0026a36028801200220044188016a200910d70120042802d00221010240024020042802b402220920042802b80222036b4104490d0020042802b00221090c010b200341046a22022003490d15200941017422032002200320024b1b22034100480d150240024020090d002003102821090c010b20042802b00220092003102c21090b2009450d0e200420033602b402200420093602b00220042802b80221030b2004200341046a3602b802200920036a200136000020042802d40221010240024020042802b402220920042802b80222036b4104490d0020042802b00221090c010b200341046a22022003490d15200941017422032002200320024b1b22034100480d150240024020090d002003102821090c010b20042802b00220092003102c21090b2009450d0f200420033602b402200420093602b00220042802b80221030b2004200341046a3602b802200920036a20013600000c0f0b20042802b402450d1120042802b002102a0c110b411241011037000b412041011037000b41c00041011037000b200341011037000b200341011037000b200741011037000b200320011044000b20012002103c000b200920021044000b200441f8026a41146a410836020020044184036a412536020020044190026a41146a41033602002004420337029402200441c8afc60036029002200441253602fc02200420044194036a36029c03200420044198036a3602c00220044204370398012004420137028c012004419cb0c600360288012004200441f8026a3602a002200420044188016a360288032004200441c0026a3602800320042004419c036a3602f80220044190026a41d8b0c600103e000b200341011037000b200341011037000b200341011037000b200341011037000b20042802b802210920042802b402210120042802b00221030b2003450d01200541c00020032009100702402001450d002003102a0b200041206a21002005102a200a41606a220a0d000c020b0b2005102a0b200441a0036a24000f0b1031000b41c4d1c300413320044188016a419cd9c3001038000b1036000bcd0101047f200020014105746a210320002104024003400240200320046b41e0004b0d00024020042003460d00200020014105746a210503404101210620022004460d04200420024120109c05450d042005200441206a2204470d000b0b41000f0b4101210620042002460d01200420024120109c05450d01200441206a22052002460d01200520024120109c05450d01200441c0006a22052002460d01200520024120109c05450d01200441e0006a22052002460d0120044180016a2104200520024120109c050d000b0b20060bba0604017f017e047f027e230041c0006b2201240042002102200141186a41086a220342003703002001420037031841b1f0c200410d200141186a1008200141086a200329030037030020012001290318370300410021032001410036021820014110200141186a100621040240024002400240024020012802182205417f460d002001200536021420012004360210200141186a200141106a107620012802182206450d02200129021c210202402005450d002004102a0b2002422088a721032002a721050c010b41042106410021050b200141186a41206a200041206a280200360200200141186a41186a200041186a290200370300200141186a41106a200041106a290200370300200141186a41086a200041086a29020037030020012000290200370318024020032005470d00024020032002a7470d00200341016a22002003490d04200341017422052000200520004b1bad220742247e2208422088a70d042008a722004100480d040240024020030d002000102821060c010b2006200341246c2000102c21060b2006450d0320024280808080708320078421020b2002422088a721030b2006200341246c22056a22002001290318370200200041206a200141186a41206a280200360200200041186a200141186a41186a290300370200200041106a200141186a41106a290300370200200041086a200141186a41086a2200290300370200200042003703002001420037031841b1f0c200410d200141186a1008200141086a2000290300370300200120012903183703002001411036021c200120013602182006200341016a2200200141186a10e102024020002003490d00200541246a21002006210303400240024020032d0000220541034b0d0002400240024020050e0404000102040b2003410c6a280200450d03200341086a280200102a0c030b2003410c6a280200450d02200341086a280200102a0c020b2003410c6a280200450d01200341086a280200102a0c010b200341086a280200450d00200341046a280200102a0b200341246a21032000415c6a22000d000b0b02402002a7450d002006102a0b200141c0006a24000f0b41c4d1c3004133200141186a419cd9c3001038000b200041041037000b1031000b8c0702067f067e230041d0006b220424000240024002400240411410282205450d00200541002900cfe140370000200541106a41002800dfe140360000200541086a41002900d7e14037000020044294808080c002370224200420053602202001200441206a108f012004280228210520042802202106200441306a41186a22074200370300200441306a41106a22084200370300200441306a41086a220942003703002004420037033020062005200441306a1000200441186a2007290300370300200441106a2008290300370300200441086a20092903003703002004200429033037030002402004280224450d002004280220102a0b2004410036023020044120200441306a100621050240024020042802302206417f470d004200210a4200210b0c010b20064110490d02200541086a290000210b2005290000210a2005102a0b2001200a2002200a200a200256200b200356200b2003511b22051b220c7d200b2003200b20051b220d7d200a200c54ad7d108f02024002402002200c7d220b2003200d7d2002200c54ad7d220e8450450d004200210a4200210e0c010b411810282205450d03200541002900e3e140370000200541106a41002900f3e140370000200541086a41002900ebe140370000200442988080808003370224200420053602202001200441206a108f012004280228210520042802202106200441306a41186a22074200370300200441306a41106a22084200370300200441306a41086a220942003703002004420037033020062005200441306a1000200441186a2007290300370300200441106a2008290300370300200441086a20092903003703002004200429033037030002402004280224450d002004280220102a0b2004410036023020044120200441306a100621050240024020042802302206417f470d0042002102420021030c010b20064110490d05200541086a2900002103200529000021022005102a0b20012002200b20022002200b562003200e562003200e511b22051b220a7d2003200e200320051b220f7d2002200a54ad7d109002200e200f7d200b200a54ad7d210e200f200d7c200a200c7c2202200a54ad7c2103200b200a7d210a0b2000200a37031020002002370300200041186a200e37030020002003370308200441d0006a24000f0b411441011037000b41c4d1c3004133200441306a419cd9c3001038000b411841011037000b41c4d1c3004133200441306a419cd9c3001038000be20302067f027e230041d0006b2204240002400240411410282205450d00200541002900cfe140370000200541106a41002800dfe140360000200541086a41002900d7e14037000020044294808080c002370224200420053602202001200441206a108f012004280228210520042802202106200441306a41186a22074200370300200441306a41106a22084200370300200441306a41086a220942003703002004420037033020062005200441306a1000200441186a2007290300370300200441106a2008290300370300200441086a20092903003703002004200429033037030002402004280224450d002004280220102a0b2004410036023020044120200441306a100621050240024020042802302206417f470d004200210a4200210b0c010b20064110490d02200541086a290000210b2005290000210a2005102a0b200441306a2001200a20027c2202200b20037c2002200a54ad7c109401200441106a200441306a41106a290300220a370300200420042903382202370308200420042903302203370300024020034200510d002004200441086a360230200441306a109d01420021024200210a0b200020023703002000200a370308200441d0006a24000f0b411441011037000b41c4d1c3004133200441306a419cd9c3001038000b0a0041a8acc3001032000b0a0041b8abc3001032000bbf0301077f230041d0006b22012400024002400240024002400240410110282202450d00200241ed003a0000200241014102102c2202450d01200241ef003a0001200241024104102c2202450d02200241e4d8013b0002200241044108102c2202450d03200241f0f2bda107360004200241084110102c2203450d04200341f2e6c9cb07360008200141003a0048410c210220032104410021050340200141003a0008200141086a200420024100472206109a051a024020020d00200141003a00080b20022006490d06200141286a20056a20012d00083a00002001200541016a22073a0048200220066b2102200420066a21042007210520074120470d000b200141086a41186a2202200141286a41186a290300370300200141086a41106a2206200141286a41106a290300370300200141086a41086a2204200141286a41086a290300370300200120012903283703082003102a200041186a2002290300370000200041106a2006290300370000200041086a200429030037000020002001290308370000200141d0006a24000f0b410141011037000b410241011037000b410441011037000b410841011037000b411041011037000b200620021044000b940705017f047e087f057e017f23004180026b22022400200241c0006a2001109f01024002402002290340a7450d00200041003602200c010b200241c0006a41106a290300210320022903482104200241286a2001109f0102402002290328a7450d00200041003602200c010b200241286a41106a290300210520022903302106200241206a2001106c0240024002400240024020022802200d00200128020441306e220741306c2208417f4c0d02200228022421090240024020080d004108210a0c010b20081028220a450d040b02402009450d004100210b0340200241003a00f801200b220c41016a210b2001280204417f6a21084100210d024002400240024003402008417f460d01200241d8016a200d6a2001280200220e2d00003a0000200120083602042001200e41016a3602002002200d41016a220e3a00f8012008417f6a2108200e210d200e4120470d000b200241b8016a41186a2208200241d8016a41186a290300370300200241b8016a41106a220d200241d8016a41106a290300370300200241b8016a41086a220e200241d8016a41086a290300370300200220022903d8013703b801200241086a2001109f012002290308a70d01200241086a41106a290300210f20022903102110200241f8006a41086a200e2903002211370300200241f8006a41106a200d2903002212370300200241f8006a41186a20082903002213370300200241d8006a41086a220d2011370300200241d8006a41106a220e2012370300200241d8006a41186a22142013370300200220022903b8012211370378200220113703582007200c470d030240200c4101742208200b2008200b4b1b2207ad42307e2211422088a70d002011a7220841004e0d030b1031000b200d41ff0171450d00200241003a00f8010b200241f8006a41086a20024198016a41086a2903003703002007450d04200a102a0c040b02400240200c0d0020081028210a0c010b200a200c41306c2008102c210a0b200a450d070b200a200c41306c6a2208200f3703082008201037030020082002290358370310200841186a200d290300370300200841206a200e290300370300200841286a2014290300370300200b2009470d000b0b200a0d010b200041003602200c040b20002004370300200020073602242000200a3602202000200637031020002003370308200041286a2009360200200041186a20053703000c030b1036000b200841081037000b200841081037000b20024180026a24000b0a0041f0b8c0001032000b4d01017f230041206b22002400200041146a410136020020004201370204200041ccd1c5003602002000410436021c200041c4d1c5003602182000200041186a360210200041ccb9c000103e000b8d0301027f230041e0006b22032400200341003a0005024002402000413f4b0d0041012104200341013a0005200320004102743a00000c010b02400240200041808001490d0020004180808080044f0d0141042104200341043a0005200320004102744102723602000c020b41022104200341023a0005200320004102744101723b01000c010b41052104200341053a0005200341033a0000200320003600010b024002402001280200220028020822012002490d0020002802002100200320023602082003200436020c20042002470d01200020032002109a051a200341e0006a24000f0b20022001103c000b200341286a41146a4108360200200341346a4125360200200341106a41146a410336020020034203370214200341c8afc6003602102003412536022c2003200341086a36024020032003410c6a360244200342043703582003420137024c2003419cb0c6003602482003200341286a3602202003200341c8006a3602382003200341c4006a3602302003200341c0006a360228200341106a41d8b0c600103e000bb60201037f23004180016b220224002000280200210002400240024002400240200128020022034110710d002000280200210420034120710d012004ad41012001103f21000c020b20002802002104410021000340200220006a41ff006a2004410f712203413072200341d7006a2003410a491b3a00002000417f6a2100200441047622040d000b20004180016a22044181014f0d0220014101419087c0004102200220006a4180016a410020006b104221000c010b410021000340200220006a41ff006a2004410f712203413072200341376a2003410a491b3a00002000417f6a2100200441047622040d000b20004180016a22044181014f0d0220014101419087c0004102200220006a4180016a410020006b104221000b20024180016a240020000f0b20044180011044000b20044180011044000b130020004102360204200041cc9dc6003602000b130020004101360204200041b8a8c3003602000b130020004103360204200041a8dcc0003602000b130020004103360204200041bcaac4003602000b130020004101360204200041d899c6003602000b13002000410b3602042000418082c5003602000b13002000410636020420004198e8c2003602000b130020004104360204200041d09ec1003602000b130020004105360204200041f8aec3003602000b130020004103360204200041ec91c6003602000b130020004105360204200041ac81c2003602000b130020004106360204200041f8d1c3003602000b130020004103360204200041a896c4003602000b13002000410136020420004190e0c0003602000b130020004101360204200041f896c6003602000b8b0701077f23004190026b2202240041002103200241003a002820012802042104417f210502400240034020042003460d01200241086a20036a200128020022062d00003a00002001200420056a3602042001200641016a3602002002200341016a22073a00282005417f6a21052007210320074120470d000b200241e8006a41086a200241086a41086a290300370300200241e8006a41106a200241086a41106a290300370300200241e8006a41186a200241086a41186a2903003703002002200229030837036841002103200241003a0028200420076b2108200420056a21050340024020082003470d000240200341ff0171450d00200241003a00280b200041013a00000c030b200241086a20036a200620036a220741016a2d00003a0000200120053602042001200741026a3602002002200341016a22073a00282005417f6a21052007210320074120470d000b20024188016a41086a200241086a41086a29030037030020024188016a41106a200241086a41106a29030037030020024188016a41186a200241086a41186a290300370300200220022903083703880141002103200241003a008802200620076a2106034002402005417f470d000240200341ff0171450d00200241003a0088020b200041013a00000c030b200241e8016a20036a200620036a220741016a2d00003a0000200120053602042001200741026a3602002002200341016a22073a0088022005417f6a21052007210320074120470d000b200241a8016a41086a2201200241e8016a41086a290300370300200241a8016a41106a2203200241e8016a41106a290300370300200241a8016a41186a2205200241e8016a41186a290300370300200241086a41086a200241e8006a41086a290300370300200241086a41106a200241e8006a41106a290300370300200241086a41186a200241e8006a41186a290300370300200220022903e8013703a80120022002290368370308200241c0006a20024188016a41186a290300370300200241386a20024188016a41106a290300370300200241306a20024188016a41086a2903003703002002200229038801370328200241e0006a2005290300370300200241d8006a2003290300370300200241d0006a2001290300370300200220022903a801370348200041016a200241086a41e000109a051a200041003a00000c010b0240200341ff0171450d00200241003a00280b200041013a00000b20024190026a24000bf90802067f047e230041d0026b220224000240024002400240024002400240024002400240024020012802042203450d00200128020022042d0000210520012003417f6a3602042001200441016a360200200541034b0d0620050e0401020304010b200041053a00000c090b200241206a2001106d20022802200d03200041053a00000c080b200241c0006a20011081010240024020022802404113460d00200241c8016a200241c0006a418801109a051a418801102822050d0141880141081037000b200041053a00000c080b2005200241c8016a418801109a052105200041023a0000200020022f00103b0001200041036a200241106a41026a2d00003a0000200041046a2005360200200041086a2002290220370200200041106a200241206a41086a290200370200200041186a200241206a41106a290200370200200041206a200241206a41186a2902003702000c070b20022001106c20022802000d0520022802042105200241c0006a200110810120022802404113460d05200241c8016a200241c0006a418801109a051a41880110282201450d032001200241c8016a418801109a052101200041033a0000200020022f00103b0001200041036a200241126a2d00003a0000200041086a2001360200200041046a20053602002000410c6a2002290220370200200041146a200241206a41086a2902003702002000411c6a200241306a290200370200200041246a200241386a2802003602000c060b41002105200241003a00e8012003417f6a21062003417e6a21030340024020062005470d00200541ff0171450d05200241003a00e8010c050b200241c8016a20056a200420056a220741016a2d00003a0000200120033602042001200741026a3602002002200541016a22073a00e8012003417f6a21032007210520074120470d000b200241c0006a41186a200241c8016a41186a290300370300200241c0006a41106a200241c8016a41106a290300370300200241c0006a41086a200241c8016a41086a290300370300200220022903c801370340200241086a2001106c20022802080d0320012802042205450d03200228020c2103200128020022072d0000210420012005417f6a3602042001200741016a360200200241206a41086a200241c0006a41086a2903002208370300200241206a41106a200241c0006a41106a2903002209370300200241206a41186a200241c0006a41186a290300220a37030020022002290340220b370320200041043a00002000200b370001200041096a2008370000200041116a2009370000200041196a200a370000200041246a2003360200200041216a20043a00000c050b200241cb006a200241206a41086a28020036000020022002290320370043200041013a000020002002290040370001200041086a200241c7006a290000370000200041106a20022902c801370200200041186a200241c8016a41086a290200370200200041206a200241c8016a41106a2902003702000c040b200041053a00000c030b41880141081037000b200041053a00000c010b200041053a00000b200241d0026a24000bd50603057f0b7e057f230041106b21020240200128020422034104490d0020012802002204280000210520012003417c6a22063602042001200441046a36020020064108490d00200429000421072001200341746a220636020420012004410c6a36020020064108490d00200429000c210820012003416c6a22063602042001200441146a36020020064108490d00200429001421092001200341646a220636020420012004411c6a36020020064108490d00200429001c210a20012003415c6a22063602042001200441246a36020020064108490d002004290024210b2001200341546a220636020420012004412c6a36020020064108490d00200429002c210c20012003414c6a22063602042001200441346a36020020064108490d002004290034210d2001200341446a220636020420012004413c6a36020020064108490d00200429003c210e2001200341bc7f6a22063602042001200441c4006a36020020064108490d002004290044210f2001200341b47f6a22063602042001200441cc006a36020020064108490d00200429004c21102001200341ac7f6a22063602042001200441d4006a36020020064108490d00200429005421112001200341a47f6a22063602042001200441dc006a36020020064104490d00200428005c21122001200341a07f6a22063602042001200441e0006a36020020064104490d002004280060211320012003419c7f6a22063602042001200441e4006a36020020064104490d00200428006421142001200341987f6a22063602042001200441e8006a36020020064104490d00200428006821152001200341947f6a22063602042001200441ec006a22043602002006450d0020042d000021162001200341937f6a22063602042001200441016a36020020064104490d00200020163a00702000201536026820002014360264200020133602602000201236025c2000200536025820002011370350200020103703482000200f3703402000200e3703382000200d3703302000200c3703282000200b3703202000200a3703182000200937031020002008370308200020073703002004280001210620012003418f7f6a3602042001200441056a3602002000200636026c200041f4006a2002410c6a280000360000200020022800093600710f0b200041023a00700bfb910205057f017e067f017e017f230041206b2202240002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002402000280200220341144b0d00024002400240024002400240024002400240024002400240024002400240024002400240024002400240024020030e15000102030405060708090a0b0c0d0e0f1011121314000b02400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490d62200341017422052004200520044b1b22054100480d620240024020030d002005102821040c010b200128020020032005102c21040b2004450d1720012004360200200141046a2005360200200141086a28020021030b200141086a200341016a360200200420036a41003a00002000280208417f6a220341054b0d1502400240024002400240024020030e06000102030405000b200241003a001802400240200141046a280200200141086a2802002203460d00200128020021000c010b200341016a22002003490d67200341017422042000200420004b1b22044100480d670240024020030d002004102821000c010b200128020020032004102c21000b2000450d1d20012000360200200141046a2004360200200141086a28020021030b200141086a200341016a360200200020036a41003a00000c1a0b200241013a001802400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490d66200341017422052004200520044b1b22054100480d660240024020030d002005102821040c010b200128020020032005102c21040b2004450d1d20012004360200200141046a2005360200200141086a28020021030b200141086a2205200341016a360200200420036a41013a0000200028020c2106200041146a2802002203200110b40102400240200141046a2802002204200528020022006b2003490d00200128020021040c010b200020036a22052000490d66200441017422002005200020054b1b22004100480d660240024020040d002000102821040c010b200128020020042000102c21040b2004450d1e20012004360200200141046a2000360200200141086a28020021000b200141086a200020036a360200200420006a20062003109a051a0c190b200241023a001802400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490d65200341017422052004200520044b1b22054100480d650240024020030d002005102821040c010b200128020020032005102c21040b2004450d1e20012004360200200141046a2005360200200141086a28020021030b200141086a2205200341016a360200200420036a41023a00002000290310210702400240200141046a2802002200200528020022036b4108490d00200128020021000c010b200341086a22042003490d65200041017422032004200320044b1b22034100480d650240024020000d002003102821000c010b200128020020002003102c21000b2000450d1f20012000360200200141046a2003360200200141086a28020021030b200141086a200341086a360200200020036a20073700000c180b200241033a001802400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490d64200341017422052004200520044b1b22054100480d640240024020030d002005102821040c010b200128020020032005102c21040b2004450d1f20012004360200200141046a2005360200200141086a28020021030b200141086a2205200341016a360200200420036a41033a0000200028020c2106200041146a2802002203200110b40102400240200141046a2802002204200528020022006b2003490d00200128020021040c010b200020036a22052000490d64200441017422002005200020054b1b22004100480d640240024020040d002000102821040c010b200128020020042000102c21040b2004450d2020012004360200200141046a2000360200200141086a28020021000b200141086a200020036a360200200420006a20062003109a051a0c170b200141086a2802002103200241043a0018024002402003200141046a280200460d00200128020021050c010b200341016a22042003490d63200341017422052004200520044b1b22044100480d630240024020030d002004102821050c010b200128020020032004102c21050b2005450d2020012005360200200141046a2004360200200141086a28020021030b200141086a2204200341016a360200200520036a41043a0000200028020c2103200041146a2802002200200110b4012000450d162003200041186c6a2108200141046a2106034020032802002109200341086a2802002200200110b401024002402006280200220a200428020022056b2000490d002001280200210a0c010b200520006a220b2005490d64200a4101742205200b2005200b4b1b22054100480d6402400240200a0d0020051028210a0c010b2001280200200a2005102c210a0b200a450d222001200a36020020062005360200200428020021050b2004200520006a360200200a20056a20092000109a051a2003410c6a2802002109200341146a2802002200200110b401024002402006280200220a200428020022056b2000490d002001280200210a0c010b200520006a220b2005490d64200a4101742205200b2005200b4b1b22054100480d6402400240200a0d0020051028210a0c010b2001280200200a2005102c210a0b200a450d232001200a36020020062005360200200428020021050b2004200520006a360200200a20056a20092000109a051a200341186a22032008470d000c170b0b200241053a001802400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490d62200341017422052004200520044b1b22054100480d620240024020030d002005102821040c010b200128020020032005102c21040b2004450d2220012004360200200141046a2005360200200141086a28020021030b200141086a2206200341016a360200200420036a41053a0000200028020c2104200041146a2802002203200110b4012003450d1520042003410c6c6a2108200141046a210903402004280200210a200441086a2802002203200110b4010240024020092802002205200628020022006b2003490d00200128020021050c010b200020036a220b2000490d6320054101742200200b2000200b4b1b22004100480d630240024020050d002000102821050c010b200128020020052000102c21050b2005450d242001200536020020092000360200200628020021000b2006200020036a360200200520006a200a2003109a051a2004410c6a22042008470d000c160b0b02400240200141046a280200200141086a2802002203460d00200128020021000c010b200341016a22002003490d61200341017422042000200420004b1b22044100480d610240024020030d002004102821000c010b200128020020032004102c21000b2000450d2320012000360200200141046a2004360200200141086a28020021030b200141086a200341016a360200200020036a41013a00000c130b02400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490d60200341017422052004200520044b1b22054100480d600240024020030d002005102821040c010b200128020020032005102c21040b2004450d2320012004360200200141046a2005360200200141086a28020021030b200141086a2205200341016a360200200420036a41023a000002400240200141046a28020020052802002203460d00200128020021040c010b200341016a22042003490d60200341017422052004200520044b1b22054100480d600240024020030d002005102821040c010b200128020020032005102c21040b2004450d2420012004360200200141046a2005360200200141086a28020021030b200141086a200341016a360200200420036a41003a0000200041086a200110a1010c130b02400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490d5f200341017422052004200520044b1b22054100480d5f0240024020030d002005102821040c010b200128020020032005102c21040b2004450d2420012004360200200141046a2005360200200141086a28020021030b200141086a2205200341016a360200200420036a41033a000002400240200141046a28020020052802002203460d00200128020021040c010b200341016a22042003490d5f200341017422052004200520044b1b22054100480d5f0240024020030d002005102821040c010b200128020020032005102c21040b2004450d2520012004360200200141046a2005360200200141086a28020021030b200141086a220a200341016a360200200420036a41003a00002000280204210c2000410c6a2802002203200110b4012003450d12200c200341f0006c6a210d200141046a210b034020022001360208200c41106a200241086a10c801200c200110a00120022001360208200c41306a200241086a10c80120022001360208200c41d0006a200241086a10c801200c2802042104200c28020c2203200110b40102402003450d00200341246c21090340200241086a200410ec012002280208210602400240200b2802002205200a28020022036b20022802102200490d00200128020021050c010b200320006a22082003490d62200541017422032008200320084b1b22034100480d620240024020050d002003102821050c010b200128020020052003102c21050b2005450d2920012005360200200b2003360200200a28020021030b200a200320006a360200200520036a20062000109a051a0240200228020c450d002006102a0b200441246a21042009415c6a22090d000b0b200c41f0006a220c200d470d000c130b0b02400240200141046a280200200141086a2802002203460d00200128020021000c010b200341016a22002003490d5e200341017422042000200420004b1b22044100480d5e0240024020030d002004102821000c010b200128020020032004102c21000b2000450d2620012000360200200141046a2004360200200141086a28020021030b200141086a200341016a360200200020036a41043a00000c100b02400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490d5d200341017422052004200520044b1b22054100480d5d0240024020030d002005102821040c010b200128020020032005102c21040b2004450d2620012004360200200141046a2005360200200141086a28020021030b200141086a200341016a360200200420036a41053a00002000280208417f6a220341024b0d10024002400240024020030e03000102000b200241003a001802400240200141046a280200200141086a2802002203460d00200128020021050c010b200341016a22042003490d60200341017422052004200520044b1b22044100480d600240024020030d002004102821050c010b200128020020032004102c21050b2005450d2a20012005360200200141046a2004360200200141086a28020021030b200041306a2104200141086a200341016a360200200520036a41003a00002000410c6a200110a601200241146a21030c020b200241013a001802400240200141046a280200200141086a2802002203460d00200128020021050c010b200341016a22042003490d5f200341017422052004200520044b1b22044100480d5f0240024020030d002004102821050c010b200128020020032004102c21050b2005450d2a20012005360200200141046a2004360200200141086a28020021030b200041c0006a2104200141086a200341016a360200200520036a41013a00002000410c6a200110a6012002200041306a360218200241186a200110a3012002411c6a21030c010b200241023a001802400240200141046a280200200141086a2802002203460d00200128020021050c010b200341016a22042003490d5e200341017422052004200520044b1b22044100480d5e0240024020030d002004102821050c010b200128020020032004102c21050b2005450d2a20012005360200200141046a2004360200200141086a28020021030b200041d8006a2104200141086a200341016a360200200520036a41023a00002000410c6a200110a601200041306a200110a601200241086a21030b200320043602002003200110a3010c100b02400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490d5c200341017422052004200520044b1b22054100480d5c0240024020030d002005102821040c010b200128020020032005102c21040b2004450d2920012004360200200141046a2005360200200141086a28020021030b200141086a200341016a360200200420036a41063a000020002d0008417f6a2203410c4b0d0f024002400240024002400240024002400240024002400240024020030e0d000102030405060708090a0b0c000b200241003a001802400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490d68200341017422052004200520044b1b22054100480d680240024020030d002005102821040c010b200128020020032005102c21040b2004450d3620012004360200200141046a2005360200200141086a28020021030b200141086a200341016a360200200420036a41003a00002000410c6a200110a6012002200041306a360208200241086a200110a30120002d0009220341024b0d1b02400240024020030e03000102000b200241003a001802400240200141046a280200200141086a2802002203460d00200128020021000c010b200341016a22002003490d6a200341017422042000200420004b1b22044100480d6a0240024020030d002004102821000c010b200128020020032004102c21000b2000450d3920012000360200200141046a2004360200200141086a28020021030b200141086a200341016a360200200020036a41003a00000c1d0b200241013a001802400240200141046a280200200141086a2802002203460d00200128020021000c010b200341016a22002003490d69200341017422042000200420004b1b22044100480d690240024020030d002004102821000c010b200128020020032004102c21000b2000450d3920012000360200200141046a2004360200200141086a28020021030b200141086a200341016a360200200020036a41013a00000c1c0b200241023a001802400240200141046a280200200141086a2802002203460d00200128020021000c010b200341016a22002003490d68200341017422042000200420004b1b22044100480d680240024020030d002004102821000c010b200128020020032004102c21000b2000450d3920012000360200200141046a2004360200200141086a28020021030b200141086a200341016a360200200020036a41023a00000c1b0b200241013a001802400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490d67200341017422052004200520044b1b22054100480d670240024020030d002005102821040c010b200128020020032005102c21040b2004450d3920012004360200200141046a2005360200200141086a28020021030b200141086a200341016a360200200420036a41013a00002002200041106a360208200241086a200110a3010c1a0b200241023a001802400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490d66200341017422052004200520044b1b22054100480d660240024020030d002005102821040c010b200128020020032005102c21040b2004450d3920012004360200200141046a2005360200200141086a28020021030b200141086a200341016a360200200420036a41023a00002002200041106a360208200241086a200110a3010c190b200241033a001802400240200141046a280200200141086a2802002203460d00200128020021000c010b200341016a22002003490d65200341017422042000200420004b1b22044100480d650240024020030d002004102821000c010b200128020020032004102c21000b2000450d3920012000360200200141046a2004360200200141086a28020021030b200141086a200341016a360200200020036a41033a00000c180b200141086a2802002103200241043a0018024002402003200141046a280200460d00200128020021040c010b200341016a22042003490d64200341017422052004200520044b1b22054100480d640240024020030d002005102821040c010b200128020020032005102c21040b2004450d3920012004360200200141046a2005360200200141086a28020021030b200141086a200341016a360200200420036a41043a00002002200041106a360208200241086a200110a3010c170b200241053a001802400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490d63200341017422052004200520044b1b22054100480d630240024020030d002005102821040c010b200128020020032005102c21040b2004450d3920012004360200200141046a2005360200200141086a28020021030b200141086a200341016a360200200420036a41053a0000200028020c2103200041146a2802002200200110b4012000450d16200041246c210003402003200110a601200341246a21032000415c6a22000d000c170b0b200241063a001802400240200141046a280200200141086a2802002203460d00200128020021000c010b200341016a22002003490d62200341017422042000200420004b1b22044100480d620240024020030d002004102821000c010b200128020020032004102c21000b2000450d3920012000360200200141046a2004360200200141086a28020021030b200141086a200341016a360200200020036a41063a00000c150b200241073a001802400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490d61200341017422052004200520044b1b22054100480d610240024020030d002005102821040c010b200128020020032005102c21040b2004450d3920012004360200200141046a2005360200200141086a28020021030b200141086a200341016a360200200420036a41073a000020002d0009220341024b0d1402400240024020030e03000102000b200241003a001802400240200141046a280200200141086a2802002203460d00200128020021000c010b200341016a22002003490d63200341017422042000200420004b1b22044100480d630240024020030d002004102821000c010b200128020020032004102c21000b2000450d3c20012000360200200141046a2004360200200141086a28020021030b200141086a200341016a360200200020036a41003a00000c160b200241013a001802400240200141046a280200200141086a2802002203460d00200128020021000c010b200341016a22002003490d62200341017422042000200420004b1b22044100480d620240024020030d002004102821000c010b200128020020032004102c21000b2000450d3c20012000360200200141046a2004360200200141086a28020021030b200141086a200341016a360200200020036a41013a00000c150b200241023a001802400240200141046a280200200141086a2802002203460d00200128020021000c010b200341016a22002003490d61200341017422042000200420004b1b22044100480d610240024020030d002004102821000c010b200128020020032004102c21000b2000450d3c20012000360200200141046a2004360200200141086a28020021030b200141086a200341016a360200200020036a41023a00000c140b200141046a2802002104200241083a0018024002402004200141086a2802002203460d00200128020021040c010b200341016a22042003490d60200341017422052004200520044b1b22054100480d600240024020030d002005102821040c010b200128020020032005102c21040b2004450d3c20012004360200200141046a2005360200200141086a28020021030b200141086a200341016a360200200420036a41083a00002000410c6a200110a6010c130b200241093a001802400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490d5f200341017422052004200520044b1b22054100480d5f0240024020030d002005102821040c010b200128020020032005102c21040b2004450d3c20012004360200200141046a2005360200200141086a28020021030b200141086a200341016a360200200420036a41093a00002000410c6a200110a0010c120b2002410a3a001802400240200141046a280200200141086a2802002203460d00200128020021000c010b200341016a22002003490d5e200341017422042000200420004b1b22044100480d5e0240024020030d002004102821000c010b200128020020032004102c21000b2000450d3c20012000360200200141046a2004360200200141086a28020021030b200141086a200341016a360200200020036a410a3a00000c110b2002410b3a001802400240200141046a280200200141086a2802002203460d00200128020021000c010b200341016a22002003490d5d200341017422042000200420004b1b22044100480d5d0240024020030d002004102821000c010b200128020020032004102c21000b2000450d3c20012000360200200141046a2004360200200141086a28020021030b200141086a200341016a360200200020036a410b3a00000c100b2002410c3a001802400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490d5c200341017422052004200520044b1b22054100480d5c0240024020030d002005102821040c010b200128020020032005102c21040b2004450d3c20012004360200200141046a2005360200200141086a28020021030b200141086a200341016a360200200420036a410c3a0000200028020c2103200041146a2802002200200110b4012000450d0f20004105742100034020032001108f01200341206a2103200041606a22000d000c100b0b02400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490d5b200341017422052004200520044b1b22054100480d5b0240024020030d002005102821040c010b200128020020032005102c21040b2004450d3c20012004360200200141046a2005360200200141086a28020021030b200141086a2205200341016a360200200420036a41073a000002400240200141046a28020020052802002203460d00200128020021040c010b200341016a22042003490d5b200341017422052004200520044b1b22054100480d5b0240024020030d002005102821040c010b200128020020032005102c21040b2004450d3d20012004360200200141046a2005360200200141086a28020021030b200141086a2205200341016a360200200420036a41003a0000200041106a2001108f01200041306a2001108f01200041d0006a2001108f01200028020421062000410c6a2802002203200110b40102400240200141046a2802002204200528020022006b2003490d00200128020021040c010b200020036a22052000490d5b200441017422002005200020054b1b22004100480d5b0240024020040d002000102821040c010b200128020020042000102c21040b2004450d3e20012004360200200141046a2000360200200141086a28020021000b200141086a200020036a360200200420006a20062003109a051a0c0e0b02400240200141046a2206280200200141086a22042802002203460d00200128020021050c010b200341016a22052003490d5a2003410174220a2005200a20054b1b220a4100480d5a0240024020030d00200a102821050c010b20012802002003200a102c21050b2005450d3e20012005360200200141046a200a360200200141086a28020021030b2004200341016a360200200520036a41083a0000200041086a22052d0000417f6a220341104b0d0d0240024002400240024002400240024002400240024002400240024002400240024020030e11000102030405060708090a0b0c0d0e0f10000b02400240200628020020042802002203460d00200128020021040c010b200341016a22042003490d6a200341017422052004200520044b1b22054100480d6a0240024020030d002005102821040c010b200128020020032005102c21040b2004450d4f20012004360200200141046a2005360200200141086a28020021030b200141086a200341016a360200200420036a41003a0000200028020c200110eb012002200041106a360208200241086a200110a3010c1d0b02400240200628020020042802002203460d00200128020021040c010b200341016a22042003490d69200341017422052004200520044b1b22054100480d690240024020030d002005102821040c010b200128020020032005102c21040b2004450d4f20012004360200200141046a2005360200200141086a28020021030b200141086a200341016a360200200420036a41013a00002000410c6a200110a0010c1c0b02400240200628020020042802002203460d00200128020021060c010b200341016a22062003490d682003410174220a2006200a20064b1b220a4100480d680240024020030d00200a102821060c010b20012802002003200a102c21060b2006450d4f20012006360200200141046a200a360200200141086a28020021030b200141086a220a200341016a360200200620036a41023a00002000410c6a200110a00120052d00012106200541026a2d0000210502400240200141046a280200200a2802002203460d00200128020021000c010b200341016a22002003490d682003410174220a2000200a20004b1b220a4100480d680240024020030d00200a102821000c010b20012802002003200a102c21000b2000450d5020012000360200200141046a200a360200200141086a28020021030b2004200341016a360200200020036a20064100474107742005723a00000c1b0b02400240200628020020042802002203460d00200128020021060c010b200341016a22062003490d672003410174220a2006200a20064b1b220a4100480d670240024020030d00200a102821060c010b20012802002003200a102c21060b2006450d5020012006360200200141046a200a360200200141086a28020021030b200141086a220a200341016a360200200620036a41033a00002000410c6a200110a00120052d00012106200541026a2d0000210502400240200141046a280200200a2802002203460d00200128020021000c010b200341016a22002003490d672003410174220a2000200a20004b1b220a4100480d670240024020030d00200a102821000c010b20012802002003200a102c21000b2000450d5120012000360200200141046a200a360200200141086a28020021030b2004200341016a360200200020036a20064100474107742005723a00000c1a0b02400240200628020020042802002203460d00200128020021050c010b200341016a22052003490d662003410174220a2005200a20054b1b220a4100480d660240024020030d00200a102821050c010b20012802002003200a102c21050b2005450d5120012005360200200141046a200a360200200141086a28020021030b2004200341016a360200200520036a41043a0000200028020c21050240024020062802002200200428020022036b4104490d00200128020021000c010b200341046a22062003490d66200041017422032006200320064b1b22034100480d660240024020000d002003102821000c010b200128020020002003102c21000b2000450d5220012000360200200141046a2003360200200141086a28020021030b2004200341046a360200200020036a20053600000c190b02400240200628020020042802002203460d00200128020021040c010b200341016a22042003490d65200341017422052004200520044b1b22054100480d650240024020030d002005102821040c010b200128020020032005102c21040b2004450d5220012004360200200141046a2005360200200141086a28020021030b200141086a200341016a360200200420036a41053a0000200028020c200110eb010c180b02400240200628020020042802002203460d00200128020021040c010b200341016a22042003490d64200341017422052004200520044b1b22054100480d640240024020030d002005102821040c010b200128020020032005102c21040b2004450d5220012004360200200141046a2005360200200141086a28020021030b200141086a200341016a360200200420036a41063a0000200028020c200110eb010c170b02400240200628020020042802002203460d00200128020021040c010b200341016a22042003490d63200341017422052004200520044b1b22054100480d630240024020030d002005102821040c010b200128020020032005102c21040b2004450d5220012004360200200141046a2005360200200141086a28020021030b200141086a200341016a360200200420036a41073a0000200028020c200110eb010c160b02400240200628020020042802002203460d002001280200210a0c010b200341016a220a2003490d6220034101742209200a2009200a4b1b22094100480d620240024020030d0020091028210a0c010b200128020020032009102c210a0b200a450d522001200a360200200141046a2009360200200141086a28020021030b200141086a2209200341016a360200200a20036a41083a000020022001360208200541016a200241086a10c801200028022c210a02400240200141046a2802002205200928020022036b4104490d00200128020021050c010b200341046a22092003490d62200541017422032009200320094b1b22034100480d620240024020050d002003102821050c010b200128020020052003102c21050b2005450d5320012005360200200141046a2003360200200141086a28020021030b2004200341046a360200200520036a200a360000200028023021050240024020062802002200200428020022036b4104490d00200128020021000c010b200341046a22062003490d62200041017422032006200320064b1b22034100480d620240024020000d002003102821000c010b200128020020002003102c21000b2000450d5420012000360200200141046a2003360200200141086a28020021030b2004200341046a360200200020036a20053600000c150b02400240200628020020042802002203460d00200128020021000c010b200341016a22002003490d61200341017422042000200420004b1b22044100480d610240024020030d002004102821000c010b200128020020032004102c21000b2000450d5420012000360200200141046a2004360200200141086a28020021030b200141086a200341016a360200200020036a41093a000020022001360208200541016a200241086a10c8010c140b02400240200628020020042802002203460d00200128020021040c010b200341016a22042003490d60200341017422052004200520044b1b22054100480d600240024020030d002005102821040c010b200128020020032005102c21040b2004450d5420012004360200200141046a2005360200200141086a28020021030b200141086a200341016a360200200420036a410a3a00002000410c6a200110a0010c130b02400240200628020020042802002203460d00200128020021040c010b200341016a22042003490d5f200341017422052004200520044b1b22054100480d5f0240024020030d002005102821040c010b200128020020032005102c21040b2004450d5420012004360200200141046a2005360200200141086a28020021030b200141086a200341016a360200200420036a410b3a00002000410c6a200110a001200041106a200110a001200041146a200110a0010c120b02400240200628020020042802002203460d00200128020021000c010b200341016a22002003490d5e200341017422042000200420004b1b22044100480d5e0240024020030d002004102821000c010b200128020020032004102c21000b2000450d5420012000360200200141046a2004360200200141086a28020021030b200141086a200341016a360200200020036a410c3a0000200541016a2001108f010c110b02400240200628020020042802002203460d00200128020021000c010b200341016a22002003490d5d200341017422052000200520004b1b22054100480d5d0240024020030d002005102821000c010b200128020020032005102c21000b2000450d5420012000360200200141046a2005360200200141086a28020021030b2004200341016a360200200020036a410d3a00000c100b02400240200628020020042802002203460d00200128020021000c010b200341016a22002003490d5c200341017422042000200420004b1b22044100480d5c0240024020030d002004102821000c010b200128020020032004102c21000b2000450d5420012000360200200141046a2004360200200141086a28020021030b200141086a200341016a360200200020036a410e3a0000200541016a2001108f010c0f0b02400240200628020020042802002203460d00200128020021000c010b200341016a22002003490d5b2003410174220a2000200a20004b1b220a4100480d5b0240024020030d00200a102821000c010b20012802002003200a102c21000b2000450d5420012000360200200141046a200a360200200141086a28020021030b200141086a200341016a360200200020036a410f3a0000200541016a2001108f0120052d0021220341064b0d0e0240024002400240024002400240024020030e0700010203040506000b410021000c060b410121000c050b410221000c040b410321000c030b410421000c020b410521000c010b410621000b200220003a001802400240200628020020042802002203460d00200128020021050c010b200341016a22052003490d5b200341017422062005200620054b1b22064100480d5b0240024020030d002006102821050c010b200128020020032006102c21050b2005450d5520012005360200200141046a2006360200200141086a28020021030b2004200341016a360200200520036a20003a00000c0e0b02400240200628020020042802002203460d00200128020021000c010b200341016a22002003490d5a200341017422052000200520004b1b22054100480d5a0240024020030d002005102821000c010b200128020020032005102c21000b2000450d5520012000360200200141046a2005360200200141086a28020021030b2004200341016a360200200020036a41103a00000c0d0b02400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490d59200341017422052004200520044b1b22054100480d590240024020030d002005102821040c010b200128020020032005102c21040b2004450d5520012004360200200141046a2005360200200141086a28020021030b200141086a200341016a360200200420036a41093a0000200041046a200110ed010c0c0b02400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490d58200341017422052004200520044b1b22054100480d580240024020030d002005102821040c010b200128020020032005102c21040b2004450d5520012004360200200141046a2005360200200141086a28020021030b200141086a200341016a360200200420036a410a3a0000200041046a200110ed010c0b0b02400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490d57200341017422052004200520044b1b22054100480d570240024020030d002005102821040c010b200128020020032005102c21040b2004450d5520012004360200200141046a2005360200200141086a28020021030b200141086a200341016a360200200420036a410b3a00002000280208417f6a220341094b0d0a024002400240024002400240024002400240024020030e0a00010203040506070809000b200241003a001802400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490d60200341017422052004200520044b1b22054100480d600240024020030d002005102821040c010b200128020020032005102c21040b2004450d5f20012004360200200141046a2005360200200141086a28020021030b200141086a2206200341016a360200200420036a41003a0000200028020c2104200041146a280200220a200110b4010240200a450d00200141046a2109034002400240200928020020062802002203460d00200128020021050c010b200341016a22052003490dad012003410174220b2005200b20054b1b220b4100480dad010240024020030d00200b102821050c010b20012802002003200b102c21050b2005450d63200120053602002009200b360200200628020021030b2006200341016a360200200520036a20042d00003a0000200441016a2104200a417f6a220a0d000b0b200041186a200110a001200028021c210502400240200141046a2802002204200628020022036b4104490d00200128020021040c010b200341046a22062003490dab01200441017422032006200320064b1b22034100480dab010240024020040d002003102821040c010b200128020020042003102c21040b2004450d6220012004360200200141046a2003360200200141086a28020021030b200141086a2206200341046a360200200420036a2005360000200041286a29030021072000290320210e02400240200141046a2802002200200628020022036b4110490d00200128020021000c010b200341106a22042003490dab01200041017422032004200320044b1b22034100480dab010240024020000d002003102821000c010b200128020020002003102c21000b2000450d6320012000360200200141046a2003360200200141086a28020021030b200141086a200341106a360200200020036a220320073700082003200e3700000c130b200241013a001802400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490daa01200341017422052004200520044b1b22054100480daa010240024020030d002005102821040c010b200128020020032005102c21040b2004450d6320012004360200200141046a2005360200200141086a28020021030b200141086a2206200341016a360200200420036a41013a0000200028020c2104200041146a280200220a200110b4010240200a450d00200141046a2109034002400240200928020020062802002203460d00200128020021050c010b200341016a22052003490dac012003410174220b2005200b20054b1b220b4100480dac010240024020030d00200b102821050c010b20012802002003200b102c21050b2005450d66200120053602002009200b360200200628020021030b2006200341016a360200200520036a20042d00003a0000200441016a2104200a417f6a220a0d000b0b200041186a200110a001200028021c210502400240200141046a2802002204200628020022036b4104490d00200128020021040c010b200341046a22062003490daa01200441017422032006200320064b1b22034100480daa010240024020040d002003102821040c010b200128020020042003102c21040b2004450d6520012004360200200141046a2003360200200141086a28020021030b200141086a2206200341046a360200200420036a2005360000200041286a29030021072000290320210e02400240200141046a2802002200200628020022036b4110490d00200128020021000c010b200341106a22042003490daa01200041017422032004200320044b1b22034100480daa010240024020000d002003102821000c010b200128020020002003102c21000b2000450d6620012000360200200141046a2003360200200141086a28020021030b200141086a200341106a360200200020036a220320073700082003200e3700000c120b200241023a001802400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490da901200341017422052004200520044b1b22054100480da9010240024020030d002005102821040c010b200128020020032005102c21040b2004450d6620012004360200200141046a2005360200200141086a28020021030b200141086a200341016a360200200420036a41023a00002000410c6a200110a001200041106a200110a601200041346a200110a001200041386a200110a0010c110b200241033a001802400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490da801200341017422052004200520044b1b22054100480da8010240024020030d002005102821040c010b200128020020032005102c21040b2004450d6620012004360200200141046a2005360200200141086a28020021030b200141086a200341016a360200200420036a41033a00002000410c6a200110a0010c100b200141086a2802002103200241043a0018024002402003200141046a280200460d00200128020021040c010b200341016a22042003490da701200341017422052004200520044b1b22054100480da7010240024020030d002005102821040c010b200128020020032005102c21040b2004450d6620012004360200200141046a2005360200200141086a28020021030b200141086a200341016a360200200420036a41043a00002000410c6a200110a0010c0f0b200241053a001802400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490da601200341017422052004200520044b1b22054100480da6010240024020030d002005102821040c010b200128020020032005102c21040b2004450d6620012004360200200141046a2005360200200141086a28020021030b200141086a200341016a360200200420036a41053a00002000410c6a200110a6012002200041386a360208200241086a200110a301200041306a200110a0010c0e0b200241063a001802400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490da501200341017422052004200520044b1b22054100480da5010240024020030d002005102821040c010b200128020020032005102c21040b2004450d6620012004360200200141046a2005360200200141086a28020021030b200141086a200341016a360200200420036a41063a00002000410c6a200110a0010c0d0b200241073a001802400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490da401200341017422052004200520044b1b22054100480da4010240024020030d002005102821040c010b200128020020032005102c21040b2004450d6620012004360200200141046a2005360200200141086a28020021030b200141086a200341016a360200200420036a41073a00002000410c6a200110a6010c0c0b200141046a2802002104200241083a0018024002402004200141086a2802002203460d00200128020021040c010b200341016a22042003490da301200341017422052004200520044b1b22054100480da3010240024020030d002005102821040c010b200128020020032005102c21040b2004450d6620012004360200200141046a2005360200200141086a28020021030b200141086a200341016a360200200420036a41083a00002000410c6a200110a0010c0b0b200241093a001802400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490da201200341017422052004200520044b1b22054100480da2010240024020030d002005102821040c010b200128020020032005102c21040b2004450d6620012004360200200141046a2005360200200141086a28020021030b200141086a200341016a360200200420036a41093a00002000410c6a200110a0010c0a0b02400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490da101200341017422052004200520044b1b22054100480da1010240024020030d002005102821040c010b200128020020032005102c21040b2004450d6620012004360200200141046a2005360200200141086a28020021030b200141086a200341016a360200200420036a410c3a0000200041046a22042d0000417f6a220341034b0d09024002400240024020030e0400010203000b200241003a001802400240200141046a280200200141086a2802002203460d00200128020021000c010b200341016a22002003490da401200341017422052000200520004b1b22054100480da4010240024020030d002005102821000c010b200128020020032005102c21000b2000450d6a20012000360200200141046a2005360200200141086a28020021030b200141086a200341016a360200200020036a41003a0000200441016a2001108f010c0c0b200141086a2802002103200141046a2802002100200241013a00180240024020002003460d00200128020021000c010b200341016a22002003490da301200341017422052000200520004b1b22054100480da3010240024020030d002005102821000c010b200128020020032005102c21000b2000450d6a20012000360200200141046a2005360200200141086a28020021030b200141086a200341016a360200200020036a41013a0000200441016a2001108f010c0b0b200241023a001802400240200141046a280200200141086a2802002203460d00200128020021000c010b200341016a22002003490da201200341017422052000200520004b1b22054100480da2010240024020030d002005102821000c010b200128020020032005102c21000b2000450d6a20012000360200200141046a2005360200200141086a28020021030b200141086a200341016a360200200020036a41023a0000200441016a2001108f01200441216a2001108f010c0a0b200241033a001802400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490da101200341017422052004200520044b1b22054100480da1010240024020030d002005102821040c010b200128020020032005102c21040b2004450d6a20012004360200200141046a2005360200200141086a28020021030b200141086a200341016a360200200420036a41033a000020002802082103200041106a2802002200200110b4012000450d0920004105742100034020032001108f01200341206a2103200041606a22000d000c0a0b0b02400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490da001200341017422052004200520044b1b22054100480da0010240024020030d002005102821040c010b200128020020032005102c21040b2004450d6a20012004360200200141046a2005360200200141086a28020021030b200141086a2205200341016a360200200420036a410d3a000002400240200141046a28020020052802002203460d00200128020021040c010b200341016a22042003490da001200341017422052004200520044b1b22054100480da0010240024020030d002005102821040c010b200128020020032005102c21040b2004450d6b20012004360200200141046a2005360200200141086a28020021030b200141086a200341016a360200200420036a41003a0000200041046a200110a0010c080b02400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490d9f01200341017422052004200520044b1b22054100480d9f010240024020030d002005102821040c010b200128020020032005102c21040b2004450d6b20012004360200200141046a2005360200200141086a28020021030b200141086a2205200341016a360200200420036a410e3a000002400240200141046a28020020052802002203460d00200128020021040c010b200341016a22042003490d9f01200341017422052004200520044b1b22054100480d9f010240024020030d002005102821040c010b200128020020032005102c21040b2004450d6c20012004360200200141046a2005360200200141086a28020021030b200141086a2205200341016a360200200420036a41003a0000200028020421062000410c6a2802002203200110b40102400240200141046a2802002204200528020022006b2003490d00200128020021040c010b200020036a22052000490d9f01200441017422002005200020054b1b22004100480d9f010240024020040d002000102821040c010b200128020020042000102c21040b2004450d6d20012004360200200141046a2000360200200141086a28020021000b200141086a200020036a360200200420006a20062003109a051a0c070b02400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490d9e01200341017422052004200520044b1b22054100480d9e010240024020030d002005102821040c010b200128020020032005102c21040b2004450d6d20012004360200200141046a2005360200200141086a28020021030b200141086a200341016a360200200420036a410f3a00002000280208417f6a220341024b0d0602400240024020030e03000102000b200241003a001802400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490da001200341017422052004200520044b1b22054100480da0010240024020030d002005102821040c010b200128020020032005102c21040b2004450d7020012004360200200141046a2005360200200141086a28020021030b200141086a200341016a360200200420036a41003a00002002200041306a360208200241086a200110a3012000410c6a200110a6010c080b200241013a001802400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490d9f01200341017422052004200520044b1b22054100480d9f010240024020030d002005102821040c010b200128020020032005102c21040b2004450d7020012004360200200141046a2005360200200141086a28020021030b200141086a200341016a360200200420036a41013a00002000410c6a200110a0010c070b200241023a001802400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490d9e01200341017422052004200520044b1b22054100480d9e010240024020030d002005102821040c010b200128020020032005102c21040b2004450d7020012004360200200141046a2005360200200141086a28020021030b200141086a200341016a360200200420036a41023a00002000410c6a200110a0010c060b02400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490d9d01200341017422052004200520044b1b22054100480d9d010240024020030d002005102821040c010b200128020020032005102c21040b2004450d7020012004360200200141046a2005360200200141086a28020021030b200141086a200341016a360200200420036a41103a0000200041086a22042d0000417f6a220341044b0d050240024002400240024020030e050001020304000b200241003a001802400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490da101200341017422052004200520044b1b22054100480da1010240024020030d002005102821040c010b200128020020032005102c21040b2004450d7520012004360200200141046a2005360200200141086a28020021030b200141086a200341016a360200200420036a41003a0000200041106a200110ee010c090b200241013a001802400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490da001200341017422052004200520044b1b22054100480da0010240024020030d002005102821040c010b200128020020032005102c21040b2004450d7520012004360200200141046a2005360200200141086a28020021030b200141086a2205200341016a360200200420036a41013a0000200041186a200110a101200028020c2106200041146a2802002203200110b40102400240200141046a2802002204200528020022006b2003490d00200128020021040c010b200020036a22052000490da001200441017422002005200020054b1b22004100480da0010240024020040d002000102821040c010b200128020020042000102c21040b2004450d7620012004360200200141046a2000360200200141086a28020021000b200141086a200020036a360200200420006a20062003109a051a0c080b200241023a001802400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490d9f01200341017422052004200520044b1b22054100480d9f010240024020030d002005102821040c010b200128020020032005102c21040b2004450d7620012004360200200141046a2005360200200141086a28020021030b200141086a2205200341016a360200200420036a41023a00002000410c6a200110a6012002200041c0006a360208200241086a200110a301200041d0006a200110a10120002802302106200041386a2802002203200110b40102400240200141046a2802002204200528020022006b2003490d00200128020021040c010b200020036a22052000490d9f01200441017422002005200020054b1b22004100480d9f010240024020040d002000102821040c010b200128020020042000102c21040b2004450d7720012004360200200141046a2000360200200141086a28020021000b200141086a200020036a360200200420006a20062003109a051a0c070b200241033a001802400240200141046a280200200141086a2802002203460d00200128020021050c010b200341016a22052003490d9e01200341017422062005200620054b1b22064100480d9e010240024020030d002006102821050c010b200128020020032006102c21050b2005450d7720012005360200200141046a2006360200200141086a28020021030b200141086a2206200341016a360200200520036a41033a00002002200041386a360208200241086a200110a301200041c8006a200110a10120022001360208200441016a200241086a10c801200028022c2105200041346a2802002203200110b40102400240200141046a2802002204200628020022006b2003490d00200128020021040c010b200020036a22062000490d9e01200441017422002006200020064b1b22004100480d9e010240024020040d002000102821040c010b200128020020042000102c21040b2004450d7820012004360200200141046a2000360200200141086a28020021000b200141086a200020036a360200200420006a20052003109a051a0c060b200141086a2802002103200241043a0018024002402003200141046a280200460d00200128020021000c010b200341016a22002003490d9d01200341017422052000200520004b1b22054100480d9d010240024020030d002005102821000c010b200128020020032005102c21000b2000450d7820012000360200200141046a2005360200200141086a28020021030b200141086a2205200341016a360200200020036a41043a0000200441016a2001108f01024020042d00214101460d00200241003a001802400240200141046a28020020052802002203460d00200128020021000c010b200341016a22002003490d9e01200341017422042000200420004b1b22044100480d9e010240024020030d002004102821000c010b200128020020032004102c21000b2000450d7a20012000360200200141046a2004360200200141086a28020021030b200141086a200341016a360200200020036a41003a00000c060b200241013a001802400240200141046a28020020052802002203460d00200128020021000c010b200341016a22002003490d9d01200341017422052000200520004b1b22054100480d9d010240024020030d002005102821000c010b200128020020032005102c21000b2000450d7a20012000360200200141046a2005360200200141086a28020021030b200141086a200341016a360200200020036a41013a0000200441226a2001108f010c050b02400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490d9c01200341017422052004200520044b1b22054100480d9c010240024020030d002005102821040c010b200128020020032005102c21040b2004450d7a20012004360200200141046a2005360200200141086a28020021030b200141086a200341016a360200200420036a41113a00002000280204417f6a220341024b0d0402400240024020030e03000102000b200241003a001802400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490d9e01200341017422052004200520044b1b22054100480d9e010240024020030d002005102821040c010b200128020020032005102c21040b2004450d7d20012004360200200141046a2005360200200141086a28020021030b200141086a200341016a360200200420036a41003a00002000280208200110eb010c060b200241013a001802400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490d9d01200341017422052004200520044b1b22054100480d9d010240024020030d002005102821040c010b200128020020032005102c21040b2004450d7d20012004360200200141046a2005360200200141086a28020021030b200141086a200341016a360200200420036a41013a0000200041086a200110a6010c050b200241023a001802400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490d9c01200341017422052004200520044b1b22054100480d9c010240024020030d002005102821040c010b200128020020032005102c21040b2004450d7d20012004360200200141046a2005360200200141086a28020021030b200141086a200341016a360200200420036a41023a0000200041086a200110a601200028022c200110eb010c040b02400240200141046a220a280200200141086a22032802002204460d00200128020021050c010b200441016a22052004490d9b01200441017422062005200620054b1b22064100480d9b010240024020040d002006102821050c010b200128020020042006102c21050b2005450d7d20012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a41123a000002400240200a28020020032802002204460d00200128020021050c010b200441016a22052004490d9b01200441017422062005200620054b1b22064100480d9b010240024020040d002006102821050c010b200128020020042006102c21050b2005450d7e20012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a41003a00002000280204210602400240200a2802002205200328020022046b4104490d00200128020021050c010b200441046a22092004490d9b01200541017422042009200420094b1b22044100480d9b010240024020050d002004102821050c010b200128020020052004102c21050b2005450d7f20012005360200200141046a2004360200200141086a28020021040b200141086a2209200441046a360200200520046a2006360000200041086a280200210b200041106a2802002204200110b40102400240200141046a2802002206200928020022056b2004490d00200128020021060c010b200520046a22092005490d9b01200641017422052009200520094b1b22054100480d9b010240024020060d002005102821060c010b200128020020062005102c21060b2006450d800120012006360200200141046a2005360200200141086a28020021050b200141086a2208200520046a360200200620056a200b2004109a051a200041146a28020021062000411c6a2802002204200110b40102402004450d0020062004410c6c6a210f200141046a210c03402006280200210b200641086a2802002204200110b40102400240200c2802002209200828020022056b2004490d00200128020021090c010b200520046a220d2005490d9d0120094101742205200d2005200d4b1b22054100480d9d010240024020090d002005102821090c010b200128020020092005102c21090b2009450d830120012009360200200c2005360200200828020021050b2003200520046a360200200920056a200b2004109a051a2006410c6a2206200f470d000b0b200041206a280200210602400240200a2802002205200328020022046b4104490d00200128020021050c010b200441046a22092004490d9b01200541017422042009200420094b1b22044100480d9b010240024020050d002004102821050c010b200128020020052004102c21050b2005450d820120012005360200200141046a2004360200200141086a28020021040b2003200441046a360200200520046a2006360000200041246a280200210602400240200a2802002205200328020022046b4104490d00200128020021050c010b200441046a22092004490d9b01200541017422042009200420094b1b22044100480d9b010240024020050d002004102821050c010b200128020020052004102c21050b2005450d830120012005360200200141046a2004360200200141086a28020021040b2003200441046a360200200520046a200636000002400240200a28020020032802002204460d00200128020021050c010b200441016a22052004490d9b01200441017422062005200620054b1b22064100480d9b010240024020040d002006102821050c010b200128020020042006102c21050b2005450d840120012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a200041286a22042d00003a000002400240200a28020020032802002205460d00200128020021060c010b200541016a22062005490d9b01200541017422092006200920064b1b22094100480d9b010240024020050d002009102821060c010b200128020020052009102c21060b2006450d850120012006360200200141046a2009360200200141086a28020021050b2003200541016a360200200620056a20042d00013a000002400240200a28020020032802002205460d00200128020021060c010b200541016a22062005490d9b01200541017422092006200920064b1b22094100480d9b010240024020050d002009102821060c010b200128020020052009102c21060b2006450d860120012006360200200141046a2009360200200141086a28020021050b2003200541016a360200200620056a20002d002a3a000002400240200a28020020032802002205460d00200128020021060c010b200541016a22062005490d9b01200541017422092006200920064b1b22094100480d9b010240024020050d002009102821060c010b200128020020052009102c21060b2006450d870120012006360200200141046a2009360200200141086a28020021050b2003200541016a360200200620056a20042d00033a000002400240200a28020020032802002205460d00200128020021060c010b200541016a22062005490d9b01200541017422092006200920064b1b22094100480d9b010240024020050d002009102821060c010b200128020020052009102c21060b2006450d880120012006360200200141046a2009360200200141086a28020021050b2003200541016a360200200620056a20002d002c3a000002400240200a28020020032802002205460d00200128020021060c010b200541016a22062005490d9b01200541017422092006200920064b1b22094100480d9b010240024020050d002009102821060c010b200128020020052009102c21060b2006450d890120012006360200200141046a2009360200200141086a28020021050b2003200541016a360200200620056a20042d00053a000002400240200a28020020032802002205460d00200128020021060c010b200541016a22062005490d9b01200541017422092006200920064b1b22094100480d9b010240024020050d002009102821060c010b200128020020052009102c21060b2006450d8a0120012006360200200141046a2009360200200141086a28020021050b2003200541016a360200200620056a20002d002e3a000002400240200a28020020032802002205460d00200128020021060c010b200541016a22062005490d9b01200541017422092006200920064b1b22094100480d9b010240024020050d002009102821060c010b200128020020052009102c21060b2006450d8b0120012006360200200141046a2009360200200141086a28020021050b2003200541016a360200200620056a20042d00073a000002400240200a28020020032802002205460d00200128020021060c010b200541016a22062005490d9b01200541017422092006200920064b1b22094100480d9b010240024020050d002009102821060c010b200128020020052009102c21060b2006450d8c0120012006360200200141046a2009360200200141086a28020021050b2003200541016a360200200620056a20002d00303a000002400240200a28020020032802002205460d00200128020021060c010b200541016a22062005490d9b01200541017422092006200920064b1b22094100480d9b010240024020050d002009102821060c010b200128020020052009102c21060b2006450d8d0120012006360200200141046a2009360200200141086a28020021050b2003200541016a360200200620056a20042d00093a000002400240200a28020020032802002205460d00200128020021060c010b200541016a22062005490d9b01200541017422092006200920064b1b22094100480d9b010240024020050d002009102821060c010b200128020020052009102c21060b2006450d8e0120012006360200200141046a2009360200200141086a28020021050b2003200541016a360200200620056a20002d00323a000002400240200a28020020032802002205460d00200128020021060c010b200541016a22062005490d9b01200541017422092006200920064b1b22094100480d9b010240024020050d002009102821060c010b200128020020052009102c21060b2006450d8f0120012006360200200141046a2009360200200141086a28020021050b2003200541016a360200200620056a20042d000b3a000002400240200a28020020032802002205460d00200128020021060c010b200541016a22062005490d9b01200541017422092006200920064b1b22094100480d9b010240024020050d002009102821060c010b200128020020052009102c21060b2006450d900120012006360200200141046a2009360200200141086a28020021050b2003200541016a360200200620056a20002d00343a000002400240200a28020020032802002205460d00200128020021060c010b200541016a22062005490d9b01200541017422092006200920064b1b22094100480d9b010240024020050d002009102821060c010b200128020020052009102c21060b2006450d910120012006360200200141046a2009360200200141086a28020021050b2003200541016a360200200620056a20042d000d3a000002400240200a28020020032802002205460d00200128020021060c010b200541016a22062005490d9b01200541017422092006200920064b1b22094100480d9b010240024020050d002009102821060c010b200128020020052009102c21060b2006450d920120012006360200200141046a2009360200200141086a28020021050b2003200541016a360200200620056a20002d00363a000002400240200a28020020032802002205460d00200128020021060c010b200541016a22062005490d9b01200541017422092006200920064b1b22094100480d9b010240024020050d002009102821060c010b200128020020052009102c21060b2006450d930120012006360200200141046a2009360200200141086a28020021050b2003200541016a360200200620056a20042d000f3a000002400240200a28020020032802002205460d00200128020021060c010b200541016a22062005490d9b01200541017422092006200920064b1b22094100480d9b010240024020050d002009102821060c010b200128020020052009102c21060b2006450d940120012006360200200141046a2009360200200141086a28020021050b2003200541016a360200200620056a20002d00383a000002400240200a28020020032802002205460d00200128020021060c010b200541016a22062005490d9b01200541017422092006200920064b1b22094100480d9b010240024020050d002009102821060c010b200128020020052009102c21060b2006450d950120012006360200200141046a2009360200200141086a28020021050b2003200541016a360200200620056a20042d00113a000002400240200a28020020032802002205460d00200128020021060c010b200541016a22062005490d9b01200541017422092006200920064b1b22094100480d9b010240024020050d002009102821060c010b200128020020052009102c21060b2006450d960120012006360200200141046a2009360200200141086a28020021050b2003200541016a360200200620056a20002d003a3a000002400240200a28020020032802002205460d00200128020021060c010b200541016a22062005490d9b01200541017422092006200920064b1b22094100480d9b010240024020050d002009102821060c010b200128020020052009102c21060b2006450d970120012006360200200141046a2009360200200141086a28020021050b2003200541016a360200200620056a20042d00133a000002400240200a28020020032802002205460d00200128020021060c010b200541016a22062005490d9b01200541017422092006200920064b1b22094100480d9b010240024020050d002009102821060c010b200128020020052009102c21060b2006450d980120012006360200200141046a2009360200200141086a28020021050b2003200541016a360200200620056a20002d003c3a000002400240200a28020020032802002205460d00200128020021060c010b200541016a22062005490d9b01200541017422092006200920064b1b22094100480d9b010240024020050d002009102821060c010b200128020020052009102c21060b2006450d990120012006360200200141046a2009360200200141086a28020021050b2003200541016a360200200620056a20042d00153a000002400240200a28020020032802002205460d00200128020021060c010b200541016a22062005490d9b01200541017422092006200920064b1b22094100480d9b010240024020050d002009102821060c010b200128020020052009102c21060b2006450d9a0120012006360200200141046a2009360200200141086a28020021050b2003200541016a360200200620056a20002d003e3a000002400240200a28020020032802002205460d00200128020021060c010b200541016a22062005490dc701200541017422092006200920064b1b22094100480dc7010240024020050d002009102821060c010b200128020020052009102c21060b2006450d9c0120012006360200200141046a2009360200200141086a28020021050b2003200541016a360200200620056a20042d00173a000002400240200a28020020032802002205460d00200128020021060c010b200541016a22062005490dc701200541017422092006200920064b1b22094100480dc7010240024020050d002009102821060c010b200128020020052009102c21060b2006450d9d0120012006360200200141046a2009360200200141086a28020021050b2003200541016a360200200620056a20002d00403a000002400240200a28020020032802002205460d00200128020021060c010b200541016a22062005490dc701200541017422092006200920064b1b22094100480dc7010240024020050d002009102821060c010b200128020020052009102c21060b2006450d9e0120012006360200200141046a2009360200200141086a28020021050b2003200541016a360200200620056a20042d00193a000002400240200a28020020032802002205460d00200128020021060c010b200541016a22062005490dc701200541017422092006200920064b1b22094100480dc7010240024020050d002009102821060c010b200128020020052009102c21060b2006450d9f0120012006360200200141046a2009360200200141086a28020021050b2003200541016a360200200620056a20002d00423a000002400240200a28020020032802002205460d00200128020021060c010b200541016a22062005490dc701200541017422092006200920064b1b22094100480dc7010240024020050d002009102821060c010b200128020020052009102c21060b2006450da00120012006360200200141046a2009360200200141086a28020021050b2003200541016a360200200620056a20042d001b3a000002400240200a28020020032802002205460d00200128020021060c010b200541016a22062005490dc701200541017422092006200920064b1b22094100480dc7010240024020050d002009102821060c010b200128020020052009102c21060b2006450da10120012006360200200141046a2009360200200141086a28020021050b2003200541016a360200200620056a20002d00443a000002400240200a28020020032802002205460d00200128020021060c010b200541016a22062005490dc701200541017422092006200920064b1b22094100480dc7010240024020050d002009102821060c010b200128020020052009102c21060b2006450da20120012006360200200141046a2009360200200141086a28020021050b2003200541016a360200200620056a20042d001d3a000002400240200a28020020032802002205460d00200128020021060c010b200541016a22062005490dc701200541017422092006200920064b1b22094100480dc7010240024020050d002009102821060c010b200128020020052009102c21060b2006450da30120012006360200200141046a2009360200200141086a28020021050b2003200541016a360200200620056a20002d00463a000002400240200a28020020032802002205460d00200128020021060c010b200541016a22062005490dc701200541017422092006200920064b1b22094100480dc7010240024020050d002009102821060c010b200128020020052009102c21060b2006450da40120012006360200200141046a2009360200200141086a28020021050b2003200541016a360200200620056a20042d001f3a000002400240200a28020020032802002205460d00200128020021060c010b200541016a22062005490dc701200541017422092006200920064b1b22094100480dc7010240024020050d002009102821060c010b200128020020052009102c21060b2006450da50120012006360200200141046a2009360200200141086a28020021050b2003200541016a360200200620056a20002d00483a000002400240200a28020020032802002205460d00200128020021060c010b200541016a22062005490dc701200541017422092006200920064b1b22094100480dc7010240024020050d002009102821060c010b200128020020052009102c21060b2006450da60120012006360200200141046a2009360200200141086a28020021050b2003200541016a360200200620056a20042d00213a000002400240200a28020020032802002205460d00200128020021060c010b200541016a22062005490dc701200541017422092006200920064b1b22094100480dc7010240024020050d002009102821060c010b200128020020052009102c21060b2006450da70120012006360200200141046a2009360200200141086a28020021050b2003200541016a360200200620056a20002d004a3a000002400240200a28020020032802002205460d00200128020021060c010b200541016a22062005490dc701200541017422092006200920064b1b22094100480dc7010240024020050d002009102821060c010b200128020020052009102c21060b2006450da80120012006360200200141046a2009360200200141086a28020021050b2003200541016a360200200620056a20042d00233a000002400240200a28020020032802002205460d00200128020021060c010b200541016a22062005490dc701200541017422092006200920064b1b22094100480dc7010240024020050d002009102821060c010b200128020020052009102c21060b2006450da90120012006360200200141046a2009360200200141086a28020021050b2003200541016a360200200620056a20002d004c3a000002400240200a28020020032802002205460d00200128020021060c010b200541016a22062005490dc701200541017422092006200920064b1b22094100480dc7010240024020050d002009102821060c010b200128020020052009102c21060b2006450daa0120012006360200200141046a2009360200200141086a28020021050b2003200541016a360200200620056a20042d00253a000002400240200a28020020032802002205460d00200128020021060c010b200541016a22062005490dc701200541017422092006200920064b1b22094100480dc7010240024020050d002009102821060c010b200128020020052009102c21060b2006450dab0120012006360200200141046a2009360200200141086a28020021050b2003200541016a360200200620056a20002d004e3a000002400240200a28020020032802002205460d00200128020021060c010b200541016a22062005490dc701200541017422092006200920064b1b22094100480dc7010240024020050d002009102821060c010b200128020020052009102c21060b2006450dac0120012006360200200141046a2009360200200141086a28020021050b2003200541016a360200200620056a20042d00273a000002400240200a28020020032802002205460d00200128020021060c010b200541016a22062005490dc701200541017422092006200920064b1b22094100480dc7010240024020050d002009102821060c010b200128020020052009102c21060b2006450dad0120012006360200200141046a2009360200200141086a28020021050b2003200541016a360200200620056a20002d00503a000002400240200a28020020032802002205460d00200128020021060c010b200541016a22062005490dc701200541017422092006200920064b1b22094100480dc7010240024020050d002009102821060c010b200128020020052009102c21060b2006450dae0120012006360200200141046a2009360200200141086a28020021050b2003200541016a360200200620056a20042d00293a000002400240200a28020020032802002205460d00200128020021060c010b200541016a22062005490dc701200541017422092006200920064b1b22094100480dc7010240024020050d002009102821060c010b200128020020052009102c21060b2006450daf0120012006360200200141046a2009360200200141086a28020021050b2003200541016a360200200620056a20002d00523a000002400240200a28020020032802002205460d00200128020021060c010b200541016a22062005490dc701200541017422092006200920064b1b22094100480dc7010240024020050d002009102821060c010b200128020020052009102c21060b2006450db00120012006360200200141046a2009360200200141086a28020021050b2003200541016a360200200620056a20042d002b3a000002400240200a28020020032802002205460d00200128020021060c010b200541016a22062005490dc701200541017422092006200920064b1b22094100480dc7010240024020050d002009102821060c010b200128020020052009102c21060b2006450db10120012006360200200141046a2009360200200141086a28020021050b2003200541016a360200200620056a20002d00543a000002400240200a28020020032802002205460d00200128020021060c010b200541016a22062005490dc701200541017422092006200920064b1b22094100480dc7010240024020050d002009102821060c010b200128020020052009102c21060b2006450db20120012006360200200141046a2009360200200141086a28020021050b2003200541016a360200200620056a20042d002d3a000002400240200a28020020032802002205460d00200128020021060c010b200541016a22062005490dc701200541017422092006200920064b1b22094100480dc7010240024020050d002009102821060c010b200128020020052009102c21060b2006450db30120012006360200200141046a2009360200200141086a28020021050b2003200541016a360200200620056a20002d00563a000002400240200a28020020032802002205460d00200128020021060c010b200541016a22062005490dc701200541017422092006200920064b1b22094100480dc7010240024020050d002009102821060c010b200128020020052009102c21060b2006450db40120012006360200200141046a2009360200200141086a28020021050b2003200541016a360200200620056a20042d002f3a000002400240200a28020020032802002205460d00200128020021060c010b200541016a22062005490dc701200541017422092006200920064b1b22094100480dc7010240024020050d002009102821060c010b200128020020052009102c21060b2006450db50120012006360200200141046a2009360200200141086a28020021050b2003200541016a360200200620056a20002d00583a000002400240200a28020020032802002205460d00200128020021060c010b200541016a22062005490dc701200541017422092006200920064b1b22094100480dc7010240024020050d002009102821060c010b200128020020052009102c21060b2006450db60120012006360200200141046a2009360200200141086a28020021050b2003200541016a360200200620056a20042d00313a000002400240200a28020020032802002205460d00200128020021060c010b200541016a22062005490dc701200541017422092006200920064b1b22094100480dc7010240024020050d002009102821060c010b200128020020052009102c21060b2006450db70120012006360200200141046a2009360200200141086a28020021050b2003200541016a360200200620056a20002d005a3a000002400240200a28020020032802002205460d00200128020021060c010b200541016a22062005490dc701200541017422092006200920064b1b22094100480dc7010240024020050d002009102821060c010b200128020020052009102c21060b2006450db80120012006360200200141046a2009360200200141086a28020021050b2003200541016a360200200620056a20042d00333a000002400240200a28020020032802002205460d00200128020021060c010b200541016a22062005490dc701200541017422092006200920064b1b22094100480dc7010240024020050d002009102821060c010b200128020020052009102c21060b2006450db90120012006360200200141046a2009360200200141086a28020021050b2003200541016a360200200620056a20002d005c3a000002400240200a28020020032802002205460d00200128020021060c010b200541016a22062005490dc701200541017422092006200920064b1b22094100480dc7010240024020050d002009102821060c010b200128020020052009102c21060b2006450dba0120012006360200200141046a2009360200200141086a28020021050b2003200541016a360200200620056a20042d00353a000002400240200a28020020032802002205460d00200128020021060c010b200541016a22062005490dc701200541017422092006200920064b1b22094100480dc7010240024020050d002009102821060c010b200128020020052009102c21060b2006450dbb0120012006360200200141046a2009360200200141086a28020021050b2003200541016a360200200620056a20002d005e3a000002400240200a28020020032802002205460d00200128020021060c010b200541016a22062005490dc701200541017422092006200920064b1b22094100480dc7010240024020050d002009102821060c010b200128020020052009102c21060b2006450dbc0120012006360200200141046a2009360200200141086a28020021050b2003200541016a360200200620056a20042d00373a000002400240200a28020020032802002205460d00200128020021060c010b200541016a22062005490dc701200541017422092006200920064b1b22094100480dc7010240024020050d002009102821060c010b200128020020052009102c21060b2006450dbd0120012006360200200141046a2009360200200141086a28020021050b2003200541016a360200200620056a20002d00603a000002400240200a28020020032802002205460d00200128020021060c010b200541016a22062005490dc701200541017422092006200920064b1b22094100480dc7010240024020050d002009102821060c010b200128020020052009102c21060b2006450dbe0120012006360200200141046a2009360200200141086a28020021050b2003200541016a360200200620056a20042d00393a000002400240200a28020020032802002205460d00200128020021060c010b200541016a22062005490dc701200541017422092006200920064b1b22094100480dc7010240024020050d002009102821060c010b200128020020052009102c21060b2006450dbf0120012006360200200141046a2009360200200141086a28020021050b2003200541016a360200200620056a20002d00623a000002400240200a28020020032802002205460d00200128020021060c010b200541016a22062005490dc701200541017422092006200920064b1b22094100480dc7010240024020050d002009102821060c010b200128020020052009102c21060b2006450dc00120012006360200200141046a2009360200200141086a28020021050b2003200541016a360200200620056a20042d003b3a000002400240200a28020020032802002205460d00200128020021060c010b200541016a22062005490dc701200541017422092006200920064b1b22094100480dc7010240024020050d002009102821060c010b200128020020052009102c21060b2006450dc10120012006360200200141046a2009360200200141086a28020021050b2003200541016a360200200620056a20002d00643a000002400240200a28020020032802002200460d00200128020021050c010b200041016a22052000490dc701200041017422062005200620054b1b22064100480dc7010240024020000d002006102821050c010b200128020020002006102c21050b2005450dc20120012005360200200141046a2006360200200141086a28020021000b2003200041016a360200200520006a20042d003d3a000002400240200a28020020032802002200460d00200128020021050c010b200041016a22052000490dc701200041017422062005200620054b1b22064100480dc7010240024020000d002006102821050c010b200128020020002006102c21050b2005450dc30120012005360200200141046a2006360200200141086a28020021000b2003200041016a360200200520006a20042d003e3a000002400240200a28020020032802002200460d00200128020021050c010b200041016a22052000490dc701200041017422062005200620054b1b22064100480dc7010240024020000d002006102821050c010b200128020020002006102c21050b2005450dc40120012005360200200141046a2006360200200141086a28020021000b2003200041016a360200200520006a20042d003f3a00000c030b02400240200141046a280200200141086a2802002203460d00200128020021000c010b200341016a22002003490dc601200341017422042000200420004b1b22044100480dc6010240024020030d002004102821000c010b200128020020032004102c21000b2000450dc40120012000360200200141046a2004360200200141086a28020021030b200141086a200341016a360200200020036a41133a00000c010b02400240200141046a280200200141086a2802002203460d00200128020021000c010b200341016a22002003490dc501200341017422042000200420004b1b22044100480dc5010240024020030d002004102821000c010b200128020020032004102c21000b2000450dc40120012000360200200141046a2004360200200141086a28020021030b200141086a200341016a360200200020036a41143a00000b200110c4010b200241206a24000f0b200541011037000b200441011037000b200541011037000b200041011037000b200541011037000b200341011037000b200541011037000b200041011037000b200441011037000b200541011037000b200541011037000b200541011037000b200041011037000b200441011037000b200541011037000b200541011037000b200541011037000b200541011037000b200341011037000b200441011037000b200541011037000b200441011037000b200441011037000b200441011037000b200541011037000b200541011037000b200441011037000b200441011037000b200441011037000b200541011037000b200541011037000b200441011037000b200541011037000b200541011037000b200441011037000b200541011037000b200441011037000b200441011037000b200441011037000b200541011037000b200541011037000b200441011037000b200441011037000b200541011037000b200541011037000b200541011037000b200041011037000b200a41011037000b200541011037000b200541011037000b200a41011037000b200a41011037000b200a41011037000b200a41011037000b200a41011037000b200341011037000b200541011037000b200541011037000b200541011037000b200941011037000b200341011037000b200341011037000b200441011037000b200541011037000b200541011037000b200441011037000b200541011037000b200441011037000b200a41011037000b200641011037000b200541011037000b200541011037000b200541011037000b200541011037000b200541011037000b1031000b200b41011037000b200341011037000b200341011037000b200541011037000b200b41011037000b200341011037000b200341011037000b200541011037000b200541011037000b200541011037000b200541011037000b200541011037000b200541011037000b200541011037000b200541011037000b200541011037000b200541011037000b200541011037000b200541011037000b200541011037000b200541011037000b200541011037000b200541011037000b200541011037000b200041011037000b200541011037000b200541011037000b200541011037000b200541011037000b200541011037000b200541011037000b200541011037000b200041011037000b200541011037000b200041011037000b200641011037000b200041011037000b200541011037000b200441011037000b200541011037000b200541011037000b200541011037000b200541011037000b200541011037000b200641011037000b200641011037000b200441011037000b200541011037000b200541011037000b200441011037000b200441011037000b200641011037000b200941011037000b200941011037000b200941011037000b200941011037000b200941011037000b200941011037000b200941011037000b200941011037000b200941011037000b200941011037000b200941011037000b200941011037000b200941011037000b200941011037000b200941011037000b200941011037000b200941011037000b200941011037000b200941011037000b200941011037000b200941011037000b200941011037000b1031000b200941011037000b200941011037000b200941011037000b200941011037000b200941011037000b200941011037000b200941011037000b200941011037000b200941011037000b200941011037000b200941011037000b200941011037000b200941011037000b200941011037000b200941011037000b200941011037000b200941011037000b200941011037000b200941011037000b200941011037000b200941011037000b200941011037000b200941011037000b200941011037000b200941011037000b200941011037000b200941011037000b200941011037000b200941011037000b200941011037000b200941011037000b200941011037000b200941011037000b200941011037000b200941011037000b200941011037000b200941011037000b200941011037000b200641011037000b200641011037000b200641011037000b200441011037000b200441011037000b1031000bb31601067f230041106b22022400024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024020012d00000e050003010204000b2002410036020820024201370300410110282203450d05200242818080801037020420022003360200200341023a00002002200236020c200141016a2002410c6a10c8010c040b2002410036020820024201370300410110282203450d05200242818080801037020420022003360200200341043a000002400240200228020420022802082203460d00200228020021040c010b200341016a22042003490d1a200341017422052004200520044b1b22054100480d1a0240024020030d002005102821040c010b200228020020032005102c21040b2004450d0720022005360204200220043602000b2002200341016a360208200420036a20012d00013a000002400240200228020420022802082203460d00200228020021040c010b200341016a22042003490d1a200341017422052004200520044b1b22054100480d1a0240024020030d002005102821040c010b200228020020032005102c21040b2004450d0820022005360204200220043602000b2002200341016a360208200420036a20012d00023a000002400240200228020420022802082203460d00200228020021040c010b200341016a22042003490d1a200341017422052004200520044b1b22054100480d1a0240024020030d002005102821040c010b200228020020032005102c21040b2004450d0920022005360204200220043602000b2002200341016a360208200420036a20012d00033a000002400240200228020420022802082203460d00200228020021040c010b200341016a22042003490d1a200341017422052004200520044b1b22054100480d1a0240024020030d002005102821040c010b200228020020032005102c21040b2004450d0a20022005360204200220043602000b2002200341016a360208200420036a20012d00043a000020012802082105200141106a2802002201200210b4010240024020022802042204200228020822036b2001490d00200228020021040c010b200320016a22062003490d1a200441017422072006200720064b1b22064100480d1a0240024020040d002006102821040c010b200228020020042006102c21040b2004450d0b20022006360204200220043602000b2002200320016a360208200420036a20052001109a051a0c030b2002410036020820024201370300410110282203450d0a200242818080801037020420022003360200200341053a000002400240200228020420022802082203460d00200228020021040c010b200341016a22042003490d19200341017422052004200520044b1b22054100480d190240024020030d002005102821040c010b200228020020032005102c21040b2004450d0c20022005360204200220043602000b2002200341016a360208200420036a20012d00013a000002400240200228020420022802082203460d00200228020021040c010b200341016a22042003490d19200341017422052004200520044b1b22054100480d190240024020030d002005102821040c010b200228020020032005102c21040b2004450d0d20022005360204200220043602000b2002200341016a360208200420036a20012d00023a000002400240200228020420022802082203460d00200228020021040c010b200341016a22042003490d19200341017422052004200520044b1b22054100480d190240024020030d002005102821040c010b200228020020032005102c21040b2004450d0e20022005360204200220043602000b2002200341016a360208200420036a20012d00033a000002400240200228020420022802082203460d00200228020021040c010b200341016a22042003490d19200341017422052004200520044b1b22054100480d190240024020030d002005102821040c010b200228020020032005102c21040b2004450d0f20022005360204200220043602000b2002200341016a360208200420036a20012d00043a000020012802082105200141106a2802002201200210b4010240024020022802042204200228020822036b2001490d00200228020021040c010b200320016a22062003490d19200441017422072006200720064b1b22064100480d190240024020040d002006102821040c010b200228020020042006102c21040b2004450d1020022006360204200220043602000b2002200320016a360208200420036a20052001109a051a0c020b2002410036020820024201370300410110282203450d0f200242818080801037020420022003360200200341063a000002400240200228020420022802082203460d00200228020021040c010b200341016a22042003490d18200341017422052004200520044b1b22054100480d180240024020030d002005102821040c010b200228020020032005102c21040b2004450d1120022005360204200220043602000b2002200341016a360208200420036a20012d00013a000002400240200228020420022802082203460d00200228020021040c010b200341016a22042003490d18200341017422052004200520044b1b22054100480d180240024020030d002005102821040c010b200228020020032005102c21040b2004450d1220022005360204200220043602000b2002200341016a360208200420036a20012d00023a000002400240200228020420022802082203460d00200228020021040c010b200341016a22042003490d18200341017422052004200520044b1b22054100480d180240024020030d002005102821040c010b200228020020032005102c21040b2004450d1320022005360204200220043602000b2002200341016a360208200420036a20012d00033a000002400240200228020420022802082203460d00200228020021040c010b200341016a22042003490d18200341017422052004200520044b1b22054100480d180240024020030d002005102821040c010b200228020020032005102c21040b2004450d1420022005360204200220043602000b2002200341016a360208200420036a20012d00043a000020012802082105200141106a2802002201200210b4010240024020022802042204200228020822036b2001490d00200228020021040c010b200320016a22062003490d18200441017422072006200720064b1b22064100480d180240024020040d002006102821040c010b200228020020042006102c21040b2004450d1520022006360204200220043602000b2002200320016a360208200420036a20052001109a051a0c010b2002410036020820024201370300410110282203450d14200242818080801037020420022003360200200341003a0000200141046a28020021052001410c6a2802002201200210b4010240024020022802042204200228020822036b2001490d00200228020021040c010b200320016a22062003490d17200441017422072006200720064b1b22064100480d170240024020040d002006102821040c010b200228020020042006102c21040b2004450d1620022006360204200220043602000b2002200320016a360208200420036a20052001109a051a0b200020022201290200370200200041086a200141086a280200360200200241106a24000f0b410141011037000b410141011037000b200541011037000b200541011037000b200541011037000b200541011037000b200641011037000b410141011037000b200541011037000b200541011037000b200541011037000b200541011037000b200641011037000b410141011037000b200541011037000b200541011037000b200541011037000b200541011037000b200641011037000b410141011037000b200641011037000b1031000b800801047f230041106b22022400024002400240024002400240024020002d0000417f6a220341034b0d00024002400240024020030e0400010203000b02400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490d0a200341017422052004200520044b1b22054100480d0a0240024020030d002005102821040c010b200128020020032005102c21040b2004450d0520012004360200200141046a2005360200200141086a28020021030b200141086a200341016a360200200420036a41003a0000200028020421032000410c6a2802002200200110b4012000450d0320004105742100034020032001108f01200341206a2103200041606a22000d000c040b0b02400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490d09200341017422052004200520044b1b22054100480d090240024020030d002005102821040c010b200128020020032005102c21040b2004450d0520012004360200200141046a2005360200200141086a28020021030b200141086a200341016a360200200420036a41013a00002000280204200110eb010c020b02400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490d08200341017422052004200520044b1b22054100480d080240024020030d002005102821040c010b200128020020032005102c21040b2004450d0520012004360200200141046a2005360200200141086a28020021030b200141086a200341016a360200200420036a41023a0000200041046a200110a0012000280208200110eb010c010b02400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490d07200341017422052004200520044b1b22054100480d070240024020030d002005102821040c010b200128020020032005102c21040b2004450d0520012004360200200141046a2005360200200141086a28020021030b200141086a2205200341016a360200200420036a41033a00002002200136020c200041016a2002410c6a10c801200041246a200110a00102400240200141046a28020020052802002203460d00200128020021040c010b200341016a22042003490d07200341017422052004200520044b1b22054100480d070240024020030d002005102821040c010b200128020020032005102c21040b2004450d0620012004360200200141046a2005360200200141086a28020021030b200141086a200341016a360200200420036a20002d00213a00000b200241106a24000f0b200541011037000b200541011037000b200541011037000b200541011037000b200541011037000b1031000bf71802047f017e20002802582102024002400240024002400240024002400240024002400240024002400240024002400240024002400240200141046a2802002203200141086a28020022046b4104490d00200128020021030c010b200441046a22052004490d13200341017422042005200420054b1b22044100480d130240024020030d002004102821030c010b200128020020032004102c21030b2003450d0120012003360200200141046a2004360200200141086a28020021040b200141086a2205200441046a360200200320046a20023600002000290300210602400240200141046a2802002203200528020022046b4108490d00200128020021030c010b200441086a22022004490d13200341017422042002200420024b1b22044100480d130240024020030d002004102821030c010b200128020020032004102c21030b2003450d0220012003360200200141046a2004360200200141086a28020021040b200141086a2202200441086a360200200320046a20063700002000290308210602400240200141046a2802002203200228020022046b4108490d00200128020021030c010b200441086a22022004490d13200341017422042002200420024b1b22044100480d130240024020030d002004102821030c010b200128020020032004102c21030b2003450d0320012003360200200141046a2004360200200141086a28020021040b200141086a2202200441086a360200200320046a20063700002000290310210602400240200141046a2802002203200228020022046b4108490d00200128020021030c010b200441086a22022004490d13200341017422042002200420024b1b22044100480d130240024020030d002004102821030c010b200128020020032004102c21030b2003450d0420012003360200200141046a2004360200200141086a28020021040b200141086a2202200441086a360200200320046a20063700002000290318210602400240200141046a2802002203200228020022046b4108490d00200128020021030c010b200441086a22022004490d13200341017422042002200420024b1b22044100480d130240024020030d002004102821030c010b200128020020032004102c21030b2003450d0520012003360200200141046a2004360200200141086a28020021040b200141086a2202200441086a360200200320046a20063700002000290320210602400240200141046a2802002203200228020022046b4108490d00200128020021030c010b200441086a22022004490d13200341017422042002200420024b1b22044100480d130240024020030d002004102821030c010b200128020020032004102c21030b2003450d0620012003360200200141046a2004360200200141086a28020021040b200141086a2202200441086a360200200320046a20063700002000290328210602400240200141046a2802002203200228020022046b4108490d00200128020021030c010b200441086a22022004490d13200341017422042002200420024b1b22044100480d130240024020030d002004102821030c010b200128020020032004102c21030b2003450d0720012003360200200141046a2004360200200141086a28020021040b200141086a2202200441086a360200200320046a20063700002000290330210602400240200141046a2802002203200228020022046b4108490d00200128020021030c010b200441086a22022004490d13200341017422042002200420024b1b22044100480d130240024020030d002004102821030c010b200128020020032004102c21030b2003450d0820012003360200200141046a2004360200200141086a28020021040b200141086a2202200441086a360200200320046a20063700002000290338210602400240200141046a2802002203200228020022046b4108490d00200128020021030c010b200441086a22022004490d13200341017422042002200420024b1b22044100480d130240024020030d002004102821030c010b200128020020032004102c21030b2003450d0920012003360200200141046a2004360200200141086a28020021040b200141086a2202200441086a360200200320046a20063700002000290340210602400240200141046a2802002203200228020022046b4108490d00200128020021030c010b200441086a22022004490d13200341017422042002200420024b1b22044100480d130240024020030d002004102821030c010b200128020020032004102c21030b2003450d0a20012003360200200141046a2004360200200141086a28020021040b200141086a2202200441086a360200200320046a20063700002000290348210602400240200141046a2802002203200228020022046b4108490d00200128020021030c010b200441086a22022004490d13200341017422042002200420024b1b22044100480d130240024020030d002004102821030c010b200128020020032004102c21030b2003450d0b20012003360200200141046a2004360200200141086a28020021040b200141086a2202200441086a360200200320046a20063700002000290350210602400240200141046a2802002203200228020022046b4108490d00200128020021030c010b200441086a22022004490d13200341017422042002200420024b1b22044100480d130240024020030d002004102821030c010b200128020020032004102c21030b2003450d0c20012003360200200141046a2004360200200141086a28020021040b200141086a2202200441086a360200200320046a2006370000200028025c210502400240200141046a2802002203200228020022046b4104490d00200128020021030c010b200441046a22022004490d13200341017422042002200420024b1b22044100480d130240024020030d002004102821030c010b200128020020032004102c21030b2003450d0d20012003360200200141046a2004360200200141086a28020021040b200141086a2202200441046a360200200320046a20053600002000280260210502400240200141046a2802002203200228020022046b4104490d00200128020021030c010b200441046a22022004490d13200341017422042002200420024b1b22044100480d130240024020030d002004102821030c010b200128020020032004102c21030b2003450d0e20012003360200200141046a2004360200200141086a28020021040b200141086a2202200441046a360200200320046a20053600002000280264210502400240200141046a2802002203200228020022046b4104490d00200128020021030c010b200441046a22022004490d13200341017422042002200420024b1b22044100480d130240024020030d002004102821030c010b200128020020032004102c21030b2003450d0f20012003360200200141046a2004360200200141086a28020021040b200141086a2202200441046a360200200320046a20053600002000280268210502400240200141046a2802002203200228020022046b4104490d00200128020021030c010b200441046a22022004490d13200341017422042002200420024b1b22044100480d130240024020030d002004102821030c010b200128020020032004102c21030b2003450d1020012003360200200141046a2004360200200141086a28020021040b200141086a2202200441046a360200200320046a200536000002400240200141046a28020020022802002204460d00200128020021030c010b200441016a22032004490d13200441017422022003200220034b1b22024100480d130240024020040d002002102821030c010b200128020020042002102c21030b2003450d1120012003360200200141046a2002360200200141086a28020021040b200141086a2202200441016a360200200320046a20002d00703a0000200028026c210302400240200141046a2802002204200228020022006b4104490d00200128020021040c010b200041046a22022000490d13200441017422002002200020024b1b22004100480d130240024020040d002000102821040c010b200128020020042000102c21040b2004450d1220012004360200200141046a2000360200200141086a28020021000b200141086a200041046a360200200420006a20033600000f0b200441011037000b200441011037000b200441011037000b200441011037000b200441011037000b200441011037000b200441011037000b200441011037000b200441011037000b200441011037000b200441011037000b200441011037000b200441011037000b200441011037000b200441011037000b200441011037000b200241011037000b200041011037000b1031000bb90201057f230041106b2203240020034100360208200342013703002001200310b4010240024002402001450d00200141b0016c2104034020004188016a28020021050240024020032802042206200328020822016b4104490d00200328020021060c010b200141046a22072001490d04200641017422012007200120074b1b22014100480d040240024020060d002001102821060c010b200328020020062001102c21060b2006450d032003200136020420032006360200200328020821010b2003200141046a360208200620016a20053600002000200310eb012000418c016a2003108f01200041b0016a2100200441d07e6a22040d000b0b2003280204210020022802002002280204200328020022012003280208100702402000450d002001102a0b200341106a24000f0b200141011037000b1031000bee1405177f017e017f027e047f230041206b220224000240024020014115490d0002402001410176220341ffffff3f712003470d0020034105742204417f4c0d0041012105024002402004450d00200410282205450d010b200041606a2106200041a07f6a210741002108410021094104210a4100210b2001210c034002400240200c220d417f6a220e0d004101210f4100210c0c010b0240024002400240024002402000200e4105746a200d410574221020006a41406a4120109c054100480d004102200d6b210e200720106a21044101210f03400240200e200f6a4101470d004100210c200d210f0c080b200f41016a210f200441206a20044120109c052111200441606a21042011417f4a0d000b200d200f6b210e0c010b200720106a2104024003400240200e4101470d004100210e0c020b200e417f6a210e200441206a20044120109c052111200441606a210420114100480d000b0b200d200e490d01200d20014b0d03200d200e6b220f4101762212450d00200620106a21042000200e4105746a21110340200241186a2210201141186a2213290000370300200241106a2214201141106a2215290000370300200241086a2216201141086a221729000037030020022011290000370300200441086a22182900002119200441106a221a290000211b200441186a220c290000211c201120042900003700002013201c3700002015201b37000020172019370000200c2010290300370000201a20142903003700002018201629030037000020042002290300370000200441606a2104201141206a21112012417f6a22120d000b0b0240200e0d00200e210c0c050b0240200f41094d0d00200e210c0c050b200d20014b0d01200d200e6b21122000200e4105746a21100340200d200e417f6a220c490d040240200d200c6b220f4102490d002000200e4105746a22042000200c4105746a220e4120109c05417f4a0d00200e2900002119200e2004290000370000200241186a2216200e41186a2211290000370300200241106a2217200e41106a2213290000370300200241086a2218200e41086a22142900003703002014200441086a2900003700002013200441106a2900003700002011200441186a29000037000020022019370300410121150240200f4103490d00200e41c0006a20024120109c05417f4a0d00410221112010210402400340200441186a200441386a290000370000200441106a200441306a290000370000200441086a200441286a2900003700002004200441206a221329000037000020122011460d01200441c0006a21142011211520132104201141016a2111201420024120109c05417f4a0d020c000b0b201121150b200e20154105746a22042002290300370000200441186a2016290300370000200441106a2017290300370000200441086a20182903003700000b200c450d05201041606a2110201241016a2112200c210e200f410a4f0d050c000b0b200e200d1044000b200d200e417f6a220c490d010b200d2001103c000b200c200d1044000b024002400240200b2009470d0002400240200941016a22042009490d00200941017422112004201120044b1b220441ffffffff01712004470d002004410374221141004e0d010b1031000b0240024020090d0020111028210a0c010b200a20094103742011102c210a0b200a450d01200421092008210b0b200a200b4103746a2204200f3602042004200c360200200841016a220b2108200b4102490d01024003400240024002400240200a200b417f6a22084103746a2204280200450d00200b410374200a6a220f41746a280200220e200428020422114d0d000240200b41024b0d00200b21084102210b0c080b200a200b417d6a22164103746a28020422042011200e6a4d0d010240200b41034b0d00200b21084103210b0c080b200f41646a2802002004200e6a4d0d01200b21080c070b200b4103490d0120042802042111200a200b417d6a22164103746a28020421040b20042011490d010b200b417e6a21160b024002400240024002400240200b201641016a221d4b221e450d00200b20164b221f450d01200a20164103746a2217280204222020172802006a2204200a201d4103746a2218280200221a490d02200420014b0d032000201a4105746a22142018280204221541057422116a210f2004410574210e2004201a6b220d20156b220420154f0d042005200f20044105742211109a05221320116a21120240024020154101480d00200441014e0d010b200f2104201321110c060b2006200e6a210e200f21040340200e200441606a220f201241606a220d200d200f4120109c0541004822101b2211290000370000200e41186a201141186a290000370000200e41106a201141106a290000370000200e41086a201141086a2900003700002012200d20101b211202402014200f200420101b2204490d00201321110c070b200e41606a210e2013211120132012490d000c060b0b41b8dbc000201d200b1034000b41b8dbc0002016200b1034000b201a20041044000b20042001103c000b200520142011109a05221320116a21120240024020154101480d00200d20154a0d010b20142104201321110c010b2000200e6a2110201321112014210403402004200f2011200f20114120109c05410048220d1b220e290000370000200441186a200e41186a290000370000200441106a200e41106a290000370000200441086a200e41086a2900003700002011201141206a200d1b2111200441206a2104200f41206a200f200d1b220f20104f0d01201220114b0d000b0b20042011201220116b416071109a051a0240201f450d002017201a360200201741046a202020156a360200201e450d022018201841086a200b201d417f736a410374109b051a2008210b200841014d0d040c010b0b41c8dbc0002016200b1034000b41b0b1c0001032000b201141041037000b200c0d000b02402009450d00200a102a0b2003450d032005102a0c030b200441011037000b1036000b20014102490d002001417f6a2111200141057420006a41206a2110410121120340024002400240024020112204417f6a221120014b0d00200120116b220e4102490d03200020044105746a2204200020114105746a220d4120109c05417f4a0d03200d2900002119200d2004290000370000200241186a2214200d41186a220f290000370300200241106a220b200d41106a2213290000370300200241086a2215200d41086a220a290000370300200a200441086a2900003700002013200441106a290000370000200f200441186a2900003700002002201937030041012104200e4103490d02200d41c0006a20024120109c05417f4a0d0241002113201021040340200441406a220e200441606a220f290000370000200e41186a200f41186a290000370000200e41106a200f41106a290000370000200e41086a200f41086a29000037000020122013220e460d02200e417f6a2113200420024120109c05210f200441206a2104200f417f4a0d020c000b0b201120011044000b4102200e6b21040b200d20044105746a22042002290300370000200441186a2014290300370000200441106a200b290300370000200441086a20152903003700000b201041606a21102012417f6a211220110d000b0b200241206a24000ba3950103057f027e027f230041106b220224000240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024020002d00000e10000102030405060708090a0b0c0d0e0f000b02400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490d5c200341017422052004200520044b1b22054100480d5c0240024020030d002005102821040c010b200128020020032005102c21040b2004450d1120012004360200200141046a2005360200200141086a28020021030b200141086a2205200341016a360200200420036a41003a0000200141046a28020021042005280200210302402000410c6a2d000022054102470d000240024020042003460d00200128020021000c010b200341016a22002003490d5d200341017422042000200420004b1b22044100480d5d0240024020030d002004102821000c010b200128020020032004102c21000b2000450d1320012000360200200141046a2004360200200141086a28020021030b200141086a200341016a360200200020036a41003a00000c100b0240024020042003460d00200128020021040c010b200341016a22042003490d5c200341017422062004200620044b1b22064100480d5c0240024020030d002006102821040c010b200128020020032006102c21040b2004450d1320012004360200200141046a2006360200200141086a28020021030b200141086a2206200341016a360200200420036a41013a00000240024020054101460d0002400240200141046a28020020062802002203460d00200128020021040c010b200341016a22042003490d5e200341017422052004200520044b1b22054100480d5e0240024020030d002005102821040c010b200128020020032005102c21040b2004450d1620012004360200200141046a2005360200200141086a28020021030b200141086a200341016a360200200420036a41003a00000c010b02400240200141046a28020020062802002203460d00200128020021040c010b200341016a22042003490d5d200341017422052004200520044b1b22054100480d5d0240024020030d002005102821040c010b200128020020032005102c21040b2004450d1620012004360200200141046a2005360200200141086a28020021030b200141086a2205200341016a360200200420036a41013a000002400240200141046a28020020052802002203460d00200128020021040c010b200341016a22042003490d5d200341017422052004200520044b1b22054100480d5d0240024020030d002005102821040c010b200128020020032005102c21040b2004450d1720012004360200200141046a2005360200200141086a28020021030b200141086a200341016a360200200420036a20002d000d3a00000b02400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490d5c200341017422052004200520044b1b22054100480d5c0240024020030d002005102821040c010b200128020020032005102c21040b2004450d1720012004360200200141046a2005360200200141086a28020021030b200141086a200341016a360200200420036a20002d000e3a00000c0f0b02400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490d5b200341017422052004200520044b1b22054100480d5b0240024020030d002005102821040c010b200128020020032005102c21040b2004450d1720012004360200200141046a2005360200200141086a28020021030b200141086a2205200341016a360200200420036a41013a000002400240200141046a28020020052802002203460d00200128020021040c010b200341016a22042003490d5b200341017422052004200520044b1b22054100480d5b0240024020030d002005102821040c010b200128020020032005102c21040b2004450d1820012004360200200141046a2005360200200141086a28020021030b200141086a2205200341016a360200200420036a41003a0000200041086a2001108f012000280204210402400240200141046a2802002203200528020022006b4104490d00200128020021030c010b200041046a22052000490d5b200341017422002005200020054b1b22004100480d5b0240024020030d002000102821030c010b200128020020032000102c21030b2003450d1920012003360200200141046a2000360200200141086a28020021000b200141086a200041046a360200200320006a20043600000c0e0b02400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490d5a200341017422052004200520044b1b22054100480d5a0240024020030d002005102821040c010b200128020020032005102c21040b2004450d1920012004360200200141046a2005360200200141086a28020021030b200141086a200341016a360200200420036a41023a000020002d0008220341024b0d0d02400240024020030e03000102000b02400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490d5c200341017422052004200520044b1b22054100480d5c0240024020030d002005102821040c010b200128020020032005102c21040b2004450d1c20012004360200200141046a2005360200200141086a28020021030b200141086a2205200341016a360200200420036a41003a0000200041096a2001108f01200041386a29030021072000290330210802400240200141046a2802002203200528020022006b4110490d00200128020021030c010b200041106a22042000490d5c200341017422002004200020044b1b22004100480d5c0240024020030d002000102821030c010b200128020020032000102c21030b2003450d1d20012003360200200141046a2000360200200141086a28020021000b200141086a200041106a360200200320006a22012007370008200120083700000c0f0b02400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490d5b200341017422052004200520044b1b22054100480d5b0240024020030d002005102821040c010b200128020020032005102c21040b2004450d1d20012004360200200141046a2005360200200141086a28020021030b200141086a200341016a360200200420036a41013a0000200041096a2001108f010c0e0b02400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490d5a200341017422052004200520044b1b22054100480d5a0240024020030d002005102821040c010b200128020020032005102c21040b2004450d1d20012004360200200141046a2005360200200141086a28020021030b200141086a2205200341016a360200200420036a41023a0000200041096a2001108f01200041296a2001108f01200041d8006a29030021072000290350210802400240200141046a2802002204200528020022036b4110490d00200128020021040c010b200341106a22052003490d5a200441017422032005200320054b1b22034100480d5a0240024020040d002003102821040c010b200128020020042003102c21040b2004450d1e20012004360200200141046a2003360200200141086a28020021030b200141086a2205200341106a360200200420036a2203200737000820032008370000200041e8006a29030021072000290360210802400240200141046a2802002203200528020022006b4110490d00200128020021030c010b200041106a22042000490d5a200341017422002004200020044b1b22004100480d5a0240024020030d002000102821030c010b200128020020032000102c21030b2003450d1f20012003360200200141046a2000360200200141086a28020021000b200141086a200041106a360200200320006a22012007370008200120083700000c0d0b02400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490d59200341017422052004200520044b1b22054100480d590240024020030d002005102821040c010b200128020020032005102c21040b2004450d1f20012004360200200141046a2005360200200141086a28020021030b200141086a200341016a360200200420036a41033a000020002d0008220341024b0d0c02400240024020030e03000102000b02400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490d5b200341017422052004200520044b1b22054100480d5b0240024020030d002005102821040c010b200128020020032005102c21040b2004450d2220012004360200200141046a2005360200200141086a28020021030b200141086a2205200341016a360200200420036a41003a0000200041186a29030021072000290310210802400240200141046a2802002203200528020022006b4110490d00200128020021030c010b200041106a22042000490d5b200341017422002004200020044b1b22004100480d5b0240024020030d002000102821030c010b200128020020032000102c21030b2003450d2320012003360200200141046a2000360200200141086a28020021000b200141086a200041106a360200200320006a22012007370008200120083700000c0e0b02400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490d5a200341017422052004200520044b1b22054100480d5a0240024020030d002005102821040c010b200128020020032005102c21040b2004450d2320012004360200200141046a2005360200200141086a28020021030b200141086a2205200341016a360200200420036a41013a0000200041096a2001108f01200041386a29030021072000290330210802400240200141046a2802002203200528020022006b4110490d00200128020021030c010b200041106a22042000490d5a200341017422002004200020044b1b22004100480d5a0240024020030d002000102821030c010b200128020020032000102c21030b2003450d2420012003360200200141046a2000360200200141086a28020021000b200141086a200041106a360200200320006a22012007370008200120083700000c0d0b02400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490d59200341017422052004200520044b1b22054100480d590240024020030d002005102821040c010b200128020020032005102c21040b2004450d2420012004360200200141046a2005360200200141086a28020021030b200141086a2205200341016a360200200420036a41023a0000200028020c210402400240200141046a2802002203200528020022006b4104490d00200128020021030c010b200041046a22052000490d59200341017422002005200020054b1b22004100480d590240024020030d002000102821030c010b200128020020032000102c21030b2003450d2520012003360200200141046a2000360200200141086a28020021000b200141086a200041046a360200200320006a20043600000c0c0b02400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490d58200341017422052004200520044b1b22054100480d580240024020030d002005102821040c010b200128020020032005102c21040b2004450d2520012004360200200141046a2005360200200141086a28020021030b200141086a2205200341016a360200200420036a41043a000002400240200141046a28020020052802002203460d00200128020021040c010b200341016a22042003490d58200341017422052004200520044b1b22054100480d580240024020030d002005102821040c010b200128020020032005102c21040b2004450d2620012004360200200141046a2005360200200141086a28020021030b200141086a2205200341016a360200200420036a41003a00002000280204210402400240200141046a2802002203200528020022006b4104490d00200128020021030c010b200041046a22052000490d58200341017422002005200020054b1b22004100480d580240024020030d002000102821030c010b200128020020032000102c21030b2003450d2720012003360200200141046a2000360200200141086a28020021000b200141086a200041046a360200200320006a20043600000c0b0b02400240200141046a2206280200200141086a22042802002203460d00200128020021050c010b200341016a22052003490d57200341017422092005200920054b1b22094100480d570240024020030d002009102821050c010b200128020020032009102c21050b2005450d2720012005360200200141046a2009360200200141086a28020021030b2004200341016a360200200520036a41053a000020002d00082203410a4b0d0a0240024002400240024002400240024002400240024020030e0b000102030405060708090a000b02400240200628020020042802002203460d00200128020021050c010b200341016a22052003490d61200341017422092005200920054b1b22094100480d610240024020030d002009102821050c010b200128020020032009102c21050b2005450d3220012005360200200141046a2009360200200141086a28020021030b2004200341016a360200200520036a41003a0000200028020c21090240024020062802002205200428020022036b4104490d00200128020021050c010b200341046a220a2003490d6120054101742203200a2003200a4b1b22034100480d610240024020050d002003102821050c010b200128020020052003102c21050b2005450d3320012005360200200141046a2003360200200141086a28020021030b2004200341046a360200200520036a2009360000200041186a2903002107200029031021080240024020062802002203200428020022006b4110490d00200128020021030c010b200041106a22052000490d61200341017422002005200020054b1b22004100480d610240024020030d002000102821030c010b200128020020032000102c21030b2003450d3420012003360200200141046a2000360200200141086a28020021000b2004200041106a360200200320006a22012007370008200120083700000c140b02400240200628020020042802002203460d00200128020021050c010b200341016a22052003490d60200341017422092005200920054b1b22094100480d600240024020030d002009102821050c010b200128020020032009102c21050b2005450d3420012005360200200141046a2009360200200141086a28020021030b2004200341016a360200200520036a41013a0000200028020c21090240024020062802002205200428020022036b4104490d00200128020021050c010b200341046a220a2003490d6020054101742203200a2003200a4b1b22034100480d600240024020050d002003102821050c010b200128020020052003102c21050b2005450d3520012005360200200141046a2003360200200141086a28020021030b2004200341046a360200200520036a2009360000200041286a2903002107200029032021080240024020062802002205200428020022036b4110490d00200128020021040c010b200341106a22042003490d60200541017422032004200320044b1b22034100480d600240024020050d002003102821040c010b200128020020052003102c21040b2004450d3620012004360200200141046a2003360200200141086a28020021030b200141086a200341106a360200200420036a220320073700082003200837000020002802102103200041186a2802002200200110b4012000450d1320004105742100034020032001108f01200341206a2103200041606a22000d000c140b0b02400240200628020020042802002200460d00200128020021030c010b200041016a22032000490d5f200041017422052003200520034b1b22054100480d5f0240024020000d002005102821030c010b200128020020002005102c21030b2003450d3620012003360200200141046a2005360200200141086a28020021000b2004200041016a360200200320006a41023a00000c120b02400240200628020020042802002203460d00200128020021050c010b200341016a22052003490d5e200341017422092005200920054b1b22094100480d5e0240024020030d002009102821050c010b200128020020032009102c21050b2005450d3620012005360200200141046a2009360200200141086a28020021030b2004200341016a360200200520036a41033a0000200028020c21090240024020062802002205200428020022036b4104490d00200128020021050c010b200341046a220a2003490d5e20054101742203200a2003200a4b1b22034100480d5e0240024020050d002003102821050c010b200128020020052003102c21050b2005450d3720012005360200200141046a2003360200200141086a28020021030b2004200341046a360200200520036a200936000020002d0009220041024b0d1102400240024020000e03000102000b02400240200628020020042802002200460d00200128020021030c010b200041016a22032000490d60200041017422052003200520034b1b22054100480d600240024020000d002005102821030c010b200128020020002005102c21030b2003450d3a20012003360200200141046a2005360200200141086a28020021000b2004200041016a360200200320006a41003a00000c130b02400240200628020020042802002200460d00200128020021030c010b200041016a22032000490d5f200041017422052003200520034b1b22054100480d5f0240024020000d002005102821030c010b200128020020002005102c21030b2003450d3a20012003360200200141046a2005360200200141086a28020021000b2004200041016a360200200320006a41013a00000c120b02400240200628020020042802002200460d00200128020021030c010b200041016a22032000490d5e200041017422052003200520034b1b22054100480d5e0240024020000d002005102821030c010b200128020020002005102c21030b2003450d3a20012003360200200141046a2005360200200141086a28020021000b2004200041016a360200200320006a41023a00000c110b02400240200628020020042802002203460d00200128020021050c010b200341016a22052003490d5d200341017422092005200920054b1b22094100480d5d0240024020030d002009102821050c010b200128020020032009102c21050b2005450d3a20012005360200200141046a2009360200200141086a28020021030b2004200341016a360200200520036a41043a0000200028020c21050240024020062802002203200428020022006b4104490d00200128020021030c010b200041046a22062000490d5d200341017422002006200020064b1b22004100480d5d0240024020030d002000102821030c010b200128020020032000102c21030b2003450d3b20012003360200200141046a2000360200200141086a28020021000b2004200041046a360200200320006a20053600000c100b02400240200628020020042802002203460d00200128020021050c010b200341016a22052003490d5c200341017422092005200920054b1b22094100480d5c0240024020030d002009102821050c010b200128020020032009102c21050b2005450d3b20012005360200200141046a2009360200200141086a28020021030b2004200341016a360200200520036a41053a0000200028020c21050240024020062802002203200428020022006b4104490d00200128020021030c010b200041046a22062000490d5c200341017422002006200020064b1b22004100480d5c0240024020030d002000102821030c010b200128020020032000102c21030b2003450d3c20012003360200200141046a2000360200200141086a28020021000b2004200041046a360200200320006a20053600000c0f0b02400240200628020020042802002203460d00200128020021050c010b200341016a22052003490d5b200341017422092005200920054b1b22094100480d5b0240024020030d002009102821050c010b200128020020032009102c21050b2005450d3c20012005360200200141046a2009360200200141086a28020021030b2004200341016a360200200520036a41063a0000200028020c21050240024020062802002203200428020022006b4104490d00200128020021030c010b200041046a22062000490d5b200341017422002006200020064b1b22004100480d5b0240024020030d002000102821030c010b200128020020032000102c21030b2003450d3d20012003360200200141046a2000360200200141086a28020021000b2004200041046a360200200320006a20053600000c0e0b02400240200628020020042802002203460d00200128020021050c010b200341016a22052003490d5a200341017422092005200920054b1b22094100480d5a0240024020030d002009102821050c010b200128020020032009102c21050b2005450d3d20012005360200200141046a2009360200200141086a28020021030b2004200341016a360200200520036a41073a0000200028020c21090240024020062802002205200428020022036b4104490d00200128020021050c010b200341046a220a2003490d5a20054101742203200a2003200a4b1b22034100480d5a0240024020050d002003102821050c010b200128020020052003102c21050b2005450d3e20012005360200200141046a2003360200200141086a28020021030b2004200341046a360200200520036a200936000002400240200628020020042802002203460d00200128020021050c010b200341016a22052003490d5a200341017422062005200620054b1b22064100480d5a0240024020030d002006102821050c010b200128020020032006102c21050b2005450d3f20012005360200200141046a2006360200200141086a28020021030b2004200341016a360200200520036a20002d00093a00000c0d0b02400240200628020020042802002203460d00200128020021040c010b200341016a22042003490d59200341017422052004200520044b1b22054100480d590240024020030d002005102821040c010b200128020020032005102c21040b2004450d3f20012004360200200141046a2005360200200141086a28020021030b200141086a200341016a360200200420036a41083a0000200041096a2001108f01200041296a2001108f010c0c0b02400240200628020020042802002203460d00200128020021040c010b200341016a22042003490d58200341017422052004200520044b1b22054100480d580240024020030d002005102821040c010b200128020020032005102c21040b2004450d3f20012004360200200141046a2005360200200141086a28020021030b200141086a200341016a360200200420036a41093a0000200041096a2001108f010c0b0b02400240200628020020042802002203460d00200128020021050c010b200341016a22052003490d57200341017422062005200620054b1b22064100480d570240024020030d002006102821050c010b200128020020032006102c21050b2005450d3f20012005360200200141046a2006360200200141086a28020021030b200141086a2206200341016a360200200520036a410a3a0000200041096a2001108f0120022001360208200041296a200241086a10c801200028024c210502400240200141046a2802002203200628020022006b4104490d00200128020021030c010b200041046a22062000490d57200341017422002006200020064b1b22004100480d570240024020030d002000102821030c010b200128020020032000102c21030b2003450d4020012003360200200141046a2000360200200141086a28020021000b2004200041046a360200200320006a20053600000c0a0b02400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490d56200341017422052004200520044b1b22054100480d560240024020030d002005102821040c010b200128020020032005102c21040b2004450d4020012004360200200141046a2005360200200141086a28020021030b200141086a200341016a360200200420036a41063a0000200041046a200110f2010c090b02400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490d55200341017422052004200520044b1b22054100480d550240024020030d002005102821040c010b200128020020032005102c21040b2004450d4020012004360200200141046a2005360200200141086a28020021030b200141086a200341016a360200200420036a41073a0000200041046a200110f2010c080b02400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490d54200341017422052004200520044b1b22054100480d540240024020030d002005102821040c010b200128020020032005102c21040b2004450d4020012004360200200141046a2005360200200141086a28020021030b200141086a2205200341016a360200200420036a41083a0000024002400240024020002d00040e0400010203000b02400240200141046a28020020052802002203460d00200128020021040c010b200341016a22042003490d57200341017422052004200520044b1b22054100480d570240024020030d002005102821040c010b200128020020032005102c21040b2004450d4420012004360200200141046a2005360200200141086a28020021030b200141086a200341016a360200200420036a41003a0000200041056a2001108f01200041256a2001108f010c0a0b02400240200141046a28020020052802002203460d00200128020021040c010b200341016a22042003490d56200341017422052004200520044b1b22054100480d560240024020030d002005102821040c010b200128020020032005102c21040b2004450d4420012004360200200141046a2005360200200141086a28020021030b200141086a200341016a360200200420036a41013a0000200041056a2001108f010c090b02400240200141046a28020020052802002203460d00200128020021040c010b200341016a22042003490d55200341017422052004200520044b1b22054100480d550240024020030d002005102821040c010b200128020020032005102c21040b2004450d4420012004360200200141046a2005360200200141086a28020021030b200141086a2205200341016a360200200420036a41023a00002000280208210402400240200141046a2802002203200528020022006b4104490d00200128020021030c010b200041046a22052000490d55200341017422002005200020054b1b22004100480d550240024020030d002000102821030c010b200128020020032000102c21030b2003450d4520012003360200200141046a2000360200200141086a28020021000b200141086a200041046a360200200320006a20043600000c080b02400240200141046a28020020052802002203460d00200128020021040c010b200341016a22042003490d54200341017422052004200520044b1b22054100480d540240024020030d002005102821040c010b200128020020032005102c21040b2004450d4520012004360200200141046a2005360200200141086a28020021030b200141086a200341016a360200200420036a41033a000020002802082103200041106a2802002204200110b40102402004450d0020044105742104034020032001108f01200341206a2103200441606a22040d000b0b200028021421032000411c6a2802002200200110b4012000450d0720004105742100034020032001108f01200341206a2103200041606a22000d000c080b0b02400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490d53200341017422052004200520044b1b22054100480d530240024020030d002005102821040c010b200128020020032005102c21040b2004450d4520012004360200200141046a2005360200200141086a28020021030b200141086a200341016a360200200420036a41093a000020002d0001220041044b0d060240024002400240024020000e050001020304000b02400240200141046a280200200141086a2802002200460d00200128020021030c010b200041016a22032000490d57200041017422042003200420034b1b22044100480d570240024020000d002004102821030c010b200128020020002004102c21030b2003450d4a20012003360200200141046a2004360200200141086a28020021000b200141086a200041016a360200200320006a41003a00000c0a0b02400240200141046a280200200141086a2802002200460d00200128020021030c010b200041016a22032000490d56200041017422042003200420034b1b22044100480d560240024020000d002004102821030c010b200128020020002004102c21030b2003450d4a20012003360200200141046a2004360200200141086a28020021000b200141086a200041016a360200200320006a41013a00000c090b02400240200141046a280200200141086a2802002200460d00200128020021030c010b200041016a22032000490d55200041017422042003200420034b1b22044100480d550240024020000d002004102821030c010b200128020020002004102c21030b2003450d4a20012003360200200141046a2004360200200141086a28020021000b200141086a200041016a360200200320006a41023a00000c080b02400240200141046a280200200141086a2802002200460d00200128020021030c010b200041016a22032000490d54200041017422042003200420034b1b22044100480d540240024020000d002004102821030c010b200128020020002004102c21030b2003450d4a20012003360200200141046a2004360200200141086a28020021000b200141086a200041016a360200200320006a41033a00000c070b02400240200141046a280200200141086a2802002200460d00200128020021030c010b200041016a22032000490d53200041017422042003200420034b1b22044100480d530240024020000d002004102821030c010b200128020020002004102c21030b2003450d4a20012003360200200141046a2004360200200141086a28020021000b200141086a200041016a360200200320006a41043a00000c060b02400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490d52200341017422052004200520044b1b22054100480d520240024020030d002005102821040c010b200128020020032005102c21040b2004450d4a20012004360200200141046a2005360200200141086a28020021030b200141086a200341016a360200200420036a410a3a00002000280204220341024b0d0502400240024020030e03000102000b02400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490d54200341017422052004200520044b1b22054100480d540240024020030d002005102821040c010b200128020020032005102c21040b2004450d4d20012004360200200141046a2005360200200141086a28020021030b200141086a2205200341016a360200200420036a41003a000020002802082103200041106a2802002200200110b4012000450d072003200041286c6a210a200141046a2106034020032001108f01200341206a29030021070240024020062802002204200528020022006b4108490d00200128020021040c010b200041086a22092000490d55200441017422002009200020094b1b22004100480d550240024020040d002000102821040c010b200128020020042000102c21040b2004450d4f2001200436020020062000360200200528020021000b2005200041086a360200200420006a2007370000200a200341286a2203470d000c080b0b02400240200141046a280200200141086a2802002200460d00200128020021030c010b200041016a22032000490d53200041017422042003200420034b1b22044100480d530240024020000d002004102821030c010b200128020020002004102c21030b2003450d4e20012003360200200141046a2004360200200141086a28020021000b200141086a200041016a360200200320006a41013a00000c060b02400240200141046a280200200141086a2802002200460d00200128020021030c010b200041016a22032000490d52200041017422042003200420034b1b22044100480d520240024020000d002004102821030c010b200128020020002004102c21030b2003450d4e20012003360200200141046a2004360200200141086a28020021000b200141086a200041016a360200200320006a41023a00000c050b02400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490d51200341017422052004200520044b1b22054100480d510240024020030d002005102821040c010b200128020020032005102c21040b2004450d4e20012004360200200141046a2005360200200141086a28020021030b200141086a200341016a360200200420036a410b3a000020002d0008220341044b0d040240024002400240024020030e050001020304000b02400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490d55200341017422052004200520044b1b22054100480d550240024020030d002005102821040c010b200128020020032005102c21040b2004450d5320012004360200200141046a2005360200200141086a28020021030b200141086a2205200341016a360200200420036a41003a0000200028020c210402400240200141046a2802002203200528020022006b4104490d00200128020021030c010b200041046a22052000490d55200341017422002005200020054b1b22004100480d550240024020030d002000102821030c010b200128020020032000102c21030b2003450d5420012003360200200141046a2000360200200141086a28020021000b200141086a200041046a360200200320006a20043600000c080b02400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490d74200341017422052004200520044b1b22054100480d740240024020030d002005102821040c010b200128020020032005102c21040b2004450d5520012004360200200141046a2005360200200141086a28020021030b200141086a2205200341016a360200200420036a41013a0000200041186a29030021072000290310210802400240200141046a2802002203200528020022006b4110490d00200128020021030c010b200041106a22042000490d74200341017422002004200020044b1b22004100480d740240024020030d002000102821030c010b200128020020032000102c21030b2003450d5620012003360200200141046a2000360200200141086a28020021000b200141086a200041106a360200200320006a22012007370008200120083700000c070b02400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490d73200341017422052004200520044b1b22054100480d730240024020030d002005102821040c010b200128020020032005102c21040b2004450d5620012004360200200141046a2005360200200141086a28020021030b200141086a2205200341016a360200200420036a41023a0000200028022c210602400240200141046a2802002204200528020022036b4104490d00200128020021040c010b200341046a22052003490d73200441017422032005200320054b1b22034100480d730240024020040d002003102821040c010b200128020020042003102c21040b2004450d5720012004360200200141046a2003360200200141086a28020021030b200141086a2205200341046a360200200420036a2006360000200041386a29030021072000290330210802400240200141046a2802002204200528020022036b4110490d00200128020021040c010b200341106a22052003490d73200441017422032005200320054b1b22034100480d730240024020040d002003102821040c010b200128020020042003102c21040b2004450d5820012004360200200141046a2003360200200141086a28020021030b200141086a200341106a360200200420036a2203200737000820032008370000200041096a2001108f010c060b02400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490d72200341017422052004200520044b1b22054100480d720240024020030d002005102821040c010b200128020020032005102c21040b2004450d5820012004360200200141046a2005360200200141086a28020021030b200141086a2205200341016a360200200420036a41033a0000200041186a29030021072000290310210802400240200141046a2802002203200528020022006b4110490d00200128020021030c010b200041106a22042000490d72200341017422002004200020044b1b22004100480d720240024020030d002000102821030c010b200128020020032000102c21030b2003450d5920012003360200200141046a2000360200200141086a28020021000b200141086a200041106a360200200320006a22012007370008200120083700000c050b02400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490d71200341017422052004200520044b1b22054100480d710240024020030d002005102821040c010b200128020020032005102c21040b2004450d5920012004360200200141046a2005360200200141086a28020021030b200141086a2205200341016a360200200420036a41043a0000200041186a29030021072000290310210802400240200141046a2802002203200528020022006b4110490d00200128020021030c010b200041106a22042000490d71200341017422002004200020044b1b22004100480d710240024020030d002000102821030c010b200128020020032000102c21030b2003450d5a20012003360200200141046a2000360200200141086a28020021000b200141086a200041106a360200200320006a22012007370008200120083700000c040b02400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490d70200341017422052004200520044b1b22054100480d700240024020030d002005102821040c010b200128020020032005102c21040b2004450d5a20012004360200200141046a2005360200200141086a28020021030b200141086a200341016a360200200420036a410c3a000020002d0008220341054b0d0302400240024002400240024020030e06000102030405000b02400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490d75200341017422052004200520044b1b22054100480d750240024020030d002005102821040c010b200128020020032005102c21040b2004450d6020012004360200200141046a2005360200200141086a28020021030b200141086a2205200341016a360200200420036a41003a0000200041096a2001108f01200041296a2001108f01200041d8006a29030021072000290350210802400240200141046a2802002203200528020022006b4110490d00200128020021030c010b200041106a22042000490d75200341017422002004200020044b1b22004100480d750240024020030d002000102821030c010b200128020020032000102c21030b2003450d6120012003360200200141046a2000360200200141086a28020021000b200141086a200041106a360200200320006a22012007370008200120083700000c080b02400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490d74200341017422052004200520044b1b22054100480d740240024020030d002005102821040c010b200128020020032005102c21040b2004450d6120012004360200200141046a2005360200200141086a28020021030b200141086a200341016a360200200420036a41013a0000200041096a2001108f01200041296a2001108f010c070b02400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490d73200341017422052004200520044b1b22054100480d730240024020030d002005102821040c010b200128020020032005102c21040b2004450d6120012004360200200141046a2005360200200141086a28020021030b200141086a200341016a360200200420036a41023a00002002200136020c200041096a2002410c6a10c8010c060b02400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490d72200341017422052004200520044b1b22054100480d720240024020030d002005102821040c010b200128020020032005102c21040b2004450d6120012004360200200141046a2005360200200141086a28020021030b200141086a2205200341016a360200200420036a41033a0000200028020c210402400240200141046a2802002203200528020022006b4104490d00200128020021030c010b200041046a22052000490d72200341017422002005200020054b1b22004100480d720240024020030d002000102821030c010b200128020020032000102c21030b2003450d6220012003360200200141046a2000360200200141086a28020021000b200141086a200041046a360200200320006a20043600000c050b02400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490d71200341017422052004200520044b1b22054100480d710240024020030d002005102821040c010b200128020020032005102c21040b2004450d6220012004360200200141046a2005360200200141086a28020021030b200141086a2205200341016a360200200420036a41043a0000200041096a2001108f0102400240200141046a28020020052802002203460d00200128020021040c010b200341016a22042003490d71200341017422052004200520044b1b22054100480d710240024020030d002005102821040c010b200128020020032005102c21040b2004450d6320012004360200200141046a2005360200200141086a28020021030b200141086a200341016a360200200420036a20002d00293a00000c040b02400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490d70200341017422052004200520044b1b22054100480d700240024020030d002005102821040c010b200128020020032005102c21040b2004450d6320012004360200200141046a2005360200200141086a28020021030b200141086a2205200341016a360200200420036a41053a0000200041096a2001108f01200028022c2106200041346a2802002200200110b40102400240200141046a2802002204200528020022036b2000490d00200128020021040c010b200320006a22052003490d70200441017422032005200320054b1b22034100480d700240024020040d002003102821040c010b200128020020042003102c21040b2004450d6420012004360200200141046a2003360200200141086a28020021030b200141086a200320006a360200200420036a20062000109a051a0c030b02400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490d6f200341017422052004200520044b1b22054100480d6f0240024020030d002005102821040c010b200128020020032005102c21040b2004450d6420012004360200200141046a2005360200200141086a28020021030b200141086a200341016a360200200420036a410d3a000020002d0001220341024b0d0202400240024020030e03000102000b02400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490d71200341017422052004200520044b1b22054100480d710240024020030d002005102821040c010b200128020020032005102c21040b2004450d6720012004360200200141046a2005360200200141086a28020021030b200141086a2205200341016a360200200420036a41003a000002400240200141046a28020020052802002203460d00200128020021040c010b200341016a22042003490d71200341017422052004200520044b1b22054100480d710240024020030d002005102821040c010b200128020020032005102c21040b2004450d6820012004360200200141046a2005360200200141086a28020021030b200141086a200341016a360200200420036a20002d00023a00000c040b02400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490d70200341017422052004200520044b1b22054100480d700240024020030d002005102821040c010b200128020020032005102c21040b2004450d6820012004360200200141046a2005360200200141086a28020021030b200141086a200341016a360200200420036a41013a0000200041026a2001108f010c030b02400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490d6f200341017422052004200520044b1b22054100480d6f0240024020030d002005102821040c010b200128020020032005102c21040b2004450d6820012004360200200141046a2005360200200141086a28020021030b200141086a2205200341016a360200200420036a41023a000002400240200141046a28020020052802002203460d00200128020021040c010b200341016a22042003490d6f200341017422052004200520044b1b22054100480d6f0240024020030d002005102821040c010b200128020020032005102c21040b2004450d6920012004360200200141046a2005360200200141086a28020021030b200141086a200341016a360200200420036a20002d00023a00000c020b02400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490d6e200341017422052004200520044b1b22054100480d6e0240024020030d002005102821040c010b200128020020032005102c21040b2004450d6920012004360200200141046a2005360200200141086a28020021030b200141086a2205200341016a360200200420036a410e3a000002400240200141046a28020020052802002203460d00200128020021040c010b200341016a22042003490d6e200341017422052004200520044b1b22054100480d6e0240024020030d002005102821040c010b200128020020032005102c21040b2004450d6a20012004360200200141046a2005360200200141086a28020021030b200141086a200341016a360200200420036a41003a0000200041016a2001108f010c010b02400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490d6d200341017422052004200520044b1b22054100480d6d0240024020030d002005102821040c010b200128020020032005102c21040b2004450d6a20012004360200200141046a2005360200200141086a28020021030b200141086a2205200341016a360200200420036a410f3a000002400240200141046a28020020052802002203460d00200128020021040c010b200341016a22042003490d6d200341017422052004200520044b1b22054100480d6d0240024020030d002005102821040c010b200128020020032005102c21040b2004450d6b20012004360200200141046a2005360200200141086a28020021030b200141086a2205200341016a360200200420036a41003a0000200041106a200110c601200028020421062000410c6a2802002200200110b40102400240200141046a2802002204200528020022036b2000490d00200128020021040c010b200320006a22052003490d6d200441017422032005200320054b1b22034100480d6d0240024020040d002003102821040c010b200128020020042003102c21040b2004450d6c20012004360200200141046a2003360200200141086a28020021030b200141086a200320006a360200200420036a20062000109a051a0b200241106a24000f0b200541011037000b200441011037000b200641011037000b200541011037000b200541011037000b200541011037000b200541011037000b200541011037000b200541011037000b200041011037000b200541011037000b200541011037000b200041011037000b200541011037000b200541011037000b200341011037000b200041011037000b200541011037000b200541011037000b200041011037000b200541011037000b200041011037000b200541011037000b200041011037000b200541011037000b200541011037000b200041011037000b200941011037000b200941011037000b200341011037000b200041011037000b200941011037000b200341011037000b200341011037000b200541011037000b200941011037000b200341011037000b200541011037000b200541011037000b200541011037000b200941011037000b200041011037000b200941011037000b200041011037000b200941011037000b200041011037000b200941011037000b200341011037000b200641011037000b200541011037000b200541011037000b200641011037000b200041011037000b200541011037000b200541011037000b200541011037000b200541011037000b200541011037000b200541011037000b200041011037000b200541011037000b200541011037000b200441011037000b200441011037000b200441011037000b200441011037000b200441011037000b200541011037000b200541011037000b200041011037000b200441011037000b200441011037000b200541011037000b200541011037000b200041011037000b1031000b200541011037000b200041011037000b200541011037000b200341011037000b200341011037000b200541011037000b200041011037000b200541011037000b200041011037000b200541011037000b200541011037000b200041011037000b200541011037000b200541011037000b200541011037000b200041011037000b200541011037000b200541011037000b200541011037000b200341011037000b200541011037000b200541011037000b200541011037000b200541011037000b200541011037000b200541011037000b200541011037000b200541011037000b200541011037000b200541011037000b200341011037000b1031000bfd1201057f230041106b2202240002400240024002400240024002400240024002400240024002400240024020002d0000220341054b0d0002400240024002400240024020030e06000102030405000b02400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490d14200341017422052004200520044b1b22054100480d140240024020030d002005102821040c010b200128020020032005102c21040b2004450d0720012004360200200141046a2005360200200141086a28020021030b200141086a2205200341016a360200200420036a41003a0000200041016a2001108f012000280244210602400240200141046a2802002204200528020022036b4104490d00200128020021040c010b200341046a22052003490d14200441017422032005200320054b1b22034100480d140240024020040d002003102821040c010b200128020020042003102c21040b2004450d0820012004360200200141046a2003360200200141086a28020021030b200141086a2205200341046a360200200420036a20063600002002200136020c200041216a2002410c6a10c8012000280248210402400240200141046a2802002203200528020022006b4104490d00200128020021030c010b200041046a22052000490d14200341017422002005200020054b1b22004100480d140240024020030d002000102821030c010b200128020020032000102c21030b2003450d0920012003360200200141046a2000360200200141086a28020021000b200141086a200041046a360200200320006a20043600000c050b02400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490d13200341017422052004200520044b1b22054100480d130240024020030d002005102821040c010b200128020020032005102c21040b2004450d0920012004360200200141046a2005360200200141086a28020021030b200141086a2205200341016a360200200420036a41013a0000200041016a2001108f012002200136020c200041216a2002410c6a10c80102400240200141046a28020020052802002203460d00200128020021040c010b200341016a22042003490d13200341017422052004200520044b1b22054100480d130240024020030d002005102821040c010b200128020020032005102c21040b2004450d0a20012004360200200141046a2005360200200141086a28020021030b200141086a2205200341016a360200200420036a20002d00413a00002000280244210602400240200141046a2802002204200528020022036b4104490d00200128020021040c010b200341046a22052003490d13200441017422032005200320054b1b22034100480d130240024020040d002003102821040c010b200128020020042003102c21040b2004450d0b20012004360200200141046a2003360200200141086a28020021030b200141086a2205200341046a360200200420036a20063600002000280248210402400240200141046a2802002203200528020022006b4104490d00200128020021030c010b200041046a22052000490d13200341017422002005200020054b1b22004100480d130240024020030d002000102821030c010b200128020020032000102c21030b2003450d0c20012003360200200141046a2000360200200141086a28020021000b200141086a200041046a360200200320006a20043600000c040b02400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490d12200341017422052004200520044b1b22054100480d120240024020030d002005102821040c010b200128020020032005102c21040b2004450d0c20012004360200200141046a2005360200200141086a28020021030b200141086a200341016a360200200420036a41023a00002002200136020c200041016a2002410c6a10c8010c030b02400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490d11200341017422052004200520044b1b22054100480d110240024020030d002005102821040c010b200128020020032005102c21040b2004450d0c20012004360200200141046a2005360200200141086a28020021030b200141086a200341016a360200200420036a41033a00002002200136020c200041016a2002410c6a10c8010c020b02400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490d10200341017422052004200520044b1b22054100480d100240024020030d002005102821040c010b200128020020032005102c21040b2004450d0c20012004360200200141046a2005360200200141086a28020021030b200141086a2205200341016a360200200420036a41043a00002002200136020c200041016a2002410c6a10c80102400240200141046a28020020052802002203460d00200128020021040c010b200341016a22042003490d10200341017422052004200520044b1b22054100480d100240024020030d002005102821040c010b200128020020032005102c21040b2004450d0d20012004360200200141046a2005360200200141086a28020021030b200141086a200341016a360200200420036a20002d00213a00000c010b02400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490d0f200341017422052004200520044b1b22054100480d0f0240024020030d002005102821040c010b200128020020032005102c21040b2004450d0d20012004360200200141046a2005360200200141086a28020021030b200141086a2205200341016a360200200420036a41053a00002002200136020c200041016a2002410c6a10c80102400240200141046a28020020052802002203460d00200128020021040c010b200341016a22042003490d0f200341017422052004200520044b1b22054100480d0f0240024020030d002005102821040c010b200128020020032005102c21040b2004450d0e20012004360200200141046a2005360200200141086a28020021030b200141086a200341016a360200200420036a20002d00213a00000b200241106a24000f0b200541011037000b200341011037000b200041011037000b200541011037000b200541011037000b200341011037000b200041011037000b200541011037000b200541011037000b200541011037000b200541011037000b200541011037000b200541011037000b1031000bf40501027f4190ce0021024100210302400240024002400240024002400240024002400240024002400240024020012802000e15000e08080e01020304050607090e0e0a0e0c0e0e0e000b417f2102200141086a280200417f6a220141054b0d0a41012103024020010e060e0b0d000d0d0e0b41c09a0c21020c0d0b200141086a280200417f6a220141024b0d0941c0843d210241002103024020010e030d000d0d0b4101210341d0860321020c0c0b200141086a2d0000417f6a2201410c4b0d0841a0c21e21024100210302400240024020010e0d0e0e000001010e0e01020808080e0b4180b5182102410021030c0d0b41b0e32d2102410021030c0c0b4101210341f0930921020c0b0b41f093092102410021030c0a0b200141086a2d0000417f6a220141104b0d0641c096b102210241002103024002400240024020010e110d0d0101000d0d0d0101070702020203030d0b4101210341a0c21e21020c0c0b41c09a0c2102410021030c0b0b41a08d062102410021030c0a0b41a0c21e2102410021030c090b20012d0004417f6a220141034b0d054101210341a08d0621020240024020010e040a0a00010a0b41c096b10221020c090b41c09a0c21020c080b20012d0004417f6a220141034b0d044101210341a08d0621020240024020010e0409090001090b41c096b10221020c080b41c09a0c21020c070b200141086a280200417f6a220141094b0d0341a0cb98012102410021030240024020010e0a08080800080102020202080b41d0a5cc002102410021030c070b4180ade2042102410021030c060b410121030c040b41d086034190ce0020012d0004411d7441808080807e6a411d75417f4a1b2102410021030c040b200141086a280200417f6a220141024b0d0041a0c21e210241002103024020010e03040000040b4101210341a08d0621020c030b4190ce002102410021030c020b02402001280204417f6a220141024b0d00410121034100210220010e03020002020b410021030b4190ce0021020b200020033a0004200020023602000be6fe0109017f017e067f017e047f017e0a7f037e177f230041d0076b2203240002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024020012802000e15000102031e1c1b1a191817160f0e0d0c0b0a090807000b200141106a29030021042001410c6a280200210520022d0001210620022d000021020240024002400240024002400240200141086a28020022070e0700060102030405000b200341d4066a4101360200200342013702c406200341ccd1c5003602c006200341043602e405200341c4d1c5003602e0052003200341e0056a3602d006200341c0066a4188a6c300103e000b2004a7210702400240200241ff01710d00200641ff01714101460d010b2007450d2d2005102a0c2d0b2007450d2a2005102a0c2a0b200220067241ff01710d2a410810282202450d09200220043700004198a6c300410a2002410810072002102a0c290b2004a721070240200220067241ff0171450d002007450d2a2005102a0c2a0b41a2a6c300410520052004422088a710072007450d282005102a0c280b2004422088a721082004a721090240200220067241ff0171450d0002402008450d00200841186c21062005210203400240200241046a280200450d002002280200102a0b0240200241106a280200450d002002410c6a280200102a0b200241186a2102200641686a22060d000b0b410121064100210a4105210820090d260c270b0240200841186c2202450d00200520026a21062005210203402002280200200241086a2802002002410c6a280200200241146a2802001007200241186a22022006470d000b0b02402008450d00200841186c21062005210203400240200241046a280200450d002002280200102a0b0240200241106a280200450d002002410c6a280200102a0b200241186a2102200641686a22060d000b0b410121064100210a4107210820090d250c260b2004422088a721082004a721090240200220067241ff0171450d0002402008450d002008410c6c21062005210203400240200241046a280200450d002002280200102a0b2002410c6a2102200641746a22060d000b0b410021064101210a410521082009450d260c250b02402008410c6c2202450d00200520026a21062005210203402002280200200241086a28020010092002410c6a22022006470d000b0b02402008450d002008410c6c21062005210203400240200241046a280200450d002002280200102a0b2002410c6a2102200641746a22060d000b0b410021064101210a4107210820090d240c250b200220067241ff01710d260c250b10f501000b024020022d00000d0020022d000141ff01714102470d00200141086a290300210420034180056a41086a22024200370300200342003703800541d8a1c600411320034180056a1008200341b8026a41086a2206200229030037030020032003290380053703b8020240200341b8026a41104101410041001003417f470d0020024200370300200342003703800541feb3c300410d20034180056a10082006200229030037030020032003290380053703b802200341003602c006200341b8026a4110200341c0066a100621020240024020032802c0062206417f460d002002450d0020064108490d012002290000210b2002102a200b500d004200210b20034180056a41086a22024200370300200342003703800541feb3c300410d20034180056a1008200341b8026a41086a200229030037030020032003290380053703b802200341003602c006200341b8026a4110200341c0066a10062102024020032802c0062206417f460d002002450d0020064108490d072002290000210b2002102a0b200b42dc0b7c2004560d050b20034180056a41086a22024200370300200342003703800541feb3c300410d20034180056a1008200341b8026a41086a2206200229030037030020032003290380053703b802200320043703c006200341b8026a4110200341c0066a4108100741012105200341013a00c00620024200370300200342003703800541d8a1c600411320034180056a10082006200229030037030020032003290380053703b802200341b8026a4110200341c0066a41011007200041023a0008410121060c2b0b41c4d1c3004133200341c8076a419cd9c3001038000b41c8adc3001032000b20004181043b01082000410f360204200041ea9fc6003602002000410a6a41003a00000c1a0b2001410c6a2802002105200141086a280200210c2001280204210d41ea9fc600210e410f210f20022d00000d1e20022d000141ff01714102470d1e20034180056a41086a22024200370300200342003703800541c8fbc500411720034180056a1008200341b8026a41086a200229030037030020032003290380053703b802200341003602c006200341b8026a4110200341c0066a10062102024002400240024020032802c0062206417f460d002002450d002006450d0120022d000021062002102a20064102460d002006410171450d0041a4cdc200210e411c210f0c220b200341013a00c00620034180056a41086a22024200370300200342003703800541c8fbc500411720034180056a1008200341b8026a41086a2206200229030037030020032003290380053703b802200341b8026a4110200341c0066a4101100710980121082002420037030020034200370380054193cdc200411120034180056a10082006200229030037030020032003290380053703b802200341003602c006200341b8026a4110200341c0066a1006210202400240024020032802c0062206417f460d002002450d0020032006360294012003200236029001200341c0066a20034190016a107b20032802c0062207450d0520032902c406210402402006450d002002102a0b200320073602980302402004422088220ba722022004a7470d00200341c0066a21060c020b200341c0066a21060c020b4104210720034104360298034200210441002102200341c0066a21060b024020022004a7470d00200241016a220a2002490d1120024101742209200a2009200a4b1bad220b42c4007e2210422088a70d112010a7220a4100480d110240024020020d00200a102821070c010b2007200241c4006c200a102c21070b2007450d032003200736029803200442808080807083200b8421040b2004422088220ba721020b2007200241c4006c6a22022008360204200241003a000020022006290200370208200241106a200641086a290200370200200241186a200641106a290200370200200241206a200641186a290200370200200241286a200641206a290200370200200241306a200641286a290200370200200241386a200641306a290200370200200241c0006a200641386a280200360200200b422086200442ffffffff0f83844280808080107c2104200d200541f0006c6a2108024020050d00200d21070c200b200341e0056a417f6a210a20034193046a2111200341d7046a21122003419b056a2113200341c0066a41106a2114200341c0066a41086a211520034180056a41186a2116200d2107024003402007280204210220072802002106200341c0066a200741086a41e800109a051a200741f0006a21072002450d2120034190016a200341c0066a41e800109a051a200320023602c406200320063602c006201520034190016a41e800109a051a20032802980321171098012102200341e0056a200341c0066a10f60102400240024020032802c00622060d0041d6cdc200210e4110210f0c010b0240200620024d0d00411a210f41e6cdc200210e0c010b20034198046a2006417f6a10f701024020034198046a20144120109c05450d004119210f4180cec200210e0c010b024020032802c006221841002002417b6a2206200620024b1b4f0d004126210f4199cec200210e0c010b20172004422088220ba7220941c4006c22196a21052017210202400240201941cd01490d00201721020340024020022d00004101470d00200241016a2106200a2002460d032006200341e0056a4120109c05450d030b0240200241c4006a2d00004101470d00200241c5006a210620132002460d032006200341e0056a4120109c05450d030b024020024188016a2d00004101470d0020024189016a210620122002460d032006200341e0056a4120109c05450d030b0240200241cc016a2d00004101470d00200241cd016a210620112002460d032006200341e0056a4120109c05450d030b200520024190026a22026b41cc014b0d000b0b024020022005460d000340024020022d00004101470d00200241016a2106200a2002460d032006200341e0056a4120109c05450d030b2005200241c4006a2202470d000b0b410021060b20034198046a201810f70120034198046a200341e0056a4120109c052102200341b8036a41086a221a20034180056a41086a2205290200370300200341b8036a41106a20034180056a41106a221829020037030020032003290280053703b80341c0cdc200210e4116210f20060d2220020d010c220b200341b8036a41086a20034180056a41086a290200370300200341b8036a41106a20034180056a41106a29020037030020032003290280053703b8030c210b200341b8026a410e6a2206200341b8036a410e6a290100370100200341b8026a41086a220e201a290300370300200320032903b8033703b80220034198046a200341c0066a10f6012016420037030020184200370300200542003703002003420037038005024041c80010282202450d0020034198026a10f8012002410236022020024101360244200241186a20034198026a41186a290300370200200241106a20034198026a41106a290300370200200241086a20034198026a41086a290300370200200220032903980237020020022003290380053700242002412c6a2005290300370000200241346a20182903003700002002413c6a2016290300370000200320023602e00520034282808080203702e405200341e0056a10f901200341f8016a41086a220520034198046a41086a290300370300200341f8016a41106a221820034198046a41106a290300370300200341f8016a41186a220f20034198046a41186a290300370300200341e0056a41086a221a200e290300370300200341e0056a410e6a220e200629010037010020032003290398043703f801200320032903b8023703e0050240024020092004a7460d00200421100c010b200941016a22022009490d13200ba74101742206200220022006491bad221042c4007e220b422088a70d13200ba722064100480d130240024020090d002006102821020c010b201720192006102c21020b2002450d0320032002360298032004422088220ba721090b200328029803200941c4006c6a220241013a0000200f29030021042018290300211b2005290300211c20032903f801211d20024116360028200241c0cdc200360024200241003a00212002413a6a200e290100370000200241346a201a290300370000200220032903e00537002c2002201d370001200241096a201c370000200241116a201b370000200241196a2004370000201042ffffffff0f832104200b422086210b024020032802cc062206450d0020032802c4062102200641246c210603400240024020022d0000220541034b0d0002400240024020050e0404000102040b2002410c6a280200450d03200241086a280200102a0c030b2002410c6a280200450d02200241086a280200102a0c020b2002410c6a280200450d01200241086a280200102a0c010b200241086a280200450d00200241046a280200102a0b200241246a21022006415c6a22060d000b0b200b2004842104024020032802c806450d0020032802c406102a0b20044280808080107c210420072008470d010c230b0b41c80041041037000b200641041037000b41c4d1c3004133200341c8076a419cd9c3001038000b200a41041037000b41c4d1c3004133200341c8076a419cd9c3001038000b4190aec3001032000b41c4d1c3004133200341c8076a419cd9c3001038000b410841011037000b10d601000b10fa01000b200141246a280200211a200141206a280200210f2001411c6a280200210a200141186a2802002118200141146a2802002109200141106a28020021132001410c6a280200210e200141086a280200211920022d0001210620022d000021022001280204210820034190016a41386a200141e0006a29000037030020034190016a41306a200141d8006a29000037030020034190016a41286a200141d0006a29000037030020034190016a41206a200141c8006a29000037030020034190016a41186a200141c0006a29000037030020034190016a41106a200141386a29000037030020034190016a41086a200141306a2900003703002003200141286a2900003703900141ea9fc6002105410f21070240024020020d00200641ff01714102470d00024010fb01200f460d0041fb91c1002105411c21070c010b200341c0066a200f201a10fc0120032802c006220220032802c80641014100410010032106024020032802c406450d002002102a0b20034180056a41086a22024200370300200342003703800541c2e1c000410d20034180056a1008200341b8026a41086a200229030037030020032003290380053703b802200341003602c006200341b8026a4110200341c0066a1006210202400240024002400240024002400240024002400240024020032802c0062205417f460d002002450d002003200536029c042003200236029804200341c0066a20034198046a107c20032802c006220c450d0220032902c40621042005450d012002102a0c010b420021044101210c0b02402006417f460d0041b392c1002105411521070c030b200c201a4105746a4100201a2004422088a7491b22120d0141c892c1002105411821070c020b41c4d1c3004133200341c8076a419cd9c3001038000b200341003602c806200342013703c00602400240024002400240410410282202450d0020034284808080c0003702c406200320023602c006200220083600002013200341c0066a10b4010240024020032802c406220620032802c80622026b2013490d0020032802c00621060c010b200220136a22052002490d16200641017422072005200720054b1b22054100480d160240024020060d002005102821060c010b20032802c00620062005102c21060b2006450d02200320053602c406200320063602c0060b2003200220136a3602c806200620026a20192013109a051a200a200341c0066a10b4012009200a410c6c6a2116200a450d0220092106034020062802002117200641086a2802002202200341c0066a10b4010240024020032802c406220720032802c80622056b2002490d0020032802c00621080c010b200520026a22082005490d172007410174220d2008200d20084b1b220d4100480d170240024020070d00200d102821080c010b20032802c0062007200d102c21080b2008450d052003200d3602c406200320083602c006200d21070b2003200520026a220d3602c806200820056a20172002109a051a2006410c6a22062016470d000c050b0b410441011037000b200541011037000b20032802c406210720032802c806210d0c010b200d41011037000b024002402007200d6b4104490d0020032802c00621020c010b200d41046a2202200d490d11200741017422062002200620024b1b22064100480d110240024020070d002006102821020c010b20032802c00620072006102c21020b2002450d03200320063602c406200320023602c006200621070b2003200d41046a22063602c8062002200d6a200f36000002400240200720066b41034d0d00200721050c010b200641046a22052006490d11200741017422082005200820054b1b22054100480d110240024020070d002005102821020c010b200220072005102c21020b2002450d04200320053602c406200320023602c0060b200220066a201a3600002002200d41086a20034190016a2012100a210602402005450d002002102a0b2006450d01419792c1002105411c21070b2004a7450d07200c102a0c070b201241086a290000210b201241106a29000021102012290000211b20034198026a41186a201241186a290000221c37030020034198026a41106a201037030020034198026a41086a200b3703002003201b37039802200341c9066a200b370000200341d1066a2010370000200341d9066a201c3700002003410e3a00c0062003201b3700c10641014100200341c0066a10cc01200341003602c806200342013703c0062013200341c0066a10b4010240024020032802c406220620032802c80622026b2013490d0020032802c00621060c010b200220136a22052002490d0f200641017422072005200720054b1b22054100480d0f0240024020060d002005102821060c010b20032802c00620062005102c21060b2006450d03200320053602c406200320063602c0060b2003200220136a3602c806200620026a20192013109a051a200a200341c0066a10b401200a450d0320092106034020062802002117200641086a2802002202200341c0066a10b4010240024020032802c406220820032802c80622056b2002490d0020032802c00621070c010b200520026a22072005490d102008410174220d2007200d20074b1b220d4100480d100240024020080d00200d102821070c010b20032802c0062008200d102c21070b2007450d062003200d3602c406200320073602c006200d21080b2003200520026a220d3602c806200720056a20172002109a051a2006410c6a22062016470d000c060b0b200641011037000b200541011037000b200541011037000b20032802c806210d20032802c406210820032802c00621070c010b200d41011037000b200341c0066a200f201a10fc0120032802c0062102200320032802c80636029c0420032002360298042007200d20034198046a10cb01024020032802c406450d002002102a0b02402008450d002007102a0b02402004a7450d00200c102a0b0240200e450d002019102a0b0240200a450d00200a410c6c21062009210203400240200241046a280200450d002002280200102a0b2002410c6a2102200641746a22060d000b0b02402018450d002009102a0b200041023a0008410021160c010b0240200e450d002019102a0b0240200a450d00200a410c6c21062009210203400240200241046a280200450d002002280200102a0b2002410c6a2102200641746a22060d000b0b02402018450d002009102a0b20004181243b01082000200736020420002005360200410021162000410a6a41003a00000b410121054101210641012107410121084101210a41012109410121174101210d410121184101210e4101210f410121190c2b0b2002411a6a2901002104200241196a2d00002119200241186a2d00002116200241166a2f0100211a200241156a2d00002113200241146a2d0000210c200241126a2f01002112200241116a2d00002111200241106a2d000021092002410e6a2f010021172002410d6a2d0000210d2002410c6a2d000021182002410a6a2f0100210e200241096a2d0000210f200241086a2d00002106200241066a2f01002105200241056a2d00002107200241046a2d00002115200241026a2f01002114200141216a290000210b200141206a2d0000211e2001411d6a2f0000211f2001411c6a2d00002120200141196a2f00002121200141186a2d00002122200141156a2f00002123200141146a2d00002124200141116a2f00002125200141106a2d000021262001410c6a2802002127200141086a280200210a20022d0001210820022d0000210220012d001f212820012d001b212920012d0017212a20012d0013212b024002400240024002400240024002400240024020012802040e0400010203000b200341c0066a41146a4101360200200342013702c406200341ccd1c5003602c006200341043602e405200341c4d1c5003602e0052003200341e0056a3602d006200341c0066a41b49dc400103e000b410420054108742006411874722007724104200841ff017141014622061b200241ff017122021b21050240024020020d0020060d010b410f210641ea9fc600210202400240024002400240024020050e070001020304050a000b200e410874200f7220184118747221022017410874200d7220094118747221060c090b410e210641dc9fc60021020c080b410c210641d09fc60021020c070b4109210641c79fc60021020c060b4113210641b49fc60021020c050b4111210641a39fc60021020c040b200320043703b004200320193a00af04200320163a00ae042003201a3b01ac04200320133a00ab042003200c3a00aa04200320123b01a804200320113a00a704200320093a00a604200320173b01a4042003200d3a00a304200320183a00a2042003200e3b01a0042003200f3a009f042003200536009b04200320153a009a04200320143b01980420034180056a41086a22024200370300200342003703800541e69dc400410820034180056a1008200341b8026a41086a200229030037030020032003290380053703b802200341c0066a200341b8026a411010fd010240024020032d00c0064101460d00200341a8016a420037030020034190016a41106a420037030020034190016a41086a420037030020034200370390010c010b200320032f00c1063b019001200320032d00c3063a009201200320032802c406360093012003200341c0066a41086a2d00003a0097012003200341d9066a2900003703a8012003200341c9066a290000370398012003200341d1066a2900003703a0010b024020034198046a20034190016a4120109c05450d0041c49dc4002102412221060c040b200341c0066a200a418801109a051a200341003b019001200341e0056a200341c0066a20034190016a10f40141012102024020032d00e80522064102460d00200341e9056a310000210b20033100ea05210420032802e405210720032802e005210541f19ec600410d100b02402006450d00200b100c0b2004100c410021022005450d0020052007100b0b200320023a00c2062003410d3b01c00641014100200341c0066a10cc01200a102a0c060b410420054108742006411874722007724104200841ff017141014622061b200241ff017122021b21050240024020020d0020060d010b410f210641ea9fc600210202400240024002400240024020050e070001020304050a000b200e410874200f7220184118747221022017410874200d7220094118747221060c090b410e210641dc9fc60021020c080b410c210641d09fc60021020c070b4109210641c79fc60021020c060b4113210641b49fc60021020c050b4111210641a39fc60021020c040b200320043703b004200320193a00af04200320163a00ae042003201a3b01ac04200320133a00ab042003200c3a00aa04200320123b01a804200320113a00a704200320093a00a604200320173b01a4042003200d3a00a304200320183a00a2042003200e3b01a0042003200f3a009f042003200536009b04200320153a009a04200320143b01980420034180056a41086a22024200370300200342003703800541e69dc400410820034180056a1008200341b8026a41086a200229030037030020032003290380053703b802200341c0066a200341b8026a411010fd010240024020032d00c0064101460d00200341a8016a420037030020034190016a41106a420037030020034190016a41086a420037030020034200370390010c010b200320032f00c1063b019001200320032d00c3063a009201200320032802c406360093012003200341c0066a41086a2d00003a0097012003200341d9066a2900003703a8012003200341c9066a290000370398012003200341d1066a2900003703a0010b024020034198046a20034190016a4120109c05450d0041ee9dc4002102413121060c050b0240200a41ff01714101460d00200a4118762105200a41087621070c020b200341c0066a202741067610fe0120032802c00621060240024020032802c8062027413f7122024b0d00410021020c010b200620024105746a2202290018210b20022d0017211e20022d0016212820022f0014211f20022d0013212020022d0012212920022f0010212120022d000f212220022d000e212a20022f000c212320022d000b212420022d000a212b20022f0008212520022d000721262002280003212720022d0002210520022f00002107410121020b024020032802c406450d002006102a0b20020d0141dc9fc6002102410e21060c040b2001412c6a280200212c410420054108742007722006411874724104200841ff017141014622061b200241ff017122021b210502400240024020020d0020060d010b410f210641ea9fc600210202400240024002400240024020050e0700010203040507000b200e410874200f7220184118747221022017410874200d7220094118747221060c060b410e210641dc9fc60021020c050b410c210641d09fc60021020c040b4109210641c79fc60021020c030b4113210641b49fc60021020c020b4111210641a39fc60021020c010b200320043703b004200320193a00af04200320163a00ae042003201a3b01ac04200320133a00ab042003200c3a00aa04200320123b01a804200320113a00a704200320093a00a604200320173b01a4042003200d3a00a304200320183a00a2042003200e3b01a0042003200f3a009f042003200536009b04200320153a009a04200320143b01980420034180056a41086a22024200370300200342003703800541e69dc400410820034180056a1008200341b8026a41086a200229030037030020032003290380053703b802200341c0066a200341b8026a411010fd010240024020032d00c0064101460d00200341a8016a420037030020034190016a41106a420037030020034190016a41086a420037030020034200370390010c010b200320032f00c1063b019001200320032d00c3063a009201200320032802c406360093012003200341c0066a41086a2d00003a0097012003200341d9066a2900003703a8012003200341c9066a290000370398012003200341d1066a2900003703a0010b024020034198046a20034190016a4120109c05450d0041c49dc4002102412221060c010b4101210602400240200a41ff01714101460d00200a4118762105200a41087621020c010b200341c0066a202741067610fe0120032802c00621070240024020032802c8062027413f7122024b0d00410021080c010b200720024105746a2202290018210b20022d0017211e20022d0016212820022f0014211f20022d0013212020022d0012212920022f0010212120022d000f212220022d000e212a20022f000c212320022d000b212420022d000a212b20022f0008212520022d000721262002280003212720022d0002210520022f00002102410121080b024020032802c406450d002007102a0b20080d0041dc9fc6002102410e21060c010b200341c0066a202c418801109a051a200341aa016a200b370100200341a9016a201e3a0000200341a8016a20283a0000200341a6016a201f3b0100200341a5016a20203a0000200341a4016a20293a0000200341a2016a20213b0100200341a1016a20223a0000200341a0016a202a3a00002003419e016a20233b010020034190016a410d6a20243a00002003419c016a202b3a00002003419a016a20253b010020034190016a41096a20263a00002003202736009501200320053a009401200320023b01920120034180023b019001200341e0056a200341c0066a20034190016a10f401024020032d00e80522024102460d00200341e0056a41096a310000210b20033100ea05210420032802e405210720032802e005210541f19ec600410d100b02402002450d00200b100c0b2004100c410021062005450d0020052007100b0b200320063a00c2062003418d043b01c00641014100200341c0066a10cc01202c102a0c050b202c106a202c102a0c020b20034180056a41086a22064200370300200342003703800541e69dc400410820034180056a1008200341b8026a41086a2208200629030037030020032003290380053703b802200341c0066a200341b8026a411010fd01200341c0066a41086a2d0000210a200341c9066a22092f00002117200341cb066a2d0000210d200341cc066a22182d0000210e200341cd066a220f2f00002119200341cf066a2d00002116200341c0066a41106a221a2d00002113200341d1066a220c2f00002112200341d3066a2d00002111200341d4066a22152d00002114200341d5066a222c2f0000212d200341d7066a2d0000212e200341d8066a222f2d0000213020032f00c106213120032d00c306213220032802c4062133200341da066a200341d9066a2234290000420020032d00c00641014622021b37010020342030410020021b3a0000202f202e410020021b3a0000200341d6066a202d410020021b3b0100202c2014410020021b3a000020152011410020021b3a0000200341d2066a2012410020021b3b0100200c2013410020021b3a0000201a2016410020021b3a0000200341ce066a2019410020021b3b0100200f200e410020021b3a00002018200d410020021b3a0000200341ca066a2017410020021b3b01002009200a410020021b3a000020032033410020021b3600c50620032032410020021b3a00c40620032031410020021b3b01c2062003418d023b01c00641014100200341c0066a10cc012003200b3703d8062003201e3a00d706200320283a00d6062003201f3b01d406200320203a00d306200320293a00d206200320213b01d006200320223a00cf062003202a3a00ce06200320233b01cc06200320243a00cb062003202b3a00ca06200320253b01c806200320263a00c706200320273600c306200320053a00c206200320073b01c00620064200370300200342003703800541e69dc400410820034180056a10082008200629030037030020032003290380053703b80220034110360294012003200341b8026a36029001200341c0066a20034190016a10ff010c030b200a106a200a102a0b2002450d010b20004181223b01082000200636020420002002360200410021192000410a6a41003a00000c010b200041023a0008410021190b410121054101210641012107410121084101210a41012109410121174101210d410121184101210e4101210f0c290b200341c0066a200141086a418001109a051a20034190016a41206a200241206a29020037030020034190016a41186a200241186a29020037030020034190016a41106a200241106a29020037030020034190016a41086a200241086a290200370300200320022902003703900120034188016a200341c0066a20034190016a1080020240024020032802880122020d00200041023a00084100210f0c010b200328028c01210620004181203b0108200020023602004100210f2000410a6a41003a0000200020063602040b410121054101210641012107410121084101210a41012109410121174101210d410121184101210e410121190c280b200341b8036a41086a22092001411c6a290200370300200341b8036a41106a2217200141246a290200370300200341b8036a41186a220d2001412c6a2802003602002003200141146a2902003703b803200241086a28020021062001410c6a280200210a410e2105200241046a280200210820022d000021070240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240200141086a2802000e0400010203000b200341c0066a41146a4101360200200342013702c406200341ccd1c5003602c006200341043602e405200341c4d1c5003602e0052003200341e0056a3602d006200341c0066a41e4c4c200103e000b200641107621182006410876210e200141386a290300210b200141306a29030021042002411a6a2901002110200241196a2d00002113200241186a2d0000210c200241166a2f01002112200241156a2d00002111200241146a2d00002115200241126a2f01002114200241116a2d00002127200241106a2d0000210f2002410e6a2f010021192002410d6a2d000021162002410c6a2d0000211a200241026a2f0100211e200141106a280200210520022d0001210220034198046a41186a200d28020036020020034198046a41106a201729030037030020034198046a41086a2009290300370300200320032903b80337039804410420084108762006411874724104200241014622091b200741ff017122021b21060240024020020d0020090d010b410f210541ea9fc600210202400240024002400240024020060e0700010203040516000b200e41ff0171201841087472201a4118747221022019410874201672200f4118747221050c150b410e210541dc9fc60021020c140b410c210541d09fc60021020c130b4109210541c79fc60021020c120b4113210541b49fc60021020c110b4111210541a39fc60021020c100b200320103703a801200320133a00a7012003200c3a00a601200320123b01a401200320113a00a301200320153a00a201200320143b01a001200320273a009f012003200f3a009e01200320193b019c01200320163a009b012003201a3a009a01200320183b0198012003200e3a0097012003200636009301200320083a0092012003201e3b019001200341c0066a41186a220220034198046a41186a280200360200200341c0066a41106a220720034198046a41106a290300370300200341c0066a41086a220820034198046a41086a29030037030020032003290398043703c0060240200a41ff01714101460d00200a4108762106200341e0056a41186a20022d00003a0000200341e0056a41106a2007290300370300200341e0056a41086a2008290300370300200320032903c0063703e0050c0f0b20034198026a200541067610fe0120032802980221070240024020032802a0022005413f7122024b0d00410021020c010b200341e8056a200720024105746a2202410f6a290000370300200341e0056a41106a200241176a290000370300200341f8056a2002411f6a2d00003a0000200320022900073703e00520022f0000200241026a2d000041107472210620022800032105410121020b0240200328029c02450d002007102a0b20020d0e200341b8026a41086a20034180056a41086a290000370300200341b8026a41106a20034180056a41106a29000037030041dc9fc6002102410e21050c0f0b41a6f5c5002102200741ff01714101470d0f20064102490d0f200841ff01710d0f411210282202450d01200241106a41002f008086423b0000200241086a41002900f88542370000200241002900f08542370000200241124124102c2202450d022002200a36001220034198026a41186a2206420037030020034198026a41106a2205420037030020034198026a41086a2207420037030020034200370398022002411620034198026a1000200341f8016a41186a2006290300370300200341f8016a41106a2005290300370300200341f8016a41086a200729030037030020032003290398023703f8012002102a200341003602c006200341f8016a4120200341c0066a1006210220032802c0062206417f460d092002450d09200320063602bc02200320023602b802200341c0066a200341b8026a10810220032903c0064201510d0320032802c806210520034198046a200341cc066a41dc00109a051a02402006450d002002102a0b200341c0066a20034198046a41dc00109a051a200341f8016a41201009410121020c0a0b41a6f5c5002102200741ff01714101470d0e20064104490d0e200841ff01710d0e411210282202450d03200241106a41002f008086423b0000200241086a41002900f88542370000200241002900f08542370000200241124124102c2202450d042002200a36001220034198026a41186a2206420037030020034198026a41106a2205420037030020034198026a41086a2207420037030020034200370398022002411620034198026a1000200341f8016a41186a2006290300370300200341f8016a41106a2005290300370300200341f8016a41086a200729030037030020032003290398023703f8012002102a200341f8016a41204101410041001003417f460d0a20034180056a41086a2202420037030020034200370380054181a2c600411220034180056a1008200341b8026a41086a200229030037030020032003290380053703b80241002102200341003602c006200341b8026a4110200341c0066a100621060240024020032802c0062205417f470d000c010b024020060d000c010b20032005360294012003200636029001200341c0066a20034190016a10820120032802c0062202450d0620032902c40621042005450d002006102a0b2002410420021b210d02402004420020021b2204422088220ba722022004a7470d00200241016a22062002490d19200ba722074101742205200620062005491b220641ffffffff03712006470d19200641027422054100480d190240024020020d0020051028210d0c010b200d20074102742005102c210d0b200d450d072004422088220ba721022006ad21040b200d20024102746a200a36020020034180056a41086a2202420037030020034200370380054181a2c600411220034180056a1008200341b8026a41086a200229030037030020032003290380053703b8020240200d0d00200341b8026a411010090c100b200341003602c806200342013703c006200ba741016a2206200341c0066a10b4010240024020060d0020032802c806210a20032802c406210820032802c00621060c010b410020032802c80622026b2105200d20064102746a211720032802c4062108200d210703402007280200210902400240200820056a4104490d0020032802c00621060c010b200241046a22062002490d1b2008410174220a2006200a20064b1b220a4100480d1b0240024020080d00200a102821060c010b20032802c0062008200a102c21060b2006450d0a2003200a3602c406200320063602c006200a21080b2003200241046a220a3602c806200620026a20093600002005417c6a2105200a21022017200741046a2207470d000b0b2004a72102200341b8026a41102006200a100702402008450d002006102a0b2002450d0f200d102a0c0f0b411241011037000b412441011037000b41c4d1c3004133200341c8076a419cd9c3001038000b411241011037000b412441011037000b41c4d1c3004133200341c8076a419cd9c3001038000b200541041037000b200a41011037000b410021020b200341e0056a200341c0066a41dc00109a051a200341c0066a200341e0056a41dc00109a051a20020d010b418ec5c2002102411921050c030b20034180056a200341c0066a41dc00109a051a200320053602900120034190016a41047220034180056a41dc00109a051a200341f8006a200341b0016a20032903a001200341a8016a29030010820220032903782104200320034180016a2903003703c806200320043703c0062003200341c0066a3602980420034198046a109d010c030b200341e0006a2004200b42c0843d420010a005200341d0006a20032903602210200341e0006a41086a290300221b42c0fb42427f109f05200341c0006a2010201b42d086034200109f0520034198036a41086a200341e0056a41086a29030037030020034198036a41106a200341e0056a41106a29030037030020034198036a41186a200341e0056a41186a2d00003a0000200320032903e00522103703b8022003201037039803200341f0006a20034190016a2003290340221b200420032903507c42148042ffffffff0f837c2210428080e983b1de162010428080e983b1de1656200341c0006a41086a2903002010201b54ad7c22104200522010501b22021b221b2010420020021b221010830202402003280270450d0041f4c4c2002102411a21050c010b20034180056a41086a22024200370300200342003703800541eba1c600411620034180056a1008200341b8026a41086a200229030037030020032003290380053703b80241002107200341003602c006200341b8026a4110200341c0066a10062102024020032802c0062208417f460d002002450d0020084104490d04200228000021072002102a0b20034180056a41086a22024200370300200342003703800541eba1c600411620034180056a1008200341b8026a41086a200229030037030020032003290380053703b8022003200741016a3602c006200341b8026a4110200341c0066a41041007200341f8066a20034190016a41186a290300370300200341f0066a20034190016a41106a290300370300200341e8066a20034190016a41086a29030037030020034183076a200536000020034187076a2003290398033700002003418f076a20034198036a41086a29030037000020034197076a20034198036a41106a2903003700002003419f076a20034198036a41186a2d00003a0000200320063b01800720034182076a20064110763a00002003200b3703c806200320043703c00620032003290390013703e006200341c0066a41186a20103703002003201b3703d006411210282202450d04200241106a41002f008086423b0000200241086a41002900f88542370000200241002900f08542370000200241124124102c2202450d052002200736001220034198026a41186a2206420037030020034198026a41106a2205420037030020034198026a41086a2208420037030020034200370398022002411620034198026a1000200341f8016a41186a2006290300370300200341f8016a41106a2005290300370300200341f8016a41086a200829030037030020032003290398023703f8012002102a200341003602e805200342013703e005200341e0066a200341e0056a108f01200341c0066a41086a290300210420032903c006210b0240024020032802e405220620032802e80522026b4110490d0020032802e00521060c010b200241106a22052002490d0c200641017422022005200220054b1b22024100480d0c0240024020060d002002102821060c010b20032802e00520062002102c21060b2006450d07200320023602e405200320063602e00520032802e80521020b200620026a220620043700082006200b3700002003200241106a3602e80520034180076a200341e0056a108f01200341d8066a290300210420032903d006210b0240024020032802e405220520032802e80522066b4110490d0020032802e00521020c010b200641106a22022006490d0c200541017422062002200620024b1b22084100480d0c0240024020050d002008102821020c010b20032802e00520052008102c21020b2002450d08200320083602e405200320023602e00520032802e8052106200821050b200220066a220820043700082008200b370000200341f8016a41202002200641106a100702402005450d002002102a0b200341cc066a200736020041002102200341c8066a41003a00002003410b3a00c00641014100200341c0066a10cc010b2002450d010b200041811e3b010820002005360204200020023602002000410a6a41003a00000c160b200041023a00080c150b41c4d1c3004133200341c8076a419cd9c3001038000b411241011037000b412441011037000b200241011037000b200841011037000b200141086a28020021062001280204210502400240024020022d00000d0020022d000141ff01714101460d010b02402006450d002005102a0b200041811c3b010820004113360204200041b49fc6003602004100210e2000410a6a41003a00000c010b02402006450d002005102a0b200041023a00084100210e0b410121054101210641012107410121084101210a41012109410121174101210d410121180c250b02400240024020022d00000d0020022d000141ff01714102470d002001280204210220034180056a41086a220642003703002003420037038005418194c100411020034180056a1008200341b8026a41086a200629030037030020032003290380053703b802200341b8026a41104101410041001003417f470d011098012002490d0220034180056a41086a220642003703002003420037038005418194c100411020034180056a1008200341b8026a41086a200629030037030020032003290380053703b802200320023602c006200341b8026a4110200341c0066a41041007200041023a00080c110b200041811a3b01082000410f360204200041ea9fc6003602002000410a6a41003a00000c100b41a894c1001032000b41bc95c1001032000b200341b8036a41026a2205200141076a2d00003a000020034190016a41086a22072001411c6a29020037030020034190016a41106a220a200141246a29020037030020034190016a41186a2001412c6a290200370300200341b0016a200141346a290200370300200341b8016a2001413c6a290200370300200341c0016a200141c4006a2d00003a0000200320012f00053b01b8032003200141146a29020037039001200141086a28020021082001410c6a2802002109200141106a280200210620022f0001200241036a2d000041107472210d2002410c6a2802002118200241086a280200210e200241046a280200210f20022d0000210202400240024002400240024002400240024002400240024020012d000422170e050001020304000b200341c0066a41146a4101360200200342013702c406200341ccd1c5003602c006200341043602e405200341c4d1c5003602e0052003200341e0056a3602d006200341c0066a41e8cfc300103e000b200341af046a2007290300370000200341b7046a200a2d00003a0000200320032f01b8033b019804200320063600a3042003200936009f042003200836009b0420032003290390013700a704200320052d00003a009a04024002402002417f6a220641024b0d00024020060e03000102000b200e41017420184d0d00200f41ff0171450d010b2002200d7241ff0171450d0041a3d0c3002105410a2118410021060c0e0b20034180056a41086a22024200370300200342003703800541f8cfc300411b20034180056a1008200341b8026a41086a200229030037030020032003290380053703b802200341003602c006200341b8026a4110200341c0066a1006210202400240024002400240024002400240024020032802c0062206417f460d002002450d00200320063602e405200320023602e005200341c0066a200341e0056a106d20032802c006220a450d0c20032902c406210420032802c406211802402006450d002002102a0b2003200a3602e0052004a7210e410021022004422088a7220d41014b0d02200d0e020103010b4101210a200341013602e005410021184100210e0b200341f8016a41186a20034198046a41186a290300370300200341f8016a41106a20034198046a41106a290300370300200341f8016a41086a20034198046a41086a29030037030020032003290398043703f8014100210d200341f8016a2106410021050c020b200d210603402006410176220520026a22072002200a20074105746a20034198046a4120109c054101481b2102200620056b220641014b0d000b0b0240200a20024105746a20034198046a4120109c0522060d004193d0c3002105200e450d05200a102a0c050b200341f8016a41186a20034198046a41186a290300370300200341f8016a41106a20034198046a41106a290300370300200341f8016a41086a20034198046a41086a29030037030020032003290398043703f8012006411f7620026a2205200d4b0d01200341f8016a21060b200d200e460d012018210e0c020b41f8b0c0001032000b02402018200d460d002018210e0c010b201841016a22022018490d0c201841017422072002200720024b1b220e41ffffff3f71200e470d0c200e41057422024100480d0c0240024020180d0020021028210a0c010b200a20184105742002102c210a0b200a450d062003200a3602e0050b200a20054105746a220241206a2002200d20056b410574109b051a200241186a200641186a290000370000200241106a200641106a290000370000200241086a200641086a2900003700002002200629000037000020034180056a41086a22024200370300200342003703800541f8cfc300411b20034180056a1008200341b8026a41086a200229030037030020032003290380053703b80220032802e0052102200341003602c806200342013703c006200d41016a2207200341c0066a10b40102402007200d490d00200d41057441206a210603402002200341c0066a108f01200241206a2102200641606a22060d000b0b20032802c4062102200341b8026a411020032802c006220620032802c806100702402002450d002006102a0b200341c0066a41186a20034198046a41186a290300370300200341c0066a41106a20034198046a41106a290300370300200341c0066a41086a20034198046a41086a29030037030020032003290398043703c006410021054101410020032802e00522022007108402200341093b01c00641014100200341c0066a10cc01200e450d002002102a0b41102118410021060c0d0b200341af046a2007290300370000200341b7046a200a2d00003a0000200320032f01b8033b019804200320063600a3042003200936009f042003200836009b0420032003290390013700a704200320052d00003a009a04024002402002417f6a220641024b0d00024020060e03000102000b200e41017420184d0d00200f41ff0171450d010b2002200d7241ff0171450d0041a3d0c3002105410a2118410021060c0d0b20034180056a41086a22024200370300200342003703800541f8cfc300411b20034180056a1008200341b8026a41086a200229030037030020032003290380053703b802200341003602c006200341b8026a4110200341c0066a100621020240024020032802c0062206417f460d002002450d00200320063602e405200320023602e005200341c0066a200341e0056a106d20032802c006220a450d0620032902c40621042006450d012002102a0c010b420021044101210a0b41002102024002400240024002402004422088a7220d41014b0d00200d0e020201020b200d210603402006410176220520026a22072002200a20074105746a20034198046a4120109c054101481b2102200620056b220641014b0d000b0b200a20024105746a20034198046a4120109c05450d010b41add0c3002105410c21182004a7450d01200a102a410021060c0e0b2002200d4f0d06200a20024105746a2206200641206a2002417f73200d6a410574109b051a20034180056a41086a22024200370300200342003703800541f8cfc300411b20034180056a1008200341b8026a41086a200229030037030020032003290380053703b802200341003602c806200342013703c006200d417f6a2205200341c0066a10b40102402005450d00200d41057441606a2106200a210203402002200341c0066a108f01200241206a2102200641606a22060d000b0b20032802c4062102200341b8026a411020032802c006220620032802c806100702402002450d002006102a0b200341c0066a41186a20034198046a41186a290300370300200341c0066a41106a20034198046a41106a290300370300200341c0066a41086a20034198046a41086a29030037030020032003290398043703c006200341c0066a4101200a200510840220034189023b01c0064100210541014100200341c0066a10cc0102402004a7450d00200a102a0b0b410021060c0c0b200341f7056a2007290300370000200341ff056a200a2d00003a0000200320032f01b8033b01e005200320063600eb05200320093600e705200320083600e30520032003290390013700ef05200320052d00003a00e20520034198046a41186a200341b9016a29000037030020034198046a41106a200341b1016a29000037030020034198046a41086a200341a9016a290000370300200320032900a10137039804024002402002417f6a220641024b0d00024020060e03000102000b200e41017420184d0d00200f41ff0171450d010b2002200d7241ff0171450d0041a3d0c3002105410a2118410021060c0c0b02400240200341e0056a20034198046a4120109c050d00410021050c010b20034180056a41086a22024200370300200342003703800541f8cfc300411b20034180056a1008200341b8026a41086a200229030037030020032003290380053703b802200341003602c006200341b8026a4110200341c0066a100621020240024020032802c0062206417f460d002002450d0020032006360284052003200236028005200341c0066a20034180056a106d20032802c006220d450d0820032902c40621042006450d012002102a0c010b4101210d420021040b41add0c3002105410c211841002102024002402004422088a7220e41014b0d00200e0e020c010c0b200e210603402006410176220720026a220a2002200d200a4105746a200341e0056a4120109c054101481b2102200620076b220641014b0d000b0b200d20024105746a2206200341e0056a4120109c050d0a20034198026a41186a220520034198046a41186a29030037030020034198026a41106a220720034198046a41106a29030037030020034198026a41086a220a20034198046a41086a2903003703002003200329039804370398022002200e4f0d072006200329039802370000200641186a2005290300370000200641106a2007290300370000200641086a200a290300370000410021020240200e4101460d0041002102200e210603402006410176220520026a22072002200d20074105746a20034198046a4120109c054101481b2102200620056b220641014b0d000b0b0240200d20024105746a20034198046a4120109c050d004193d0c3002105411021180c0b0b200d200e10f00120034180056a41086a22024200370300200342003703800541f8cfc300411b20034180056a1008200341b8026a41086a200229030037030020032003290380053703b802200341003602c806200342013703c006200e200341c0066a10b4010240200e450d00200e4105742106200d210203402002200341c0066a108f01200241206a2102200641606a22060d000b0b20032802c4062102200341b8026a411020032802c006220620032802c806100702402002450d002006102a0b200341c0066a41186a200341e0056a41186a290300370300200341c0066a41106a200341e0056a41106a290300370300200341c0066a41086a200341e0056a41086a290300370300200320032903e0053703c006200341c0066a4101200d200e10840220034189043b01c0064100210541014100200341c0066a10cc012004a7450d00200d102a0b0c0a0b024002402002417f6a220541024b0d00024020050e03000102000b200e41017420184d0d00200f41ff0171450d010b2002200d7241ff0171450d0002402009450d002008102a0b41a3d0c3002105410a21180c0c0b2008200610f00120034180056a41086a22024200370300200342003703800541f8cfc300411b20034180056a1008200341b8026a41086a200229030037030020032003290380053703b802200341003602c006200341b8026a4110200341c0066a100621050240024020032802c0062207417f460d002005450d002003200736029c042003200536029804200341c0066a20034198046a106d20032802c0062202450d0820032902c40621042007450d012005102a0c010b42002104410121020b2008200620022004422088a710850202402004a7450d002002102a0b20034180056a41086a22024200370300200342003703800541f8cfc300411b20034180056a1008200341b8026a41086a200229030037030020032003290380053703b802200341003602c806200342013703c0062006200341c0066a10b40102402006450d00200641057421062008210203402002200341c0066a108f01200241206a2102200641606a22060d000b0b20032802c4062102200341b8026a411020032802c006220620032802c806100702402002450d002006102a0b02402009450d002008102a0b20034189063b01c006410021054101210641014100200341c0066a10cc010c0a0b41c4d1c3004133200341c8076a419cd9c3001038000b200241011037000b41c4d1c3004133200341c8076a419cd9c3001038000b41b0b1c0001032000b41c4d1c3004133200341c8076a419cd9c3001038000b41bcd0c3002002200e1034000b41c4d1c3004133200341c8076a419cd9c3001038000b1031000b2004a7450d00200d102a410021060c010b410021060b0240024002402017417f6a220241034b0d00024020020e0403030300030b200620094572450d010c020b20174104490d012009450d010b2008102a0b20050d00200041023a0008410021180c010b20004181183b01082000201836020420002005360200410021182000410a6a41003a00000b410121054101210641012107410121084101210a41012109410121174101210d0c1c0b200341c0066a41386a200141c0006a290300370300200341c0066a41306a200141386a290300370300200341c0066a41286a200141306a290300370300200341c0066a41206a200141286a290300370300200341c0066a41186a200141206a290300370300200341c0066a41106a200141186a290300370300200341c0066a41086a200141106a2903003703002003200141086a2903003703c00620034190016a41206a200241206a29020037030020034190016a41186a200241186a29020037030020034190016a41106a200241106a29020037030020034190016a41086a200241086a2902003703002003200229020037039001200341386a200341c0066a20034190016a10860202400240200328023822020d00200041023a00084100210d0c010b200328023c210620004181163b0108200020023602004100210d2000410a6a41003a0000200020063602040b410121054101210641012107410121084101210a41012109410121170c1a0b20034190016a41206a200141246a29020037030020034190016a41186a2001411c6a29020037030020034190016a41106a200141146a29020037030020034190016a41086a2001410c6a2902003703002003200129020437039001200341c0066a41206a200241206a290200370300200341c0066a41186a200241186a290200370300200341c0066a41106a200241106a290200370300200341c0066a41086a200241086a290200370300200320022902003703c006200341306a20034190016a200341c0066a10870202400240200328023022020d00200041023a0008410021170c010b2003280234210620004181143b010820002002360200410021172000410a6a41003a0000200020063602040b410121054101210641012107410121084101210a410121090c180b20034190016a41206a200141246a29020037030020034190016a41186a2001411c6a29020037030020034190016a41106a200141146a29020037030020034190016a41086a2001410c6a2902003703002003200129020437039001200341c0066a41206a200241206a290200370300200341c0066a41186a200241186a290200370300200341c0066a41106a200241106a290200370300200341c0066a41086a200241086a290200370300200320022902003703c006200341286a20034190016a200341c0066a10880202400240200328022822020d00200041023a0008410021090c010b200328022c210620004181123b010820002002360200410021092000410a6a41003a0000200020063602040b410121054101210641012107410121084101210a0c160b200341c0066a41286a200141306a290300370300200341c0066a41206a200141286a290300370300200341c0066a41186a200141206a290300370300200341c0066a41106a200141186a290300370300200341c0066a41086a200141106a2903003703002003200141086a2903003703c00620034190016a41206a200241206a29020037030020034190016a41186a200241186a29020037030020034190016a41106a200241106a29020037030020034190016a41086a200241086a2902003703002003200229020037039001200341206a200341c0066a20034190016a10890202400240200328022022020d00200041023a00084100210a0c010b2003280224210620004181103b0108200020023602004100210a2000410a6a41003a0000200020063602040b410121054101210641012107410121080c140b200141086a28020021162001280204211a200341c0066a2001410c6a41e400109a051a2002411a6a2901002104200241196a2d00002118200241186a2d0000210e200241166a2f0100210f200241156a2d00002119200241146a2d00002113200241126a2f0100210c200241116a2d00002112200241106a2d000021072002410e6a2f010021082002410d6a2d0000210a2002410c6a2d000021092002410a6a2f01002117200241096a2d0000210d200241046a2d00002111200241026a2f01002115200241056a280000210520022d0000210620022d00012102200341b8026a200341c0066a41046a41e000109a051a410420054104200241014622021b20061b21050240024002400240024020060d0020020d010b410f210641ea9fc600210202400240024002400240024020050e0700010203040507000b2017410874200d7220094118747221022008410874200a7220074118747221060c060b410e210641dc9fc60021020c050b410c210641d09fc60021020c040b4109210641c79fc60021020c030b4113210641b49fc60021020c020b4111210641a39fc60021020c010b2003200437039805200320183a0097052003200e3a0096052003200f3b019405200320193a009305200320133a0092052003200c3b019005200320123a008f05200320073a008e05200320083b018c052003200a3a008b05200320093a008a05200320173b0188052003200d3a0087052003200536008305200320113a008205200320153b018005024002400240024002400240410e10282202450d002002410029008aaf44370000200241066a4100290090af443700002003428e808080e00137029401200320023602900120034180056a20034190016a108f012003280298012102200328029001210620034198026a41186a2205420037030020034198026a41106a2207420037030020034198026a41086a2208420037030020034200370398022006200220034198026a1000200341f8016a41186a2005290300370300200341f8016a41106a2007290300370300200341f8016a41086a200829030037030020032003290398023703f8010240200328029401450d00200328029001102a0b2003410036029001200341f8016a412020034190016a100621022003280290012206417f460d022002450d022003200636029c02200320023602980220034190016a20034198026a108a0220032802b0012217450d0120034198046a41086a2205200341c0016a29030037030020034198046a41106a2207200341c8016a29030037030020034198046a41186a2208200341d0016a29030037030020034198046a41206a220a200341d8016a2802003602002003200341b8016a2903003703980420032802b401210902402006450d002002102a0b200341e0056a41086a20052903002204370300200341e0056a41106a2007290300220b370300200341e0056a41186a20082903002210370300200341e0056a41206a200a28020022023602002003200329039804221b3703e00520034190016a41106a200b37030020034190016a41086a200437030020034190016a41186a201037030020034190016a41206a2002360200200341f8016a41086a2003419c016a290200370300200341f8016a41106a200341a4016a290200370300200341f8016a41186a200341ac016a2902003703002003201b3703900120032003290294013703f80102402009450d002017102a0b20034198036a41086a200341f8016a41086a29030037030020034198036a41106a200341f8016a41106a29030037030020034198036a41186a200341f8016a41186a290300370300200320032903f80137039803200341b8036a200341b8026a41e000109a051a20034198026a20034198036a108b0220032802a0022106200328029802210220034100360290012002200620034190016a100621062003280290012205417f460d042006450d042003200536028405200320063602800520034190016a20034180056a10e80120032d0090014101460d03200341e0056a20034190016a41017241e000109a051a02402005450d002006102a0b20034180056a200341e0056a41e000109a051a20034190016a20034180056a41e000109a051a200341013a00980420034198046a41017220034190016a41e000109a051a0c050b410e41011037000b41c4d1c3004133200341c8076a419cd9c3001038000b41a5c4c2002102412721060c030b41c4d1c3004133200341c8076a419cd9c3001038000b20034190016a20034180056a41e000109a051a200341003a0098040b0240200328029c02450d002002102a0b200341b9046a2112200341d9046a2111200341b8036a41206a2113200341f8036a210c20034198046a410172211520034190016a41017221054104210741e7e485f30621060240024003400240024002400240200641e9dabdf30646220f0d000240200641e7e485f306470d00200341b8036a210a0c020b200641e2c289ab06470d022013210a0c010b200c210a0b41202102410021084120102822090d01412041011037000b41012108410021024101210a410121090b2009200a2002109a052109200320023602a402200320023602a0022003200936029c022003200636029802200341f8016a20034198026a108c0220034190016a20032802f801221720032802800210fd0120034180056a41086a220d200541086a29000037030020034180056a41106a2218200541106a29000037030020034180056a41186a220e200541186a29000037030020032005290000370380050240024020032d0090014101470d00200341e0056a41186a2219200e290300370300200341e0056a41106a220e2018290300370300200341e0056a41086a2218200d29030037030020032003290380053703e005024020032802fc01450d002017102a0b024020080d002009102a0b20034190016a41186a201929030037030020034190016a41106a200e29030037030020034190016a41086a2018290300370300200320032903e0053703900120034190016a20034198036a4120109c05450d0141ccc4c2002102411821060c050b024020032802fc01450d002017102a0b20080d002009102a0b0240024020032d0098044101470d00024002400240200641e2c289ab06460d00200f0d010240200641e7e485f306460d0041002109410121170c030b41202109201521170c020b41202109201221170c010b41202109201121170b024020022009470d00200a2017460d02200a20172002109c05450d020b0240024020090d004100210d410121180c010b2009210d200910282218450d040b201820172009109a0521172003200936029c012003200d3602980120032017360294012003200636029001200341e0056a20034190016a108c0220032802e005220920032802e8051009024020032802e405450d002009102a0b200d450d002017102a0b41012109024020080d00200210282209450d040b2009200a2002109a05210a2003200236029c0120032002360298012003200a360294012003200636029001200341e0056a20034190016a108c0220032802e0052102200320032802e80536028405200320023602800520034198036a20034180056a10ff01024020032802e405450d002002102a0b20080d00200a102a0b02402007410c460d00200741f8c8c0006a2800002106200741046a21070c010b0b200341e0056a20034198036a108b0220032802e805210620032802e005210220034100360298012003420137039001200341b8036a20034190016a108f01201320034190016a108f01200c20034190016a108f012003280294012105200220062003280290012207200328029801100702402005450d002007102a0b024020032802e405450d002002102a0b2016450d03201a102a0c030b200941011037000b200241011037000b02402016450d00201a102a0b2002450d00200041810e3b01082000200636020420002002360200410021082000410a6a41003a00000c010b200041023a0008410021080b4101210541012106410121070c120b200341c0066a41306a200141386a290300370300200341c0066a41286a200141306a290300370300200341c0066a41206a200141286a290300370300200341c0066a41186a200141206a290300370300200341c0066a41106a200141186a290300370300200341c0066a41086a200141106a2903003703002003200141086a2903003703c00620034190016a41206a200241206a29020037030020034190016a41186a200241186a29020037030020034190016a41106a200241106a29020037030020034190016a41086a200241086a2902003703002003200229020037039001200341186a200341c0066a20034190016a108d0202400240200328021822020d00200041023a0008410021070c010b200328021c2106200041810c3b010820002002360200410021072000410a6a41003a0000200020063602040b41012105410121060c100b200141256a2900002110200141246a2d0000211a200141216a2f00002113200141206a2d0000210c2001411d6a2f000021122001411c6a2d00002111200141196a2f00002109200141186a2d00002117200141156a2f0000210d200141146a2d00002118200141106a28020021052001410d6a2f0000210e2001410c6a2d00002127200141086a2802002107200141306a2903002104200141386a290300210b20012d0023211520012d001f211420012d001b210f20012d0017211920012d000f211620034198046a41106a200141d0006a2d00003a000020034198046a41086a221e200141c8006a2903003703002003200141c0006a290300370398044111210620022d0001210820022d0000210a02400240024002400240024002400240024002400240024002400240024020070e0400010203000b200341c0066a41146a4101360200200342013702c406200341ccd1c5003602c006200341043602e405200341c4d1c5003602e0052003200341e0056a3602d006200341c0066a41e092c100103e000b200241106a2d0000211e2002410e6a2f0100211f2002410d6a2d000021202002410c6a2d000021212002410a6a2f01002122200241096a2d000021234104200241056a2800004104200841ff017141014622081b200a41ff017122061b21070240024020060d0020080d010b410f210641ea9fc600210202400240024002400240024020070e0700010203040511000b20224108742023722021411874722102201f410874202072201e4118747221060c100b410e210641dc9fc60021020c0f0b410c210641d09fc60021020c0e0b4109210641c79fc60021020c0d0b4113210641b49fc60021020c0c0b4111210641a39fc60021020c0b0b200241196a2d00002106200241186a2d00002108200241166a2f0100210a200241156a2d00002124200241146a2d00002125200241126a2f01002126200241116a2d00002128200241046a2d00002129200241026a2f0100212a20032002411a6a2901003703a801200320063a00a701200320083a00a6012003200a3b01a401200320243a00a301200320253a00a201200320263b01a001200320283a009f012003201e3a009e012003201f3b019c01200320203a009b01200320213a009a01200320223b019801200320233a0097012003200736009301200320293a0092012003202a3b01900102400240202741ff01714101470d00200341e0056a200541067610fe0120032802e00521060240024020032802e8052005413f7122024b0d00410021020c010b200620024105746a2202290018211020022d0017211a20022d0016211520022f0014211320022d0013210c20022d0012211420022f0010211220022d000f211120022d000e210f20022f000c210920022d000b211720022d000a211920022f0008210d20022d000721182002280003210520022d0002211620022f0000210e410121020b024020032802e405450d002006102a0b20020d00410121020c010b410021020b20032010370390022003201a3a008f02200320153a008e02200320133b018c022003200c3a008b02200320143a008a02200320123b018802200320113a0087022003200f3a008602200320093b018402200320173a008302200320193a0082022003200d3b018002200320183a00ff01200320053600fb01200320163a00fa012003200e3b01f80120020d09200341c0066a41186a200341f8016a41186a290300370300200341c0066a41106a200341f8016a41106a290300370300200341c0066a41086a200341f8016a41086a290300370300200320032903f8013703c006200341086a20034190016a200341c0066a2004200b108e0220032802082202450d0b200328020c21060c0a0b41a39fc60021022008200a7241ff01710d0b201e290300211b200329039804211c0240202741ff01714101470d0020034190016a200541067610fe012003280290012106024002402003280298012005413f7122024b0d00410021020c010b200620024105746a2202290018211020022d0017211a20022d0016211520022f0014211320022d0013210c20022d0012211420022f0010211220022d000f211120022d000e210f20022f000c210920022d000b211720022d000a211920022f0008210d20022d000721182002280003210520022d0002211620022f0000210e410121020b0240200328029401450d002006102a0b2002450d080b200320103703d8062003201a3a00d706200320153a00d606200320133b01d4062003200c3a00d306200320143a00d206200320123b01d006200320113a00cf062003200f3a00ce06200320093b01cc06200320173a00cb06200320193a00ca062003200d3b01c806200320183a00c706200320053600c306200320163a00c2062003200e3b01c006411410282202450d01200241002900cfe140370000200241106a41002800dfe140360000200241086a41002900d7e14037000020034294808080c002370294012003200236029001200341c0066a20034190016a108f012003280298012102200328029001210620034198026a41186a2205420037030020034198026a41106a2207420037030020034198026a41086a2208420037030020034200370398022006200220034198026a1000200341f8016a41186a2005290300370300200341f8016a41106a2007290300370300200341f8016a41086a200829030037030020032003290398023703f8010240200328029401450d00200328029001102a0b2003410036029001200341f8016a412020034190016a100621022003280290012206417f460d052002450d0520064110490d02200241086a29000021102002290000211d2002102a0c060b41a39fc60021022008200a7241ff01710d0a200141e0006a290300211c200141d8006a290300211d20032900a104211b20032d00a004210720032d009f04210820032f009d04210a20032d009c04211e20032d009b04211f20032f009904212020032d00980421210240202741ff01714101470d00200341c0066a200541067610fe0120032802c00621060240024020032802c8062005413f7122024b0d00410021020c010b200620024105746a2202290018211020022d0017211a20022d0016211520022f0014211320022d0013210c20022d0012211420022f0010211220022d000f211120022d000e210f20022f000c210920022d000b211720022d000a211920022f0008210d20022d000721182002280003210520022d0002211620022f0000210e410121020b024020032802c406450d002006102a0b2002450d070b2004422088a72106200320103703a8012003201a3a00a701200320153a00a601200320133b01a4012003200c3a00a301200320143a00a201200320123b01a001200320113a009f012003200f3a009e01200320093b019c01200320173a009b01200320193a009a012003200d3b019801200320183a0097012003200536009301200320163a0092012003200e3b01900102402004a741ff01714101460d00200ba72118200b423888a7210f200b422888a72109200b422088a72117200b421888a72119200b420888a7210d2004421888a721162004420888a7210e0c030b200341e0056a2004422688a710fe0120032802e00521050240024020032802e8052006413f7122024b0d00410021022013210a200c211e2014211f201221202011212120152108201a21072010211b0c010b200520024105746a2202290018211b20022d0017210720022d0016210820022f0014210a20022d0013211e20022d0012211f20022f0010212020022d000f212120022d000e210f20022f000c210920022d000b211720022d000a211920022f0008210d20022d000721182002280003210620022d0002211620022f0000210e410121020b024020032802e405450d002005102a0b20020d02410121020c030b411441011037000b41c4d1c3004133200341c8076a419cd9c3001038000b410021020b2003201b37039002200320073a008f02200320083a008e022003200a3b018c022003201e3a008b022003201f3a008a02200320203b018802200320213a0087022003200f3a008602200320093b018402200320173a008302200320193a0082022003200d3b018002200320183a00ff01200320063600fb01200320163a00fa012003200e3b01f80120020d03200341c0066a41186a200341f8016a41186a290300370300200341c0066a41106a200341f8016a41106a290300370300200341c0066a41086a200341f8016a41086a290300370300200320032903f8013703c006200341106a20034190016a200341c0066a201d201c108e0220032802102202450d05200328021421060c040b4200211d420021100b02400240201d20045422062010200b542010200b5122021b0d00201d2004562010200b5620021b450d012003201d20047d3703900120032010200b7d2006ad7d37039801200320034190016a3602e005200341e0056a109d010c010b20032004201d7d370390012003200b20107d2004201d54ad7d37039801200320034190016a3602e005200341e0056a109c010b200341c0066a2004200b108f020240024002400240411810282202450d00200241002900e3e140370000200241106a41002900f3e140370000200241086a41002900ebe140370000200342988080808003370294012003200236029001200341c0066a20034190016a108f012003280298012102200328029001210620034198026a41186a2205420037030020034198026a41106a2207420037030020034198026a41086a2208420037030020034200370398022006200220034198026a1000200341f8016a41186a2005290300370300200341f8016a41106a2007290300370300200341f8016a41086a200829030037030020032003290398023703f8010240200328029401450d00200328029001102a0b2003410036029001200341f8016a412020034190016a100621022003280290012206417f460d022002450d0220064110490d01200241086a29000021042002290000210b2002102a0c030b411841011037000b41c4d1c3004133200341c8076a419cd9c3001038000b4200210b420021040b02400240200b201c5422062004201b542004201b5122021b0d00200b201c562004201b5620021b450d012003200b201c7d3703900120032004201b7d2006ad7d37039801200320034190016a3602e005200341e0056a109d010c010b2003201c200b7d370390012003201b20047d201c200b54ad7d37039801200320034190016a3602e005200341e0056a109c010b200341c0066a201c201b1090020c030b41dc9fc6002102410e21060c030b41dc9fc6002102410e21060b20020d010b200041023a00080c010b200041810a3b010820002006360204200020023602002000410a6a41003a00000b41012105410121060c0d0b109102000b024020032802cc062206450d0020032802c4062102200641246c210603400240024020022d0000220541034b0d0002400240024020050e0404000102040b2002410c6a280200450d03200241086a280200102a0c030b2002410c6a280200450d02200241086a280200102a0c020b2002410c6a280200450d01200241086a280200102a0c010b200241086a280200450d00200241046a280200102a0b200241246a21022006415c6a22060d000b0b024020032802c806450d0020032802c406102a0b024020072008460d0003402007280204220a450d01200741086a280200210902402007410c6a2802002202450d00200241246c2106200a210203400240024020022d0000220541034b0d0002400240024020050e0404000102040b2002410c6a280200450d03200241086a280200102a0c030b2002410c6a280200450d02200241086a280200102a0c020b2002410c6a280200450d01200241086a280200102a0c010b200241086a280200450d00200241046a280200102a0b200241246a21022006415c6a22060d000b0b200741f0006a210702402009450d00200a102a0b20072008470d000b0b0240200c450d00200d102a0b2004a7450d032017102a0c030b20072008460d0003402007280204220a450d01200741086a280200210902402007410c6a2802002202450d00200241246c2106200a210203400240024020022d0000220541034b0d0002400240024020050e0404000102040b2002410c6a280200450d03200241086a280200102a0c030b2002410c6a280200450d02200241086a280200102a0c020b2002410c6a280200450d01200241086a280200102a0c010b200241086a280200450d00200241046a280200102a0b200241246a21022006415c6a22060d000b0b200741f0006a210702402009450d00200a102a0b20072008470d000b0b0240200c450d00200d102a0b20034180056a41086a2202420037030020034200370380054193cdc200411120034180056a1008200341b8026a41086a200229030037030020032003290380053703b802200341c0066a20032802980322022004422088a7109202200341b8026a411020032802c006220620032802c8061007024020032802c406450d002006102a0b02402004a7450d002002102a0b200041023a000841002106410121050c090b02402005450d00200d200541f0006c6a2108200d2107034002402007410c6a2802002206450d0020072802042102200641246c210603400240024020022d0000220541034b0d0002400240024020050e0404000102040b2002410c6a280200450d03200241086a280200102a0c030b2002410c6a280200450d02200241086a280200102a0c020b2002410c6a280200450d01200241086a280200102a0c010b200241086a280200450d00200241046a280200102a0b200241246a21022006415c6a22060d000b0b200741f0006a21020240200741086a280200450d002007280204102a0b2002210720022008470d000b0b200c450d00200d102a0b20004181063b01082000200f3602042000200e360200410021062000410a6a41003a0000410121050c070b2005102a0b0240024002402007417f6a220241054b0d00024002400240024020020e06060006010203060b41000d052004a70d040c050b41000d042004a70d030c040b200a450d0302402004422088a72202450d00200241186c21062005210203400240200241046a280200450d002002280200102a0b0240200241106a280200450d002002410c6a280200102a0b200241186a2102200641686a22060d000b0b2004a70d020c030b2006450d0202402004422088a72202450d002002410c6c21062005210203400240200241046a280200450d002002280200102a0b2002410c6a2102200641746a22060d000b0b2004a70d010c020b02402004422088a72202450d002002410c6c21062005210203400240200241046a280200450d002002280200102a0b2002410c6a2102200641746a22060d000b0b2004a7450d010b2005102a0b410f210241ea9fc6002105410621072008417c6a0e0402010300020b200041023a0008410121060c030b4111210241a39fc6002105410521070c010b4113210241b49fc6002105410421070b41012106200041013b010820002002360204200020053602002000410a6a20073a00000b410021050b410121070b410121080b4101210a0b410121090b410121170b4101210d0b410121180b4101210e0b4101210f410121190b410121160b02402001280200220241124b0d00024002400240024002400240024002400240024002400240024020020e13000d0d010d0d020304050607080d090d0a0b0c000b2005450d0c0240200141086a280200220241054b0d0002400240024020020e06101000100102100b200141106a280200450d0f2001410c6a280200102a0c0f0b200141106a280200450d0e2001410c6a280200102a0c0e0b0240200141146a2802002206450d002001410c6a2802002102200641186c210603400240200241046a280200450d002002280200102a0b0240200241106a280200450d002002410c6a280200102a0b200241186a2102200641686a22060d000b0b200141106a280200450d0d200128020c102a0c0d0b0240200141146a2802002206450d002001410c6a28020021022006410c6c210603400240200241046a280200450d002002280200102a0b2002410c6a2102200641746a22060d000b0b200141106a280200450d0c200128020c102a0c0c0b2006450d0b02402001410c6a2802002202450d0020012802042200200241f0006c6a2107034002402000410c6a2802002206450d0020002802042102200641246c210603400240024020022d0000220541034b0d0002400240024020050e0404000102040b2002410c6a280200450d03200241086a280200102a0c030b2002410c6a280200450d02200241086a280200102a0c020b2002410c6a280200450d01200241086a280200102a0c010b200241086a280200450d00200241046a280200102a0b200241246a21022006415c6a22060d000b0b200041f0006a21020240200041086a280200450d002000280204102a0b2002210020022007470d000b0b200141086a280200450d0b2001280204102a0c0b0b2007450d0a0240200141086a2d00002202410c4b0d0020024106470d0b200141106a280200450d0b2001410c6a280200102a0c0b0b200141106a280200450d0a2001410c6a280200102a0c0a0b2008450d09200141086a280200450d092001280204102a0c090b200a450d08200141086a2d0000417f6a220241074b0d08024002400240024020020e08000c0c0c0c010203000b2001410c6a2202280200106a2002280200102a0c0b0b2001410c6a2202280200106a2002280200102a0c0a0b2001410c6a2202280200106a2002280200102a0c090b2001410c6a2202280200106a2002280200102a0c080b2009450d0720012d0004417f6a220241024b0d0702400240024020020e03000102000b2001410c6a280200450d09200141086a280200102a0c090b200141086a2202280200106a2002280200102a0c080b2001410c6a2202280200106a2002280200102a0c070b2017450d0620012d0004417f6a220241024b0d0602400240024020020e03000102000b2001410c6a280200450d08200141086a280200102a0c080b200141086a2202280200106a2002280200102a0c070b2001410c6a2202280200106a2002280200102a0c060b200d450d05200141086a280200417f6a220241014b0d050240024020020e020001000b200141106a280200450d062001410c6a280200102a0c060b200141106a280200450d052001410c6a280200102a0c050b2018450d0420012d00044104490d042001410c6a280200450d04200141086a280200102a0c040b200e450d03200141086a280200450d032001280204102a0c030b200f450d02200141086a2d0000417e6a220241024b0d0202400240024020020e03000102000b200141106a280200450d042001410c6a280200102a0c040b200141346a280200450d03200141306a280200102a0c030b200141306a280200450d022001412c6a280200102a0c020b2019450d0102402001280204220241024b0d00024020020e03030003030b200141086a2202280200106a2002280200102a0c020b2001412c6a2202280200106a2002280200102a0c010b2016450d0002402001410c6a280200450d00200141086a280200102a0b02402001411c6a2802002206450d00200141146a28020021022006410c6c210603400240200241046a280200450d002002280200102a0b2002410c6a2102200641746a22060d000b0b200141186a280200450d002001280214102a0b200341d0076a24000b4d01017f230041206b22002400200041146a410136020020004201370204200041ccd1c5003602002000410436021c200041c4d1c5003602182000200041186a360210200041a8c6c200103e000bfa0301077f230041306b22022400200241003602082002420137030020022002360210200141106a200241106a10c8012001200210a00120022002360210200141306a200241106a10c80120022002360210200141d0006a200241106a10c801200128020421032001410c6a2802002201200210b4010240024002402001450d00200141246c21040340200241106a200310ec01200228021021050240024020022802042206200228020822016b20022802182207490d00200228020021060c010b200120076a22082001490d04200641017422012008200120084b1b22014100480d040240024020060d002001102821060c010b200228020020062001102c21060b2006450d032002200136020420022006360200200228020821010b2002200120076a360208200620016a20052007109a051a02402002280214450d002005102a0b200341246a21032004415c6a22040d000b0b200228020421072002280208210320022802002101200241106a41186a22064200370300200241106a41106a22054200370300200241106a41086a220442003703002002420037031020012003200241106a1000200041186a2006290300370000200041106a2005290300370000200041086a20042903003700002000200229031037000002402007450d002001102a0b200241306a24000f0b200141011037000b1031000ba80301047f230041f0006b2202240002400240411010282203450d00200341086a41002900c6f042370000200341002900bef042370000200341104120102c2203450d0120032001360010200241086a41186a22014200370300200241086a41106a22044200370300200241086a41086a220542003703002002420037030820034114200241086a1000200241306a41186a2001290300370300200241306a41106a2004290300370300200241306a41086a2005290300370300200220022903083703302003102a200241086a200241306a412010a703200241d0006a41086a200241116a290000370300200241d0006a41106a2203200241196a290000370300200241d0006a41186a2201200241216a290000370300200220022900093703500240024020022d00084101460d0020004200370000200041186a4200370000200041106a4200370000200041086a42003700000c010b20002002290350370000200041186a2001290300370000200041106a2003290300370000200041086a200241d0006a41086a2903003700000b200241f0006a24000f0b411041011037000b412041011037000bd50c04077f017e027f017e230041b0016b22012400200141306a41086a220242003703002001420037033041afc5c2004111200141306a1008200141086a200229030037030020012001290330370300200141c0006a2001411010fd0120012d00402103200141106a41186a2204200141d9006a290000370300200141106a41106a2205200141c0006a41116a290000370300200141106a41086a2206200141c9006a290000370300200120012900413703100240024020034101470d0020002001290310370000200041186a2004290300370000200041106a2005290300370000200041086a20062903003700000c010b200141c0006a41086a220342003703002001420037034041b1f0c200410d200141c0006a1008200220032903003703002001200129034037033020014100360240200141306a4110200141c0006a1006210202400240024020012802402203417f460d002002450d002001200336021420012002360210200141c0006a200141106a107620012802402207450d02200129024421082003450d012002102a0c010b41042107420021080b20072008422088a7220941246c6a2104200721020240024002400240034002400240200420026b41ed00490d0003400240200222032d00004101470d00200341246a210a200341106a2105200341086a2106200341016a21020c030b0240200341246a2d00004101470d00200341c8006a210a200341346a21052003412c6a2106200341256a21020c030b0240200341c8006a2d00004101470d00200341ec006a210a200341d8006a2105200341d0006a2106200341c9006a21020c030b0240200341ec006a2d00004101470d0020034190016a210a200341fc006a2105200341f4006a2106200341ed006a21020c030b200420034190016a22026b41ec004b0d000b20034190016a21020b20022004460d020240034020022d00004101460d012004200241246a2202460d040c000b0b200241246a210a200241106a2105200241086a2106200241016a21020b200228000021022006280200210320012005280200360214200120033602100240200241c28289aa04460d00200a21020c010b0b200141c0006a200141106a10ba0220012d004022024102460d00200141a4016a28020021062001280244210a4200210b200141306a41086a220342003703002001420037033041c785c2004112200141306a1008200141c0006a41086a20032903003703002001200129033037034020014100360210200141c0006a4110200141106a100621050240024020012802102203417f460d002001200336023420012005360230200141106a200141306a106d20012802102204450d052001290214210b2003450d012005102a0c010b410121040b410021030240200a200620024101711b2202200b422088a74f0d00200420024105746a2202450d00200141106a41186a200241186a290000370300200141106a41106a200241106a290000370300200141106a41086a200241086a29000037030020012002290000370310410121030b0240200ba7450d002004102a0b20030d010b20004200370000200041186a4200370000200041106a4200370000200041086a42003700000c010b200141c0006a41186a2202200141106a41186a290300370300200141c0006a41106a2203200141106a41106a290300370300200141c0006a41086a2204200141106a41086a29030037030020012001290310370340200141306a41086a220542003703002001420037033041afc5c2004111200141306a1008200141086a2005290300370300200120012903303703002001411036023420012001360230200141c0006a200141306a10ff01200041186a2002290300370000200041106a2003290300370000200041086a2004290300370000200020012903403700000b02402009450d00200941246c21032007210203400240024020022d0000220441034b0d0002400240024020040e0404000102040b2002410c6a280200450d03200241086a280200102a0c030b2002410c6a280200450d02200241086a280200102a0c020b2002410c6a280200450d01200241086a280200102a0c010b200241086a280200450d00200241046a280200102a0b200241246a21022003415c6a22030d000b0b2008a7450d022007102a0c020b41c4d1c30041332001419cd9c3001038000b41c4d1c30041332001419cd9c3001038000b200141b0016a24000b860c07057f017e047f027e037f027e047f230041c0006b22012400200141106a41086a220242003703002001420037031041f09cc600411e200141106a1008200141086a2203200229030037030020012001290310370300200141106a200110de03200128021021042001280214210520012903182106200028020821072000280204210820002802002109200242003703002001420037031041a5afc4004116200141106a100820032002290300370300200120012903103703002001410036021020014110200141106a100621000240024002400240024002400240024020012802102202417f460d002000450d002001200236023420012000360230200141106a200141306a106d2001280210220a450d022001290214210b2002450d012000102a0c010b4101210a4200210b0b2006420020051b210c2004410020051b21042005410420051b210d02402007450d002009200741246c6a210e200a200b422088a74105746a21032009210203402002280220210f200241086a2900002106200241106a290000211020022900002111200141106a41186a200241186a290000370300200141106a41106a2010370300200141106a41086a200637030020012011370310200241246a2102200a2105410021000240024003400240200320056b41e0004b0d0020052003460d030340200141106a2005460d0320002005200141106a4120109c0522074100476a21002007450d032003200541206a2205470d000c040b0b200141106a2005460d0120002005200141106a4120109c0522074100476a21002007450d01200541206a2207200141106a460d0120002007200141106a4120109c0522074100476a21002007450d01200541c0006a2207200141106a460d0120002007200141106a4120109c0522074100476a21002007450d01200541e0006a2207200141106a460d0120054180016a210520002007200141106a4120109c0522074100476a210020070d000b0b2004200f6a22072004490d000240200041016a2204200c422088a722054d0d000240200ca7221220056b20042005200420054b1b221320056b22044f0d00200520046a22142005490d0a201241017422152014201520144b1b221441ffffffff03712014470d0a201441027422154100480d0a0240024020120d0020151028210d0c010b200d20124102742015102c210d0b200d450d062014ad210c0b200d20054102746a21120240024020044102490d002012410020132005417f736a22044102741099051a200d200520136a20056b4102746a417c6a2112200420056a21050c010b2004450d010b20124100360200200541016a21050b200520004d0d05200d20004102746a22002000280200200f6a360200200c42ffffffff0f832005ad42208684210c200721040b2002200e470d000b0b02402008450d002009102a0b0240200ba7450d00200a102a0b200141106a41086a220542003703002001420037031041f09cc600411e200141106a1008200141086a20052903003703002001200129031037030002400240200d0d002001411010090c010b2001410036021820014201370310410410282205450d042005200436000020014284808080c00037021420012005360210200c422088a72205200141106a10b4010240024020050d002001280218210420012802142103200128021021000c010b2005410274210f4100200128021822056b210220012802142103200d210703402007280200210a02400240200320026a4104490d00200128021021000c010b200541046a22002005490d09200341017422042000200420004b1b22044100480d090240024020030d002004102821000c010b200128021020032004102c21000b2000450d082001200436021420012000360210200421030b200741046a21072001200541046a2204360218200020056a200a3600002002417c6a210220042105200f417c6a220f0d000b0b200ca721052001411020002004100702402003450d002000102a0b2005450d00200d102a0b200141c0006a24000f0b41c4d1c3004133200141386a419cd9c3001038000b201541041037000b41ac9bc600200020051034000b410441011037000b200441011037000b1031000b4d01017f230041206b22002400200041146a410136020020004201370204200041ccd1c5003602002000410436021c200041c4d1c5003602182000200041186a3602102000419896c400103e000ba70101047f230041206b22002400200041106a41086a2201420037030020004200370310419499c6004114200041106a1008200041086a200129030037030020002000290310370300410021022000410036021020004110200041106a100621010240024020002802102203417f460d002001450d0020034104490d01200128000021022001102a0b200041206a240020020f0b41c4d1c3004133200041106a419cd9c3001038000b9d0401067f230041d0006b220324000240024002400240411b10282204450d00200441176a41002800d89646360000200441106a41002900d19646370000200441086a41002900c99646370000200441002900c196463700002004411b4136102c2204450d012004200136001b200341306a41186a22014200370300200341306a41106a22054200370300200341306a41086a22064200370300200342003703302004411f200341306a1000200341086a41186a22072001290300370300200341086a41106a2005290300370300200341086a41086a2006290300370300200320032903303703082004102a412010282204450d0220042003290308370000200441186a2007290300370000200441106a200341086a41106a2205290300370000200441086a200341086a41086a22062903003700002003200236022c20014200370300200341306a41106a22024200370300200341306a41086a22084200370300200342003703302003412c6a4104200341306a1000200720012903003703002005200229030037030020062008290300370300200320032903303703082004412041c000102c2204450d0320042003290308370020200441386a200341206a290300370000200441306a2005290300370000200441286a2006290300370000200042c0808080800837020420002004360200200341d0006a24000f0b411b41011037000b413641011037000b412041011037000b41c00041011037000bcb0201047f230041d0006b220324002003410036022820012002200341286a1006210402400240024020032802282205417f460d0020040d010b200041003a00000c010b41002101200341003a00480340024020052001470d000240200141ff0171450d00200341003a00480b41c4d1c3004133200341286a419cd9c3001038000b200341286a20016a200420016a2d00003a00002003200141016a22023a00482002210120024120470d000b200341086a41186a2201200341286a41186a290300370300200341086a41106a2202200341286a41106a290300370300200341086a41086a2206200341286a41086a2903003703002003200329032837030802402005450d002004102a0b20002003290308370001200041013a0000200041196a2001290300370000200041116a2002290300370000200041096a20062903003700000b200341d0006a24000bec0202047f017e230041d0006b22022400024002400240410f10282203450d00200341076a4100290092b4433700002003410029008bb4433700002003410f411e102c2203450d012003200136000f200241286a41186a22014200370300200241286a41106a22044200370300200241286a41086a220542003703002002420037032820034113200241286a1000200241186a2001290300370300200241106a2004290300370300200241086a2005290300370300200220022903283703002003102a2002410036022820024120200241286a100621010240024020022802282203417f460d002002200336022420022001360220200241286a200241206a106d20022802282204450d04200229022c210602402003450d002001102a0b20002006370204200020043602000c010b20004100360208200042013702000b200241d0006a24000f0b410f41011037000b411e41011037000b41c4d1c3004133200241c8006a419cd9c3001038000bdf0301017f024002400240024002400240410110282202450d00200220002d00003a0000200241014102102c2202450d01200220002d00013a0001200241024104102c2202450d02200220002d00023a0002200220002d00033a0003200241044108102c2202450d03200220002d00043a0004200220002d00053a0005200220002d00063a0006200220002d00073a0007200241084110102c2202450d04200220002d00083a0008200220002d00093a0009200220002d000a3a000a200220002d000b3a000b200220002d000c3a000c200220002d000d3a000d200220002d000e3a000e200220002d000f3a000f200241104120102c2202450d05200220002d00103a0010200220002d00113a0011200220002d00123a0012200220002d00133a0013200220002d00143a0014200220002d00153a0015200220002d00163a0016200220002d00173a0017200220002d00183a0018200220002d00193a0019200220002d001a3a001a200220002d001b3a001b200220002d001c3a001c200220002d001d3a001d200220002d001e3a001e200220002d001f3a001f200128020020012802042002412010072002102a0f0b410141011037000b410241011037000b410441011037000b410841011037000b411041011037000b412041011037000bf54606077f027e0f7f047e117f017e230041800a6b2203240002400240024002400240024002400240024002400240024002400240024002400240024002400240024020012d00000e06000102030405000b200341cc026a4101360200200342013702bc02200341ccd1c5003602b802200341043602b406200341c4d1c5003602b0062003200341b0066a3602c802200341b8026a41e893c400103e000b200141e0006a2802002104200341b0066a200141086a41d800109a051a20034198056a200141fc006a28020036020020034190056a200141f4006a29020037030020034180056a41086a200141ec006a2902003703002003200141e4006a29020037038005024020022d000120022d000072450d0041a39fc600210541112104410121060c120b200341b8026a10f70302402003280290032004490d0041f893c400210541352104410121060c120b200341b8026a41086a41033a00002003410c3a00b802200341b8026a410c6a20043602004100210541014100200341b8026a10cc01200341b8026a200341b0066a41d800109a051a2003419c036a20034180056a41086a290300370200200341a4036a20034180056a41106a290300370200200341ac036a20034180056a41186a2802003602002003200436029003200320032903800537029403200341c0086a41086a22024200370300200342003703c00841c0fec5004118200341c0086a100820034180046a41086a2002290300370300200320032903c00837038004200341003602c808200342013703c008200341b8026a200341c0086a10ee0120032802c408210220034180046a411020032802c008220420032802c80810072002450d0f2004102a0c0f0b2001410c6a2802002107200141086a280200210841042104200141046a2802002109200141106a290300210a2002411a6a290100210b200241196a2d0000210c200241186a2d0000210d200241166a2f0100210e200241156a2d0000210f200241146a2d00002110200241126a2f01002111200241116a2d00002112200241106a2d000021132002410e6a2f010021142002410d6a2d000021152002410c6a2d000021162002410a6a2f01002117200241096a2d00002118200241046a2d00002119200241026a2f0100211a0240024020022d00000d0020022d00014101470d00200241056a2d00002104200241066a2f01002105200241086a2d00002102410021060c010b4101210641002102410021050b200541ffff0371410874200241187472200441ff017172210202402006450d0041ea9fc6002105410f210402400240024002400240024020020e0700010203040513000b20174108742018722016411874722105201441087420157220134118747221040c120b41dc9fc6002105410e21040c110b41d09fc6002105410c21040c100b41c79fc6002105410921040c0f0b41b49fc6002105411321040c0e0b41a39fc6002105411121040c0d0b2003200b370398042003200c3a0097042003200d3a0096042003200e3b0194042003200f3a009304200320103a009204200320113b019004200320123a008f04200320133a008e04200320143b018c04200320153a008b04200320163a008a04200320173b018804200320183a0087042003200236008304200320193a0082042003201a3b018004200341e8006a10f603024002402003290368220b200341e8006a41086a290300221b8450450d004200211c4200211d0c010b200341c8006a201b4200200a4200109f05200341d8006a200b4200200a4200109f05200341386a42004200200b4200109f0502402003290350200329034084420052200341e0006a290300221c200329034820032903387c7c221d201c5472450d0041a6b5c0002105412721040c0e0b2003290358211c0b200341b8026a20034180046a201c201d4108109802024020032802b8024101470d0020032802c002210420032802bc0221050c0d0b200341c8026a290300211c20032903c002211d200341b8026a10f703200341286a20032903b80242002007ad4200109f050240200a427f200329032820032903304200521b7d221e200a562205450d0041fdbfc2002102412c21040c0b0b200341b0066a20092007200341b8026a10f802024020032802b0064101470d00200341b8066a280200210420032802b40621020c0b0b200341c8096a41186a2206200341b0066a410472220241186a280200360200200341c8096a41106a2216200241106a290200370300200341c8096a41086a2217200241086a290200370300200320022902003703c80920034180056a41186a2213420037030020034180056a41106a2214420037030020034180056a41086a2215420037030020034200370380052009200720034180056a1000200341da016a221820032d0082053a000020034198026a41086a220c20034180056a41136a290000370300200341a5026a220d2013290000370000200320032f0180053b01d8012003200329008b053703980220032800830521022003280087052104200341e0076a41186a2006280200360200200341e0076a41106a2016290300370300200341e0076a41086a2017290300370300200320032903c8093703e007200320043600b706200320023600b306200320182d00003a00b206200320032f01d8013b01b006200341b0066a41136a200c290300370000200341b0066a41186a200d29000037000020032003290398023700bb06411410282206450d03200641002900ddd843370000200641106a41002800edd843360000200641086a41002900e5d84337000020034294808080c0023702fc01200320063602f8012003200341f8016a36028005200341b0066a20034180056a10c80120032802f8012106200328028002211620134200370300201442003703002015420037030020034200370380052006201620034180056a1000200341c0086a41186a2013290300370300200341c0086a41106a2014290300370300200341c0086a41086a201529030037030020032003290380053703c008024020032802fc01450d0020032802f801102a0b200341203602b4062003200341c0086a3602b006200341e0076a200341b0066a10f9020240200341f0076a280200450d0020032802ec07102a0b200341c3066a20034198026a41086a290300370000200341b0066a41186a20034198026a410d6a2900003700002003200341da016a2d00003a00b206200320032f01d8013b01b006200320043600b706200320023600b30620032003290398023700bb06411510282206450d04200641002900c8d8433700002006410d6a41002900d5d843370000200641086a41002900d0d84337000020034295808080d0023702e407200320063602e0072003200341e0076a36028005200341b0066a20034180056a10c80120032802e007210620032802e807211320034180056a41186a2214420037030020034180056a41106a2215420037030020034180056a41086a2216420037030020034200370380052006201320034180056a1000200341c0086a41186a2014290300370300200341c0086a41106a2015290300370300200341c0086a41086a201629030037030020032003290380053703c008024020032802e407450d0020032802e007102a0b200341203602b4062003200341c0086a3602b00620092007200341b0066a10cb0102402008450d002009102a0b200341f8016a41026a200341d8016a41026a2d000022063a000020034180056a41086a221320034198026a41086a29030037030020034180056a410d6a220820034198026a410d6a290000370000200320032f01d80122093b01f801200320032903980237038005200341b0066a41086a41023a0000200341b9066a20093b0000200341bb066a20063a0000200341c0066a20043602002003410c3a00b006200341b0066a410c6a2002360200200341c4066a200329038005370200200341cc066a2013290300370200200341d1066a20082900003700004100211341014100200341b0066a10cc010c0b0b200141c0006a290300210b200141386a290300211d2002411a6a290100211c200241196a2d0000211f200241186a2d00002120200241166a2f01002121200241156a2d00002122200241146a2d00002123200241126a2f01002124200241116a2d00002125200241106a2d000021262002410e6a2f010021272002410d6a2d000021282002410c6a2d000021292002410a6a2f0100212a200241096a2d0000212b41042104200241046a2d0000212c200241026a2f0100212d200141306a280200212e2001412c6a2802002108200141286a28020021092001411d6a290000210a2001411c6a2d000021142001411b6a2d00002115200141196a2f00002116200141186a2d00002117200141176a2d00002118200141156a2f0000210c200141146a2d0000210d200141136a2d0000210e200141116a2f0000210f200141106a2d000021102001410f6a2d000021112001410d6a2f000021122001410c6a2d00002119200141086a2802002105200141076a2d0000211a200141056a2f00002107200141046a2d0000212f200141c8006a290300211b0240024020022d00000d0020022d00014101470d00200241056a2d00002104200241066a2f01002106200241086a2d00002102410021130c010b4101211341002102410021060b200641ffff0371410874200241187472200441ff01717221060240024002402013450d0041ea9fc6002105410f21040240024002400240024020060e0700060102030410000b202a410874202b722029411874722105202741087420287220264118747221040c0f0b41d09fc6002105410c21040c0e0b41c79fc6002105410921040c0d0b41b49fc6002105411321040c0c0b41a39fc6002105411121040c0b0b202f41ff01714101470d01200341b8026a200541067610fe0120032802b80221040240024020032802c0022005413f7122024b0d00410021020c010b200420024105746a2202290018210a20022d0017211420022d0016211520022f0014211620022d0013211720022d0012211820022f0010210c20022d000f210d20022d000e210e20022f000c210f20022d000b211020022d000a211120022f0008211220022d000721192002280003210520022d0002211a20022f00002107410121020b024020032802bc02450d002004102a0b20020d010b41dc9fc6002105410e21040c090b2003201c3703c8062003201f3a00c706200320203a00c606200320213b01c406200320223a00c306200320233a00c206200320243b01c006200320253a00bf06200320263a00be06200320273b01bc06200320283a00bb06200320293a00ba062003202a3b01b8062003202b3a00b706200320063600b3062003202c3a00b2062003202d3b01b0062003200a3703d002200320143a00cf02200320153a00ce02200320163b01cc02200320173a00cb02200320183a00ca022003200c3b01c8022003200d3a00c7022003200e3a00c6022003200f3b01c402200320103a00c302200320113a00c202200320123b01c002200320193a00bf02200320053600bb022003201a3a00ba02200320073b01b8022003202e3602c808200320083602c408200320093602c00820034180056a200341b0066a200341b8026a201d200b201b200341c0086a10f5030240024002402003280280054101460d00024020034188056a280200450d00200328028405102a0b41002113410121060c010b4101210620032802840522050d01410021130b41012108410021050c110b20034188056a2802002104024020034190056a280200450d002003418c056a280200102a0b41002113410121080c100b200141386a290300211c200141306a290300211b200141c0006a290300210a200341d8016a41186a200141196a290000370300200341d8016a41106a200141116a290000370300200341d8016a41086a200141096a290000370300200320012900013703d8012002411a6a290100210b200241196a2d0000210c200241186a2d0000210d200241166a2f0100210e200241156a2d0000210f200241146a2d00002110200241126a2f01002111200241116a2d00002112200241106a2d000021092002410e6a2f010021142002410d6a2d000021152002410c6a2d000021162002410a6a2f01002117200241096a2d0000211841042104200241046a2d00002119200241026a2f0100211a2001412c6a2802002107200141286a2802002106200141246a28020021080240024020022d00000d0020022d00014101470d00200241056a2d00002104200241066a2f01002105200241086a2d00002102410021130c010b4101211341002105410021020b200541ffff0371410874200441ff017172200241187472210202402013450d00410f210441ea9fc6002105024002400240024002400240024020020e0700010203040506000b20174108742018722016411874722105201441087420157220094118747221040c050b410e210441dc9fc60021050c040b410c210441d09fc60021050c030b4109210441c79fc60021050c020b4113210441b49fc60021050c010b4111210441a39fc60021050b2006450d072008102a0c070b2003200b370390022003200c3a008f022003200d3a008e022003200e3b018c022003200f3a008b02200320103a008a02200320113b018802200320123a008702200320093a008602200320143b018402200320153a008302200320163a008202200320173b018002200320183a00ff01200320023600fb01200320193a00fa012003201a3b01f801200341c8016a10f603024002400240024020032903c801220b200341c8016a41086a29030022308450450d004200211e4200211d0c010b200341a8016a20304200200a4200109f05200341b8016a200b4200200a4200109f0520034198016a42004200200b4200109f05024020032903b00120032903a00184420052200341c0016a290300221e20032903a8012003290398017c7c221d201e5472450d004127210441a6b5c00021050c020b20032903b801211e0b200341b8026a200341f8016a201e201d410810980220032802b8024101470d0120032802c002210420032802bc0221050b2006450d072008102a0c070b200341b8026a41106a290300211e20032903c002211d20034198026a41186a20303703002003200b3703a8022003200a3703a0022003200a37039802200341b8026a10f703200341b8036a4200370300200341e8036a4200370300200341d8036a4200370300200341c8036a42003703002003428080e983b1de163703b00320034280a094a58d1d3703e00320034280a094a58d1d3703d00320034280a094a58d1d3703c003200342808880808080103703f0032003200341b8026a3602f8032003200341b8026a3602fc03200341b0066a41186a2204200341f8016a41186a290300370300200341b0066a41106a2202200341f8016a41106a290300370300200341b0066a41086a2205200341f8016a41086a290300370300200320032903f8013703b00610a003210a1098012113200341b8046a420037030020034180046a412c6a41d0b5c00036020020034180046a41286a4101360200200341a0046a42003703002003419c046a41f8b9c000360200200341d8046a2005290300370300200341e0046a2002290300370300200341e8046a200429030037030020034200370388042003428080808080013703b004410021122003410036029804200320032903b0063703d0042003200341fc036a3602c8042003200341f8036a3602c4042003200341b8026a3602c004200320133602cc042003200a37038004200320073602880520032006360284052003200836028005200341b0066a20034180046a201b201c20034198026a200341d8016a20034180056a10b50120032802b0064101470d0420022802002207410876212f200341bc066a2802002126200341b0066a41086a280200210420032802b406211a41012112410121190c050b200141216a2d0000210620034180056a41186a200141196a29000037030020034180056a41106a200141116a29000037030020034180056a41086a200141096a290000370300200320012900013703800541ad94c400210541e900210420022d00000d0c200228000121130240200641ff01714101460d00201341ff01714101470d0d20134118762104201341087621052002411a6a290100210a200241196a2d00002106200241186a2d00002113200241166a2f01002108200241156a2d00002109200241146a2d00002114200241126a2f01002115200241116a2d00002116200241106a2d000021172002410e6a2f010021182002410d6a2d0000210c2002410c6a2d0000210d2002410a6a2f0100210e200241096a2d0000210f200241056a2800002102410221100c030b201341ff01714102470d0c2001413a6a290000210a200141396a2d00002106200141386a2d00002113200141366a2f00002108200141356a2d00002109200141346a2d00002114200141326a2f00002115200141316a2d00002116200141306a2d000021172001412e6a2f000021182001412d6a2d0000210c2001412c6a2d0000210d2001412a6a2f0000210e200141296a2d0000210f200141256a2800002102200141246a2d00002104200141226a2f00002105410021100c020b411441011037000b411541011037000b2003200a3703c806200320063a00c706200320133a00c606200320083b01c406200320093a00c306200320143a00c206200320153b01c006200320163a00bf06200320173a00be06200320183b01bc062003200c3a00bb062003200d3a00ba062003200e3b01b8062003200f3a00b706200320023600b306200320043a00b206200320053b01b006200341b8026a20034180056a2010410010c20120032d00b8022102024020032d00c0020d00200341dc026a280200450d00200341d8026a280200102a0b0240200241ff01714101470d00200341b8026a200341b0066a42808086bdbacdd21a420010a502024020032802b8024101470d0020032802c002210420032802bc022105410121060c0c0b200320032903c0023703c0082003200341c8026a2903003703c8082003200341c0086a3602800420034180046a109c010b410021050c080b200341e0066a2802002207410876212f200341b0066a412c6a2802002126200341b0066a41286a2802002104200341d4066a280200211a41012119200741ff01710d00200341b0066a41086a200341a0046a29030037030020034180056a41086a200341bc066a28020036020020032003290398043703b006200320032902b40637038005200341f8096a20034180056a1092014100210741002112410021190b200341f8006a20032903a802200341b0026a29030020032903a002220a4200109f05200329039802200a7d10e50320034188016a200341f8016a2003290378200341f8006a41086a29030010d001200341c0066a201e20034188016a41086a290300220b7d201d200329038801220a54ad7d200b201e7d200a201d54ad7d200a201d58200b201e58200b201e5122021b22051b221c3703002003201d200a7d200a201d7d20051b221b3703b8062003200a201d56200b201e5620021b2202ad220a3703b00641012105024020020d002003201b370380052003201c37038805200320034180056a3602c008200341c0086a109d014100210520032903b006210a0b200341b0066a41086a210202400240200a4200520d002005450d01200320023602800520034180056a109d010c010b200320023602800520034180056a109c010b20032802bc04210520032802b8042106200320032802b40422023602f804200320063602f404200320023602f00420032002200541b0016c6a22163602fc0402402005450d00200341c0086a410172210e200341e7076a210f200341e0076a4102722113200341b0066a41106a2110200341d8066a210d20034194076a2118200341f1066a2108200341d1066a2109200341b0066a4101722117200341a8076a2111034020022d0000210520034180056a200241016a41af01109a051a0240024020054103460d00200320053a00b006201720034180056a41af01109a052106024002400240024020050e03000102000b20032802b806211520032802bc06210620032802b4062105200f201041d800109a051a2003410c3a00c008200e200341e0076a41df00109a051a20052006200341c0086a10cc01410121064100211402402015450d002005102a0b410021150c020b20032f00b106210520032d00b306211420032802b406211520032d00b806210c20032900b906210a20032900c106210b20032900c906211d200341c0086a200d418801109a051a20132006290000370000201341086a200641086a290000370000201341106a200641106a290000370000201341186a200641186a29000037000020034180023b01e007200341c8096a200341c0086a200341e0076a10f401200320032d00d0094102463a00e9082003201d3700e1082003200b3700d9082003200a3700d1082003200c3a00d008200320153602cc08200320143a00cb08200320053b00c908200341043a00c8082003410c3a00c008410021064101211441014100200341c0086a10cc01410021150c010b2011290300210a20032903a007210b200341c8096a41186a200641186a290000370300200341c8096a41106a200641106a290000370300200341c8096a41086a200641086a290000370300200320062900003703c809200341e0076a41186a200941186a290000370300200341e0076a41106a200941106a290000370300200341e0076a41086a200941086a290000370300200320092900003703e007200341c0086a41186a200841186a290000370300200341c0086a41106a200841106a290000370300200341c0086a41086a200841086a290000370300200320082900003703c008200341e8096a41086a201841086a280200360200200320182902003703e809200341c8096a200341e0076a200341c0086a200b200a200341e8096a10f8034101211441012106410121150b024020032d00b006220541014b0d000240024020050e020001000b2014450d03024020032802b806450d0020032802b406102a0b20032d00c0064105490d0320032802e806450d0320032802e406102a0c030b2006450d02200d106a0c020b201520032802980745720d01200328029407102a0c010b2003200241b0016a3602f8040c020b200241b0016a22022016470d000b200320163602f8040b200341f0046a10690240200328028c042202450d0020034190046a280200450d002002102a0b02402019450d0020034180046a411c6a280200210220032802a40421080240024020032802a00422060d00200221050c010b2006211320022105034020052802880b21052013417f6a22130d000b0340200220022f01064102746a41880b6a28020021022006417f6a22060d000b0b200341b0066a411c6a20022f0106360200200341c8066a4100360200200341c4066a2002360200200320083602d006200341003602c006200342003703b806200320053602b406200341003602b006200341b0066a109b010b024020120d0041002105024020040d00410021040c020b201a102a0c010b0240201a0d00410021050c010b0240202f410874200741ff017172450d002026102a0b201a21050b4100210841012106410121130c080b41002113410121062008450d032009102a410121080c070b410121132008450d002009102a0b200341086a200b201b4200201e20051b221e4200109f05200a201e7d10e503200341186a20034180046a2003290308200341086a41086a29030010d001200341c0066a201c200341186a41086a290300220b7d201d2003290318220a54ad7d200b201c7d200a201d54ad7d200a201d58200b201c58200b201c5122051b22061b221b3703002003201d200a7d200a201d7d20061b221e3703b8062003200a201d56200b201c5620051b2205ad220a3703b00641012106024020050d002003201e3703c0082003201b3703c8082003200341c0086a3602e007200341e0076a109d014100210620032903b006210a0b200341b0066a41086a210502400240200a4200520d002006450d01200320053602c008200341c0086a109d010c010b200320053602c008200341c0086a109c010b41002106410021052013450d04200221050c040b41012113410021062008450d002009102a0b410121080c030b0b410121060b41012113410121080b024020012d0000417e6a220241024b0d00024002400240024020020e03000102000b2006450d03200141086a280200450d03200141046a280200102a0c030b20130d010c020b2008450d01200141286a280200450d01200141246a280200102a0c010b2001412c6a280200450d00200141286a280200102a0b2000200436020420002005360200200341800a6a24000be90604057f027e067f027e23004190016b2202240041002103200241003a008801200128020421040240024003402004450d01200241e8006a20036a200128020022052d00003a000020012004417f6a22043602042001200541016a3602002002200341016a22063a0088012006210320064120470d000b200241086a41086a200241e8006a41086a290300370300200241086a41106a200241e8006a41106a290300370300200241086a41186a200241e8006a41186a29030037030020022002290368370308024020044110490d00200541096a2900002107200529000121082001200441706a22093602042001200541116a36020041002103200241003a008801416f210a0340024020092003470d000240200341ff0171450d00200241003a0088010b200042013703000c040b200241e8006a20036a200520036a220641116a2d00003a00002001200420036b416f6a3602042001200641126a3602002002200341016a22063a008801200a417f6a210a2006210320064120470d000b200241286a41086a220b200241e8006a41086a2203290300370300200241286a41106a220c200241e8006a41106a220a290300370300200241286a41186a220d200241e8006a41186a2209290300370300200220022903683703280240200420066b220441706a4110490d002003200241086a41086a290300370300200a200241086a41106a2903003703002009200241086a41186a290300370300200241c8006a41086a220e200b290300370300200241c8006a41106a220b200c290300370300200241c8006a41186a220c200d290300370300200520066a220641116a290000210f200641196a29000021102001200441606a3602042001200641216a3602002002200229030837036820022002290328370348200041206a2010370300200041186a200f370300200041106a200737030020002008370308200041286a2002290368370300200041306a2003290300370300200041386a200a290300370300200041c0006a2009290300370300200041c8006a2002290348370300200041d0006a200e290300370300200041d8006a200b290300370300200041e0006a200c290300370300200042003703000c030b200042013703000c020b200042013703000c010b0240200341ff0171450d00200241003a0088010b200042013703000b20024190016a24000ba80302067f027e230041d0006b2204240002400240411810282205450d00200541002900e3e140370000200541106a41002900f3e140370000200541086a41002900ebe140370000200442988080808003370224200420053602202001200441206a108f012004280228210520042802202106200441306a41186a22074200370300200441306a41106a22084200370300200441306a41086a220942003703002004420037033020062005200441306a1000200441186a2007290300370300200441106a2008290300370300200441086a20092903003703002004200429033037030002402004280224450d002004280220102a0b2004410036023020044120200441306a100621050240024020042802302206417f470d004200210a4200210b0c010b20064110490d02200541086a290000210b2005290000210a2005102a0b2001200a2002200a200a200256200b200356200b2003511b22051b22027d200b2003200b20051b22037d200a200254ad7d1090022000200337030820002002370300200441d0006a24000f0b411841011037000b41c4d1c3004133200441306a419cd9c3001038000be40602067f047e230041e0006b22042400024002400240024002400240411410282205450d00200541002900cfe140370000200541106a41002800dfe140360000200541086a41002900d7e14037000020044294808080c002370234200420053602302001200441306a108f012004280238210520042802302106200441c0006a41186a22074200370300200441c0006a41106a22084200370300200441c0006a41086a220942003703002004420037034020062005200441c0006a1000200441106a41186a2007290300370300200441106a41106a2008290300370300200441106a41086a20092903003703002004200429034037031002402004280234450d002004280230102a0b20044100360240200441106a4120200441c0006a100621050240024020042802402206417f470d004200210a4200210b0c010b20064110490d02200541086a290000210b2005290000210a2005102a0b0240200a2002542205200b200354200b2003511b450d00418991c1002105411521010c060b200441086a20014104200a20027d220a200b20037d2005ad7d220b10bc01200428020822050d04411810282205450d02200541002900e3e140370000200541106a41002900f3e140370000200541086a41002900ebe140370000200442988080808003370234200420053602302001200441306a108f012004280238210520042802302106200441c0006a41186a22074200370300200441c0006a41106a22084200370300200441c0006a41086a220942003703002004420037034020062005200441c0006a1000200441106a41186a2007290300370300200441106a41106a2008290300370300200441106a41086a20092903003703002004200429034037031002402004280234450d002004280230102a0b20044100360240200441106a4120200441c0006a100621050240024020042802402206417f470d004200210c4200210d0c010b20064110490d04200541086a290000210d2005290000210c2005102a0b2001200c20027c2202200d20037c2002200c54ad7c1090022001200a200b108f02410021050c050b411441011037000b41c4d1c3004133200441c0006a419cd9c3001038000b411841011037000b41c4d1c3004133200441c0006a419cd9c3001038000b200428020c21010b2000200136020420002005360200200441e0006a24000bd9140a057f017e067f037e037f017e017f027e077f057e23002204210520044180026b4160712204240002400240200141ffffff3f712001470d0020014105742206417f4c0d0002400240024020060d00410121070c010b200610282207450d010b410021084100210602402001450d002001410574210820072106034020062000290000370000200641186a200041186a290000370000200641106a200041106a290000370000200641086a200041086a290000370000200641206a2106200041206a2100200841606a22080d000b200141057441606a41057641016a2106200121080b20042006360218200420083602142004200736021020072006410041202006676b10c40242002109200441b0016a41086a22004200370300200442003703b00141cf96c300411d200441b0016a1008200441e0016a41086a2000290300370300200420042903b0013703e001200441003602b001200441e0016a4110200441b0016a1006210602400240024020042802b0012200417f460d0020042000360294012004200636029001200441b0016a20044190016a106d20042802b001220a450d0220042902b40121092000450d012006102a0c010b4101210a0b2009422088a72200450d032000410574210b200441e0016a410c6a210c200441e0016a411472210d200441e0016a410872210e200441c0006a410c72210f200a210002400340200041086a2900002110200041106a290000211120002900002112200441206a41186a2213200041186a290000370300200441206a41106a22142011370300200441206a41086a22152010370300200420123703200240024002400240411a10282206450d00200641002900ec96432216370000200641186a41002f0084974322173b0000200641106a41002900fc96432218370000200641086a41002900f4964322193700002004429a808080a0033702b401200420063602b0012004200441b0016a3602e001200441206a200441e0016a10c80120042802b001210720042802b801211a200441e0016a41186a22014200370300200441e0016a41106a22064200370300200441e0016a41086a22084200370300200442003703e0012007201a200441e0016a100020044190016a41186a221b200129030037030020044190016a41106a221c200629030037030020044190016a41086a221a2008290300370300200420042903e00137039001024020042802b401450d0020042802b001102a0b200441003602e00120044190016a4120200441e0016a1006211d20042802e0012207417f460d02200420073602642004201d360260200441e0016a200441e0006a10b30320042802e801221e450d01200441b0016a41086a221f200c41086a290200370300200441b0016a41106a2220200c41106a2802003602002004200c2902003703b00120042903e001211002402007450d00201d102a0b200f20042903b00122113702002006202028020022073602002008201f2903002212370300200f41086a2012370200200f41106a2007360200200420113703e001200420103703400c030b411a41011037000b41c4d1c3004133200441d0016a419cd9c3001038000b2006200441b0016a41106a2802003602002008200441b0016a41086a290300370300200420042903b0013703e0014100211e0b2004201e360248200441003602e80120042903582112200420042903f801222137035820042903502122200420042903f001222337035020042903402124200420042903e001221137034020042903482110200420042903e80122253703482025a72107024002402010a7221d0d002025211020232122202121120c010b200420243703e001200420103703e801200420223703f001200420123703f8012004201d2022a74105746a3602bc012004201d3602b80120042010422088a73602b4012004201d3602b0012004200441106a3602c00120044190016a200441b0016a108401200e41086a201a280200360200200e20042903900137020020042022422088a7221d2012422088a74105746a3602bc012004201d3602b80120042012a73602b4012004201d3602b0012004200441106a3602c00120044190016a200441b0016a108401200d41086a201a280200360200200d20042903900137020020042903e801211020042903e001211120042903f801211220042903f001212202402007450d002021a7211d02402025422088a7450d002007102a0b201d450d002023422088a7102a0b200420113703402004201037034820042022370350200420123703582010a721070b2004201137036020042010370368200420223703702004201237037802400240024020070d00200441b0016a41186a2013290300370300200441b0016a41106a2014290300370300200441b0016a41086a2015290300370300200420042903203703b001411a10282207450d0220072016370000200741186a20173b0000200741106a2018370000200741086a20193700002004429a808080a0033702d401200420073602d0012004200441d0016a3602e001200441b0016a200441e0016a10c80120042802d001210720042802d801211d200142003703002006420037030020084200370300200442003703e0012007201d200441e0016a1000201b2001290300370300201c2006290300370300201a2008290300370300200420042903e00137039001024020042802d401450d0020042802d001102a0b20044190016a412010090c010b200441b0016a41186a2013290300370300200441b0016a41106a2014290300370300200441b0016a41086a2015290300370300200420042903203703b001411a10282207450d0320072016370000200741186a20173b0000200741106a2018370000200741086a20193700002004429a808080a0033702d401200420073602d0012004200441d0016a3602e001200441b0016a200441e0016a10c80120042802d001210720042802d801211d200142003703002006420037030020084200370300200442003703e0012007201d200441e0016a1000201b2001290300370300201c2006290300370300201a2008290300370300200420042903e00137039001024020042802d401450d0020042802d001102a0b200441203602e401200420044190016a3602e001200441e0006a200441e0016a10b4030b02402010a72206450d002012a7210802402010422088a7450d002006102a0b2008450d002022422088a7102a0b200041206a2100200b41606a220b0d010c060b0b411a41011037000b411a41011037000b41c4d1c3004133200441d0016a419cd9c3001038000b200641011037000b1036000b02402009a7450d00200a102a0b200441003602e801200442013703e0012003200441e0016a10b40102402003450d002003410574210003402002200441e0016a108f01200241206a2102200041606a22000d000b0b20042802e401210620042802e801210820042802e0012100200441b0016a41086a22014200370300200442003703b0014196f0c200411b200441b0016a1008200441e0016a41086a2001290300370300200420042903b0013703e001200441e0016a411020002008100702402006450d002000102a0b02402004280214450d002004280210102a0b200524000bb80901177f230041206b220424002002410020031b21052000410020011b2106200241206a200220031b2107200041206a200020011b2108200020014105746a2109200220034105746a210a4100210b4100210c4101210d4100210e4100210f41012110024002400340200b4101742111200b4105742112024002400240024002400340024020050d0020072113200d2114200c2115200b21160c040b2005210220072103200d2114200c2115200b2116201221172011211802400340024002402006450d0020022006460d06200220064120109c052213450d062013417f4c0d01200321072014210d2015210c2016210b200221050c080b200441186a2203200541186a290000370300200441106a2216200541106a290000370300200441086a2206200541086a290000370300200420052900003703000240200b200c470d00200b41016a2202200b490d0c200b41017422172002201720024b1b220c41ffffff3f71200c470d0c200c41057422024100480d0c02400240200b0d0020021028210d0c010b200d200b4105742002102c210d0b200d450d030b200d200b4105746a22022004290300370000200241186a2003290300370000200241106a2016290300370000200241086a200629030037000041002106410020072007200a4622021b2105201141026a2111201241206a2112200b41016a210b2007200741206a20021b21070c030b200441186a2213200241186a290000370300200441106a2219200241106a290000370300200441086a221a200241086a29000037030020042002290000370300024020162015470d00201641016a22022016490d0b20182002201820024b1b221541ffffff3f712015470d0b201541057422024100480d0b0240024020160d002002102821140c010b201420172002102c21140b2014450d040b201420176a22022004290300370000200241186a2013290300370000200241106a2019290300370000200241086a201a290300370000410020032003200a4622131b2102201841026a2118201741206a2117201641016a21162003200341206a20131b221321032002450d050c000b0b0b200241011037000b200241011037000b2014210d2015210c2016210b2003200341206a2003200a4622021b210741002008200820094622161b21064100200320021b21052008200841206a20161b21080c030b410021052006450d01201321072014210d2015210c2016210b0b200441186a2203200641186a290000370300200441106a2216200641106a290000370300200441086a2217200641086a290000370300200420062900003703000240200e200f470d00200e41016a2202200e490d04200e41017422062002200620024b1b220f41ffffff3f71200f470d04200f41057422024100480d0402400240200e0d002002102821100c010b2010200e4105742002102c21100b2010450d030b2010200e4105746a22022004290300370000200241186a2003290300370000200241106a2016290300370000200241086a201729030037000041002008200820094622021b2106200e41016a210e2008200841206a20021b21080c010b0b201420162000200110840202402015450d002014102a0b0240200f450d002010102a0b200441206a24000f0b200241011037000b1031000ba8ca0106017f027e057f017e217f0b7e230041e0046b22032400024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024020012802000e0b000102030405060c0d0e0f000b20034184036a4101360200200342013702f402200341ccd1c5003602f002200341043602b404200341c4d1c5003602b0042003200341b0046a36028003200341f0026a41a0f8c100103e000b200141206a2903002104200141186a29030021052001410c6a2802002106200141086a2802002107200141146a2802002108200141106a28020021092001280204210a2002411a6a290100210b200241196a2d0000210c200241186a2d0000210d200241166a2f0100210e200241156a2d0000210f200241146a2d00002110200241126a2f01002111200241116a2d00002112200241106a2d000021132002410e6a2f010021142002410d6a2d000021152002410c6a2d000021162002410a6a2f01002117200241096a2d0000211841042119200241046a2d0000211a200241026a2f0100211b0240024020022d00000d0020022d00014101470d00200241056a2d00002119200241066a2f0100211c200241086a2d000021024100211d0c010b4101211d410021024100211c0b2003200b370380012003200c3a007f2003200d3a007e2003200e3b017c2003200f3a007b200320103a007a200320113b0178200320123a0077200320133a0076200320143b0174200320153a0073200320163a0072200320173b0170200320183a006f2003201a3a006a2003201b3b01682003201c41ffff0371410874200241187472201941ff017172221c36006b201d450d0e410f210241ea9fc60021190240024002400240024002400240201c0e0700010203040506000b200328006f2119200328007321020c050b410e210241dc9fc60021190c040b410c210241d09fc60021190c030b4109210241c79fc60021190c020b4113210241b49fc60021190c010b4111210241a39fc60021190b4100210c4101211d2007450d43200a102a0c430b200141206a2903002104200141186a29030021052001410c6a2802002106200141086a280200211b200141146a2802002108200141106a28020021092001280204210a2002411a6a290100210b200241196a2d0000210c200241186a2d00002107200241166a2f0100210d200241156a2d0000210e200241146a2d0000210f200241126a2f01002110200241116a2d00002111200241106a2d000021122002410e6a2f010021132002410d6a2d000021142002410c6a2d000021152002410a6a2f01002116200241096a2d0000211741042119200241046a2d00002118200241026a2f0100211a0240024020022d00000d0020022d00014101470d00200241056a2d00002119200241066a2f0100211c200241086a2d000021024100211d0c010b4101211d410021024100211c0b2003200b3703e8022003200c3a00e702200320073a00e6022003200d3b01e4022003200e3a00e3022003200f3a00e202200320103b01e002200320113a00df02200320123a00de02200320133b01dc02200320143a00db02200320153a00da02200320163b01d802200320173a00d702200320183a00d2022003201a3b01d0022003201c41ffff0371410874200241187472201941ff017172221c3600d3020240201d450d00410f210241ea9fc6002119024002400240024002400240201c0e0700010203040548000b20032800d702211920032800db0221020c470b410e210241dc9fc60021190c460b410c210241d09fc60021190c450b4109210241c79fc60021190c440b4113210241b49fc60021190c430b4111210241a39fc60021190c420b20034188046a41186a200341d0026a41186a29030037030020034188046a41106a200341d0026a41106a29030037030020034188046a41086a200341d0026a41086a290300370300200320032903d00237038804410d10282202450d0e200241002900b0f841370000200241056a41002900b5f8413700002003428d808080d0013702f402200320023602f00220034188046a200341f0026a108f0120032802f802210220032802f0022119200341b0046a41186a221c4200370300200341b0046a41106a221d4200370300200341b0046a41086a220c4200370300200342003703b00420192002200341b0046a1000200341e8006a41186a201c290300370300200341e8006a41106a201d290300370300200341e8006a41086a200c290300370300200320032903b004370368024020032802f402450d0020032802f002102a0b200341003602f002200341e8006a4120200341f0026a1006211c20032802f002221d417f460d3f201c450d3f41002102200341003a009003024002400340201d2002460d01200341f0026a20026a201c20026a2d00003a00002003200241016a22193a0090032019210220194120470d000b200341b0046a41186a2202200341f0026a41186a290300370300200341b0046a41106a200341f0026a41106a290300370300200341b0046a41086a200341f0026a41086a290300370300200320032903f0023703b004201941ff0171411f4d0d01200341e0036a41086a2219200341c3046a290000370300200341e0036a410d6a220c2002290000370000200341e8016a41026a220720032d00b2043a0000200341a8026a41086a2019290300370300200341a8026a410d6a220d200c290000370000200320032f01b0043b01e801200320032900bb043703a80220032800b304211920032800b70421020240201d450d00201c102a0b200341b0046a41026a20072d00003a0000200341f0026a41086a200341a8026a41086a290300370300200341f0026a410d6a200d290000370000200320032f01e8013b01b004200320032903a8023703f0024101211c0c420b200241ff0171450d00200341003a0090030b41c4d1c3004133200341d8046a419cd9c3001038000b200141216a290000210b200141206a2d000021072001411d6a2f0000210d2001411c6a2d0000210e200141196a2f0000210f200141186a2d00002110200141156a2f00002111200141146a2d00002112200141116a2f00002113200141106a2d000021142001410c6a280200211c200141086a2d0000211e200141306a280200211f2001412c6a280200212020012d001f211520012d001b211620012d0017211720012d0013211820012d000b211a20012f0009211b200128020421212002411a6a2901002104200241196a2d00002122200241186a2d00002123200241166a2f01002124200241156a2d00002125200241146a2d00002126200241126a2f01002127200241116a2d00002128200241106a2d0000210a2002410e6a2f010021062002410d6a2d000021082002410c6a2d000021092002410a6a2f01002129200241096a2d0000212a41042119200241046a2d0000212b200241026a2f0100212c0240024020022d00000d0020022d00014101470d00200241056a2d00002119200241066a2f0100211d200241086a2d000021024100210c0c010b4101210c410021024100211d0b201d41ffff0371410874200241187472201941ff017172211d0240200c450d00410f210241ea9fc60021190240201d0e0700050607083e3f000b2029410874202a7220094118747221192006410874200872200a4118747221020c3e0b200320043703a002200320223a009f02200320233a009e02200320243b019c02200320253a009b02200320263a009a02200320273b019802200320283a0097022003200a3a009602200320063b019402200320083a009302200320093a009202200320293b0190022003202a3a008f022003201d36008b022003202b3a008a022003202c3b0188020240201e41ff01714101470d00200341f0026a201c41067610fe0120032802f00221190240024020032802f802201c413f7122024b0d00410021020c010b201920024105746a2202290018210b20022d0017210720022d0016211520022f0014210d20022d0013210e20022d0012211620022f0010210f20022d000f211020022d000e211720022f000c211120022d000b211220022d000a211820022f0008211320022d000721142002280003211c20022d0002211a20022f0000211b410121020b024020032802f402450d002019102a0b2002450d3c0b2003200b3703c002200320073a00bf02200320153a00be022003200d3b01bc022003200e3a00bb02200320163a00ba022003200f3b01b802200320103a00b702200320173a00b602200320113b01b402200320123a00b302200320183a00b202200320133b01b002200320143a00af022003201c3600ab022003201a3a00aa022003201b3b01a802200341b0046a41086a22024200370300200342003703b00441b8a2c1004114200341b0046a1008200341e8006a41086a2002290300370300200320032903b0043703680240200341e8006a41104101410041001003417f460d0041bdf8c1002119412621020c3e0b411310282202450d0e200241002900c2a3413700002002410f6a41002800d1a341360000200241086a41002900caa34137000020034293808080b0023702f402200320023602f00220034188026a200341f0026a108f0120032802f802210220032802f0022119200341b0046a41186a221c4200370300200341b0046a41106a221d4200370300200341b0046a41086a220c4200370300200342003703b00420192002200341b0046a1000200341d0026a41186a201c290300370300200341d0026a41106a201d290300370300200341d0026a41086a200c290300370300200320032903b0043703d002024020032802f402450d0020032802f002102a0b200341003602f002200341d0026a4120200341f0026a1006210220032802f0022219417f460d102002450d10200320193602b404200320023602b004200341f0026a200341b0046a10c20220032903f0024201510d0f02402019450d002002102a0b411310282202450d11200241002900c2a3413700002002410f6a41002800d1a341360000200241086a41002900caa34137000020034293808080b0023702f402200320023602f002200341a8026a200341f0026a108f0120032802f802210220032802f0022119200341b0046a41186a221c4200370300200341b0046a41106a221d4200370300200341b0046a41086a220c4200370300200342003703b00420192002200341b0046a1000200341d0026a41186a201c290300370300200341d0026a41106a201d290300370300200341d0026a41086a200c290300370300200320032903b0043703d002024020032802f402450d0020032802f002102a0b200341003602f002200341d0026a4120200341f0026a1006210220032802f0022219417f460d132002450d13200320193602b404200320023602b004200341f0026a200341b0046a10c20220032903f0024201510d1220034198036a280200211002402019450d002002102a0b200341b0046a41086a22024200370300200342003703b004418891c6004111200341b0046a1008200341e8006a41086a2002290300370300200320032903b00437036841002119200341003602f002200341e8006a4110200341f0026a10062102024020032802f002221c417f460d002002450d00201c4104490d15200228000021192002102a0b02402019201f460d0041e3f8c1002119411621020c3e0b0240201041016a201f490d0041f9f8c1002119411f21020c3e0b410e10282202450d15200241066a41002900b2a441370000200241002900aca4413700002002410e411c102c2202450d162002202141067636000e200341b0046a41186a22194200370300200341b0046a41106a221c4200370300200341b0046a41086a221d4200370300200342003703b00420024112200341b0046a1000200341d0026a41186a2019290300370300200341d0026a41106a201c290300370300200341d0026a41086a201d290300370300200320032903b0043703d0022002102a200341003602f002200341d0026a4120200341f0026a1006210220032802f0022219417f460d342002450d34200320193602b404200320023602b004200341f0026a200341b0046a107420032802f002220c450d172021413f71211c20032902f402210b02402019450d002002102a0b4100211d201c200b422088a74f0d32200c201c41216c6a22192d00004101470d32200341a6016a201941036a2d00003a000020034188016a41086a201941146a29000037030020034195016a201941196a290000370000200320192f00013b01a40120032019410c6a29000037038801201941086a2800002102201941046a28000021194101211d0c330b2001280204211b2002411a6a290100210b200241196a2d0000210c200241186a2d00002107200241166a2f0100210d200241156a2d0000210e200241146a2d0000210f200241126a2f01002110200241116a2d00002111200241106a2d000021122002410e6a2f010021132002410d6a2d000021142002410c6a2d000021152002410a6a2f01002116200241096a2d0000211741042119200241046a2d00002118200241026a2f0100211a0240024020022d00000d0020022d00014101470d00200241056a2d00002119200241066a2f0100211c200241086a2d000021024100211d0c010b4101211d410021024100211c0b2003200b3703e8022003200c3a00e702200320073a00e6022003200d3b01e4022003200e3a00e3022003200f3a00e202200320103b01e002200320113a00df02200320123a00de02200320133b01dc02200320143a00db02200320153a00da02200320163b01d802200320173a00d702200320183a00d2022003201a3b01d0022003201c41ffff0371410874200241187472201941ff017172221c3600d3020240201d450d00410f210241ea9fc60021190240201c0e0700040506073d3e000b20032800d702211920032800db0221020c3d0b20034188046a41186a200341d0026a41186a29030037030020034188046a41106a200341d0026a41106a29030037030020034188046a41086a200341d0026a41086a290300370300200320032903d00237038804200341b0046a41086a22024200370300200342003703b00441b8a2c1004114200341b0046a1008200341e8006a41086a2002290300370300200320032903b0043703680240200341e8006a41104101410041001003417f460d0041d9fac1002119411e21020c3d0b411310282202450d17200241002900c2a3413700002002410f6a41002800d1a341360000200241086a41002900caa34137000020034293808080b0023702f402200320023602f00220034188046a200341f0026a108f0120032802f802211920032802f002211c41182102200341b0046a41186a221d4200370300200341b0046a41106a220c4200370300200341b0046a41086a22074200370300200342003703b004201c2019200341b0046a1000200341d0026a41186a201d290300370300200341d0026a41106a200c290300370300200341d0026a41086a2007290300370300200320032903b0043703d002024020032802f402450d0020032802f002102a0b0240200341d0026a41204101410041001003417f470d0041f7fac10021190c3d0b410e10282202450d18200241066a41002900b2a441370000200241002900aca4413700002002410e411c102c2219450d192019201b41067636000e41182102200341b0046a41186a221c4200370300200341b0046a41106a221d4200370300200341b0046a41086a220c4200370300200342003703b00420194112200341b0046a1000200341e8006a41186a201c290300370300200341e8006a41106a201d290300370300200341e8006a41086a200c290300370300200320032903b0043703682019102a200341003602b004200341e8006a4120200341b0046a1006211c20032802b0042219417f460d1b200320193602e4032003201c3602e003200341b0046a200341e0036a107420032802b004221d450d1a201b413f71210220032902b404210b02402019450d00201c102a0b4100211c2002200b422088a74f0d2e201d200241216c6a22192d00004101470d2e20034186026a201941036a2d00003a0000200341e8016a41086a201941146a290000370300200341f5016a201941196a290000370000200320192f00013b01840220032019410c6a2900003703e801201941086a2800002102201941046a28000021194101211c0c2f0b2001280204210c2002411a6a290100210b200241196a2d00002112200241186a2d00002113200241166a2f01002114200241156a2d00002115200241146a2d00002116200241126a2f01002117200241116a2d00002118200241106a2d000021072002410e6a2f0100210d2002410d6a2d0000210e2002410c6a2d0000210f2002410a6a2f01002110200241096a2d0000211141042119200241046a2d0000211a200241026a2f0100211b0240024020022d00000d0020022d00014101470d00200241056a2d00002119200241066a2f0100211c200241086a2d000021024100211d0c010b4101211d4100211c410021020b201c41ffff0371410874201941ff017172200241187472211c0240201d450d00410f210241ea9fc60021190240201c0e0700030405063c3d000b2010410874201172200f411874722119200d410874200e7220074118747221020c3c0b2003200b3703a004200320123a009f04200320133a009e04200320143b019c04200320153a009b04200320163a009a04200320173b019804200320183a009704200320073a0096042003200d3b0194042003200e3a0093042003200f3a009204200320103b019004200320113a008f042003201c36008b042003201a3a008a042003201b3b018804411610282202450d1b20024100290093a2413700002002410e6a41002900a1a241370000200241086a410029009ba24137000020034296808080e0023702f402200320023602f00220034188046a200341f0026a108f0120032802f802210220032802f0022119200341b0046a41186a221c4200370300200341b0046a41106a221d4200370300200341b0046a41086a22074200370300200342003703b00420192002200341b0046a1000200341e8006a41186a201c290300370300200341e8006a41106a201d290300370300200341e8006a41086a2007290300370300200320032903b004370368024020032802f402450d0020032802f002102a0b4101211d0240200341e8006a41204101410041001003417f460d00418ffbc1002119411e21024101210c0c400b200341b0046a41086a22024200370300200342003703b00441bf91c6004116200341b0046a1008200341e8006a41086a2002290300370300200320032903b0043703684100211c200341003602f002200341e8006a4110200341f0026a10062102024020032802f0022219417f460d002002450d0020194104490d1d2002280000211c2002102a0b200341b0046a41086a22024200370300200342003703b00441b0a3c1004112200341b0046a1008200341e8006a41086a2002290300370300200320032903b004370368200341003602f002200341e8006a4110200341f0026a100621020240024020032802f0022219417f460d002002450d00200320193602b404200320023602b004200341f0026a200341b0046a106d20032802f0022207450d1f20032902f402210b02402019450d002002102a0b200b422088a7210d0c010b4100210d4200210b410121070b0240024002400240201c200c470d00200d200c460d010b41adfbc100211941162102200d200c4d0d01200c200b422088a7220d4f0d2120034188036a420037030020034180036a4200370300200341f8026a4200370300200342003703f0022007200c4105746a220d200341f0026a460d00200d200341f0026a4120109c050d010b200341306a20034188046a4280809aa6eaafe30142001083022003280230450d0141c3fbc1002119411e21020b0240200ba7450d002007102a0b4101210c0c400b200341b0046a41086a22024200370300200342003703b004418891c6004111200341b0046a1008200341e8006a41086a2002290300370300200320032903b00437036841002119200341003602f002200341e8006a4110200341f0026a10062102024020032802f002221d417f460d002002450d00201d4104490d20200228000021192002102a0b411610282202450d2020024100290093a2413700002002410e6a41002900a1a241370000200241086a410029009ba24137000020034296808080e0023702f402200320023602f00220034188046a200341f0026a108f0120032802f802210220032802f002211d200341b0046a41186a220d4200370300200341b0046a41106a220e4200370300200341b0046a41086a220f4200370300200342003703b004201d2002200341b0046a1000200341e8006a41186a200d290300370300200341e8006a41106a200e290300370300200341e8006a41086a200f290300370300200320032903b004370368024020032802f402450d0020032802f002102a0b410810282202450d212002200c36000420022019360000200341e8006a41202002410810072002102a200ba7211d02400240200c200b422088a72202460d00200341d0026a41186a220d20034188046a41186a290300370300200341d0026a41106a220e20034188046a41106a290300370300200341d0026a41086a20034188046a41086a29030037030020032003290388043703d002200c20024f0d242007200c4105746a221920032903d002370000201941186a200d290300370000201941106a200e290300370000201941086a200341d0026a41086a2903003700000c010b200341d0026a41186a221920034188046a41186a290300370300200341d0026a41106a220d20034188046a41106a290300370300200341d0026a41086a20034188046a41086a29030037030020032003290388043703d0020240200c201d470d00200c41016a2202200c490d38200c410174221d2002201d20024b1b221d41ffffff3f71201d470d38201d41057422024100480d3802400240200c0d002002102821070c010b2007200c4105742002102c21070b2007450d25200b422088a7210c0b2007200c4105746a220220032903d002370000200241186a2019290300370000200241106a200d290300370000200241086a200341d0026a41086a290300370000200c41016a21020b200341b0046a41086a22194200370300200342003703b00441b0a3c1004112200341b0046a1008200341e8006a41086a2019290300370300200320032903b004370368200341003602f802200342013703f0022002200341f0026a10b40102402002450d00200241057421192007210203402002200341f0026a108f01200241206a2102201941606a22190d000b0b20032802f4022102200341e8006a411020032802f002221920032802f802100702402002450d002019102a0b0240201d450d002007102a0b200341b0046a41086a22024200370300200342003703b00441bf91c6004116200341b0046a1008200341e8006a41086a2002290300370300200320032903b0043703684101211d2003201c41016a3602f002200341e8006a4110200341f0026a41041007410021194101210c0c3f0b200141386a2903002104200141306a29030021052001411d6a290000210b2001411c6a2d00002112200141196a2f00002113200141186a2d00002114200141156a2f00002115200141146a2d00002116200141116a2f00002117200141106a2d000021182001410d6a2f0000211a2001410c6a2d0000211b200141086a280200210c200141286a280200211f20012d001b210a20012d0017210620012d0013210820012d000f210920012d0007212920012f0005212a20012d0004212c2002411a6a290100212d200241196a2d0000211e200241186a2d00002122200241166a2f01002123200241156a2d00002124200241146a2d00002125200241126a2f01002126200241116a2d00002127200241106a2d000021072002410e6a2f0100210d2002410d6a2d0000210e2002410c6a2d0000210f2002410a6a2f01002110200241096a2d0000211141042119200241046a2d00002128200241026a2f0100212b0240024020022d00000d0020022d00014101470d00200241056a2d00002119200241066a2f0100211c200241086a2d000021024100211d0c010b4101211d4100211c410021020b201c41ffff0371410874201941ff017172200241187472211c201d450d04410f210241ea9fc60021190240201c0e0700010203043a3b000b2010410874201172200f411874722119200d410874200e7220074118747221020c3a0b410e210241dc9fc60021190c390b410c210241d09fc60021190c380b4109210241c79fc60021190c370b4113210241b49fc60021190c360b2003202d3703f8032003201e3a00f703200320223a00f603200320233b01f403200320243a00f303200320253a00f203200320263b01f003200320273a00ef03200320073a00ee032003200d3b01ec032003200e3a00eb032003200f3a00ea03200320103b01e803200320113a00e7032003201c3600e303200320283a00e2032003202b3b01e0030240200520048450450d00419ffcc100211941d00021020c360b02400240202c41ff01714101470d00200341f0026a200c41067610fe0120032802f00221190240024020032802f802200c413f7122024b0d00410021020c010b201920024105746a2202290018210b20022d0017211220022d0016210a20022f0014211320022d0013211420022d0012210620022f0010211520022d000f211620022d000e210820022f000c211720022d000b211820022d000a210920022f0008211a20022d0007211b2002280003210c20022d0002212920022f0000212a410121020b024020032802f402450d002019102a0b20020d00410121020c010b410021020b2003200b3701e802200320123a00e7022003200a3a00e602200320133b01e402200320143a00e302200320063a00e202200320153b01e002200320163a00df02200320083a00de02200320173b01dc02200320183a00db02200320093a00da022003201a3b01d8022003201b3a00d7022003200c3600d302200320293a00d2022003202a3b01d00220020d3320034188046a41186a200341d0026a41186a29010037030020034188046a41106a200341d0026a41106a29010037030020034188046a41086a200341d0026a41086a290100370300200320032901d00237038804200341b0046a41086a22024200370300200342003703b004418891c6004111200341b0046a1008200341e8006a41086a2002290300370300200320032903b00437036841002119200341003602f002200341e8006a4110200341f0026a10062102024020032802f002221c417f460d002002450d00201c4104490d1f200228000021192002102a0b02402019201f460d00418efcc1002119411121020c360b200341b0046a41086a22024200370300200342003703b00441b8a2c1004114200341b0046a1008200341e8006a41086a22192002290300370300200320032903b004370368200341f0026a200341e8006a10be02024020032802f802220d0d0041e1fbc1002119412d21020c360b20032902fc02212e20024200370300200342003703b00441ad91c6004112200341b0046a100820192002290300370300200320032903b00437036841002119200341003602f002200341e8006a4110200341f0026a10062102024020032802f002221c417f460d002002450d00201c4104490d20200228000021192002102a0b200341d8006a2019ad42004280a094a58d1d4200109f05200341d8006a41086a290300210b411410282202450d202003290358212f200241002900cfe140370000200241106a41002800dfe140360000200241086a41002900d7e14037000020034294808080c0023702d402200320023602d002200341e0036a200341d0026a108f0120032802d802210220032802d0022119200341b0046a41186a221c4200370300200341b0046a41106a221d4200370300200341b0046a41086a220c4200370300200342003703b00420192002200341b0046a1000200341f0026a41186a201c290300370300200341f0026a41106a201d290300370300200341f0026a41086a200c290300370300200320032903b0043703f002024020032802d402450d0020032802d002102a0b200341003602b004200341f0026a4120200341b0046a1006210220032802b0042219417f460d252002450d2520194110490d21200241086a290000212d200229000021302002102a0c260b4101211d20022d000120022d0000720d2320012802042102200341b0046a41086a22194200370300200342003703b00441f490c6004114200341b0046a1008200341e8006a41086a2019290300370300200320032903b004370368200320023602f002200341e8006a4110200341f0026a41041007410021194101210c0c380b024020022d000120022d000072450d0041a39fc6002119411121020c340b200141086a2802002119024020012d00044101460d00200141106a2d0000211c200141146a2d0000211d200141186a2d0000210c2001411c6a2d0000210720012f0005210220012d0007210d20012d000c210e20012f000d210f20012d000f211020012f0011211120012d0013211220012f0015211320012d0017211420012f0019211520012d001b2116200129001d210b0c210b200341f0026a201941067610fe0120032802f00221170240024020032802f8022019413f7122024b0d00410021180c010b201720024105746a2202290018210b20022d0017210720022d0016211620022f0014211520022d0013210c20022d0012211420022f0010211320022d000f211d20022d000e211220022f000c211120022d000b211c20022d000a211020022f0008210f20022d0007210e2002280003211920022d0002210d20022f00002102410121180b024020032802f402450d002017102a0b20180d20410121170c210b4101211d20022d000120022d0000720d2120012802042102200341b0046a41086a22194200370300200342003703b00441f0a2c100411c200341b0046a1008200341e8006a41086a2019290300370300200320032903b004370368200320023602f002200341e8006a4110200341f0026a41041007410021194101210c0c360b4101211d20022d000120022d0000720d2020012802042102200341b0046a41086a22194200370300200342003703b00441dca2c1004114200341b0046a1008200341e8006a41086a2019290300370300200320032903b004370368200320023602f002200341e8006a4110200341f0026a41041007410021194101210c0c350b200341d0026a41186a200341e8006a41186a290300220b370300200341d0026a41106a200341e8006a41106a290300222d370300200341d0026a41086a200341e8006a41086a290300222e37030020032003290368222f3703d002200341f0026a41186a200b370300200341f0026a41106a202d370300200341f0026a41086a202e3703002003202f3703f002200320063602b804200320073602b4042003200a3602b0042003200341f0026a200341b0046a200920082005200410d40220032802042102200328020021194100210c4101211d0c340b410d41011037000b411341011037000b41c4d1c3004133200341d8046a419cd9c3001038000b41c4f9c1002119411821020c2c0b411341011037000b41c4d1c3004133200341d8046a419cd9c3001038000b4198f9c1002119412c21020c290b41c4d1c3004133200341d8046a419cd9c3001038000b410e41011037000b411c41011037000b41c4d1c3004133200341d8046a419cd9c3001038000b411341011037000b410e41011037000b411c41011037000b41c4d1c3004133200341d8046a419cd9c3001038000b4101211c41a8fac10021190c140b411641011037000b41c4d1c3004133200341d8046a419cd9c3001038000b41c4d1c3004133200341d8046a419cd9c3001038000b41cca2c100200c200d1034000b41c4d1c3004133200341d8046a419cd9c3001038000b411641011037000b410841011037000b41a0a3c100200c20021034000b200241011037000b41c4d1c3004133200341d8046a419cd9c3001038000b41c4d1c3004133200341d8046a419cd9c3001038000b411441011037000b41c4d1c3004133200341d8046a419cd9c3001038000b410021170b2003200b37018001200320073a007f200320163a007e200320153b017c2003200c3a007b200320143a007a200320133b01782003201d3a0077200320123a0076200320113b01742003201c3a0073200320103a00722003200f3b01702003200e3a006f2003201936006b2003200d3a006a200320023b016820170d0f200341d0026a41186a200341e8006a41186a290100370300200341d0026a41106a200341e8006a41106a290100370300200341d0026a41086a200341e8006a41086a2202290100370300200320032901683703d002200341b0046a41086a22194200370300200342003703b00441a9a2c100410f200341b0046a100820022019290300370300200320032903b004370368200341003602f002200341e8006a4110200341f0026a10062102024002400240024002400240024020032802f0022219417f460d002002450d00200320193602b404200320023602b004200341f0026a200341b0046a107d20032802f002221c450d0220032902f402210b2019450d012002102a0c010b4200210b4104211c0b200ba72111024002400240200b422088a72207450d00201c200741246c221d6a210c410021190340200341f0026a41206a201c20196a220241206a280200360200200341f0026a41186a200241186a290200370300200341f0026a41106a200241106a290200370300200341f0026a41086a200241086a290200370300200320022902003703f002200341f0026a200341d0026a4120109c050d02201d201941246a2219470d000b0b4104210f4100210d024020110d00410021100c020b201c102a410021100c010b20034188046a41086a200341f0026a41086a290300220b370300200341e0036a41086a221d200b370300200341e0036a41106a220d200341f0026a41106a290300370300200341e0036a41186a220e200341f0026a41186a290300370300200341e0036a41206a2210200341f0026a41206a280200360200200320032903f002220b370388042003200b3703e00341241028220f450d02200f20032903e003370200200f41206a2010280200360200200f41186a200e290300370200200f41106a200d290300370200200f41086a201d29030037020002400240200741246c415c6a2019470d004101210d410121100c010b200241246a2113200c415c6a21144101210d4101211003402013210202400340200341f0026a41206a2219200241206a280200360200200341f0026a41186a221d200241186a290200370300200341f0026a41106a2207200241106a290200370300200341f0026a41086a220e200241086a290200370300200320022902003703f002200341f0026a200341d0026a4120109c050d01200c200241246a2202470d000c030b0b200341b0046a41206a2019280200221236020020034188046a41086a200e290300220b37030020034188046a41106a2007290300220437030020034188046a41186a201d290300220537030020034188046a41206a2012360200200320032903f002222d3703880420192012360200201d200537030020072004370300200e200b3703002003202d3703f00202402010200d470d00200d41016a2210200d490d15200d41017422122010201220104b1b2210ad42247e220b422088a70d15200ba722124100480d1502400240200d0d0020121028210f0c010b200f200d41246c2012102c210f0b200f450d060b200241246a2113200f200d41246c6a221220032903f002370200201241206a2019280200360200201241186a201d290300370200201241106a2007290300370200201241086a200e290300370200200d41016a210d20142002470d000b0b2011450d00201c102a0b200341b0046a41086a22024200370300200342003703b00441a9a2c100410f200341b0046a1008200341e8006a41086a2002290300370300200320032903b004370368200341003602f802200342013703f002200d200341f0026a10b4010240200d450d00200f200d41246c6a2107200f211903402019200341f0026a108f01201941206a280200211d0240024020032802f402221c20032802f80222026b4104490d0020032802f002211c0c010b200241046a220c2002490d14201c4101742202200c2002200c4b1b22024100480d1402400240201c0d0020021028211c0c010b20032802f002201c2002102c211c0b201c450d06200320023602f4022003201c3602f00220032802f80221020b2003200241046a3602f802201c20026a201d3600002007201941246a2219470d000b0b20032802f4022102200341e8006a411020032802f002221920032802f802100702402002450d002019102a0b200d41246c220241246d210c4100211c0240024020020d00410121074100210c0c010b200c41ffffff3f71200c470d12200c41057422024100480d12200210282207450d050b0240200d450d00200d41246c211d4100211c20072102200f21190340201941086a290000210b201941106a290000210420192900002105200241186a201941186a290000370000200241106a2004370000200241086a200b37000020022005370000201c41016a211c200241206a2102201941246a2119201d415c6a221d0d000b0b02402010450d00200f102a0b200341f0026a41186a200341d0026a41186a290300370300200341f0026a41106a200341d0026a41106a290300370300200341f0026a41086a200341d0026a41086a290300370300200320032903d0023703f002410021192007201c41004120201c676b10c4024101211d200341f0026a41012007201c10c5020240200c450d002007102a0b4101210c0c1a0b41c4d1c3004133200341d8046a419cd9c3001038000b412441041037000b201241041037000b200241011037000b200241011037000b41a39fc6002119411121024101210c0c140b420021304200212d0b024002402030202f54202d200b54202d200b511b450d0041a0fdc1002119412e21020c010b200341b0046a41086a22024200370300200342003703b004418ca3c1004113200341b0046a1008200341e8006a41086a2002290300370300200320032903b004370368200341003602f002200341e8006a4110200341f0026a1006210202400240024002400240024002400240024020032802f0022219417f460d002002450d00200320193602b404200320023602b004200341f0026a200341b0046a107820032802f0022210450d0320032902f402212d02402019450d002002102a0b202d422088a72217450d05202da7211441f1fdc1002119412321022010290300200554201041086a290300223020045420302004511b450d07200341b0046a41086a22194200370300200342003703b00441a9a2c100410f200341b0046a1008200341e8006a41086a2019290300370300200320032903b004370368200341003602f002200341e8006a4110200341f0026a1006211920032802f002221c417f460d012019450d012003201c3602b404200320193602b004200341f0026a200341b0046a107d20032802f0022207450d0420032902f4022130201c450d022019102a0c020b41effcc1002119413121020c080b42002130410421070b20072030422088a7220e41246c6a210c200721194100211c024003400240200c20196b41ec004b0d00200c2019460d062007200e41246c6a210c034020034188046a2019460d03201c201920034188046a4120109c05221d4100476a211c201d450d03200c201941246a2219470d000c070b0b201920034188046a460d01201c201920034188046a4120109c05221d4100476a211c201d450d01201941246a221d20034188046a460d01201c201d20034188046a4120109c05221d4100476a211c201d450d01201941c8006a221d20034188046a460d01201c201d20034188046a4120109c05221d4100476a211c201d450d01201941ec006a221d20034188046a460d0120194190016a2119201c201d20034188046a4120109c05221d4100476a211c201d0d000b0b201c202e422088a7490d034194fec1002119413621022030a7450d042007102a0c040b41c4d1c3004133200341d8046a419cd9c3001038000b41c4d1c3004133200341d8046a419cd9c3001038000b41cca2c100410041001034000b02402030a7450d002007102a0b200341a8026a10c002200341f0026a20034188046a10bf0220032802f0024101460d01024020032802ac02450d0020032802a802102a0b41cefdc10021190b2014450d012010102a0c010b20032802a80221260240024002400240024002400240024002400240024020032802b00222020d0042002131420021320c010b20032802f4022111200241216c211c202641016a2102200341f8026a2802002219410876211241012019411f7174211520194105764107712213417f7321164200213142002132034002402002417f6a2d00004101470d00411310282219450d06201941002900c2a3413700002019410f6a41002800d1a341360000201941086a41002900caa34137000020034293808080b0023702f402200320193602f0022002200341f0026a108f0120032802f802211d20032802f002210c200341b0046a41186a22074200370300200341b0046a41106a220e4200370300200341b0046a41086a22194200370300200342003703b004200c201d200341b0046a1000200341e8006a41186a2007290300370300200341e8006a41106a200e290300370300200341e8006a41086a22072019290300370300200320032903b004370368024020032802f402450d0020032802f002102a0b200341003602f002200341e8006a4120200341f0026a1006210c20032802f002221d417f460d002003201d3602b4042003200c3602b004200341f0026a200341b0046a10c20220032903f0024201510d05200341f0026a41206a2903002133200341f0026a41106a220f2903002134200329038803213520032903f8022136200328029803210e0240201d450d00200c102a0b200e2011490d0020194200370300200342003703b004418891c6004111200341b0046a100820072019290300370300200320032903b004370368200341003602f002200341e8006a4110200341f0026a10062119024020032802f002221d417f460d00201d41034d0d052019102a0b200341f0026a41186a200241186a290000370300200f200241106a290000370300200341f0026a41086a200241086a290000370300200320022900003703f0022003201236029003200341b0046a200341f0026a10c10242002130420021370240201320032802b80422194f0d00201920166a221d20194f0d04203320347c203520367c2230203554ad7c420020032802b004201d4102746a28020020157122191b21372030420020191b21300b024020032802b404450d0020032802b004102a0b203720327c203020317c2231203054ad7c21320b200241216a2102201c415f6a221c0d000b0b2010201741306c6a210920102102024002400240024003400240200920026b4190014b0d00024020022009460d0003404101211c200241106a220220034188046a460d04200220034188046a4120109c05450d04200241206a22022009470d000b0b4100211c203120058520322004858450450d02200341d0026a41186a220220034188046a41186a290300370300200341d0026a41106a221920034188046a41106a290300370300200341d0026a41086a221c20034188046a41086a29030037030020032003290388043703d0022010200437030820102005370300201020032903d002370310201041186a201c290300370300201041206a2019290300370300201041286a200229030037030020174115490d0a202d422188220b42307e2204422088a70d182004a72202417f4c0d1820020d03410821254108210f0c040b4101211c200241106a221920034188046a460d01201920034188046a4120109c05450d01200241c0006a221920034188046a460d01201920034188046a4120109c05450d01200241f0006a221920034188046a460d01201920034188046a4120109c05450d01200241a0016a221920034188046a460d01200241c0016a2102201920034188046a4120109c050d000b0b200341386a200341e0036a202f200b10cf012003290338210b2003200341c0006a2903003703f8022003200b3703f00241cafec10041e0fec100201c1b21194116410f201c1b21022003200341f0026a3602b004200341b0046a109d014101211c0c090b200210282225450d012025210f0b200ba7211f201041506a2128201041306a212c201041f07e6a212b410421154100212741002106410021122017210a0340200a21074100210a4101210c02402007417f6a221c450d000240024002400240024002402010201c41306c6a2202290300200741306c221120106a41a07f6a2219290300220454200241086a2903002205201941086a290300220b542005200b511b0d002007417e6a210e202b20116a21024100210a4100211903400240200e2019470d002007210c0c080b20042002290300222d5a211c200b200241086a290300220551211d200b20055a210c200241506a2102201941016a2119202d21042005210b201c200c201d1b0d000b201941016a210c2019417f7320076a211c0c010b202b20116a2102024003400240201c4101470d004100211c0c020b20042002290300222d542119200b200241086a290300220551211d200b200554210c200241506a2102201c417f6a211c202d21042005210b2019200c201d1b0d000b0b2007201c490d01200720174b0d032007201c6b220c410176221d450d00202820116a21022010201c41306c6a21190340200341f0026a41286a220e201941286a2211290300370300200341f0026a41206a2213201941206a2216290300370300200341f0026a41186a2218201941186a221a290300370300200341f0026a41106a221b201941106a220a290300370300200341f0026a41086a2208201941086a2229290300370300200320192903003703f002200241086a222a290300210b200241106a221e2903002104200241186a22222903002105200241206a2223290300212d200241286a2224290300212f201920022903003703002011202f3703002016202d370300201a2005370300200a20043703002029200b3703002024200e2903003703002023201329030037030020222018290300370300201e201b290300370300202a2008290300370300200220032903f002370300201941306a2119200241506a2102201d417f6a221d0d000b0b0240201c0d00201c210a0c050b0240200c41094d0d00201c210a0c050b200720174b0d012007201c6b211d202c201c41306c6a210e03402007201c417f6a220a490d0402402007200a6b220c4102490d002010201c41306c6a22022903002010200a41306c6a221c29030022055a200241086a22192903002204201c41086a2211290300220b5a2004200b511b0d00200341b0046a41186a2216201c41286a2213290300370300200341b0046a41106a2218201c41206a221a290300370300200341b0046a41086a221b201c41186a22082903003703002003201c2903103703b004201c200229030037030020112019290300370300201c41106a200241106a2903003703002008200241186a290300370300201a200241206a2903003703002013200241286a290300370300410121190240200c4103490d00201c29036020055a201c41e8006a2903002204200b5a2004200b511b0d0041022111200e211303402013220241506a22192002290300370300201941286a200241286a290300370300201941206a200241206a290300370300201941186a200241186a290300370300201941106a200241106a290300370300201941086a200241086a290300370300201d20112219460d01201941016a2111200241306a221329030020055a200241386a2903002204200b5a2004200b511b450d000b0b200220053703002002200b370308201c201941306c6a220241286a2016290300370300200241206a2018290300370300200241186a201b290300370300200220032903b0043703100b200a450d05200e41506a210e201d41016a211d200a211c200c410a4f0d050c000b0b201c20071044000b2007201c417f6a220a490d010b20072017103c000b200a20071044000b02400240024020122027470d00202741016a22022027490d18202741017422192002201920024b1b220241ffffffff01712002470d18200241037422194100480d180240024020270d002019102821150c010b201520274103742019102c21150b2015450d0120022127200621120b201520124103746a2202200c3602042002200a360200200641016a2212210620124102490d0102400340024002400240024020152012417f6a22064103746a2202280200450d00201241037420156a221d41746a280200221c200228020422194d0d000240201241024b0d0020122106410221120c080b20152012417d6a22164103746a28020422022019201c6a4d0d010240201241034b0d0020122106410321120c080b201d41646a2802002002201c6a4d0d01201221060c070b20124103490d012002280204211920152012417d6a22164103746a28020421020b20022019490d010b2012417e6a21160b0240024002400240024002402012201641016a22084b2229450d00201220164b222a450d01201520164103746a2218280204221e20182802006a2202201520084103746a221a280200221b490d02200220174b0d032010201b41306c6a2211201a280204221341306c22196a211d200241306c211c2002201b6b220720136b220220134f0d042025201d200241306c2219109a051a200f20196a210c0240024020134101480d00200241014e0d010b201d2102200f21190c060b2028201c6a211c201d21020340201c200241506a221d200c41506a22072007290300201d29030054200741086a290300220b201d41086a290300220454200b2004511b220e1b2219290300370300201c41086a201941086a290300370300201c41106a201941106a290300370300201c41186a201941186a290300370300201c41206a201941206a290300370300201c41286a201941286a290300370300200c2007200e1b210c02402011201d2002200e1b2202490d00200f21190c070b201c41506a211c200f2119200f200c490d000c060b0b41b8dbc000200820121034000b41b8dbc000201620121034000b201b20021044000b20022017103c000b202520112019109a051a200f20196a210c0240024020134101480d00200720134a0d010b20112102200f21190c010b2010201c6a210e200f21192011210203402002201d2019201d290300201929030054201d41086a290300220b201941086a290300220454200b2004511b22071b221c290300370300200241086a201c41086a290300370300200241106a201c41106a290300370300200241186a201c41186a290300370300200241206a201c41206a290300370300200241286a201c41286a2903003703002019201941306a20071b2119200241306a2102201d41306a201d20071b221d200e4f0d01200c20194b0d000b0b20022019200c20196b221c201c4130706b109a051a0240202a450d002018201b360200201841046a201e20136a3602002029450d02201a201a41086a20122008417f736a410374109b051a20062112200641014d0d040c010b0b41c8dbc000201620121034000b41b0b1c0001032000b201941041037000b200a0d000b02402027450d002015102a0b201f450d062025102a0c060b200241081037000b41cca2c100201d20191034000b41c4d1c3004133200341d8046a419cd9c3001038000b41c4d1c3004133200341d8046a419cd9c3001038000b411341011037000b20174102490d002017417f6a211c2010201741306c6a21074101211d03400240024002400240201c2202417f6a221c20174b0d002017201c6b22194102490d032010200241306c6a22022903002010201c41306c6a220c29030022055a200241086a220e2903002204200c41086a220f290300220b5a2004200b511b0d03200341b0046a41186a2211200c41286a2212290300370300200341b0046a41106a2213200c41206a2215290300370300200341b0046a41086a2216200c41186a22182903003703002003200c2903103703b004200c2002290300370300200f200e290300370300200c41106a200241106a2903003703002018200241186a2903003703002015200241206a2903003703002012200241286a2903003703004101210e20194103490d02200c29036020055a200c41e8006a2903002204200b5a2004200b511b0d024100210e2007211903402019220241506a22192002290300370300201941286a200241286a290300370300201941206a200241206a290300370300201941186a200241186a290300370300201941106a200241106a290300370300201941086a200241086a290300370300201d200e220f460d02200f417f6a210e200241306a221929030020055a200241386a2903002204200b5a2004200b511b0d020c000b0b201c20171044000b4102200f6b210e0b200220053703002002200b370308200c200e41306c6a220241286a2011290300370300200241206a2013290300370300200241186a2016290300370300200220032903b0043703100b200741506a2107201d417f6a211d201c0d000b0b200341b0046a41086a22024200370300200342003703b004418ca3c1004113200341b0046a1008200341e8006a41086a2002290300370300200320032903b004370368200341003602f802200342013703f0022017200341f0026a10b401201021020340200241086a290300210b200229030021040240024020032802f402221c20032802f80222196b4110490d0020032802f002211c0c010b201941106a221d2019490d0f201c4101742219201d2019201d4b1b22194100480d0f02400240201c0d0020191028211c0c010b20032802f002201c2019102c211c0b201c450d03200320193602f4022003201c3602f00220032802f80221190b201c20196a221c200b370008201c20043700002003201941106a3602f802200241106a200341f0026a108f01200241306a22022009470d000b20032802f4022102200341e8006a411020032802f002221920032802f802100702402002450d002019102a0b02402014450d002010102a0b4100211c410021190b024020032802ac02450d002026102a0b0240201c0d00202ea7450d120c020b02402014450d002010102a0b202ea7450d110c010b201941011037000b200d102a0c0f0b202ea7450d0e200d102a0c0e0b0b024002400240200ba7450d00201d102a201c0d010c020b201c450d010b200341e4016a41026a20034184026a41026a2d00003a0000200341c8016a41086a200341e8016a41086a290300370300200341c8016a410d6a200341e8016a410d6a290000370000200320032f0184023b01e401200320032903e8013703c8014100211c0c010b4101211c4118210241a8fac10021190b200341c4016a41026a221d200341e4016a41026a2d00003a0000200341a8016a41086a220c200341c8016a41086a290300370300200341a8016a41106a200341c8016a41106a290300370300200320032f01e4013b01c401200320032903c8013703a801201c0d0b20034183036a200c29030037000020034188036a200341b5016a290000370000200320032f01c4013b01f002200320023600f702200320193600f302200320032903a8013700fb022003201d2d00003a00f2020240200341f0026a20034188046a4120109c050d0020034188046a201b10d50220034188046a428080e983b1de16420010aa02200342f0f2bda9c6add9b1f4003703d00220031098013602a802200341b0046a20034188046a109a0220032802b404211920032802b004210220032802b804211c200341c4046a200341d0026a36020020032002201c4105746a3602bc04200320023602b804200320193602b404200320023602b0042003200341a8026a3602c004200341e0036a200341b0046a108701200341b0046a41086a200341e0036a41086a280200360200200320032903e0033703b00420034188046a200341b0046a109c02410021190c0c0b41c0fac1002119411921020c0b0b0b0240200ba7450d00200c102a201d450d010c020b201d0d010b4101211c4116210241dcf9c10021190c010b200341b0046a41026a200341a4016a41026a2d00003a0000200341f0026a41086a20034188016a41086a290300370300200341f0026a410d6a20034188016a410d6a290000370000200320032f01a4013b01b00420032003290388013703f0024100211c0b200341e8006a41026a221d200341b0046a41026a2d00003a000020034188046a41086a220c200341f0026a41086a29030037030020034188046a41106a200341f0026a41106a290300370300200320032f01b0043b0168200320032903f00237038804201c0d06200341f3036a200c290300370000200341f8036a20034195046a290000370000200320032f01683b01e003200320023600e703200320193600e30320032003290388043700eb032003201d2d00003a00e20302400240024002400240024002400240410e10282202450d00200241066a41002900b2a441370000200241002900aca4413700002002410e411c102c2202450d012002202041067636000e200341b0046a41186a22194200370300200341b0046a41106a221c4200370300200341b0046a41086a221d4200370300200342003703b00420024112200341b0046a1000200341e8006a41186a2019290300370300200341e8006a41106a201c290300370300200341e8006a41086a201d290300370300200320032903b0043703682002102a200341003602f002200341e8006a4120200341f0026a1006210220032802f0022219417f460d052002450d05200320193602b404200320023602b004200341f0026a200341b0046a107420032802f002220c450d022020413f71211c20032902f402210b02402019450d002002102a0b4100211d201c200b422088a74f0d03200c201c41216c6a22192d00004101470d0320034186026a201941036a2d00003a0000200341e8016a41086a201941146a290000370300200341f5016a201941196a290000370000200320192f00013b01840220032019410c6a2900003703e801201941086a2800002102201941046a28000021194101211d0c040b410e41011037000b411c41011037000b41c4d1c3004133200341d8046a419cd9c3001038000b0b0240200ba7450d00200c102a201d450d010c020b201d0d010b4101211c4114210241f2f9c10021190c010b200341e4016a41026a20034184026a41026a2d00003a0000200341c8016a41086a200341e8016a41086a290300370300200341c8016a410d6a200341e8016a410d6a290000370000200320032f0184023b01e401200320032903e8013703c8014100211c0b200341c4016a41026a221d200341e4016a41026a2d00003a0000200341a8016a41086a220c200341c8016a41086a290300370300200341a8016a41106a200341c8016a41106a290300370300200320032f01e4013b01c401200320032903c8013703a801201c0d062003419b046a200c290300370000200341a0046a200341b5016a290000370000200320032f01c4013b0188042003200236008f042003201936008b04200320032903a801370093042003201d2d00003a008a040240200341e0036a20034188026a4120109c05450d004186fac1002119411221020c070b024020034188046a200341a8026a4120109c05450d004198fac1002119411021020c070b200341f0026a41186a2217200341a8026a41186a2218290300370300200341f0026a41106a221a200341a8026a41106a221b290300370300200341f0026a41086a220a200341a8026a41086a2206290300370300200320032903a8023703f002410021022003410036029003200341b0046a200341f0026a10c1020240024020032802b804220d0d0041012112410021130c010b410021114100211341012112410021150340200d417f4c0d0220032802b404211620032802b00421140240024002400240200d1028220e450d0002400240200d41027422020d00410021070c010b201420026a210f410021072014210c0340200c2802002119412010282202450d0320022019411f763a001f200220194101713a000020022019411e764101713a001e20022019411d764101713a001d20022019411c764101713a001c20022019411b764101713a001b20022019411a764101713a001a200220194119764101713a0019200220194118764101713a0018200220194117764101713a0017200220194116764101713a0016200220194115764101713a0015200220194114764101713a0014200220194113764101713a0013200220194112764101713a0012200220194111764101713a0011200220194110764101713a001020022019410f764101713a000f20022019410e764101713a000e20022019410d764101713a000d20022019410c764101713a000c20022019410b764101713a000b20022019410a764101713a000a200220194109764101713a0009200220194108764101713a00082002201941ff017122194107763a0007200220194106764101713a0006200220194105764101713a0005200220194104764101713a0004200220194103764101713a0003200220194102764101713a0002200220194101764101713a0001200c41046a210c4100211902400240024002400340201941206a221c41034d0d010240200220196a221c411f6a2d0000450d002019411f6a211d0c040b0240201c411e6a2d0000450d002019411e6a211d0c040b0240201c411d6a2d00000d002019417c6a2119201c411c6a2d00000d030c010b0b2019411d6a211d0c020b0340201c450d032002201c6a2119201c417f6a221d211c2019417f6a2d0000450d000c020b0b201941206a211d0b201d41016a221c201d490d000240200d20076b201c4120201c4120491b22194f0d00200720196a22192007490d0b200d410174221d2019201d20194b1b22194100480d0b02400240200d0d0020191028210e0c010b200e200d2019102c210e0b200e450d062019210d0b200e20076a211d410021190240034020194120460d01201d20196a200220196a2d00004101713a0000201c201941016a2219470d000b0b200720196a21070b2002102a200c200f470d000b0b02402016450d002014102a0b0240201320116b2007490d00201120076a21020c040b201120076a22022011490d07201341017422192002201920024b1b22194100480d070240024020130d002019102821120c010b201220132019102c21120b02402012450d00201921130c040b201941011037000b200d41011037000b412041011037000b201941011037000b201220116a200e2007109a051a0240200d450d00200e102a0b20172018290300370300201a201b290300370300200a2006290300370300200320032903a8023703f0022003201541016a221536029003200341b0046a200341f0026a10c1022002211120032802b804220d0d000b0b024020032802b404450d0020032802b004102a0b200341b0046a41086a22194200370300200342003703b00441b0a3c1004112200341b0046a1008200341e8006a41086a2019290300370300200320032903b004370368200341003602f002200341e8006a4110200341f0026a1006211902400240024020032802f002221c417f460d002019450d002003201c3602b404200320193602b004200341f0026a200341b0046a106d20032802f002220e450d0220032902f402210b201c450d012019102a0c010b4101210e4200210b0b200b422088a741ffffff3f7122192002200220194b1b221c450d034100211920034188036a211d20034180036a210c200341f8026a2107200e210203400240201220196a2d0000450d00201d4200370300200c420037030020074200370300200342003703f002200341f0026a2002460d002002200341f0026a4120109c05450d00200341f0026a200210bf024101210d20032802f0024101470d0020032802f40220104d0d060b200241206a2102201941016a2219201c4f0d040c000b0b41c4d1c3004133200341d8046a419cd9c3001038000b1036000b1031000b4100210d0b0240200ba7450d00200e102a0b02402013450d002012102a0b20034188026a200341a8026a200d1b221920212020200d1b10d502200342f0f2bda9c6add9b1f4003703c80220031098013602d002200341f0026a2019109a0220032802f402211c20032802f002210220032802f802211d20034184036a200341c8026a36020020032002201d4105746a3602fc02200320023602f8022003201c3602f402200320023602f0022003200341d0026a36028003200341b0046a200341f0026a108701200341f0026a41086a200341b0046a41086a280200360200200320032903b0043703f0022019200341f0026a109c020240024002400240024002400240200d450d00200341106a20034188026a428080e983b1de1642001082022003290310210b2003200341106a41086a2903003703f8022003200b3703f0022003200341f0026a3602b004200341b0046a109d01200341013a00f402200341083a00f002200341f0026a4105722102200341f0026a211c0c010b200341206a20034188026a109d022003290320200341206a41086a29030084500d02411810282202450d03200241002900e3e140370000200241106a41002900f3e140370000200241086a41002900ebe1403700002003429880808080033702d402200320023602d002200341a8026a200341d0026a108f0120032802d802210220032802d0022119200341b0046a41186a221c4200370300200341b0046a41106a221d4200370300200341b0046a41086a220c4200370300200342003703b00420192002200341b0046a1000200341f0026a41186a201c290300370300200341f0026a41106a201d290300370300200341f0026a41086a200c290300370300200320032903b0043703f002024020032802d402450d0020032802d002102a0b200341003602b004200341f0026a4120200341b0046a1006210202400240024020032802b0042219417f470d004200210b420021050c010b20194110490d06200241086a29000021052002290000210b2002102a428080e983b1de1621044200212d200b428080e983b1de165441002005501b450d010b200b21042005212d0b411410282202450d05200241002900cfe140370000200241106a41002800dfe140360000200241086a41002900d7e14037000020034294808080c0023702d402200320023602d00220034188026a200341d0026a108f0120032802d802210220032802d0022119200341b0046a41186a221c4200370300200341b0046a41106a221d4200370300200341b0046a41086a220c4200370300200342003703b00420192002200341b0046a1000200341f0026a41186a201c290300370300200341f0026a41106a201d290300370300200341f0026a41086a200c290300370300200320032903b0043703f002024020032802d402450d0020032802d002102a0b200341003602b004200341f0026a4120200341b0046a100621020240024020032802b0042219417f470d004200212e4200212f0c010b20194110490d02200241086a290000212f2002290000212e2002102a0b20034188026a202e20047c2230202f202d7c2030202e54ad7c108f02200341a8026a200b20047d2005202d7d200b200454ad7d10900220034185036a200341b8026a2903003700002003418d036a200341c0026a290300370000200341083a00f002200341fd026a200341a8026a41086a290300370000200341003a00f402200320032903a8023700f50220034195036a2102200341f0026a211c0b2002200329038802370000200241186a20034188026a41186a290300370000200241106a20034188026a41106a290300370000200241086a20034188026a41086a290300370000410021194101211d41014100201c10cc014101210c0c0b0b41c4d1c3004133200341d8046a419cd9c3001038000b41b5dfc0002119412221020c050b411841011037000b41c4d1c3004133200341d8046a419cd9c3001038000b411441011037000b41dc9fc6002119410e21020c010b4111210241a39fc60021190b4101211d4101210c0c030b4100211c0b20034184026a41026a221d200341b0046a41026a2d00003a0000200341e8016a41086a220c200341f0026a41086a290300370300200341e8016a410d6a2207200341f0026a410d6a290000370000200320032f01b0043b018402200320032903f0023703e80102400240201c0d004101211c410b210241d8d2c50021190c010b200341e4016a41026a201d2d00003a0000200341c8016a41086a200c290300370300200341c8016a410d6a2007290000370000200320032f0184023b01e401200320032903e8013703c8014100211c0b200341c4016a41026a200341e4016a41026a2d00003a0000200341a8016a41086a200341c8016a41086a290300370300200341a8016a41106a200341c8016a41106a290300370300200320032f01e4013b01c401200320032903c8013703a801201c0d00200341a4016a41026a200341c4016a41026a2d0000221c3a000020034188016a41086a221d200341a8016a41086a29030037030020034188016a410d6a220c200341a8016a410d6a290000370000200320032f01c40122073b01a401200320032903a8013703880120034183036a201d29030037000020034188036a200c2900003700002003201c3a00f202200320073b01f002200320023600f702200320193600f30220032003290388013700fb02200320063602b8042003201b3602b4042003200a3602b004200341086a200341f0026a200341b0046a200920082005200410d402200328020c2102200328020821194101210c4100211d0c010b4101210c4100211d201b450d00200a102a0b02402001280200417f6a221c41014b0d0002400240201c0e020100010b201d450d01200141086a280200450d012001280204102a0c010b200c450d00200141086a280200450d002001280204102a0b2000200236020420002019360200200341e0046a24000bb55304087f017e097f027e23004190056b22032400024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024020012d000022040e050001020304000b2003418c046a4101360200200342013702fc03200341ccd1c5003602f803200341043602f402200341c4d1c5003602f0022003200341f0026a36028804200341f8036a41a8a6c300103e000b200141086a2802002105200141046a2802002106024020022d000020022d000172450d0041a39fc600210741112108410021094101210a02402005450d002006102a0b410121060c230b20062001410c6a280200220210f0014200210b200341f8036a41086a22074200370300200342003703f8034196f0c200411b200341f8036a1008200341f0026a41086a2007290300370300200320032903f8033703f002200341003602f803200341f0026a4110200341f8036a100621090240024020032802f8032208417f460d00200320083602ec01200320093602e801200341f8036a200341e8016a106d20032802f8032207450d0520032902fc03210b2008450d012009102a0c010b410121070b200620022007200b422088a71085020240200ba7450d002007102a0b200341f8036a41086a22074200370300200342003703f8034196f0c200411b200341f8036a1008200341f0026a41086a2007290300370300200320032903f8033703f0022003410036028004200342013703f8032002200341f8036a10b40102402002450d00200241057421072006210203402002200341f8036a108f01200241206a2102200741606a22070d000b0b20032802fc032102200341f0026a411020032802f8032207200328028004100702402002450d002007102a0b4101210a2005450d212006102a0c210b200141046a280200210941b49fc60021074113210820022d00000d1e2002280001220a41ff01714101470d1e2003200a4118763a00622003200a4108763b01602003200241216a2d00003a007f2003200241196a2900003700772003200241116a29000037006f2003200241096a2900003700672003200241056a2800003600634200210b200341f8036a41086a22024200370300200342003703f8034196f0c200411b200341f8036a1008200341f0026a41086a2002290300370300200320032903f8033703f002200341003602f803200341f0026a4110200341f8036a100621080240024020032802f8032207417f460d00200320073602ec01200320083602e801200341f8036a200341e8016a106d20032802f8032202450d0520032902fc03210b2007450d012008102a0c010b410121020b2002200b422088a7200341e0006a10cd0121070240200ba7450d002002102a0b024020070d0041b8a6c3002107411521080c1f0b4100210a2003410036028004200342013703f8032009200341f8036a10eb0120032802fc032107200328028004210820032802f8032102200341f0026a41186a22064200370300200341f0026a41106a22054200370300200341f0026a41086a220c4200370300200342003703f00220022008200341f0026a1000200341e8016a41186a22082006290300370300200341e8016a41106a220d2005290300370300200341e8016a41086a2205200c290300370300200320032903f0023703e80102402007450d002002102a0b200341f8036a2009418801109a051a200341f0026a410d6a200341e0006a41086a290300370000200341f0026a41156a200341e0006a41106a290300370000200341f0026a411d6a200341e0006a41186a29030037000041012106200341013a00f402200320032903603700f502200341023a00f002200341c0006a200341f8036a200341f0026a10f40120032d00482102200341f8036a410d6a2005290300370000200341f8036a41156a200d290300370000200341f8036a411d6a20082903003700002003419d046a20024102463a0000200341053a00fc03200341073a00f803200320032903e8013700fd0341014100200341f8036a10cc012009102a0c170b200141086a280200210941b49fc60021074113210820022d00000d1c2002280001220a41ff01714101470d1c200141046a28020021062003200a4118763a00422003200a4108763b01402003200241216a2d00003a005f2003200241196a2900003700572003200241116a29000037004f2003200241096a2900003700472003200241056a280000360043200341f8036a41086a22024200370300200342003703f8034196f0c200411b200341f8036a1008200341f0026a41086a2002290300370300200320032903f8033703f002200341003602f803200341f0026a4110200341f8036a100621070240024020032802f8032208417f460d002007450d00200320083602ec01200320073602e801200341f8036a200341e8016a106d20032802f8032202450d0520032902fc03210b2008450d012007102a0c010b4200210b410121020b2002200b422088a7200341c0006a10cd0121070240200ba7450d002002102a0b024020070d0041b8a6c3002107411521080c1d0b2003410036028004200342013703f8032009200341f8036a10eb0120032802fc032107200328028004210820032802f8032102200341f0026a41186a220a4200370300200341f0026a41106a22054200370300200341f0026a41086a220c4200370300200342003703f00220022008200341f0026a1000200341e0006a41186a2208200a290300370300200341e0006a41106a220a2005290300370300200341e0006a41086a2205200c290300370300200320032903f00237036002402007450d002002102a0b200341f8036a41186a2008290300370300200341f8036a41106a200a290300370300200341f8036a41086a2005290300370300200320032903603703f803411e10282202450d04200241002900f6a743370000200241166a410029008ca843370000200241106a4100290086a843370000200241086a41002900fea7433700002003429e808080e0033702ec01200320023602e8012003200341e8016a3602f002200341f8036a200341f0026a10c80120032802e801210220032802f0012107200341f0026a41186a22084200370300200341f0026a41106a220a4200370300200341f0026a41086a22054200370300200342003703f00220022007200341f0026a1000200341206a41186a2008290300370300200341206a41106a200a290300370300200341206a41086a2005290300370300200320032903f002370320024020032802ec01450d0020032802e801102a0b200341206a41204101410041001003417f470d05200341f8036a41086a22024200370300200342003703f803024020064102490d004194a8c3004121200341f8036a1008200341f0026a41086a2002290300370300200320032903f8033703f0024100210a200341003602f803200341f0026a4110200341f8036a10062102024020032802f8032207417f460d002002450d0020074104490d082002280000210a2002102a0b200341f8036a41086a22024200370300200342003703f8034194a8c3004121200341f8036a1008200341f0026a41086a2002290300370300200320032903f8033703f002200341003602f803200341f0026a4110200341f8036a100621020240024020032802f8032207417f460d002002450d00024020074104490d00200228000021072002102a200741016a21070c020b41c4d1c300413320034188056a419cd9c3001038000b410121070b200341f8036a41086a22024200370300200342003703f8034194a8c3004121200341f8036a1008200341f0026a41086a22082002290300370300200320032903f8033703f002200320073602f803200341f0026a4110200341f8036a4104100720024200370300200342003703f80341cf96c300411d200341f8036a100820082002290300370300200320032903f8033703f002200341003602f803200341f0026a4110200341f8036a1006210220032802f8032207417f460d092002450d09200320073602ec01200320023602e801200341f8036a200341e8016a106d20032802f8032208450d0820032902fc03210b02402007450d002002102a0b200320083602e8012003200b3702ec01200341206a41186a200341e0006a41186a290300370300200341206a41106a200341e0006a41106a290300370300200341206a41086a200341e0006a41086a29030037030020032003290360370320200341e8016a2107200b422088a72202200ba72208470d150c140b4196f0c200411b200341f8036a1008200341f0026a41086a2002290300370300200320032903f8033703f00241002102200341003602f803200341f0026a4110200341f8036a10062108024020032802f8032207417f460d00200320073602ec01200320083602e801200341f8036a200341e8016a106d20032802f803220a450d0a20032902fc03210b02402007450d002008102a0b200b422088a72102200ba7450d00200a102a0b200341f8036a2009418801109a051a200341fc026a2002360200200341f0026a41086a4101360200200341003a00f402200341023a00f002200341e8016a200341f8036a200341f0026a10f40120032d00f001210220034185046a200341e0006a41086a2903003700002003418d046a200341f0006a29030037000020034195046a200341f8006a2903003700002003419d046a20024102463a0000200341043a00fc03200341073a00f803200320032903603700fd03200341f8036a21020c150b200141216a2d0000210a200141246a2802002109200341186a200141196a290000370300200341106a200141116a290000370300200341086a200141096a290000370300200320012900013703000240024020022d00000d002002280001220741ff01714101460d010b41b49fc60021070c110b200320074118763a0042200320074108763b01402003200241216a2d00003a005f2003200241196a2900003700572003200241116a29000037004f2003200241096a2900003700472003200241056a280000360043200341f8036a41086a22024200370300200342003703f8034196f0c200411b200341f8036a1008200341f0026a41086a2002290300370300200320032903f8033703f002200341003602f803200341f0026a4110200341f8036a100621070240024020032802f8032208417f460d002007450d00200320083602ec01200320073602e801200341f8036a200341e8016a106d20032802f8032202450d0b20032902fc03210b2008450d012007102a0c010b4200210b410121020b2002200b422088a7200341c0006a10cd0121070240200ba7450d002002102a0b024020070d0041bea7c3002107411221080c120b411a10282202450d0a200241002900ec9643370000200241186a41002f008497433b0000200241106a41002900fc9643370000200241086a41002900f496433700002003429a808080a0033702fc03200320023602f8032003200341f8036a3602f0022003200341f0026a10c80120032802f80321022003280280042107200341f0026a41186a22084200370300200341f0026a41106a22064200370300200341f0026a41086a22054200370300200342003703f00220022007200341f0026a1000200341206a41186a2008290300370300200341206a41106a2006290300370300200341206a41086a2005290300370300200320032903f002370320024020032802fc03450d0020032802f803102a0b200341003602f803200341206a4120200341f8036a1006210220032802f8032207417f460d0f2002450d0f200320073602f402200320023602f002200341f8036a200341f0026a10b3032003280280042205450d0b20034194046a280200210e20034190046a280200210f2003418c046a280200210c41102108200341f8036a41106a2802002110200328028404211120032802fc03211220032802f803210602402007450d002002102a0b41d0a7c300210720062009470d0e200520104105746a21062005210241002108024003400240200620026b41e0004b0d0020022006470d02410021130c100b200341c0006a2002460d0e20082002200341c0006a4120109c0522074100476a21082007450d0e200241206a2207200341c0006a460d0e20082007200341c0006a4120109c0522074100476a21082007450d0e200241c0006a2207200341c0006a460d0e20082007200341c0006a4120109c0522074100476a21082007450d0e200241e0006a2207200341c0006a460d0e20024180016a210220082007200341c0006a4120109c0522074100476a210820070d000c0e0b0b200520104105746a21060340200341c0006a2002460d0d20082002200341c0006a4120109c0522074100476a21082007450d0d410021132006200241206a2202470d000c0e0b0b41c4d1c300413320034188056a419cd9c3001038000b41c4d1c300413320034188056a419cd9c3001038000b41c4d1c300413320034188056a419cd9c3001038000b411e41011037000b41cda6c3002107411f21080c160b41c4d1c300413320034188056a419cd9c3001038000b41c4d1c300413320034188056a419cd9c3001038000b41002102200341003602f001200342013703e801200341206a41186a200341e0006a41186a290300370300200341206a41106a200341e0006a41106a290300370300200341206a41086a200341e0006a41086a29030037030020032003290360370320200341e8016a21070c0a0b41c4d1c300413320034188056a419cd9c3001038000b41c4d1c300413320034188056a419cd9c3001038000b411a41011037000b41c4d1c300413320034188056a419cd9c3001038000b410121130b200c200e4105746a210d200c21024100210702400240024003400240200d20026b41e0004b0d002002200d470d02410021060c040b200341c0006a2002460d0220072002200341c0006a4120109c0522064100476a21072006450d02200241206a2206200341c0006a460d0220072006200341c0006a4120109c0522064100476a21072006450d02200241c0006a2206200341c0006a460d0220072006200341c0006a4120109c0522064100476a21072006450d02200241e0006a2206200341c0006a460d0220024180016a210220072006200341c0006a4120109c0522064100476a210720060d000c020b0b0340200341c0006a2002460d0120072002200341c0006a4120109c0522064100476a21072006450d0141002106200d200241206a2202470d000c020b0b410121060b024002400240024002400240024002400240200a41ff01710d002006450d010c080b20130d07200341f8036a41186a220d200341c0006a41186a290300370300200341f8036a41106a2213200341c0006a41106a290300370300200341f8036a41086a2214200341c0006a41086a290300370300200320032903403703f803024020102011460d0020112108201021110c020b201141016a22022011490d10201141017422082002200820024b1b220841ffffff3f712008470d10200841057422024100480d100240024020110d002002102821050c010b200520114105742002102c21050b20050d01200241011037000b200341f8036a41186a2206200341c0006a41186a290300370300200341f8036a41106a220d200341c0006a41106a290300370300200341f8036a41086a2214200341c0006a41086a290300370300200320032903403703f80302400240200e200f460d00200f2107200e210f0c010b200f41016a2202200f490d10200f41017422072002200720024b1b220741ffffff3f712007470d10200741057422024100480d1002400240200f0d0020021028210c0c010b200c200f4105742002102c210c0b200c0d00200241011037000b200c200f4105746a220220032903f803370000200241186a2006290300370000200241106a200d290300370000200241086a2014290300370000200e41016a210e024002402013450d00201020084d0d0120052010417f6a22104105746a2202290000210b2002290008211520022900102116200520084105746a220841186a200241186a29000037000020082016370010200820153700082008200b3700000b2007210f201121080c020b41c4f2c200200820101034000b200520114105746a220220032903f803370000200241186a200d290300370000200241106a2013290300370000200241086a2014290300370000201041016a21102006450d00200e20074d0d01200c200e417f6a220e4105746a2202290000210b2002290008211520022900102116200c20074105746a220741186a200241186a29000037000020072016370010200720153700082007200b3700000b2003419d046a200329030037000020034185046a200341c0006a41086a2903003700002003418d046a200341c0006a41106a29030037000020034195046a200341c0006a41186a290300370000200341a5046a200341086a290300370000200341ad046a200341106a290300370000200341b5046a200341186a290300370000200341013a00fc03200341073a00f803200320032903403700fd03200341c4046a200e360200200341c0046a2010360200200341bd046a200a3a000041014100200341f8036a10cc01200341f8036a41086a22024200370300200342003703f8034196f0c200411b200341f8036a1008200341f0026a41086a2002290300370300200320032903f8033703f002200341003602f803200341f0026a4110200341f8036a1006210220032802f8032207417f460d022002450d02200320073602ec01200320023602e801200341f8036a200341e8016a106d20032802f803220a450d0120032902fc03210b02402007450d002002102a0b200b422088a72102200ba7450d03200a102a0c030b41c4f2c2002007200e1034000b41c4d1c300413320034188056a419cd9c3001038000b410021020b024002400240024002400240024002400240201020124f22070d0041002002200e6b220a200a20024b1b2012490d0020034194046a200e360200200341f8036a41186a200f360200200341f8036a41106a201036020020034184046a20083602002003200c36028c042003200536028004200320123602fc03200320093602f803411a10282202450d01200241002900ec9643370000200241186a41002f008497433b0000200241106a41002900fc9643370000200241086a41002900f496433700002003429a808080a0033702ec01200320023602e8012003200341e8016a3602f0022003200341f0026a10c80120032802e801210220032802f0012107200341f0026a41186a22094200370300200341f0026a41106a220a4200370300200341f0026a41086a22064200370300200342003703f00220022007200341f0026a1000200341206a41186a2009290300370300200341206a41106a200a290300370300200341206a41086a2006290300370300200320032903f002370320024020032802ec01450d0020032802e801102a0b200341203602f4022003200341206a3602f002200341f8036a200341f0026a10b40302402008450d002005102a0b200f0d050c060b024020070d0020034185046a200341086a2903003700002003418d046a200341106a29030037000020034195046a200341186a290300370000200341033a00fc03200341073a00f803200320032903003700fd0341014100200341f8036a10cc010c040b20034185046a200341086a2903003700002003418d046a200341106a29030037000020034195046a200341186a290300370000200341023a00fc03200341073a00f803200320032903003700fd0341014100200341f8036a10cc01411e10282207450d01200741002900f6a743370000200741166a410029008ca843370000200741106a4100290086a843370000200741086a41002900fea7433700002003429e808080e0033702fc03200320073602f8032003200341f8036a3602f0022003200341f0026a10c80120032802f80321072003280280042109200341f0026a41186a220a4200370300200341f0026a41106a22064200370300200341f0026a41086a220d4200370300200342003703f00220072009200341f0026a1000200341206a41186a200a290300370300200341206a41106a2006290300370300200341206a41086a200d290300370300200320032903f002370320024020032802fc03450d0020032802f803102a0b200341003602f803200341206a4120200341f8036a100621090240024020032802f803220a417f470d00411321070c010b024020090d00411321070c010b2003200a360284052003200936028005200341f8036a20034180056a10810120032802f80322074113460d03200341f0026a200341f8036a410472418401109a051a0240200a450d002009102a0b200341206a412010090b200341e8016a200341f0026a418401109a051a200341f8036a200341e8016a418401109a051a20074113460d03200341e0006a200341f8036a418401109a051a200320073602f803200341f8036a410472200341e0006a418401109a051a200341fc026a2002360200200341f0026a41086a2012360200200341003a00f402200341023a00f002200341e8016a200341f8036a200341f0026a10f40120032d00f001210220034185046a200341086a2903003700002003418d046a200341106a29030037000020034195046a200341186a2903003700002003419d046a20024102463a0000200341043a00fc03200341073a00f803200320032903003700fd0341014100200341f8036a10cc010c030b411a41011037000b411e41011037000b41c4d1c300413320034188056a419cd9c3001038000b411a10282202450d02200241002900ec9643370000200241186a41002f008497433b0000200241106a41002900fc9643370000200241086a41002900f496433700002003429a808080a0033702fc03200320023602f8032003200341f8036a3602f0022003200341f0026a10c80120032802f80321072003280280042109200341f0026a41186a220a4200370300200341f0026a41106a22064200370300200341f0026a41086a22024200370300200342003703f00220072009200341f0026a1000200341206a41186a200a290300370300200341206a41106a2006290300370300200341206a41086a2002290300370300200320032903f002370320024020032802fc03450d0020032802f803102a0b200341206a41201009200341f8036a41086a22074200370300200342003703f80341cf96c300411d200341f8036a100820022007290300370300200320032903f8033703f002200341003602f803200341f0026a4110200341f8036a100621070240024020032802f8032202417f460d00200320023602ec01200320073602e801200341f8036a200341e8016a106d20032802f8032209450d0520032902fc03210b02402002450d002007102a0b2003200b3702ec01200320093602e8010c010b200341003602f001200342013703e8010b200341e8016a2003106e20032802f001210220032802ec01210a20032802e8012109200341f8036a41086a22074200370300200342003703f80341cf96c300411d200341f8036a1008200341f0026a41086a2007290300370300200320032903f8033703f0020240024020090d00200341f0026a411010090c010b2003410036028004200342013703f8032002200341f8036a10b40102402002450d00200241057421072009210203402003200341f8036a3602602002200341e0006a10c801200241206a2102200741606a22070d000b0b20032802fc032102200341f0026a411020032802f8032207200328028004100702402002450d002007102a0b200a450d002009102a0b02402008450d002005102a0b200f450d010b200c102a0b410021074101210a41012106410121090c140b411a41011037000b41c4d1c300413320034188056a419cd9c3001038000b41e0a7c3002107411621080b02402011450d002005102a0b200f450d02200c102a0c020b41aba7c30021070b411321080b4101210a410121060c0b0b200741046a28020022082002470d00200241016a22082002490d03200241017422052008200520084b1b220841ffffff3f712008470d03200841057422054100480d030240024020020d002005102821020c010b200728020020024105742005102c21020b2002450d0420072002360200200741046a200836020020032802f00121020b200728020022052002410574220d6a22072003290320370000200741186a200341206a41186a290300370000200741106a200341206a41106a290300370000200741086a200341206a41086a2903003700002003200241016a22073602f001200341f8036a41086a220c4200370300200342003703f80341cf96c300411d200341f8036a1008200341f0026a41086a200c290300370300200320032903f8033703f0022003410036028004200342013703f8032007200341f8036a10b401024020072002490d00200d41206a21072005210203402003200341f8036a3602202002200341206a10c801200241206a2102200741606a22070d000b0b20032802fc032102200341f0026a411020032802f8032207200328028004100702402002450d002007102a0b02402008450d002005102a0b200341f8036a2009418801109a051a200341e8016a41186a200341e0006a41186a290300370300200341e8016a41106a200341e0006a41106a290300370300200341e8016a41086a200341e0006a41086a290300370300200320032903603703e801411e10282202450d04200241002900f6a743370000200241166a410029008ca843370000200241106a4100290086a843370000200241086a41002900fea7433700002003429e808080e00337020420032002360200200320033602f002200341e8016a200341f0026a10c8012003280200210220032802082107200341f0026a41186a22084200370300200341f0026a41106a22054200370300200341f0026a41086a220c4200370300200342003703f00220022007200341f0026a1000200341206a41186a2008290300370300200341206a41106a2005290300370300200341206a41086a200c290300370300200320032903f00237032002402003280204450d002003280200102a0b200341003602f802200342013703f002200341f8036a200341f0026a10eb0120032802f4022102200341206a412020032802f002220720032802f802100702402002450d002007102a0b200341f8036a106a412010282202450d0520022003290340370000200241186a200341c0006a41186a290300370000200241106a200341c0006a41106a290300370000200241086a200341c0006a41086a29030037000020034184026a4100360200200341f4016a428180808010370200200342013702fc01200320023602f001200320063602ec012003200a3602e801200341f8036a41186a200341e0006a41186a290300370300200341f8036a41106a200341e0006a41106a290300370300200341f8036a41086a200341e0006a41086a290300370300200320032903603703f803411a10282207450d06200741002900ec9643370000200741186a41002f008497433b0000200741106a41002900fc9643370000200741086a41002900f496433700002003429a808080a00337020420032007360200200320033602f002200341f8036a200341f0026a10c8012003280200210720032802082108200341f0026a41186a22054200370300200341f0026a41106a220c4200370300200341f0026a41086a220d4200370300200342003703f00220072008200341f0026a1000200341206a41186a2005290300370300200341206a41106a200c290300370300200341206a41086a200d290300370300200320032903f00237032002402003280204450d002003280200102a0b200341203602fc032003200341206a3602f803200341e8016a200341f8036a10b4032002102a20034185046a200341c0006a41086a2903003700002003418d046a200341c0006a41106a29030037000020034195046a200341c0006a41186a2903003700002003419d046a2003290360370000200341a5046a200341e0006a41086a290300370000200341ad046a200341e0006a41106a290300370000200341b5046a200341e0006a41186a290300370000200341c4046a2006360200200341c0046a200a360200200341003a00fc03200341073a00f803200320032903403700fd03200341f8036a21020b410021064101210a41014100200210cc012009102a0b41012109410021070c090b1031000b200541011037000b411e41011037000b412041011037000b411a41011037000b2009106a2009102a410021064101210a0c010b2009106a2009102a410121064100210a0b410121090c010b4100210941012106410021070b02402004410771417f6a220241024b0d0002400240024020020e03000102000b2009450d02200141086a280200450d02200141046a280200102a0c020b200a450d01200141046a2802002202106a2002102a0c010b2006450d00200141086a2802002202106a2002102a0b200020083602042000200736020020034190056a24000bf35c040b7f017e127f027e23004190056b220324000240024002400240024002400240024002400240024002400240024002400240024020012d000022040e0500010a0302000b2003418c046a4101360200200342013702fc03200341ccd1c5003602f803200341043602f402200341c4d1c5003602f0022003200341f0026a36028804200341f8036a41a8a6c300103e000b200141086a2802002105200141046a2802002106024020022d000020022d000172450d0041a39fc600210741112108410021094101210a02402005450d002006102a0b4101210b0c0f0b20062001410c6a280200220c10f001200341f8036a41086a22024200370300200342003703f80341fbefc200411b200341f8036a1008200341f0026a41086a2002290300370300200320032903f8033703f002200341003602f803200341f0026a4110200341f8036a1006210202400240024020032802f8032207417f460d002002450d00200320073602ec01200320023602e801200341f8036a200341e8016a106d20032802f803220d450d0220032902fc03210e2007450d012002102a0c010b4101210d4200210e0b20064100200c1b2109200d41206a200d200e422088a722021b210f200641206a2006200c1b2110200d410020021b21112006200c4105746a2112200d20024105746a2113410021144100211541012116410021174100211841012119024003402014410174211a2014410574211b024002400240024002400340024020110d00200f211c2016211d2015211e201421080c040b20112102200f21072016211d2015211e20142108201b210a201a210b02400340024002402009450d0020022009460d06200220094120109c05221c450d06201c417f4c0d012007210f201d2116201e211520082114200221110c080b200341f8036a41186a2207201141186a290000370300200341f8036a41106a2208201141106a290000370300200341f8036a41086a2209201141086a290000370300200320112900003703f803024020142015470d00201441016a22022014490d0f2014410174220a2002200a20024b1b221541ffffff3f712015470d0f201541057422024100480d0f0240024020140d002002102821160c010b201620144105742002102c21160b2016450d030b201620144105746a220220032903f803370000200241186a2007290300370000200241106a2008290300370000200241086a2009290300370000410021094100200f200f20134622021b2111201a41026a211a201b41206a211b201441016a2114200f200f41206a20021b210f0c030b200341f8036a41186a221c200241186a290000370300200341f8036a41106a221f200241106a290000370300200341f8036a41086a2220200241086a290000370300200320022900003703f80302402008201e470d00200841016a22022008490d0e200b2002200b20024b1b221e41ffffff3f71201e470d0e201e41057422024100480d0e0240024020080d0020021028211d0c010b201d200a2002102c211d0b201d450d040b201d200a6a220220032903f803370000200241186a201c290300370000200241106a201f290300370000200241086a2020290300370000410020072007201346221c1b2102200b41026a210b200a41206a210a200841016a21082007200741206a201c1b221c21072002450d050c000b0b0b200241011037000b200241011037000b201d2116201e2115200821142007200741206a200720134622021b210f41002010201020124622081b21094100200720021b21112010201041206a20081b21100c030b410021112009450d01201c210f201d2116201e2115200821140b200341206a41186a2207200941186a290000370300200341206a41106a2208200941106a290000370300200341206a41086a220a200941086a29000037030020032009290000370320024020172018470d00201741016a22022017490d07201741017422092002200920024b1b221841ffffff3f712018470d07201841057422024100480d070240024020170d002002102821190c010b201920174105742002102c21190b2019450d030b201920174105746a22022003290320370000200241186a2007290300370000200241106a2008290300370000200241086a200a29030037000041002010201020124622021b2109201741016a21172010201041206a20021b21100c010b0b201d20082006200c10c5020240201e450d00201d102a0b02402018450d002019102a0b0240200ea7450d00200d102a0b200341f8036a41086a22024200370300200342003703f80341fbefc200411b200341f8036a1008200341f0026a41086a2002290300370300200320032903f8033703f0022003410036028004200342013703f803200c200341f8036a10b4010240200c450d00200c41057421072006210203402002200341f8036a108f01200241206a2102200741606a22070d000b0b20032802fc032102200341f0026a411020032802f8032207200328028004100702402002450d002007102a0b4101210a2005450d0f2006102a0c0f0b200241011037000b41c4d1c300413320034188056a419cd9c3001038000b200141216a2d0000210a200141246a2802002109200341186a200141196a290000370300200341106a200141116a290000370300200341086a200141096a29000037030020032001290001370300024002400240024020022d00000d002002280001220741ff01714101460d010b41b49fc60021070c010b200320074118763a0042200320074108763b01402003200241216a2d00003a005f2003200241196a2900003700572003200241116a29000037004f2003200241096a2900003700472003200241056a280000360043200341f8036a41086a22024200370300200342003703f80341fbefc200411b200341f8036a1008200341f0026a41086a2002290300370300200320032903f8033703f002200341003602f803200341f0026a4110200341f8036a1006210702400240024002400240024002400240024020032802f8032208417f460d002007450d00200320083602ec01200320073602e801200341f8036a200341e8016a106d20032802f8032202450d0220032902fc03210e2008450d012007102a0c010b4200210e410121020b2002200e422088a7200341c0006a10cd0121070240200ea7450d002002102a0b024020070d0041bea7c3002107411221080c090b411a10282202450d01200241002900b59643370000200241186a41002f00cd96433b0000200241106a41002900c59643370000200241086a41002900bd96433700002003429a808080a0033702fc03200320023602f8032003200341f8036a3602f0022003200341f0026a10c80120032802f80321022003280280042107200341f0026a41186a22084200370300200341f0026a41106a220b4200370300200341f0026a41086a221e4200370300200342003703f00220022007200341f0026a1000200341206a41186a2008290300370300200341206a41106a200b290300370300200341206a41086a201e290300370300200320032903f002370320024020032802fc03450d0020032802f803102a0b200341003602f803200341206a4120200341f8036a1006210220032802f8032207417f460d062002450d06200320073602f402200320023602f002200341f8036a200341f0026a10b303200328028004221e450d0220034194046a280200211420034190046a28020021202003418c046a280200211d41102108200341f8036a41106a280200211f200328028404211320032802fc03211020032802f803210b02402007450d002002102a0b41d0a7c3002107200b2009470d05201e201f4105746a210b201e210241002108024003400240200b20026b41e0004b0d002002200b470d02410021110c070b200341c0006a2002460d0520082002200341c0006a4120109c0522074100476a21082007450d05200241206a2207200341c0006a460d0520082007200341c0006a4120109c0522074100476a21082007450d05200241c0006a2207200341c0006a460d0520082007200341c0006a4120109c0522074100476a21082007450d05200241e0006a2207200341c0006a460d0520024180016a210220082007200341c0006a4120109c0522074100476a210820070d000c050b0b201e201f4105746a210b0340200341c0006a2002460d0420082002200341c0006a4120109c0522074100476a21082007450d0441002111200b200241206a2202470d000c050b0b41c4d1c300413320034188056a419cd9c3001038000b411a41011037000b41c4d1c300413320034188056a419cd9c3001038000b410121110b201d20144105746a211c201d21024100210702400240024003400240201c20026b41e0004b0d002002201c470d024100210b0c040b200341c0006a2002460d0220072002200341c0006a4120109c05220b4100476a2107200b450d02200241206a220b200341c0006a460d022007200b200341c0006a4120109c05220b4100476a2107200b450d02200241c0006a220b200341c0006a460d022007200b200341c0006a4120109c05220b4100476a2107200b450d02200241e0006a220b200341c0006a460d0220024180016a21022007200b200341c0006a4120109c05220b4100476a2107200b0d000c020b0b0340200341c0006a2002460d0120072002200341c0006a4120109c05220b4100476a2107200b450d014100210b201c200241206a2202470d000c020b0b4101210b0b024002400240024002400240024002400240200a41ff01710d00200b450d010c080b20110d07200341f8036a41186a221c200341c0006a41186a290300370300200341f8036a41106a2211200341c0006a41106a290300370300200341f8036a41086a220f200341c0006a41086a290300370300200320032903403703f8030240201f2013460d0020132108201f21130c020b201341016a22022013490d0d201341017422082002200820024b1b220841ffffff3f712008470d0d200841057422024100480d0d0240024020130d0020021028211e0c010b201e20134105742002102c211e0b201e0d01200241011037000b200341f8036a41186a220b200341c0006a41186a290300370300200341f8036a41106a221c200341c0006a41106a290300370300200341f8036a41086a220f200341c0006a41086a290300370300200320032903403703f8030240024020142020460d0020202107201421200c010b202041016a22022020490d0d202041017422072002200720024b1b220741ffffff3f712007470d0d200741057422024100480d0d0240024020200d0020021028211d0c010b201d20204105742002102c211d0b201d0d00200241011037000b201d20204105746a220220032903f803370000200241186a200b290300370000200241106a201c290300370000200241086a200f290300370000201441016a2114024002402011450d00201f20084d0d01201e201f417f6a221f4105746a2202290000210e2002290008212120022900102122201e20084105746a220841186a200241186a29000037000020082022370010200820213700082008200e3700000b20072120201321080c020b41c4f2c2002008201f1034000b201e20134105746a220220032903f803370000200241186a201c290300370000200241106a2011290300370000200241086a200f290300370000201f41016a211f200b450d00201420074d0d01201d2014417f6a22144105746a2202290000210e2002290008212120022900102122201d20074105746a220741186a200241186a29000037000020072022370010200720213700082007200e3700000b2003419d046a200329030037000020034185046a200341c0006a41086a2903003700002003418d046a200341c0006a41106a29030037000020034195046a200341c0006a41186a290300370000200341a5046a200341086a290300370000200341ad046a200341106a290300370000200341b5046a200341186a290300370000200341013a00fc03200341063a00f803200320032903403700fd03200341c4046a2014360200200341c0046a201f360200200341bd046a200a3a000041014100200341f8036a10cc01200341f8036a41086a22024200370300200342003703f80341fbefc200411b200341f8036a1008200341f0026a41086a2002290300370300200320032903f8033703f002200341003602f803200341f0026a4110200341f8036a1006210220032802f8032207417f460d022002450d02200320073602ec01200320023602e801200341f8036a200341e8016a106d20032802f803220a450d0120032902fc03210e02402007450d002002102a0b200e422088a72102200ea7450d03200a102a0c030b41c4f2c200200720141034000b41c4d1c300413320034188056a419cd9c3001038000b410021020b024002400240024002400240024002400240201f20104f22070d004100200220146b220a200a20024b1b2010490d0020034194046a2014360200200341f8036a41186a2020360200200341f8036a41106a201f36020020034184046a20083602002003201d36028c042003201e36028004200320103602fc03200320093602f803411a10282202450d01200241002900b59643370000200241186a41002f00cd96433b0000200241106a41002900c59643370000200241086a41002900bd96433700002003429a808080a0033702ec01200320023602e8012003200341e8016a3602f0022003200341f0026a10c80120032802e801210220032802f0012107200341f0026a41186a22094200370300200341f0026a41106a220a4200370300200341f0026a41086a220b4200370300200342003703f00220022007200341f0026a1000200341206a41186a2009290300370300200341206a41106a200a290300370300200341206a41086a200b290300370300200320032903f002370320024020032802ec01450d0020032802e801102a0b200341203602f4022003200341206a3602f002200341f8036a200341f0026a10b40302402008450d00201e102a0b20200d050c060b024020070d0020034185046a200341086a2903003700002003418d046a200341106a29030037000020034195046a200341186a290300370000200341033a00fc03200341063a00f803200320032903003700fd0341014100200341f8036a10cc010c040b20034185046a200341086a2903003700002003418d046a200341106a29030037000020034195046a200341186a290300370000200341023a00fc03200341063a00f803200320032903003700fd0341014100200341f8036a10cc01411e10282207450d01200741002900eca643370000200741166a4100290082a743370000200741106a41002900fca643370000200741086a41002900f4a6433700002003429e808080e0033702fc03200320073602f8032003200341f8036a3602f0022003200341f0026a10c80120032802f80321072003280280042109200341f0026a41186a220a4200370300200341f0026a41106a220b4200370300200341f0026a41086a221c4200370300200342003703f00220072009200341f0026a1000200341206a41186a200a290300370300200341206a41106a200b290300370300200341206a41086a201c290300370300200320032903f002370320024020032802fc03450d0020032802f803102a0b200341003602f803200341206a4120200341f8036a100621090240024020032802f803220a417f470d00411321070c010b024020090d00411321070c010b2003200a360284052003200936028005200341f8036a20034180056a10810120032802f80322074113460d03200341f0026a200341f8036a410472418401109a051a0240200a450d002009102a0b200341206a412010090b200341e8016a200341f0026a418401109a051a200341f8036a200341e8016a418401109a051a20074113460d03200341e0006a200341f8036a418401109a051a200320073602f803200341f8036a410472200341e0006a418401109a051a200341fc026a2002360200200341f0026a41086a2010360200200341003a00f402200341013a00f002200341e8016a200341f8036a200341f0026a10f40120032d00f001210220034185046a200341086a2903003700002003418d046a200341106a29030037000020034195046a200341186a2903003700002003419d046a20024102463a0000200341043a00fc03200341063a00f803200320032903003700fd0341014100200341f8036a10cc010c030b411a41011037000b411e41011037000b41c4d1c300413320034188056a419cd9c3001038000b411a10282202450d02200241002900b59643370000200241186a41002f00cd96433b0000200241106a41002900c59643370000200241086a41002900bd96433700002003429a808080a0033702fc03200320023602f8032003200341f8036a3602f0022003200341f0026a10c80120032802f80321072003280280042109200341f0026a41186a220a4200370300200341f0026a41106a220b4200370300200341f0026a41086a22024200370300200342003703f00220072009200341f0026a1000200341206a41186a200a290300370300200341206a41106a200b290300370300200341206a41086a2002290300370300200320032903f002370320024020032802fc03450d0020032802f803102a0b200341206a41201009200341f8036a41086a22074200370300200342003703f803419896c300411d200341f8036a100820022007290300370300200320032903f8033703f002200341003602f803200341f0026a4110200341f8036a100621070240024020032802f8032202417f460d00200320023602ec01200320073602e801200341f8036a200341e8016a106d20032802f8032209450d0520032902fc03210e02402002450d002007102a0b2003200e3702ec01200320093602e8010c010b200341003602f001200342013703e8010b200341e8016a2003106e20032802f001210220032802ec01210a20032802e8012109200341f8036a41086a22074200370300200342003703f803419896c300411d200341f8036a1008200341f0026a41086a2007290300370300200320032903f8033703f0020240024020090d00200341f0026a411010090c010b2003410036028004200342013703f8032002200341f8036a10b40102402002450d00200241057421072009210203402003200341f8036a3602602002200341e0006a10c801200241206a2102200741606a22070d000b0b20032802fc032102200341f0026a411020032802f8032207200328028004100702402002450d002007102a0b200a450d002009102a0b02402008450d00201e102a0b2020450d010b201d102a0b410021074101210a4101210b410121090c140b411a41011037000b41c4d1c300413320034188056a419cd9c3001038000b41e0a7c3002107411621080b02402013450d00201e102a0b2020450d02201d102a0c020b41aba7c30021070b411321080b4101210a4101210b0c0b0b200141086a280200210941b49fc60021074113210820022d00000d052002280001220a41ff01714101470d05200141046a280200210b2003200a4118763a00422003200a4108763b01402003200241216a2d00003a005f2003200241196a2900003700572003200241116a29000037004f2003200241096a2900003700472003200241056a280000360043200341f8036a41086a22024200370300200342003703f80341fbefc200411b200341f8036a1008200341f0026a41086a2002290300370300200320032903f8033703f002200341003602f803200341f0026a4110200341f8036a1006210702400240024002400240024002400240024002400240024020032802f8032208417f460d002007450d00200320083602ec01200320073602e801200341f8036a200341e8016a106d20032802f8032202450d0220032902fc03210e2008450d012007102a0c010b4200210e410121020b2002200e422088a7200341c0006a10cd0121070240200ea7450d002002102a0b024020070d0041b8a6c3002107411521080c100b2003410036028004200342013703f8032009200341f8036a10eb0120032802fc032107200328028004210820032802f8032102200341f0026a41186a220a4200370300200341f0026a41106a221e4200370300200341f0026a41086a221d4200370300200342003703f00220022008200341f0026a1000200341e0006a41186a2208200a290300370300200341e0006a41106a220a201e290300370300200341e0006a41086a221e201d290300370300200320032903f00237036002402007450d002002102a0b200341f8036a41186a2008290300370300200341f8036a41106a200a290300370300200341f8036a41086a201e290300370300200320032903603703f803411e10282202450d01200241002900eca643370000200241166a4100290082a743370000200241106a41002900fca643370000200241086a41002900f4a6433700002003429e808080e0033702ec01200320023602e8012003200341e8016a3602f002200341f8036a200341f0026a10c80120032802e801210220032802f0012107200341f0026a41186a22084200370300200341f0026a41106a220a4200370300200341f0026a41086a221e4200370300200342003703f00220022007200341f0026a1000200341206a41186a2008290300370300200341206a41106a200a290300370300200341206a41086a201e290300370300200320032903f002370320024020032802ec01450d0020032802e801102a0b200341206a41204101410041001003417f470d02200341f8036a41086a22024200370300200342003703f8030240200b4102490d00418aa7c3004121200341f8036a1008200341f0026a41086a2002290300370300200320032903f8033703f0024100210a200341003602f803200341f0026a4110200341f8036a10062102024020032802f8032207417f460d002002450d0020074104490d052002280000210a2002102a0b200341f8036a41086a22024200370300200342003703f803418aa7c3004121200341f8036a1008200341f0026a41086a2002290300370300200320032903f8033703f002200341003602f803200341f0026a4110200341f8036a100621020240024020032802f8032207417f460d002002450d00024020074104490d00200228000021072002102a200741016a21070c020b41c4d1c300413320034188056a419cd9c3001038000b410121070b200341f8036a41086a22024200370300200342003703f803418aa7c3004121200341f8036a1008200341f0026a41086a22082002290300370300200320032903f8033703f002200320073602f803200341f0026a4110200341f8036a4104100720024200370300200342003703f803419896c300411d200341f8036a100820082002290300370300200320032903f8033703f002200341003602f803200341f0026a4110200341f8036a1006210220032802f8032207417f460d062002450d06200320073602ec01200320023602e801200341f8036a200341e8016a106d20032802f8032208450d0520032902fc03210e02402007450d002002102a0b200320083602e8012003200e3702ec01200341206a41186a200341e0006a41186a290300370300200341206a41106a200341e0006a41106a290300370300200341206a41086a200341e0006a41086a29030037030020032003290360370320200341e8016a2107200e422088a72202200ea72208470d090c080b41fbefc200411b200341f8036a1008200341f0026a41086a2002290300370300200320032903f8033703f00241002102200341003602f803200341f0026a4110200341f8036a10062108024020032802f8032207417f460d00200320073602ec01200320083602e801200341f8036a200341e8016a106d20032802f803220a450d0720032902fc03210e02402007450d002008102a0b200e422088a72102200ea7450d00200a102a0b200341f8036a2009418801109a051a200341fc026a2002360200200341f0026a41086a4101360200200341003a00f402200341013a00f002200341e8016a200341f8036a200341f0026a10f40120032d00f001210220034185046a200341e0006a41086a2903003700002003418d046a200341f0006a29030037000020034195046a200341f8006a2903003700002003419d046a20024102463a0000200341043a00fc03200341063a00f803200320032903603700fd03200341f8036a21020c090b41c4d1c300413320034188056a419cd9c3001038000b411e41011037000b41cda6c3002107411f21080c0c0b41c4d1c300413320034188056a419cd9c3001038000b41c4d1c300413320034188056a419cd9c3001038000b41002102200341003602f001200342013703e801200341206a41186a200341e0006a41186a290300370300200341206a41106a200341e0006a41106a290300370300200341206a41086a200341e0006a41086a29030037030020032003290360370320200341e8016a21070c010b41c4d1c300413320034188056a419cd9c3001038000b200741046a28020022082002470d00200241016a22082002490d022002410174221e2008201e20084b1b220841ffffff3f712008470d022008410574221e4100480d020240024020020d00201e102821020c010b20072802002002410574201e102c21020b2002450d0320072002360200200741046a200836020020032802f00121020b2007280200221e2002410574221c6a22072003290320370000200741186a200341206a41186a290300370000200741106a200341206a41106a290300370000200741086a200341206a41086a2903003700002003200241016a22073602f001200341f8036a41086a221d4200370300200342003703f803419896c300411d200341f8036a1008200341f0026a41086a201d290300370300200320032903f8033703f0022003410036028004200342013703f8032007200341f8036a10b401024020072002490d00201c41206a2107201e210203402003200341f8036a3602202002200341206a10c801200241206a2102200741606a22070d000b0b20032802fc032102200341f0026a411020032802f8032207200328028004100702402002450d002007102a0b02402008450d00201e102a0b200341f8036a2009418801109a051a200341e8016a41186a200341e0006a41186a290300370300200341e8016a41106a200341e0006a41106a290300370300200341e8016a41086a200341e0006a41086a290300370300200320032903603703e801411e10282202450d03200241002900eca643370000200241166a4100290082a743370000200241106a41002900fca643370000200241086a41002900f4a6433700002003429e808080e00337020420032002360200200320033602f002200341e8016a200341f0026a10c8012003280200210220032802082107200341f0026a41186a22084200370300200341f0026a41106a221e4200370300200341f0026a41086a221d4200370300200342003703f00220022007200341f0026a1000200341206a41186a2008290300370300200341206a41106a201e290300370300200341206a41086a201d290300370300200320032903f00237032002402003280204450d002003280200102a0b200341003602f802200342013703f002200341f8036a200341f0026a10eb0120032802f4022102200341206a412020032802f002220720032802f802100702402002450d002007102a0b200341f8036a106a412010282202450d0420022003290340370000200241186a200341c0006a41186a290300370000200241106a200341c0006a41106a290300370000200241086a200341c0006a41086a29030037000020034184026a4100360200200341f4016a428180808010370200200342013702fc01200320023602f0012003200b3602ec012003200a3602e801200341f8036a41186a200341e0006a41186a290300370300200341f8036a41106a200341e0006a41106a290300370300200341f8036a41086a200341e0006a41086a290300370300200320032903603703f803411a10282207450d05200741002900b59643370000200741186a41002f00cd96433b0000200741106a41002900c59643370000200741086a41002900bd96433700002003429a808080a00337020420032007360200200320033602f002200341f8036a200341f0026a10c8012003280200210720032802082108200341f0026a41186a221e4200370300200341f0026a41106a221d4200370300200341f0026a41086a221c4200370300200342003703f00220072008200341f0026a1000200341206a41186a201e290300370300200341206a41106a201d290300370300200341206a41086a201c290300370300200320032903f00237032002402003280204450d002003280200102a0b200341203602fc032003200341206a3602f803200341e8016a200341f8036a10b4032002102a20034185046a200341c0006a41086a2903003700002003418d046a200341c0006a41106a29030037000020034195046a200341c0006a41186a2903003700002003419d046a2003290360370000200341a5046a200341e0006a41086a290300370000200341ad046a200341e0006a41106a290300370000200341b5046a200341e0006a41186a290300370000200341c4046a200b360200200341c0046a200a360200200341003a00fc03200341063a00f803200320032903403700fd03200341f8036a21020b4100210b4101210a41014100200210cc012009102a0c070b1031000b201e41011037000b411e41011037000b412041011037000b411a41011037000b2009106a2009102a4100210b4101210a0c040b200141046a280200210941b49fc60021074113210820022d00000d022002280001220a41ff01714101470d022003200a4118763a00622003200a4108763b01602003200241216a2d00003a007f2003200241196a2900003700772003200241116a29000037006f2003200241096a2900003700672003200241056a2800003600634200210e200341f8036a41086a22024200370300200342003703f80341fbefc200411b200341f8036a1008200341f0026a41086a2002290300370300200320032903f8033703f002200341003602f803200341f0026a4110200341f8036a100621080240024020032802f8032207417f460d00200320073602ec01200320083602e801200341f8036a200341e8016a106d20032802f8032202450d0320032902fc03210e2007450d012008102a0c010b410121020b2002200e422088a7200341e0006a10cd0121070240200ea7450d002002102a0b024020070d0041b8a6c3002107411521080c030b4100210a2003410036028004200342013703f8032009200341f8036a10eb0120032802fc032107200328028004210820032802f8032102200341f0026a41186a220b4200370300200341f0026a41106a221e4200370300200341f0026a41086a221d4200370300200342003703f00220022008200341f0026a1000200341e8016a41186a2208200b290300370300200341e8016a41106a221c201e290300370300200341e8016a41086a221e201d290300370300200320032903f0023703e80102402007450d002002102a0b200341f8036a2009418801109a051a200341f0026a410d6a200341e0006a41086a290300370000200341f0026a41156a200341e0006a41106a290300370000200341f0026a411d6a200341e0006a41186a2903003700004101210b200341013a00f402200320032903603700f502200341013a00f002200341c0006a200341f8036a200341f0026a10f40120032d00482102200341f8036a410d6a201e290300370000200341f8036a41156a201c290300370000200341f8036a411d6a20082903003700002003419d046a20024102463a0000200341053a00fc03200341063a00f803200320032903e8013700fd0341014100200341f8036a10cc012009102a0b41012109410021070c040b41c4d1c300413320034188056a419cd9c3001038000b2009106a2009102a4101210b4100210a0b410121090c010b410021094101210b410021070b02402004410771417f6a220241024b0d0002400240024020020e03000102000b2009450d02200141086a280200450d02200141046a280200102a0c020b200a450d01200141046a2802002202106a2002102a0c010b200b450d00200141086a2802002202106a2002102a0b200020083602042000200736020020034190056a24000bfad30106017f027e017f017e157f017e230041b0086b220324000240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024020012d00000e12000102030405060708090a0b0c0d0e0f1013000b200341ac066a41013602002003420137029c06200341ccd1c5003602980620034104360254200341c4d1c5003602502003200341d0006a3602a80620034198066a41d4d1c500103e000b200141106a2903002104200141086a2903002105200141046a28020021062002411a6a2901002107200241196a2d00002108200241186a2d00002109200241166a2f0100210a200241156a2d0000210b200241146a2d0000210c200241126a2f0100210d200241116a2d0000210e200241106a2d0000210f2002410e6a2f010021102002410d6a2d000021112002410c6a2d000021122002410a6a2f01002113200241096a2d00002114200241046a2d00002115200241026a2f0100211602400240024020022d0000450d002003200737029c06200320083a009b06200320093a009a062003200a3b0198060c010b200241086a2d00002117200241066a2f01002118200241056a2d0000211920022d0001211a200320073703980641002102201a41ff01714101460d010b410121024104211941002117410021180b20032007370348200320083a0047200320093a00462003200a3b01442003200b3a00432003200c3a00422003200d3b01402003200e3a003f2003200f3a003e200320103b013c200320113a003b200320123a003a200320133b0138200320143a0037200320153a0032200320163b01302003201841ffff0371410874201741187472201941ff017172220a36003302402002450d00410f210841ea9fc6002109024002400240024002400240200a0e0700010203040565000b20032800372109200328003b21080c640b410e210841dc9fc60021090c630b410c210841d09fc60021090c620b4109210841c79fc60021090c610b4113210841b49fc60021090c600b4111210841a39fc60021090c5f0b200341b8036a41186a200341306a41186a290300370300200341b8036a41106a200341306a41106a290300370300200341b8036a41086a200341306a41086a290300370300200320032903303703b8030240200542808084fea6dee1115441002004501b450d0041e4d1c5002109410d21080c5f0b2003200341b8036a2005200410830202402003280200450d0041f1d1c5002109411a21080c5f0b20034188086a41086a220242003703002003420037038808419090c600411920034188086a1008200341e8076a41086a200229030037030020032003290388083703e807410021082003410036029806200341e8076a411020034198066a1006210202402003280298062209417f460d002002450d0020094104490d18200228000021082002102a0b20034188086a41086a220942003703002003420037038808419090c600411920034188086a1008200341e8076a41086a220a200929030037030020032003290388083703e8072003200841016a36029806200341e8076a411020034198066a41041007412010282202450d18200220032903b803370000200341ac066a428180808010370200200241186a200341b8036a41186a2217290300370000200241106a200341b8036a41106a2218290300370000200241086a200341b8036a41086a22192903003700002003200537039806200320023602a806200320043703a006200820034198066a10c404200341a0026a200610cf03200341d0006a200341a0026a418801109a051a200341e4016a2019290300370200200341ec016a2018290300370200200341f4016a2017290300370200200320083602d801200320032903b8033702dc0120094200370300200342003703880841ac89c500411520034188086a1008200a200929030037030020032003290388083703e8072003410036029806200341e8076a411020034198066a10062109024002402003280298062202417f460d002002210a20090d010b200341003602a0062003420137039806410020034198066a10b40120032802a0062102200328029c06210a20032802980621090b200320023602d0072003200a3602cc07200320093602c807024002402002450d0020034198066a20092002410110d6022003280298064101470d0120032802cc07450d5d20032802c807102a0c5d0b4101200341c8076a10b40120032802d801210a0240024020032802cc07220920032802d00722026b4104490d0020032802c80721090c010b200241046a22172002490d4b200941017422022017200220174b1b22024100480d4b0240024020090d002002102821090c010b20032802c80720092002102c21090b2009450d1b200320023602cc07200320093602c80720032802d00721020b2003200241046a3602d007200920026a200a360000200341d0006a200341c8076a10eb01200341dc016a200341c8076a108f010c5a0b200328029c0621170240200341a4066a2802002202200341a0066a2802002209460d0020032802d007200220096b6a220a41b0016a2218417f4c0d1b0240024020180d00410121190c010b201810282219450d1d0b2003201836028c0820032019360288082003200a36029008200320034188086a36029806201720034198066a200210d701200a2002490d1d2003280290082217200a490d1e20032802d00722172009490d1f200328028808211820032802c80721192003200a20026b220a3602302003201720096b221736028002200a2017470d20201820026a201920096a200a109a051a20032802d801210a02400240200328028c08220920032802900822026b4104490d0020032802880821090c010b200241046a22172002490d4b200941017422022017200220174b1b22024100480d4b0240024020090d002002102821090c010b20032802880820092002102c21090b2009450d222003200236028c08200320093602880820032802900821020b2003200241046a36029008200920026a200a360000200341d0006a20034188086a10eb01200341dc016a20034188086a108f012003280290082109200328028c08210a200328028808210220032802cc07450d5b20032802c807102a0c5b0b2003200341c8076a36029806201720034198066a200910d70120032802d801210a0240024020032802cc07220920032802d00722026b4104490d0020032802c80721090c010b200241046a22172002490d4a200941017422022017200220174b1b22024100480d4a0240024020090d002002102821090c010b20032802c80720092002102c21090b2009450d22200320023602cc07200320093602c80720032802d00721020b2003200241046a3602d007200920026a200a360000200341d0006a200341c8076a10eb01200341dc016a200341c8076a108f010c590b200141046a28020021162002411a6a2901002107200241196a2d00002108200241186a2d00002109200241166a2f0100210a200241156a2d00002119200241146a2d0000210b200241126a2f0100210c200241116a2d0000210d200241106a2d0000210e2002410e6a2f0100210f2002410d6a2d000021102002410c6a2d000021112002410a6a2f01002112200241096a2d00002113200241046a2d00002114200241026a2f0100211502400240024020022d0000450d002003200737029c06200320083a009b06200320093a009a062003200a3b0198060c010b200241086a2d00002117200241066a2f01002106200241056a2d0000211820022d0001211a200320073703980641002102201a41ff01714101460d010b410121024104211841002117410021060b2003200737039802200320083a009702200320093a0096022003200a3b019402200320193a0093022003200b3a0092022003200c3b0190022003200d3a008f022003200e3a008e022003200f3b018c02200320103a008b02200320113a008a02200320123b018802200320133a008702200320143a008202200320153b0180022003200641ffff0371410874201741187472201841ff017172220a3600830202402002450d00410f210841ea9fc6002109200a0e070f1213141555560f0b200341d0006a41186a20034180026a41186a290300370300200341d0006a41106a20034180026a41106a290300370300200341d0006a41086a20034180026a41086a290300370300200320032903800237035020034198066a201610b804024020032802a80622170d00418bd2c5002109412421084101210a0c570b200341b4066a280200210920034198066a41186a280200210820032802ac062102200341086a200341d0006a200329029c062207422086200335029806842204200341a4066a350200422086200742208884220710830220032802080d53200341306a41186a200341d0006a41186a290300370300200341306a41106a220a200341d0006a41106a290300370300200341306a41086a2218200341d0006a41086a29030037030020032003290350370330024020082002460d0020022106200821020c520b200241016a22062002490d48200241017422192006201920064b1b220641ffffff3f712006470d48200641057422194100480d480240024020020d002019102821170c010b201720024105742019102c21170b20170d51201941011037000b200141026a2d00002116200141046a280200211a20012d0001211b2002411a6a2901002107200241196a2d00002108200241186a2d00002109200241166a2f0100210a200241156a2d00002119200241146a2d0000210b200241126a2f0100210c200241116a2d0000210d200241106a2d0000210e2002410e6a2f0100210f2002410d6a2d000021102002410c6a2d000021112002410a6a2f01002112200241096a2d00002113200241046a2d00002114200241026a2f0100211502400240024020022d0000450d002003200737029c06200320083a009b06200320093a009a062003200a3b0198060c010b200241086a2d00002117200241066a2f01002106200241056a2d0000211820022d0001211c200320073703980641002102201c41ff01714101460d010b410121024104211841002117410021060b20032007370348200320083a0047200320093a00462003200a3b0144200320193a00432003200b3a00422003200c3b01402003200d3a003f2003200e3a003e2003200f3b013c200320103a003b200320113a003a200320123b0138200320133a0037200320143a0032200320153b01302003200641ffff0371410874201741187472201841ff017172220a36003302402002450d00410f210841ea9fc60021090240200a0e0700121314155556000b20032800372109200328003b21084101210a0c560b20034180026a41186a200341306a41186a290300220737030020034180026a41106a200341306a41106a290300220437030020034180026a41086a200341306a41086a290300220537030020032003290330221d3703800220034198066a41186a200737030020034198066a41106a200437030020034198066a41086a20053703002003201d3703980620034198066a201a201b41ff0171410047201610c50421090c4f0b200141026a2d00002116200141046a280200211a20012d0001211b2002411a6a2901002107200241196a2d00002108200241186a2d00002109200241166a2f0100210a200241156a2d00002119200241146a2d0000210b200241126a2f0100210c200241116a2d0000210d200241106a2d0000210e2002410e6a2f0100210f2002410d6a2d000021102002410c6a2d000021112002410a6a2f01002112200241096a2d00002113200241046a2d00002114200241026a2f0100211502400240024020022d0000450d002003200737029c06200320083a009b06200320093a009a062003200a3b0198060c010b200241086a2d00002117200241066a2f01002106200241056a2d0000211820022d0001211c200320073703980641002102201c41ff01714101460d010b410121024104211841002117410021060b2003200737039802200320083a009702200320093a0096022003200a3b019402200320193a0093022003200b3a0092022003200c3b0190022003200d3a008f022003200e3a008e022003200f3b018c02200320103a008b02200320113a008a02200320123b018802200320133a008702200320143a008202200320153b0180022003200641ffff0371410874201741187472201841ff017172220a3600830202402002450d00410f210841ea9fc6002109200a0e070d1011121353540d0b200341d0006a41186a20034180026a41186a290300370300200341d0006a41106a20034180026a41106a290300370300200341d0006a41086a20034180026a41086a2903003703002003200329038002370350410f10282202450d1f200241002900c9d245370000200241076a41002900d0d2453700002003428f808080f00137029c062003200236029806200341d0006a20034198066a108f0120032802a00621022003280298062108200341a0026a41186a22094200370300200341a0026a41106a220a4200370300200341a0026a41086a22174200370300200342003703a00220082002200341a0026a1000200341306a41186a2009290300370300200341306a41106a200a290300370300200341306a41086a2017290300370300200320032903a0023703300240200328029c06450d00200328029806102a0b20034198066a200341306a412010fd01200341e8046a41026a220a20032d009b063a0000200341e8076a41086a200341ac066a290200370300200341e8076a410d6a2217200341b1066a290000370000200320032f0099063b01e8042003200341a4066a2902003703e807410121020240024020032d0098064101460d00410b210841d8d2c50021090c010b20034198066a41086a2802002108200328029c062109200341c0046a41026a200a2d00003a000020034188056a41086a200341e8076a41086a29030037030020034188056a410d6a2017290000370000200320032f01e8043b01c004200320032903e80737038805410021020b200341106a41026a200341c0046a41026a2d00003a000020034188086a41086a220a20034188056a41086a29030037030020034188086a41106a20034188056a41106a290300370300200320032f01c0043b011020032003290388053703880820020d53200341d0056a41026a200341106a41026a2d000022023a0000200341b8036a41086a2217200a290300370300200341b8036a410d6a220a20034188086a410d6a290000370000200320032f011022063b01d00520032003290388083703b803200341ab066a2017290300370000200341b0066a200a290000370000200320023a009a06200320063b0198062003200836009f062003200936009b06200320032903b8033700a30620034198066a201a201b41ff0171410047201610c50421090c4e0b41a6f5c5002109410e210820022d0000417f6a221941024b0d52200141046a280200210b4101210a4101210641012118410121170240024020190e03005d01000b200241046a2d00000d534101210a410121064101211841012117200241086a28020041036c2002410c6a280200410174490d5c0b20034198066a200b10ca03024020032802980622024113470d0041f3d4c5002109410d21084101210a0c540b200341a0026a20034198066a410472419401109a051a20032002360250200341d0006a410472200341a0026a419401109a051a200341003602a0062003420137039806200341d0006a20034198066a10eb01200328029c06210820032802a00621092003280298062102200341a0026a41186a220a4200370300200341a0026a41106a22174200370300200341a0026a41086a22064200370300200342003703a00220022009200341a0026a1000200341b8036a41186a2209200a290300370300200341b8036a41106a220a2017290300370300200341b8036a41086a22172006290300370300200320032903a0023703b80302402008450d002002102a0b20034198066a41186a200929030037030020034198066a41106a200a29030037030020034198066a41086a2017290300370300200320032903b80337039806411710282202450d1f200241002900e3d2453700002002410f6a41002900f2d245370000200241086a41002900ebd24537000020034297808080f0023702d405200320023602d0052003200341d0056a3602a00220034198066a200341a0026a10c80120032802d005210220032802d8052108200341a0026a41186a22094200370300200341a0026a41106a220a4200370300200341a0026a41086a22174200370300200342003703a00220022008200341a0026a1000200341306a41186a2009290300370300200341306a41106a200a290300370300200341306a41086a2017290300370300200320032903a002370330024020032802d405450d0020032802d005102a0b4101210a200341306a41204101410041001003417f460d4c200341d0006a106a4180d5c5002109412521080c530b200141046a280200210a41a6f5c5002109410e210820022d0000417f6a221741024b0d4a0240024020170e03004c01000b200241086a2802004101742002410c6a280200490d4b200241046a28020041ff01710d4b0b20034188086a41086a22024200370300200342003703880841988bc500411620034188086a1008200341e8076a41086a200229030037030020032003290388083703e8070240200341e8076a41104101410041001003417f460d004194d3c5002109411521080c4b0b200341003602a0062003420137039806200a20034198066a10eb01200328029c06210820032802a00621092003280298062102200341a0026a41186a22174200370300200341a0026a41106a22064200370300200341a0026a41086a22184200370300200342003703a00220022009200341a0026a1000200341d0006a41186a22092017290300370300200341d0006a41106a2006290300370300200341d0006a41086a2018290300370300200320032903a00237035002402008450d002002102a0b20034198066a41186a200929030037030020034198066a41106a200341d0006a41106a29030037030020034198066a41086a200341d0006a41086a2903003703002003200329035037039806411310282202450d1f200241002900a9d3453700002002410f6a41002800b8d345360000200241086a41002900b1d34537000020034293808080b0023702d405200320023602d0052003200341d0056a3602a00220034198066a200341a0026a10c80120032802d005210220032802d8052108200341a0026a41186a22094200370300200341a0026a41106a22174200370300200341a0026a41086a22064200370300200342003703a00220022008200341a0026a1000200341306a41186a2009290300370300200341306a41106a2017290300370300200341306a41086a2006290300370300200320032903a002370330024020032802d405450d0020032802d005102a0b200341b8036a200341306a10e103024020032802bc032202450d0020032802b803210820032802c0032109109801211702402009450d002002102a0b201720084f0d0041fad2c5002109411a21080c4b0b20034198066a200a418801109b051a200341003a00a00720034188086a41086a22024200370300200342003703880841988bc500411620034188086a1008200341e8076a41086a200229030037030020032003290388083703e807200341003602a802200342013703a00220034198066a200341a0026a10eb01024020032d00a007220241024b0d00024002400240024020020e03000102000b410021080c020b410121080c010b410221080b200320083a00a8080240024020032802a40220032802a8022202460d0020032802a00221090c010b200241016a22082002490d46200241017422092008200920084b1b22084100480d460240024020020d002008102821090c010b20032802a00220022008102c21090b2009450d22200320083602a402200320093602a00220032d00a808210820032802a80221020b2003200241016a3602a802200920026a20083a00000b20032802a4022102200341e8076a411020032802a002220820032802a802100702402002450d002008102a0b20034198066a106a200a102a4100210a410121060c480b200141046a28020021080240024020022d0000417f6a220941024b0d00024020090e03000102000b200241046a2d00000d00200241086a2802004102742002410c6a28020041036c4f0d010b2008106a2008102a41a6f5c5002109410e2108410021064101210a410121180c530b20034198066a2008418801109a051a200341023a00a00720034188086a41086a22024200370300200342003703880841988bc500411620034188086a1008200341e8076a41086a200229030037030020032003290388083703e807200341003602582003420137035020034198066a200341d0006a10eb01024020032d00a007220241024b0d00024002400240024020020e03000102000b410021090c020b410121090c010b410221090b200320093a00a80802400240200328025420032802582202460d002003280250210a0c010b200241016a22092002490d452002410174220a2009200a20094b1b22094100480d450240024020020d0020091028210a0c010b200328025020022009102c210a0b200a450d22200320093602542003200a36025020032d00a8082109200328025821020b2003200241016a360258200a20026a20093a00000b20032802542102200341e8076a4110200328025022092003280258100702402002450d002009102a0b20034198066a106a2008102a410021064101210a0c470b200141046a28020021080240024020022d0000417f6a220941024b0d00024020090e03000102000b200241086a2802002002410c6a280200490d00200241046a28020041ff0171450d010b2008106a2008102a41a6f5c5002109410e2108410021184101210a410121060c520b20034198066a2008418801109a051a200341013a00a00720034188086a41086a22024200370300200342003703880841988bc500411620034188086a1008200341e8076a41086a200229030037030020032003290388083703e807200341003602582003420137035020034198066a200341d0006a10eb01024020032d00a007220241024b0d00024002400240024020020e03000102000b410021090c020b410121090c010b410221090b200320093a00a80802400240200328025420032802582202460d002003280250210a0c010b200241016a22092002490d442002410174220a2009200a20094b1b22094100480d440240024020020d0020091028210a0c010b200328025020022009102c210a0b200a450d22200320093602542003200a36025020032d00a8082109200328025821020b2003200241016a360258200a20026a20093a00000b20032802542102200341e8076a4110200328025022092003280258100702402002450d002009102a0b20034198066a106a2008102a410021184101210a410121060c470b200141286a2802002118200141246a2802002106200341e8056a200141196a290000370300200341e0056a200141116a290000370300200341d0056a41086a200141096a290000370300200320012900013703d0054101210a41a6f5c5002109410e210820022d0000417e6a221741014b0d4f0240024020170e020001000b200241046a2d00000d50200241086a28020041036c2002410c6a280200410174490d500b20034188086a41086a22024200370300200342003703880841988bc500411620034188086a1008200341e8076a41086a200229030037030020032003290388083703e80720034198066a200341e8076a10df032003280298062102200341a0026a20034198066a410472418401109a051a200320032800a107360288082003200341a4076a28000036008b08024020024113470d0041f2d3c5002109411021080c500b200341a0076a2d00002108200341b8036a200341a0026a418401109a051a20032002360250200341d0006a410472200341b8036a418401109a051a200841ff01710d4341c8d3c5002109412a21080c440b200341a0056a200141196a29000037030020034188056a41106a200141116a29000037030020034188056a41086a200141096a2900003703002003200129000137038805200241216a2f0000200241236a2d00004110747221082002411d6a2f00002002411f6a2d00004110747221092002410d6a2f00002002410f6a2d000041107472210a200241096a2f00002002410b6a2d0000411074722117200241056a2f0000200241076a2d0000411074722106200241206a2d0000210b200241106a2d0000210c2002410c6a2d0000210d200241086a2d0000210e0240024020022d00004102460d00410121180c010b200241246a2802002119200241116a2900002107200241046a2d0000210f2003200241196a2800003602a0062003200737039806410121180240200f4101460d000c010b2007421888a7210f2007a7210241002118200329029c0621070b200320083b019c022003419e026a20084110763a0000200320093b0198022003419a026a20094110763a0000200320023b018c02410e210820034180026a410e6a20024110763a00002003200a3b0188022003418a026a200a4110763a0000200320193a009f022003200b3a009b0220032007370390022003200f3a008f022003200c3a008b022003200d3a0087022003200e3a008302200320173b018402200320174110763a008602200320063b018002200320064110763a00820202402018450d0041a6f5c50021094101210a0c4f0b200341d0056a41186a20034180026a41186a290300370300200341d0056a41106a20034180026a41106a290300370300200341d0056a41086a20034180026a41086a29030037030020032003290380023703d00520034188086a41086a22024200370300200342003703880841988bc500411620034188086a1008200341e8076a41086a200229030037030020032003290388083703e80720034198066a200341e8076a10df032003280298062102200341a0026a20034198066a4104722208418401109a051a2003200341a4076a28000036008b08200320032800a10736028808024020024113460d00200341d0006a200341a0026a418401109a051a20032002360298062008200341d0006a418401109a051a200341003602a802200342013703a00220034198066a200341a0026a10eb0120032802a402210820032802a802210920032802a0022102200341a0026a41186a220a4200370300200341a0026a41106a22174200370300200341a0026a41086a22064200370300200342003703a00220022009200341a0026a1000200341b8036a41186a200a290300370300200341b8036a41106a2017290300370300200341b8036a41086a2006290300370300200320032903a0023703b80302402008450d002002102a0b20034188056a200341b8036a4120109c05210220034198066a106a02402002450d00411021084182d4c50021094101210a0c500b411310282202450d20200241002900a9d3453700002002410f6a41002800b8d345360000200241086a41002900b1d34537000020034293808080b002370254200320023602502003200341d0006a3602a00220034188056a200341a0026a10c8012003280250210220032802582108200341a0026a41186a22094200370300200341a0026a41106a220a4200370300200341a0026a41086a22174200370300200342003703a00220022008200341a0026a1000200341306a41186a2009290300370300200341306a41106a200a290300370300200341306a41086a2017290300370300200320032903a00237033002402003280254450d002003280250102a0b20034198066a200341306a10e103200328029c0622170d374101211741002118410021190c380b411421084192d4c50021094101210a0c4e0b4101210a20022d000120022d0000720d34200141046a28020010ce03410021090c490b4101210a20022d000120022d0000720d332001410c6a2802002119200141086a2802002108200141046a2802002109411710282202450d1e2002410f6a41002900918945370000200241086a410029008a894537000020024100290082894537000020024117412e102c2202450d1f2002200936001742002107200341a0026a41186a22174200370300200341a0026a41106a22064200370300200341a0026a41086a22184200370300200342003703a0022002411b200341a0026a1000200341306a41186a2017290300370300200341306a41106a2006290300370300200341306a41086a2018290300370300200320032903a0023703302002102a2003410036029806200341306a412020034198066a10062102024002402003280298062206417f470d00410821170c010b024020020d00410821170c010b200320063602542003200236025020034198066a200341d0006a1080012003280298062217450d21200329029c0621072006450d002002102a0b2007422088a721020240024002400240201720084190016c6a2206450d00200820024f0d0020062802004113460d01201720084190016c6a22084188016a2802002019470d012006106a20064113360200200841046a200341a0026a418401109a051a2008418c016a2003418b086a28000036000020084189016a200328008808360000411710282208450d252008410f6a41002900918945370000200841086a410029008a894537000020084100290082894537000020084117412e102c2208450d2620082009360017200341a0026a41186a22094200370300200341a0026a41106a22064200370300200341a0026a41086a22184200370300200342003703a0022008411b200341a0026a1000200341306a41186a2009290300370300200341306a41106a2006290300370300200341306a41086a2018290300370300200320032903a0023703302008102a20034198066a2017200210ac02200341306a4120200328029806220820032802a00610070240200328029c06450d002008102a0b20024190016c2108201721020340024020022802004113460d002002106a0b20024190016a2102200841f07e6a22080d000b410021092007a70d030c4c0b2002450d010b20024190016c2108201721020340024020022802004113460d002002106a0b20024190016a2102200841f07e6a22080d000b0b41a5d5c5002109411221082007a7450d4d2017102a0c4d0b2017102a0c480b200341b8036a41186a200141196a290000370300200341b8036a41106a200141116a290000370300200341b8036a41086a200141096a290000370300200320012900013703b8032002411a6a2901002107200241196a2d00002108200241186a2d00002109200241166a2f0100210a200241156a2d00002119200241146a2d0000210b200241126a2f0100210c200241116a2d0000210d200241106a2d0000210e2002410e6a2f0100210f2002410d6a2d000021102002410c6a2d000021112002410a6a2f01002112200241096a2d00002113200241046a2d00002114200241026a2f0100211502400240024020022d0000450d002003200737029c06200320083a009b06200320093a009a062003200a3b0198060c010b200241086a2d00002117200241066a2f01002106200241056a2d0000211820022d00012116200320073703980641002102201641ff01714101460d010b410121024100210641042118410021170b2003200737039802200320083a009702200320093a0096022003200a3b019402200320193a0093022003200b3a0092022003200c3b0190022003200d3a008f022003200e3a008e022003200f3b018c02200320103a008b02200320113a008a02200320123b018802200320133a008702200320143a008202200320153b0180022003200641ffff0371410874201841ff017172201741187472220a3600830202402002450d00410f210841ea9fc6002109200a0e07040708090a4a4b040b200341c0046a41186a20034180026a41186a290300370300200341c0046a41106a20034180026a41106a290300370300200341c0046a41086a20034180026a41086a29030037030020032003290380023703c004410f10282202450d22200241002900c9d245370000200241076a41002900d0d2453700002003428f808080f00137029c062003200236029806200341b8036a20034198066a108f0120032802a00621022003280298062108200341a0026a41186a22094200370300200341a0026a41106a220a4200370300200341a0026a41086a22174200370300200342003703a00220082002200341a0026a1000200341306a41186a2009290300370300200341306a41106a200a290300370300200341306a41086a2017290300370300200320032903a0023703300240200328029c06450d00200328029806102a0b0240200341306a41204101410041001003417f460d0041ccd4c5002109410f21084101210a0c4c0b200341d0006a41186a200341c0046a41186a290300370300200341d0006a41106a200341c0046a41106a290300370300200341d0006a41086a200341c0046a41086a290300370300200320032903c00437035020034198066a41186a200341b8036a41186a29030037030020034198066a41106a200341b8036a41106a29030037030020034198066a41086a200341b8036a41086a290300370300200320032903b80337039806410f10282202450d2341002109200241002900c9d245370000200241076a41002900d0d2453700002003428f808080f0013702d405200320023602d00520034198066a200341d0056a108f0120032802d805210220032802d0052108200341a0026a41186a220a4200370300200341a0026a41106a22174200370300200341a0026a41086a22064200370300200342003703a00220082002200341a0026a1000200341306a41186a200a290300370300200341306a41106a2017290300370300200341306a41086a2006290300370300200320032903a002370330024020032802d405450d0020032802d005102a0b2003412036029c062003200341306a36029806200341d0006a20034198066a10ff014101210a0c4b0b2002411a6a2901002107200241196a2d00002108200241186a2d00002109200241166a2f0100210a200241156a2d00002119200241146a2d0000210b200241126a2f0100210c200241116a2d0000210d200241106a2d0000210e2002410e6a2f0100210f2002410d6a2d000021102002410c6a2d000021112002410a6a2f01002112200241096a2d00002113200241046a2d00002114200241026a2f0100211502400240024020022d0000450d002003200737029c06200320083a009b06200320093a009a062003200a3b0198060c010b200241086a2d00002117200241066a2f01002106200241056a2d0000211820022d00012116200320073703980641002102201641ff01714101460d010b410121024100210641042118410021170b2003200737039802200320083a009702200320093a0096022003200a3b019402200320193a0093022003200b3a0092022003200c3b0190022003200d3a008f022003200e3a008e022003200f3b018c02200320103a008b02200320113a008a02200320123b018802200320133a008702200320143a008202200320153b0180022003200641ffff0371410874201841ff017172201741187472220a3600830202402002450d00410f210841ea9fc6002109200a0e070306070809494a030b200341c0046a41186a20034180026a41186a2903002207370300200341c0046a41106a20034180026a41106a2903002204370300200341c0046a41086a20034180026a41086a29030022053703002003200329038002221d3703c00420034198066a41186a200737030020034198066a41106a200437030020034198066a41086a20053703002003201d37039806410f10282202450d2341002109200241002900c9d245370000200241076a41002900d0d2453700002003428f808080f0013702542003200236025020034198066a200341d0006a108f012003280258210220032802502108200341a0026a41186a220a4200370300200341a0026a41106a22174200370300200341a0026a41086a22064200370300200342003703a00220082002200341a0026a1000200341306a41186a200a290300370300200341306a41106a2017290300370300200341306a41086a2006290300370300200320032903a00237033002402003280254450d002003280250102a0b200341306a412010094101210a0c460b200341d0056a41186a200141196a290000370300200341d0056a41106a200141116a290000370300200341d0056a41086a200141096a290000370300200320012900013703d0052002411a6a2901002107200241196a2d00002108200241186a2d00002109200241166a2f0100210a200241156a2d00002119200241146a2d0000210b200241126a2f0100210c200241116a2d0000210d200241106a2d0000210e2002410e6a2f0100210f2002410d6a2d000021102002410c6a2d000021112002410a6a2f01002112200241096a2d00002113200241046a2d00002114200241026a2f0100211502400240024020022d0000450d002003200737029c06200320083a009b06200320093a009a062003200a3b0198060c010b200241086a2d00002117200241066a2f01002106200241056a2d0000211820022d00012116200320073703980641002102201641ff01714101460d010b410121024100210641042118410021170b200320073703d804200320083a00d704200320093a00d6042003200a3b01d404200320193a00d3042003200b3a00d2042003200c3b01d0042003200d3a00cf042003200e3a00ce042003200f3b01cc04200320103a00cb04200320113a00ca04200320123b01c804200320133a00c704200320143a00c204200320153b01c0042003200641ffff0371410874201841ff017172201741187472220a3600c30402402002450d00410f210841ea9fc60021090240200a0e070006070809494a000b20032800c704210920032800cb0421084101210a0c4a0b200341b8036a41186a200341c0046a41186a290300370300200341b8036a41106a200341c0046a41106a290300370300200341b8036a41086a200341c0046a41086a290300370300200320032903c0043703b803410f10282202450d23200241002900c9d245370000200241076a41002900d0d2453700002003428f808080f0013702cc07200320023602c807200341d0056a200341c8076a108f0120032802d007210220032802c8072108200341a0026a41186a22094200370300200341a0026a41106a220a4200370300200341a0026a41086a22174200370300200342003703a00220082002200341a0026a1000200341306a41186a2009290300370300200341306a41106a200a290300370300200341306a41086a2017290300370300200320032903a002370330024020032802cc07450d0020032802c807102a0b20034198066a200341306a412010fd0120034180026a41086a200341a1066a29000037030020034190026a200341a9066a29000037030020034180026a41186a200341b1066a290000370300200320032900990637038002410121020240024020032d0098064101460d00410b210841d8d2c50021090c010b200341e8046a41026a20032d00820222023a0000200341e8076a41086a220a20034193026a290000370300200341e8076a410d6a221720034198026a290000370000200341c0046a41026a20023a0000200320032f01800222023b01e8042003200329008b0222073703e807200320023b01c0042003280083022109200328008702210820034188056a410d6a201729000037000020034188056a41086a200a2903003703002003200737038805410021020b200341106a41026a220a200341c0046a41026a2d00003a000020034188086a41086a221720034188056a41086a29030037030020034188086a41106a20034188056a41106a290300370300200320032f01c0043b011020032003290388053703880820020d48200341e3006a2017290300370000200341d0006a41186a20034195086a290000370000200320032f01103b01502003200836005720032009360053200320032903880837005b2003200a2d00003a00520240200341d0006a200341b8036a4120109c05450d0041dbd4c5002109410b21084101210a0c4a0b20034198066a41186a200341d0056a41186a29030037030020034198066a41106a200341d0056a41106a29030037030020034198066a41086a200341d0056a41086a290300370300200320032903d00537039806410f10282202450d2441002109200241002900c9d245370000200241076a41002900d0d2453700002003428f808080f0013702542003200236025020034198066a200341d0006a108f012003280258210220032802502108200341a0026a41186a220a4200370300200341a0026a41106a22174200370300200341a0026a41086a22064200370300200342003703a00220082002200341a0026a100020034180026a41186a200a29030037030020034180026a41106a201729030037030020034180026a41086a2006290300370300200320032903a0023703800202402003280254450d002003280250102a0b20034180026a412010094101210a0c490b200141216a2d00002116200341106a41186a200141196a290000370300200341106a41106a200141116a290000370300200341106a41086a200141096a290000370300200320012900013703102002411a6a2901002107200241196a2d00002108200241186a2d00002109200241166a2f0100210a200241156a2d00002119200241146a2d0000210b200241126a2f0100210c200241116a2d0000210d200241106a2d0000210e2002410e6a2f0100210f2002410d6a2d000021102002410c6a2d000021112002410a6a2f01002112200241096a2d00002113200241046a2d00002114200241026a2f0100211502400240024020022d0000450d002003200737029c06200320083a009b06200320093a009a062003200a3b0198060c010b200241086a2d00002117200241066a2f01002106200241056a2d0000211820022d0001211a200320073703980641002102201a41ff01714101460d010b410121024100210641042118410021170b2003200737039802200320083a009702200320093a0096022003200a3b019402200320193a0093022003200b3a0092022003200c3b0190022003200d3a008f022003200e3a008e022003200f3b018c02200320103a008b02200320113a008a02200320123b018802200320133a008702200320143a008202200320153b0180022003200641ffff0371410874201841ff017172201741187472220a360083022002450d01410f210841ea9fc6002109200a0e0700030405064647000b2003280087022109200328008b0221084101210a0c470b200341c0046a41186a20034180026a41186a2903002207370300200341c0046a41106a20034180026a41106a2903002204370300200341c0046a41086a20034180026a41086a29030022053703002003200329038002221d3703c004200341e8046a41186a2007370300200341e8046a41106a2004370300200341e8046a41086a20053703002003201d3703e80420034188056a41186a200341106a41186a29030037030020034188056a41106a200341106a41106a29030037030020034188056a41086a200341106a41086a2903003703002003200329031037038805200320163a00a805411510282202450d22200241002900d088453700002002410d6a41002900dd8845370000200241086a41002900d8884537000020034295808080d00237029c062003200236029806200341e8046a20034198066a108f0120032802a00621022003280298062108200341a0026a41186a22094200370300200341a0026a41106a220a4200370300200341a0026a41086a22174200370300200342003703a00220082002200341a0026a1000200341306a41186a2009290300370300200341306a41106a200a290300370300200341306a41086a2017290300370300200320032903a0023703300240200328029c06450d00200328029806102a0b2003410036029806200341306a412020034198066a1006210202400240200328029806220a417f460d002002450d002003200a3602bc03200320023602b80320034198066a200341b8036a10b10120032d00b90622084102460d25200341d0006a41186a2217200341d2066a290100370300200341d0006a41106a2206200341ca066a290100370300200341d0006a41086a2218200341c2066a290100370300200341a0026a41086a2219200341e3066a290000370300200341a0026a41106a220b200341eb066a290000370300200341a0026a41186a220c200341f3066a290000370300200320032901ba063703502003200341db066a2900003703a002200341da066a2d000021090240200a450d002002102a0b200341b8036a41186a2017290300370300200341b8036a41106a2006290300370300200341b8036a41086a201829030037030020034188086a41086a201929030037030020034188086a41106a200b29030037030020034188086a41186a200c290300370300200320032903503703b803200320032903a002370388080c010b200341a0026a41186a22024200370300200341a0026a41106a22084200370300200341a0026a41086a22094200370300200342003703a00241e588c500411d200341a0026a100020034198066a41186a220a200229030037030020034198066a41106a2217200829030037030020034198066a41086a22062009290300370300200320032903a00237039806200341d0056a20034198066a412010fd010240024020032d00d0050d00200242003703002008420037030020094200370300200342003703a00241e588c500411d200341a0026a1000200a20022903003703002017200829030037030020062009290300370300200320032903a0023703980620034120360254200320034198066a360250200341e8046a200341d0006a10ff01410021090c010b200341c8076a41186a200341e9056a290000370300200341c8076a41106a200341e1056a290000370300200341c8076a41086a200341d9056a290000370300200320032900d1053703c807200341e8076a200341c8076a10b0012003410036029806200341e8076a412020034198066a100621022003280298062208417f460d272002450d27200320083602542003200236025020034198066a200341d0006a10b10120032d00b906220a4102460d2620034188086a41186a220920034198066a41186a29030037030020034188086a41106a221720034198066a41106a29030037030020034188086a41086a220620034198066a41086a29030037030020032003290398063703880820032d00b8062118200341a0026a200341ba066a221941c100109a051a02402008450d002002102a0b200341d0006a41186a22022009290300370300200341d0006a41106a22082017290300370300200341d0006a41086a220920062903003703002003200329038808370350200341b8036a200341a0026a41c100109a051a200341a0026a41186a22172002290300370300200341a0026a41106a22062008290300370300200341a0026a41086a220b2009290300370300200320032903503703a0022003200a3a00980620034198066a410172200341b8036a41c100109a051a20022017290300370300200820062903003703002009200b290300370300200341f8006a2019410020032d00b9064101461b360200200320032903a002370350200320183a00702003200341e8046a360274200341003602c003200342013703b803200341d0006a200341b8036a108f01024020032d0070220241064b0d000240024002400240024002400240024020020e0700010203040506000b410021080c060b410121080c050b410221080c040b410321080c030b410421080c020b410521080c010b410621080b200320083a00a8080240024020032802bc0320032802c0032202460d0020032802b80321090c010b200241016a22082002490d3c200241017422092008200920084b1b22084100480d3c0240024020020d002008102821090c010b20032802b80320022008102c21090b2009450d2a200320083602bc03200320093602b80320032d00a808210820032802c00321020b2003200241016a3602c003200920026a20083a00000b200341f4006a200341b8036a10aa0120032802bc032102200341e8076a412020032802b803220820032802c003100702402002450d002008102a0b200341a0026a41186a22024200370300200341a0026a41106a22084200370300200341a0026a41086a22094200370300200342003703a00241e588c500411d200341a0026a100020034198066a41186a200229030037030020034198066a41106a200829030037030020034198066a41086a2009290300370300200320032903a0023703980620034120360254200320034198066a360250200341e8046a200341d0006a10ff0120034188086a41086a200341c8076a41086a29030037030020034188086a41106a200341c8076a41106a29030037030020034188086a41186a200341c8076a41186a290300370300200320032903c80737038808410121090b410021080b200341a5066a200341b8036a41086a290300370000200341ad066a200341b8036a41106a290300370000200341b5066a200341b8036a41186a290300370000200341bd066a20093a0000200341be066a200329038808370100200341c6066a20034188086a41086a290300370100200341ce066a20034188086a41106a290300370100200341d6066a20034188086a41186a290300370100200320083a009c06200320032903b80337009d06200320034188056a36029806200341003602582003420137035020034188056a200341d0006a108f01024020032d00a805220241064b0d000240024002400240024002400240024020020e0700010203040506000b410021080c060b410121080c050b410221080c040b410321080c030b410421080c020b410521080c010b410621080b200320083a00a80802400240200328025420032802582202460d00200328025021090c010b200241016a22082002490d3a200241017422092008200920084b1b22084100480d3a0240024020020d002008102821090c010b200328025020022008102c21090b2009450d29200320083602542003200936025020032d00a8082108200328025821020b2003200241016a360258200920026a20083a00000b20034198066a410472200341d0006a10a90120032802542102200341306a4120200328025022082003280258100702402002450d002008102a0b200342e4cab5fbb6ccdcb0e3003703e004200341e0046a200341c0046a417f10a80220034198066a41086a41083a0000200341a1066a20032903c004370000200341a9066a200341c0046a41086a290300370000200341b1066a200341c0046a41106a290300370000200341b9066a200341c0046a41186a290300370000200341c1066a2003290310370000200341c9066a200341106a41086a290300370000200341d1066a200341106a41106a290300370000200341d9066a200341106a41186a290300370000200341053a009806410021094101210a4101410020034198066a10cc010c420b2002411a6a2901002107200241196a2d00002117200241186a2d00002106200241166a2f01002118200241156a2d00002110200241146a2d00002111200241126a2f01002112200241116a2d00002113200241106a2d000021192002410e6a2f0100210b2002410d6a2d0000210c2002410c6a2d0000210d2002410a6a2f0100210e200241096a2d0000210f200241046a2d00002114200241026a2f0100211502400240024020022d0000450d002003200737029c06200320173a009b06200320063a009a06200320183b0198060c010b200241086a2d00002108200241066a2f01002109200241056a2d0000210a20022d00012116200320073703980641002102201641ff01714101460d010b41012102410021094104210a410021080b200941ffff0371410874200a41ff017172200841187472210a2002450d04410f210841ea9fc60021090240200a0e0700010203044445000b200e410874200f72200d411874722109200b410874200c7220194118747221084101210a0c450b410e210841dc9fc60021094101210a0c440b410c210841d09fc60021094101210a0c430b4109210841c79fc60021094101210a0c420b4113210841b49fc60021094101210a0c410b2003200737038005200320173a00ff04200320063a00fe04200320183b01fc04200320103a00fb04200320113a00fa04200320123b01f804200320133a00f704200320193a00f6042003200b3b01f4042003200c3a00f3042003200d3a00f2042003200e3b01f0042003200f3a00ef042003200a3600eb04200320143a00ea04200320153b01e804411510282202450d22200241002900d08845370000410d21082002410d6a41002900dd8845370000200241086a41002900d8884537000020034295808080d00237025420032002360250200341e8046a200341d0006a108f012003280258210220032802502109200341a0026a41186a220a4200370300200341a0026a41106a22174200370300200341a0026a41086a22064200370300200342003703a00220092002200341a0026a100020034198066a41186a200a29030037030020034198066a41106a201729030037030020034198066a41086a2006290300370300200320032903a0023703980602402003280254450d002003280250102a0b024020034198066a41204101410041001003417f470d0041e6d4c50021094101210a0c410b411510282202450d23200241002900d088453700002002410d6a41002900dd8845370000200241086a41002900d8884537000020034295808080d00237029c062003200236029806200341e8046a20034198066a108f0120032802a00621022003280298062108200341a0026a41186a22094200370300200341a0026a41106a220a4200370300200341a0026a41086a22174200370300200342003703a00220082002200341a0026a1000200341c0046a41186a2009290300370300200341c0046a41106a200a290300370300200341c0046a41086a2017290300370300200320032903a0023703c0040240200328029c06450d00200328029806102a0b2003410036029806200341c0046a412020034198066a100621022003280298062209417f460d252002450d25200320093602542003200236025020034198066a200341d0006a10b10120032d00b90622084102460d2420034188086a41186a20034198066a41186a29030037030020034188086a41106a20034198066a41106a29030037030020034188086a41086a20034198066a41086a29030037030020032003290398063703880820032d00b8062117200341a0026a200341ba066a41c100109a051a02402009450d002002102a0b200341c0046a412010090c260b41c4d1c3004133200341a8086a419cd9c3001038000b412041011037000b200241011037000b1036000b201841011037000b2002200a1044000b200a2017103c000b200920171044000b200341d0056a41146a4108360200200341dc056a412536020020034188056a41146a41033602002003420337028c05200341c8afc60036028805200341253602d4052003200341306a3602c004200320034180026a3602e804200342043703a8062003420137029c062003419cb0c600360298062003200341d0056a36029805200320034198066a3602e0052003200341e8046a3602d8052003200341c0046a3602d00520034188056a41d8b0c600103e000b200241011037000b200241011037000b410f41011037000b411741011037000b411341011037000b200841011037000b200941011037000b200941011037000b411341011037000b411741011037000b412e41011037000b41c4d1c3004133200341a8086a419cd9c3001038000b411741011037000b412e41011037000b410f41011037000b410f41011037000b410f41011037000b410f41011037000b410f41011037000b411541011037000b41c4d1c3004133200341a8086a419cd9c3001038000b41c4d1c3004133200341a8086a419cd9c3001038000b41b7b3c0004192011050000b200841011037000b200841011037000b411541011037000b411541011037000b41c4d1c3004133200341a8086a419cd9c3001038000b410221080b200341c8076a41186a220220034188086a41186a290300370300200341c8076a41106a220920034188086a41106a290300370300200341c8076a41086a220a20034188086a41086a29030037030020032003290388083703c80720034188056a200341a0026a41c100109a051a200341306a41086a2206200a290300370300200341306a41106a220a2009290300370300200341306a41186a22092002290300370300200320032903c807370330200341d0056a20034188056a41c100109a051a41072102024020084102460d0020034180026a41186a200929030037030020034180026a41106a200a29030037030020034180026a41086a20062903003703002003200329033037038002200320083a0050200341d0006a410172200341d0056a41c100109a05210a200341f2006a21094100210202400240024002400240024002400240024020032d00714101470d0020034198066a200910b001200341a0026a41186a20034198066a41186a22082900002207370300200341a0026a41106a20034198066a41106a22062900002204370300200341a0026a41086a20034198066a41086a221829000022053703002003200329009806221d3703a0022008200737030020062004370300201820053703002003201d37039806412010282202450d012002200329039806370000200241186a2008290300370000200241106a2006290300370000200241086a201829030037000020032d005021080b0240200841ff01714101460d0020032d00714101460d03200341a0026a41186a22084200370300200341a0026a41106a22094200370300200341a0026a41086a220a4200370300200342003703a00241e588c500411d200341a0026a100020034198066a41186a200829030037030020034198066a41106a200929030037030020034198066a41086a200a290300370300200320032903a0023703980620034198066a412010090c070b20034198066a200a10b001200341a0026a41186a20034198066a41186a2903002207370300200341a0026a41106a20034198066a41106a2903002204370300200341a0026a41086a20034198066a41086a29030022053703002003200329039806221d3703a002200341e8076a41186a22092007370300200341e8076a41106a220a2004370300200341e8076a41086a220620053703002003201d3703e807412010282208450d01200820032903e807370000200841186a2009290300370000200841106a200a290300370000200841086a200629030037000020034100360298062008412020034198066a1006210a2003280298062206417f460d04200a450d042003200636028c082003200a3602880820034198066a20034188086a10b10120032d00b90622194102460d03200341f1006a2109200341a0026a41206a220b20034198066a41206a22182d00003a0000200341a0026a41186a220c20034198066a41186a220d290300370300200341a0026a41106a220e20034198066a41106a220f290300370300200341a0026a41086a221020034198066a41086a221129030037030020032003290398063703a002200341b8036a200341ba066a221241c100109a051a02402006450d00200a102a0b201220032900b8033701002018200b2d00003a0000200d200c290300370300200f200e29030037030020112010290300370300200341c2066a200341b8036a41086a290000370100200341ca066a200341b8036a41106a290000370100200341d2066a200341b8036a41186a290000370100200320032903a00237039806200320193a00b906200341fa066a200941206a2d00003a0000200341f2066a200941186a290000370100200341ea066a200941106a290000370100200341e2066a200941086a290000370100200341da066a2009290000370100200341003602a802200342013703a00220034198066a200341a0026a108f01024020182d0000220941064b0d000240024002400240024002400240024020090e0700010203040506000b4100210a0c060b4101210a0c050b4102210a0c040b4103210a0c030b4104210a0c020b4105210a0c010b4106210a0b2003200a3a00a8080240024020032802a40220032802a8022209460d0020032802a00221060c010b200941016a220a2009490d1620094101742206200a2006200a4b1b220a4100480d160240024020090d00200a102821060c010b20032802a0022009200a102c21060b2006450d072003200a3602a402200320063602a00220032d00a808210a20032802a80221090b2003200941016a3602a802200620096a200a3a00000b200341b9066a200341a0026a10a90120032802a40221092008412020032802a002220a20032802a802100702402009450d00200a102a0b2008102a4101210a0c070b412041011037000b412041011037000b200341a0026a41186a22084200370300200341a0026a41106a220a4200370300200341a0026a41086a22064200370300200342003703a00241e588c500411d200341a0026a100020034198066a41186a200829030037030020034198066a41106a200a29030037030020034198066a41086a2006290300370300200320032903a00237039806200341203602a402200320034198066a3602a0022009200341a0026a10ff010c030b41c4d1c3004133200341a8086a419cd9c3001038000b41e2bbc00041d8001050000b200a41011037000b410021084100210a0b024002400240024002400240024020020d00410021090c010b20034100360298062002412020034198066a100621092003280298062206417f460d022009450d02200320063602bc03200320093602b80320034198066a200341b8036a10b10120032d00b9064102460d0120034188086a41186a221820034198066a41186a221929030037030020034188086a41106a220b20034198066a41106a220c29030037030020034188086a41086a220d20034198066a41086a220e29030037030020032003290398063703880820032d00b806210f200341a0026a200341ba066a221041c100109a051a02402006450d002009102a0b20192018290300370300200c200b290300370300200e200d2903003703002003200329038808370398062003200f3a00b8062010200341a0026a41c100109a051a200341c1066a200341d0006a41086a290300370000200341c9066a200341d0006a41106a290300370000200341d1066a200341d0006a41186a29030037000020034198066a41c1006a200341d0006a41206a2d00003a0000200320032903503700b906200341003602a802200342013703a00220034198066a200341a0026a108f01024020032d00b806220941064b0d000240024002400240024002400240024020090e0700010203040506000b410021060c060b410121060c050b410221060c040b410321060c030b410421060c020b410521060c010b410621060b200320063a00a8080240024020032802a40220032802a8022209460d0020032802a00221180c010b200941016a22062009490d14200941017422182006201820064b1b22064100480d140240024020090d002006102821180c010b20032802a00220092006102c21180b2018450d05200320063602a402200320183602a00220032d00a808210620032802a80221090b2003200941016a3602a802201820096a20063a00000b200341b9066a200341a0026a10a90120032802a40221092002412020032802a002220620032802a802100702402009450d002006102a0b2002102a410121090b200a20084572450d030c040b41c4d1c3004133200341a8086a419cd9c3001038000b41e2bbc00041d8001050000b200641011037000b2008102a0b02402002452009720d002002102a0b201721020b1098012108200342e4cab5fbb6ccdcb0e30037035041002109200341d0006a200341e8046a427f427f200841002002200241ff01714107461b41187441187541027441f48fc6006a2802004180de346c6a410210a90220034198066a41086a41093a000020034198066a41096a20032903e804370000200341a9066a200341e8046a41086a290300370000200341b1066a200341e8046a41106a290300370000200341b9066a200341e8046a41186a290300370000200341053a0098064101410020034198066a10cc014101210a0c190b41a39fc6002109411121080c180b20032802a006211820032903a0062207a7211941002102024002402007422088a7220641014b0d0020060e020201020b2006210803402008410176220920026a220a20022017200a4105746a200341d0056a4120109c054101481b2102200820096b220841014b0d000b0b201720024105746a200341d0056a4120109c052208450d0a0c010b20034198066a41186a200341d0056a41186a29030037030020034198066a41106a200341d0056a41106a29030037030020034198066a41086a200341d0056a41086a290300370300200320032903d005370398064100210620034198066a2108410021090c010b20034198066a41186a200341d0056a41186a29030037030020034198066a41106a200341d0056a41106a29030037030020034198066a41086a200341d0056a41086a290300370300200320032903d005370398062008411f7620026a220920064b0d0120034198066a21080b20062019460d012018210a0c020b41f8b0c0001032000b024020182006460d002018210a0c010b201841016a22022018490d042018410174220a2002200a20024b1b220a41ffffff3f71200a470d04200a41057422024100480d040240024020180d002002102821170c010b201720184105742002102c21170b2017450d010b201720094105746a220241206a2002200620096b410574109b051a200241186a200841186a290000370000200241106a200841106a290000370000200241086a200841086a290000370000200220082900003700001098012108411310282202450d01200241002900a9d3453700002002410f6a41002800b8d345360000200241086a41002900b1d34537000020034293808080b00237029c062003200236029806200320034198066a36025020034188056a200341d0006a10c801200328029806210220032802a0062109200341a0026a41186a22184200370300200341a0026a41106a22194200370300200341a0026a41086a220b4200370300200342003703a00220022009200341a0026a1000200341306a41186a2018290300370300200341306a41106a2019290300370300200341306a41086a200b290300370300200320032903a0023703300240200328029c06450d00200328029806102a0b410410282202450d0220034284808080c00037029c0620032002360298062002200841809c316a2209360000200641016a220220034198066a10b40102402002450d00200641057441206a2108201721020340200220034198066a108f01200241206a2102200841606a22080d000b0b200328029c062102200341306a4120200328029806220820032802a006100702402002450d002008102a0b0240200a450d002017102a0b20034198066a41086a410a3a0000200341a1066a20032903d005370000200341c1066a200329038805370000200341a9066a200341d0056a41086a290300370000200341b1066a200341d0056a41106a290300370000200341b9066a200341d0056a41186a290300370000200341c9066a20034188056a41086a290300370000200341d1066a20034188056a41106a290300370000200341d9066a20034188056a41186a290300370000200341053a009806200341e4066a2009360200410021094101410020034198066a10cc0120034188086a41086a22024200370300200342003703880841988bc500411620034188086a1008200341e8076a41086a200229030037030020032003290388083703e807200341e8076a411010094101210a0c110b200241011037000b411341011037000b410441011037000b1031000b41a6d4c5002109412621082019450d0b2017102a4101210a0c0c0b200341003602a0062003420137039806200341d0006a20034198066a10eb01200328029c06210920032802a00621172003280298062102200341a0026a41186a22194200370300200341a0026a41106a220b4200370300200341a0026a41086a220c4200370300200342003703a00220022017200341a0026a100020034198066a41186a201929030037030020034198066a41106a200b29030037030020034198066a41086a200c290300370300200320032903a0023703980602402009450d002002102a0b0240200341d0056a20034198066a4120109c05450d0041bcd3c5002109410c21080c010b20034188086a41086a22024200370300200342003703880841988bc500411620034188086a1008200341e8076a41086a200229030037030020032003290388083703e807200341e8076a41101009109801210220034198066a200341d0006a418801109a051a200341a0026a200220064180a30520064180a3054b1b6a20034198066a2008201810b704024020032802a0024101470d0020032802a4022209450d00200341a0026a41086a28020021080c0c0b410021090c0b0b200341d0006a106a0c0a0b410121180b41012117410021090c100b200a106a200a102a410121064100210a410121180c080b200341013a00880520034198066a41186a200341b8036a41186a29030037030020034198066a41106a200341b8036a41106a29030037030020034198066a41086a200341b8036a41086a290300370300200320032903b803370398060240411710282202450d0041002109200241002900e3d2453700002002410f6a41002900f2d245370000200241086a41002900ebd24537000020034297808080f0023702d405200320023602d0052003200341d0056a3602a00220034198066a200341a0026a10c80120032802d005210220032802d8052108200341a0026a41186a220a4200370300200341a0026a41106a22174200370300200341a0026a41086a22064200370300200342003703a00220022008200341a0026a1000200341306a41186a200a290300370300200341306a41106a2017290300370300200341306a41086a2006290300370300200320032903a002370330024020032802d405450d0020032802d005102a0b4101210a200341306a412020034188056a41011007200b10ce03200341d0006a106a0c030b411741011037000b412221084101210a0c050b201720024105746a22022003290330370000200241186a200341306a41186a290300370000200241106a200a290300370000200241086a20182903003700004101210a20034198066a41186a200841016a360200200341ac066a2006360200200320073703a0062003200437039806200320093602b406200320173602a806201620034198066a10c404410021090b4101210641012118410121170c0b0b41afd2c5002109411a21082002450d012017102a4101210a0c020b4111210841a39fc60021090b4101210a0b41012106410121180b410121170c060b20032802d007210920032802cc07210a20032802c80721020b2002450d00200341e8076a4110200220091007200a450d012002102a0c010b41b00110282202450d01200320032802d8013602a00720034198066a200341d0006a10cf0320034198066a41a4016a200341d0006a41a4016a29020037020020034198066a419c016a200341d0006a419c016a29020037020020034198066a4194016a200341d0006a4194016a290200370200200320032902dc013702a407200220034198066a41b001109a05210220034188086a41086a22094200370300200342003703880841ac89c500411520034188086a1008200341e8076a41086a200929030037030020032003290388083703e8072003411036029c062003200341e8076a360298062002410120034198066a10ef012002106a2002102a0b200341d0006a106a200341b0066a2004370300200341a8066a2005370300200341a4066a200836020041002117200341a0066a41003a0000200341053a0098064101210a4101410020034198066a10cc012006106a2006102a4101210641012118410021090c020b41b00141081037000b2006106a2006102a410021174101210a41012106410121180b0240024020012d0000417f6a2202410f4b0d00024002400240024020020e1000040404040102030404040405040505000b2017450d04200141046a2202280200106a2002280200102a0c040b200a450d03200141046a2202280200106a2002280200102a0c030b2006450d02200141046a2202280200106a2002280200102a0c020b2018450d01200141046a2202280200106a2002280200102a0c010b200241074b0d00024002400240024020020e080004040404010203000b200141046a2202280200106a2002280200102a0c030b200141046a2202280200106a2002280200102a0c020b200141046a2202280200106a2002280200102a0c010b200141046a2202280200106a2002280200102a0b2000200836020420002009360200200341b0086a24000b8b0708047f047e057f027e017f017e017f017e230041a0016b2202240041002103200241003a0098012001280204417f6a210402400240024003402004417f460d01200241f8006a20036a200128020022052d00003a0000200120043602042001200541016a3602002002200341016a22053a0098012004417f6a21042005210320054120470d000b200241d8006a41186a200241f8006a41186a290300370300200241d8006a41106a200241f8006a41106a290300370300200241d8006a41086a200241f8006a41086a29030037030020022002290378370358200241c0006a2001109f012002290340a7450d01200041003602200c020b0240200341ff0171450d00200241003a0098010b200041003602200c010b200241c0006a41106a290300210620022903482107200241286a2001109f0102402002290328a7450d00200041003602200c010b200241286a41106a290300210820022903302109200241206a2001106c02400240024002400240024020022802200d00200128020441186e220a41186c2204417f4c0d022002280224210b0240024020040d004108210c0c010b20041028220c450d040b0240200b450d00200241086a41106a210d4100210e41002105410021030340200241086a2001109f01024002402002290308a70d00200d290300210f2002290310211020022001106c2002280200450d010b200a450d03200c102a0c030b200341016a21042002280204211102402003200a470d00200e2004200e20044b1b220aad42187e2212422088a70d082012a722134100480d080240024020030d0020131028210c0c010b200c20052013102c210c0b200c450d070b200c20056a2203200f37030820032010370300200341106a2011360200200e41026a210e200541186a210520042103200b2004470d000b0b200c0d010b200041003602200c050b200241f8006a41186a200241d8006a41186a290300220f370300200241f8006a41106a200241d8006a41106a2903002210370300200241f8006a41086a200241d8006a41086a2903002212370300200220022903582214370378200041186a2008370300200020093703102000200637030820002007370300200041286a200b3602002000200a3602242000200c3602202000412c6a2014370200200041346a20123702002000413c6a2010370200200041c4006a200f3702000c040b1036000b200441081037000b201341081037000b1031000b200241a0016a24000bde0401067f230041306b2202240002400240024002400240411010282203450d00200341086a4100290097a5423700002003410029008fa54237000020024290808080800237021420022003360210410d200241106a10b40102400240024020022802142204200228021822056b410d490d002005410d6a2106200228021021030c010b2005410d6a22062005490d01200441017422032006200320064b1b22074100480d010240024020040d002007102821030c010b200228021020042007102c21030b2003450d032002200736021420022003360210200721040b20022006360218200320056a22054100290082a542370000200541056a4100290087a54237000020022003200610df0202402004450d002003102a0b20022802082203417f4c0d03200228020021050240024020030d0041012106410021040c010b20032104200310282206450d050b200620052003109a05210702402002280204450d002005102a0b200241106a200110e0020240200420036b4120490d00200341206a21050c060b200341206a22052003490d00200441017422062005200620054b1b22014100480d000240024020040d002001102821060c010b200720042001102c21060b02402006450d00200121040c060b200141011037000b1031000b411041011037000b200741011037000b1036000b200341011037000b200620036a22032002290010370000200341186a200241106a41186a290000370000200341106a200241106a41106a290000370000200341086a200241106a41086a290000370000200020053602082000200436020420002006360200200241306a24000bd00a010b7f230041c0006b2202240002400240024002400240024002400240024002400240411010282203450d00200341086a41002900b1c042370000200341002900a9c04237000020024290808080800237022420022003360220410d200241206a10b40102400240024020022802242204200228022822056b410d490d002005410d6a2106200228022021030c010b2005410d6a22062005490d01200441017422032006200320064b1b22074100480d010240024020040d002007102821030c010b200228022020042007102c21030b2003450d032002200736022420022003360220200721040b20022006360228200320056a22054100290082a542370000200541056a4100290087a54237000020022003200610df0202402004450d002003102a0b20022802082206417f4c0d03200228020021030240024020060d0041012107410021080c010b20062108200610282207450d050b200720032006109a05210902402002280204450d002003102a0b2001410c6a28020041046a2204417f4c0d03024002402004450d00200410282203450d0720024100360228200220043602240c010b200241003602282002200436022420024101360220410110282203450d07200241013602240b2002200336022020024101360228200320012d00003a00000240200228022422044101470d0041000d014102410241024102491b22044100480d01200341012004102c2203450d0820022004360224200220033602200b20024102360228200320012d00013a00010240024020044102460d00200421050c010b200441016a22052004490d012004410174220a2005200a20054b1b22054100480d010240024020040d002005102821030c010b200320042005102c21030b2003450d0920022005360224200220033602200b20024103360228200341026a20012d00023a0000024020054103470d00200541016a22042005490d012005410174220a2004200a20044b1b22044100480d010240024020050d002004102821030c010b200320052004102c21030b2003450d0a20022004360224200220033602200b20024104360228200341036a20012d00033a00002001280204210a200128020c2201200241206a10b4010240024020022802242205200228022822046b2001490d00200228022021030c010b200420016a22032004490d012005410174220b2003200b20034b1b220b4100480d010240024020050d00200b102821030c010b20022802202005200b102c21030b2003450d0b2002200b36022420022003360220200b21050b200320046a200a2001109a051a200241206a41186a220a4200370300200241206a41106a220b4200370300200241206a41086a220c4200370300200242003703202003200420016a200241206a1000200241186a200a290300370300200241106a200b290300370300200241086a200c2903003703002002200229032037030002402005450d002003102a0b0240200820066b4120490d00200641206a21010c0c0b200641206a22012006490d00200841017422032001200320014b1b22034100480d000240024020080d002003102821070c010b200920082003102c21070b02402007450d00200321080c0c0b200341011037000b1031000b411041011037000b200741011037000b1036000b200641011037000b200441011037000b410141011037000b200441011037000b200541011037000b200441011037000b200b41011037000b200720066a22032002290300370000200341186a200241186a290300370000200341106a200241106a290300370000200341086a200241086a290300370000200020013602082000200836020420002007360200200241c0006a24000be6e80106017f037e137f017e117f057e230041c0056b22032400024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024020012d00000e0e000102030405060708090f101112000b20034184056a4101360200200342013702f404200341ccd1c5003602f004200341043602b401200341c4d1c5003602b0012003200341b0016a36028005200341f0046a41bc80c500103e000b200141306a2903002104200141286a29030021052001411d6a29000021062001411c6a2d000021072001411b6a2d00002108200141196a2f00002109200141186a2d0000210a200141176a2d0000210b200141156a2f0000210c200141146a2d0000210d200141136a2d0000210e200141116a2f0000210f200141106a2d000021102001410f6a2d000021112001410d6a2f000021122001410c6a2d00002113200141086a2802002114200141076a2d00002115200141056a2f0000211641042117200141046a2d0000211820012d000121192002411a6a290100211a200241196a2d0000211b200241186a2d0000211c200241166a2f0100211d200241156a2d0000211e200241146a2d0000211f200241126a2f01002120200241116a2d00002121200241106a2d000021222002410e6a2f010021232002410d6a2d000021242002410c6a2d000021252002410a6a2f01002126200241096a2d00002127200241046a2d00002128200241026a2f010021290240024020022d00000d0020022d00014101470d00200241056a2d00002117200241066a2f0100212a200241086a2d000021024100212b0c010b4101212b410021024100212a0b202a41ffff0371410874200241187472201741ff017172212a0240202b450d00410f211741ea9fc60021020240202a0e07000a0b0c0d5253000b20264108742027722025411874722102202341087420247220224118747221170c520b2003201a3703b8032003201b3a00b7032003201c3a00b6032003201d3b01b4032003201e3a00b3032003201f3a00b203200320203b01b003200320213a00af03200320223a00ae03200320233b01ac03200320243a00ab03200320253a00aa03200320263b01a803200320273a00a7032003202a3600a303200320283a00a203200320293b01a003410e10282202450d11200241002900fcae44370000200241066a4100290082af443700002003428e808080e0013702f404200320023602f004200341a0036a200341f0046a108f0120032802f804210220032802f004211720034188046a41186a222a420037030020034188046a41106a222b420037030020034188046a41086a2222420037030020034200370388042017200220034188046a1000200341d0006a41186a202a290300370300200341d0006a41106a202b290300370300200341d0006a41086a20222903003703002003200329038804370350024020032802f404450d0020032802f004102a0b4101212b0240200341d0006a41204101410041001003417f460d00419681c500210241142117410121220c530b0240201841ff01714101470d00200341f0046a201441067610fe0120032802f00421170240024020032802f8042014413f7122024b0d00410021020c010b201720024105746a2202290018210620022d0017210720022d0016210820022f0014210920022d0013210a20022d0012210b20022f0010210c20022d000f210d20022d000e210e20022f000c210f20022d000b211020022d000a211120022f0008211220022d000721132002280003211420022d0002211520022f00002116410121020b024020032802f404450d002017102a0b20020d0041dc9fc6002102410e2117410121220c530b200320063703c801200320073a00c701200320083a00c601200320093b01c4012003200a3a00c3012003200b3a00c2012003200c3b01c0012003200d3a00bf012003200e3a00be012003200f3b01bc01200320103a00bb01200320113a00ba01200320123b01b801200320133a00b701200320143600b301200320153a00b201200320163b01b001410e10282202450d122002410029008aaf44370000200241066a4100290090af443700002003428e808080e0013702f404200320023602f004200341b0016a200341f0046a108f0120032802f804210220032802f004211720034188046a41186a222a420037030020034188046a41106a2222420037030020034188046a41086a2223420037030020034200370388042017200220034188046a1000200341d0006a41186a202a290300370300200341d0006a41106a2022290300370300200341d0006a41086a20232903003703002003200329038804370350024020032802f404450d0020032802f004102a0b0240200341d0006a41204101410041001003417f460d0041cc80c500210241192117410121220c530b02402005428080e983b1de165441002004501b450d0041e580c500210241312117410121220c530b200341f0046a41186a200341b0016a41186a290300370300200341f0046a41106a200341b0016a41106a290300370300200341f0046a41086a200341b0016a41086a290300370300200320032903b0013703f004410e10282202450d13200241002900fcae44370000200241066a4100290082af443700002003428e808080e0013702d404200320023602d004200341a0036a200341d0046a108f0120032802d804210220032802d004211720034188046a41186a222a420037030020034188046a41106a222b420037030020034188046a41086a2222420037030020034200370388042017200220034188046a1000200341d0006a41186a202a290300370300200341d0006a41106a202b290300370300200341d0006a41086a20222903003703002003200329038804370350024020032802d404450d0020032802d004102a0b200341203602d4042003200341d0006a3602d004200341f0046a200341d0046a10ff01410d10282202450d1420024100290098af44370000200241056a410029009daf443700002003428d808080d0013702f404200320023602f004200341a0036a200341f0046a108f0120032802f804210220032802f004211720034188046a41186a222a420037030020034188046a41106a222b420037030020034188046a41086a2222420037030020034200370388042017200220034188046a1000200341d0006a41186a202a290300370300200341d0006a41106a202b290300370300200341d0006a41086a20222903003703002003200329038804370350024020032802f404450d0020032802f004102a0b024002400240024002400240201941037122024103460d0020020e03010203010b200341d0006a41204101410010070c040b410021170c020b410121170c010b410221170b200320173a00f004410110282202450d16200220173a0000200341d0006a41202002410110072002102a0b2003200341a0036a109101200341086a290300211a200329030021064100210220034198056a41003602002003419e056a20032d00a2033a00002003419f056a20032800a303360000200341a3056a20032d00a7033a0000200341b4056a20032903b803370200200341a4056a20032903a803370200200341ac056a20032903b00337020020034188056a201a20042006200554201a200454201a2004511b22171b221a370300200320032f01a0033b019c0520034208370390052003201a3703f80420032006200520171b221a3703f0042003201a37038005200341b0016a200341f0046a10b50420034194056a280200450d4f200328029005102a0c4f0b200141106a2903002106200141086a29030021042002411a6a290100211a200241196a2d0000211b200241186a2d0000211c200241166a2f0100211d200241156a2d0000211e200241146a2d0000211f200241126a2f01002120200241116a2d00002121200241106a2d000021222002410e6a2f010021232002410d6a2d000021242002410c6a2d000021252002410a6a2f01002126200241096a2d0000212741042117200241046a2d00002128200241026a2f010021290240024020022d00000d0020022d00014101470d00200241056a2d00002117200241066a2f0100212a200241086a2d000021024100212b0c010b4101212b410021024100212a0b202a41ffff0371410874200241187472201741ff017172212a0240202b450d00410f211741ea9fc60021020240202a0e0700090a0b0c5152000b20264108742027722025411874722102202341087420247220224118747221170c510b2003201a3703e8042003201b3a00e7042003201c3a00e6042003201d3b01e4042003201e3a00e3042003201f3a00e204200320203b01e004200320213a00df04200320223a00de04200320233b01dc04200320243a00db04200320253a00da04200320263b01d804200320273a00d7042003202a3600d304200320283a00d204200320293b01d004200341f0046a200341d0046a10b1044101212a0240024020032d00f0044101460d00410b211741aa81c50021020c010b2003418a046a20032d00f3043a0000200341b0016a41086a20034184056a290200370300200341bd016a20034189056a290000370000200320032f00f1043b0188042003200341fc046a2902003703b001200341f0046a41086a28020021174100212a20032802f40421020b20034180036a41026a222b20034188046a41026a2d00003a0000200341a8046a41086a2222200341b0016a41086a290300370300200341a8046a41106a200341b0016a41106a290300370300200320032f0188043b018003200320032903b0013703a804202a0d50200341b3036a2022290300370000200341a0036a41186a200341b5046a290000370000200320032f0180033b01a003200320173600a703200320023600a303200320032903a8043700ab032003202b2d00003a00a203410e10282202450d152002410029008aaf44370000200241066a4100290090af443700002003428e808080e0013702f404200320023602f004200341a0036a200341f0046a108f0120032802f804210220032802f004211720034188046a41186a222a420037030020034188046a41106a222b420037030020034188046a41086a2222420037030020034200370388042017200220034188046a1000200341d0006a41186a202a290300370300200341d0006a41106a202b290300370300200341d0006a41086a20222903003703002003200329038804370350024020032802f404450d0020032802f004102a0b200341003602f004200341d0006a4120200341f0046a1006211720032802f0042202417f460d2e200320023602ac04200320173602a804200341f0046a200341a8046a108a02200328029005222a450d16200341f0046a41186a290300212c200341f0046a410c6a350200211a200341bc056a280200212b200341f0046a41c4006a2902002105200341f0046a41c0006a2f01002122200341f0046a413c6a2f01002123200341f0046a41386a2f01002124200341f0046a41346a2f01002125200341f0046a412f6a28000021262003419c056a2f01002127200329038005212d20032902f404212e20032d00b305211b20032d00b205211c20032d00af05211d20032d00ae05211e20032d00ab05211f20032d00aa05212020032d00a705212120032d00a605212820032d00a305212920032d009e052114200329029405212f20032802f004210702402002450d002017102a0b200341b0016a41186a202c370300200341b0016a410c6a201a3e0200200341b0016a41c4006a2005370200200341f3016a201b3a0000200341f2016a201c3a0000200341b0016a41c0006a20223b0100200341ef016a201d3a0000200341ee016a201e3a0000200341b0016a413c6a20233b0100200341eb016a201f3a0000200341ea016a20203a0000200341b0016a41386a20243b0100200341e7016a20213a0000200341e6016a20283a0000200341b0016a41346a20253b0100200341e3016a20293a0000200341b0016a412f6a2026360000200341de016a20143a0000200341d4016a202f3702002003202d3703c0012003202e3702b4012003202b3602fc01200320273b01dc012003202a3602d001200320073602b001200341106a200341d0046a10910102402003290310221a20032903b001222e7d222f201a56200341106a41086a2903002205200341b0016a41086a29030022307d201a202e54ad7d221a200556201a2005511b0d0020032004202f202f200456201a200656201a2006511b22021b2204202d7c22053703c001200341c8016a2006201a20021b221a202c7c2005200454ad7c37030020032004202e7c22063703b0012003201a20307c2006200454ad7c3703b801200341a0036a200341b0016a10b5040b20032802d401450d4d20032802d001102a0c4d0b200141106a2903002106200141086a29030021042002411a6a290100211a200241196a2d0000211b200241186a2d0000211c200241166a2f0100211d200241156a2d0000211e200241146a2d0000211f200241126a2f01002120200241116a2d00002121200241106a2d000021222002410e6a2f010021232002410d6a2d000021242002410c6a2d000021252002410a6a2f01002126200241096a2d0000212741042117200241046a2d00002128200241026a2f010021290240024020022d00000d0020022d00014101470d00200241056a2d00002117200241066a2f0100212a200241086a2d000021024100212b0c010b4101212b410021024100212a0b202a41ffff0371410874200241187472201741ff017172212a0240202b450d00410f211741ea9fc60021020240202a0e070008090a0b5051000b20264108742027722025411874722102202341087420247220224118747221170c500b2003201a3703b8032003201b3a00b7032003201c3a00b6032003201d3b01b4032003201e3a00b3032003201f3a00b203200320203b01b003200320213a00af03200320223a00ae03200320233b01ac03200320243a00ab03200320253a00aa03200320263b01a803200320273a00a7032003202a3600a303200320283a00a203200320293b01a003410e10282202450d162002410029008aaf44370000200241066a4100290090af443700002003428e808080e0013702f404200320023602f004200341a0036a200341f0046a108f0120032802f804210220032802f004211720034188046a41186a222a420037030020034188046a41106a222b420037030020034188046a41086a2222420037030020034200370388042017200220034188046a1000200341d0006a41186a202a290300370300200341d0006a41106a202b290300370300200341d0006a41086a20222903003703002003200329038804370350024020032802f404450d0020032802f004102a0b200341003602f004200341d0006a4120200341f0046a1006210220032802f0042217417f460d2d2002450d2d200320173602d404200320023602d004200341f0046a200341d0046a108a02200328029005222a450d17200341f0046a41186a290300211a200341f0046a410c6a350200212d200341bc056a280200212b200341f0046a41c4006a290200212e200341f0046a41c0006a2f01002122200341f0046a413c6a2f01002123200341f0046a41386a2f01002124200341f0046a41346a2f01002125200341f0046a412f6a28000021262003419c056a2f01002127200329038005212c20032902f404212f20032d00b305211b20032d00b205211c20032d00af05211d20032d00ae05211e20032d00ab05211f20032d00aa05212020032d00a705212120032d00a605212820032d00a305212920032d009e052114200329029405210520032802f004210702402017450d002002102a0b200341b0016a41186a201a370300200341b0016a410c6a202d3e0200200341b0016a41c4006a202e370200200341f3016a201b3a0000200341f2016a201c3a0000200341b0016a41c0006a20223b0100200341ef016a201d3a0000200341ee016a201e3a0000200341b0016a413c6a20233b0100200341eb016a201f3a0000200341ea016a20203a0000200341b0016a41386a20243b0100200341e7016a20213a0000200341e6016a20283a0000200341b0016a41346a20253b0100200341e3016a20293a0000200341b0016a412f6a2026360000200341de016a20143a0000200341d4016a20053702002003202c3703c0012003202f3702b4012003202b3602fc01200320273b01dc012003202a3602d001200320073602b0012005a7212b02400240024002402005422088a7411f4b0d00202c2004202c200454201a200654201a2006511b22021b2204201a200620021b220684500d03200341c8016a4200201a20067d202c200454ad7d2205202c20047d222d428080e983b1de165441002005501b22171b37030020034200202d20171b3703c001200341f0046a41086a22024200370300200342003703f00441bb9cc6004112200341f0046a1008200341d0046a41086a2002290300370300200320032903f0043703d004200341003602f004200341d0046a4110200341f0046a1006210220032802f004222a417f470d0141a005212a0c020b41c581c500210241232117202b450d52202a102a0c520b024020020d0041a005212a0c010b202a4104490d1a2002280000212a2002102a202a41a0056a212a0b024020032802d801220220032802d401470d00200241016a222b2002490d4720024101742222202b2022202b4b1b2222ad42187e2205422088a70d472005a7222b4100480d470240024020020d00202b102821020c010b20032802d001200241186c202b102c21020b2002450d1b200320223602d401200320023602d00120032802d80121020b20032802d001200241186c6a2202201a200620171b3703082002202c200420171b3703002002202a360210200320032802d80141016a3602d801200341a0036a200341b0016a10b50420032802d401212b0b202b450d4c20032802d001102a410021020c4d0b2002411a6a290100211a200241196a2d0000211b200241186a2d0000211c200241166a2f0100211d200241156a2d0000211e200241146a2d0000211f200241126a2f01002120200241116a2d00002121200241106a2d000021222002410e6a2f010021232002410d6a2d000021242002410c6a2d000021252002410a6a2f01002126200241096a2d0000212741042117200241046a2d00002128200241026a2f010021290240024020022d00000d0020022d00014101470d00200241056a2d00002117200241066a2f0100212a200241086a2d000021024100212b0c010b4101212b410021024100212a0b202a41ffff0371410874200241187472201741ff017172212a0240202b450d00410f211741ea9fc60021020240202a0e07000708090a4f50000b20264108742027722025411874722102202341087420247220224118747221170c4f0b2003201a3703b8032003201b3a00b7032003201c3a00b6032003201d3b01b4032003201e3a00b3032003201f3a00b203200320203b01b003200320213a00af03200320223a00ae03200320233b01ac03200320243a00ab03200320253a00aa03200320263b01a803200320273a00a7032003202a3600a303200320283a00a203200320293b01a003410e10282202450d192002410029008aaf44370000200241066a4100290090af443700002003428e808080e0013702f404200320023602f004200341a0036a200341f0046a108f0120032802f804210220032802f004211720034188046a41186a222a420037030020034188046a41106a222b420037030020034188046a41086a2222420037030020034200370388042017200220034188046a1000200341d0006a41186a202a290300370300200341d0006a41106a202b290300370300200341d0006a41086a20222903003703002003200329038804370350024020032802f404450d0020032802f004102a0b200341003602f004200341d0006a4120200341f0046a1006210220032802f0042217417f460d2c2002450d2c200320173602b401200320023602b001200341f0046a200341b0016a108a022003280290052224450d1a20034188056a290300212c200341fc046a350200211a200341b4056a290200212e200341b0056a2f01002126200341ac056a2f01002127200341a8056a2f0100211b200341a4056a2f0100211c2003419c056a2f0100211d200329038005212d20032902f404210620032d00b305211e20032d00b205211f20032d00af05212020032d00ae05212120032d00ab05212820032d00aa05212920032d00a705211420032d00a605210720032d00a3052108200328009f05210920032d009e05210a200329029405210420032802f004212a02402017450d002002102a0b200341f0046a41086a22024200370300200342003703f00441bb9cc6004112200341f0046a1008200341d0046a41086a2002290300370300200320032903f0043703d0044100212b200341003602f004200341d0046a4110200341f0046a10062102024020032802f0042217417f460d002002450d0020174104490d1d2002280000212b2002102a0b201a422086200642208884211a2006422086202aad8421062004a7210b0240024002402004422088a7222541186c2202450d00202420026a2122200241686a2117202421020340200241086a290300210520022903002104202b200241106a280200222a490d024200201a20057d2006200454ad7d2205200620047d22042006562005201a562005201a511b222a1b211a42002004202a1b2106201741686a2117200241186a22022022470d000b0b410821234100212a0240200b0d00410021250c020b2024102a410021250c010b411810282223450d1e202320043703002023202a360210202320053703080240024020170d004101212a410121250c010b200241186a210c202541186c20246a41686a210e4101212a410121250340200c210202400340200241086a290300210520022903002104202b200241106a2802002217490d014200201a20057d2006200454ad7d2205200620047d22042006562005201a562005201a511b22171b211a4200200420171b2106200241186a22022022470d000c030b0b02402025202a470d00202a41016a2225202a490d48202a410174220c2025200c20254b1b2225ad42187e222f422088a70d48202fa7220c4100480d4802400240202a0d00200c102821230c010b2023202a41186c200c102c21230b2023450d220b200241186a210c2023202a41186c6a220d2005370308200d2004370300200d2017360210202a41016a212a200e2002470d000b0b200b450d002024102a0b200341b4056a202e370200200341b3056a201e3a0000200341b2056a201f3a0000200341b0056a20263b0100200341af056a20203a0000200341ae056a20213a0000200341ac056a20273b0100200341ab056a20283a0000200341aa056a20293a0000200341a8056a201b3b0100200341a7056a20143a0000200341a6056a20073a0000200341a4056a201c3b0100200341a3056a20083a00002003419f056a20093600002003419e056a200a3a000020034198056a202a36020020034194056a20253602002003202d3703800520034188056a202c370300200320063703f0042003201d3b019c0520032023360290052003201a3703f8040240202d202c844200520d00202a450d1c0b200341a0036a200341f0046a10b5040c4a0b200141106a2903002106200141086a29030021042002411a6a290100211a200241196a2d0000211b200241186a2d0000211c200241166a2f0100211d200241156a2d0000211e200241146a2d0000211f200241126a2f01002120200241116a2d00002121200241106a2d000021222002410e6a2f010021232002410d6a2d000021242002410c6a2d000021252002410a6a2f01002126200241096a2d0000212741042117200241046a2d00002128200241026a2f010021290240024020022d00000d0020022d00014101470d00200241056a2d00002117200241066a2f0100212a200241086a2d000021024100212b0c010b4101212b410021024100212a0b202a41ffff0371410874200241187472201741ff017172212a0240202b450d00410f211741ea9fc60021020240202a0e0700060708094e4f000b20264108742027722025411874722102202341087420247220224118747221170c4e0b2003201a370398012003201b3a0097012003201c3a0096012003201d3b0194012003201e3a0093012003201f3a009201200320203b019001200320213a008f01200320223a008e01200320233b018c01200320243a008b01200320253a008a01200320263b018801200320273a0087012003202a36008301200320283a008201200320293b018001410e10282202450d1e2002410029008aaf44370000200241066a4100290090af443700002003428e808080e0013702f404200320023602f00420034180016a200341f0046a108f0120032802f804210220032802f004211720034188046a41186a222a420037030020034188046a41106a222b420037030020034188046a41086a2222420037030020034200370388042017200220034188046a1000200341d0006a41186a202a290300370300200341d0006a41106a202b290300370300200341d0006a41086a20222903003703002003200329038804370350024020032802f404450d0020032802f004102a0b200341003602f004200341d0006a4120200341f0046a1006210220032802f0042217417f460d2b2002450d2b200320173602a403200320023602a003200341f0046a200341a0036a108a02200328029005222a450d1f200341f0046a41186a290300211a200341f0046a410c6a3502002105200341bc056a280200212b200341f0046a41c4006a290200212c200341f0046a41c0006a2f01002122200341f0046a413c6a2f01002123200341f0046a41386a2f01002124200341f0046a41346a2f01002125200341f0046a412c6a2f01002126200329038005212d20032902f404212e20032d00b305212720032d00b205211b20032d00af05211c20032d00ae05211d20032d00ab05211e20032d00aa05211f20032d00a705212020032d00a605212120032d00a3052128200328009f05212920032d009e052114200329029405212f20032802f004210702402017450d002002102a0b200341b0016a41186a201a370300200341b0016a410c6a20053e0200200341b0016a41c4006a202c370200200341f3016a20273a0000200341f2016a201b3a0000200341b0016a41c0006a20223b0100200341ef016a201c3a0000200341ee016a201d3a0000200341b0016a413c6a20233b0100200341eb016a201e3a0000200341ea016a201f3a0000200341b0016a41386a20243b0100200341e7016a20203a0000200341e6016a20213a0000200341b0016a41346a20253b0100200341e3016a20283a0000200341df016a2029360000200341de016a20143a0000200341d4016a202f3702002003202d3703c0012003202e3702b4012003202b3602fc01200320263b01dc012003202a3602d001200320073602b001200341b0016a412c6a222310a7042003200637037820032004370370411210282202450d20200241002900c1ae44370000200241106a41002f00d1ae443b0000200241086a41002900c9ae4437000020034292808080a0023702f404200320023602f0042023200341f0046a108f0120032802f804210220032802f004211720034188046a41186a222a420037030020034188046a41106a222b420037030020034188046a41086a2222420037030020034200370388042017200220034188046a1000200341d0006a41186a202a290300370300200341d0006a41106a202b290300370300200341d0006a41086a20222903003703002003200329038804370350024020032802f404450d0020032802f004102a0b200341003602f004200341d0006a4120200341f0046a100621250240024020032802f0042226417f460d002025450d00200320263602ec03200320253602e803200341386a200341e8036a109f0120032802380d4a20032802ec032202450d4a20032002417f6a222a3602ec03200320032802e803222241016a222b3602e80320222d0000220241014b0d4a410021240240024020020e020100010b41002102200341003a00900503400240202a2002470d00200341003602ec03200241ff0171450d4d200341003a0090050c4d0b200341f0046a20026a202220026a221741016a2d00003a00002003201741026a3602e8032003200241016a22173a0090052017210220174120470d000b200341a0036a41086a200341f0046a41086a290300370300200341a0036a41106a200341f0046a41106a290300370300200341a0036a41186a200341f0046a41186a290300370300200320032903f0043703a0032003202a20176b222a3602ec0341012124202220176a41016a212b0b20034188046a41186a200341a0036a41186a29030037030020034188046a41106a200341a0036a41106a29030037030020034188046a41086a200341a0036a41086a290300370300200320032903a00337038804202a450d4a2003202a417f6a222a3602ec032003202b41016a3602e803202b2d0000221741014b0d4a410021020240024020170e020100010b41002102200341003a00900503400240202a2002470d00200341003602ec03200241ff0171450d4d200341003a0090050c4d0b200341f0046a20026a202b20026a221741016a2d00003a00002003201741026a3602e8032003200241016a22173a0090052017210220174120470d000b200341a0036a41086a200341f0046a41086a290300370300200341a0036a41106a200341f0046a41106a290300370300200341a0036a41186a200341f0046a41186a290300370300200320032903f0043703a0032003202a20176b3602ec03410121020b200341c0026a41186a2222200341a0036a41186a2217290300370300200341c0026a41106a2223200341a0036a41106a222a290300370300200341c0026a41086a2227200341a0036a41086a222b290300370300200341e0026a41086a221b20034188046a41086a290300370300200341e0026a41106a221c20034188046a41106a290300370300200341e0026a41186a221d20034188046a41186a290300370300200320032903a0033703c00220032003290388043703e002200341a0026a41186a221e201d290300370300200341a0026a41106a221d201c290300370300200341a0026a41086a221c201b290300370300200320032903e0023703a00220034180026a41186a221b202229030037030020034180026a41106a2222202329030037030020034180026a41086a22232027290300370300200320032903c00237038002200341f0046a41186a2227201e290300370300200341f0046a41106a221e201d290300370300200341f0046a41086a221d201c290300370300200320032903a0023703f0042017201b290300370300202a2022290300370300202b202329030037030020032003290380023703a00320244102460d4a200341d0046a41186a2027290300370300200341d0046a41106a201e290300370300200341d0046a41086a201d290300370300200341a8046a41086a202b290300370300200341a8046a41106a202a290300370300200341a8046a41186a2017290300370300200320032903f0043703d004200320032903a0033703a80402402026450d002025102a0b200341a0036a41186a200341d0046a41186a290300370300200341a0036a41106a200341d0046a41106a290300370300200341a0036a41086a200341d0046a41086a29030037030020034188046a41086a200341a8046a41086a29030037030020034188046a41106a200341a8046a41106a29030037030020034188046a41186a200341a8046a41186a290300370300200320032903d0043703a003200320032903a804370388040c010b200341e8036a41186a22024200370300200341e8036a41106a22174200370300200341e8036a41086a222a4200370300200342003703e80341d3aec400411a200341e8036a1000200341f0046a41186a222b2002290300370300200341f0046a41106a22222017290300370300200341f0046a41086a2224202a290300370300200320032903e8033703f004200341a0036a200341f0046a412010fd01024020032d00a0030d002002420037030020174200370300202a4200370300200342003703e80341d3aec400411a200341e8036a1000202b2002290300370300202220172903003703002024202a290300370300200320032903e8033703f004200341203602d4042003200341f0046a3602d0042023200341d0046a10ff0141002102410021240c010b200341c8036a41186a200341b9036a290000370300200341c8036a41106a200341b1036a290000370300200341c8036a41086a200341a9036a290000370300200320032900a1033703c80320034180036a200341c8036a10ac01200341003602f00420034180036a4120200341f0046a1006212420032802f0042226417f460d222024450d22200320263602a401200320243602a001200341206a200341a0016a109f012003290320a70d4820032802a4012202450d48200341306a290300211a2003290328210620032002417f6a222a3602a401200320032802a001222241016a222b3602a00120222d0000220241014b0d48410021250240024020020e020100010b41002102200341003a00900503400240202a2002470d00200341003602a401200241ff0171450d4b200341003a0090050c4b0b200341f0046a20026a202220026a221741016a2d00003a00002003201741026a3602a0012003200241016a22173a0090052017210220174120470d000b20034188046a41086a200341f0046a41086a2903002204370300200341d0046a41186a200341f0046a41186a290300370300200341d0046a41106a200341f0046a41106a290300370300200341d0046a41086a20043703002003202a20176b222a3602a401200320032903f004220437038804200320043703d00441012125202220176a41016a212b0b200341e8036a41186a200341d0046a41186a290300370300200341e8036a41106a200341d0046a41106a290300370300200341e8036a41086a200341d0046a41086a290300370300200320032903d0043703e80341002122200341003a00f004202a450d482003202a417f6a222a3602a4012003202b41016a3602a001202b2d0000220241014b0d480240024020020e020100010b41002102200341003a00900503400240202a2002470d00200341003602a401200241ff0171450d4b200341003a0090050c4b0b200341f0046a20026a202b20026a221741016a2d00003a00002003201741026a3602a0012003200241016a22173a0090052017210220174120470d000b200341a8046a41086a200341f0046a41086a2903002204370300200341d0046a41186a200341f0046a41186a290300370300200341d0046a41106a200341f0046a41106a290300370300200341d0046a41086a20043703002003202a20176b3602a401200320032903f00422043703a804200320043703d004410121220b200341c0026a41186a222b200341d0046a41186a2202290300370300200341c0026a41106a2227200341d0046a41106a2217290300370300200341c0026a41086a221b200341d0046a41086a222a290300370300200341e0026a41086a221c200341e8036a41086a290300370300200341e0026a41106a221d200341e8036a41106a290300370300200341e0026a41186a221e200341e8036a41186a290300370300200320032903d0043703c002200320032903e8033703e002200341a0026a41186a221f201e290300370300200341a0026a41106a221e201d290300370300200341a0026a41086a221d201c290300370300200320032903e0023703a00220034180026a41186a221c202b29030037030020034180026a41106a222b202729030037030020034180026a41086a2227201b290300370300200320032903c00237038002200341f0046a41186a221b201f290300370300200341f0046a41106a221f201e290300370300200341f0046a41086a221e201d290300370300200320032903a0023703f0042002201c2903003703002017202b290300370300202a202729030037030020032003290380023703d00420254102460d48200341a8046a41186a201b290300370300200341a8046a41106a201f290300370300200341a8046a41086a201e29030037030020034188046a41086a202a29030037030020034188046a41106a201729030037030020034188046a41186a2002290300370300200320032903f0043703a804200320032903d0043703880402402026450d002024102a0b200341d0046a41186a2224200341a8046a41186a290300370300200341d0046a41106a222b200341a8046a41106a290300370300200341d0046a41086a2226200341a8046a41086a290300370300200341e8036a41086a220220034188046a41086a2227290300370300200341e8036a41106a221720034188046a41106a221b290300370300200341e8036a41186a222a20034188046a41186a221c290300370300200320032903a8043703d00420032003290388043703e803200320253a00f004200341f9046a202629030037000020034181056a202b29030037000020034189056a2024290300370000200320032903d0043700f104200320223a00910520034192056a222520032903e8033701002003419a056a2002290300370100200341a2056a2017290300370100200341aa056a202a29030037010041002124200341e4046a2025410020221b3602002003201a3703d804200320063703d004200320233602e004200341003602b004200342013703a8042003200341d0046a3602880420034188046a200341a8046a10a301202b200341a8046a10aa0120032802ac04212b20034180036a412020032802a804222220032802b00410070240202b450d002022102a0b202a42003703002017420037030020024200370300200342003703e80341d3aec400411a200341e8036a1000200341f0046a41186a202a290300370300200341f0046a41106a2017290300370300200341f0046a41086a2002290300370300200320032903e8033703f004200341203602d4042003200341f0046a3602d0042023200341d0046a10ff012027200341c8036a41086a290300370300201b200341c8036a41106a290300370300201c200341c8036a41186a290300370300200320032903c80337038804410121020b200341fd046a200341a0036a41086a29030037000020034185056a200341a0036a41106a2903003700002003418d056a200341a0036a41186a29030037000020034195056a20023a000020034196056a2003290388043701002003419e056a20034188046a41086a290300370100200341a6056a20034188046a41106a290300370100200341ae056a20034188046a41186a290300370100200320243a00f404200320032903a0033700f5042003200341f0006a3602f004200341003602d804200342013703d0042003200341f0006a3602a804200341a8046a200341d0046a10a301200341f0046a410472200341d0046a10a90120032802d4042102200341d0006a412020032802d004221720032802d804100702402002450d002017102a0b20032802d401450d4a20032802d001102a410021020c4b0b2001410c6a2802002108200141086a280200211b41042117200141046a280200211c2002411a6a290100211a200241196a2d0000211d200241186a2d0000211e200241166a2f0100211f200241156a2d00002120200241146a2d00002121200241126a2f01002128200241116a2d00002129200241106a2d000021222002410e6a2f010021232002410d6a2d000021242002410c6a2d000021252002410a6a2f01002126200241096a2d00002127200241046a2d00002114200241026a2f010021070240024020022d00000d0020022d00014101470d00200241056a2d00002117200241066a2f0100212a200241086a2d000021024100212b0c010b4101212b4100212a410021020b202a41ffff0371410874201741ff017172200241187472212a0240202b450d00410f211741ea9fc6002102024002400240024002400240202a0e070001020304054c000b20264108742027722025411874722102202341087420247220224118747221170c4b0b410e211741dc9fc60021020c4a0b410c211741d09fc60021020c490b4109211741c79fc60021020c480b4113211741b49fc60021020c470b4111211741a39fc60021020c460b2003201a370398012003201d3a0097012003201e3a0096012003201f3b019401200320203a009301200320213a009201200320283b019001200320293a008f01200320223a008e01200320233b018c01200320243a008b01200320253a008a01200320263b018801200320273a0087012003202a36008301200320143a008201200320073b018001410e10282202450d212002410029008aaf44370000200241066a4100290090af443700002003428e808080e0013702f404200320023602f00420034180016a200341f0046a108f0120032802f804210220032802f004211720034188046a41186a222a420037030020034188046a41106a222b420037030020034188046a41086a2222420037030020034200370388042017200220034188046a1000200341d0006a41186a202a290300370300200341d0006a41106a202b290300370300200341d0006a41086a20222903003703002003200329038804370350024020032802f404450d0020032802f004102a0b200341003602f004200341d0006a4120200341f0046a10062102024020032802f0042217417f460d002002450d00200320173602a403200320023602a003200341f0046a200341a0036a108a02200328029005222a450d23200341f0046a41186a2903002106200341f0046a410c6a3502002104200341bc056a280200212b200341f0046a41c4006a2902002105200341f0046a41c0006a2f01002122200341f0046a413c6a2f01002123200341f0046a41386a2f01002124200341f0046a41346a2f01002125200341f0046a412c6a2f01002126200329038005212c20032902f404212d20032d00b305212720032d00b205211d20032d00af05211e20032d00ae05211f20032d00ab05212020032d00aa05212120032d00a705212820032d00a605212920032d00a3052114200328009f05210720032d009e052109200329029405211a20032802f004210a02402017450d002002102a0b200341b0016a41186a2006370300200341b0016a410c6a20043e0200200341b0016a41c4006a2005370200200341f3016a20273a0000200341f2016a201d3a0000200341b0016a41c0006a20223b0100200341ef016a201e3a0000200341ee016a201f3a0000200341b0016a413c6a20233b0100200341eb016a20203a0000200341ea016a20213a0000200341b0016a41386a20243b0100200341e7016a20283a0000200341e6016a20293a0000200341b0016a41346a20253b0100200341e3016a20143a0000200341df016a2007360000200341de016a20093a0000200341b0016a41246a201a3702002003202c3703c0012003202d3702b4012003202b3602fc01200320263b01dc012003202a3602d0012003200a3602b0012008450d44200341003a00a804200341103602e0042003201c200841246c6a3602dc042003201c3602d8042003201b3602d4042003201c3602d0042003200341a8046a3602e404200341f0046a200341d0046a1085040240024020032d00f0044101460d0020032802dc04212a20032802d8042102024003400240202a2002470d002002212b0c020b20022d00002117200241246a222b210220174102470d000b0b2003202b3602d8044100212441012123024020032802d4040d00410021020c020b20032802d004102a410021020c010b412010282223450d25202320032900f104370000202341186a20034189056a290000370000202341106a20034181056a290000370000202341086a200341f9046a290000370000200341a0036a41106a200341d0046a41106a290300370300200341a0036a41086a200341d0046a41086a290300370300200320032903d0043703a003200341f0046a200341a0036a1085040240024020032d00f0040d0041012102410121240c010b200341f0046a4101722117410221224120212b4101210241012124034020034188046a41186a2225201741186a29000037030020034188046a41106a2226201741106a29000037030020034188046a41086a2227201741086a2900003703002003201729000037038804024020022024470d00200241016a222a2002490d472022202a2022202a4b1b222441ffffff3f712024470d472024410574222a4100480d470240024020020d00202a102821230c010b2023202b202a102c21230b20230d00202a41011037000b2023202b6a222a200329038804370000202a41186a2025290300370000202a41106a2026290300370000202a41086a2027290300370000202241026a2122202b41206a212b200241016a2102200341f0046a200341a0036a10850420032d00f0040d000b0b20032802ac03212b20032802a8032117024003400240202b2017470d00201721220c020b20172d0000212a201741246a22222117202a4102470d000b0b200320223602a80320032802a403450d0020032802a003102a0b024020032d00a804450d002024450d432023102a0c430b2023450d42200341b0016a412c6a222a10a604200320023602a801200320243602a401200320233602a001411210282202450d2520024100290095ae44370000200241106a41002f00a5ae443b0000200241086a410029009dae4437000020034292808080a0023702f404200320023602f004202a200341f0046a108f0120032802f804210220032802f004211720034188046a41186a222b420037030020034188046a41106a2222420037030020034188046a41086a2223420037030020034200370388042017200220034188046a1000200341d0006a41186a202b290300370300200341d0006a41106a2022290300370300200341d0006a41086a20232903003703002003200329038804370350024020032802f404450d0020032802f004102a0b200341003602f004200341d0006a4120200341f0046a1006212b024020032802f0042222417f460d00202b450d00200320223602ec032003202b3602e803200341d0046a200341e8036a106d20032802d0042224450d3f20032802d404212a20032802ec032202450d3e20032002417f6a22233602ec03200320032802e803222541016a22263602e80320252d0000221741014b0d3e410021020240024020170e020100010b41002102200341003a0090050340024020232002470d00200341003602ec03200241ff0171450d41200341003a0090050c410b200341f0046a20026a202520026a221741016a2d00003a00002003201741026a3602e8032003200241016a22173a0090052017210220174120470d000b200341a0036a41086a200341f0046a41086a290300370300200341a0036a41106a200341f0046a41106a290300370300200341a0036a41186a200341f0046a41186a290300370300200320032903f0043703a0032003202320176b22233602ec0341012102202520176a41016a21260b20034188046a41186a200341a0036a41186a29030037030020034188046a41106a200341a0036a41106a29030037030020034188046a41086a200341a0036a41086a290300370300200320032903a003370388042023450d3e20032023417f6a22253602ec032003202641016a3602e80320262d0000222341014b0d3e410021170240024020230e020100010b41002117200341003a0090050340024020252017470d00200341003602ec03201741ff0171450d41200341003a0090050c410b200341f0046a20176a202620176a222341016a2d00003a00002003202341026a3602e8032003201741016a22233a0090052023211720234120470d000b200341a0036a41086a200341f0046a41086a290300370300200341a0036a41106a200341f0046a41106a290300370300200341a0036a41186a200341f0046a41186a290300370300200320032903f0043703a0032003202520236b3602ec03410121170b200341c0026a41186a2223200341a0036a41186a2225290300370300200341c0026a41106a2226200341a0036a41106a2227290300370300200341c0026a41086a221b200341a0036a41086a221c290300370300200341e0026a41086a221d20034188046a41086a290300370300200341e0026a41106a221e20034188046a41106a290300370300200341e0026a41186a221f20034188046a41186a290300370300200320032903a0033703c00220032003290388043703e002200341a0026a41186a2220201f290300370300200341a0026a41106a221f201e290300370300200341a0026a41086a221e201d290300370300200320032903e0023703a00220034180026a41186a221d202329030037030020034180026a41106a2223202629030037030020034180026a41086a2226201b290300370300200320032903c00237038002200341f0046a41186a2020290300370300200341f0046a41106a201f290300370300200341f0046a41086a201e290300370300200320032903a0023703f0042025201d29030037030020272023290300370300201c202629030037030020032003290380023703a0030c400b200341e8036a41186a22024200370300200341e8036a41106a22174200370300200341e8036a41086a222b4200370300200342003703e80341a7aec400411a200341e8036a1000200341f0046a41186a22222002290300370300200341f0046a41106a22232017290300370300200341f0046a41086a2224202b290300370300200320032903e8033703f004200341a0036a200341f0046a412010fd01024020032d00a0030d002002420037030020174200370300202b4200370300200342003703e80341a7aec400411a200341e8036a100020222002290300370300202320172903003703002024202b290300370300200320032903e8033703f004200341203602d4042003200341f0046a3602d004202a200341d0046a10ff01410021170c3c0b200341c8036a41186a200341b9036a290000370300200341c8036a41106a200341b1036a290000370300200341c8036a41086a200341a9036a290000370300200320032900a1033703c80320034180036a200341c8036a10ae01200341003602f00420034180036a4120200341f0046a1006212320032802f0042226417f460d262023450d26200320263602cc04200320233602c804200341f0006a200341c8046a106d20032802702224450d392003280274212220032802cc042202450d38200341f8006a280200212b20032002417f6a22273602cc04200320032802c804221b41016a221c3602c804201b2d0000220241014b0d38410021250240024020020e020100010b41002102200341003a0090050340024020272002470d00200341003602cc04200241ff0171450d3b200341003a0090050c3b0b200341f0046a20026a201b20026a221741016a2d00003a00002003201741026a3602c8042003200241016a22173a0090052017210220174120470d000b20034188046a41086a200341f0046a41086a290300221a370300200341d0046a41186a200341f0046a41186a290300370300200341d0046a41106a200341f0046a41106a290300370300200341d0046a41086a201a3703002003202720176b22273602cc04200320032903f004221a370388042003201a3703d00441012125201b20176a41016a211c0b200341e8036a41186a200341d0046a41186a290300370300200341e8036a41106a200341d0046a41106a290300370300200341e8036a41086a200341d0046a41086a290300370300200320032903d0043703e80341002117200341003a00f0042027450d3820032027417f6a22273602cc042003201c41016a3602c804201c2d0000220241014b0d380240024020020e020100010b41002102200341003a0090050340024020272002470d00200341003602cc04200241ff0171450d3b200341003a0090050c3b0b200341f0046a20026a201c20026a221741016a2d00003a00002003201741026a3602c8042003200241016a22173a0090052017210220174120470d000b200341a8046a41086a200341f0046a41086a290300221a370300200341d0046a41186a200341f0046a41186a290300370300200341d0046a41106a200341f0046a41106a290300370300200341d0046a41086a201a3703002003202720176b3602cc04200320032903f004221a3703a8042003201a3703d004410121170b200341c0026a41186a2202200341d0046a41186a2227290300370300200341c0026a41106a221b200341d0046a41106a221c290300370300200341c0026a41086a221d200341d0046a41086a221e290300370300200341e0026a41086a221f200341e8036a41086a290300370300200341e0026a41106a2220200341e8036a41106a290300370300200341e0026a41186a2221200341e8036a41186a290300370300200320032903d0043703c002200320032903e8033703e002200341a0026a41186a22282021290300370300200341a0026a41106a22212020290300370300200341a0026a41086a2220201f290300370300200320032903e0023703a00220034180026a41186a221f200229030037030020034180026a41106a2202201b29030037030020034180026a41086a221b201d290300370300200320032903c00237038002200341f0046a41186a2028290300370300200341f0046a41106a2021290300370300200341f0046a41086a2020290300370300200320032903a0023703f0042027201f290300370300201c2002290300370300201e201b29030037030020032003290380023703d0040c3a0b4110211741b581c50021020c450b2002411a6a290100211a200241196a2d0000211b200241186a2d0000211c200241166a2f0100211d200241156a2d0000211e200241146a2d0000211f200241126a2f01002120200241116a2d00002121200241106a2d000021222002410e6a2f010021232002410d6a2d000021242002410c6a2d000021252002410a6a2f01002126200241096a2d0000212741042117200241046a2d00002128200241026a2f010021290240024020022d00000d0020022d00014101470d00200241056a2d00002117200241066a2f0100212a200241086a2d000021024100212b0c010b4101212b4100212a410021020b202a41ffff0371410874201741ff017172200241187472212a0240202b450d00410f211741ea9fc60021020240202a0e0700040506074c4d000b20264108742027722025411874722102202341087420247220224118747221170c4c0b2003201a3703b8032003201b3a00b7032003201c3a00b6032003201d3b01b4032003201e3a00b3032003201f3a00b203200320203b01b003200320213a00af03200320223a00ae03200320233b01ac03200320243a00ab03200320253a00aa03200320263b01a803200320273a00a7032003202a3600a303200320283a00a203200320293b01a003410e10282202450d252002410029008aaf44370000200241066a4100290090af443700002003428e808080e0013702f404200320023602f004200341a0036a200341f0046a108f0120032802f804210220032802f004211720034188046a41186a222a420037030020034188046a41106a222b420037030020034188046a41086a2222420037030020034200370388042017200220034188046a1000200341d0006a41186a202a290300370300200341d0006a41106a202b290300370300200341d0006a41086a20222903003703002003200329038804370350024020032802f404450d0020032802f004102a0b200341003602f004200341d0006a4120200341f0046a1006211720032802f0042202417f460d29200320023602d404200320173602d004200341f0046a200341d0046a108a02200328029005222a450d26200341f0046a41186a290300211a200341f0046a410c6a3502002106200341bc056a280200212b200341f0046a41c4006a2902002104200341f0046a41c0006a2f01002122200341f0046a413c6a2f01002123200341f0046a41386a2f01002124200341f0046a41346a2f01002125200341f0046a412c6a2f01002126200329038005210520032902f404212c20032d00b305212720032d00b205211b20032d00af05211c20032d00ae05211d20032d00ab05211e20032d00aa05211f20032d00a705212020032d00a605212120032d00a3052128200328009f05212920032d009e052114200329029405212d20032802f004210702402002450d002017102a0b200341b0016a41186a201a370300200341b0016a410c6a20063e0200200341b0016a41c4006a2004370200200341f3016a20273a0000200341f2016a201b3a0000200341b0016a41c0006a20223b0100200341ef016a201c3a0000200341ee016a201d3a0000200341b0016a413c6a20233b0100200341eb016a201e3a0000200341ea016a201f3a0000200341b0016a41386a20243b0100200341e7016a20203a0000200341e6016a20213a0000200341b0016a41346a20253b0100200341e3016a20283a0000200341df016a2029360000200341de016a20143a0000200341d4016a2202202d370200200320053703c0012003202c3702b4012003202b3602fc01200320263b01dc012003202a3602d001200320073602b001200341b0016a412c6a221710a604201710a7042002280200450d4820032802d001102a410021020c490b20012d000121142002411a6a290100211a200241196a2d0000211b200241186a2d0000211c200241166a2f0100211d200241156a2d0000211e200241146a2d0000211f200241126a2f01002120200241116a2d00002121200241106a2d000021222002410e6a2f010021232002410d6a2d000021242002410c6a2d000021252002410a6a2f01002126200241096a2d0000212741042117200241046a2d00002128200241026a2f010021290240024020022d00000d0020022d00014101470d00200241056a2d00002117200241066a2f0100212a200241086a2d000021024100212b0c010b4101212b4100212a410021020b202a41ffff0371410874201741ff017172200241187472212a0240202b450d00410f211741ea9fc60021020240202a0e0700030405064b4c000b20264108742027722025411874722102202341087420247220224118747221170c4b0b2003201a3703b8032003201b3a00b7032003201c3a00b6032003201d3b01b4032003201e3a00b3032003201f3a00b203200320203b01b003200320213a00af03200320223a00ae03200320233b01ac03200320243a00ab03200320253a00aa03200320263b01a803200320273a00a7032003202a3600a303200320283a00a203200320293b01a003410e10282202450d262002410029008aaf44370000200241066a4100290090af443700002003428e808080e0013702f404200320023602f004200341a0036a200341f0046a108f0120032802f804210220032802f004211720034188046a41186a222a420037030020034188046a41106a222b420037030020034188046a41086a2222420037030020034200370388042017200220034188046a1000200341d0006a41186a202a290300370300200341d0006a41106a202b290300370300200341d0006a41086a20222903003703002003200329038804370350024020032802f404450d0020032802f004102a0b200341003602f004200341d0006a4120200341f0046a1006210220032802f0042217417f460d282002450d28200320173602d404200320023602d004200341f0046a200341d0046a108a02200328029005222a450d27200341f0046a41186a290300211a200341f0046a410c6a3502002106200341bc056a280200212b200341f0046a41c4006a2902002104200341f0046a41c0006a2f01002122200341f0046a413c6a2f01002123200341f0046a41386a2f01002124200341f0046a41346a2f01002125200341f0046a412c6a2f01002126200329038005210520032902f404212c20032d00b305212720032d00b205211b20032d00af05211c20032d00ae05211d20032d00ab05211e20032d00aa05211f20032d00a705212020032d00a605212120032d00a3052128200328009f05212920032d009e052107200329029405212d20032802f004210802402017450d002002102a0b200341b0016a41186a201a370300200341b0016a410c6a20063e0200200341b0016a41c4006a2004370200200341f3016a20273a0000200341f2016a201b3a0000200341b0016a41c0006a20223b0100200341ef016a201c3a0000200341ee016a201d3a0000200341b0016a413c6a20233b0100200341eb016a201e3a0000200341ea016a201f3a0000200341b0016a41386a20243b0100200341e7016a20203a0000200341e6016a20213a0000200341b0016a41346a20253b0100200341e3016a20283a0000200341df016a2029360000200341de016a20073a0000200341d4016a202d370200200320053703c0012003202c3702b4012003202b3602fc01200320263b01dc012003202a3602d001200320083602b001410d10282202450d2920024100290098af44370000200241056a410029009daf443700002003428d808080d0013702f404200320023602f004200341b0016a412c6a200341f0046a108f0120032802f804210220032802f004211720034188046a41186a222a420037030020034188046a41106a222b420037030020034188046a41086a2222420037030020034200370388042017200220034188046a1000200341d0006a41186a202a290300370300200341d0006a41106a202b290300370300200341d0006a41086a20222903003703002003200329038804370350024020032802f404450d0020032802f004102a0b024002400240024002400240201441037122024103460d0020020e03010203010b200341d0006a41204101410010070c040b410021170c020b410121170c010b410221170b200320173a00f004410110282202450d2b200220173a0000200341d0006a41202002410110072002102a0b20032802d401450d4720032802d001102a410021020c480b2001411d6a29000021062001411c6a2d000021072001411b6a2d00002108200141196a2f00002109200141186a2d0000210a200141176a2d0000210b200141156a2f0000210c200141146a2d0000210d200141136a2d0000210e200141116a2f0000210f200141106a2d000021102001410f6a2d000021112001410d6a2f000021122001410c6a2d00002113200141086a280200211b200141076a2d00002115200141056a2f0000211641042117200141046a2d000021182002411a6a290100211a200241196a2d0000211c200241186a2d0000211d200241166a2f0100211e200241156a2d0000211f200241146a2d00002120200241126a2f01002121200241116a2d00002128200241106a2d000021222002410e6a2f010021232002410d6a2d000021242002410c6a2d000021252002410a6a2f01002126200241096a2d00002127200241046a2d00002129200241026a2f010021140240024020022d00000d0020022d00014101470d00200241056a2d00002117200241066a2f0100212a200241086a2d000021024100212b0c010b4101212b4100212a410021020b202a41ffff0371410874201741ff017172200241187472212a202b450d04410f211741ea9fc60021020240202a0e070001020304494a000b20264108742027722025411874722102202341087420247220224118747221170c490b410e211741dc9fc60021020c480b410c211741d09fc60021020c470b4109211741c79fc60021020c460b4113211741b49fc60021020c450b2003201a3703e0032003201c3a00df032003201d3a00de032003201e3b01dc032003201f3a00db03200320203a00da03200320213b01d803200320283a00d703200320223a00d603200320233b01d403200320243a00d303200320253a00d203200320263b01d003200320273a00cf032003202a3600cb03200320293a00ca03200320143b01c803200341f0046a200341c8036a10b1044101212a0240024020032d00f0044101460d00410b211741aa81c50021020c010b2003418a046a20032d00f3043a0000200341b0016a41086a20034184056a290200370300200341bd016a20034189056a290000370000200320032f00f1043b0188042003200341fc046a2902003703b001200341f0046a41086a28020021174100212a20032802f40421020b20034180036a41026a222b20034188046a41026a2d00003a0000200341a8046a41086a2222200341b0016a41086a290300370300200341a8046a41106a200341b0016a41106a290300370300200320032f0188043b018003200320032903b0013703a804202a0d44200341fb036a202229030037000020034180046a200341b5046a290000370000200320032f0180033b01e803200320173600ef03200320023600eb03200320032903a8043700f3032003202b2d00003a00ea030240201841ff01714101470d00200341f0046a201b41067610fe0120032802f00421170240024020032802f804201b413f7122024b0d00410021020c010b201720024105746a2202290018210620022d0017210720022d0016210820022f0014210920022d0013210a20022d0012210b20022f0010210c20022d000f210d20022d000e210e20022f000c210f20022d000b211020022d000a211120022f0008211220022d000721132002280003211b20022d0002211520022f00002116410121020b024020032802f404450d002017102a0b20020d0041dc9fc6002102410e21170c450b200320063703c004200320073a00bf04200320083a00be04200320093b01bc042003200a3a00bb042003200b3a00ba042003200c3b01b8042003200d3a00b7042003200e3a00b6042003200f3b01b404200320103a00b304200320113a00b204200320123b01b004200320133a00af042003201b3600ab04200320153a00aa04200320163b01a804410e10282202450d252002410029008aaf44370000200241066a4100290090af443700002003428e808080e0013702f404200320023602f004200341a8046a200341f0046a108f0120032802f804210220032802f004211720034188046a41186a222a420037030020034188046a41106a222b420037030020034188046a41086a2222420037030020034200370388042017200220034188046a1000200341d0006a41186a202a290300370300200341d0006a41106a202b290300370300200341d0006a41086a20222903003703002003200329038804370350024020032802f404450d0020032802f004102a0b0240200341d0006a41204101410041001003417f460d0041cc80c5002102411921170c450b200341a8046a200341e8036a4120109c05450d41410e10282202450d26200241002900fcae44370000200241066a4100290082af443700002003428e808080e0013702f404200320023602f004200341c8036a200341f0046a108f0120032802f804210220032802f004211720034188046a41186a222a420037030020034188046a41106a222b420037030020034188046a41086a2222420037030020034200370388042017200220034188046a1000200341d0006a41186a202a290300370300200341d0006a41106a202b290300370300200341d0006a41086a20222903003703002003200329038804370350024020032802f404450d0020032802f004102a0b200341203602f4042003200341d0006a3602f004200341a8046a200341f0046a10ff01410e10282202450d272002410029008aaf44370000200241066a4100290090af443700002003428e808080e0013702f404200320023602f004200341e8036a200341f0046a108f0120032802f804210220032802f004211720034188046a41186a222a420037030020034188046a41106a222b420037030020034188046a41086a2222420037030020034200370388042017200220034188046a1000200341d0006a41186a202a290300370300200341d0006a41106a202b290300370300200341d0006a41086a20222903003703002003200329038804370350024020032802f404450d0020032802f004102a0b200341003602f004200341d0006a4120200341f0046a1006212a0240024020032802f0042217417f470d00410021020c010b2003201736028c042003202a36028804200341f0046a20034188046a108a022003280290052202450d29200341b0016a41186a200341f0046a41186a290300370300200341b0016a41106a200341f0046a41106a290300370300200341b0016a41086a200341f0046a41086a290300370300200320032903f0043703b0012003419c056a2f010021222003419f056a2800002124200341a4056a2f01002126200341a8056a2f0100211c200341ac056a2f0100211f200341b0056a2f01002128200341b4056a290200212d200341bc056a2802002107200329029405212c20032d009e05212320032d00a305212520032d00a605212720032d00a705211b20032d00aa05211d20032d00ab05211e20032d00ae05212020032d00af05212120032d00b205212920032d00b305211402402017450d00202a102a0b200341d0006a412010090b200341a0036a41186a200341b0016a41186a290300221a370300200341a0036a41106a200341b0016a41106a2903002206370300200341a0036a41086a200341b0016a41086a2903002204370300200320032903b00122053703a003200341f0046a41186a2217201a370300200341f0046a41106a222a2006370300200341f0046a41086a222b2004370300200320053703f0042002450d41200341d0046a41186a2017290300221a370300200341d0046a41106a202a2903002206370300200341d0046a41086a202b2903002204370300200320032903f00422053703d0042017201a370300202a2006370300202b2004370300200341b4056a202d370200200341b3056a20143a0000200341b2056a20293a0000200341b0056a20283b0100200341af056a20213a0000200341ae056a20203a0000200341ac056a201f3b0100200341ab056a201e3a0000200341aa056a201d3a0000200341a8056a201c3b0100200341a7056a201b3a0000200341a6056a20273a0000200341a4056a20263b0100200341a3056a20253a00002003419f056a20243600002003419e056a20233a000020034194056a202c370200200320053703f004200320073602bc05200320223b019c052003200236029005410e10282202450d292002410029008aaf44370000200241066a4100290090af443700002003428e808080e0013702b401200320023602b001200341a8046a200341b0016a108f0120032802b801210220032802b001211720034188046a41186a222a420037030020034188046a41106a222b420037030020034188046a41086a2222420037030020034200370388042017200220034188046a1000200341d0006a41186a202a290300370300200341d0006a41106a202b290300370300200341d0006a41086a20222903003703002003200329038804370350024020032802b401450d0020032802b001102a0b200341203602b4012003200341d0006a3602b001200341f0046a200341b0016a10b604200328029405450d41200328029005102a410021020c420b4101212b024020022d000120022d000072450d0041a39fc600210241112117410121220c450b200141046a2802002102200341f0046a41086a22174200370300200342003703f00441889cc6004116200341f0046a1008200341d0046a41086a2017290300370300200320032903f0043703d004200320023602f004200341d0046a4110200341f0046a410410070c2c0b20022d000120022d0000720d2c200341f0046a41086a22024200370300200342003703f004418e9dc6004110200341f0046a1008200341d0046a41086a2002290300370300200320032903f0043703d004200341023a00f0044101212b410110282202450d28200241023a0000200341d0046a41102002410110072002102a0c2b0b20022d000120022d0000720d2b200341f0046a41086a22024200370300200342003703f004418e9dc6004110200341f0046a1008200341d0046a41086a2002290300370300200320032903f0043703d0044101212b200341013a00f004410110282202450d28200241013a0000200341d0046a41102002410110072002102a0c2a0b200141086a280200212a200141046a2802002123024020022d000120022d000072450d0041a39fc600210241112117410021224101212b202a450d422023102a0c420b2001410c6a2802002102200341f0046a41086a22174200370300200342003703f00441c8ffc4004115200341f0046a1008200341d0046a41086a2017290300370300200320032903f0043703d004200341003602f804200342013703f0042002200341f0046a10b40102402002450d00200241057421172023210203402002200341f0046a108f01200241206a2102201741606a22170d000b0b20032802f4042102200341d0046a411020032802f004221720032802f804100702402002450d002017102a0b4101212b202a450d282023102a0c280b410e41011037000b410e41011037000b410e41011037000b410d41011037000b410141011037000b410e41011037000b41c4d1c3004133200341e0026a419cd9c3001038000b410e41011037000b41c4d1c3004133200341e0026a419cd9c3001038000b41c4d1c3004133200341e0026a419cd9c3001038000b202b41081037000b410e41011037000b41c4d1c3004133200341e0026a419cd9c3001038000b200341c8016a200341b4056a290200370300200341c0016a200341ac056a290200370300200341b0016a41086a200341a4056a2902003703002003200329029c053703b001200342f3e885db96cddbb3203703e803200310980136028804200341d0046a200341b0016a109a0220032802d404211720032802d004210220032802d804212a200341e4046a200341e8036a36020020032002202a4105746a3602dc04200320023602d804200320173602d404200320023602d004200320034188046a3602e004200341a8046a200341d0046a108701200341d0046a41086a200341a8046a41086a280200360200200320032903a8043703d004200341b0016a200341d0046a109c02200341b0016a1095020c2e0b41c4d1c3004133200341e0026a419cd9c3001038000b411841081037000b200c41081037000b410e41011037000b41c4d1c3004133200341e0026a419cd9c3001038000b411241011037000b41b7b3c0004192011050000b410e41011037000b41c4d1c3004133200341e0026a419cd9c3001038000b412041011037000b411241011037000b41b7b3c0004192011050000b410e41011037000b41c4d1c3004133200341e0026a419cd9c3001038000b410e41011037000b41c4d1c3004133200341e0026a419cd9c3001038000b41b581c5002102411021170c210b410d41011037000b410141011037000b410e41011037000b410e41011037000b410e41011037000b41c4d1c3004133200341e0026a419cd9c3001038000b410e41011037000b410141011037000b410141011037000b41002122410021020c180b41002102410121220c170b41a39fc6002102411121170c150b2022450d002024102a0b410221250b20254102460d01200341a8046a41186a221c200341f0046a41186a290300370300200341a8046a41106a221d200341f0046a41106a290300370300200341a8046a41086a221e200341f0046a41086a29030037030020034188046a41086a221f200341d0046a41086a222729030037030020034188046a41106a2220200341d0046a41106a220229030037030020034188046a41186a2221200341d0046a41186a221b290300370300200320032903f0043703a804200320032903d0043703880402402026450d002023102a0b201b201c2903003703002002201d2903003703002027201e290300370300200341e8036a41086a2223201f290300370300200341e8036a41106a22262020290300370300200341e8036a41186a221c2021290300370300200320032903a8043703d00420032003290388043703e803200320253a00f004200341f9046a202729030037000020034181056a200229030037000020034189056a201b290300370000200320032903d0043700f104200320173a00910520034192056a222520032903e8033701002003419a056a2023290300370100200341a2056a2026290300370100200341aa056a201c290300370100200220254100201741ff01714101461b3602002003202a3602dc042003202b3602d804200320223602d404200320243602d004200341003602b004200342013703a804202b200341a8046a10b401200341dc046a21230240202b450d00202b41057421172024210203402002200341a8046a108f01200241206a2102201741606a22170d000b0b2023200341a8046a10aa0120032802ac04210220034180036a412020032802a804221720032802b004100702402002450d002017102a0b02402022450d002024102a0b200341e8036a41186a22024200370300200341e8036a41106a22174200370300200341e8036a41086a222b4200370300200342003703e80341a7aec400411a200341e8036a1000200341f0046a41186a2002290300370300200341f0046a41106a2017290300370300200341f0046a41086a202b290300370300200320032903e8033703f004200341203602d4042003200341f0046a3602d004202a200341d0046a10ff0120034188046a41086a200341c8036a41086a29030037030020034188046a41106a200341c8036a41106a29030037030020034188046a41186a200341c8036a41186a290300370300200320032903c80337038804410121170b410021020c040b41c4d1c3004133200341e0026a419cd9c3001038000b202a450d002024102a0b410221020b20024102460d01200341d0046a41186a2223200341f0046a41186a290300370300200341d0046a41106a2225200341f0046a41106a290300370300200341d0046a41086a2226200341f0046a41086a290300370300200341a8046a41086a2227200341a0036a41086a221b290300370300200341a8046a41106a221c200341a0036a41106a221d290300370300200341a8046a41186a221e200341a0036a41186a221f290300370300200320032903f0043703d004200320032903a0033703a80402402022450d00202b102a0b201f2023290300370300201d2025290300370300201b202629030037030020034188046a41086a202729030037030020034188046a41106a201c29030037030020034188046a41186a201e290300370300200320032903d0043703a003200320032903a80437038804202a450d002024102a0b200341fd046a200341a0036a41086a29030037000020034185056a200341a0036a41106a2903003700002003418d056a200341a0036a41186a29030037000020034195056a20173a000020034196056a2003290388043701002003419e056a20034188046a41086a290300370100200341a6056a20034188046a41106a290300370100200341ae056a20034188046a41186a290300370100200320023a00f404200320032903a0033700f5042003200341a0016a3602f004200341003602d804200342013703d00420032802a001210220032802a8012217200341d0046a10b401200341f0046a410472212a02402017450d002017410574211703402002200341d0046a108f01200241206a2102201741606a22170d000b0b202a200341d0046a10a90120032802d4042102200341d0006a412020032802d004221720032802d804100702402002450d002017102a0b024020032802a401450d0020032802a001102a0b024020032802d401450d0020032802d001102a0b4100212b41012122410021020c0d0b41c4d1c3004133200341e0026a419cd9c3001038000b41dc9fc6002102410e21174100212b20032802d401212a0c020b1031000b201aa7212a41e881c5002102411721174101212b0b0240202a450d0020032802d001102a0b202b0d00410121224100212b0c080b410121224100212b201b450d07201c102a0c070b41c4d1c3004133200341e0026a419cd9c3001038000b41c4d1c3004133200341e0026a419cd9c3001038000b200328029405450d00200328029005102a410021020c010b410021020b4101212b410121220c020b4111211741a39fc60021020b4101212b410121220b0240024020012d0000222a410d4b0d004101202a7441be3f710d010240202a4106460d00202a410d470d012022450d02200141086a280200450d02200141046a280200102a0c020b202b450d01200141086a280200450d01200141046a280200102a0c010b200141086a280200450d00200141046a280200102a0b2000201736020420002002360200200341c0056a24000b990d02067f077e230041b0016b22052400024002400240024002400240411410282206450d00200641002900cfe140370000200641106a41002800dfe140360000200641086a41002900d7e14037000020054294808080c002370234200520063602302001200541306a108f012005280238210620052802302107200541c0006a41186a22084200370300200541c0006a41106a22094200370300200541c0006a41086a220a42003703002005420037034020072006200541c0006a1000200541106a41186a2008290300370300200541106a41106a2009290300370300200541106a41086a200a2903003703002005200529034037031002402005280234450d002005280230102a0b20054100360240200541106a4120200541c0006a100621060240024020052802402207417f470d004200210b4200210c0c010b20074110490d02200641086a290000210c2006290000210b2006102a0b411410282206450d02200641002900cfe140370000200641106a41002800dfe140360000200641086a41002900d7e14037000020054294808080c002370234200520063602302002200541306a108f012005280238210620052802302107200541c0006a41186a22084200370300200541c0006a41106a22094200370300200541c0006a41086a220a42003703002005420037034020072006200541c0006a1000200541106a41186a2008290300370300200541106a41106a2009290300370300200541106a41086a200a2903003703002005200529034037031002402005280234450d002005280230102a0b20054100360240200541106a4120200541c0006a100621060240024020052802402207417f470d004200210d4200210e0c010b20074110490d04200641086a290000210e2006290000210d2006102a0b024020034280a094a58d1d7c220f200354220620042006ad7c2210200454200f20035a1b450d0041f092c1002106412821010c060b0240200b200f7d2211200b56200c20107d200b200f54ad7d220f200c56200f200c511b4101470d00419893c1002106411d21010c060b0240200342ffffe883b1de165620044200522004501b0d00200d200e8450450d0041e293c1002106411f21010c060b200541086a200141022011200f10bc01024020052802082206450d00200528020c21010c060b0240200d20037c220c200d542206200e20047c2006ad7c220b200e54200b200e511b450d0041b593c1002106412d21010c060b41002106024020012002470d000c060b0240200120024120109c050d000c060b20012011200f108f02411410282206450d04200641002900cfe140370000200641106a41002800dfe140360000200641086a41002900d7e14037000020054294808080c002370234200520063602302002200541306a108f012005280238210620052802302107200541c0006a41186a22084200370300200541c0006a41106a22094200370300200541c0006a41086a220a42003703002005420037034020072006200541c0006a1000200541106a41186a2008290300370300200541106a41106a2009290300370300200541106a41086a200a2903003703002005200529034037031002402005280234450d002005280230102a0b0240200541106a41204101410041001003417f470d002002109302200541f8006a200b370300200541f0006a200c370300200541c0006a41086a41003a0000200541c9006a2002290000370000200541d1006a200241086a290000370000200541d9006a200241106a290000370000200541e1006a200241186a290000370000200541023a004041014100200541c0006a10cc010b2002200c200b108f022005420037034820054280a094a58d1d3703402005200541c0006a360210200541106a109d01200541a8016a4200370300200541a0016a4280a094a58d1d37030020054198016a200437030020054190016a2003370300200541c0006a41086a41023a0000200541c9006a2001290000370000200541d1006a200141086a290000370000200541d9006a200141106a290000370000200541e1006a200141186a290000370000200541e9006a2002290000370000200541f1006a200241086a290000370000200541f9006a200241106a29000037000020054181016a200241186a290000370000200541023a00404100210641014100200541c0006a10cc010c050b411441011037000b41c4d1c3004133200541c0006a419cd9c3001038000b411441011037000b41c4d1c3004133200541c0006a419cd9c3001038000b411441011037000b2000200136020420002006360200200541b0016a24000b881201097f230041f0026b22032400024002400240024002400240024002400240411410282204450d00200441002900cfe140370000200441106a41002800dfe140360000200441086a41002900d7e14037000020034294808080c002370294012003200436029001200020034190016a108f0120032802980121042003280290012105200341206a41186a22064200370300200341206a41106a22074200370300200341206a41086a220842003703002003420037032020052004200341206a100020034180026a41186a200629030037030020034180026a41106a200729030037030020034180026a41086a200829030037030020032003290320370380020240200328029401450d00200328029001102a0b200320013703202003200237032820034180026a4120200341206a41101007200142ffffe883b1de165620024200522002501b0d06411410282204450d01200441002900cfe140370000200441106a41002800dfe140360000200441086a41002900d7e14037000020034294808080c002370294012003200436029001200020034190016a108f0120032802980121042003280290012105200341206a41186a22064200370300200341206a41106a22074200370300200341206a41086a220842003703002003420037032020052004200341206a100020034180026a41186a200629030037030020034180026a41106a200729030037030020034180026a41086a200829030037030020032003290320370380020240200328029401450d00200328029001102a0b200341086a20034180026a109402200341086a41106a29030021022003290310210120032802082109410e10282204450d02200441002900fbe140370000200441066a4100290081e2403700002003428e808080e001370294012003200436029001200020034190016a108f0120032802980121042003280290012105200341206a41186a22064200370300200341206a41106a22074200370300200341206a41086a220842003703002003420037032020052004200341206a100020034180026a41186a200629030037030020034180026a41106a200729030037030020034180026a41086a200829030037030020032003290320370380020240200328029401450d00200328029001102a0b20034180026a4120100902402001200284500d002009450d0020032001370320200320023703282003200341206a3602800220034180026a109d010b2000109502411710282204450d03200441002900f1d8433700002004410f6a4100290080d943370000200441086a41002900f9d84337000020034297808080f002370294012003200436029001200020034190016a108f0120032802980121042003280290012105200341206a41186a22064200370300200341206a41106a22074200370300200341206a41086a220842003703002003420037032020052004200341206a100020034180026a41186a200629030037030020034180026a41106a200729030037030020034180026a41086a200829030037030020032003290320370380020240200328029401450d00200328029001102a0b200341206a20034180026a109602024020032d002022044102460d0020034180026a412010090b2003413c6a2802002106200341386a2802002105024020040d002005200341c0006a28020010042006450d060c050b20044103710d0520060d040c050b411441011037000b411441011037000b410e41011037000b411741011037000b2005102a0b200341f0016a2000108b0220032802f001210420032802f8012105410021062003410036022020042005200341206a10062108024002400240024020032802202207417f460d00200320073602e402200320083602e002200341206a200341e0026a10e80120032d00204101460d0120034180026a200341206a41017241e000109a051a02402007450d002008102a0b200341206a20034180026a41e000109a051a200420051009410121060b20034190016a200341206a41e000109a051a200341206a20034190016a41e000109a051a2006450d0120034180026a200341206a41e000109a051a024020032802f401450d002004102a0b200341206a20034180026a41e000109a051a200341c0006a210a200341e0006a210b4104210641e7e485f30621040340200b210702400240200441e9dabdf306460d000240200441e7e485f306470d00200341206a21070c010b200a2107200441e2c289ab06460d00410121084100210541012107410121090c010b41202105410021084120102822090d00412041011037000b200920072005109a0521072003200536029c01200320053602980120032007360294012003200436029001200341f0016a20034190016a108c0220032802f001220420032802f8011009024020032802f401450d002004102a0b024020080d002007102a0b2006410c460d03200641f8c8c0006a2800002104200641046a21060c000b0b41c4d1c3004133200341e8026a419cd9c3001038000b20032802f401450d002004102a0b411810282204450d01200441002900e3e140370000200441106a41002900f3e140370000200441086a41002900ebe140370000200342988080808003370294012003200436029001200020034190016a108f0120032802980121042003280290012105200341206a41186a22064200370300200341206a41106a22074200370300200341206a41086a220842003703002003420037032020052004200341206a100020034180026a41186a200629030037030020034180026a41106a200729030037030020034180026a41086a200829030037030020032003290320370380020240200328029401450d00200328029001102a0b2003410036022020034180026a4120200341206a10062104024020032802202205417f460d0020054110490d03200441086a2900002102200429000021012004102a200120028450450d010b2000109702200341206a41086a41013a0000200341296a2000290000370000200341316a200041086a290000370000200341396a200041106a290000370000200341c1006a200041186a290000370000200341023a002041014100200341206a10cc010b200341f0026a24000f0b411841011037000b41c4d1c3004133200341e8026a419cd9c3001038000bd40801067f230041c0016b220324000240024002400240411810282204450d00200441002900e3e140370000200441106a41002900f3e140370000200441086a41002900ebe140370000200342988080808003370244200320043602402000200341c0006a108f012003280248210420032802402105200341d0006a41186a22064200370300200341d0006a41106a22074200370300200341d0006a41086a220842003703002003420037035020052004200341d0006a1000200341206a41186a2006290300370300200341206a41106a2007290300370300200341206a41086a20082903003703002003200329035037032002402003280244450d002003280240102a0b2003200137035020032002370358200341206a4120200341d0006a411010070240200142ffffe883b1de165620024200522002501b0d00411810282204450d02200441002900e3e140370000200441106a41002900f3e140370000200441086a41002900ebe140370000200342988080808003370244200320043602402000200341c0006a108f012003280248210420032802402105200341d0006a41186a22064200370300200341d0006a41106a22074200370300200341d0006a41086a220842003703002003420037035020052004200341d0006a1000200341206a41186a2006290300370300200341206a41106a2007290300370300200341206a41086a20082903003703002003200329035037032002402003280244450d002003280240102a0b200341086a200341206a109402024020032903102202200341086a41106a290300220184500d002003280208450d0020032002370350200320013703582003200341d0006a360220200341206a109d010b411410282204450d03200441002900cfe140370000200441106a41002800dfe140360000200441086a41002900d7e14037000020034294808080c002370244200320043602402000200341c0006a108f012003280248210420032802402105200341d0006a41186a22064200370300200341d0006a41106a22074200370300200341d0006a41086a220842003703002003420037035020052004200341d0006a1000200341206a41186a2006290300370300200341206a41106a2007290300370300200341206a41086a20082903003703002003200329035037032002402003280244450d002003280240102a0b20034100360250200341206a4120200341d0006a10062104024020032802502205417f460d0020054110490d05200441086a2900002102200429000021012004102a200120028450450d010b2000109702200341d0006a41086a41013a0000200341d9006a2000290000370000200341e1006a200041086a290000370000200341e9006a200041106a290000370000200341f1006a200041186a290000370000200341023a005041014100200341d0006a10cc010b200341c0016a24000f0b411841011037000b411841011037000b411441011037000b41c4d1c3004133200341d0006a419cd9c3001038000b4d01017f230041206b22002400200041146a410136020020004201370204200041ccd1c5003602002000410436021c200041c4d1c5003602182000200041186a360210200041e8b5c300103e000bb30701057f230041106b2203240020034100360208200342013703002002200310b40102400240024002400240024002402002450d00200241c4006c210403400240024020012d00004101460d0002400240200328020420032802082202460d00200328020021050c010b200241016a22052002490d0a200241017422062005200620054b1b22064100480d0a0240024020020d002006102821050c010b200328020020022006102c21050b2005450d052003200636020420032005360200200328020821020b2003200241016a360208200520026a41003a0000200141046a28020021060240024020032802042205200328020822026b4104490d00200328020021050c010b200241046a22072002490d0a200541017422022007200220074b1b22024100480d0a0240024020050d002002102821050c010b200328020020052002102c21050b2005450d062003200236020420032005360200200328020821020b2003200241046a360208200520026a20063600000c010b02400240200328020420032802082202460d00200328020021050c010b200241016a22052002490d09200241017422062005200620054b1b22064100480d090240024020020d002006102821050c010b200328020020022006102c21050b2005450d062003200636020420032005360200200328020821020b2003200241016a360208200520026a41013a00002003200336020c200141016a2003410c6a10c8010240200141216a2d00004101460d0002400240200328020420032802082202460d00200328020021050c010b200241016a22052002490d0a200241017422062005200620054b1b22064100480d0a0240024020020d002006102821050c010b200328020020022006102c21050b2005450d082003200636020420032005360200200328020821020b2003200241016a360208200520026a41003a00000c010b02400240200328020420032802082202460d00200328020021050c010b200241016a22052002490d09200241017422062005200620054b1b22064100480d090240024020020d002006102821050c010b200328020020022006102c21050b2005450d082003200636020420032005360200200328020821020b2003200241016a360208200520026a41013a0000200141226a2003108f010b200141c4006a2101200441bc7f6a22040d000b0b20002003290300370200200041086a200341086a280200360200200341106a24000f0b200641011037000b200241011037000b200641011037000b200641011037000b200641011037000b1031000bcc0b03057f037e047f230041a0016b22012400200141306a41086a220242003703002001420037033041f5b8c3004113200141306a1008200141206a41086a2002290300370300200120012903303703204100210220014100360230200141206a4110200141306a100621030240024002400240024002400240024002400240024020012802302204417f460d002003450d0020044104490d01200328000021022003102a0b410110282203450d01200320002d00003a0000200341014102102c2203450d02200320002d00013a0001200341024104102c2203450d03200320002d00023a0002200320002d00033a0003200341044108102c2203450d04200320002d00043a0004200320002d00053a0005200320002d00063a0006200320002d00073a0007200341084110102c2203450d05200320002d00083a0008200320002d00093a0009200320002d000a3a000a200320002d000b3a000b200320002d000c3a000c200320002d000d3a000d200320002d000e3a000e200320002d000f3a000f200341104120102c2203450d06200320002d00103a0010200320002d00113a0011200320002d00123a0012200320002d00133a0013200320002d00143a0014200320002d00153a0015200320002d00163a0016200320002d00173a0017200320002d00183a0018200320002d00193a0019200320002d001a3a001a200320002d001b3a001b200320002d001c3a001c200320002d001d3a001d200320002d001e3a001e200320002d001f3a001f20032d0000210420032d000121052003102a200141206a2004200541087472410676220510fe0102402004413f71220320012802284f0d002001200128022020034105746a2203109d022001290300200141086a290300844200520d00200041086a2900002106200041106a2900002107200041186a290000210820032000290000370000200341186a2008370000200341106a2007370000200341086a2006370000200141306a41086a200141206a41086a280200360200200120012903203703302005200141306a10c5030c0a0b02402001280224450d002001280220102a0b200141306a200210fe010240200128023841c000490d000340200241016a210202402001280234450d002001280230102a0b200141306a200210fe012001280238413f4b0d000b0b200141106a41086a200141306a41086a2205280200220336020020012001290330370310200141306a41186a2209200041186a290000370300200141306a41106a220a200041106a2900003703002005200041086a29000037030020012000290000370330024020032001280214470d00200341016a22042003490d092003410174220b2004200b20044b1b220441ffffff3f712004470d092004410574220c4100480d090240024020030d00200c1028210b0c010b20012802102003410574200c102c210b0b200b450d08200120043602142001200b3602100b200320024106746a210b200128021020034105746a22042001290330370000200441086a2005290300370000200441106a200a290300370000200441186a20092903003700002001200341016a22033602180240200341c000470d00200141306a41086a220342003703002001420037033041f5b8c3004113200141306a1008200141206a41086a2003290300370300200120012903303703202001200241016a360230200141206a4110200141306a410410070b200141306a41086a2203200141106a41086a280200360200200120012903103703302002200141306a10c50320032000290000370300200141306a41106a200041086a290000370300200141306a41186a200041106a290000370300200141d0006a200041186a2900003703002001200b360234200141013a003041014100200141306a10cc010c090b41c4d1c3004133200141306a419cd9c3001038000b410141011037000b410241011037000b410441011037000b410841011037000b411041011037000b412041011037000b200c41011037000b1031000b200141a0016a24000b980102037f037e230041106b220224002002410036020420014120200241046a1006210302400240024020022802042204417f470d00420021050c010b20044110490d01200341086a2900002106200329000021072003102a200141201009420121050b2000200537030020002007370308200041106a2006370300200241106a24000f0b41c4d1c3004133200241086a419cd9c3001038000ba00803067f047e027f230041b0016b22012400024002400240410e10282202450d00200241002900fcae44370000200241066a4100290082af443700002001428e808080e00137026c200120023602682000200141e8006a108f01200128027021022001280268210320014188016a41186a2204420037030020014188016a41106a2205420037030020014188016a41086a2206420037030020014200370388012003200220014188016a1000200141286a41186a2004290300370300200141286a41106a2005290300370300200141286a41086a200629030037030020012001290388013703280240200128026c450d002001280268102a0b20014188016a200141286a412010fd01024020012d00880141014722020d00200141286a412010090b200141c8006a41186a2203200141a1016a2900002207370300200141c8006a41106a220420014199016a2900002208370300200141c8006a41086a220520014191016a29000022093703002001200129008901220a370348200141e8006a41186a22062007370300200141e8006a41106a220b2008370300200141e8006a41086a220c20093703002001200a370368024020020d00200141086a41186a20062903002207370300200141086a41106a200b2903002208370300200141086a41086a200c290300220937030020012001290368220a3703082003200737030020042008370300200520093703002001200a370348410e10282202450d022002410029008aaf44370000200241066a4100290090af443700002001428e808080e00137022c20012002360228200141c8006a200141286a108f01200128023021022001280228210320014188016a41186a2204420037030020014188016a41106a2205420037030020014188016a41086a2206420037030020014200370388012003200220014188016a1000200141e8006a41186a2004290300370300200141e8006a41106a2005290300370300200141e8006a41086a200629030037030020012001290388013703680240200128022c450d002001280228102a0b200141e8006a412010090b410d10282202450d0220024100290098af44370000200241056a410029009daf443700002001428d808080d00137024c200120023602482000200141c8006a108f01200128025021022001280248210320014188016a41186a2204420037030020014188016a41106a2205420037030020014188016a41086a2206420037030020014200370388012003200220014188016a1000200141e8006a41186a2004290300370300200141e8006a41106a2005290300370300200141e8006a41086a200629030037030020012001290388013703680240200128024c450d002001280248102a0b200141e8006a41201009200010a604200010a704200141b0016a24000f0b410e41011037000b410e41011037000b410d41011037000bd00a050a7f027e037f027e017f230041e0006b220224002002410036023820014120200241386a1006210302400240024002400240024002400240024020022802382204417f460d0020030d010b200041023a00000c010b2002200436021c200220033602182004450d0520032d0000210120022004417f6a36021c2002200341016a360218200141014b0d0502400240024020010e020001000b200241086a200241186a106c20022802080d07200228021c200228020c2205490d072005417f4c0d030240024020050d0041012106200228021c21070c010b2005102e2206450d092006200228021822012005109a051a200228021c22042005490d052002200420056b220736021c2002200120056a3602180b20074104490d0520022802182208280000210920022007417c6a220a36021c2002200841046a36021841002101200241003a0058417b210b03400240200a2001470d000240200141ff0171450d00200241003a00580b20050d080c090b200241386a20016a200820016a220441046a2d00003a000020022007200b6a36021c2002200441056a3602182002200141016a22043a0058200b417f6a210b2004210120044120470d000b200220022802383602302002200228003b3600330240024002400240200720046b220b417c6a4110490d00200241c7006a290000210c200229003f210d20022d0057210a2002280053210e200228004f210f2002200820046a220141146a22083602182002200b416c6a221036021c20104104490d002001410c6a2900002111200141046a2900002112200828000021082002200b41686a36021c2002200141186a2210360218200741686a2004460d0320102d000021102002200b41676a221336021c2002200141196a360218201041014b0d034100210420100e020201020b20050d090c0a0b20134104490d01200141196a28000021072002200b41636a36021c20022001411d6a360218410121040b2002200228003336002b20022002280230360228200220022802283602382002200228002b36003b200220022800203602102002200241236a280000360013410021012005210b0c020b2005450d070c060b41002101200241003a00582004417f6a21072004417e6a21040340024020072001470d00200141ff0171450d08200241003a00580c080b200241386a20016a200320016a220b41016a2d00003a00002002200b41026a3602182002200141016a220b3a00582002200436021c2004417f6a2104200b2101200b4120470d000b2002200228003b360033200220022802383602302002200228003336002b20022002280230360228200220022802283602102002200228002b360013200241c7006a2900002111200229003f2112200228004f21062002280053210b20022d005721052002200241236a28000036003b20022002280020360238410121010b2002200228021036023020022002280013360033200220022802383602282002200228003b36002b2003102a200041106a2011370300200041086a2012370300200041c3006a200c3700002000413b6a200d370000200020013a0000200041306a20073602002000412c6a2004360200200041286a2008360200200041246a2009360200200041206a20053602002000411c6a200b360200200041186a2006360200200041d3006a200a3a0000200041cf006a200e360000200041cb006a200f36000020002002280230360001200041046a2002280033360000200041346a2002280228360200200041376a200228002b3600000b200241e0006a24000f0b1036000b200520041044000b2005450d010b2006102a0b41c4d1c3004133200241206a419cd9c3001038000b200541011037000b870201057f230041d0006b220124000240411310282202450d00200241002900cef0423700002002410f6a41002800ddf042360000200241086a41002900d6f04237000020014293808080b002370224200120023602202000200141206a108f012001280228210220012802202100200141306a41186a22034200370300200141306a41106a22044200370300200141306a41086a220542003703002001420037033020002002200141306a1000200141186a2003290300370300200141106a2004290300370300200141086a20052903003703002001200129033037030002402001280224450d002001280220102a0b200141201009200141d0006a24000f0b411341011037000bd10402067f037e230041e0006b22052400024002400240411410282206450d00200641002900cfe140370000200641106a41002800dfe140360000200641086a41002900d7e14037000020054294808080c002370234200520063602302001200541306a108f012005280238210620052802302107200541c0006a41186a22084200370300200541c0006a41106a22094200370300200541c0006a41086a220a42003703002005420037034020072006200541c0006a1000200541106a41186a2008290300370300200541106a41106a2009290300370300200541106a41086a200a2903003703002005200529034037031002402005280234450d002005280230102a0b20054100360240200541106a4120200541c0006a100621060240024020052802402207417f470d004200210b4200210c0c010b20074110490d02200641086a290000210c2006290000210b2006102a0b410121060240200b20027d220d200b56200c20037d200b200254ad7d220b200c56200b200c511b4101470d00200041d7dfc000360204200041086a411d3602000c030b024002400240200d428080e983b1de16544100200b501b0d00200541086a20012004200d200b10bc0120052802082206450d02200528020c210120002006360204200041086a20013602000c010b200041f4dfc000360204200041086a411a3602000b410121060c030b2001200d200b108f02200041106a2003370300200041086a2002370300410021060c020b411441011037000b41c4d1c3004133200541c0006a419cd9c3001038000b20002006360200200541e0006a24000bdb0702067f087e23004180016b22022400024002400240411010282203450d0020034100290089e240370000200341086a4100290091e240370000200242908080808002370254200220033602502001200241d0006a108f012002280258210320022802502104200241e0006a41186a22054200370300200241e0006a41106a22064200370300200241e0006a41086a220742003703002002420037036020042003200241e0006a1000200241306a41186a2005290300370300200241306a41106a2006290300370300200241306a41086a20072903003703002002200229036037033002402002280254450d002002280250102a0b20024100360260200241306a4120200241e0006a1006210302400240024020022802602204417f460d002003450d00024020044110490d0020044170714110460d002004417c714120470d020b41c4d1c3004133200241e0006a419cd9c3001038000b42002108420021090c010b200341086a290000210a2003290000210b200341186a290000210c20032900102108200328002021042003102a411410282203450d02200341002900cfe140370000200341106a41002800dfe140360000200341086a41002900d7e14037000020024294808080c002370254200220033602502001200241d0006a108f012002280258210320022802502101200241e0006a41186a22054200370300200241e0006a41106a22064200370300200241e0006a41086a220742003703002002420037036020012003200241e0006a1000200241306a41186a2005290300370300200241306a41106a2006290300370300200241306a41086a20072903003703002002200229036037033002402002280254450d002002280250102a0b20024100360260200241306a4120200241e0006a100621030240024020022802602201417f470d004200210d420021090c010b20014110490d04200341086a29000021092003290000210d2003102a0b4200210e200241106a200c42004100109801220320046b2201200120034b1bad220f4200109f05200241206a200f420020084200109f0520024200420020084200109f054200210802402002290308200229031884420052200241286a290300220f200229030020022903107c7c220c200f54720d00200a200c200b2002290320220e56200a200c56200a200c511b22031b200c7d200b200e20031b220c200e54ad7d2108200c200e7d210e0b20082009200d200e56200920085620092008511b22031b2109200e200d20031b21080b200020083703002000200937030820024180016a24000f0b411041011037000b411441011037000b41c4d1c3004133200241e0006a419cd9c3001038000baf07030b7f037e037f230041f0006b22022400024002400240024002400240410e10282203450d00200341002900fbe140370000200341066a4100290081e2403700002002428e808080e001370234200220033602302001200241306a108f012002280238210320022802302101200241c0006a41186a22044200370300200241c0006a41106a22054200370300200241c0006a41086a220642003703002002420037034020012003200241c0006a1000200241106a41186a2004290300370300200241106a41106a2005290300370300200241106a41086a20062903003703002002200229034037031002402002280234450d002002280230102a0b20024100360240200241106a4120200241c0006a100621070240024020022802402208417f460d002002200836023420022007360230200241086a200241306a106c20022802080d07200228023422034160712201417f4c0d03200228020c2109024002402003410576220a0d004108210b0c010b20011028220b450d050b02402009450d004100210c41002106410021050340200241c0006a200241306a109b020240024020022d00404101460d00200228023422014110490d002002290041210d20022002280230220341106a3602302002200141706a220436023420044104490d00200341086a290000210e2003290000210f20022001416c6a22043602342002200341146a36023020040d010b200a450d0a200b102a0c0a0b200541016a210420032800102110200241e6006a41026a200241ed006a41026a2d000022113a0000200241e2006a41026a221220113a000020022001416b6a3602342002200341156a360230200220022f006d22013b0166200220013b016220032d0014210102402005200a470d00200c2004200c20044b1b220a41ffffff3f71200a470d09200a41057422034100480d090240024020050d0020031028210b0c010b200b20062003102c210b0b200b450d080b200b20066a2203411c6a20013a00002003200e3703082003200f370300200341146a200d370200200341106a20103602002003411d6a20022f01623b00002003411f6a20122d00003a0000200c41026a210c200641206a21062004210520092004470d000b0b200b450d072009ad422086200aad84210d02402008450d002007102a0b2000200d3702042000200b3602000c010b20004100360208200042083702000b200241f0006a24000f0b410e41011037000b1036000b200141081037000b200341081037000b1031000b41c4d1c3004133200241c0006a419cd9c3001038000bf00204027f017e017f077e0240024020012802042202450d0020012802002203310000210420012002417f6a22053602042001200341016a3602002005450d012003310001210620012002417e6a22053602042001200341026a3602002005450d012003310002210720012002417d6a22053602042001200341036a3602002005450d012003310003210820012002417c6a22053602042001200341046a3602002005450d012003310004210920012002417b6a22053602042001200341056a3602002005450d012003310005210a20012002417a6a22053602042001200341066a3602002005450d012003310006210b2001200241796a22053602042001200341076a3602002005450d01200041003a00002003310007210c2001200241786a3602042001200341086a3602002000200c423886200b42308684200a422886842009422086842008421886842007421086842006420886842004843700010f0b200041013a00000f0b200041013a00000bce1003077f027e027f230041d0006b220224000240024002400240024002400240024002400240024002400240410e10282203450d00200341002900fbe140370000200341066a4100290081e2403700002002428e808080e001370224200220033602202000200241206a108f012002280228210320022802202100200241306a41186a22044200370300200241306a41106a22054200370300200241306a41086a220642003703002002420037033020002003200241306a1000200241186a2004290300370300200241106a2005290300370300200241086a20062903003703002002200229033037030002402002280224450d002002280220102a0b200128020021072001280208210320024100360238200242013703302003200241306a10b40102402003450d002003410574210841002106034002400240200228023420022802382203460d00200228023021000c010b200341016a22002003490d0f200341017422042000200420004b1b22044100480d0f0240024020030d002004102821000c010b200228023020032004102c21000b2000450d042002200436023420022000360230200228023821030b2002200341016a360238200020036a200720066a220341146a2d00003a000002400240200228023420022802382200460d00200228023021040c010b200041016a22042000490d0f200041017422052004200520044b1b22054100480d0f0240024020000d002005102821040c010b200228023020002005102c21040b2004450d052002200536023420022004360230200228023821000b2002200041016a360238200420006a200341156a2d00003a000002400240200228023420022802382200460d00200228023021040c010b200041016a22042000490d0f200041017422052004200520044b1b22054100480d0f0240024020000d002005102821040c010b200228023020002005102c21040b2004450d062002200536023420022004360230200228023821000b2002200041016a360238200420006a200341166a2d00003a000002400240200228023420022802382200460d00200228023021040c010b200041016a22042000490d0f200041017422052004200520044b1b22054100480d0f0240024020000d002005102821040c010b200228023020002005102c21040b2004450d072002200536023420022004360230200228023821000b2002200041016a360238200420006a200341176a2d00003a000002400240200228023420022802382200460d00200228023021040c010b200041016a22042000490d0f200041017422052004200520044b1b22054100480d0f0240024020000d002005102821040c010b200228023020002005102c21040b2004450d082002200536023420022004360230200228023821000b2002200041016a360238200420006a200341186a2d00003a000002400240200228023420022802382200460d00200228023021040c010b200041016a22042000490d0f200041017422052004200520044b1b22054100480d0f0240024020000d002005102821040c010b200228023020002005102c21040b2004450d092002200536023420022004360230200228023821000b2002200041016a360238200420006a200341196a2d00003a000002400240200228023420022802382200460d00200228023021040c010b200041016a22042000490d0f200041017422052004200520044b1b22054100480d0f0240024020000d002005102821040c010b200228023020002005102c21040b2004450d0a2002200536023420022004360230200228023821000b2002200041016a360238200420006a2003411a6a2d00003a000002400240200228023420022802382200460d00200228023021040c010b200041016a22042000490d0f200041017422052004200520044b1b22054100480d0f0240024020000d002005102821040c010b200228023020002005102c21040b2004450d0b2002200536023420022004360230200228023821000b2002200041016a360238200420006a2003411b6a2d00003a0000200341086a29030021092003290300210a0240024020022802342205200228023822046b4110490d00200228023021000c010b200441106a22002004490d0f200541017422042000200420004b1b220b4100480d0f0240024020050d00200b102821000c010b20022802302005200b102c21000b2000450d0c2002200b3602342002200036023020022802382104200b21050b200020046a220b2009370008200b200a3700002002200441106a2204360238200341106a280200210b0240200520046b41034b0d00200441046a220c2004490d0f20054101742204200c2004200c4b1b22044100480d0f0240024020050d002004102821000c010b200020052004102c21000b2000450d0d2002200436023420022000360230200228023821040b2002200441046a360238200020046a200b36000002400240200228023420022802382200460d00200228023021040c010b200041016a22042000490d0f200041017422052004200520044b1b22054100480d0f0240024020000d002005102821040c010b200228023020002005102c21040b2004450d0e2002200536023420022004360230200228023821000b2002200041016a360238200420006a2003411c6a2d00003a00002008200641206a2206470d000b0b2002280234210320024120200228023022002002280238100702402003450d002000102a0b0240200141046a280200450d002007102a0b200241d0006a24000f0b410e41011037000b200441011037000b200541011037000b200541011037000b200541011037000b200541011037000b200541011037000b200541011037000b200541011037000b200b41011037000b200441011037000b200541011037000b1031000bd00502067f047e230041d0006b220224000240024002400240411410282203450d00200341002900cfe140370000200341106a41002800dfe140360000200341086a41002900d7e14037000020024294808080c002370224200220033602202001200241206a108f012002280228210320022802202104200241306a41186a22054200370300200241306a41106a22064200370300200241306a41086a220742003703002002420037033020042003200241306a1000200241186a2005290300370300200241106a2006290300370300200241086a20072903003703002002200229033037030002402002280224450d002002280220102a0b2002410036023020024120200241306a100621030240024020022802302204417f470d0042002108420021090c010b20044110490d02200341086a2900002109200329000021082003102a0b411810282203450d02200341002900e3e140370000200341106a41002900f3e140370000200341086a41002900ebe140370000200242988080808003370224200220033602202001200241206a108f012002280228210320022802202101200241306a41186a22044200370300200241306a41106a22054200370300200241306a41086a220642003703002002420037033020012003200241306a1000200241186a2004290300370300200241106a2005290300370300200241086a20062903003703002002200229033037030002402002280224450d002002280220102a0b2002410036023020024120200241306a100621030240024020022802302201417f470d004200210a4200210b0c010b20014110490d04200341086a290000210b2003290000210a2003102a0b2000200a20087c22083703002000200b20097c2008200a54ad7c370308200241d0006a24000f0b411441011037000b41c4d1c3004133200241306a419cd9c3001038000b411841011037000b41c4d1c3004133200241306a419cd9c3001038000bf00906017f037e017f017e017f037e230041c0016b220724004200210842002109024020050d00200741f0006a2006ad42004280c8afa0254200109f05200741f8006a2903002007290370220a4280a094a58d1d7c2208200a54ad7c21090b20074180016a41086a22054200370300200742003703800141bfa0c600411b20074180016a1008200741a0016a41086a220b200529030037030020072007290380013703a001200741e0006a200741a0016a109f02200728026021052007290368210a2007418094ebdc03360284012007200a420020051b220a200a423f87220c7c200c85220c200c428094ebdc037f220c4280ec94a37c7e7ca7220536028001200741d0006a417f2004418094ebdc032004418094ebdc03491b2204417f417f2004ad200ca7417f200c428080808010541bad7e220ca7200c422088a71b220620074180016a2005418094ebdc034b4102746a28020022052004418094ebdc036e220d6c2005ad2004200d4180ec94a37c6c6aad7e428094ebdc0380a76a6a220520052006491b22056a220620062004491b4100200420056b2205200520044b1b200a4200551bad420042e8074200109f0520074180016a2003427f200820072903507c220a20017c220c200c200a5422042009200741d0006a41086a2903007c200a200854ad7c220820027c2004ad7c220a200854200a2008511b22041b220e427f200a20041b220f4101109802024002402007280280014101470d0020004180023b0001200041013a0000200041036a41003a00000c010b200741206a2007290388012209420042044200109f05200741106a4200420020094200109f05200741306a2007290320200741206a41086a290300220820074180016a41106a290300220a42028620072903107c7c220c4205420010a00520072903182101200741306a41086a29030021022007290330211020074180016a10d301200741c0006a20074180016a42b3e6cc99b3e6cc99332010200a200a42ffffffffffffffff3f8352200142005272200c2008547222041b22082009200820095442b3e6cc99b3e6cc9933200220041b220c200a54200c200a511b22041b2208200c200a20041b220c10d001200741a0016a41106a200c200741c0006a41086a29030022027d20082007290340220154ad7d2002200c7d2001200854ad7d20012008582002200c582002200c5122041b22051b3703002007200820017d200120087d20051b3703a801200720012008562002200c5620041b2204ad3703a001200a200c7d2009200854ad7d210a200920087d21080240024020040d002007200b3602bc01200741bc016a109d010c010b2007200b3602bc01200741bc016a109c010b20074180016a10f801200720074180016a2008200a10d001200741b0016a200a200741086a29030022097d20082007290300220c54ad7d2009200a7d200c200854ad7d200c2008582009200a582009200a5122041b22051b37030020072008200c7d200c20087d20051b3703a8012007200c2008562009200a5620041b2204ad3703a001200741a0016a41086a21050240024020040d00200720053602bc01200741bc016a109d010c010b200720053602bc01200741bc016a109c010b200041306a41013a0000200041286a4200370300200041206a4280808080c000370300200041186a4204370300200041106a427f370300200041086a200e427f200f501b370300200041003a00000b200741c0016a24000b820102027f027e230041106b220224002002410036020420014110200241046a100621010240024020022802042203417f460d002001450d00024020034108490d00200129000021042001102a420121050c020b41c4d1c3004133200241086a419cd9c3001038000b420021050b2000200437030820002005370300200241106a24000b1300200041033602042000419ce2c0003602000bc70104017f017e027f017e230041206b2201240042002102200141106a41086a220342003703002001420037031041ace1c0004116200141106a1008200141086a2003290300370300200120012903103703002001410036021020014110200141106a1006210302400240024020012802102204417f470d00420021050c010b20044110490d01200341086a2900002105200329000021022003102a0b2000200237030020002005370308200141206a24000f0b41c4d1c3004133200141106a419cd9c3001038000b3400200041b2f3c00036020420004100360200200041146a4105360200200041106a41bcf3c000360200200041086a42083702000b3701017f02404110102822020d00411041011037000b2002420037000820024200370000200042908080808002370204200020023602000b130020004105360204200041d884c1003602000be70302067f037e230041e0006b2204240020042001109d0202400240024002402004290300200441086a29030084500d00411410282205450d02200541002900cfe140370000200541106a41002800dfe140360000200541086a41002900d7e14037000020044294808080c002370234200420053602302001200441306a108f012004280238210520042802302106200441c0006a41186a22074200370300200441c0006a41106a22084200370300200441c0006a41086a220942003703002004420037034020062005200441c0006a1000200441106a41186a2007290300370300200441106a41106a2008290300370300200441106a41086a20092903003703002004200429034037031002402004280234450d002004280230102a0b20044100360240200441106a4120200441c0006a100621050240024020042802402206417f470d004200210a4200210b0c010b20064110490d04200541086a290000210b2005290000210a2005102a0b2001200a20027c220c200b20037c200c200a54ad7c108f02200041106a2003370300200041086a2002370300410021010c010b200041b5dfc000360204200041086a4122360200410121010b20002001360200200441e0006a24000f0b411441011037000b41c4d1c3004133200441c0006a419cd9c3001038000b130020004101360204200041f88ac1003602000b3400200041b18cc10036020420004100360200200041146a4103360200200041106a41bc8cc100360200200041086a42083702000bef0a09037f017e067f037e017f027e077f017e017f230041306b2203240010980121042000280000210520003500042106200341106a2001109a02200328021021072003280214210802400240024002400240024002400240024020032802182209450d0020072009410574220a6a210b200341246a210c200721090340200941086a290300210d200941106a290300210e2009290300210f200341106a41186a200941186a290300370300200341106a41106a200e370300200341106a41086a200d3703002003200f370310200c2000460d02200c2900002000290000510d0202402003280220221020044d0d002003410e6a2003412f6a2d00003a0000200320032f002d3b010c200341186a290300210f427f210e200329031021114201210d20032d002c210c200329022421120c040b200941206a2109200a41606a220a0d000b0b41082113410021102008450d022007102a0c020b2003280220220c2002200c20024b1b211020032d002c410272210c427f21114200210e41002102200329022421124200210d41002105427f210f0b200341026a22142003410c6a41026a2d00003a0000200320032f010c3b010002400240412010282213450d00201320113703002013200c3a001c2013201237021420132010360210201320032f01003b001d2013200f3703082013411f6a20142d00003a000002400240200a4120470d0041012110200e210f410121140c010b200941206a2115200b41606a21162003412d6a2117200341246a210c200e210f4101211041012114034020152109024002400340200341106a41186a200941186a290300370300200341106a41106a200941106a290300370300200341106a41086a220a200941086a2903003703002003200929030037031002400240200c2000460d00200c2900002000290000510d002003280220221820044d0d012003410c6a41026a201741026a2d00003a0000200320172f00003b010c200a29030021112003290310211220032d002c21192003290224211a0c040b200d4201510d024200210e410021024200210f4200210d410021050b200b200941206a2209470d000c040b0b200a290300220d200f20032903102212200e56200d200f56200d200f511b220a1b21112012200e200a1b21122003280220220a2002200a20024b1b211820032d002c41027221194200210e410021022003290224211a4200210f4200210d410021050b200341046a41026a2003410c6a41026a2d0000220a3a0000200320032f010c22153b0104200341106a41026a221b200a3a0000200320153b0110024020142010470d00201041016a220a2010490d0a20104101742214200a2014200a4b1b221441ffffff3f712014470d0a2014410574220a4100480d0a0240024020100d00200a102821130c010b20132010410574200a102c21130b2013450d040b200941206a2115201320104105746a220a20193a001c200a2011370308200a2012370300200a201a370214200a2018360210200a20032f01103b001d200a411f6a201b2d00003a0000201041016a211020162009470d000b0b02402008450d002007102a0b200d4201520d0520102014470d040c030b412041081037000b200a41081037000b427f210e427f210f0b201041016a22092010490d03201041017422002009200020094b1b221441ffffff3f712014470d03201441057422094100480d030240024020100d002009102821130c010b201320104105742009102c21130b2013450d020b201320104105746a2209200f3703082009200e3703002009200536021420092002360210200941186a200642808080802084370300201041016a21100b2003201036021820032014360214200320133602102001200341106a109c02200341306a24000f0b200941081037000b1031000bef0a07037f027e047f087e017f047e027f230022062107200641c0006b41607122062400109801210820062003370310200620023703082006200436021842012109200642013703002006200028000036021c20003500042102200641206a2001109a0220022005ad42ff018342208684210a2006280220210b2006280224210c0240024002400240024020062802282205450d00200b200541057422046a210d200641346a210e2006290300220921032006290308220f2110200629031022112112200629031822132114200b21050340200541086a2903002102200541106a290300211520052903002116200641206a41186a200541186a290300370300200641206a41106a22172015370300200641206a41086a20023703002006201637032002400240200e2000460d00200e2900002000290000510d000240200628023020084b0d0020032102420021030c020b20172903002118200629032821192006290320211a2006290338211b20032102420121030c010b420021094200210f420021114200211342002102200a211b2010211a20122119201421180b20034201510d02200541206a210520022103200441606a22040d000b200620093703002006200f37030820062011370310200620133703180b41002104200c450d01200b102a0c010b200620023703002006201037030820062012370310200620143703180240412010282217450d002017201b3703182017201a37030020172019370308201741106a201837030002400240024020044120470d0041012104200221094101211c0c010b200541206a2105200641346a211d20022109410121044101211c034002400240201d2000460d00200221030340200641206a41186a200541186a290300370300200641206a41106a220e200541106a290300370300200641206a41086a200541086a2903003703002006200529030037032002400240201d2900002000290000510d000240200628023020084b0d0020032102420021030c020b200e290300211b20062903282116200629032021152006290338211a20032102420121030c010b42002109200642003703004200210220102115201221162014211b200a211a0b024020034201510d0020022103200d200541206a2205470d010c050b0b200541206a21050c010b024003402006420037030020024201510d0142002102200d200541206a2205470d000b420021090c030b200541206a2105420021094200210220102115201221162014211b200a211a0b0240201c2004470d00200441016a220e2004490d072004410174221c200e201c200e4b1b221c41ffffff3f71201c470d07201c410574220e4100480d070240024020040d00200e102821170c010b20172004410574200e102c21170b2017450d030b201720044105746a220e2016370308200e2015370300200e41106a201b370300200e41186a201a370300200441016a21042005200d470d000b0b200c450d03200b102a0c030b200e41081037000b412041081037000b4100211c410821170b0240024020094201520d00200641206a41106a22002006410872220541106a290300370300200641206a41086a220e200541086a2903003703002006200529030037032002402004201c470d00200441016a22052004490d03200441017422082005200820054b1b221c41ffffff3f71201c470d03201c41057422054100480d030240024020040d002005102821170c010b201720044105742005102c21170b2017450d020b201720044105746a22052006290320370300200541106a2000290300370300200541086a200e290300370300200541186a200a370300200441016a21040b200620043602282006201c360224200620173602202001200641206a109c02200724000f0b200541081037000b1031000bff0502067f057e230041d0006b220324000240024002400240411810282204450d00200441002900e3e140370000200441106a41002900f3e140370000200441086a41002900ebe140370000200342988080808003370224200320043602202000200341206a108f012003280228210420032802202105200341306a41186a22064200370300200341306a41106a22074200370300200341306a41086a220842003703002003420037033020052004200341306a1000200341186a2006290300370300200341106a2007290300370300200341086a20082903003703002003200329033037030002402003280224450d002003280220102a0b2003410036023020034120200341306a100621040240024020032802302205417f470d00420021094200210a0c010b20054110490d02200441086a290000210a200429000021092004102a0b411410282204450d02200441002900cfe140370000200441106a41002800dfe140360000200441086a41002900d7e14037000020034294808080c002370224200320043602202000200341206a108f012003280228210420032802202105200341306a41186a22064200370300200341306a41106a22074200370300200341306a41086a220842003703002003420037033020052004200341306a1000200341186a2006290300370300200341106a2007290300370300200341086a20082903003703002003200329033037030002402003280224450d002003280220102a0b2003410036023020034120200341306a100621040240024020032802302205417f470d004200210b4200210c0c010b20054110490d04200441086a290000210c2004290000210b2004102a0b2000200b200120092009200156200a200256200a2002511b22041b22017c220d200c2002200a20041b22027c200d200b54ad7c108f022000200920017d200a20027d2009200154ad7d109002200341d0006a24000f0b411841011037000b41c4d1c3004133200341306a419cd9c3001038000b411441011037000b41c4d1c3004133200341306a419cd9c3001038000bc70301047f230041106b2203240020034100360208200342013703002001200310b40102400240024002402001450d00200141216c210403400240024020002d00004101460d0002400240200328020420032802082201460d00200328020021050c010b200141016a22052001490d07200141017422062005200620054b1b22064100480d070240024020010d002006102821050c010b200328020020012006102c21050b2005450d052003200636020420032005360200200328020821010b2003200141016a360208200520016a41003a00000c010b02400240200328020420032802082201460d00200328020021050c010b200141016a22052001490d06200141017422062005200620054b1b22064100480d060240024020010d002006102821050c010b200328020020012006102c21050b2005450d052003200636020420032005360200200328020821010b2003200141016a360208200520016a41013a0000200041016a2003108f010b200041216a21002004415f6a22040d000b0b2003280204210020022802002002280204200328020022012003280208100702402000450d002001102a0b200341106a24000f0b200641011037000b200641011037000b1031000bdb0401057f230041106b2203240020034100360208200342013703002002200310b401024002400240024002402002450d0020024190016c2104034020032802042105200328020821020240024020012802004113470d000240024020052002460d00200328020021050c010b200241016a22052002490d08200241017422062005200620054b1b22064100480d080240024020020d002006102821050c010b200328020020022006102c21050b2005450d052003200636020420032005360200200328020821020b2003200241016a360208200520026a41003a00000c010b0240024020052002460d00200328020021050c010b200241016a22052002490d07200241017422062005200620054b1b22064100480d070240024020020d002006102821050c010b200328020020022006102c21050b2005450d052003200636020420032005360200200328020821020b2003200241016a360208200520026a41013a00002001200310eb0120014188016a28020021060240024020032802042205200328020822026b4104490d00200328020021050c010b200241046a22072002490d07200541017422022007200220074b1b22024100480d070240024020050d002002102821050c010b200328020020052002102c21050b2005450d062003200236020420032005360200200328020821020b2003200241046a360208200520026a20063600000b20014190016a2101200441f07e6a22040d000b0b20002003290300370200200041086a200341086a280200360200200341106a24000f0b200641011037000b200641011037000b200241011037000b1031000b6801037f024041094101200128020022024101461b220310282204450d000240024020020d00200441003a0000410121010c010b200441013a000020042001290204370001410921010b2000200136020820002003360204200020043602000f0b200341011037000bcc0902057f027e230041c0006b22022400024002400240024002402001280200417f6a220341024b0d0020030e03010203010b41a091c1001032000b410121030240024020012d00044101460d00200241026a200141046a220341036a2d00003a0000200241206a41086a200141146a290200370300200241306a2001411c6a290200370300200241386a200141246a2d00003a0000200220032f00013b010020022001410c6a290200370320200141086a2802002104410021030c010b200141086a28020021040b200020033a0004200020022f01003b000520004101360200200041286a2001290328370300200041086a20043602002000410c6a2002290320370200200041306a200141306a290300370300200041076a200241026a2d00003a0000200041146a200241206a41086a2903003702002000411c6a200241306a290300370200200041246a200241386a2802003602000c020b410121030240024020012d00044101460d00200241026a200141046a220341036a2d00003a0000200241206a41086a200141146a290200370300200241306a2001411c6a290200370300200241386a200141246a2d00003a0000200220032f00013b010020022001410c6a290200370320200141086a2802002104410021030c010b200141086a28020021040b200020033a0004200020022f01003b0005200041286a2001290328370300200041386a2001290338370300200041086a20043602002000410c6a2002290320370200200041306a200141306a290300370300200041c0006a200141c0006a290300370300200041076a200241026a2d00003a0000200041146a200241206a41086a2903003702002000411c6a200241306a290300370200200041246a200241386a280200360200200041023602000c010b200141286a2103410121040240024020012d00044101460d002002411e6a200141046a220441036a2d00003a0000200241086a200141146a290200370300200241106a2001411c6a290200370300200241186a200141246a2d00003a0000200220042f00013b011c20022001410c6a290200370300200141086a2802002105410021040c010b200141086a28020021050b410121060240024020032d00004101460d002002413e6a200341036a2d00003a0000200241286a200141386a290200370300200241306a200141c0006a290200370300200241386a200141c8006a2d00003a0000200220032f00013b013c2002200141306a2902003703202001412c6a2802002103410021060c010b2001412c6a28020021030b200020043a0004200020022f011c3b0005200020022f013c3b0029200041086a20053602002000410c6a2002290300370200200041286a20063a0000200041076a2002411c6a41026a2d00003a0000200041146a200241086a2903003702002000411c6a200241106a290300370200200041246a200241186a2802003602002000412b6a2002413c6a41026a2d00003a0000200141d8006a2903002107200129035021082000412c6a2003360200200041d0006a2008370300200041d8006a200737030020004103360200200041306a2002290320370200200041386a200241206a41086a290300370200200041c0006a200241206a41106a290300370200200041c8006a200241206a41186a2802003602000b200241c0006a24000b960403077f017e067f02400240024002402001410c6a2802002202417f4c0d0020012802042103200128020021040240024020020d0041012105410021060c010b20022106200210282205450d020b200520032002109a052107200141186a2802002208ad420c7e2209422088a70d002009a72203417f4c0d002001280210210a0240024020030d004104210b0c010b20031028220b450d030b0240024020080d004100210c0c010b200a2008410c6c6a210d4100210c200b21050340200a41086a2802002203417f4c0d02200a280200210e0240024020030d004101210f0c010b20031028220f450d060b200f200e2003109a05210e200541086a2003360200200541046a20033602002005200e3602002005410c6a2105200c41016a210c200a410c6a220a200d470d000b0b20002007360204200020043602002000200129021c37021c200041186a200c360200200041146a2008360200200041106a200b3602002000410c6a2002360200200041086a2006360200200020012902243702242000412c6a2001412c6a290200370200200041346a200141346a2902003702002000413c6a2001413c6a290200370200200041c4006a200141c4006a290200370200200041cc006a200141cc006a290200370200200041d4006a200141d4006a290200370200200041dc006a200141dc006a2902003702000f0b1036000b200241011037000b200341041037000b200341011037000bd90303027f017e027f02402001450d00034020002802e40121002001417f6a22010d000b0b02402002450d004100210341002101034002400240200120002f01064f0d0020002001410c6c6a220441e4006a2902002105200441e0006a2802002104200141016a21010c010b02400240200028020022010d002003ad210541002106410021010c010b20003301044220862003ad842105410121060b2000102a2005a72103024002402005422088a7220720012f01064f0d00200121040c010b034002400240200128020022040d002003ad2105410021040c010b200641016a210620013301044220862003ad8421050b2001102a2005a72103200421012005422088a7220720042f01064f0d000b0b200741027420046a41e8016a280200210020042007410c6c6a220141e4006a2902002105200141e0006a280200210402402006417f6a2201450d00034020002802e40121002001417f6a22010d000b0b410021010b2004450d012002417f6a210202402005a7450d002004102a0b20020d000b0b0240200041f8b9c000460d00200028020021012000102a2001450d00200128020021042001102a2004450d00024020042802002201450d0003402004102a2001210420012802002200210120000d000b0b2004102a0b0bd308030d7f017e017f230041a0016b2202240002400240024020012802202203450d0020012003417f6a36022020012802082104200128020c2205200128020422062f01064f0d01200241186a2207200620054105746a220341206a290000370300200241106a2208200341186a290000370300200241086a2209200341106a2900003703002002200341086a290000370300200241206a41286a220a2006200541306c6a22034190036a290300370300200241206a41206a220b20034188036a290300370300200241206a41186a220c20034180036a290300370300200241206a41106a220d200341f8026a290300370300200241206a41086a220e200341f0026a290300370300200341e8026a290300210f2001200541016a36020c20012004360208200120063602042002200f370320200241d0006a41186a2007290300370300200241d0006a41106a2008290300370300200241d0006a41086a200929030037030020022002290300370350200241d0006a41286a200e290300370300200241d0006a41306a200d29030037030020024188016a200c29030037030020024190016a200b29030037030020024198016a200a290300370300200220022903203703702000200241d0006a41d000109a051a0c020b200041003602400c010b2001280200210702400240200628020022030d002004ad210f410021030c010b200741016a210720063301044220862004ad84210f0b2006102a200fa7210502400240200f422088a7220420032f01064f0d00200321060c010b034002400240200328020022060d002005ad210f410021060c010b200741016a210720033301044220862005ad84210f0b2003102a200fa7210520062103200f422088a7220420062f01064f0d000b0b200241186a2208200620044105746a220341206a290000370300200241106a2209200341186a290000370300200241086a220a200341106a2900003703002002200341086a290000370300200241206a41286a220b2006200441306c6a22034190036a290300370300200241206a41206a220c20034188036a290300370300200241206a41186a220d20034180036a290300370300200241206a41106a220e200341f8026a290300370300200241206a41086a2210200341f0026a2903003703002002200341e8026a290300370320200441027420066a41fc066a280200210302402007417f6a2206450d00034020032802f80621032006417f6a22060d000b0b2001410036020c200120053602082001200336020420014100360200200241d0006a41186a2008290300370300200241d0006a41106a2009290300370300200241d0006a41086a200a290300370300200241d0006a41286a2010290300370300200241d0006a41306a200e29030037030020024188016a200d29030037030020024190016a200c29030037030020024198016a200b29030037030020022002290300370350200220022903203703702000200241d0006a41d000109a051a0b200241a0016a24000bbd0301057f230041106b2203240002400240024002400240200141046a2204417f4c0d000240024020040d00410121050c010b200410282205450d020b2003410036020820032004360204200320053602002001200310b4010240024020032802042206200328020822056b2001490d00200328020021040c010b200520016a22042005490d05200641017422072004200720044b1b22074100480d050240024020060d002007102821040c010b200328020020062007102c21040b2004450d032003200736020420032004360200200721060b200420056a20002001109a051a02400240200241046a2802002207200241086a28020022006b200520016a2201490d00200228020021050c010b200020016a22052000490d05200741017422002005200020054b1b22004100480d050240024020070d002000102821050c010b200228020020072000102c21050b2005450d0420022005360200200241046a2000360200200241086a28020021000b200241086a200020016a360200200520006a20042001109a051a02402006450d002004102a0b200341106a24000f0b1036000b200441011037000b200741011037000b200041011037000b1031000b880201057f230041d0006b220224000240411710282203450d00200341002900f1d8433700002003410f6a4100290080d943370000200341086a41002900f9d84337000020024297808080f002370224200220033602202000200241206a108f012002280228210320022802202100200241306a41186a22044200370300200241306a41106a22054200370300200241306a41086a220642003703002002420037033020002003200241306a1000200241186a2004290300370300200241106a2005290300370300200241086a20062903003703002002200229033037030002402002280224450d002002280220102a0b2002200110e203200241d0006a24000f0b411741011037000b1000200028020020002802042001105f0baf0201037f23004180016b2202240002400240024002400240200128020022034110710d002000280200210420034120710d012004ad41012001103f21000c020b20002802002104410021000340200220006a41ff006a2004410f712203413072200341d7006a2003410a491b3a00002000417f6a2100200441047622040d000b20004180016a22044181014f0d0220014101419087c0004102200220006a4180016a410020006b104221000c010b410021000340200220006a41ff006a2004410f712203413072200341376a2003410a491b3a00002000417f6a2100200441047622040d000b20004180016a22044181014f0d0220014101419087c0004102200220006a4180016a410020006b104221000b20024180016a240020000f0b20044180011044000b20044180011044000b130020004101360204200041cc9ac1003602000b130020004102360204200041849cc1003602000b3101017f02404104102822020d00410441011037000b20004284808080c00037020420002002360200200241e8073600000b3101017f02404104102822020d00410441011037000b20004284808080c00037020420002002360200200241e5003600000bd20903067f017e057f230041f0016b22022400024002400240024002400240024020012802042203450d00200128020022042d0000210520012003417f6a22063602042001200441016a3602002005417f6a220541014b0d0520050e020102010b200041023a00000c050b20064104490d012004280001210720012003417b6a22053602042001200441056a36020020054108490d02200429000521082001200341736a36020420012004410d6a36020041002105200241003a00b001410d20036b2109200341726a210603400240200920056a0d000240200541ff0171450d00200241003a00b0010b200041023a00000c060b20024190016a20056a200420056a220a410d6a2d00003a0000200120063602042001200a410e6a3602002002200541016a220a3a00b0012006417f6a2106200a2105200a4120470d000b200241f0006a41186a20024190016a41186a290300370300200241f0006a41106a20024190016a41106a290300370300200241f0006a41086a20024190016a41086a290300370300200220022903900137037041002105200241003a00d0012004200a6a2109200a20036b410d6a210a03400240200a20056a0d000240200541ff0171450d00200241003a00d0010b200041023a00000c060b20024190016a20056a200920056a2204410d6a2d00003a00002001200636020420012004410e6a3602002002200541016a22043a00d0012006417f6a210620042105200441c000470d000b200241106a41386a220120024190016a41386a290300370300200241106a41306a220520024190016a41306a290300370300200241106a41286a220620024190016a41286a290300370300200241106a41206a220420024190016a41206a290300370300200241106a41186a220a20024190016a41186a290300370300200241106a41106a220320024190016a41106a290300370300200241106a41086a220920024190016a41086a290300370300200241d0006a41086a220b200241f0006a41086a290300370300200241d0006a41106a220c200241f0006a41106a290300370300200241d0006a41186a220d200241f0006a41186a290300370300200220022903900137031020022002290370370350200041003a000020002002290350370001200041096a200b290300370000200041116a200c290300370000200041196a200d290300370000200041216a2002290310370000200041296a2009290300370000200041316a2003290300370000200041396a200a290300370000200041c1006a2004290300370000200041c9006a2006290300370000200041d1006a2005290300370000200041d9006a2001290300370000200041e3006a2002410f6a2d00003a0000200041e1006a20022f000d3b0000200041e8006a2008370300200041e4006a20073602000c040b0240024020064104490d002004280001210620012003417b6a22053602042001200441056a360200200541084f0d010b200041023a00000c040b200041013a0000200020022f00103b0001200429000521082001200341736a36020420012004410d6a360200200041086a2008370300200041046a2006360200200041036a200241126a2d00003a0000200041106a20024190016a41e000109a051a0c030b200041023a00000c020b200041023a00000c010b200041023a00000b200241f0016a24000be71207027f017e057f027e017f017e0a7f230041b0036b2202240020002802102203200328020041016a36020020002902142104200028020c2103200028020821052000280200210620002802042100200241f0016a41086a2207200141086a280200360200200220012902003703f001024002400240024020002f01062201410b490d00200241d0026a410272410041da001099051a200241386a41004184011099051a0240024041e40110282208450d0020084100360200200841046a200241d0026a41dc00109a051a200841e0006a200241386a418401109a052107200241386a41086a2209200041b0016a280200360200200220002902a8013703382000413c6a330000210a2000413e6a310000210b20002d003f210c2000350038210d200841086a200041c0006a20002f010641796a2201410374109a05210e2007200041b4016a2001410c6c109a052107200041063b0106200820013b0106200241d0026a41086a2009280200360200200220022903383703d002200d200a200b4210868442208684210a0240024020034107490d002003410374200e6a41506a200e200341796a22094103746a220e200141ffff037120096b410374109b051a200e20043700002003410c6c20076a220341b87f6a200341ac7f6a2203200841066a22012f010020096b410c6c109b051a200341086a200241f0016a41086a280200360200200320022903f0013702000c010b200041086a20034103746a220741086a2007200041066a22012f010020036b410374109b051a20072004370000200041e0006a2003410c6c6a2207410c6a200720012f010020036b410c6c109b051a200741086a200241f0016a41086a280200360200200720022903f0013702000b200120012f010041016a3b0100200241286a41086a220f200241d0026a41086a22102802002203360200200241086a221120033602002002200c3a0017200220022903d00222043703282002200a3e02102002200a4230883c00162002200a4220883d011420022004370300200229031021042000280200220c450d0320002f01042112200241d0026a410272211303402002200641016a22063602202002200c360224200f201128020036020020022002290300370328201241ffff03712109024002400240200c2f01062200410b490d002013410041da001099051a200241f0016a200241d0026a41dc00109a051a200241386a410041b4011099051a41940210282207450d0520074100360200200741046a200241f0016a41dc00109a051a200741e0006a200241386a41b401109a052103200c41386a290000210a200241386a41086a2214200c41b0016a2802003602002002200c41a8016a290200370338200741086a200c41c0006a200c2f0106220141796a2200410374109a0521152003200c41b4016a2000410c6c109a052116200741e4016a200c4180026a2001417a6a220e410274109a052117200c41063b0106200720003b01060240200e450d00410021002017210303402003280200220120003b010420012007360200200341046a2103200e200041016a2200470d000b0b20102014280200220036020020022002290338220b3703d002201420003602002002200b370338201241ffff037122034107490d0120152009417a6a22034103746a2015200941796a22004103746a220120072f010620006b410374109b051a200120043700002009410c6c20166a220141b87f6a200141ac7f6a220120072f0106220e20006b410c6c109b051a200141086a200f280200360200200120022903283702002007200e41016a22013b01062009410274221220176a416c6a201720034102746a220e200141ffff0371220920036b410274109b051a200e200836020020092003490d02200720126a41cc016a2103034020032802002201200041016a22003b010420012007360200200341046a210320002009490d000c030b0b200c41086a2201200941016a22034103746a200120094103746a2201200020096b2207410374109b051a20012004370000200c2009410c6c6a220141ec006a200141e0006a220e2007410c6c109b051a200141e8006a200241286a41086a280200360200200e2002290328370200200c200041016a22003b01062009410274200c41e4016a22016a41086a200120034102746a2201200041ffff0371220720036b410274109b051a20012008360200201241ffff037120074f0d07200c2003417f6a22004102746a41e8016a2103034020032802002201200041016a22003b01042001200c360200200341046a210320002007490d000c080b0b200c41086a2200200941016a220e4103746a200020094103746a2200200c2f0106220120096b2212410374109b051a20002004370000200c41e0006a2009410c6c6a2200410c6a20002012410c6c109b051a200041086a200f28020036020020002002290328370200200c200141016a22003b010620094102742217200c41e4016a22016a41086a2001200e4102746a2212200041ffff03712201200e6b410274109b051a20122008360200200320014f0d00200c20176a41e8016a2100034020002802002203200941016a22093b01042003200c360200200041046a210020012009470d000b0b200241106a41086a2014280200220036020020112000360200200220022903382204370310200220043703000240200c28020022000d0020072108200a21040c050b200c2f010421122000210c200a2104200721080c000b0b41e40141041037000b41940241041037000b200020034103746a220941106a200941086a2209200120036b410374109b051a2009200437000020002003410c6c6a220141ec006a200141e0006a220920002f010620036b410c6c109b051a200141e8006a2007280200360200200920022903f001370200200020002f010641016a3b01060c010b200241d0026a410272410041da001099051a200241f0016a200241d0026a41dc00109a051a200241386a410041b4011099051a41940210282200450d0120004100360200200041046a200241f0016a41dc00109a051a200041e0006a200241386a41b401109a0521012000200528020022033602e401200520003602002005200528020441016a360204200341003b010420032000360200200120002f01062203410c6c6a22012002290300370200200020034103746a41086a2004370000200141086a200241086a280200360200200041e4016a200341016a22034102746a2008360200200020033b0106200820033b0104200820003602000b200241b0036a24000f0b41940241041037000b8b0303017f017e027f02402001450d00034020002802940321002001417f6a22010d000b0b02402002450d00410021034100210103402002417f6a210202400240200120002f01064f0d00200141016a21010c010b02400240200028020022010d002003ad210441002105410021010c010b20003301044220862003ad842104410121050b2000102a2004a72103024002402004422088a7220620012f01064f0d00200121000c010b034002400240200128020022000d002003ad2104410021000c010b200541016a210520013301044220862003ad8421040b2001102a2004a72103200021012004422088a7220620002f01064f0d000b0b200641027420006a4198036a280200210002402005417f6a2201450d00034020002802940321002001417f6a22010d000b0b410021010b20020d000b0b0240200041f8b9c000460d00200028020021012000102a2001450d00200128020021002001102a2000450d00024020002802002201450d0003402000102a2001210020012802002203210120030d000b0b2000102a0b0be480010d067f017e017f027e0b7f017e027f017e017f017e067f017e127f230041e0026b22012400024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024020004180c20370450d00200141e8006a21020c010b20014190026a41086a22034200370300200142003703900241f490c600411420014190026a1008200141e8006a41086a20032903003703002001200129039002370368200141003602a001200141e8006a4110200141a0016a100621030240024020012802a0012204417f460d0020030d010b200141e8006a21020c010b024002400240024002400240024020044104490d00200328000021042003102a200141e8006a21022004450d0720014190026a41086a22034200370300200142003703900241a9a2c100410f20014190026a1008200141e8006a41086a20032903003703002001200129039002370368200141003602a001200141e8006a4110200141a0016a100621030240024020012802a0012205417f460d002003450d0020012005360294022001200336029002200141a0016a20014190026a107d20012802a0012206450d0320012902a40121072005450d012003102a0c010b41042106420021070b20014190026a41086a22034200370300200142003703900241b8a2c100411420014190026a1008200141e8006a41086a20032903003703002001200129039002370368200141a0016a200141e8006a10be020240024020012802a8012208450d002007422088a720012902ac012209422088a76b20012903a001220a422088a7220b6a2105200aa721032009a7450d012008102a0c010b2007422088a721054100210b10980121030b200520044f0d020c030b41c4d1c3004133200141d8026a419cd9c3001038000b41c4d1c3004133200141d8026a419cd9c3001038000b0240200b20044f0d00200b20046b22032007422088a722056a220420034f0d032006200441246c6a28022021030c010b20014190026a41086a22044200370300200142003703900241dca2c100411420014190026a1008200141e8006a41086a2004290300370300200120012903900237036841002105200141003602a001200141e8006a4110200141a0016a10062104024020012802a001220b417f460d002004450d00200b4104490d02200428000021052004102a0b200520036a21030b200341ffc1036a220320034180c203706b210302402007a7450d002006102a0b20032000470d0320014190026a41086a22034200370300200142003703900241a9a2c100410f20014190026a1008200141e8006a41086a20032903003703002001200129039002370368200141003602a001200141e8006a4110200141a0016a1006210302400240024020012802a0012204417f460d002003450d0020012004360294022001200336029002200141a0016a20014190026a107d20012802a001220c450d0220012902a401210a2004450d012003102a0c010b4104210c4200210a0b20014190026a41086a22034200370300200142003703900241f490c600411420014190026a1008200141e8006a41086a200329030037030020012001290390023703684100210d200141003602a001200141e8006a4110200141a0016a100621030240024020012802a0012204417f460d002003450d0020044104490d012003280000210d2003102a0b109801210e02400240200a422088a7220f41246c2204450d00200c41206a280200200e4d0d010b4101210b41002105410021060c050b200141a0016a41186a2203200c41186a290200370300200141a0016a41106a2205200c41106a290200370300200141a0016a41086a2206200c41086a2902003703002001200c2902003703a001024041201028220b450d00200b20012903a001370000200b41186a2003290300370000200b41106a2005290300370000200b41086a20062903003700000240200c41246a2203200c20046a470d0041012105410121060c060b200c200f41246c6a211041202108410121044101210503400240200341206a280200200e4d0d00200421060c070b200141b8026a41186a2211200341186a290200370300200141b8026a41106a2212200341106a290200370300200141b8026a41086a2213200341086a290200370300200120032902003703b8020240024020052004460d00200421060c010b200441016a22062004490d1e200441017422142006201420064b1b220641ffffff3f712006470d1e200641057422144100480d1e0240024020040d0020141028210b0c010b200b20044105742014102c210b0b200b0d00201441011037000b200b20086a220420012903b802370000200441186a2011290300370000200441106a2012290300370000200441086a2013290300370000200841206a2108200541016a2105200621042010200341246a2203460d060c000b0b412041011037000b41c4d1c3004133200141d8026a419cd9c3001038000b41c4d1c3004133200141d8026a419cd9c3001038000b41c4d1c3004133200141d8026a419cd9c3001038000b41cca2c100200420051034000b024002400240024002400240024002400240200d200f20056b22044d0d0020014190026a41086a22034200370300200142003703900241f0a2c100411c20014190026a1008200141e8006a41086a2003290300370300200120012903900237036841002108200141003602a001200141e8006a4110200141a0016a10062103024020012802a0012211417f460d002003450d0020114104490d02200328000021082003102a0b20014190026a41086a22034200370300200142003703900241b8a2c100411420014190026a1008200141e8006a41086a20032903003703002001200129039002370368410810282203450d0220014288808080c0003702a401200120033602a00120032008200e6a3600000240024020012802a401220820012802a80122036b4104490d0020012802a00121080c010b200341046a22112003490d20200841017422032011200320114b1b22034100480d200240024020080d002003102821080c010b20012802a00120082003102c21080b2008450d04200120033602a401200120083602a00120012802a80121030b2001200341046a3602a801200820036a200d20046b22133600002005200141a0016a10b40102402005450d0020054105742104200b210303402003200141a0016a108f01200341206a2103200441606a22040d000b0b20012802a4012103200141e8006a411020012802a001220420012802a801100702402003450d002004102a0b02402006450d00200b102a0b200141a8026a4200370300200141a0026a420037030020014198026a42003703002001420037039002201341066a220ead42307e2207422088a70d172007a72203417f4c0d170240024020030d0041082110410821040c010b200310282210450d05201021040b200141a0016a41186a221120014190026a41186a290300370300200141a0016a41106a221220014190026a41106a290300370300200141a0016a41086a20014190026a41086a29030037030020012001290390023703a001200e4102490d05200d20056a200f6b41056a2105200421030340200141b8026a41186a22062011290300370300200141b8026a41106a220b2012290300370300200141b8026a41086a2208200141a0016a41086a290300370300200120012903a0013703b8022003420037030820034200370300200341106a20012903b802370300200341186a2008290300370300200341206a200b290300370300200341286a2006290300370300200341306a21032005417f6a22050d000b201341056a21050c060b2006450d07200b102a0c070b41c4d1c3004133200141d8026a419cd9c3001038000b410841011037000b200341011037000b200341081037000b4100210520042103200e450d010b2003420037030820034200370300200320012903a001370310200341186a200141a8016a290300370300200341206a200141b0016a290300370300200341286a200141a0016a41186a290300370300200541016a21050b20014190026a41086a220342003703002001420037039002418ca3c100411320014190026a1008200141e8006a41086a20032903003703002001200129039002370368200141003602a801200142013703a0012005200141a0016a10b40102402005450d002004200541306c6a210b0340200441086a2903002107200429030021090240024020012802a401220520012802a80122036b4110490d0020012802a00121050c010b200341106a22062003490d1a200541017422032006200320064b1b22034100480d1a0240024020050d002003102821050c010b20012802a00120052003102c21050b2005450d05200120033602a401200120053602a00120012802a80121030b200520036a22052007370008200520093700002001200341106a3602a801200441106a200141a0016a108f01200441306a2204200b470d000b0b20012802a4012103200141e8006a411020012802a001220420012802a801100702402003450d002004102a0b0240200e450d002010102a0b200141083a00a001200141a0016a41086a2013360200200141023a00a40141014100200141a0016a10cc010b200aa7450d00200c102a0b20014190026a41086a22034200370300200142003703900241b8a2c100411420014190026a1008200141e8006a41086a20032903003703002001200129039002370368200141a0016a200210be0220012802a8012215450d1820012902ac01211620012802a0012000470d1720014190026a41086a22034200370300200142003703900241b8a2c100411420014190026a1008200141e8006a41086a220020032903003703002001200129039002370368200141a0016a200210be02024020012802a80122170d0002402016a7450d002015102a0b41d5a3c100410f100b41e4a3c1004135100b0c190b20024110100920012802a401211820012902ac012119200342003703002001420037039002418ca3c100411320014190026a1008200020032903003703002001200129039002370368200141003602a00120024110200141a0016a100621030240024020012802a0012200417f460d002003450d0020012000360294022001200336029002200141a0016a20014190026a107820012802a001221a450d0320012902a401211b02402000450d002003102a0b2002411010090c010b4200211b4108211a0b109801211c20014190026a41086a22034200370300200142003703900241dca2c100411420014190026a1008200141e8006a41086a200329030037030020012001290390023703684100211d200141003602a00120024110200141a0016a10062103024020012802a0012200417f460d002003450d0020004104490d032003280000211d2003102a0b201a201b422088a7221e41306c6a210e0240024020180d004100211341002106410021000c010b2018417f6a2106410021000240201e450d000240201a201e41306c6a220341506a220e290300200e41086a2903008450450d00410121130c020b20014190026a41186a200341606a220341186a29000037030020014190026a41106a200341106a29000037030020014190026a41086a200341086a2900003703002001200329000037039002410121000b410021130b200141a9016a20014190026a41086a290300370000200141b1016a20014190026a41106a290300370000200141b9016a20014190026a41186a290300370000200120003a00a00120012001290390023700a101200141a0016a41017221032000450d0a20034280809aa6eaafe301420010aa02200141e8006a41086a200341086a290000370300200141e8006a41106a200341106a290000370300200141e8006a41186a200341186a2900003703002001200329000037036820012d00a0014101470d0b41201028221f450d03201f2001290368370000201f41186a200141e8006a41186a290300370000201f41106a200141e8006a41106a290300370000201f41086a200141e8006a41086a290300370000200141a0016a4101722103410221054120210441012120410121210340024002400240024020060d00410021060c010b2006417f6a2106201341ff01710d000240201a200e470d00410021130c010b200e41506a220b290300200b41086a290300844200520d0141012113200b210e0b200320012903b802370000200341086a200141b8026a41086a290300370000200341106a200141b8026a41106a290300370000200341186a200141b8026a41186a29030037000041002100200141003a00a0010c010b200141b8026a41186a200e41606a220041186a2900002207370300200141b8026a41106a200041106a2900002209370300200141b8026a41086a200041086a290000220a3703002001200029000022223703b80220032022370000200341086a200a370000200341106a2009370000200341186a2007370000200141013a00a00120034280809aa6eaafe301420010aa024100211320012d00a0012100200b210e0b20014190026a41186a220b200341186a29000037030020014190026a41106a2208200341106a29000037030020014190026a41086a2211200341086a29000037030020012003290000370390020240200041ff0171450d00200141a0016a41186a2212200b290300370300200141a0016a41106a220b2008290300370300200141a0016a41086a2208201129030037030020012001290390023703a001024020202021470d00202041016a22002020490d1820052000200520004b1b222141ffffff3f712021470d18202141057422004100480d180240024020200d0020001028211f0c010b201f20042000102c211f0b201f450d0c0b201f20046a220020012903a001370000200041186a2012290300370000200041106a200b290300370000200041086a2008290300370000200541026a2105200441206a2104202041016a21200c010b0b201f20046a21232020450d0c200141a0016a41086a2104201f210f0340200141306a200f10bf02024020012802304101470d002001280238210520014190016a10c002200128029001212402402001280298012203450d00200341216c2100202441016a21032005410876210841012005411f7174212520054105764107712211417f732126034002402003417f6a2d00004101470d00200141a0016a41186a200341186a290000370300200141a0016a41106a200341106a2900003703002004200341086a290000370300200120032900003703a001200120083602c00120014190026a200141a0016a10c1020240201120012802980222054f0d00200520266a220620054f0d0a200128029002220b20064102746a28020020257121050240200128029402450d00200b102a0b2005450d01411310282205450d0b200541002900c2a34122073700002005410f6a41002800d1a341220c360000200541086a41002900caa341220937000020014293808080b0023702a401200120053602a0012003200141a0016a108f0120012802a801211220012802a0012113200141b8026a41186a22054200370300200141b8026a41106a22064200370300200141b8026a41086a220b4200370300200142003703b80220132012200141b8026a1000200141106a41186a22102005290300370300200141106a41106a220d2006290300370300200141106a41086a2214200b290300370300200120012903b802370310024020012802a401450d0020012802a001102a0b200141003602a001200141106a4120200141a0016a1006210e024020012802a0012213417f460d00200120133602bc022001200e3602b802200141a0016a200141b8026a10c20220012903a0014201510d0d20014190026a41206a2227200441206a222828020036020020014190026a41186a2229200441186a222a29030037030020014190026a41106a222b200441106a222c29030037030020014190026a41086a2212200441086a222d290300370300200120042903003703900220012802cc01212e02402013450d00200e102a0b200141e8006a41206a20272802002213360200200141c0006a41086a220e2012290300370300200141c0006a41106a2227202b290300370300200141c0006a41186a222b2029290300370300200141c0006a41206a222920133602002001200129039002370340201242003703002001420037039002418891c600411120014190026a1008200141e8006a41086a20122903003703002001200129039002370368200141003602a00120024110200141a0016a1006211202400240024020012802a0012213417f470d00410021130c010b20134104490d01201228000021132012102a0b20042001290340370300202d200e290300370300202c2027290300370300202a202b29030037030020282029280200360200200142013703a0012001201341016a3602cc01411310282212450d10201220073700002012410f6a200c360000201241086a200937000020014293808080b002370294022001201236029002200320014190026a108f01200128029802211220012802900221132005420037030020064200370300200b4200370300200142003703b80220132012200141b8026a100020102005290300370300200d20062903003703002014200b290300370300200120012903b8023703100240200128029402450d00200128029002102a0b20014120360294022001200141106a36029002200420014190026a10c3020c030b41c4d1c3004133200141d8026a419cd9c3001038000b20042001290340370300200441086a200141c0006a41086a290300370300200441106a200141c0006a41106a290300370300200441186a200141c0006a41186a290300370300200441206a200141c0006a41206a280200360200200142003703a0012001202e3602cc01411310282212450d0d201220073700002012410f6a200c360000201241086a200937000020014293808080b002370294022001201236029002200320014190026a108f01200128029802211220012802900221132005420037030020064200370300200b4200370300200142003703b80220132012200141b8026a100020102005290300370300200d20062903003703002014200b290300370300200120012903b8023703100240200128029402450d00200128029002102a0b200141106a412010090c010b200128029402450d00200128029002102a0b200341216a21032000415f6a22000d000b0b200128029401450d002024102a0b2023200f41206a220f470d000c0d0b0b200341011037000b41c4d1c3004133200141d8026a419cd9c3001038000b41c4d1c3004133200141d8026a419cd9c3001038000b412041011037000b41cca2c100200620051034000b411341011037000b41c4d1c3004133200141d8026a419cd9c3001038000b411341011037000b411341011037000b200041011037000b200141e8006a41186a200341186a290000370300200141e8006a41106a200341106a290000370300200141e8006a41086a200341086a290000370300200120032900003703680b41002121410121234101211f410021200b20014190026a41086a22034200370300200142003703900241a9a2c100410f20014190026a1008200141e8006a41086a20032903003703002001200129039002370368200141003602a00120024110200141a0016a10062103024002400240024002400240024020012802a0012200417f460d002003450d0020012000360294022001200336029002200141a0016a20014190026a107d20012802a0012225450d0220012902a40121072000450d012003102a0c010b42002107410421250b20252007422088a7220841246c6a210d02402019422088a722050d004100212f41012130410021310c050b410021314100212f4101213002402005200d20256b41246e2203200320054b1b2203450d00200341057422004100480d0e200010282230450d022003212f0b20252103200521042030210003400240200d20036b41ec004b0d00200d2003460d062025200841246c6a21114101210b0240034020002003290000370000200041186a200341186a290000370000200041106a200341106a290000370000200041086a200341086a2900003700002004200b2206460d01200641016a210b200041206a21002011200341246a2203470d000b0b203120066a21310c060b20002003290000370000200041186a200341186a290000370000200041106a200341106a290000370000200041086a200341086a290000370000024020044101470d00203141017221310c060b20002003290024370020200041386a2003413c6a290000370000200041306a200341346a290000370000200041286a2003412c6a29000037000020044102460d0420002003290048370040200041d8006a200341e0006a290000370000200041d0006a200341d8006a290000370000200041c8006a200341d0006a29000037000020044103460d032000200329006c370060200041f8006a20034184016a290000370000200041f0006a200341fc006a290000370000200041e8006a200341f4006a290000370000203141046a213120004180016a210020034190016a21032004417c6a22040d000c050b0b41c4d1c3004133200141d8026a419cd9c3001038000b200041011037000b203141037221310c010b203141027221310b201d201c6a21262007a721270240024002400240024002402005450d00202521032008450d03200541016a2100200841246c2104202521030340200141b8026a41186a200341186a290200370300200141b8026a41106a200341106a290200370300200141b8026a41086a200341086a290200370300200120032902003703b8022000417f6a2200450d02200341246a21032004415c6a22040d000b200d21030c030b202521032008450d02200141a0016a41186a202541186a290200370300200141a0016a41106a202541106a290200370300200141a0016a41086a202541086a290200370300200120252902003703a001202541246a2103202528022021060c010b200341206a2802002106200141a0016a41186a200141b8026a41186a290300370300200141a0016a41106a200141b8026a41106a290300370300200141a0016a41086a200141b8026a41086a290300370300200120012903b8023703a001200341246a21030b20014190026a41186a200141a0016a41186a2200290300220737030020014190026a41106a200141a0016a41106a2204290300220937030020014190026a41086a200141a0016a41086a2205290300220a370300200120012903a00122223703900220002007370300200420093703002005200a370300200120223703a001417f200d20036b41246d22002023201f6b4105766a220420042000491b21054100210b200141a0016a2100201f21040c010b0240201f2023470d0002402027450d002025102a0b4100211c410421284100212c0c020b201f41086a2900002107201f41106a2900002109201f290000210a20014190026a41186a201f41186a290000222237030020014190026a41106a200937030020014190026a41086a20073703002001200a37039002200141a0016a41186a2022370300200141a0016a41106a2009370300200141a0016a41086a20073703002001200a3703a0012023201f41206a22046b41057621054102210b200141a0016a2100202621060b417f200541016a220820082005491b221cad42247e2207422088a70d012007a72205417f4c0d010240024002400240024002400240024020050d00410421280c010b200510282228450d010b20282000290200370200202841186a200041186a290200370200202841106a200041106a290200370200202841086a200041086a290200370200202820063602200240200b450d00024020042023470d004101212c0c050b200441086a2900002107200441106a29000021092004290000210a20014190026a41186a200441186a29000037030020014190026a41106a200937030020014190026a41086a20073703002001200a37039002200441206a21040c020b0240200d2003460d00200141a0016a41186a200341186a2902002209370300200141a0016a41106a200341106a290200220a370300200141a0016a41086a200341086a29020022223703002003290200210720014190026a41086a202237030020014190026a41106a200a37030020014190026a41186a2009370300200120073703a0012001200737039002200328022021134100210b200341246a21030c030b024020042023460d00200441086a2900002107200441106a29000021092004290000210a20014190026a41186a200441186a29000037030020014190026a41106a200937030020014190026a41086a20073703002001200a37039002200441206a21040c020b4101212c0c030b200541041037000b4102210b202621130b4102210641022100412421050340200141a0016a41186a220820014190026a41186a220e290300370300200141a0016a41106a221120014190026a41106a220c290300370300200141a0016a41086a221220014190026a41086a221029030037030020012001290390023703a00102402000222c417f6a2200201c470d000240024002400240200b41ff01710e03010200010b202320046b41057621140c020b417f200d20036b41246d2214202320046b4105766a220f200f2014491b21140c010b200d20036b41246d21140b2000417f201441016a220f200f2014491b6a22142000490d0e20062014200620144b1b221cad42247e2207422088a70d0e2007a722004100480d0e02400240202c4101470d002000102821280c010b202820052000102c21280b2028450d030b202820056a220020012903a001370200200041186a2008290300370200200041106a2011290300370200200041086a2012290300370200200041206a20133602000240024002400240200b41ff01710e03010200010b20042023460d04200441086a2900002107200441106a29000021092004290000210a200e200441186a290000370300200c2009370300201020073703002001200a37039002200441206a2104410121084102210b202621130c020b0240200d2003460d002008200341186a29020022093703002011200341106a290200220a3703002012200341086a29020022223703002003290200210720102022370300200c200a370300200e2009370300200120073703a001200120073703900220032802202113410121084100210b200341246a21030c020b4102210b024020042023470d00410021080c020b200441086a2900002107200441106a29000021092004290000210a200e200441186a290000370300200c2009370300201020073703002001200a37039002200441206a210441012108202621130c010b200d2003460d02200e200341186a290200370300200c200341106a2902003703002010200341086a2902003703002001200329020037039002200328022021134101210b200341246a2103410121080b200641026a2106202c41016a2100200541246a210520080d000b0b02402027450d002025102a0b202c4115490d01202c4101762232ad42247e2207422088a70d032007a72203417f4c0d0302400240024020030d004104212e410421080c010b20031028222e450d01202e21080b2028415c6a2133202841b47f6a21344104210c410021244100212641002113202c2125034020252106410021254101210502402006417f6a221d450d000240024002400240024002402028201d41246c6a41206a280200200641246c221220286a41586a2802002203490d002006417e6a2111203420126a210441002125410021000340024020112000470d00200621050c080b200041016a21002003200428020022054f210b2004415c6a210420052103200b0d000b200041016a21052000417f7320066a21040c010b203420126a2100201d210402400340024020044101470d00410021040c020b2004417f6a210420032000280200220549210b2000415c6a210020052103200b0d000b0b20062004490d012006202c4b0d03200620046b2205410176220b450d00203320126a21032028200441246c6a21000340200141a0016a41206a2211200041206a2212280200360200200141a0016a41186a220e200041186a2210290200370300200141a0016a41106a220d200041106a2214290200370300200141a0016a41086a220f200041086a2225290200370300200120002902003703a001200341206a22272802002129200341186a222a2902002107200341106a222b2902002109200341086a222d290200210a200020032902003702002025200a37020020142009370200201020073702002012202936020020272011280200360200202a200e290300370200202b200d290300370200202d200f290300370200200320012903a0013702002003415c6a2103200041246a2100200b417f6a220b0d000b0b024020040d00200421250c050b0240200541094d0d00200421250c050b2006202c4b0d012028200441246c6a2111034020062004417f6a2225490d040240200620256b22054102490d002028200441246c6a220041206a22032802002028202541246c6a221241206a220b280200220e4f0d00200141b8026a41186a2210201241186a220d290200370300200141b8026a41106a2214201241106a220f290200370300200141b8026a41086a2227201241086a2229290200370300200120122902003703b802201220002902003702002029200041086a290200370200200f200041106a290200370200200d200041186a290200370200200b2003280200360200024020054103490d00201d210b20112103201241e8006a280200200e4f0d000340200341206a200341c4006a280200360200200341186a2003413c6a290200370200200341106a200341346a290200370200200341086a2003412c6a2902003702002003200341246a22002902003702002004200b417f6a220b460d01200341e8006a2112200021032012280200200e490d000b0b200020012903b8023702002000200e360220200041186a2010290300370200200041106a2014290300370200200041086a20272903003702000b2025450d052011415c6a2111202521042005410a4f0d050c000b0b200420061044000b20062004417f6a2225490d010b2006202c103c000b202520061044000b02400240024020132024470d00202441016a22032024490d10202441017422002003200020034b1b220341ffffffff01712003470d10200341037422004100480d100240024020240d0020001028210c0c010b200c20244103742000102c210c0b200c450d0120032124202621130b200c20134103746a2203200536020420032025360200202641016a2213212620134102490d01024003400240024002400240200c2013417f6a22264103746a2203280200450d002013410374200c6a220541746a2802002204200328020422004d0d000240201341024b0d0020132126410221130c080b200c2013417d6a22104103746a2802042203200020046a4d0d010240201341034b0d0020132126410321130c080b200541646a280200200320046a4d0d01201321260c070b20134103490d0120032802042100200c2013417d6a22104103746a28020421030b20032000490d010b2013417e6a21100b0240024002400240024002402013201041016a22274b2229450d00201320104b222a450d01200c20104103746a220d280204222b200d2802006a2203200c20274103746a2214280200220f490d022003202c4b0d032028200f41246c6a22122014280204220e41246c22006a2106200341246c21042003200f6b220b200e6b2203200e4f0d04202e2006200341246c2200109a051a200820006a210502400240200e4101480d00200341014e0d010b20062103200821000c060b203320046a210420062103034020042003415c6a220b2005415c6a22112005417c6a2802002003417c6a2802004922061b2200290200370200200441206a200041206a280200360200200441186a200041186a290200370200200441106a200041106a290200370200200441086a200041086a2902003702002005201120061b210502402012200b200320061b2203490d00200821000c070b2004415c6a21042008210020082005490d000c060b0b41b8dbc000202720131034000b41b8dbc000201020131034000b200f20031044000b2003202c103c000b202e20122000109a051a200820006a210502400240200e4101480d00200b200e4a0d010b20122103200821000c010b202820046a211120082100201221030340200320062000200641206a280200200041206a28020049220b1b2204290200370200200341206a200441206a280200360200200341186a200441186a290200370200200341106a200441106a290200370200200341086a200441086a2902003702002000200041246a200b1b2100200341246a2103200641246a2006200b1b220620114f0d01200520004b0d000b0b20032000200520006b220420044124706b109a051a0240202a450d00200d200f360200200d41046a202b200e6a3602002029450d022014201441086a20132027417f736a410374109b051a20262113202641014d0d040c010b0b41c8dbc000201020131034000b41b0b1c0001032000b200041041037000b20250d000b02402024450d00200c102a0b2032450d03202e102a0c030b200341041037000b200041041037000b202c4102490d00202c417f6a21042028202c41246c6a21064100210b0340024002400240202c20042203417f6a2204490d00202c20046b22004102490d022028200341246c6a220341206a22052802002028200441246c6a220841206a221228020022114f0d02200141b8026a41186a2213200841186a220e290200370300200141b8026a41106a220c200841106a2210290200370300200141b8026a41086a220d200841086a2214290200370300200120082902003703b802200820032902003702002014200341086a2902003702002010200341106a290200370200200e200341186a2902003702002012200528020036020020004103490d01200b210520062100200841e8006a28020020114f0d01034020002203415c6a22002003290200370200200041206a200341206a280200360200200041186a200341186a290200370200200041106a200341106a290200370200200041086a200341086a2902003702002005417f6a2205450d02200341246a2100200341c4006a28020020114f0d020c000b0b2004202c1044000b200320012903b80237020020032011360220200341186a2013290300370200200341106a200c290300370200200341086a200d2903003702000b200b41016a210b2006415c6a210620040d000b0b20014190026a41086a22034200370300200142003703900241a9a2c100410f20014190026a1008200141e8006a41086a20032903003703002001200129039002370368200141003602a801200142013703a001202c200141a0016a10b4010240202c450d002028202c41246c6a210b2028210003402000200141a0016a108f01200041206a28020021050240024020012802a401220420012802a80122036b4104490d0020012802a00121040c010b200341046a22062003490d0b200441017422032006200320064b1b22034100480d0b0240024020040d002003102821040c010b20012802a00120042003102c21040b2004450d04200120033602a401200120043602a00120012802a80121030b2001200341046a3602a801200420036a2005360000200b200041246a2200470d000b0b20012802a40121032002411020012802a001220020012802a801100702402003450d002000102a0b202c41246c220341246d2106410021040240024020030d004101210b410021060c010b200641ffffff3f712006470d09200641057422034100480d0920031028220b450d030b0240202c450d00202c41246c210541002104200b2103202821000340200041086a2900002107200041106a29000021092000290000210a200341186a200041186a290000370000200341106a2009370000200341086a20073700002003200a370000200441016a2104200341206a2103200041246a21002005415c6a22050d000b0b0240201c450d002028102a0b200b2004410041202004676b10c40220302031200b200410c50202402006450d00200b102a0b20014190026a41086a22034200370300200142003703900241b0a3c100411220014190026a1008200141e8006a41086a20032903003703002001200129039002370368200141003602a00120024110200141a0016a100621030240024020012802a0012200417f460d002003450d0020012000360294022001200336029002200141a0016a20014190026a106d20012802a0012208450d0520012902a401210a2000450d012003102a0c010b4200210a410121080b200141b8016a4200370300200141b0016a4200370300200141a8016a4200370300200142003703a001200a422088a7221041ffffff3f712010470d0020104105742203417f4c0d000240024020030d00410121060c010b200310282206450d050b200141b8026a41186a2204200141a0016a41186a290300370300200141b8026a41106a2205200141a0016a41106a290300370300200141b8026a41086a220b200141a0016a41086a290300370300200120012903a0013703b80220104102490d052010417f6a2100200621030340200320012903b802370000200341186a2004290300370000200341106a2005290300370000200341086a200b290300370000200341206a21032000417f6a22000d000b2010417f6a210c0c060b1036000b200341011037000b200341011037000b41c4d1c3004133200141d8026a419cd9c3001038000b200341011037000b4100210c200621032010450d010b200320012903b802370000200341186a200141b8026a41186a290300370000200341106a200141b8026a41106a290300370000200341086a200141b8026a41086a290300370000200c41016a210c0b201a201e41306c6a2103201ba7210e410021140c010b1031000b0240024002400240034002402018450d002003201a460d02200341506a2203290300200341086a29030084500d022018417f6a2200450d000340201a2003460d03200341506a2203290300200341086a29030084500d032000417f6a22000d000b0b2003201a460d0102400340200341506a22042903002107200441086a290300210920014190026a41186a2205200341606a220041186a29030037030020014190026a41106a220b200041106a29030037030020014190026a41086a2211200041086a29030037030020012000290300370390022007200984500d01200141a0016a41186a22002005290300370300200141a0016a41106a2205200b290300370300200141a0016a41086a220b201129030037030020012001290390023703a00120014190016a200141a0016a10bf02200141c0006a41186a22112000290300370300200141c0006a41106a22122005290300370300200141c0006a41086a2213200b290300370300200120012903a00137034002402001280290014101460d0020042103201a2004470d010c040b0b200141106a41086a220d2013290300370300200141106a41106a22132012290300370300200141106a41186a221220112903003703002001200129034022073703b8022001200737031020012802980121042000201229030037030020052013290300370300200b200d290300370300200120012903103703a001200c20044d0d03200341506a2103200620044105746a220420012903a001370000200441186a2000290300370000200441106a2005290300370000200441086a200b290300370000201441016a2114410021180c010b0b200141b8026a41086a200141e8006a41086a290300370300200141b8026a41106a200141e8006a41106a290300370300200141b8026a41186a200141e8006a41186a290300370300200120012903683703b8020b0240200e450d00201a102a0b200c201041ffffff3f7122032003200c4b1b2211450d022008210b410021050340024020082006460d002008200541057422036a2200200620036a4120109c05450d00411610282203450d0320034100290093a2413700002003410e6a41002900a1a241370000200341086a410029009ba24137000020014296808080e0023702a401200120033602a0012000200141a0016a108f0120012802a801210320012802a0012104200141b8026a41186a22124200370300200141b8026a41106a22134200370300200141b8026a41086a220e4200370300200142003703b80220042003200141b8026a1000200141106a41186a2012290300370300200141106a41106a2013290300370300200141106a41086a200e290300370300200120012903b802370310024020012802a401450d0020012802a001102a0b200141106a41201009201f210303400240202320036b41e0004b0d00024020032023460d000340200b2003460d04200320004120109c05450d042023200341206a2203470d000b0b200120004280809aa6eaafe3014200108202200129030021072001200141086a2903003703a801200120073703a0012001200141a0016a3602900220014190026a109d010c020b20002003460d01200320004120109c05450d01200341206a22042000460d01200420004120109c05450d01200341c0006a22042000460d01200420004120109c05450d01200341e0006a22042000460d0120034180016a2103200420004120109c050d000b0b200b41206a210b200541016a22052011490d000c030b0b41a0a3c1002004200c1034000b411641011037000b2006200c4105746a2103200c2111024002400240200c4104490d00200141a0016a41206a2112200141e0016a2113200141a0016a41e0006a210e200141a0026a210d200141b8016a2104200141b0016a2105200141a8016a210b20032100200c211103402004420037030020054200370300200b4200370300200142003703a001024020122000460d00200041606a200141a0016a4120109c05450d002011417f6a21000c030b2004420037030020054200370300200b4200370300200142003703a001024020132000460d00200041406a200141a0016a4120109c05450d002011417e6a21000c030b2004420037030020054200370300200b4200370300200142003703a0010240200e2000460d00200041a07f6a200141a0016a4120109c05450d002011417d6a21000c030b2004420037030020054200370300200b4200370300200142003703a001200041807f6a210302400240200d2000460d002003200141a0016a4120109c050d010b2011417c6a211120032100200320066b41e0004b0d010c020b0b2011417c6a21000c010b20032006460d012011417f6a2100200141a0016a41206a2104200141b8016a2105200141b0016a210b200141a8016a2111034020054200370300200b420037030020114200370300200142003703a001024020042003460d00200341606a200141a0016a4120109c050d020b2000417f6a21002006200341606a2203470d000c020b0b200041016a210c0b200141bc016a2031360200200141b8016a202f360200200141b4016a2030360200200141a0016a41106a2020360200200141ac016a2021360200200141083a00a001200141a0016a41086a201f360200200141033a00a40141014100200141a0016a10cc0120014190026a41086a22034200370300200142003703900241b0a3c100411220014190026a1008200141e8006a41086a20032903003703002001200129039002370368200141003602a801200142013703a001200c200141a0016a10b4010240200c450d00200c41057421002006210303402003200141a0016a108f01200341206a2103200041606a22000d000b0b20012802a40121032002411020012802a001220020012802a801100702402003450d002000102a0b02402010450d002006102a0b20014190026a41086a22034200370300200142003703900241bf91c600411620014190026a1008200141e8006a41086a220020032903003703002001200129039002370368200120143602a00120024110200141a0016a41041007200342003703002001420037039002418891c600411120014190026a1008200020032903003703002001200129039002370368200141003602a00120024110200141a0016a100621030240024020012802a0012200417f470d00410121030c010b024020030d00410121030c010b20004104490d03200328000021002003102a200041016a21030b20014190026a41086a220042003703002001420037039002418891c600411120014190026a1008200141e8006a41086a20002903003703002001200129039002370368200120033602a00120024110200141a0016a410410070240200aa7450d002008102a0b2019a7450d002017102a0b2016a7450d002015102a0b200141e0026a24000f0b41c4d1c3004133200141d8026a419cd9c3001038000bef0101047f230041206b220224002002410036021020014110200241106a10062101024002400240024020022802102203417f460d0020010d010b200041003602080c010b200220013602082002200336020c20034104490d012002200141046a36020820022003417c6a220436020c20044104490d01200128000021042002200341786a36020c2002200141086a36020820012800042103200241106a200241086a106d20022802102205450d012000200229021437020c2000200536020820002003360204200020043602002001102a0b200241206a24000f0b41c4d1c3004133200241106a419cd9c3001038000bb70201057f230041d0006b220224000240411610282203450d0020034100290093a2413700002003410e6a41002900a1a241370000200341086a410029009ba24137000020024296808080e002370224200220033602202001200241206a108f012002280228210320022802202101200241306a41186a22044200370300200241306a41106a22054200370300200241306a41086a220642003703002002420037033020012003200241306a1000200241186a2004290300370300200241106a2005290300370300200241086a20062903003703002002200229033037030002402002280224450d002002280220102a0b200241306a2002412010c6020240024020022802304101460d00200041003602000c010b20002002290234370204200041013602000b200241d0006a24000f0b411641011037000ba50708027f017e047f027e017f017e037f017e230041d0006b220124000240024002400240024002400240410e10282202450d00200241066a41002900b2a441370000200241002900aca4413700002002410e411c102c2202450d012002410036000e42002103200141286a41186a22044200370300200141286a41106a22054200370300200141286a41086a220642003703002001420037032820024112200141286a1000200141186a2004290300370300200141106a2005290300370300200141086a2006290300370300200120012903283703002002102a2001410036022820014120200141286a100621040240024020012802282202417f470d00410121070c010b2001200236022420012004360220200141286a200141206a107420012802282207450d03200129022c21032002450d002004102a0b02400240410e10282202450d0041002900b2a441210841002900aca4412109410121040340200241066a2008370000200220093700002002410e411c102c2202450d062002200436000e200141286a41186a22054200370300200141286a41106a22064200370300200141286a41086a220a42003703002001420037032820024112200141286a1000200141186a2005290300370300200141106a2006290300370300200141086a200a290300370300200120012903283703002002102a2001410036022820014120200141286a100621060240024020012802282202417f470d00410121054200210b0c010b2001200236022420012006360220200141286a200141206a107420012802282205450d08200129022c210b2002450d002006102a0b200b422088a72206450d0202402003a7220a2003422088a722026b200641216c220c41216d22064f0d00200220066a220d2002490d0a200a410174220e200d200e200d4b1bad220342217e220f422088a70d0a200fa7220d4100480d0a02400240200a0d00200d102821070c010b2007200a41216c200d102c21070b2007450d090b2007200241216c6a2005200c109a051a200342ffffffff0f832103200220066aad422086210f0240200ba7450d002005102a0b200441016a21042003200f842103410e102822020d000b0b410e41011037000b0240200ba7450d002005102a0b2000200337020420002007360200200141d0006a24000f0b410e41011037000b411c41011037000b41c4d1c3004133200141c8006a419cd9c3001038000b411c41011037000b41c4d1c3004133200141c8006a419cd9c3001038000b200d41011037000b1031000bcc0402057f017e230041e0006b220224000240024002400240411310282203450d0020034100290099a4413700002003410f6a41002800a8a441360000200341086a41002900a1a44137000020024293808080b00237022c200220033602282001200241286a108f012001280220210402400240200228022c2201200228023022036b4104490d00200228022821010c010b200341046a22052003490d03200141017422032005200320054b1b22034100480d030240024020010d002003102821010c010b200228022820012003102c21010b2001450d022002200336022c20022001360228200228023021030b2002200341046a360230200120036a20043600002002280230210320022802282101200241386a41186a22044200370300200241386a41106a22054200370300200241386a41086a220642003703002002420037033820012003200241386a1000200241086a41186a2004290300370300200241086a41106a2005290300370300200241086a41086a2006290300370300200220022903383703080240200228022c450d002002280228102a0b20024100360238200241086a4120200241386a100621010240024020022802382203417f460d002002200336022c20022001360228200241386a200241286a10820120022802382204450d05200229023c210702402003450d002001102a0b20002007370204200020043602000c010b20004100360208200042043702000b200241e0006a24000f0b411341011037000b200341011037000b1031000b41c4d1c3004133200241d8006a419cd9c3001038000bf70103017e057f027e420121020240200128020422034104490d0020012802002204280000210520012003417c6a22063602042001200441046a360200200641034d0d00200428000421072001200341786a22063602042001200441086a36020020064110490d00200441106a2900002108200429000821092001200341686a22063602042001200441186a36020020064110490d0020002009370308200041186a2004290018370300200041106a20083703002000412c6a2007360200200041286a2005360200200041206a200441206a2900003703002001200341586a3602042001200441286a360200420021020b200020023703000bd30102027f027e200028022021020240024002400240410410282203450d002003200236000020002802242102200341044108102c2203450d0120032002360004200041086a290300210420002903002105200341084118102c2203450d0220032005370008200341106a2004370000200041186a290300210420002903102105200341184130102c2200450d0320002005370018200041206a2004370000200128020020012802042000412810072000102a0f0b410441011037000b410841011037000b411841011037000b413041011037000b942103157f037e077f230041c0026b220424000240024020014115490d0041012105410121060240024002400340200121072000210820052006714101732109024002400240024002400240034002400240024002402003450d00024020054101710d002000200110da032003417f6a21030b2001410276220a41036c210b200a410174210c4100210d024020014132490d00200a200a417f6a220d2000200a4105746a2000200d4105746a4120109c05220e410048220f1b2210200a41016a2211200d200a200f1b220a200020114105746a2000200a4105746a4120109c05220f4100481b220a2000200a4105746a200020104105746a4120109c0522104100481b210a200c200c417f6a220d2000200c4105746a2000200d4105746a4120109c05221141004822121b2213200c4101722214200d200c20121b220c200020144105746a2000200c4105746a4120109c0522124100481b220c2000200c4105746a200020134105746a4120109c0522134100481b210c200b200b417f6a220d2000200b4105746a2000200d4105746a4120109c05221441004822151b2216200b41016a2217200d200b20151b220b200020174105746a2000200b4105746a4120109c05220d4100481b220b2000200b4105746a200020164105746a4120109c0522154100481b210b200f411f76200e411f766a2010411f766a2011411f766a2012411f766a2013411f766a2014411f766a200d411f766a2015411f766a210d0b2000200c4105746a2000200a4105746a4120109c05220e411f76200d6a2000200b4105746a2000200a200c200e410048220e1b220f4105746a4120109c052210411f766a210d2000200b200f20104100481b220b4105746a2000200c200a200e1b22184105746a4120109c05417f4c0d01200b21180c020b2000200110db030c0f0b200d41016a220d410c490d0002402001410176220b450d00200020014105746a41606a210a2000210c0340200441206a41186a220d200c41186a220e290000370300200441206a41106a220f200c41106a2210290000370300200441206a41086a2211200c41086a22122900003703002004200c290000370320200a41086a22132900002119200a41106a2214290000211a200a41186a2215290000211b200c200a290000370000200e201b3700002010201a370000201220193700002015200d2903003700002014200f29030037000020132011290300370000200a2004290320370000200a41606a210a200c41206a210c200b417f6a220b0d000b0b20012018417f736a21184101210a0c010b200d45210a0b0240200a452009724101710d002000200110dc030d0d0b2002450d02201820014f0d0102402002200020184105746a220a4120109c0541004e0d0020002108200121070c040b200441206a41186a2212200041186a220f290000370300200441206a41106a2213200041106a2210290000370300200441206a41086a2214200041086a221129000037030020042000290000370320200a41086a220c2900002119200a41106a220b290000211a200a41186a220d290000211b2000200a290000370000200f201b3700002010201a37000020112019370000200d2012290300370000200b2013290300370000200c2014290300370000200a2004290320370000200441c0016a41186a2217200f290000370300200441c0016a41106a221c2010290000370300200441c0016a41086a22182011290000370300200420002900003703c001200041606a2115200041206a21164100210c2001210b03400240200c200b417f6a220d4f0d002016200c4105746a210a0340200441c0016a200a4120109c05417f4c0d01200a41206a210a200d200c41016a220c470d000b200d210c0b2015200b4105746a210a02400340200c200b417f6a220b4f0d01200441c0016a200a4120109c05210d200a41606a220e210a200d4100480d000b20122016200c4105746a220a41186a220d2900003703002013200a41106a221d2900003703002014200a41086a22062900003703002004200a290000370320200e41286a221e2900002119200e41306a221f290000211a200e41386a2220290000211b200a200e41206a220e290000370000200d201b370000201d201a3700002006201937000020202012290300370000201f2013290300370000201e2014290300370000200e2004290320370000200c41016a210c0c010b0b200020042903c001370000200f20172903003700002010201c2903003700002011201829030037000002402001200c41016a220a490d002000200a4105746a21002001200a6b220141154f0d010c0c0b0b200a20011044000b41a0cec300201820011034000b2007450d010b201820074f0d01200441206a41186a2216200841186a221e290000370300200441206a41106a2217200841106a221f290000370300200441206a41086a221c200841086a222029000037030020042008290000370320200820184105746a220a41086a220c2900002119200a41106a220b290000211a200a41186a220d290000211b2008200a290000370000201e201b370000201f201a37000020202019370000200d2016290300370000200b2017290300370000200c201c290300370000200a2004290320370000200441186a2205201e290000370300200441106a2209201f290000370300200441086a2221202029000037030020042008290000370300200841206a21014100211d2007417f6a220d450d022001210a0340200a20044120109c0541004e0d03200a41206a210a200d201d41016a221d470d000b200d211d0c020b4180cec300410041001034000b4190cec300201820071034000b200820074105746a210c200d210b02400340200c2100200b220a201d4d22060d01200a417f6a210b200041606a220c20044120109c05417f4a0d000b0b0240200a201d490d00200d200a490d0241800121144100210e410021124100210d4100211141800121152001201d4105746a2222210103400240200020016b220a419fc0004b22180d00200a410576220a41807f6a200a2012200e492011200d49220c72220b1b210a0240200b450d002015200a200c1b2115200a2014200c1b21140c010b200a200a41017622156b21140b02402011200d470d00024020150d00200441c0006a220d21110c010b4100210a200441c0006a2211210d2001210c0340200d200a3a0000200d200c20044120109c05417f73411f766a210d200c41206a210c2015200a41016a220a470d000b0b02402012200e470d00024020140d00200441c0016a220e21120c010b200041606a210a4100210c200441c0016a2212210e0340200e200c3a0000200e200a20044120109c05411f766a210e200a41606a210a2014200c41016a220c470d000b0b0240200e20126b220a200d20116b220c200c200a4b1b2213450d002016200120112d00004105746a220a41186a2900003703002017200a41106a290000370300201c200a41086a2900003703002004200a290000370320200120112d00004105746a220a200020122d0000417f734105746a220c290000370000200a41186a200c41186a290000370000200a41106a200c41106a290000370000200a41086a200c41086a290000370000024020134101460d004100210a034020002012200a6a220f2d0000417f734105746a220c20012011200a6a41016a22102d00004105746a220b290000370000200c41186a200b41186a290000370000200c41106a200b41106a290000370000200c41086a200b41086a290000370000200120102d00004105746a220c2000200f41016a2d0000417f734105746a220b290000370000200c41186a200b41186a290000370000200c41106a200b41106a290000370000200c41086a200b41086a290000370000200a41026a210c200a41016a220b210a200c2013490d000b2012200b6a21122011200b6a21110b200020122d0000417f734105746a220a2004290320370000200a41186a2016290300370000200a41106a2017290300370000200a41086a201c290300370000201241016a2112201141016a21110b200020144105746b20002012200e461b2100200120154105746a20012011200d461b210120180d000b024002402011200d4f0d002000210a034020162001200d417f6a220d2d00004105746a220c41186a220b2900003703002017200c41106a220e290000370300201c200c41086a22002900003703002004200c290000370320200a41606a220a41086a220f2900002119200a41106a2210290000211a200a41186a2212290000211b200c200a290000370000200b201b370000200e201a370000200020193700002012201629030037000020102017290300370000200f201c290300370000200a20042903203700002011200d490d000c020b0b2001210a2012200e4f0d000340200e417f6a220e2d0000210c2016200a41186a220b2900003703002017200a41106a220d290000370300201c200a41086a22012900003703002004200a2900003703202000200c417f734105746a220c41086a220f2900002119200c41106a2210290000211a200c41186a2211290000211b200a200c290000370000200b201b370000200d201a370000200120193700002011201629030037000020102017290300370000200f201c290300370000200c2004290320370000200a41206a210a2012200e490d000b0b20082004290300370000201e2005290300370000201f2009290300370000202020212903003700002007200a20226b410576201d6a22014d0d032016201e2900003703002017201f290000370300201c202029000037030020042008290000370320200820014105746a220a41086a220c2900002119200a41106a220b290000211a200a41186a220d290000211b2008200a290000370000201e201b370000201f201a37000020202019370000200d2016290300370000200b2017290300370000200c201c290300370000200a2004290320370000200720016b220c450d04200c20012001200c4b1b210b2007410376210d200a41206a2100024002402001200c417f6a220c490d002000200c200a200310c402200821000c010b200820012002200310c402200a2102200c21010b200b200d4f2105200141154f0d010c050b0b201d200a1044000b200a200d103c000b4190cec300200120071034000b41dc83c6001032000b20014102490d00200041406a210f410021104101210d0340200d410574210a200d417f6a210b200d41016a210d02402000200a6a220e2000200b4105746a220a4120109c05417f4a0d00200441c0016a41186a2211200e41186a220c290000370300200441c0016a41106a2212200e41106a2213290000370300200441c0016a41086a2214200e41086a22152900003703002004200e2900003703c001200e200a2900003700002015200a41086a2900003700002013200a41106a290000370000200c200a41186a29000037000002400240200b0d004100210b0c010b2010210c200f210a200441c0016a200e41406a4120109c05417f4a0d0002400340200a41d8006a200a41386a290000370000200a41d0006a200a41306a290000370000200a41c8006a200a41286a290000370000200a41c0006a200a41206a290000370000200c4101460d01200441c0016a200a4120109c05210e200c417f6a220b210c200a41606a210a200e4100480d000c020b0b4100210b0b2000200b4105746a220a20042903c001370000200a41186a2011290300370000200a41106a2012290300370000200a41086a20142903003700000b201041016a2110200f41206a210f200d2001470d000b0b200441c0026a24000bd9140a057f017e067f037e037f017e017f027e077f057e23002204210520044180026b4160712204240002400240200141ffffff3f712001470d0020014105742206417f4c0d0002400240024020060d00410121070c010b200610282207450d010b410021084100210602402001450d002001410574210820072106034020062000290000370000200641186a200041186a290000370000200641106a200041106a290000370000200641086a200041086a290000370000200641206a2106200041206a2100200841606a22080d000b200141057441606a41057641016a2106200121080b20042006360218200420083602142004200736021020072006410041202006676b10c40242002109200441b0016a41086a22004200370300200442003703b001419896c300411d200441b0016a1008200441e0016a41086a2000290300370300200420042903b0013703e001200441003602b001200441e0016a4110200441b0016a1006210602400240024020042802b0012200417f460d0020042000360294012004200636029001200441b0016a20044190016a106d20042802b001220a450d0220042902b40121092000450d012006102a0c010b4101210a0b2009422088a72200450d032000410574210b200441e0016a410c6a210c200441e0016a411472210d200441e0016a410872210e200441c0006a410c72210f200a210002400340200041086a2900002110200041106a290000211120002900002112200441206a41186a2213200041186a290000370300200441206a41106a22142011370300200441206a41086a22152010370300200420123703200240024002400240411a10282206450d00200641002900b596432216370000200641186a41002f00cd964322173b0000200641106a41002900c596432218370000200641086a41002900bd964322193700002004429a808080a0033702b401200420063602b0012004200441b0016a3602e001200441206a200441e0016a10c80120042802b001210720042802b801211a200441e0016a41186a22014200370300200441e0016a41106a22064200370300200441e0016a41086a22084200370300200442003703e0012007201a200441e0016a100020044190016a41186a221b200129030037030020044190016a41106a221c200629030037030020044190016a41086a221a2008290300370300200420042903e00137039001024020042802b401450d0020042802b001102a0b200441003602e00120044190016a4120200441e0016a1006211d20042802e0012207417f460d02200420073602642004201d360260200441e0016a200441e0006a10b30320042802e801221e450d01200441b0016a41086a221f200c41086a290200370300200441b0016a41106a2220200c41106a2802003602002004200c2902003703b00120042903e001211002402007450d00201d102a0b200f20042903b00122113702002006202028020022073602002008201f2903002212370300200f41086a2012370200200f41106a2007360200200420113703e001200420103703400c030b411a41011037000b41c4d1c3004133200441d0016a419cd9c3001038000b2006200441b0016a41106a2802003602002008200441b0016a41086a290300370300200420042903b0013703e0014100211e0b2004201e360248200441003602e80120042903582112200420042903f801222137035820042903502122200420042903f001222337035020042903402124200420042903e001221137034020042903482110200420042903e80122253703482025a72107024002402010a7221d0d002025211020232122202121120c010b200420243703e001200420103703e801200420223703f001200420123703f8012004201d2022a74105746a3602bc012004201d3602b80120042010422088a73602b4012004201d3602b0012004200441106a3602c00120044190016a200441b0016a108401200e41086a201a280200360200200e20042903900137020020042022422088a7221d2012422088a74105746a3602bc012004201d3602b80120042012a73602b4012004201d3602b0012004200441106a3602c00120044190016a200441b0016a108401200d41086a201a280200360200200d20042903900137020020042903e801211020042903e001211120042903f801211220042903f001212202402007450d002021a7211d02402025422088a7450d002007102a0b201d450d002023422088a7102a0b200420113703402004201037034820042022370350200420123703582010a721070b2004201137036020042010370368200420223703702004201237037802400240024020070d00200441b0016a41186a2013290300370300200441b0016a41106a2014290300370300200441b0016a41086a2015290300370300200420042903203703b001411a10282207450d0220072016370000200741186a20173b0000200741106a2018370000200741086a20193700002004429a808080a0033702d401200420073602d0012004200441d0016a3602e001200441b0016a200441e0016a10c80120042802d001210720042802d801211d200142003703002006420037030020084200370300200442003703e0012007201d200441e0016a1000201b2001290300370300201c2006290300370300201a2008290300370300200420042903e00137039001024020042802d401450d0020042802d001102a0b20044190016a412010090c010b200441b0016a41186a2013290300370300200441b0016a41106a2014290300370300200441b0016a41086a2015290300370300200420042903203703b001411a10282207450d0320072016370000200741186a20173b0000200741106a2018370000200741086a20193700002004429a808080a0033702d401200420073602d0012004200441d0016a3602e001200441b0016a200441e0016a10c80120042802d001210720042802d801211d200142003703002006420037030020084200370300200442003703e0012007201d200441e0016a1000201b2001290300370300201c2006290300370300201a2008290300370300200420042903e00137039001024020042802d401450d0020042802d001102a0b200441203602e401200420044190016a3602e001200441e0006a200441e0016a10b4030b02402010a72206450d002012a7210802402010422088a7450d002006102a0b2008450d002022422088a7102a0b200041206a2100200b41606a220b0d010c060b0b411a41011037000b411a41011037000b41c4d1c3004133200441d0016a419cd9c3001038000b200641011037000b1036000b02402009a7450d00200a102a0b200441003602e801200442013703e0012003200441e0016a10b40102402003450d002003410574210003402002200441e0016a108f01200241206a2102200041606a22000d000b0b20042802e401210620042802e801210820042802e0012100200441b0016a41086a22014200370300200442003703b00141fbefc200411b200441b0016a1008200441e0016a41086a2001290300370300200420042903b0013703e001200441e0016a411020002008100702402006450d002000102a0b02402004280214450d002004280210102a0b200524000ba50101027f230041206b22032400410021042003410036021420012002200341146a100621010240024020032802142202417f460d002001450d002003410036020c20024104490d0120012800002104200341003602102002417c714104460d01200128000421022001102a200041086a200236020020002004360204410121040b20002004360200200341206a24000f0b41c4d1c3004133200341186a419cd9c3001038000b13002000410a36020420004188a5c1003602000b3400200041fecbc10036020420004100360200200041146a4110360200200041106a4188ccc100360200200041086a42073702000b3001017f02404104102822020d00410441011037000b20004284808080c00037020420002002360200200241003600000b2201017f230041106b22022400200241003602002000200210ad02200241106a24000b13002000410b360204200041c0e5c1003602000b3101017f02404104102822020d00410441011037000b20004284808080c00037020420002002360200200241c0003600000b3d01017f02404110102822020d00411041011037000b200242003700082002428080e983b1de16370000200042908080808002370204200020023602000b3201017f02404104102822020d00410441011037000b20004284808080c0003702042000200236020020024180c2033600000b3001017f02404104102822020d00410441011037000b20004284808080c00037020420002002360200200241013600000b3001017f02404104102822020d00410441011037000b20004284808080c00037020420002002360200200241063600000b3d01017f02404110102822020d00411041011037000b200242003700082002428080d287e2bc2d370000200042908080808002370204200020023602000b3e01017f02404110102822020d00411041011037000b2002420037000820024280809aa6eaafe301370000200042908080808002370204200020023602000b9f0a01047f230041206b220224000240024002400240024002400240024002400240024002400240024002402001280200417f6a220341094b0d0020030e0a0102030405060708090a010b41c4f7c1001032000b2001410c6a2802002203417f4c0d0a200128020421044101210502402003450d00200310282205450d0c0b200520042003109a0521052000410c6a2003360200200041086a20033602002000200536020420004101360200200041206a200141206a290300370300200041186a2001290318370300200041106a20012902103703000c090b2001410c6a2802002203417f4c0d09200128020421050240024020030d00410121040c010b200310282204450d0c0b200420052003109a0521052000410c6a2003360200200041086a20033602002000200536020420004102360200200041206a200141206a290300370300200041186a2001290318370300200041106a20012902103703000c080b200128020421054101210302400240200141086a22042d00004101460d002002411e6a200441036a2d00003a0000200241086a200141186a290200370300200241106a200141206a290200370300200241186a200141286a2d00003a0000200220042f00013b011c2002200141106a2902003703002001410c6a2802002104410021030c010b2001410c6a28020021040b20002005360204200020022f011c3b0009200041086a20033a00002000410c6a2004360200200041106a20022903003702002000412c6a200129022c3702002000410b6a2002411e6a2d00003a0000200041186a200241086a290300370200200041206a200241106a290300370200200041286a200241186a280200360200200041033602000c070b20004104360200200020012802043602040c060b20004105360200200020012802043602040c050b410121030240024020012d00044101460d002002411e6a200141046a220341036a2d00003a0000200241086a200141146a290200370300200241106a2001411c6a290200370300200241186a200141246a2d00003a0000200220032f00013b011c20022001410c6a290200370300200141086a2802002105410021030c010b200141086a28020021050b200020033a0004200020022f011c3b0005200041306a2001290330370300200041086a20053602002000410c6a2002290300370200200041386a200141386a290300370300200041076a2002411e6a2d00003a0000200041146a200241086a2903003702002000411c6a200241106a290300370200200041246a200241186a2802003602002001280228210120004106360200200041286a20013602000c040b20004107360200200020012802043602040c030b410121030240024020012d00044101460d002002411e6a200141046a220341036a2d00003a0000200241086a200141146a290200370300200241106a2001411c6a290200370300200241186a200141246a2d00003a0000200220032f00013b011c20022001410c6a290200370300200141086a2802002101410021030c010b200141086a28020021010b200020033a0004200020022f011c3b000520004108360200200041086a20013602002000410c6a2002290300370200200041076a2002411e6a2d00003a0000200041146a200241086a2903003702002000411c6a200241106a290300370200200041246a200241186a2802003602000c020b20004109360200200020012802043602040c010b2000410a360200200020012802043602040b200241206a24000f0b1036000b200341011037000b200341011037000bbf4305047f027e037f017e067f23004190026b22072400200741f0006a41086a220842003703002007420037037041b0a3c1004112200741f0006a1008200741a0016a41086a2008290300370300200720072903703703a0014100210920074100360270200741a0016a4110200741f0006a1006210802402007280270220a417f460d002008450d002007200a36027420072008360270200741306a200741f0006a106c0240024020072802300d00200728023421090c010b410021090b200a450d002008102a0b200741f0006a41086a220842003703002007420037037041b8a2c1004114200741f0006a1008200741a0016a41086a220a2008290300370300200720072903703703a001024002400240200741a0016a41104101410041001003417f460d0041effec1002108412e210a0c010b2008420037030020074200370370418891c6004111200741f0006a1008200a2008290300370300200720072903703703a00120074100360270200741a0016a4110200741f0006a1006210802400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002402007280270220a417f470d004100210a0c010b024020080d004100210a0c010b200a4104490d012008280000210a2008102a0b0240200a2003460d00419dffc10021084114210a0c1e0b024020090d0041b1ffc100210841c100210a0c1e0b02402009200241086a2802004f0d0041f2ffc1002108413c210a0c1e0b02402005428080e983b1de165441002006501b450d0041ae80c20021084124210a0c1e0b200741206a2001109d02200741206a41086a290300210b2007290320210c411310282208450d01200c200554200b200654200b2006511b210a200841002900c2a3413700002008410f6a41002800d1a341360000200841086a41002900caa34137000020074293808080b002370274200720083602702001200741f0006a108f012007280278210820072802702109200741a0016a41186a220d4200370300200741a0016a41106a220e4200370300200741a0016a41086a220f4200370300200742003703a00120092008200741a0016a1000200741c0006a41186a200d290300370300200741c0006a41106a200e290300370300200741c0006a41086a200f290300370300200720072903a00137034002402007280274450d002007280270102a0b200b2006200a1b210b200c2005200a1b210620074100360270200741c0006a4120200741f0006a100621080240024002402007280270220a417f460d002008450d002007200a3602a401200720083602a001200741f0006a200741a0016a10c20220072903704201510d0520074180016a29030021052007290378210c0240200a450d002008102a0b410e10282208450d06200841066a41002900b2a441370000200841002900aca4413700002008410e411c102c2208450d072008200441067636000e200741a0016a41186a220a4200370300200741a0016a41106a22094200370300200741a0016a41086a220d4200370300200742003703a00120084112200741a0016a1000200741f0006a41186a200a290300370300200741f0006a41106a2009290300370300200741f0006a41086a200d290300370300200720072903a0013703702008102a200741003602a001200741f0006a4120200741a0016a1006210820072802a001220a417f460d1b2008450d1b2007200a3602dc01200720083602d801200741a0016a200741d8016a107420072802a001220d450d082004413f71210920072902a40121100240200a450d002008102a0b4100210420092010422088a7490d010c190b200741106a20011091012007290310428080e983b1de1656200741186a29030022054200522005501b0d0141e380c20021084134210a0c1f0b200d200941216c6a22082d00004101470d17200741da016a200841036a2d00003a0000200741a0016a41086a200841146a290000370300200741ad016a200841196a290000370000200720082f00013b01d80120072008410c6a2900003703a001200841086a280000210a200841046a2800002108410121040c180b410e10282208450d06200841066a41002900b2a441370000200841002900aca4413700002008410e411c102c2208450d0720082004410676220e36000e200741a0016a41186a220a4200370300200741a0016a41106a22094200370300200741a0016a41086a220d4200370300200742003703a00120084112200741a0016a1000200741c0006a41186a200a290300370300200741c0006a41106a2009290300370300200741c0006a41086a200d290300370300200720072903a0013703402008102a20074100360270200741c0006a4120200741f0006a1006210802402007280270220a417f460d002008450d002007200a3602a401200720083602a001200741f0006a200741a0016a10742007280270220d450d092004413f712109200729027421050240200a450d002008102a0b41002108024020092005422088a74f0d0041014102200d200941216c6a2d00001b21080b02402005a7450d00200d102a0b20084102490d00410e10282208450d0a200841066a41002900b2a441370000200841002900aca4413700002008410e411c102c2208450d0b2008200e36000e42002105200741a0016a41186a220a4200370300200741a0016a41106a22044200370300200741a0016a41086a220d4200370300200742003703a00120084112200741a0016a1000200741c0006a41186a200a290300370300200741c0006a41106a2004290300370300200741c0006a41086a200d290300370300200720072903a0013703402008102a20074100360270200741c0006a4120200741f0006a100621080240024020072802702204417f470d004101210a0c010b024020080d004101210a0c010b200720043602a401200720083602a001200741f0006a200741a0016a10742007280270220a450d0d200729027421052004450d002008102a0b200741c0006a41186a2204200141186a290000370300200741c0006a41106a220d200141106a290000370300200741c0006a41086a220f200141086a2900003703002007200129000037034020092005422088a722114f0d0d200a200941216c6a220841013a000020082007290340370001200841096a200f290300370000200841116a200d290300370000200841196a2004290300370000410e102821080240200a0d002008450d0f200841066a41002900b2a441370000200841002900aca4413700002008410e411c102c2208450d102008200e36000e200741a0016a41186a220a4200370300200741a0016a41106a22094200370300200741a0016a41086a22044200370300200742003703a00120084112200741a0016a1000200741c0006a41186a200a290300370300200741c0006a41106a2009290300370300200741c0006a41086a2004290300370300200720072903a0013703402008102a200741c0006a412010090c170b2008450d10200841066a41002900b2a441370000200841002900aca4413700002008410e411c102c2208450d112008200e36000e200741a0016a41186a22094200370300200741a0016a41106a22044200370300200741a0016a41086a220d4200370300200742003703a00120084112200741a0016a1000200741c0006a41186a2009290300370300200741c0006a41106a2004290300370300200741c0006a41086a200d290300370300200720072903a0013703402008102a200741203602742007200741c0006a360270200a2011200741f0006a10ab022005a7450d16200a102a0c160b200741f0006a41086a2208420037030020074200370370419991c6004114200741f0006a1008200741a0016a41086a2008290300370300200720072903703703a0014100210a20074100360270200741a0016a4110200741f0006a10062108024020072802702209417f460d002008450d0020094104490d122008280000210a2008102a0b410e10282208450d12200841066a41002900b2a441370000200841002900aca4413700002008410e411c102c2208450d132008200a36000e200741a0016a41186a22094200370300200741a0016a41106a22044200370300200741a0016a41086a220d4200370300200742003703a00120084112200741a0016a1000200741c0006a41186a2009290300370300200741c0006a41106a2004290300370300200741c0006a41086a200d290300370300200720072903a0013703402008102a20074100360270200741c0006a4120200741f0006a1006210802400240024020072802702209417f460d002008450d002007200936027420072008360270200741086a200741f0006a106c0240024020072802080d00200728020c210d410021040c010b4101210441b8aec600210d0b02402009450d002008102a0b20040d00200d413f460d01200d0d170b200741f0006a2001428080d287e2bc2d4200410810980220072802704101470d012007280278210a200728027421080c1f0b200741f0006a41086a2208420037030020074200370370419991c6004114200741f0006a1008200741a0016a41086a2008290300370300200720072903703703a0012007200a41016a360270200741a0016a4110200741f0006a410410070c150b20072903782105200720074180016a29030037037820072005370370200b2006428080aef89dc3527c2205200654ad7c427f7c210b2007200741f0006a3602a001200741a0016a109d01200521060c140b41c4d1c3004133200741c0016a419cd9c3001038000b411341011037000b41c4d1c3004133200741c0016a419cd9c3001038000b410e41011037000b411c41011037000b41c4d1c3004133200741c0016a419cd9c3001038000b410e41011037000b411c41011037000b41c4d1c3004133200741c0016a419cd9c3001038000b410e41011037000b411c41011037000b41c4d1c3004133200741c0016a419cd9c3001038000b41a0a3c100200920111034000b410e41011037000b411c41011037000b410e41011037000b411c41011037000b41c4d1c3004133200741c0016a419cd9c3001038000b410e41011037000b411c41011037000b200741f9006a200141086a29000037000020074181016a200141106a29000037000020074189016a200141186a290000370000200741013a00702007200129000037007102400240024002400240024002400240024002400240024002400240024002400240410e10282208450d00200841066a41002900b2a441370000200841002900aca4413700002008410e411c102c2208450d012008200a36000e200741a0016a41186a22094200370300200741a0016a41106a22044200370300200741a0016a41086a220d4200370300200742003703a00120084112200741a0016a1000200741c0006a41186a2009290300370300200741c0006a41106a2004290300370300200741c0006a41086a200d290300370300200720072903a0013703402008102a200741003602a001200741c0006a4120200741a0016a100621080240024020072802a0012204417f460d002004210920080d010b200741003602a801200742013703a0014100200741a0016a10b40120072802a801210920072802a401210420072802a00121080b200720093602682007200436026420072008360260024002402009450d00200741a0016a20082009410110d60220072802a0014101470d012007280264450d122007280260102a0c120b4101200741e0006a10b401024020072d00704101460d0002400240200728026420072802682208460d00200728026021090c010b200841016a22092008490d1b200841017422042009200420094b1b22044100480d1b0240024020080d002004102821090c010b200728026020082004102c21090b2009450d052007200436026420072009360260200728026821080b2007200841016a360268200920086a41003a00000c100b02400240200728026420072802682208460d00200728026021090c010b200841016a22092008490d1a200841017422042009200420094b1b22044100480d1a0240024020080d002004102821090c010b200728026020082004102c21090b2009450d052007200436026420072009360260200728026821080b2007200841016a360268200920086a41013a0000200741f0006a410172200741e0006a108f010c0f0b20072802a401210d0240200741ac016a2802002208200741a8016a2802002209460d002007280268200820096b6a220441216a220e417f4c0d0502400240200e0d004101210f0c010b200e1028220f450d070b2007200e3602c4012007200f3602c001200720043602c8012007200741c0016a3602a001200d200741a0016a200810d70120042008490d0720072802c801220d2004490d082007280268220d2009490d0920072802c001210e2007280260210f2007200420086b22043602d0012007200d20096b220d3602d4012004200d470d0a200e20086a200f20096a2004109a051a0240024020072d00704101460d000240024020072802c40120072802c8012208460d0020072802c00121090c010b200841016a22092008490d1c200841017422042009200420094b1b22044100480d1c0240024020080d002004102821090c010b20072802c00120082004102c21090b2009450d0e200720043602c401200720093602c00120072802c80121080b2007200841016a3602c801200920086a41003a00000c010b0240024020072802c40120072802c8012208460d0020072802c00121090c010b200841016a22092008490d1b200841017422042009200420094b1b22044100480d1b0240024020080d002004102821090c010b20072802c00120082004102c21090b2009450d0e200720043602c401200720093602c00120072802c80121080b2007200841016a3602c801200920086a41013a0000200741f0006a410172200741c0016a108f010b20072802c801210920072802c401210420072802c00121082007280264450d102007280260102a0c100b2007200741e0006a3602a001200d200741a0016a200910d701024020072d00704101460d0002400240200728026420072802682208460d00200728026021090c010b200841016a22092008490d1a200841017422042009200420094b1b22044100480d1a0240024020080d002004102821090c010b200728026020082004102c21090b2009450d0e2007200436026420072009360260200728026821080b2007200841016a360268200920086a41003a00000c0f0b02400240200728026420072802682208460d00200728026021090c010b200841016a22092008490d19200841017422042009200420094b1b22044100480d190240024020080d002004102821090c010b200728026020082004102c21090b2009450d0e2007200436026420072009360260200728026821080b2007200841016a360268200920086a41013a0000200741f0006a410172200741e0006a108f010c0e0b410e41011037000b411c41011037000b200441011037000b200441011037000b1036000b200e41011037000b200820041044000b2004200d103c000b2009200d1044000b200741f0016a41146a4108360200200741fc016a4125360200200741d8016a41146a4103360200200742033702dc01200741c8afc6003602d801200741253602f4012007200741d0016a360288022007200741d4016a36028c02200742043703b001200742013702a4012007419cb0c6003602a0012007200741f0016a3602e8012007200741a0016a3602800220072007418c026a3602f801200720074188026a3602f001200741d8016a41d8b0c600103e000b200441011037000b200441011037000b200441011037000b200441011037000b2007280268210920072802642104200728026021080b2008450d00200741c0006a41202008200910072004450d012008102a0c010b024002400240412110282208450d0041002109024020072d00704101470d00200741b8016a20074189016a290000370300200741b0016a20074181016a290000370300200741a8016a200741f9006a290000370300200720072900713703a001410121090b200820093a0000200820072903a001370001200841096a200741a8016a290300370000200841116a200741b0016a290300370000200841196a200741b8016a290300370000410e10282209450d01200941066a41002900b2a441370000200941002900aca4413700002009410e411c102c2209450d022009200a36000e200741a0016a41186a220a4200370300200741a0016a41106a22044200370300200741a0016a41086a220d4200370300200742003703a00120094112200741a0016a1000200741c0006a41186a200a290300370300200741c0006a41106a2004290300370300200741c0006a41086a200d290300370300200720072903a0013703402009102a200741203602a4012007200741c0006a3602a00120084101200741a0016a10ab022008102a0c030b412141011037000b410e41011037000b411c41011037000b20072001428080e983b1de164200108302024020072802002208450d002007280204210a0c080b200741f0006a41086a220842003703002007420037037041ad91c6004112200741f0006a1008200741a0016a41086a2008290300370300200720072903703703a0014100210a20074100360270200741a0016a4110200741f0006a100621080240024020072802702209417f460d002008450d0020094104490d012008280000210a2008102a0b4200210c200741f0006a41086a220842003703002007420037037041ad91c6004112200741f0006a1008200741a0016a41086a2008290300370300200720072903703703a0012007200a41016a360270200741a0016a4110200741f0006a41041007420021050c060b41c4d1c3004133200741c0016a419cd9c3001038000b0b02402010a7450d00200d102a2004450d010c020b20040d010b410121094113210a419781c20021080c010b200741c0016a41026a200741d8016a41026a2d00003a0000200741f0006a41086a200741a0016a41086a290300370300200741f0006a410d6a200741a0016a410d6a290000370000200720072f01d8013b01c001200720072903a001370370410021090b200741e0006a41026a2204200741c0016a41026a2d00003a0000200741f0016a41086a220d200741f0006a41086a290300370300200741f0016a41106a200741f0006a41106a290300370300200720072f01c0013b0160200720072903703703f00120090d02200741d3006a200d290300370000200741d8006a200741fd016a290000370000200720072f01603b01402007200a36004720072008360043200720072903f00137004b200720042d00003a0042200741c0006a2001460d00200741c0006a20014120109c05450d0041d280c20021084111210a0c020b200742f0f2bda9c6add9b1f400370338200741386a20012006200b417f410f10a902200741f0006a41186a200b3703002007200637038001200720053703782007200c370370200720033602940120072003360290010240024002400240411310282208450d00200841002900c2a3413700002008410f6a41002800d1a341360000200841086a41002900caa34137000020074293808080b0023702f401200720083602f0012001200741f0016a108f0120072802f801210820072802f001210a200741a0016a41186a22094200370300200741a0016a41106a22034200370300200741a0016a41086a22044200370300200742003703a001200a2008200741a0016a1000200741c0006a41186a2009290300370300200741c0006a41106a2003290300370300200741c0006a41086a2004290300370300200720072903a001370340024020072802f401450d0020072802f001102a0b200741203602a4012007200741c0006a3602a001200741f0006a200741a0016a10c3022002280204210f20022802002103024002400240200241086a280200220941057622120d0041042113410421140c010b2012410274220810282213450d01201321140b2009450d030240024020120d00410410282213450d0141012112201321140b201441003602002009417f6a210441012115410021084100210a024003402014200a4102746a2202200320086a2d00002008411f717420022802006a360200024002400240024020042008460d00200841016a2202411f710d0320152012470d02201541016a220d2015490d0c2015410174220e200d200e200d4b1b221241ffffffff03712012470d0c2012410274220d41004e0d010c0c0b0240200f450d002003102a0b41002116024002400240024003402015410820154108491b220a410274220f10282208450d0120082014200f109a052111200741f0006a41186a200141186a290000370300200741f0006a41106a200141106a290000370300200741f0006a41086a200141086a290000370300200720163602900120072001290000370370411310282208450d0220084100290099a4413700002008410f6a41002800a8a441360000200841086a41002900a1a44137000020074293808080b0023702f401200720083602f001200741f0006a200741f0016a108f0120072802900121090240024020072802f401220220072802f80122086b4104490d0020072802f00121020c010b200841046a22032008490d11200241017422082003200820034b1b22084100480d110240024020020d002008102821020c010b20072802f00120022008102c21020b2002450d04200720083602f401200720023602f00120072802f80121080b2007200841046a3602f801200220086a200936000020072802f801210820072802f0012102200741a0016a41186a22094200370300200741a0016a41106a22034200370300200741a0016a41086a22044200370300200742003703a00120022008200741a0016a1000200741c0006a41186a2009290300370300200741c0006a41106a2003290300370300200741c0006a41086a2004290300370300200720072903a001370340024020072802f401450d0020072802f001102a0b2015200a6b21152014200f6a2114410021082007410036027820074201370370200a200741f0006a10b4014100200728027822046b210a200728027421030340200420086a2109201120086a280200210d024002402003200a6a4104490d00200728027021020c010b200941046a22022009490d122003410174220e2002200e20024b1b220e4100480d120240024020030d00200e102821020c010b20072802702003200e102c21020b2002450d062007200e36027420072002360270200e21030b2007200941046a360278200220046a20086a200d360000200a417c6a210a200f200841046a2208470d000b200741c0006a41202002200420086a100702402003450d002002102a0b2011102a201641016a211620150d000b410021082012450d0e2013102a0c0e0b200f41041037000b411341011037000b200841011037000b200e41011037000b0240024020150d00200d102821130c010b20132015410274200d102c21130b2013450d03201321140b201420154102746a4100360200200a41016a210a201541016a21150b200920024d0d05200221082015200a4b0d000b41a0a3c100200a20151034000b200d41041037000b410441041037000b200841041037000b411341011037000b41cca2c100200841016a20091034000b0240200f450d002003102a0b410021080b0c020b1031000b200241046a280200450d002002280200102a0b2000200a3602042000200836020020074190026a24000b810f03037f017e097f23004190016b2202240002400240024002400240024002400240024002400240410e10282203450d00200341066a41002900b2a441370000200341002900aca4413700002003410e411c102c2203450d0120032001410676220436000e42002105200241f0006a41186a22064200370300200241f0006a41106a22074200370300200241f0006a41086a220842003703002002420037037020034112200241f0006a1000200241086a41186a2006290300370300200241086a41106a2007290300370300200241086a41086a2008290300370300200220022903703703082003102a20024100360238200241086a4120200241386a100621030240024020022802382207417f470d00410121060c010b024020030d00410121060c010b2002200736027420022003360270200241386a200241f0006a107420022802382206450d03200229023c21052007450d002003102a0b2001413f7122032005422088a722074f0d032006200341216c6a220341003a000020032002290038370001200341096a200241c0006a290000370000200341116a200241c8006a290000370000200341196a200241d0006a290000370000410e10282203450d04200341066a41002900b2a441370000200341002900aca4413700002003410e411c102c2203450d052003200436000e200241f0006a41186a22044200370300200241f0006a41106a22084200370300200241f0006a41086a220142003703002002420037037020034112200241f0006a1000200241086a41186a2004290300370300200241086a41106a2008290300370300200241086a41086a2001290300370300200220022903703703082003102a2002412036023c2002200241086a36023820062007200241386a10ab0202402005a7450d002006102a0b200241386a41086a220342003703002002420037033841ad91c6004112200241386a1008200120032903003703002002200229033837037020024100360238200241f0006a4110200241386a10062103417f2106024020022802382201417f460d002003450d0020014104490d07200328000021062003102a2006417f6a21060b200241386a41086a220442003703002002420037033841ad91c6004112200241386a1008200241f0006a41086a220720042903003703002002200229033837037020022006360238200241f0006a4110200241386a41041007200241386a41186a2208200041186a2209290000370300200241386a41106a220a200041106a220b2900003703002004200041086a220c2900003703002002410036025820022000290000370338200241286a200241386a10c10202402002280230450d0041012106034020082009290000370300200a200b2900003703002004200c29000037030020022006417f6a36025820022000290000370338411310282203450d0920034100290099a4413700002003410f6a41002800a8a441360000200341086a41002900a1a44137000020024293808080b00237026420022003360260200241386a200241e0006a108f012002280258210d0240024020022802642201200228026822036b4104490d00200228026021010c010b200341046a220e2003490d0c20014101742203200e2003200e4b1b22034100480d0c0240024020010d002003102821010c010b200228026020012003102c21010b2001450d0b2002200336026420022001360260200228026821030b2002200341046a360268200120036a200d3600002002280268210320022802602101200241f0006a41186a220d4200370300200241f0006a41106a220e4200370300200742003703002002420037037020012003200241f0006a1000200241086a41186a200d290300370300200241086a41106a200e290300370300200241086a41086a20072903003703002002200229037037030802402002280264450d002002280260102a0b200241086a412010090240200228022c450d002002280228102a0b20082009290000370300200a200b2900003703002004200c2900003703002002200029000037033820022006360258200641016a2106200241286a200241386a10c10220022802300d000b0b0240200228022c450d002002280228102a0b411310282203450d0a200341002900c2a3413700002003410f6a41002800d1a341360000200341086a41002900caa34137000020024293808080b00237023c200220033602382000200241386a108f012002280240210320022802382106200241f0006a41186a22014200370300200241f0006a41106a22004200370300200241f0006a41086a220442003703002002420037037020062003200241f0006a1000200241086a41186a2001290300370300200241086a41106a2000290300370300200241086a41086a2004290300370300200220022903703703080240200228023c450d002002280238102a0b200241086a4120100920024190016a24000f0b410e41011037000b411c41011037000b41c4d1c3004133200241e0006a419cd9c3001038000b41a0a3c100200320071034000b410e41011037000b411c41011037000b41c4d1c3004133200241e0006a419cd9c3001038000b411341011037000b200341011037000b1031000b411341011037000bd40201027f0240024002402002450d002002417f6a2104024020012d0000220241037122054103460d000240024020050e03040001040b2004450d0220012d0001410874200272220241ffff0371418002490d02200241fcff037141027621020c040b20044103490d0120012f0001200141036a2d000041107472410874200272220241808004490d01200241027621020c030b200241034b0d0020044104490d002001280001220241ffffffff034b0d020b200041013602000f0b200241027621020b0240200220036a220120024f0d00200041013602000f0b41012103410121050240200241c000490d0041022105200241808001490d00410441052002418080808004491b21050b0240200141c000490d0041022103200141808001490d00410441052001418080808004491b21030b20002001360204200041003602002000410c6a2003360200200041086a20053602000b130020004101360204200041f486c2003602000b3400200041f487c20036020420004100360200200041146a4107360200200041106a418488c200360200200041086a420f3702000b2201017f230041106b22022400200241003602002000200210da02200241106a24000bd60201037f0240024002400240024002400240024002400240024002400240024020012802000e0400010203000b41012102410110282201450d05200141003a0000410121030c040b410110282202450d05200241013a000020012802042103200241014105102c2202450d062002200336000120012802082104410a210320024105410a102c2201450d07200120043600050c020b41012102410110282201450d07200141023a0000410121030c020b410110282202450d07200241033a000020012802042103200241014105102c2202450d082002200336000120012802082104410a210320024105410a102c2201450d09200120043600050b410921020b2000200236020820002003360204200020013602000f0b410141011037000b410141011037000b410541011037000b410a41011037000b410141011037000b410141011037000b410541011037000b410a41011037000b130020004101360204200041cc92c2003602000b34002000419596c20036020420004100360200200041146a4107360200200041106a419c96c200360200200041086a42073702000b130020004101360204200041aca3c2003602000b890201057f230041106b22022400024002400240411110282203450d002002421137020420022003360200410d200210b4010240024020022802042204200228020822036b410d490d002003410d6a2105200228020021040c010b2003410d6a22052003490d03200441017422062005200620054b1b22064100480d030240024020040d002006102821040c010b200228020020042006102c21040b2004450d0220022006360204200220043602000b20022005360208200420036a22034100290082a542370000200341056a4100290087a54237000020002002290300370200200041086a2002280208360200200241106a24000f0b411141011037000b200641011037000b1031000bce04010b7f230041106b220324002003420037030820012002200341086a102720032003290308370300200120026a21040240024002400240200241086a220520024f0d00200341086a2106200321074100210841002105410121094100210a0340200841017421022006200741016a220b6b210c034020072d00002107024002400240024020082005470d00200c2105024002400240200a41ff01710e03010200010b200420016b21050c010b417f200c200420016b6a22052005200c491b21050b2008417f200541016a220d200d2005491b6a22052008490d0920022005200220054b1b22054100480d090240024020080d002005102821090c010b200920082005102c21090b2009450d010b200920086a20073a00000240024002400240200a41ff01710e03010300010b20042001460d010c050b0240200b2006460d004100210a0c040b20042001470d040b200841016a21080c070b4101210a200b2006470d01200841016a21080c060b200541011037000b200841016a2108200b21070c020b200841016a21084102210a200241026a21022001220741016a21010c000b0b0b4101210902402005450d0020054100480d03200510282209450d020b410021080340200920086a200320086a2d00003a0000200841016a22084108470d000b024020020d00410821080c010b200920086a210a410021080340200a20086a200120086a2d00003a00002002200841016a2208470d000b200420016b41086a21080b200020083602082000200536020420002009360200200341106a24000f0b200541011037000b1031000bc30401047f230041206b22022400024002400240024002400240410110282203450d00200320012d00003a0000200341014102102c2203450d01200320012d00013a0001200341024104102c2203450d02200320012d00023a0002200320012d00033a0003200341044108102c2203450d03200320012d00043a0004200320012d00053a0005200320012d00063a0006200320012d00073a0007200341084110102c2203450d04200320012d00083a0008200320012d00093a0009200320012d000a3a000a200320012d000b3a000b200320012d000c3a000c200320012d000d3a000d200320012d000e3a000e200320012d000f3a000f200341104120102c2203450d05200320012d00103a0010200320012d00113a0011200320012d00123a0012200320012d00133a0013200320012d00143a0014200320012d00153a0015200320012d00163a0016200320012d00173a0017200320012d00183a0018200320012d00193a0019200320012d001a3a001a200320012d001b3a001b200320012d001c3a001c200320012d001d3a001d200320012d001e3a001e200320012d001f3a001f200241186a22014200370300200241106a22044200370300200241086a22054200370300200242003703002003412020021000200041186a2001290300370000200041106a2004290300370000200041086a2005290300370000200020022903003700002003102a200241206a24000f0b410141011037000b410241011037000b410441011037000b410841011037000b411041011037000b412041011037000bd40201087f230041206b2203240020034100360208200342013703002001200310b401024002400240024020010d002003280208210420032802042105200328020021060c010b200141246c210720032802042105200328020821010340200341106a200010ec012003280210210802400240200520016b20032802182209490d00200120096a2104200328020021060c010b200120096a22042001490d04200541017422062004200620044b1b220a4100480d040240024020050d00200a102821060c010b20032802002005200a102c21060b2006450d032003200a36020420032006360200200a21050b20032004360208200620016a20082009109a051a02402003280214450d002008102a0b200041246a2100200421012007415c6a22070d000b0b2002280200200228020420062004100702402005450d002006102a0b200341206a24000f0b200a41011037000b1031000b130020004103360204200041a0a5c2003602000b340020004185acc20036020420004100360200200041146a4103360200200041106a4190acc200360200200041086a42083702000b130020004104360204200041a8b0c2003602000b0b00200041a0c21e10e6020b3001017f02404104102822020d00410441011037000b20004284808080c00037020420002002360200200220013600000b3201017f02404104102822020d00410441011037000b20004284808080c0003702042000200236020020024180e1013600000b0b00200041d0860310e6020bdd0301047f230041d0026b2202240002400240024002400240411210282203450d00200341106a41002f008086423b0000200341086a41002900f88542370000200341002900f08542370000200341124124102c2203450d0120032001360012200241e8016a41186a22014200370300200241e8016a41106a22044200370300200241e8016a41086a22054200370300200242003703e80120034116200241e8016a1000200241e8006a41186a2001290300370300200241e8006a41106a2004290300370300200241e8006a41086a2005290300370300200220022903e8013703682003102a200241003602e801200241e8006a4120200241e8016a1006210120022802e8012203417f460d032002200336020c20022001360208200241e8016a200241086a10810220022903e8014201510d0220024188016a200241e8016a41086a41e000109a051a02402003450d002001102a0b200241086a20024188016a41e000109a051a200241e8016a200241086a41e000109a051a20004201370300200041086a200241e8016a41e000109a051a0c040b411241011037000b412441011037000b41c4d1c300413320024188016a419cd9c3001038000b200241e8016a200241086a41e000109a051a200042003703000b200241d0026a24000bc06709017f017e017f027e157f017e037f017e037f230041a0056b2201240010eb020240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024020004101460d0042002102200141206a41086a2200420037030020014200370320418efcc5004110200141206a100820014188036a41086a20002903003703002001200129032037038803200141003602e80320014188036a4110200141e8036a100621000240024002400240024002400240024002400240024020012802e8032203417f460d002000450d0020034108490d01200029000021022000102a0b42002104200141206a41086a220042003703002001420037032041dffbc500410f200141206a100820014188036a41086a20002903003703002001200129032037038803200141003602e80320014188036a4110200141e8036a10062100024020012802e8032203417f460d002000450d0020034108490d02200029000021042000102a0b42002105200141206a41086a220042003703002001420037032041fefbc5004110200141206a100820014188036a41086a20002903003703002001200129032037038803200141003602e80320014188036a4110200141e8036a10062100024020012802e8032203417f460d002000450d0020034108490d03200029000021052000102a0b420020022005200442c8017e7c7d220420042002561b42c801540d0a200141206a41086a2200420037030020014200370320419499c6004114200141206a100820014188036a41086a2000290300370300200120012903203703880341002106200141003602e80320014188036a4110200141e8036a10062100024020012802e8032203417f460d002000450d0020034104490d04200028000021062000102a0b200141206a41086a220042003703002001420037032041a899c6004115200141206a100820014188036a41086a20002903003703002001200129032037038803200141003602e80320014188036a4110200141e8036a100621000240024020012802e8032203417f470d00410221070c010b024020000d00410221070c010b2003450d0520002d000021072000102a0b10fb01210820014188036a41086a22004200370300200142003703880341c2e1c000410d20014188036a1008200141e8036a41086a200029030037030020012001290388033703e80320014100360220200141e8036a4110200141206a100621000240024020012802202203417f460d002000450d00200120033602a401200120003602a001200141206a200141a0016a107c20012802202209450d07200129022421052003450d012000102a0c010b41012109420021050b200141206a41086a220042003703002001420037032041c785c2004112200141206a100820014188036a41086a20002903003703002001200129032037038803200141003602e80320014188036a4110200141e8036a100621000240024020012802e8032203417f460d002000450d002001200336022420012000360220200141e8036a200141206a106d20012802e803220a450d0820012902ec0321042003450d012000102a0c010b4101210a420021040b02402004422088a722000d004108210b4100210c4100210d0c0a0b2000410574210e200141e8036a41206a210f4100210c4100210d4108210b41002103200a2100034020014188026a41186a2210200041186a29000037030020014188026a41106a2211200041106a29000037030020014188026a41086a2212200041086a2900003703002001200029000037038802200141e8036a2008200310fc0120012802e803221320012802f00341014100410010032114024020012802ec03450d002013102a0b02402014417f470d00200141206a41186a22142010290300370300200141206a41106a22132011290300370300200141206a41086a221520122903003703002001200129038802370320200141e8036a200141206a10ec02200128028804450d09200141206a41286a2216200141e8036a41286a290300370300200141206a41206a2217200f2903003703002014200141e8036a41186a22182903003703002013200141e8036a41106a22192903003703002015200141e8036a41086a221a290300370300200120012903e8033703202018201029030037030020192011290300370300201a201229030037030020012001290388023703e803200f2001290320370300200f41086a2015290300370300200f41106a2013290300370300200f41186a2014290300370300200f41206a2017290300370300200f41286a20162903003703000240200c200d470d00200c41016a2214200c490d26200c41017422102014201020144b1b220dad42d0007e2202422088a70d262002a722144100480d2602400240200c0d0020141028210b0c010b200b200c41d0006c2014102c210b0b200b450d0b0b200b200c41d0006c6a200141e8036a41d000109a051a200c41016a210c0b200341016a2103200041206a2100200e41606a220e450d0a0c000b0b41c4d1c300413320014198056a419cd9c3001038000b41c4d1c300413320014198056a419cd9c3001038000b41c4d1c300413320014198056a419cd9c3001038000b41c4d1c300413320014198056a419cd9c3001038000b41c4d1c300413320014198056a419cd9c3001038000b41c4d1c300413320014198056a419cd9c3001038000b41c4d1c300413320014198056a419cd9c3001038000b41f187c1004192021050000b201441081037000b02402004a7450d00200a102a0b02400240200c450d002001410036022820014201370320200141f8036a200c360200200141f4036a200d3602002001200b3602f003200120054220883e02ec03200120083602e803200141206a200141e8036a10c5012005a7450d012009102a0c010b02402005a7450d002009102a0b200d450d00200b102a0b200141206a41086a220042003703002001420037032041f5b6c2004112200141206a100820014188036a41086a20002903003703002001200129032037038803200141003602e80320014188036a4110200141e8036a1006210b024002400240024002400240024002400240024002400240024002400240024002400240024020012802e8032216417f460d00200b450d00200120163602ac022001200b3602a802200141086a200141a8026a106c20012802080d2b20012802ac02220f41807f712200417f4c0d14200128020c211202400240200f41077622140d00410121150c010b200010282215450d100b02402012450d00200141e8036a41206a2113200141a0016a41017221084100210c0340200141003a00c001200c41016a210e4100210002400240024002400340200f2000460d01200141a0016a20006a20012802a80222032d00003a00002001200341016a3602a8022001200041016a22033a00c0012003210020034120470d000b20014188026a41086a2200200141a0016a41086a29030037030020014188026a41106a2210200141a0016a41106a29030037030020014188026a41186a2211200141a0016a41186a290300370300200120012903a001370388022001200f20036b3602ac02200141a0016a200141a8026a10e80120012d00a0014101460d01200141e8036a41186a2011290300370300200141e8036a41106a2010290300370300200141e8036a41086a200029030037030020012001290388023703e8032013200841e000109a051a200141206a200141e8036a418001109a051a2014200c470d03200c4101742200200e2000200e4b1b221441ffffff0f712014470d322014410774220041004e0d020c320b200141003602ac02200041ff0171450d00200141003a00c0010b2014450d2f2015102a0c2f0b02400240200c0d002000102821150c010b2015200c4107742000102c21150b2015450d050b2015200c4107746a200141206a418001109a051a200e2012460d0120012802ac02210f200e210c0c000b0b2015450d2b2012ad42208621022014ad210402402016450d00200b102a0b2002200484211b0c010b410121154200211b0b4100210002400240201b422088a72218410774220c0d004101211c4100211d0c010b200c41027622031028221c450d0d201841ffffff0f71211d0b200741ff0171210e02402018450d002018410774210f201c210020152103034020002003290000370000200041186a200341186a290000370000200041106a200341106a290000370000200041086a200341086a290000370000200041206a210020034180016a2103200f41807f6a220f0d000b201841077441807f6a41077641016a21000b200e410247210f200141206a41086a220342003703002001420037032041c785c2004112200141206a100820014188036a41086a20032903003703002001200129032037038803200141003602f003200142013703e8032000200141e8036a10b40102402000450d0020004105742103201c210003402000200141e8036a108f01200041206a2100200341606a22030d000b0b2007200f71211a20012802ec03210020014188036a411020012802e803220320012802f003100702402000450d002003102a0b0240201a450d00200141206a41086a220042003703002001420037032041bd99c600411a200141206a100820014188036a41086a20002903003703002001200129032037038803200141003602e80320014188036a4110200141e8036a1006210020012802e8032203417f460d002000450d002001200336022420012000360220200141e8036a200141206a10820120012802e803220f450d0c20012902ec03210202402003450d002000102a0b20014188036a411010092002a7450d00200f102a0b200141106a200641026a10ed02024002402001280210221e0d00200141206a41086a220042003703002001420037032041c785c2004112200141206a100820014188036a41086a20002903003703002001200129032037038803200141003602e80320014188036a4110200141e8036a10062100024020012802e8032203417f460d002000450d002001200336022420012000360220200141e8036a200141206a106d20012802e803220d450d0d20012902ec03211f02402003450d002000102a0b410021200c020b410021204101210d4200211f0c010b410121202001290214211f201e210d0b200141206a41086a2200420037030020014200370320419499c6004114200141206a100820014188036a41086a20002903003703002001200129032037038803410121162001200641016a22063602e80320014188036a4110200141e8036a41041007200120203a001f20012015200c6a22073602ec04200120153602e8042001200141e8046a3602fc0420012001411f6a3602f8044100210e410021210240201f422088a722004105742203450d002003410575222141ffffff0f712021470d2b202141077422034100480d2b200310282216450d0a0b02402000450d002000410574210c200141206a410172210b200141e8036a41206a2108200141a8026a41c0006a2119200141a8026a41206a21174100210e20162114200d21000340200041086a2900002102200041106a29000021042000290000210520014188026a41186a2210200041186a29000037030020014188026a41106a2211200437030020014188026a41086a22122002370300200120053703880220014188056a20014188026a108b02200128029005210f2001280288052103200141003602202003200f200141206a1006210f0240024020012802202213417f460d00200f450d002001201336028c032001200f36028803200141206a20014188036a10e80120012d00204101460d0c200141a0016a200b41e000109a051a02402013450d00200f102a0b20014188036a200141a0016a41e000109a051a200141206a20014188036a41e000109a051a200141a0016a200141206a41e000109a051a4101210f0c010b200141206a20014188036a41e000109a051a4100210f0b0240200128028c05450d002003102a0b02400240200f0d00200141a8026a410041e0001099051a0c010b200141a8026a200141a0016a41e000109a051a0b024020012802f8042d00000d0020012802fc04220f2802002203200f280204460d00200f20034180016a36020002400240200141a8026a200341206a220f460d00200f200141a8026a4120109c050d010b02402017200341c0006a220f460d00200f20174120109c050d010b2019200341e0006a2203460d01200320194120109c05450d010b20012802f80441013a00000b200041206a2100200141e8036a41186a2010290300370300200141e8036a41106a2011290300370300200141e8036a41086a201229030037030020012001290388023703e8032008200141a8026a41e000109a051a200e41016a210e2014200141e8036a418001109a054180016a2114200c41606a220c0d000b0b0240201fa7450d00200d102a0b200e41ffffff0f71200e470d12200e4107742200417f4c0d1220012d001f21120240024020000d00410121110c010b200010282211450d080b410021000240200e450d002016200e4107746a2110200141e8036a41e0006a2103200141e8036a41c0006a210f200141e8036a41206a210c20112114201621000340200141e8036a41186a200041186a290000370300200141e8036a41106a200041106a290000370300200141e8036a41086a200041086a290000370300200120002900003703e803200c41186a200041386a290000370000200c41106a200041306a290000370000200c41086a200041286a290000370000200c200041206a290000370000200f41186a200041d8006a290000370000200f41106a200041d0006a290000370000200f41086a200041c8006a290000370000200f200041c0006a2900003700002003200041e0006a290000370000200341086a200041e8006a290000370000200341106a200041f0006a290000370000200341186a200041f8006a2900003700002014200141e8036a418001109a054180016a211420004180016a22002010470d000b200e41077441807f6a41077641016a21000b200141206a41086a220342003703002001420037032041f5b6c2004112200141206a100820014188036a41086a20032903003703002001200129032037038803200141003602f003200142013703e8032000200141e8036a10b40102402000450d00201120004107746a21032011210003402000200141e8036a108f01200041206a200141e8036a108f01200041c0006a200141e8036a108f01200041e0006a200141e8036a108f0120004180016a22002003470d000b0b20012802ec03210020014188036a411020012802e803220320012802f003100702402000450d002003102a0b0240200e450d002011102a0b200120123a00e803200141206a41086a220042003703002001420037032041a899c6004115200141206a100820014188036a41086a2000290300370300200120012903203703880320014188036a4110200141e8036a41011007200120063602ec03200141043a00e80341014100200141e8036a10cc01410810282203450d0620032007360204200320153602000240201a0d0042002102200141206a41086a220042003703002001420037032041e194c600411c200141206a100820014188036a41086a20002903003703002001200129032037038803200141003602e80320014188036a4110200141e8036a10062100024020012802e803220f417f460d002000450d00200f4108490d07200029000021022000102a0b200141206a41086a2200420037030020014200370320419499c6004114200141206a100820014188036a41086a200029030037030020012001290320370388034100210f200141003602e80320014188036a4110200141e8036a10062100024020012802e803220c417f460d002000450d00200c4104490d062000280000210f2000102a0b411c10282200450d04200041186a41002800959546360000200041106a410029008d9546370000200041086a41002900859546370000200041002900fd94463700002000411c4138102c2200450d032000200237001c20014188026a41186a220c420037030020014188026a41106a2214420037030020014188026a41086a2210420037030020014200370388022000412420014188026a1000200141e8036a41186a200c290300370300200141e8036a41106a2014290300370300200141e8036a41086a201029030037030020012001290388023703e8032000102a2001200f360220200141e8036a4120200141206a410410072003102a0c110b024002402018450d00200320154180016a2210360200200120152900223701ea032001201529002a3701f20320014188026a41086a220020012903f003370300200120152900323701fa0320014188026a41106a220f20012903f8033703002001201528003a36018204200120152f003e3b01860420014188026a41186a220c200129038004370300200141003a008804200120152d00213a00e903200120152d00203a00e803200120012903e8033703880220014188036a41186a2214200c29030037030020014188036a41106a220c200f29030037030020014188036a41086a220f2000290300370300200120012903880237038803200141206a41186a22002014290300370300200141206a41106a2214200c290300370300200141206a41086a220c200f290300370300200120012903880337032020150d010b2003102a4108211241002110410021000c100b200141a0016a41186a2000290300370300200141a0016a41106a2014290300370300200141a0016a41086a200c290300370300200120012903203703a001200720106b41077641016a220041286c220f417f4c0d12200f10282212450d01201220012903a00137030020124201370320201241186a200141a0016a41186a220a290300370300201241106a200141a0016a41106a2209290300370300201241086a200141a0016a41086a222229030037030002402003280200220f2003280204220d470d00410121100c0f0b2003200f4180016a22063602002001200f2900223701ea032001200f29002a3701f20320014188026a41086a221320012903f0033703002001200f2900323701fa0320014188026a41106a220820012903f8033703002001200f28003a360182042001200f2f003e3b01860420014188026a41186a220b200129038004370300200141003a0088042001200f2d00213a00e9032001200f2d00203a00e803200120012903e8033703880220014188036a41186a220f200b29030037030020014188036a41106a220c200829030037030020014188036a41086a22142013290300370300200120012903880237038803200141206a41186a2217200f290300370300200141206a41106a2218200c290300370300200141206a41086a2219201429030037030020012001290388033703204102211041c80021110340200a2017290300220237030020092018290300220437030020222019290300220537030020012001290320221f3703a001200f2002370300200c2004370300201420053703002001201f3703880302400240024002402010417f6a2000460d002000211a0c010b200d20066b41077620006a41016a221a2000490d2e2000410174220d201a200d201a4b1b221aad42287e2202422088a70d2e2002a7220d4100480d2e0240024020000d00200d102821120c010b2012200041286c200d102c21120b2012450d010b201220116a220d41606a220020012903880337030020142903002102200c2903002104200f2903002105200d4201370300200041186a2005370300200041106a2004370300200041086a2002370300200328020022002003280204220d470d01201a21000c110b200d41081037000b200320004180016a2206360200200120002900223701ea032001200029002a3701f203201320012903f003370300200120002900323701fa03200820012903f8033703002001200028003a36018204200120002f003e3b018604200b200129038004370300200141003a008804200120002d00213a00e903200120002d00203a00e803200120012903e80337038802200f200b290300370300200c2008290300370300201420132903003703002001200129038802370388032017200f2903003703002018200c290300370300201920142903003703002001200129038803370320201141286a2111201041016a2110201a21000c000b0b200041011037000b200f41081037000b413841011037000b411c41011037000b41c4d1c300413320014198056a419cd9c3001038000b41c4d1c300413320014198056a419cd9c3001038000b410841041037000b200041011037000b41c4d1c300413320014198056a419cd9c3001038000b200341011037000b41c4d1c300413320014198056a419cd9c3001038000b41c4d1c300413320014198056a419cd9c3001038000b200341011037000b200041011037000b2003102a0b200141206a41086a220342003703002001420037032041d985c2004117200141206a100820014188036a41086a20032903003703002001200129032037038803200141e8036a20014188036a411010c6020240024020012802e8034101460d00200120103602f003200120003602ec03200120123602e803200141e8036a41004100200110ee020c010b20014188036a4110100920012902ec032102200120103602f003200120003602ec03200120123602e803200141e8036a2002a741012002422088a710ee020b42002102200141206a41086a220042003703002001420037032041e194c600411c200141206a100820014188036a41086a20002903003703002001200129032037038803200141003602e80320014188036a4110200141e8036a10062100024020012802e8032203417f460d002000450d0020034108490d04200029000021022000102a0b200141206a41086a220042003703002001420037032041e194c600411c200141206a100820014188036a41086a2203200029030037030020012001290320370388032001200242017c22023703e80320014188036a4110200141e8036a410810072000420037030020014200370320419499c6004114200141206a100820032000290300370300200120012903203703880341002103200141003602e80320014188036a4110200141e8036a10062100024020012802e803220f417f460d002000450d00200f4104490d05200028000021032000102a0b411c10282200450d05200041186a41002800959546360000200041106a410029008d9546370000200041086a41002900859546370000200041002900fd94463700002000411c4138102c2200450d062000200237001c20014188026a41186a220f420037030020014188026a41106a220c420037030020014188026a41086a2214420037030020014200370388022000412420014188026a1000200141e8036a41186a200f290300370300200141e8036a41106a200c290300370300200141e8036a41086a201429030037030020012001290388023703e8032000102a20012003360220200141e8036a4120200141206a410410070b410810282200450d062000200736020420002015360200410810282219450d0720192016200e4107746a221a3602042019201636020042002102200141206a41086a220342003703002001420037032041dffbc500410f200141206a100820014188036a41086a20032903003703002001200129032037038803200141003602e80320014188036a4110200141e8036a10062103024020012802e803220f417f460d002003450d00200f4108490d09200329000021022003102a0b200242017c22042002540d09200141206a41086a220342003703002001420037032041dffbc500410f200141206a100820014188036a41086a220f20032903003703002001200129032037038803200120043703e80320014188036a4110200141e8036a41081007200141e8046a20004188b7c20010880120012802ec04211020012802e804211420012802f0042100200342003703002001420037032041eefbc5004110200141206a1008200f20032903003703002001200129032037038803200141003602f003200142013703e8032000200141e8036a10b40102402000450d002014200041286c6a210e2014210303402003200141e8036a108f01200341206a29030021020240024020012802ec03220f20012802f00322006b4108490d0020012802e803210f0c010b200041086a220c2000490d1c200f4101742200200c2000200c4b1b22004100480d1c02400240200f0d0020001028210f0c010b20012802e803200f2000102c210f0b200f450d0d200120003602ec032001200f3602e80320012802f00321000b2001200041086a3602f003200f20006a2002370000200e200341286a2203470d000b0b20012802ec03210020014188036a411020012802e803220320012802f003100702402000450d002003102a0b02402010450d002014102a0b200442017c22022004540d0b200141206a41086a220042003703002001420037032041adfcc5004113200141206a100820014188036a41086a20002903003703002001200129032037038803200141e8036a20014188036a10ef0220012d00e803210020014188026a41186a220320014181046a29000037030020014188026a41106a220f200141f9036a29000037030020014188026a41086a220c200141f1036a290000370300200120012900e903370388020240024020004101460d00200141a0016a41186a4200370300200141a0016a41106a4200370300200141a0016a41086a4200370300200142003703a0010c010b200141a0016a41186a2003290300370300200141a0016a41106a200f290300370300200141a0016a41086a200c29030037030020012001290388023703a0010b200141206a41086a220042003703002001420037032041c0fcc5004111200141206a100820014188036a41086a2000290300370300200120012903203703880341002112200141003602e80320014188036a4110200141e8036a10062100024020012802e8032203417f460d002000450d0020034104490d0d200028000021122000102a0b200141206a41086a220042003703002001420037032041c0fcc5004111200141206a100820014188036a41086a20002903003703002001200129032037038803200141003602e80320014188036a4110200141e8036a41041007200141206a41186a200141a0016a41186a290300370300200141206a41106a200141a0016a41106a2903003703002000200141a0016a41086a290300370300200120012903a001370320417f201241016a220020002012491b410d74412872220b417f4c0d01200b10282208450d0d2008200129032037000020082002370020200841186a200141206a41186a290300370000200841106a200141206a41106a290300370000200841086a200141206a41086a2903003700004128211341002103410021004100211102400240024003400240024002400240024002402000450d00200f200c470d010b03402000210c200320124f0d02411610282200450d182000410e6a41002900dffc45370000200041086a41002900d9fc45370000200041002900d1fc4537000020004116412c102c2200450d192000200336001620014188026a41186a220f420037030020014188026a41106a220e420037030020014188026a41086a2214420037030020014200370388022000411a20014188026a100020014188036a41186a200f29030037030020014188036a41106a200e29030037030020014188036a41086a20142903003703002001200129038802370388032000102a200141003602a80220014188036a4120200141a8026a1006210e0240024020012802a802220f417f470d0041012100420021020c010b2001200f36028c022001200e36028802200141a8026a20014188026a107320012802a8022200450d1b20012902ac0221020240200f450d00200e102a0b20014188036a412010090b20002002422088a74105746a210f0240200c450d002010450d002011102a0b200341016a21032002a7211020002111200f2000460d000b200021112000210c0b200c41086a2900002102200c41106a2900002104200c2900002105200141e8036a41186a200c41186a290000221f370300200141e8036a41106a2004370300200141e8036a41086a2002370300200120053703e80320014188036a41186a2214201f37030020014188036a41106a2217200437030020014188036a41086a221820023703002001200537038803200b20136b411f4b0d03201341206a220e2013490d21200b410174220d200e200d200e4b1b220e4100480d21200b0d01200e102821080c020b0240200c450d002010450d002000102a0b20014188026a41186a2203420037030020014188026a41106a220f420037030020014188026a41086a220c420037030020014200370388022008201320014188026a1000200141e8036a41186a22142003290300370300200141e8036a41106a2210200f290300370300200141e8036a41086a2211200c29030037030020012001290388023703e8030240200b450d002008102a0b200141206a41086a220042003703002001420037032041adfcc5004113200141206a100820014188036a41086a220e2000290300370300200120012903203703880320014110360224200120014188036a360220200141e8036a200141206a10f002200141a8026a41186a200141a0016a41186a2903002202370300200141a8026a41106a200141a0016a41106a2903002204370300200141a8026a41086a200141a0016a41086a2903002205370300200120012903a001221f3703a8022014200237030020102004370300201120053703002001201f3703e8032000420037030020014200370320419efcc500410f200141206a1008200e2000290300370300200120012903203703880320014110360224200120014188036a360220200141e8036a200141206a10f002200141f8046a20194194b9c200108801200042003703002001420037032041adfcc5004113200141206a1008200e20002903003703002001200129032037038803200141e8036a20014188036a10ef0220012d00e8032100200320014181046a290000370300200f200141f9036a290000370300200c200141f1036a290000370300200120012900e9033703880220004101460d05200141a0036a420037030020014198036a420037030020014190036a420037030020014200370388030c060b2008200b200e102c21080b2008450d02200e210b0b200c41206a210c200820136a220e200129038803370000200e41186a2014290300370000200e41106a2017290300370000200e41086a2018290300370000201341206a21130c000b0b200e41011037000b20014188036a41186a20014188026a41186a29030037030020014188036a41106a20014188026a41106a29030037030020014188036a41086a20014188026a41086a2903003703002001200129038802370388030b200141206a41086a2200200141f8046a41086a280200360200200141206a41246a20014188036a41186a290300370200200141206a411c6a20014188036a41106a290300370200200141206a41146a20014188036a41086a290300370200200120012903f8042202370320200120012903880337022c20014194046a200141206a41286a280200360200200141e8036a41246a200141c0006a290300370200200141e8036a411c6a200141206a41186a290300370200200141e8036a41146a200141206a41106a290300370200200141f4036a220f2000290300370200200120023702ec03200141003602e803200141003602a801200142013703a001410110282200450d11200141013602a401200120012802a801220341016a3602a801200120003602a001200020036a41013a000020012802ec032103200f2802002200200141a0016a10b40102402000450d002003200041286c6a210e03402003200141a0016a108f01200341206a29030021020240024020012802a401220f20012802a80122006b4108490d0020012802a001210f0c010b200041086a220c2000490d1c200f4101742200200c2000200c4b1b22004100480d1c02400240200f0d0020001028210f0c010b20012802a001200f2000102c210f0b200f450d15200120003602a4012001200f3602a00120012802a80121000b2001200041086a3602a801200f20006a2002370000200e200341286a2203470d000b0b200141f8036a200141a0016a10f10220014193026a200141a0016a41086a280200360000200120012903a0012202370388052001200237008b02200141ac016a2001418f026a290000370000200141c28289aa043600a101200141023a00a00120012001290088023700a501200141a0016a10ce01024020012802e8030d00200141e8036a41086a280200450d0020012802ec03102a0b410810282203450d13200320073602042003201536020041081028220f450d14200f201a360204200f201636020010fb01210c411b10282200450d15200041176a41002800d89646360000200041106a41002900d19646370000200041086a41002900c99646370000200041002900c196463700002000411b4136102c2200450d162000200c36001b20014188026a41186a220c420037030020014188026a41106a220e420037030020014188026a41086a2214420037030020014200370388022000411f20014188026a100020014188036a41186a200c29030037030020014188036a41106a200e29030037030020014188036a41086a220c20142903003703002001200129038802370388032000102a20014188036a4120100e109801210e200141206a41086a2200420037030020014200370320419be1c0004111200141206a1008200c200029030037030020012001290320370388032001200e3602e80320014188036a4110200141e8036a41041007200141a0016a200341a0bbc200108301200042003703002001420037032041c2e1c000410d200141206a1008200c2000290300370300200120012903203703880320012802a001210c20012802a8012100200141003602f003200142013703e8032000200141e8036a10b40102402000450d0020004105742103200c210003402000200141e8036a108f01200041206a2100200341606a22030d000b0b20012802ec03210020014188036a411020012802e803220320012802f003100702402000450d002003102a0b024020012802a401450d00200c102a0b200f102a410810282200450d172000201a36020420002016360200200141a0016a200041acbdc200108301200141206a41086a2200420037030020014200370320419695c4004117200141206a1008200141e8036a41086a2000290300370300200120012903203703e80320012802a001210f20012802a801210020014100360228200142013703202000200141206a10b40102402000450d0020004105742103200f210003402000200141206a108f01200041206a2100200341606a22030d000b0b20012802242100200141e8036a4110200128022022032001280228100702402000450d002003102a0b024020012802a401450d00200f102a0b02402021450d002016102a0b02402020201e45720d002001280214450d00201e102a0b0240201d450d00201c102a0b201ba7450d002015102a0b200141a0056a24000f0b1036000b41c4d1c300413320014198056a419cd9c3001038000b41c4d1c300413320014198056a419cd9c3001038000b411c41011037000b413841011037000b410841041037000b410841041037000b41c4d1c300413320014198056a419cd9c3001038000b41c0c7c20041c9001050000b200041011037000b41c0c7c20041c9001050000b41c4d1c300413320014198056a419cd9c3001038000b200b41011037000b411641011037000b412c41011037000b41c4d1c300413320014198056a419cd9c3001038000b410141011037000b200041011037000b410841041037000b410841041037000b411b41011037000b413641011037000b410841041037000b41c4d1c300413320014198056a419cd9c3001038000b1031000bd11906047f017e037f027e027f037e23004190046b22002400200041e8036a41086a22014200370300200042003703e80341e7fcc5004110200041e8036a100820004188036a41086a2001290300370300200020002903e80337038803200041e0016a20004188036a109a03024002400240024002400240024020002d00e0014102470d00200041e0016a41086a22024200370300200042003703e00141b1f0c200410d200041e0016a100820012002290300370300200020002903e0013703e803200041003602e001200041e8036a4110200041e0016a1006210102400240024002400240024020002802e0012202417f460d002001450d002000200236027420002001360270200041e0016a200041f0006a107620002802e0012203450d0220002902e40121042002450d012001102a0c010b41042103420021040b20032004422088a7220541246c22066a2102200321010240200641ed00490d00200321010340024020012d00004101470d00200141016a2800002106200141086a28020021072000200141106a28020036020c20002007360208200641c28289aa04470d00200041e0016a200041086a10ba0220002d00e00122074102460d00200041e0016a2101200041f0006a21020c050b0240200141246a2d00004101470d00200141256a28000021062001412c6a28020021072000200141346a28020036020c20002007360208200641c28289aa04470d00200041e0016a200041086a10ba0220002d00e00122074102460d00200041e0016a2101200041f0006a21020c050b0240200141c8006a2d00004101470d00200141c9006a2800002106200141d0006a28020021072000200141d8006a28020036020c20002007360208200641c28289aa04470d00200041e0016a200041086a10ba0220002d00e00122074102460d00200041e0016a2101200041f0006a21020c050b0240200141ec006a2d00004101470d00200141ed006a2800002106200141f4006a28020021072000200141fc006a28020036020c20002007360208200641c28289aa04470d00200041e0016a200041086a10ba0220002d00e00122074102460d00200041e0016a2101200041f0006a21020c050b200220014190016a22016b41ec004b0d000b0b20012002460d012003200541246c6a21020340024020012d00004101470d00200141016a2800002106200141086a28020021072000200141106a28020036020c20002007360208200641c28289aa04470d00200041e0016a200041086a10ba0220002d00e00122074102460d00200041e0016a2101200041f0006a21020c040b2002200141246a2201460d020c000b0b41c4d1c3004133200041e8026a419cd9c3001038000b410221070c010b20002002200141016a41ef00109a0522012800003602602000200141036a28000036006320002900772108200041086a200041ff006a41d800109a051a20002900d70121090b02402005450d00200541246c21022003210103400240024020012d0000220641034b0d0002400240024020060e0404000102040b2001410c6a280200450d03200141086a280200102a0c030b2001410c6a280200450d02200141086a280200102a0c020b2001410c6a280200450d01200141086a280200102a0c010b200141086a280200450d00200141046a280200102a0b200141246a21012002415c6a22020d000b0b02402004a7450d002003102a0b200020002802603602682000200028006336006b200041f0006a200041086a41d800109a051a41002101024020074102460d00200020002802683602e0022000200028006b3600e302200020083703d802200041e0016a200041f0006a41d800109a051a200020093703d002200041e8036a41086a22014200370300200042003703e80341fefbc5004110200041e8036a100820004188036a41086a2001290300370300200020002903e80337038803200041003602a80320004188036a4110200041a8036a100621010240024020002802a8032202417f460d002001450d0020024108490d04200129000021042001102a200450450d010b200041d8026a200041d0026a20074101461b2903002104200041e8036a41086a22014200370300200042003703e80341fefbc5004110200041e8036a100820004188036a41086a22022001290300370300200020002903e80337038803200020043703a80320004188036a4110200041a8036a4108100720014200370300200042003703e80341eefbc5004110200041e8036a100820022001290300370300200020002903e8033703880341002101200041003602a80320004188036a4110200041a8036a100621060240024020002802a8032202417f470d000c010b200020023602ec03200020063602e803200041a8036a200041e8036a107720002802a8032201450d0520002902ac0321042002450d002006102a0b200041e8036a41086a22024200370300200042003703e803419efcc500410f200041e8036a100820004188036a41086a22062002290300370300200020002903e80337038803200041a8036a20004188036a10ef0220002d00a8032103200041e8036a41186a220a200041c1036a290000370300200041e8036a41106a220b200041b9036a2900003703002002200041b1036a290000370300200020002900a9033703e8032001410820011b21050240024020034101460d0020004188036a41186a420037030020004188036a41106a42003703002006420037030020004200370388030c010b20004188036a41186a200a29030037030020004188036a41106a200b29030037030020062002290300370300200020002903e803370388030b200041e8026a41086a20004188036a41086a2903002209370300200041e8026a41106a20004188036a41106a290300220c370300200041e8026a41186a20004188036a41186a290300220d3703002000200029038803220e3703e802200041a8036a41086a2004420020011b370300200041a8036a41106a220a200e370300200041a8036a41186a2009370300200041c8036a200c370300200041a8036a41286a200d370300200020053602ac03200041003602a803200041003602f003200042013703e803410110282201450d05200041013602ec03200020002802f003220241016a3602f003200020013602e803200120026a41013a000020002802ac032102200041a8036a410c6a2802002201200041e8036a10b40102402001450d002002200141286c6a210503402002200041e8036a108f01200241206a29030021040240024020002802ec03220620002802f00322016b4108490d0020002802e80321060c010b200141086a22032001490d0a200641017422012003200120034b1b22014100480d0a0240024020060d002001102821060c010b20002802e80320062001102c21060b2006450d09200020013602ec03200020063602e80320002802f00321010b2000200141086a3602f003200620016a20043700002005200241286a2202470d000b0b200a200041e8036a10f10220004193036a200041f0036a280200360000200020002903e80322043703d8032000200437008b03200041e8036a410c6a2000418f036a290000370000200041c28289aa043600e903200041023a00e80320002000290088033700ed03200041e8036a10ce0120002802a8030d0020002802b003450d0020002802ac03102a0b200041d8026a200041d0026a20074101461b2903002104200041e8036a41086a22014200370300200042003703e803418efcc5004110200041e8036a100820004188036a41086a2001290300370300200020002903e80337038803200020043703a80320004188036a4110200041a8036a410810074100210120070d00200041a8036a41086a200041e0016a41086a290300370300200041a8036a41106a200041e0016a41106a2d00003a0000200020002800e3023600eb02200020002802e0023602e802200020002903e0013703a803410121010b200041e0016a41086a2008370300200041e0016a41106a20002903a803370300200041f8016a200041a8036a41086a29030037030020004180026a200041a8036a41106a2d00003a0000200020013a00e001200020002802e8023600e101200020002800eb023600e401200041e8036a41086a22024200370300200042003703e80341e7fcc5004110200041e8036a100820004188036a41086a2002290300370300200020002903e80337038803410110282202450d0620004201370274200020023602700240024020010d0020004101360278200241003a00000c010b20004101360278200241013a0000200041e0016a410172200041f0006a10f1020b2000280274210120004188036a411020002802702202200028027810072001450d002002102a0b20004190046a24000f0b41c4d1c3004133200041e8026a419cd9c3001038000b41c4d1c3004133200041e8026a419cd9c3001038000b410141011037000b200141011037000b1031000b410141011037000bec0501057f23004190016b2202240002400240410f10282203450d00200341002900edae44370000200341076a41002900f4ae443700002002428f808080f001370214200220033602102001200241106a108f012002280218210320022802102101200241e0006a41186a22044200370300200241e0006a41106a22054200370300200241e0006a41086a220642003703002002420037036020012003200241e0006a1000200241306a41186a2004290300370300200241306a41106a2005290300370300200241306a41086a20062903003703002002200229036037033002402002280214450d002002280210102a0b20024100360260200241306a4120200241e0006a100621040240024020022802602201417f470d00410021030c010b2002200136025420022004360250200241e0006a200241d0006a10d4012002280280012203450d02200241106a41186a200241e0006a41186a290300370300200241106a41106a200241e0006a41106a290300370300200241106a41086a200241e0006a41086a290300370300200241086a2002418c016a2802003602002002200229036037031020022002290284013703002001450d002004102a0b200241e0006a41086a2201200241106a41086a290300370300200241e0006a41106a2204200241106a41106a290300370300200241e0006a41186a2205200241106a41186a290300370300200241d0006a41086a2206200241086a2802003602002002200229031037036020022002290300370350024002402003450d002000200229036037030020002003360220200041246a2002290350370200200041186a2005290300370300200041106a2004290300370300200041086a20012903003703002000412c6a20062802003602000c010b2000420037030020004208370320200041186a4200370300200041106a4200370300200041086a4200370300200041286a41003602000b20024190016a24000f0b410f41011037000b41c4d1c3004133200241106a419cd9c3001038000b84fc0111067f017e037f017e027f017e047f017e037f017e017f0a7e017f027e017f0a7e2a7f230041a0196b22022400200241e00e6a41086a22034200370300200242003703e00e41cd9cc6004123200241e00e6a1008200241900f6a41086a2003290300370300200220022903e00e3703900f41002104200241003602f011200241900f6a4110200241f0116a10062103024002400240024002400240024002400240024020022802f0112205417f460d002003450d0020054104490d01200328000021042003102a0b2001417f6a2106200241e00e6a41086a22034200370300200242003703e00e418e9dc6004110200241e00e6a1008200241900f6a41086a2003290300370300200220022903e00e3703900f200241003602f011200241900f6a4110200241f0116a1006210302400240024020022802f0112201417f460d002003450d002001450d0220032d0000220141034f0d022003102a200141014b0d06024020010e020100010b200241e00e6a41086a22034200370300200242003703e00e418e9dc6004110200241e00e6a1008200241900f6a41086a2003290300370300200220022903e00e3703900f200241900f6a411010090c010b200620046b220320064b0d0520034106490d050b200241f0116a41086a22034200370300200242003703f01141c785c2004112200241f0116a1008200241e00e6a41086a2003290300370300200220022903f0113703e00e200241003602f011200241e00e6a4110200241f0116a1006210302400240024020022802f0112204417f460d002003450d00200220043602940f200220033602900f200241f0116a200241900f6a106d20022802f0112207450d0220022902f41121082004450d012003102a0c010b41012107420021080b410021090240024002402008422088a7220341057422010d004108210a4100210b0c010b2001410575220bad42d0007e220c422088a70d0c200ca722044100480d0c20041028220a450d010b2008a7210d02402003450d00200141606a210e200241f0116a41206a2103200a2105200721040340200441086a2900002108200441106a290000210c2004290000210f200241e00e6a41186a2210200441186a290000370300200241e00e6a41106a2211200c370300200241e00e6a41086a221220083703002002200f3703e00e200241900f6a200241e00e6a10ec02200241f0116a41186a2010290300370300200241f0116a41106a2011290300370300200241f0116a41086a2012290300370300200320022903900f370300200341086a200241900f6a41086a290300370300200341106a200241900f6a41106a290300370300200341186a200241900f6a41186a290300370300200341206a200241900f6a41206a290300370300200341286a200241900f6a41286a290300370300200220022903e00e3703f0112005200241f0116a41d000109a0541d0006a2105200441206a2104200141606a22010d000b200e41057641016a21090b0240200d450d002007102a0b200241e00e6a41086a22034200370300200242003703e00e41f09cc600411e200241e00e6a1008200241900f6a41086a22042003290300370300200220022903e00e3703900f200241f0116a200241900f6a10de030240024020022802f41122130d004104211342002114410021110c010b200241900f6a4110100920022802f011211120022903f81121140b10a003210820034200370300200242003703e00e41feadc4004117200241e00e6a100820042003290300370300200220022903e00e3703900f200241003602f011200241900f6a4110200241f0116a1006210302400240024020022802f0112204417f470d004200210c0c010b024020030d004200210c0c010b20044108490d012003290000210c2003102a0b200241e00e6a41086a22154200370300200242003703e00e41feadc4004117200241e00e6a1008200241900f6a41086a22162015290300370300200220022903e00e3703900f200220083703f011200241900f6a4110200241f0116a41081007410021172008200c7d2218500d0620154200370300200242003703e00e41a5afc4004116200241e00e6a100820162015290300370300200220022903e00e3703900f200241003602f011200241900f6a4110200241f0116a1006210302400240024020022802f0112204417f460d002003450d00200220043602e40e200220033602e00e200241f0116a200241e00e6a106d20022802f0112219450d0220022902f411211a02402004450d002003102a0b201a422088a721040c010b410021044200211a410121190b4200210c200241e00e6a41086a22034200370300200242003703e00e4199fec4004111200241e00e6a1008200241900f6a41086a2003290300370300200220022903e00e3703900f200241003602f011200241900f6a4110200241f0116a1006210302400240024020022802f0112201417f470d004200210c4200211b0c010b024020030d004200211b0c010b20014110490d01200341086a290000211b2003290000210c2003102a0b200241800c6a10a102200241f00b6a20022903800c220f200241800c6a41086a2903002208428094ebdc03420010a005200241d00b6a200c201b2004ad4200109f05200241e00b6a20022903f00b221b200241f00b6a41086a290300221c4280ec94a37c427f109f052008200241d00b6a41086a290300221d20022903d00b221e200f56201d200856201d2008511b22031b2108200f201e20031b210c2018428086ebc7f5002018428086ebc7f500541b421f8042ffffffff0f83428094ebdc037e429880b5e50380211f200f20022903e00b7c210f410021034184c9c0002104024002400340024041accbc00020046b41184b0d000240200441accbc000460d000340200241c00b6a201b201c200435020022184200109f052003200c20022903c00b22202018200f7e428094ebdc038042ffffffff0f837c22185a2008200241c00b6a41086a2903002018202054ad7c22205a200820205122011b6a2103200c201854200820205420011b0d0441accbc000200441086a2204470d000b0b200241b00b6a201b201c42e8aafa0b4200109f05200241b80b6a29030020022903b00b220c200f42e8aafa0b7e428094ebdc038042ffffffff0f837c2208200c54ad7c210c0c030b200241a00b6a201b201c200435020022184200109f052003200c20022903a00b22202018200f7e428094ebdc038042ffffffff0f837c22185a2008200241a00b6a41086a2903002018202054ad7c22205a200820205122011b6a2103200c201854200820205420011b0d01200241900b6a201b201c200441086a35020022184200109f052003200c20022903900b22202018200f7e428094ebdc038042ffffffff0f837c22185a2008200241900b6a41086a2903002018202054ad7c22205a200820205122011b6a2103200c201854200820205420011b0d01200241800b6a201b201c200441106a35020022184200109f052003200c20022903800b22202018200f7e428094ebdc038042ffffffff0f837c22185a2008200241800b6a41086a2903002018202054ad7c22205a200820205122011b6a2103200c201854200820205420011b0d01200241f00a6a201b201c200441186a35020022184200109f052003200c20022903f00a22202018200f7e428094ebdc038042ffffffff0f837c22185a2008200241f00a6a41086a2903002018202054ad7c22205a200820205122011b6a2103200441206a2104200c201854200820205420011b450d000b0b02402003417f6a220420034d0d00200241f0096a201b201c42c0f0f50b4200109f05200241f8096a29030020022903f009220c200f42288042ffffffff0f837c2208200c54ad7c210c0c010b02400240200441244b0d00200241e00a6a201b201c200441037422014184c9c0006a2802002205ad22184200109f05200241c00a6a200c20022903e00a22202018200f7e428094ebdc038042ffffffff0f837c2218200c2018562008200241e00a6a41086a2903002018202054ad7c22205620082020511b22041b22212018200c20041b220c7d22182008202020041b2020200820041b7d2021200c54ad7d4100200341037422104184c9c0006a280200220320056b2205200520034b1b22034101200341014b1bad2208420010a005200241b00a6a20022903c00a220c200241c00a6a41086a290300222020084200109f05200241d00a6a201b201c20014188c9c0006a2802002203ad22214200109f05200241800a6a2020420020104188c9c0006a28020022012003200120034b22051b2003200120051b6bad221b4200109f05200241a00a6a200c4200201b4200109f05200241900a6a42004200200c4200109f05427f427f200241a00a6a41086a290300220c20022903800a20022903900a7c7c221c20022903880a20022903980a84420052201c200c547222051b221c427f20022903a00a20051b220c201820022903b00a7d201b7e2008807c2208200c542205ad7c221b2005201b201c542008200c5a1b22051b211c427f200820051b211b200241d00a6a41086a29030020022903d00a22082021200f7e428094ebdc038042ffffffff0f837c220c200854ad7c21082004200120034d730d0142002008201c7d200c201b54ad7d220f200c201b7d221b200c56200f200856200f2008511b22031b210c4200201b20031b21080c020b41acd9c300200441251034000b427f2008201c7c200c201b7c220f200c542203ad7c220c2003200c200854200c2008511b22031b210c427f200f20031b21080b42002122200241e0096a2008200c428094ebdc03420010a005200241d0096a20022903e009220c200241e0096a41086a290300220f4280ec94a37c427f109f05200241c0096a200c200f201f4200109f05201f200820022903d0097c7e428094ebdc038021080240201a422088a722030d00420021230c080b20132014422088a74102746a210e201920034105746a2124200241c0096a41086a29030020022903c009220c200842ffffffff0f837c2225200c54ad7c2126200241f0116a41086a2127200241900f6a41086a21122011ad21284200212242002123201321052019211003402005200e460d08024020052802002203450d00024002400240024002402011450d00200241b0096a202520262028420010a005200241a0096a20022903b0092208200241b0096a41086a290300220c20284200109f0520024190096a2008200c20112003200320114b1bad220f4200109f05202520022903a0097d200f7e2028802108200229039009210f20024190096a41086a290300211c411210282203450d01200341002900c1ae44370000200341106a41002f00d1ae443b0000200341086a41002900c9ae4437000020024292808080a0023702f411200220033602f0112010200241f0116a108f0120022802f811210320022802f0112104200241900c6a41186a22014200370300200241900c6a41106a22074200370300200241900c6a41086a220d4200370300200242003703900c20042003200241900c6a1000200241c00d6a41186a2001290300370300200241c00d6a41106a2007290300370300200241c00d6a41086a200d290300370300200220022903900c3703c00d024020022802f411450d0020022802f011102a0b200241003602f011200241c00d6a4120200241f0116a1006210320022802f0112204417f460d032003450d03200220043602f411200220033602f011200241f8086a200241f0116a109f0120022903f808a70d02200241f8086a41106a290300210c200229038009211b2004450d042003102a0c040b41acfec4001032000b411241011037000b41c4d1c300413320024198196a419cd9c3001038000b4200211b4200210c0b0240024002400240024002400240200f200842ffffffff0f837c2208201b2008201b200854200c201c2008200f54ad7c220f54200c200f511b22031b22297d222a200f200c200f20031b222b7d2008202954ad7d222c8450450d004200211f4200211c420021084200210c0c010b200241f0116a201010ec0220272903002208420020022903f011220c42015620084200522008501b22031b2108200c420120031b210f20022802901221070240024020022802981222030d004200211f200241f0076a200f2008428094ebdc03420010a005200241f0076a41086a290300212d20022903f007212e4200211c0c010b2007200341306c6a21014200211f200241e8086a200f2008428094ebdc03420010a005200241c8086a202a202c428094ebdc03420010a005200241d8086a202a202c428094ebdc03420010a105200241e8086a41086a290300222d420020022903e808222e420156202d420052202d501b22031b2118202e420120031b2120200241c8086a41086a290300212f20022903c808213020022903d80821314200211c200721030340200241b8086a200f2003290300220c200c200f56200341086a290300220c200856200c2008511b22041b2008200c20041b2020201810a00520022903b808221b428080808010544100200241b8086a41086a290300501b450d03200241a8086a200f20082020201810a00520022903a808220c428080808010544100200241a8086a41086a290300501b450d04024002400240200ca7450d0020024180086a2030202f201b42ffffffff0f83428094ebdc037e200c42ffffffff0f838042ffffffff0f83220c4200109f0520024190086a200341106a2203200229038008221b200c20317e428094ebdc038042ffffffff0f837c220c20024180086a41086a290300200c201b54ad7c10b404200229039008210c200229039808211b200241900f6a41106a20024190086a41106a29030022213703002002201b3703980f2002200c3703900f0240200ca74101470d00427f201c20217c201f201b7c221b201f542204ad7c220c2004200c201c54200c201c511b22041b211c427f201b20041b211f0c030b200c4201510d010c020b41acaac3001032000b200220123602e00e200241e00e6a109c010b200341206a22032001470d000b0b200241e0076a200f200229038012220c200c200f56200241f0116a41186a290300220c200856200c2008511b22031b2008200c20031b202e4201202e420156202d420052202d501b22031b220c202d420020031b221b10a00520022903e0072218428080808010544100200241e0076a41086a290300501b450d01200241d0076a200f2008200c201b10a00520022903d0072208428080808010544100200241d0076a41086a290300501b450d022008a7450d03200241c0076a202a202c428094ebdc03420010a005200241b0076a20022903c007220c200241c0076a41086a290300220f4280ec94a37c427f109f05200241a0076a200c200f201842ffffffff0f83428094ebdc037e200842ffffffff0f838042ffffffff0f8322084200109f0520022903a007220c2008202a20022903b0077c7e428094ebdc038042ffffffff0f837c2208200c54ad210c200241a0076a41086a290300210f0240200228029412450d002007102a0b200f200c7c210c0b20024188076a2010200820297c220f200c202b7c200f200854ad7c10b4042002290388072108200229039007210c200241f0116a41106a20024188076a41106a290300220f3703002002200c3703f811200220083703f01102402008a74101470d00427f201c200f7c201f200c7c220c201f542203ad7c220820032008201c542008201c511b22031b211c427f200c20031b211f0c050b20084201510d030c040b10d101000b10d201000b41acaac3001032000b200220273602900f200241900f6a109c010b427f2023201c7c2022201f7c220c2022542203ad7c22082003200820235420082023511b22031b2123427f200c20031b21220b200541046a2105201041206a22102024470d000c080b0b41c4d1c300413320024198196a419cd9c3001038000b41c4d1c300413320024198196a419cd9c3001038000b41c4d1c300413320024198196a419cd9c3001038000b200441081037000b41c4d1c300413320024198196a419cd9c3001038000b41c4d1c300413320024198196a419cd9c3001038000b41c4d1c300413320024198196a419cd9c3001038000b02402014a7450d002013102a0b20024188126a202337030020024180126a2022370300200241f8116a41003a0000200241033a00f0114101211741014100200241f0116a10cc01200220233703f811200220223703f0112002200241f0116a3602900f200241900f6a109c0102402022202384500d00201e201d84500d00200241f8066a10a10220022903f8062208201e7d220f200856200241f8066a41086a290300220c201d7d2008201e54ad7d2208200c562008200c511b0d00200241e8066a200f2008201e201d10a005200241b8066a200241e8066a41086a2903002208420020224200109f05200241c8066a2023420020022903e806220c4200109f05200241d8066a200c420020224200109f05200842005220234200527120022903c0064200527220022903d00642005272200241d8066a41086a290300220820022903b80620022903c8067c7c220f200854720d0020022903d806211b200241e00e6a41086a22034200370300200242003703e00e41ace1c0004116200241e00e6a1008200241900f6a41086a2003290300370300200220022903e00e3703900f200241003602f011200241900f6a4110200241f0116a100621030240024020022802f0112204417f460d002003450d00024020044110490d00200341086a290000210c200329000021082003102a0c020b41c4d1c300413320024198196a419cd9c3001038000b420021084200210c0b200241e00e6a41086a22034200370300200242003703e00e41ace1c0004116200241e00e6a1008200241900f6a41086a22042003290300370300200220022903e00e3703900f2002427f200c200f7c2008201b7c22182008542203ad7c221c2003201c200c54201c200c511b22031b3703f8112002427f201820031b3703f011200241900f6a4110200241f0116a41101007200241f0116a10d301200241a8066a200241f0116a2008427f85201b20031b2208200c427f85200f20031b220c10d001200241900f6a41106a200c200241a8066a41086a290300221b7d200820022903a806220f54ad7d201b200c7d200f200854ad7d200f200858201b200c58201b200c5122031b22011b37030020022008200f7d200f20087d20011b3703980f2002200f200856201b200c5620031b2203ad3703900f024020030d00200220043602e00e200241e00e6a109d010c010b200220043602e00e200241e00e6a109c010b201aa7450d002019102a0b20154200370300200242003703e00e41bb9cc6004112200241e00e6a100820162015290300370300200220022903e00e3703900f200241003602f011200241900f6a4110200241f0116a10062103024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024020022802f0112204417f470d00410021270c010b024020030d00410021270c010b20044104490d01200328000021272003102a0b200241e00e6a41086a22034200370300200242003703e00e41bb9cc6004112200241e00e6a1008200241900f6a41086a2003290300370300200220022903e00e3703900f2002202741016a22163602f011200241900f6a4110200241f0116a41041007411710282203450d012003410f6a41002900d3fe44370000200341086a41002900ccfe44370000200341002900c4fe4437000020034117412e102c2203450d0220032027360017200241900c6a41186a22044200370300200241900c6a41106a22014200370300200241900c6a41086a22054200370300200242003703900c2003411b200241900c6a1000200241c00d6a41186a2004290300370300200241c00d6a41106a2001290300370300200241c00d6a41086a2005290300370300200220022903900c3703c00d2003102a200241c00d6a41201009200241e00e6a41086a22034200370300200242003703e00e41cd9cc6004123200241e00e6a1008200241900f6a41086a2003290300370300200220022903e00e3703900f200241003602f011200241900f6a4110200241f0116a10062103024020022802f0112204417f460d002003450d00200441034d0d042003102a0b200241e00e6a41086a22154200370300200242003703e00e41cd9cc6004123200241e00e6a1008200241900f6a41086a22192015290300370300200220022903e00e3703900f200220063602f011200241900f6a4110200241f0116a41041007201641a105490d0920154200370300200242003703e00e41b99dc6004112200241e00e6a100820192015290300370300200220022903e00e3703900f41002112200241003602f011200241900f6a4110200241f0116a100621320240024020022802f0112233417f470d000c010b024020320d000c010b200220333602f411200220323602f011200241a0066a200241f0116a106c20022802a0060d2e20022802f41122104178712203417f4c0d2020022802a406210e02400240201041037622070d00410421120c010b200310282212450d060b0240200e450d004100211141002105410021010340200241003602e00e02400240024020104104490d0020022010417c6a22103602f411200220022802f011220341046a3602f0112003280000210d200241003602e00e20104104490d00200141016a210420022010417c6a22103602f4112002200341086a3602f0112003280004210320012007470d0220112004201120044b1b220741ffffffff01712007470d342007410374222441004e0d010c340b2007450d322012102a0c320b0240024020010d002024102821120c010b201220052024102c21120b2012450d090b201220056a2201200d360200200141046a2003360200201141026a2111200541086a210520042101200e2004470d000b0b2012450d2e200ead4220862007ad8421082033450d002032102a0b2012410420121b210e02402008420020121b2208422088220ca722032008a7470d00200341016a22042003490d2f200ca722054101742201200420042001491b220441ffffffff01712004470d2f200441037422014100480d2f0240024020030d0020011028210e0c010b200e20054103742001102c210e0b200e450d072008422088a721032004ad21080b202741e17a6a2104200e20034103746a2201200636020420012016360200200e200341016a22114103746a2110410021030240201141044f0d00200e21010c080b200e2105024003402005220128020020044f0d0a0240200141086a2802002004490d00200341016a21030c0b0b0240200141106a2802002004490d00200341026a21030c0b0b200141186a28020020044f0d01200341046a21032010200141206a22056b41184b0d000b200141206a21010c080b200341036a21030c080b41c4d1c300413320024198196a419cd9c3001038000b411741011037000b412e41011037000b41c4d1c300413320024198196a419cd9c3001038000b200341041037000b202441041037000b200141041037000b20012010460d00200e20114103746a21050340200128020020044f0d01200341016a21032005200141086a2201470d000b0b20112003490d01200842ffffffff0f8321080240201120036b2207450d0002402003450d00200e200e20034103746a2007410374109b051a0b200e280204210d200241e00e6a41086a22124200370300200242003703e00e418199c6004113200241e00e6a1008200241900f6a41086a22242012290300370300200220022903e00e3703900f200241f0116a200241900f6a411010c6024101210320022902f411210c0240024020022802f01122044101460d00200441014621030c010b200c422088a72206200d200d20064b1b2211200ca72204490d000240201120044d0d000340411a10282203450d06200341186a41002f00e0bb403b0000200341106a41002900d8bb40370000200341086a41002900d0bb40370000200341002900c8bb403700002003411a4134102c2203450d072003200436001a200241900c6a41186a22014200370300200241900c6a41106a22054200370300200241900c6a41086a22104200370300200242003703900c2003411e200241900c6a1000200241b00c6a41186a2001290300370300200241b00c6a41106a2005290300370300200241b00c6a41086a2010290300370300200220022903900c3703b00c2003102a200241b00c6a41201009200441016a2203210420112003470d000b0b200d2006492103200c428080808070832011ad84210c0b20124200370300200242003703e00e418199c6004113200241e00e6a100820242012290300370300200220022903e00e3703900f0240024020030d00200241900f6a411010090c010b410810282203450d062003200c422088a73600042003200ca7360000200241900f6a41102003410810072003102a0b20082007ad4220868421080b200241e00e6a41086a22034200370300200242003703e00e41b99dc6004112200241e00e6a1008200241900f6a41086a2003290300370300200220022903e00e3703900f0240200e0d00200241900f6a411010090c010b200241003602f811200242013703f0112008422088a72203200241f0116a10b4010240024020030d0020022802f811210320022802f411210120022802f01121040c010b200e20034103746a2106410020022802f81122116b210520022802f4112101410021030340201120036a2110200e20036a2212280200210702400240200120056a4104490d0020022802f01121040c010b201041046a22042010490d282001410174220d2004200d20044b1b220d4100480d280240024020010d00200d102821040c010b20022802f0112001200d102c21040b2004450d082002200d3602f411200220043602f011200d21010b2002201041046a220d3602f811200420116a20036a2007360000201241046a28020021070240200120056a417c6a41034b0d00200d41046a2224200d490d282001410174220d2024200d20244b1b220d4100480d280240024020010d00200d102821040c010b20042001200d102c21040b2004450d092002200d3602f411200220043602f011200d21010b2002201041086a3602f811200420116a20036a41046a2007360000200541786a2105200341086a2103201241086a2006470d000b201120036a21030b2008a72105200241900f6a411020042003100702402001450d002004102a0b2005450d00200e102a0b20154200370300200242003703e00e41889cc6004116200241e00e6a100820192015290300370300200220022903e00e3703900f41002134200241003602f011200241900f6a4110200241f0116a10062103024020022802f0112204417f460d002003450d0020044104490d07200328000021342003102a0b200241e00e6a41086a22034200370300200242003703e00e419e9cc600411d200241e00e6a1008200241900f6a41086a2003290300370300200220022903e00e3703900f200241003602f011200241900f6a4110200241f0116a10062103024002400240024020022802f0112204417f460d0020030d010b410421040c010b20044104490d09200328000021042003102a41012115200441014d0d010b200421150b200241900c6a41186a22034200370300200241900c6a41106a22044200370300200241900c6a41086a22014200370300200242003703900c41d3aec400411a200241900c6a1000200241f0116a41186a2003290300370300200241f0116a41106a2004290300370300200241f0116a41086a2001290300370300200220022903900c3703f011200241900e6a200241f0116a412010fd01200241e00e6a41206a200241900e6a41206a2d00003a0000200241e00e6a41186a200241900e6a41186a290300370300200241e00e6a41106a200241900e6a41106a290300370300200241e00e6a41086a200241900e6a41086a290300370300200220022903900e3703e00e200241f0116a200241e00e6a10ab010240024020022903f0114201510d004101211141002105410021060c010b200220022f01f8113b01e00c2002200229008b123703d00c2002200241fa116a2d00003a00e20c2002200241f0116a41206a2900003700d50c200241fb116a2800002103200241ff116a280000210420024183126a280000210120024187126a2800002105412010282211450d09201120022f01e00c3b00002011200536000f2011200136000b2011200436000720112003360003201120022903d00c370013201141026a20022d00e20c3a0000201141186a20022900d50c370000200241900f6a41206a200241e00e6a41206a2d00003a0000200241900f6a41186a200241e00e6a41186a290300370300200241900f6a41106a200241e00e6a41106a290300370300200241900f6a41086a200241e00e6a41086a290300370300200220022903e00e3703900f200241f0116a200241900f6a10ab0141012105024020022903f0114201510d00410121060c010b200241f0116a41086a2103410221104120210141012105410121060340200241b00c6a41186a200341186a2903002208370300200241b00c6a41106a200341106a290300220c370300200241b00c6a41086a200341086a290300220f37030020022003290300221b3703b00c200241900c6a41186a22122008370300200241900c6a41106a2207200c370300200241900c6a41086a220d200f3703002002201b3703900c024020052006470d00200541016a22042005490d2720102004201020044b1b220641ffffff3f712006470d27200641057422044100480d270240024020050d002004102821110c010b201120012004102c21110b2011450d110b201120016a220420022903900c370000200441186a2012290300370000200441106a2007290300370000200441086a200d290300370000201041026a2110200141206a2101200541016a2105200241f0116a200241900f6a10ab0120022903f0114201510d000b0b200241900c6a41186a22034200370300200241900c6a41106a22044200370300200241900c6a41086a22014200370300200242003703900c41a7aec400411a200241900c6a1000200241f0116a41186a2003290300370300200241f0116a41106a2004290300370300200241f0116a41086a2001290300370300200220022903900c3703f011200241e00d6a200241f0116a412010fd01200241900e6a41206a200241e00d6a41206a2d00003a0000200241900e6a41186a200241e00d6a41186a290300370300200241900e6a41106a200241e00d6a41106a290300370300200241900e6a41086a200241e00d6a41086a290300370300200220022903e00d3703900e200241f0116a200241900e6a10ad01024002402002280290120d004104213541002104410021360c010b412c10282235450d0a203520022903f011370200203541286a200241f0116a41286a2212280200360200203541206a200241f0116a41206a2207290300370200203541186a200241f0116a41186a220d290300370200203541106a200241f0116a41106a220e290300370200203541086a200241f0116a41086a2224290300370200200241e00e6a41206a200241900e6a41206a2d00003a0000200241e00e6a41186a200241900e6a41186a290300370300200241e00e6a41106a200241900e6a41106a290300370300200241e00e6a41086a200241900e6a41086a290300370300200220022903900e3703e00e200241900f6a200241e00e6a10ad01024020022802b00f0d0041012104410121360c010b41022110412c2101410121044101213603402012200241900f6a41286a2802003602002007200241900f6a41206a290300370300200d200241900f6a41186a290300370300200e200241900f6a41106a2903003703002024200241900f6a41086a290300370300200220022903900f3703f011024020042036470d00200441016a22032004490d2720102003201020034b1b2236ad422c7e2208422088a70d272008a722034100480d270240024020040d002003102821350c010b203520012003102c21350b2035450d0d0b203520016a220320022903f011370200200341286a2012280200360200200341206a2007290300370200200341186a200d290300370200200341106a200e290300370200200341086a2024290300370200201041026a21102001412c6a2101200441016a2104200241900f6a200241e00e6a10ad0120022802b00f0d000b0b200242003702ec0c200241f8b9c0003602e80c200420056a2201ad42d0007e2208422088a70d152008a72203417f4c0d150240024020030d00410821100c010b200310282210450d0c0b200241003602c80e200220013602c40e200220103602c00e200241900e6a41206a200241e80c6a360200200241003602a80e200241a40e6a20024198196a36020020022011200541057422016a220d36029c0e200220113602980e200220063602940e200220113602900e2002200241c00e6a3602ac0e200220024198196a3602a00e410221244101210e0240024020050d00201121030c010b4200211b2011210302400340200341086a2900002108200341106a290000210c2003290000210f200241f0116a41186a2205200341186a290000370300200241f0116a41106a2210200c370300200241f0116a41086a221220083703002002200f3703f01120024190066a200241f0116a10b004200241b00c6a41086a22072012290300370300200241b00c6a41106a22122010290300370300200241b00c6a41186a22102005290300370300200220022903f0113703b00c20024190066a41086a290300210c200229039006210f20024180066a10a102200241f0056a20022903800620024180066a41086a290300427f420010a005200241e0056a200f200c20022903f005220842012008420156200241f0056a41086a29030022084200522008501b22051b2008420020051b10a005200241900c6a41086a2007290300370300200241900c6a41106a2012290300370300200241900c6a41186a2010290300370300200220022903b00c3703900c20022903e005220850450d01200341206a2103200141606a22010d000b2002200d3602980e200d21030c010b200220022f01900c3b01e00c200220022d00920c3a00e20c200220022900a30c3703d00c200220022800f80c3602b80d2002200341206a22033602980e2002200241a80c6a2900003700d50c2002200241fb0c6a2800003600bb0d20022800930c210120022800970c2112200228009b0c2110200228009f0c2105200220022d00e20c3a00a20d200220022f01e00c3b01a00d200220022900d50c3700f511200220022903d00c3703f011200220022800bb0d3600c30d200220022802b80d3602c00d200220022d00a20d3a00aa0d200220022f01a00d3b01a80d200220022900f5113700e50e200220022903f0113703e00e200220022800c30d3600b30d200220022802c00d3602b00d4100210e410021240b200220022f01a80d3b01c00d200220022d00aa0d3a00c20d200220022903e00e3703f011200220022900e50e3700f511200220022802b00d3602a00d200220022800b30d3600a30d024002400240200e450d00200241023a00d00f0c010b200220022d00c20d3a009a0d200220022f01c00d3b01980d200220022903f0113703e00d200220022900f5113700e50d200220022802a00d3602880d200220022800a30d36008b0d200241013602a80e200220022d009a0d3a00960d200220022f01980d3b01940d200220022900e50d3700d50e200220022903e00d3703d00e20024190126a201b37030020024188126a200837030020024180126a4200370300200241a7126a2005360000200241a3126a20103600002002419f126a20123600002002419b126a2001360000200242003703f811200242003703f01120024198126a20022f01940d3b01002002419a126a20022d00960d3a0000200241f0116a41c8006a20243a0000200241ab126a20022903d00e370000200241b0126a20022900d50e370000200241bc126a200228008b0d360000200241b9126a20022802880d360000200241900f6a200241ac0e6a200241f0116a10fb0220022d00d00f4102470d010b02402003200d460d002002200d20036b41606a41607120036a41206a3602980e0b410021372006450d142011102a0c140b41c80010282238450d0c2038200241900f6a41c800109a051a200241e00e6a41086a200241900e6a41086a2903002208370300200241e00e6a41206a200241900e6a41206a280200360200200241e00e6a41186a200241900e6a41186a290300370300200241e00e6a41106a200241900e6a41106a290300370300200220022903900e3703e00e410121102008a7220320022802ec0e2201460d10200241b9126a210e200241fc0e6a21274200211b02400340200341086a2900002108200341106a290000210c2003290000210f200241f0116a41186a2205200341186a290000370300200241f0116a41106a2211200c370300200241f0116a41086a221220083703002002200f3703f011200241d0056a200241f0116a10b004200241b00c6a41086a22072012290300370300200241b00c6a41106a22122011290300370300200241b00c6a41186a22112005290300370300200220022903f0113703b00c200241d0056a41086a290300210c20022903d005210f200241c0056a10a102200241b0056a20022903c005200241c0056a41086a290300427f420010a005200241a0056a200f200c20022903b005220842012008420156200241b0056a41086a29030022084200522008501b22051b2008420020051b10a005200241900c6a41086a2007290300370300200241900c6a41106a2012290300370300200241900c6a41186a2011290300370300200220022903b00c3703900c20022903a005220850450d012001200341206a2203470d000b200220013602e80e200121030c110b200220022f01900c3b01e00c200220022d00920c3a00e20c200220022900a30c3703d00c200220022800f80c3602b80d2002200341206a22033602e80e2002200241900c6a41186a220d2900003700d50c2002200241f80c6a41036a22392800003600bb0d20022800930c211120022800970c2112200228009b0c2107200228009f0c2116200220022d00e20c3a008a0d200220022f01e00c3b01880d200220022900d50c3700e50d200220022903d00c3703e00d200220022800bb0d3600b30d200220022802b80d3602b00d20024198126a2124200241a30c6a213a20022802f80e2105200241f0116a410472220641086a2133200641106a213b200241ab126a223c41056a213d41012110410121370340200220022d008a0d22193a00aa0d200220022f01880d22323b01a80d200220022903e00d3703c00d200220022900e50d3700c50d200220022802b00d3602a00d200220022800b30d3600a30d200220193a00960d200220323b01940d2002200541016a22193602f80e200220022900c50d3700d50e200220022903c00d3703d00e200241f0116a41206a201b3703002006420037020020334200370200203b41003602002002200837038812200220053602f011202420022f01940d3b0100202441026a20022d00960d3a0000200220163600a712200220073600a3122002201236009f122002201136009b12203c20022903d00e370000203d20022900d50e370000200241003a00b812200e41036a20022800a30d360000200e20022802a00d360000200241900f6a2027200241f0116a10fb02024020022d00d00f4102470d00203821110c140b200241f0116a200241900f6a41c800109a051a024020372010470d00201041016a22052010490d26201041017422112005201120054b1b2237ad42c8007e2208422088a70d262008a722054100480d260240024020100d002005102821380c010b2038201041c8006c2005102c21380b2038450d0f0b2038201041c8006c6a200241f0116a41c800109a051a201041016a2110024020032001470d00200121030c130b02400340200241f0116a41186a2205200341186a290000370300200241f0116a41106a2211200341106a290000370300200241f0116a41086a2212200341086a290000370300200220032900003703f01120024190056a200241f0116a10b004200241b00c6a41086a22072012290300370300200241b00c6a41106a22122011290300370300200241b00c6a41186a22112005290300370300200220022903f0113703b00c20024190056a41086a290300210c200229039005210f20024180056a10a1024200211b200241f0046a20022903800520024180056a41086a290300427f420010a005200241e0046a200f200c20022903f004220842012008420156200241f0046a41086a29030022084200522008501b22051b2008420020051b10a005200241900c6a41086a2007290300370300200241900c6a41106a2012290300370300200d2011290300370300200220022903b00c3703900c20022903e004220850450d012001200341206a2203460d120c000b0b200220022f01900c3b01e00c200220022d00920c3a00e20c200220022800f80c3602b80d2002200341206a22033602e80e2002203a2900003703d00c2002203a41056a2900003700d50c200220392800003600bb0d20022800930c211120022800970c2112200228009b0c2107200228009f0c2116200220022d00e20c3a008a0d200220022f01e00c3b01880d200220022900d50c3700e50d200220022903d00c3703e00d200220022800bb0d3600b30d200220022802b80d3602b00d201921050c000b0b41e4e8c5001032000b411a41011037000b413441011037000b410841011037000b200d41011037000b200d41011037000b41c4d1c300413320024198196a419cd9c3001038000b41c4d1c300413320024198196a419cd9c3001038000b412041011037000b412c41041037000b200341041037000b200341081037000b41c80041081037000b200541081037000b200441011037000b200220013602e80e200121030c010b410121370b20382111200241023a00d00f0b024020032001460d002002200120036b41606a41607120036a41206a3602e80e0b20022802e40e450d0120022802e00e102a0c010b4108213841082111410021100b0240024002400240024002400240024020102015490d000240024020022802c40e220320022802c80e223d6b2004412c6c2201412c6d2205490d0020022802c00e21030c010b203d20056a2205203d490d18200341017422122005201220054b1b2205ad42d0007e2208422088a70d182008a722124100480d180240024020030d002012102821030c010b20022802c00e200341d0006c2012102c21030b2003450d02200220053602c40e200220033602c00e20022802c80e213d0b203520016a213e024020040d002035213b0c070b2003203d41d0006c6a2133203521030340200241c00d6a41186a2204200341186a290200370300200241c00d6a41106a2201200341106a290200370300200241c00d6a41086a2205200341086a290200370300200220032902003703c00d2003412c6a213b2003280220223c450d07200341286a2802002124200341246a280200213a200241900f6a41186a22392004290300370300200241900f6a41106a223f2001290300370300200241900f6a41086a22402005290300370300200220022903c00d3703900f200241d0046a200241900f6a10b0042024ad42387e2208422088a70d092008a72203417f4c0d09200241d0046a41086a290300211c20022903d00421180240024020030d00410821150c010b200310282215450d040b0240024020240d0041002124410021060c010b203c20244105746a213241002106203c21070340200741086a2900002108200741106a290000210c2007290000210f200241f0116a41186a2227200741186a290000370300200241f0116a41106a2216200c370300200241f0116a41086a221920083703002002200f3703f011200741206a2107200241e80c6a210320022802ec0c210d024003402003280200221241086a210420122f0106220e4105742103410021010240024003402003450d01200241f0116a20044120109c052205450d02200341606a2103200141016a2101200441206a21042005417f4a0d000b2001417f6a210e0b200d450d02200d417f6a210d2012200e4102746a4194036a21030c010b0b2010201220014102746a41e8026a220328020022044d0d072011200441c8006c6a22042903102108200441186a290300210c200241c0046a10a102200241b0046a20022903c004200241c0046a41086a290300427f420010a0052010200328020022044d0d08200241a0046a2018201c20022903b004220f4201200f420156200241b0046a41086a290300220f420052200f501b22011b200f420020011b10a0052011200441c8006c6a220441186a427f200c200820022903a0047c220f2008542201ad7c221b2001201b200c54200f20085a1b22011b3703002004427f200f20011b370310200241900c6a41186a22042027290300370300200241900c6a41106a22012016290300370300200241900c6a41086a22052019290300370300200220022903f0113703900c200328020021120240024020062024460d00200621030c010b202441016a22032024490d1c2024410174220d2003200d20034b1b220dad42387e2208422088a70d1c2008a722034100480d1c0240024020240d002003102821150c010b2015202441386c2003102c21150b2015450d0a20242103200d21240b2015200341386c6a220342003703082003420037030020032012360210200320022903900c3702142003411c6a2005290300370200200341246a20012903003702002003412c6a2004290300370200200641016a21060b20072032470d000b0b0240203a450d00203c102a0b200241b00c6a41186a22032039290300370300200241b00c6a41106a2204203f290300370300200241b00c6a41086a22012040290300370300200220022903900f3703b00c20024190046a10a10220024180046a20022903900420024190046a41086a290300427f420010a005200241f0036a2018201c20022903800422084201200842015620024180046a41086a29030022084200522008501b22051b2008420020051b10a00520334200370308203320022903f00337030020334200370310203341186a4200370300203320063602282033202436022420332015360220203320022903b00c37022c203341346a20012903003702002033413c6a2004290300370200203341c4006a2003290300370200203d41016a213d203341d0006a2133203b2103203b203e470d000b2002203d3602c80e0c070b02402037450d002038102a0b024020022802c80e2203450d00200341d0006c210120022802c00e41206a210303400240200341046a280200450d002003280200102a0b200341d0006a2103200141b07f6a22010d000b0b024020022802c40e450d0020022802c00e102a0b20022802e80c20022802ec0c20022802f00c10bc0202402004450d002004412c6c2104203541206a210303400240200341046a280200450d002003280200102a0b2003412c6a2103200441546a22040d000b0b2036450d0f2035102a0c0f0b201241081037000b200341081037000b41a09ec400200420101034000b41b09ec400200420101034000b200341081037000b2002203d3602c80e203b203e460d000340203b41206a2802002204450d01203b412c6a21030240203b41246a280200450d002004102a0b2003213b203e2003470d000b0b02402036450d002035102a0b2034ad42307e2208422088a70d002008a72203417f4c0d00024002400240024020030d00410821060c010b200310282206450d010b2034412c6c2203417f4c0d0202400240024020030d004104213f0c010b20031028223f450d010b4100213602402010203420102034491b223b0d0020342141410021390c030b2011201041c8006c22356a2127200241f0116a41106a2132200241f0116a41086a213320112103203421164100213941002119034002402010450d002035210403400240200341c0006a2d00000d00200241e0036a427f427f200341106a290300220842012008420156200341186a29030022084200522008501b22011b2008420020011b10a0052003200241e0036a41086a290300370308200320022903e0033703000b200341c8006a2103200441b87f6a22040d000b0b20022802c00e220520022802c80e220e41d0006c6a211502400240024002400240200e450d00200521120340024020122802282203450d00200341386c2101201228022041106a210303402010200328020022044d0d0402402011200441c8006c6a22042d00400d002004290310220c200441186a290300220f84500d00200241d0036a2012290300220842004280808080104200109f05200241a0036a4200420020084200109f05200241c0036a427f20022903d003201241086a290300220842ffffffff0f8320085220022903a80342005272200241d0036a41086a290300221b200842208620022903a0037c7c2208201b547222071b427f200820071b200c200f10a005200241b0036a201241146a350200201241186a290300220842208684200842208820022903c003200241c0036a41086a290300109f052004427f2004290300220820022903b0037c220c200c2008542207200441086a220d2903002208200241b0036a41086a2903007c2007ad7c220c200854200c2008511b22071b370300200d427f200c20071b3703000b200341386a2103200141486a22010d000b0b201241d0006a22122015470d000b0b201941016a21192011201041c8006c6a21122035210420112103024003402003210102400240201220036b41d8014d0d00200141c0006a2d00000d01200141c8006a21030c070b0340024020040d00201621410c0c0b200441b87f6a2104200141c0006a2107200141c8006a2203210120072d00000d000b200341b87f6a21010c060b20014188016a2d0000450d01200141d0016a2d0000450d03200441e07d6a2104200141a0026a210320014198026a2d00000d000b410321040c030b20014190016a2103410121040c020b41bcc0c200200420101034000b200141d8016a2103410221040b2001200441c8006c6a21010b024020032012460d00200141086a29030021082001290300210c0340200341c8006a21040240200341c0006a2d00000d00200341086a290300220f2008200c2003290300221b562008200f562008200f511b22121b2108201b200c20121b210c2003200120121b21010b2004210320272004470d000b0b200141013a00400240200e450d002001410c6a210d200141206a210e0340200541d0006a2124024020052802282204450d0020052802202103200441386c2104034002400240200d2003460d00200341146a200e4120109c050d010b200541186a22122903002108200141086a2207290300210c20032001290300220f2005290310221b7d3703002003200c20087d200f201b54ad7d3703082001290300210820122007290300370300200520083703100b200341386a2103200441486a22040d000b0b2024210520242015470d000b0b200129031021082032200141306a2900003703002033200141286a290000370300200141186a290300210c200241f0116a41186a2203200141386a290000370300200220012900203703f01102400240024020392016460d00201621410c010b201641016a22042016490d15201641017422012004200120044b1b2241ad42307e220f422088a70d15200fa722044100480d150240024020160d002004102821060c010b2006201641306c2004102c21060b2006450d0120162139204121160b2033290300210f2032290300211b2003290300211c20022903f01121182006203941306c6a2203200837032020032018370300200341286a200c370300200341186a201c370300200341106a201b370300200341086a200f370300203941016a2139201121032019203b4f0d040c010b0b200441081037000b200341041037000b200341081037000b024020022802c80e2203450d0020022802c00e2235200341d0006c6a2140200641e0006a213b2006203941306c22036a210d200241900e6a41186a213c200241900e6a41106a213d200241900e6a41086a213a20034191014921334100213602400340203c203541c4006a290000370300203d2035413c6a290000370300203a203541346a2900003703002002203529002c3703900e024020352802282203450d0020352802202204200341386c6a21322035412c6a211641002127410821194100211503402006210302400240024020330d00203b2103024002400240200441146a2201200241f0116a46220e450d0020062903202108200641086a290300210c200641106a290300210f200641186a290300211b2006290300211c200241f0116a41286a200641286a290300370300200241f0116a41186a201b370300200241f0116a41106a200f370300200241f0116a41086a200c37030020022008370390122002201c3703f0110c010b024002400340200341406a22102903002108200341a07f6a2205290300210c200541086a290300210f200541106a290300211b200541186a290300211c200241f0116a41286a2205201041086a290300370300200241f0116a41186a2210201c370300200241f0116a41106a2211201b370300200241f0116a41086a2212200f37030020022008370390122002200c3703f011200241f0116a20014120109c05450d03200341706a22242903002108200341506a2207290300210c200741086a290300210f200741106a290300211b200741186a290300211c2005202441086a2903003703002010201c3703002011201b3703002012200f37030020022008370390122002200c3703f0110240200e0d00200241f0116a20014120109c05450d00200341206a2903002108200341086a290300210c200341106a290300210f200341186a290300211b2003290300211c2005200341286a2903003703002010201b3703002011200f3703002012200c37030020022008370390122002201c3703f011200e0d03200241f0116a20014120109c05450d03200341d0006a2903002108200341306a290300210c200341386a290300210f200341c0006a290300211b200341c8006a290300211c2005200341d8006a2903003703002010201c3703002011201b3703002012200f37030020022008370390122002200c3703f011200e0d02200241f0116a20014120109c05450d02200341e0006a2105200341c0016a2103200d20056b4190014d0d050c010b0b200241900f6a41286a2005290300370300200241900f6a41206a200241f0116a41206a290300370300200241900f6a41186a2010290300370300200241900f6a41106a2011290300370300200241900f6a41086a2012290300370300200220022903f0113703900f0c050b200241900f6a41286a2005290300370300200241900f6a41206a200241f0116a41206a290300370300200241900f6a41186a2010290300370300200241900f6a41106a2011290300370300200241900f6a41086a2012290300370300200220022903f0113703900f0c040b200241900f6a41286a2005290300370300200241900f6a41206a200241f0116a41206a290300370300200241900f6a41186a2010290300370300200241900f6a41106a2011290300370300200241900f6a41086a2012290300370300200220022903f0113703900f0c030b200241900f6a41286a200241f0116a41286a290300370300200241900f6a41206a200241f0116a41206a290300370300200241900f6a41186a200241f0116a41186a290300370300200241900f6a41106a200241f0116a41106a290300370300200241900f6a41086a200241f0116a41086a290300370300200220022903f0113703900f0c020b200341a07f6a21030b2003200d460d0102400240200441146a2201200241f0116a470d0020032903202108200341086a290300210c200341106a290300210f200341186a290300211b2003290300211c200241f0116a41286a200341286a290300370300200241f0116a41186a201b370300200241f0116a41106a200f370300200241f0116a41086a200c37030020022008370390122002201c3703f0110c010b0340200341206a2903002108200341086a290300210c200341106a290300210f200341186a290300211b2003290300211c200241f0116a41286a200341286a290300370300200241f0116a41186a201b370300200241f0116a41106a200f370300200241f0116a41086a200c37030020022008370390122002201c3703f011200241f0116a20014120109c05450d01200d200341306a2203470d000c030b0b200241900f6a41286a200241f0116a41286a290300370300200241900f6a41206a200241f0116a41206a290300370300200241900f6a41186a200241f0116a41186a290300370300200241900f6a41106a200241f0116a41106a290300370300200241900f6a41086a200241f0116a41086a290300370300200220022903f0113703900f0b200241e00e6a41286a200241900f6a41286a2903002208370300200241e00e6a41206a200241900f6a41206a290300220c370300200241e00e6a41186a200241900f6a41186a290300220f370300200241e00e6a41106a200241900f6a41106a290300221b370300200241e00e6a41086a200241900f6a41086a290300221c370300200220022903900f22183703e00e200241f0116a41286a2008370300200241f0116a41206a200c370300200241f0116a41186a200f370300200241f0116a41106a201b370300200241f0116a41086a201c370300200220183703f011200241f0116a2016460d00200241f0116a20164120109c05450d00024002402035290310221b2004290300220c85203541186a290300220f200441086a2903002208858450450d0042002108428080808010210c0c010b20024190036a200c42004280808080104200109f0520024180036a42004200200c4200109f050240200842ffffffff0f832008522002290388034200527220024190036a41086a290300221c20084220862002290380037c7c2218201c54724101470d000240201b422088200f42208684221b200f422088220f84500d00200241e0026a200c2008201b200f10a005200241e0026a41086a290300210820022903e002210c0c020b41dcc0c2001032000b200241f0026a2002290390032018201b4201201b420156200f420052200f501b22031b200f420020031b10a005200241f0026a41086a290300210820022903f002210c0b200220042f00143b01a00d2002200441166a2d00003a00a20d2002200441276a2900003703f80c20022004412c6a2900003700fd0c200441236a28000021012004411f6a28000021052004411b6a2800002110200441176a280000211102400240024020152027460d00201521030c010b202741016a22032027490d17202741017422122003201220034b1b2212ad42307e220f422088a70d17200fa722034100480d170240024020270d002003102821190c010b2019202741306c2003102c21190b2019450d0120272103201221270b20022d00a20d211220022f01a00d21072019200341306c6a2203200136000f2003200536000b2003201036000720032011360003200320073b0100200341026a20123a00002003200c370320200341286a2008370300200320022903f80c370013200341186a20022900fd0c370000201541016a21150c010b200341081037000b200441386a22042032470d000b024020150d002027450d012019102a0c010b02400240201541306c22040d00420021084200210c0c010b201941206a2103420021084200210c0340200341086a290300200c7c2003290300220c20087c2208200c54ad7c210c200341306a2103200441506a22040d000b0b200241d0026a420042808080801020087d220f200f428080808010564200200c200842808080801056ad7c7d22084200522008501b22031b221c4200200820031b22082015ad2218420010a00520022903d002210f0240201c20185441002008501b0d00200241d0026a41086a290300211b2015417f6a2110201941206a21034100210403402003427f20032903002208200f7c220c200c2008542201200341086a22052903002208201b7c2001ad7c220c200854200c2008511b22011b3703002005427f200c20011b37030020102004460d01200341306a21032015200441016a22044b0d000b41ccc0c200200420151034000b200241c0026a200f200820182008109f050240201c20022903c0027da72205450d004100210303402019200320157041306c6a2204427f2004290320220842017c220c200c2008542201200441286a2204290300220f2001ad7c221b200f54200c20085a1b22011b3703202004427f201b20011b370300200341016a22032005490d000b0b200241f0116a41186a2204203c290300370300200241f0116a41106a2201203d290300370300200241f0116a41086a2205203a290300370300200220022903900e3703f011024020362034470d00203441016a22032034490d14203441017422102003201020034b1b2210ad422c7e2208422088a70d142008a722034100480d140240024020340d0020031028213f0c010b203f2034412c6c2003102c213f0b203f450d0320342136201021340b203f2036412c6c6a220320022903f011370200200529030021082001290300210c2004290300210f200320153602282003202736022420032019360220200341186a200f370200200341106a200c370200200341086a2008370200203641016a21360b203541d0006a22352040470d000c020b0b200341041037000b02402037450d002038102a0b024020022802c80e2203450d00200341d0006c210420022802c00e41206a210303400240200341046a280200450d002003280200102a0b200341d0006a2103200441b07f6a22040d000b0b024020022802c40e450d0020022802c00e102a0b20022802e80c20022802ec0c20022802f00c10bc022006450d08203941306c220341306e21040240024020030d0041012142420021300c010b200441057422014100480d10200110282242450d072004ad21300b024002402006200620036a470d00410021190c010b203941306c2101410021192042210320062104034020032004290000370000200341186a200441186a290000370000200341106a200441106a290000370000200341086a200441086a290000370000201941016a2119200341206a2103200441306a2104200141506a22010d000b0b200242003702ec0c200241f8b9c0003602e80c024020194105742203450d00204220036a213b200241f0116a4102722143200241900c6a41136a213c200241b00c6a41136a2144204221070340200241b0026a200710b004200241b0026a41086a290300210c20022903b002210f200241a0026a10a10220024190026a20022903a002200241a0026a41086a290300427f420010a00520024180026a200f200c20022903900222084201200842015620024190026a41086a29030022084200522008501b22031b2008420020031b10a005200741086a2900002108200741106a290000210c2007290000210f200241e00e6a41186a220e200741186a290000370300200241e00e6a41106a2224200c370300200241e00e6a41086a221520083703002002200f3703e00e20022903800221080240024002400240024002400240024020022802e80c221041f8b9c000460d0020022802ec0c21110c010b200241900f6a410041e0021099051a200241f0116a41004190041099051a41f80610282210450d0141002111201041003b010620104100360200201041086a200241900f6a41e002109a051a201041e8026a200241f0116a419004109a051a200241003602ec0c200220103602e80c0b200741206a210702400340201041086a2104201041066a210d20102f01062212410574210341002101024003402003450d01200241e00e6a20044120109c052205450d03200341606a2103200141016a2101200441206a21042005417f4a0d000b2001417f6a21120b02402011450d002011417f6a2111201020124102746a41f8066a28020021100c010b0b200241c00d6a41186a2203200e290300370300200241c00d6a41106a2024290300220c370300200241c00d6a41086a2015290300220f370300200220022903e00e221b3703c00d200220022802f00c41016a3602f00c200241900e6a41106a2239200c370300200241900e6a41086a2240200f370300200241900e6a41186a223e20032903003703002002201b3703900e200d2f01002204410b490d04200241900f6a410041e0021099051a200241f0116a41004190041099051a41f80610282203450d02200341003b010620034100360200200341086a200241900f6a41e002109a052101200341e8026a200241f0116a419004109a052105200241b00c6a41086a2245201041d0016a290000370300200241b00c6a41106a2246201041d8016a290000370300200241b00c6a41186a2247201041e0016a290000370300200241f0116a41086a222720104190056a290300370300200241f0116a41106a221620104198056a290300370300200241f0116a41186a2232201041a0056a290300370300200241f0116a41206a2233201041a8056a290300370300200241f0116a41286a2235201041b0056a290300370300200220102900c8013703b00c20022010290388053703f0112001201041e8016a20102f010641796a2204410574109a0521012005201041b8056a200441306c109a052105201041063b0106200320043b0106200220022f01b00c3b01e00c200220022d00b20c3a00e20c200220442900003703d00c2002204441056a22482900003700d50c20022800b30c214920022800b70c214a20022800bb0c214b20022800bf0c214c200241900f6a41286a224d2035290300370300200241900f6a41206a224e2033290300370300200241900f6a41186a224f2032290300370300200241900f6a41106a22502016290300370300200241900f6a41086a22512027290300370300200220022903f0113703900f0240024020124107490d00201241057420016a41c07e6a2001201241796a22114105746a2201200441ffff037120116b410574109b051a200141186a203e290300370000200141106a2039290300370000200141086a2040290300370000200120022903900e370000201241306c20056a220441e07d6a200441b07d6a2204200341066a220d2f010020116b41306c109b051a200441186a4200370300200420083703102004420037030820042008370300200441286a4100360200200442083703200c010b201041086a20124105746a220441206a2004200d2f010020126b410574109b051a200441186a203e290300370000200441106a2039290300370000200441086a2040290300370000200420022903900e370000201041e8026a201241306c6a220441306a2004200d2f010020126b41306c109b051a200441186a4200370300200420083703102004420037030820042008370300200441286a4100360200200442083703200b200d200d2f010041016a3b0100200241d00e6a41026a220420022d00e20c3a00002015205129030037030020242050290300370300200e204f290300370300200241e00e6a41206a2238204e290300370300200241e00e6a41286a2237204d290300370300200220022f01e00c3b01d00e200220022903d00c3703900c200220022900d50c3700950c200220022903900f3703e00e200241e00d6a41286a22522037290300370300200241e00d6a41206a22532038290300370300200241e00d6a41186a2254200e290300370300200241e00d6a41106a22552024290300370300200241e00d6a41086a22562015290300370300200220022903e00e3703e00d200220022f01d00e3b01a00d200220042d00003a00a20d200220022903900c3703f80c200220022900950c3700fd0c0240201028020022110d00200241e80c6a2104200321010c060b20102f0104213d41002157200321580340200241b80d6a41026a225920022d00a20d3a0000200220022f01a00d3b01b80d200220022903f80c3703d00e200220022900fd0c3700d50e2037205229030037030020382053290300370300200e20542903003703002024205529030037030020152056290300370300200220022903e00d3703e00e203d41ffff0371211202400240024020112f01062203410b490d002043410041a2071099051a41a80710282205450d0720054100360200200541046a200241f0116a41a407109a051a2047201141e0016a2900003703002046201141d8016a2900003703002045201141d0016a290000370300200220112900c8013703b00c2035201141b0056a2903003703002033201141a8056a2903003703002032201141a0056a290300370300201620114198056a290300370300202720114190056a29030037030020022011290388053703f011200541086a201141e8016a20112f0106220441796a2203410574109a05215a200541e8026a201141b8056a200341306c109a05215b200541f8066a20114194076a2004417a6a220d410274109a05213a201141063b0106200520033b01060240200d450d0041002103203a210403402004280200220120033b010420012005360200200441046a2104200d200341016a2203470d000b0b204d2035290300370300204e2033290300370300204f20322903003703002050201629030037030020512027290300370300200220022903f0113703900f200220022f01b00c3b01e00c200220022d00b20c3a00e20c20022900b30c210820022900bb0c210c200220482900003700d50c200220442900003703d00c203c20022903d00c370000203c41056a220d20022900d50c370000200220022d00e20c3a00920c200220022f01e00c3b01900c2002200c37009b0c200220083700930c2035204d2903003703002033204e2903003703002032204f2903003703002016205029030037030020272051290300370300200220022903900f3703f011203d41ffff037122044107490d01205a2012417a6a22014105746a205a201241796a22034105746a220420052f010620036b410574109b051a200441186a20022900d50e3700002004204c36000f2004204b36000b2004204a36000720042049360003200441026a20592d00003a0000200420022f01b80d3b0000200420022903d00e370013201241306c205b6a220441e07d6a200441b07d6a220420052f0106223d20036b41306c109b051a200441286a2037290300370300200441206a2038290300370300200441186a200e290300370300200441106a2024290300370300200441086a2015290300370300200420022903e00e3703002005203d41016a22043b01062012410274223d203a6a416c6a203a20014102746a2212200441ffff037120016b410274109b051a20122058360200200120052f010622124b0d022005203d6a41e0066a2104034020042802002201200341016a22033b010420012005360200200441046a210420032012490d000c030b0b201141086a2204201241016a22014105746a200420124105746a2204200320126b2205410574109b051a2004204c36000f2004204b36000b2004204a36000720042049360003200441026a20592d00003a0000200420022f01b80d3b0000200420022903d00e370013200441186a20022900d50e3700002011201241306c6a22044198036a200441e8026a220d200541306c109b051a20044190036a203729030037030020044188036a203829030037030020044180036a200e290300370300200441f8026a2024290300370300200441f0026a2015290300370300200d20022903e00e3703002011200341016a22033b01062012410274201141f8066a22046a41086a200420014102746a2204200341ffff037120016b410274109b051a200420583602000240201220112f010622034f0d00205820013b010420582011360200200120034f0d002003417f6a210520112001417f6a22034102746a4180076a2104034020042802002201200341026a3b010420012011360200200441046a21042005200341016a2203470d000b0b41001a200241e80c6a1a20101a0c090b201141086a2203201241016a22014105746a200320124105746a220320112f0106223d20126b223a410574109b051a2003204c36000f2003204b36000b2003204a36000720032049360003200341026a20592d00003a0000200320022f01b80d3b0000200320022903d00e370013200341186a20022900d50e370000201141e8026a201241306c6a220341306a2003203a41306c109b051a200341286a2037290300370300200341206a2038290300370300200341186a200e290300370300200341106a2024290300370300200341086a2015290300370300200320022903e00e3703002011203d41016a22033b01062012410274223a201141f8066a223d6a41086a203d20014102746a223d200341ffff037120016b410274109b051a203d2058360200200420112f010622014f0d002011203a6a41fc066a2103034020032802002204201241016a22123b010420042011360200200341046a210320012012470d000b0b205741016a2112200241b00d6a41026a220320022d00920c3a00002040202729030037030020392016290300370300203e2032290300370300200241900e6a41206a22042033290300370300200241900e6a41286a22012035290300370300200220022f01900c3b01b00d200220022903f0113703900e2002203c2900003703c00e2002200d2900003700c50e20022800930c214920022800970c214a200228009b0c214b200228009f0c214c20522001290300370300205320042903003703002054203e2903003703002055203929030037030020562040290300370300200220022903900e3703e00d200220022f01b00d3b01a00d200220032d00003a00a20d200220022903c00e3703f80c200220022900c50e3700fd0c0240201128020022030d0020111a200241e80c6a22041a200521010c070b20112f0104213d200241e80c6a1a20111a2003211120052158201221570c000b0b2010200141306c6a22034180036a4200370300200341f8026a2008370300200341f0026a4200370300200341e8026a200837030020034190036a410036020020034188036a220128020021042003418c036a2802002103200142083703002004450d052003450d052004102a0c050b41f80641081037000b41f80641081037000b41a80741081037000b201020124105746a220341286a200341086a2201200420126b410574109b051a200341206a203e290300370000200341186a2039290300370000200341106a2040290300370000200120022903900e3700002010201241306c6a22034198036a200341e8026a220420102f010620126b41306c109b051a20034190036a410036020020034188036a420837030020034180036a4200370300200341f8026a2008370300200341f0026a420037030020042008370300201020102f010641016a3b01060c010b2043410041a2071099051a41a80710282203450d0820034100360200200341046a200241f0116a41a407109a051a2003200428020022053602f806200420033602002004200428020441016a360204200541003b010420052003360200200320032f010622054105746a220441086a20022f01a00d3b00002004410a6a20022d00a20d3a0000200441176a204c360000200441136a204b3600002004410f6a204a3600002004410b6a20493600002004411b6a20022903f80c370000200441206a20022900fd0c3700002003200541306c6a220441e8026a20022903e00d370300200441f0026a2056290300370300200441f8026a205529030037030020044180036a205429030037030020044188036a205329030037030020044190036a2052290300370300200341f8066a200541016a22044102746a2001360200200320043b0106200120043b01042001200336020020101a0b2007203b470d000b0b02402036412c6c2203450d00203f20036a2132203f210d03400240200d28022841306c2203450d00200d280220220e20036a21150340200241f0016a200d10b004200e221041286a2224290300210f20102903202108200241f0016a41086a290300211b20022903f001211c200241e0016a10a102200241d0016a20022903e001200241e0016a41086a290300427f420010a005200241c0016a201c201b20022903d001220c4201200c420156200241d0016a41086a290300220c420052200c501b22031b200c420020031b10a005200241a0016a200f420020022903c001220c4200109f05200241b0016a20084200200c4200109f0520024190016a4200420020084200109f0542ffffffff0f200241b0016a41086a290300220820022903a0012002290390017c7c220c42208820022903a80120022903980184420052200c2008547222031b2108427f20023502b401200c4220868420031b210c201041306a210e200241e80c6a210320022802ec0c21120240024003402003280200221141086a210420112f010622074105742103410021010240024003402003450d01201020044120109c052205450d02200341606a2103200141016a2101200441206a21042005417f4a0d000b2001417f6a21070b2012450d022012417f6a2112201120074102746a41f8066a21030c010b0b2011200141306c6a220341f8026a2204427f2004290300220f200c7c221b201b200f54220420034180036a2201290300220f20087c2004ad7c221b200f54201b200f511b22041b3703002001427f201b20041b370300200241f0116a41186a2211200d41186a290000370300200241f0116a41106a2212200d41106a290000370300200241f0116a41086a2207200d41086a2900003703002002200d2900003703f01120034188036a2105024020034190036a220128020022042003418c036a280200470d00200441016a22032004490d16200441017422272003202720034b1b2227ad42307e220f422088a70d16200fa722164100480d160240024020040d002016102821030c010b2005280200200441306c2016102c21030b2003450d0220052003360200200541046a2027360200200128020021040b2005280200200441306c6a220320022903f0113703002003200c370320200341186a2011290300370300200341106a2012290300370300200341086a2007290300370300200341286a20083703002001200128020041016a3602000b2010200c37032020242008370300200e2015460d020c010b0b201641081037000b200d412c6a220d2032470d000b0b200241e00e6a41086a22034200370300200242003703e00e41a5afc4004116200241e00e6a1008200241900f6a41086a2003290300370300200220022903e00e3703900f200241003602f011200241900f6a4110200241f0116a100621030240024020022802f0112204417f460d002003450d00200220043602e40e200220033602e00e200241f0116a200241e00e6a106d20022802f0112207450d0320022902f41121082004450d012003102a0c010b42002108410121070b02402007450d002008422088a72203450d0020034105742101200721040340410f10282203450d04200341002900edae44370000200341076a41002900f4ae443700002002428f808080f0013702f411200220033602f0112004200241f0116a108f0120022802f811210320022802f0112105200241900c6a41186a22104200370300200241900c6a41106a22114200370300200241900c6a41086a22124200370300200242003703900c20052003200241900c6a1000200241c00d6a41186a2010290300370300200241c00d6a41106a2011290300370300200241c00d6a41086a2012290300370300200220022903900c3703c00d024020022802f411450d0020022802f011102a0b200441206a2104200241c00d6a41201009200141606a22010d000b0b02402008a7450d002007102a0b20022802f00c211020022802e80c21030240024020022802ec0c22010d00200321040c010b2001210520032104034020042802f80621042005417f6a22050d000b0340200320032f01064102746a41f8066a28020021032001417f6a22010d000b0b200241ac0f6a20032f0106360200200241900f6a41186a4100360200200241a40f6a2003360200200220103602b00f200241003602a00f200242003703980f200220043602940f200241003602900f200241f0116a200241900f6a10b1020240200241b0126a223b280200220d0d00427f2120427f211c0c080b200241f0116a41106a2101200241a8126a2133200241f0116a41286a2135427f2120427f211c0340200241e00d6a41086a200241f0116a41086a22112903002208370300200241e00d6a41106a2001290300220c370300200241e00d6a41186a200241f0116a41186a2205290300220f370300200220022903f011221b3703e00d203329030021182035290300211f20022802b412212420022802b812210320022903a0122121200229039012212f200241900e6a41186a2215200f370300200241900e6a41106a2227200c370300200241900e6a41086a221620083703002002201b3703900e20024180016a10a102200241e0006a20022903800120024180016a41086a290300427f420010a005200241f0006a10a102200241c0006a2002290370200241f0006a41086a290300427f420010a005200241d0006a2002290360220842012008420156200241e0006a41086a29030022084200522008501b22041b2008420020041b202f201f109f05200241306a2002290340220842012008420156200241c0006a41086a29030022084200522008501b22041b2008420020041b20212018109f05200241d0006a41086a290300211f200241306a41086a290300211b4100211220022903502121200229033021184100210e410821070240200341306c2210450d00201041306d220ead42307e2208422088a70d112008a722044100480d11200410282207450d050b02402003450d00200341047441706a213220072103200d21040340200441286a290300210c200441206a290300210f2005200441186a2903003703002001200441106a2903003703002011200441086a290300370300200220042903003703f011200241206a10a102200241106a2002290320200241206a41086a290300427f420010a00520022002290310220842012008420156200241106a41086a29030022084200522008501b22121b2008420020121b200f200c109f052003200241086a29030037030820032002290300370300200341106a20022903f011370300200341186a2011290300370300200341206a2001290300370300200341286a2005290300370300200341306a2103200441306a2104201041506a22100d000b203241047641016a21120b02402024450d00200d102a0b2012ad42307e2208422088a70d012008a72203417f4c0d010240024020030d004108210d0c010b20031028220d450d060b0240024020120d00410021100c010b2007201241306c6a211141002110200d2103200721040340200320042903003703002003200441086a290300370308200341106a200441106a290300370300200341186a200441186a290300370300200341206a200441206a290300370300200341286a200441286a290300370300200341306a2103201041016a2110200441306a22042011470d000b0b2005201f3703002002202137038012200220183703f011200220103602981220022012360294122002200d360290122002201b3703f811200241e00e6a41186a2015290300370300200241e00e6a41106a2027290300370300200241e00e6a41086a2016290300370300200220022903900e3703e00e0240410f10282203450d00200341002900edae44370000200341076a41002900f4ae443700002002428f808080f0013702b40c200220033602b00c200241e00e6a200241b00c6a108f0120022802b80c210320022802b00c2104200241900c6a41186a22054200370300200241900c6a41106a22104200370300200241900c6a41086a22114200370300200242003703900c20042003200241900c6a1000200241c00d6a41186a2005290300370300200241c00d6a41106a2010290300370300200241c00d6a41086a2011290300370300200220022903900c3703c00d024020022802b40c450d0020022802b00c102a0b200241003602e80e200242013703e00e2002200241f0116a3602b00c200241b00c6a200241e00e6a10a301200220013602b00c200241b00c6a200241e00e6a10a30120022802901221032002280298122204200241e00e6a10b40102402004450d00200441306c21040340200341106a200241e00e6a108f01200220033602b00c200341306a2103200241b00c6a200241e00e6a10a301200441506a22040d000b0b20022802e40e2103200241c00d6a412020022802e00e220420022802e80e100702402003450d002004102a0b20182020542103201b201c512104201b201c5421050240200228029412450d00200228029012102a0b2003200520041b21030240200e450d002007102a0b201b201c20031b211c2018202020031b2120200241f0116a200241900f6a10b10220022802b012220d450d090c010b0b410f41011037000b1036000b41c4d1c300413320024198196a419cd9c3001038000b410f41011037000b200441081037000b200341081037000b41a80741081037000b200141011037000b200241f0116a200241900f6a10b1020240203b2802002203450d000340024020022802b412450d002003102a0b200241f0116a200241900f6a10b10220022802b01222030d000b0b024020022802940f220341f8b9c000460d00200328020021012003102a2001450d00200128020021042001102a2004450d00024020042802002203450d0003402004102a2003210420032802002201210320010d000b0b2004102a0b200241e00e6a41086a22034200370300200242003703e00e4199fec4004111200241e00e6a1008200241900f6a41086a22042003290300370300200220022903e00e3703900f2002201c3703f811200220203703f011200241900f6a4110200241f0116a4110100720034200370300200242003703e00e41a5afc4004116200241e00e6a100820042003290300370300200220022903e00e3703900f200241003602f811200242013703f0112019200241f0116a10b40102402019450d00201941057421042042210303402003200241f0116a108f01200341206a2103200441606a22040d000b0b20022802f4112103200241900f6a411020022802f011220420022802f811100702402003450d002004102a0b2019ad210802402036450d002036412c6c2104203f41206a210303400240200341046a280200450d002003280200102a0b2003412c6a2103200441546a22040d000b0b2008422086210802402034450d00203f102a0b203020088421082041450d012006102a0c010b200241e00e6a41086a22034200370300200242003703e00e4199fec4004111200241e00e6a1008200241900f6a41086a2003290300370300200220022903e00e3703900f200241003602f011200241900f6a4110200241f0116a10062103024020022802f0112204417f460d002004410f4d0d052003102a0b410021420b024020172014a745720d002013102a0b20420d0102402009450d00200941d0006c2104200a41c0006a210303400240200341046a280200450d002003280200102a0b200341d0006a2103200441b07f6a22040d000b0b200b450d00200a102a0b200041003602000c010b200020083702042000204236020002402009450d00200941d0006c2104200a41c0006a210303400240200341046a280200450d002003280200102a0b200341d0006a2103200441b07f6a22040d000b0b200b450d00200a102a0b200241a0196a24000f0b41c4d1c300413320024198196a419cd9c3001038000b41c4d1c300413320024198196a419cd9c3001038000b1031000baa0b02067f017e230041206b22042400200441106a41086a220542003703002004420037031041f9b5c200411d200441106a1008200441086a2005290300370300200420042903103703000240024002400240024002400240024002400240200441104101410041001003417f470d001098012106024002400240024020024101470d00200441106a41086a220542003703002004420037031041b8bfc200411a200441106a1008200441086a2005290300370300200420042903103703002004410036021020044110200441106a10062105024020042802102207417f460d002005450d0020074104490d06200528000021072005102a200720064b0d020b200441106a41086a220542003703002004420037031041b8bfc200411a200441106a1008200441086a2005290300370300200420042903103703002004200620014101746a36021020044110200441106a410410070b200028020821052000280204210820002802002109200441106a41086a220042003703002004420037031041f9b5c200411d200441106a1008200441086a2000290300370300200420042903103703002004410036021820044201370310410410282200450d052004410436021420042004280218220741046a36021820042000360210200020076a200636000020042802142206200428021822006b4104490d01200428021021060c020b200041046a280200450d0b2000280200102a0c0b0b200041046a22072000490d09200641017422002007200020074b1b22004100480d090240024020060d002000102821060c010b200428021020062000102c21060b2006450d042004200036021420042006360210200428021821000b2004200041046a360218200620006a20013600002005200441106a10b40102402005450d002009200541286c6a21072009210503402005200441106a108f01200541206a290300210a0240024020042802142201200428021822006b4108490d00200428021021010c010b200041086a22062000490d0b200141017422002006200020064b1b22004100480d0b0240024020010d002000102821010c010b200428021020012000102c21010b2001450d072004200036021420042001360210200428021821000b2004200041086a360218200120006a200a3700002007200541286a2205470d000b0b20042802142105200428021821000240024020024101460d000240024020052000460d00200428021021050c010b200041016a22052000490d0b200041017422012005200120054b1b22014100480d0b0240024020000d002001102821050c010b200428021020002001102c21050b2005450d082004200136021420042005360210200428021821000b2004200041016a360218200520006a41003a00000c010b0240024020052000460d00200428021021050c010b200041016a22052000490d0a200041017422012005200120054b1b22014100480d0a0240024020000d002001102821050c010b200428021020002001102c21050b2005450d082004200136021420042005360210200428021821000b2004200041016a360218200520006a41013a00000240024020042802142205200428021822006b4104490d00200428021021050c010b200041046a22012000490d0a200541017422002001200020014b1b22004100480d0a0240024020050d002000102821050c010b200428021020052000102c21050b2005450d092004200036021420042005360210200428021821000b2004200041046a360218200520006a20033600000b2004280214210020044110200428021022052004280218100702402000450d002005102a0b2008450d092009102a0c090b200041046a280200450d082000280200102a0c080b41c4d1c3004133200441106a419cd9c3001038000b410441011037000b200041011037000b200041011037000b200141011037000b200141011037000b200041011037000b1031000b200441206a24000bcb0201057f230041d0006b220224002002410036022820014110200241286a1006210302400240024020022802282204417f460d0020030d010b200041003a00000c010b41002101200241003a00480340024020042001470d000240200141ff0171450d00200241003a00480b41c4d1c3004133200241286a419cd9c3001038000b200241286a20016a200320016a2d00003a00002002200141016a22053a00482005210120054120470d000b200241086a41186a2201200241286a41186a290300370300200241086a41106a2205200241286a41106a290300370300200241086a41086a2206200241286a41086a2903003703002002200229032837030802402004450d002003102a0b20002002290308370001200041013a0000200041196a2001290300370000200041116a2005290300370000200041096a20062903003700000b200241d0006a24000bdf0301017f024002400240024002400240410110282202450d00200220002d00003a0000200241014102102c2202450d01200220002d00013a0001200241024104102c2202450d02200220002d00023a0002200220002d00033a0003200241044108102c2202450d03200220002d00043a0004200220002d00053a0005200220002d00063a0006200220002d00073a0007200241084110102c2202450d04200220002d00083a0008200220002d00093a0009200220002d000a3a000a200220002d000b3a000b200220002d000c3a000c200220002d000d3a000d200220002d000e3a000e200220002d000f3a000f200241104120102c2202450d05200220002d00103a0010200220002d00113a0011200220002d00123a0012200220002d00133a0013200220002d00143a0014200220002d00153a0015200220002d00163a0016200220002d00173a0017200220002d00183a0018200220002d00193a0019200220002d001a3a001a200220002d001b3a001b200220002d001c3a001c200220002d001d3a001d200220002d001e3a001e200220002d001f3a001f200128020020012802042002412010072002102a0f0b410141011037000b410241011037000b410441011037000b410841011037000b411041011037000b412041011037000b952801057f02400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240200141046a2202280200200141086a22032802002204460d00200128020021050c010b200441016a22052004490d21200441017422062005200620054b1b22064100480d210240024020040d002006102821050c010b200128020020042006102c21050b2005450d0120012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d00003a000002400240200228020020032802002204460d00200128020021050c010b200441016a22052004490d21200441017422062005200620054b1b22064100480d210240024020040d002006102821050c010b200128020020042006102c21050b2005450d0220012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d00013a000002400240200228020020032802002204460d00200128020021050c010b200441016a22052004490d21200441017422062005200620054b1b22064100480d210240024020040d002006102821050c010b200128020020042006102c21050b2005450d0320012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d00023a000002400240200228020020032802002204460d00200128020021050c010b200441016a22052004490d21200441017422062005200620054b1b22064100480d210240024020040d002006102821050c010b200128020020042006102c21050b2005450d0420012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d00033a000002400240200228020020032802002204460d00200128020021050c010b200441016a22052004490d21200441017422062005200620054b1b22064100480d210240024020040d002006102821050c010b200128020020042006102c21050b2005450d0520012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d00043a000002400240200228020020032802002204460d00200128020021050c010b200441016a22052004490d21200441017422062005200620054b1b22064100480d210240024020040d002006102821050c010b200128020020042006102c21050b2005450d0620012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d00053a000002400240200228020020032802002204460d00200128020021050c010b200441016a22052004490d21200441017422062005200620054b1b22064100480d210240024020040d002006102821050c010b200128020020042006102c21050b2005450d0720012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d00063a000002400240200228020020032802002204460d00200128020021050c010b200441016a22052004490d21200441017422062005200620054b1b22064100480d210240024020040d002006102821050c010b200128020020042006102c21050b2005450d0820012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d00073a000002400240200228020020032802002204460d00200128020021050c010b200441016a22052004490d21200441017422062005200620054b1b22064100480d210240024020040d002006102821050c010b200128020020042006102c21050b2005450d0920012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d00083a000002400240200228020020032802002204460d00200128020021050c010b200441016a22052004490d21200441017422062005200620054b1b22064100480d210240024020040d002006102821050c010b200128020020042006102c21050b2005450d0a20012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d00093a000002400240200228020020032802002204460d00200128020021050c010b200441016a22052004490d21200441017422062005200620054b1b22064100480d210240024020040d002006102821050c010b200128020020042006102c21050b2005450d0b20012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d000a3a000002400240200228020020032802002204460d00200128020021050c010b200441016a22052004490d21200441017422062005200620054b1b22064100480d210240024020040d002006102821050c010b200128020020042006102c21050b2005450d0c20012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d000b3a000002400240200228020020032802002204460d00200128020021050c010b200441016a22052004490d21200441017422062005200620054b1b22064100480d210240024020040d002006102821050c010b200128020020042006102c21050b2005450d0d20012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d000c3a000002400240200228020020032802002204460d00200128020021050c010b200441016a22052004490d21200441017422062005200620054b1b22064100480d210240024020040d002006102821050c010b200128020020042006102c21050b2005450d0e20012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d000d3a000002400240200228020020032802002204460d00200128020021050c010b200441016a22052004490d21200441017422062005200620054b1b22064100480d210240024020040d002006102821050c010b200128020020042006102c21050b2005450d0f20012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d000e3a000002400240200228020020032802002204460d00200128020021050c010b200441016a22052004490d21200441017422062005200620054b1b22064100480d210240024020040d002006102821050c010b200128020020042006102c21050b2005450d1020012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d000f3a000002400240200228020020032802002204460d00200128020021050c010b200441016a22052004490d21200441017422062005200620054b1b22064100480d210240024020040d002006102821050c010b200128020020042006102c21050b2005450d1120012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d00103a000002400240200228020020032802002204460d00200128020021050c010b200441016a22052004490d21200441017422062005200620054b1b22064100480d210240024020040d002006102821050c010b200128020020042006102c21050b2005450d1220012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d00113a000002400240200228020020032802002204460d00200128020021050c010b200441016a22052004490d21200441017422062005200620054b1b22064100480d210240024020040d002006102821050c010b200128020020042006102c21050b2005450d1320012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d00123a000002400240200228020020032802002204460d00200128020021050c010b200441016a22052004490d21200441017422062005200620054b1b22064100480d210240024020040d002006102821050c010b200128020020042006102c21050b2005450d1420012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d00133a000002400240200228020020032802002204460d00200128020021050c010b200441016a22052004490d21200441017422062005200620054b1b22064100480d210240024020040d002006102821050c010b200128020020042006102c21050b2005450d1520012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d00143a000002400240200228020020032802002204460d00200128020021050c010b200441016a22052004490d21200441017422062005200620054b1b22064100480d210240024020040d002006102821050c010b200128020020042006102c21050b2005450d1620012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d00153a000002400240200228020020032802002204460d00200128020021050c010b200441016a22052004490d21200441017422062005200620054b1b22064100480d210240024020040d002006102821050c010b200128020020042006102c21050b2005450d1720012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d00163a000002400240200228020020032802002204460d00200128020021050c010b200441016a22052004490d21200441017422062005200620054b1b22064100480d210240024020040d002006102821050c010b200128020020042006102c21050b2005450d1820012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d00173a000002400240200228020020032802002204460d00200128020021050c010b200441016a22052004490d21200441017422062005200620054b1b22064100480d210240024020040d002006102821050c010b200128020020042006102c21050b2005450d1920012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d00183a000002400240200228020020032802002204460d00200128020021050c010b200441016a22052004490d21200441017422062005200620054b1b22064100480d210240024020040d002006102821050c010b200128020020042006102c21050b2005450d1a20012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d00193a000002400240200228020020032802002204460d00200128020021050c010b200441016a22052004490d21200441017422062005200620054b1b22064100480d210240024020040d002006102821050c010b200128020020042006102c21050b2005450d1b20012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d001a3a000002400240200228020020032802002204460d00200128020021050c010b200441016a22052004490d21200441017422062005200620054b1b22064100480d210240024020040d002006102821050c010b200128020020042006102c21050b2005450d1c20012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d001b3a000002400240200228020020032802002204460d00200128020021050c010b200441016a22052004490d21200441017422062005200620054b1b22064100480d210240024020040d002006102821050c010b200128020020042006102c21050b2005450d1d20012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d001c3a000002400240200228020020032802002204460d00200128020021050c010b200441016a22052004490d21200441017422062005200620054b1b22064100480d210240024020040d002006102821050c010b200128020020042006102c21050b2005450d1e20012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d001d3a000002400240200228020020032802002204460d00200128020021050c010b200441016a22052004490d21200441017422062005200620054b1b22064100480d210240024020040d002006102821050c010b200128020020042006102c21050b2005450d1f20012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d001e3a000002400240200228020020032802002202460d00200128020021040c010b200241016a22042002490d21200241017422052004200520044b1b22054100480d210240024020020d002005102821040c010b200128020020022005102c21040b2004450d2020012004360200200141046a2005360200200141086a28020021020b2003200241016a360200200420026a20002d001f3a00000f0b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200541011037000b1031000b02000ba50201057f230041d0006b21020240200128020022032001280204470d00200041003602000f0b200120034180016a3602002002200329006237012a2002200329006a370132200241086a41086a220120022903303703002002200329007237013a200241086a41106a220420022903383703002002200328007a360142200220032f007e3b0146200241086a41186a22052002290340370300200220032f00603b012820022002290328370308200241286a41186a22062005290300370300200241286a41106a22052004290300370300200241286a41086a220420012903003703002002200229030837032820002003360200200020022903283702042000410c6a2004290300370200200041146a20052903003702002000411c6a20062903003702000b280020004101360204200041086a200128020420012802006b4107762201360200200020013602000bb905020b7f047e23004190016b22032400024002402001280200220420012802042205460d00200120044180016a22063602002003200441e2006a29000037016a2003200441ea006a290000370172200341c8006a41086a220720032903703703002003200441f2006a29000037017a200341c8006a41106a220820032903783703002003200441fa006a280000360182012003200441fe006a2f00003b018601200341c8006a41186a22092003290380013703002003200441e0006a2f00003b016820032003290368370348200341286a41186a220a2009290300370300200341286a41106a220b2008290300370300200341286a41086a220c200729030037030020032003290348370328200541807f6a210d02400340200341086a41186a200a290300220e370300200341086a41106a200b290300220f370300200341086a41086a200c2903002210370300200320032903282211370308200341e8006a41186a200e370300200341e8006a41106a200f370300200341e8006a41086a2010370300200320113703682002450d01200d2004460d02200120064180016a22053602002003200641e2006a29000037016a2003200641ea006a290000370172200720032903703703002003200641f2006a29000037017a200820032903783703002003200641fa006a280000360182012003200641fe006a2f00003b01860120092003290380013703002003200641e0006a2f00003b016820032003290368370348200a2009290300370300200b2008290300370300200c20072903003703002003200329034837032820044180016a21042002417f6a2102200521060c000b0b20002004360200200020032903683702042000410c6a200341f0006a290300370200200041146a200341f8006a2903003702002000411c6a20034180016a2903003702000c010b200041003602000b20034190016a24000ba50201057f230041d0006b21020240200128020022032001280204470d00200041003602000f0b200120034180016a3602002002200329004237012a2002200329004a370132200241086a41086a220120022903303703002002200329005237013a200241086a41106a220420022903383703002002200328005a360142200220032f005e3b0146200241086a41186a22052002290340370300200220032f00403b012820022002290328370308200241286a41186a22062005290300370300200241286a41106a22052004290300370300200241286a41086a220420012903003703002002200229030837032820002003360200200020022903283702042000410c6a2004290300370200200041146a20052903003702002000411c6a20062903003702000bb905020b7f047e23004190016b22032400024002402001280200220420012802042205460d00200120044180016a22063602002003200441c2006a29000037016a2003200441ca006a290000370172200341c8006a41086a220720032903703703002003200441d2006a29000037017a200341c8006a41106a220820032903783703002003200441da006a280000360182012003200441de006a2f00003b018601200341c8006a41186a22092003290380013703002003200441c0006a2f00003b016820032003290368370348200341286a41186a220a2009290300370300200341286a41106a220b2008290300370300200341286a41086a220c200729030037030020032003290348370328200541807f6a210d02400340200341086a41186a200a290300220e370300200341086a41106a200b290300220f370300200341086a41086a200c2903002210370300200320032903282211370308200341e8006a41186a200e370300200341e8006a41106a200f370300200341e8006a41086a2010370300200320113703682002450d01200d2004460d02200120064180016a22053602002003200641c2006a29000037016a2003200641ca006a290000370172200720032903703703002003200641d2006a29000037017a200820032903783703002003200641da006a280000360182012003200641de006a2f00003b01860120092003290380013703002003200641c0006a2f00003b016820032003290368370348200a2009290300370300200b2008290300370300200c20072903003703002003200329034837032820044180016a21042002417f6a2102200521060c000b0b20002004360200200020032903683702042000410c6a200341f0006a290300370200200041146a200341f8006a2903003702002000411c6a20034180016a2903003702000c010b200041003602000b20034190016a24000be6880106147f027e077f017e027f017e230041d0046b22042400200441c0036a20012002200310f903200441c0036a41086a280200210520042802c40321060240024020042802c0034101470d002000200636020420004101360200200041086a20053602000c010b200441d4036a280200220741306c2108200441d8036a2802002109200441d0036a280200210a200441cc036a280200210b4100210c4100210102400340024020082001470d000c020b200b20016a2102200141306a220d210120022d00004102470d000b200441d0006a200b200d6a41546a10fa032004280250210c200428025421010b4100210e20014100200c1b210f200741306c2108200c4104200c1b21104100210102400340024020082001470d000c020b200b20016a2102200141306a220d210120022d00004108470d000b200441c8006a200b200d6a41546a10fa032004280248210e200428024c21010b4100211120014100200e1b2112200741306c2108200e4104200e1b210d4100210102400340024020082001470d000c020b200b20016a2102200141306a220c210120022d00004104470d000b200441c0006a200b200c6a41546a10fa0320042802402111200428024421010b4100210e2001410020111b2113200741306c21082011410420111b21114100210102400340024020082001470d000c020b200b20016a2102200141306a220c210120022d00004103470d000b200441386a200b200c6a41546a10fa032004280238210e200428023c21010b41002102024020014100200e1b2201450d00200141286c2108200e4104200e1b41186a2101410021020340200220012d0000456a2102200141286a2101200841586a22080d000b0b0240024020120d00411e2101200041b98dc6003602040c010b200d201241146c6a211241002114410021150240024002400340200d450d0141d78dc600210841382101200d41086a280200417c6a220e41024b0d02200d280200210c024002400240200e0e03000501000b41012115200c41af8dc600460d01200c28000041e3c2b1e306460d010c040b41012114200c41b38dc600460d00200c41b38dc6004106109c050d030b0240200d410c6a280200450d0041132101200041d58ec6003602040c050b0240200d41106a280200220120026b220c20014d0d00412a2101200041e88ec6003602040c050b41af8ec6002108412621012013200c4d0d022011200c4102746a220c450d02418f8ec600210841202101200f200c280200220c4d0d022010200c4104746a220c450d0241928fc6002108411f2101200c2802080d02200c2d000d220c41077141044b0d020240200c0e050003030300000b200d41146a220d2012470d000b0b41b18fc60041b98dc600201441017122021b2108411c411e20021b21012002450d002015410171450d00200741306c2108410021010c010b200020083602040c010b0240034020082001460d01200b20016a2102200141306a220d210120022d00004106470d000b200441306a200b200d6a41546a10fa032004280234450d00200041fd8ac600360204411f21010c010b200741306c21082003280268210c410021010240034020082001460d01200b20016a2102200141306a220d210120022d00004105470d000b200441286a200b200d6a41546a220110fa030240200428022c41014d0d00411821012000419c8bc6003602040c020b200441206a200110fa032004280224450d0020042802202201450d002001280200200c4d0d0041222101200041b48bc6003602040c010b200741306c2108410021010240034020082001460d01200b20016a2102200141306a220d210120022d00004107470d000b200441186a200b200d6a41546a10fa0320042802182201200428021c4104746a2108034020012008460d012001450d012001410c6a2102200141106a210120022d0000410271450d000b41322101200041c08cc6003602040c010b200741306c2108410021010240034020082001460d01200b20016a2102200141306a220d210120022d0000410c470d000b200b200d6a2201415c6a2802002202450d00200141546a280200220d200241186c6a210c0340200d220241186a210d2002280208410374210120022802002102024003402001450d01200141786a210120022d00042108200241086a21022008410271450d000b413121012000418f8cc6003602040c030b200d200c470d000b0b200741306c2108410021010240034020082001460d01200b20016a2102200141306a220d210120022d00004102470d000b200441106a200b200d6a41546a10fa0320042802142201450d002004280210220220014104746a211103402002450d01200241106a210e200420022d000d22083a00c0032002280200220120022802086a210c410021024100200441c0036a20084104461b210d024003400240024002400240200241ff01710e03000102000b2001200c460d014100210220012108200141016a21010c020b2001200c460d034101210220012108200141016a21010c010b200d450d0241022102200d21084100210d0b20082d0000410271450d000b41392101200041d68bc6003602040c030b200e2102200e2011470d000b0b200741306c21084100210c4100210102400340024020082001470d000c020b200b20016a2102200141306a220d210120022d00004102470d000b200441086a200b200d6a41546a10fa032004280208210c200428020c21010b4100210e20014100200c1b2110200741306c2108200c4104200c1b21124100210102400340024020082001470d000c020b200b20016a2102200141306a220d210120022d00004103470d000b2004200b200d6a41546a10fa032004280200210e200428020421010b200e4104200e1b220220014100200e1b41286c6a210d41002113024002400340024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002402002200d460d00412d2101418e91c400210820022802084103470d2102402002280200220c41f8e2c500460d00200c41f8e2c5004103109c050d220b200241286a21114115210c418790c400210e4114210141fa90c400210802400240024020022d00180e0400240123000b4136210c41d18fc400210e2010200228021c22014d0d22201220014104746a220f450d222002280214210c200228020c210220092d00700d01200c410b470d014138210141c290c4002108200241ac81c600460d23200241ac81c600410b109c05450d230c210b412f210141bb91c400210820022802144106470d220240200228020c220c41cb8fc400460d00200c41cb8fc4004106109c050d230b02402013450d00411f2101200041ea91c4003602040c280b2002411c6a2113201121020c240b41262101419c90c4002108200c417d6a220c41134b0d2102400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240200c0e14003e3e3e0e043e073c0b0a120114111b103e0c19000b200241effec500460d3d200241effec5004103109c05450d3d41effec50020024103109c050d3d41011028220e450d1d200e41003a0000200f2d000c41e000460d010c3a0b200241f2fec500460d0141f2fec5002002410f109c05450d0120024181ffc500460d034181ffc5002002410f109c05450d03024020024198ffc500460d004198ffc5002002410f109c050d3d0b41071028220e450d20200e4100360003200e41013a0002200e41003b0000200f2d000c41e000460d060c380b200f2802084101470d380240200f2802002214200e460d0041002102034020024101460d01200e20026a2108201420026a210c200241016a2102200c2d000020082d0000470d3a0c000b0b200f2d000d4104470d38200e102a201121020c3d0b41041028220e450d1b200e4100360000200f2d000c41e000470d35200f2802084104470d350240200f2802002214200e460d0041002102034020024104460d01200e20026a2108201420026a210c200241016a2102200c2d000020082d0000470d370c000b0b200f2d000d4104470d35200e102a201121020c3c0b024020024190ffc500460d00200229000042e5f0d1fbb5ac98b6ec00520d3a0b41071028220e450d1c200e4100360003200e41013a0002200e41003b0000200f2d000c41e000460d010c330b41011028220e450d1a200e41003a0000200f2d000c41e000470d31200f2802084101470d31200f2802002214200e460d3041002102034020024101460d31200e20026a2108201420026a210c200241016a2102200c2d000020082d0000470d320c000b0b200f2802084107470d31200f2802002214200e460d2e41002102034020024107460d2f200e20026a2108201420026a210c200241016a2102200c2d000020082d0000470d320c000b0b200241a7ffc500460d0141a7ffc5002002410a109c05450d010240200241b1ffc500460d0041b1ffc5002002410a109c050d060b4126210c419c90c400210e200f2d000c41e000470d35200f2802080d3520112102200f2d000d4104460d380c350b200f2802084107470d31200f2802002214200e460d2b41002102034020024107460d2c200e20026a2108201420026a210c200241016a2102200c2d000020082d0000470d320c000b0b41021028220e450d19200e41003b0000200f2d000c41e000470d29200f2802084102470d290240200f2802002214200e460d0041002102034020024102460d01200e20026a2108201420026a210c200241016a2102200c2d000020082d0000470d2b0c000b0b200f2d000d4104470d29200e102a201121020c360b0240200241c6ffc500460d0041c6ffc5002002410d109c050d340b4126210c419c90c400210e200f2d000c41e000470d32200f2802080d3220112102200f2d000d4104460d350c320b0240200241d3ffc500460d0041d3ffc5002002410c109c050d330b4126210c419c90c400210e200f2d000c41e000470d31200f2802080d3120112102200f2d000d4104460d340c310b0240200241eaffc500460d0041eaffc50020024115109c050d320b4126210c419c90c400210e200f2d000c41e000470d30200f2802080d3020112102200f2d000d4104460d330c300b0240200241ffffc500460d0041ffffc5002002410a109c050d310b41021028220e450d16200e41003b0000200f2d000c41e000460d010c240b02402002418980c600460d00418980c60020024107109c050d300b4126210c419c90c400210e200f2d000c41e000470d2e200f2802080d2e20112102200f2d000d4104460d310c2e0b200f2802084102470d220240200f2802002214200e460d0041002102034020024102460d01200e20026a2108201420026a210c200241016a2102200c2d000020082d0000470d240c000b0b200f2d000d4104470d22200e102a201121020c300b02402002419080c600460d00419080c60020024113109c050d2e0b4126210c419c90c400210e200f2d000c41e000470d2c200f2802080d2c20112102200f2d000d4104460d2f0c2c0b200241a380c600460d0141a380c60020024111109c05450d01200241e280c600460d0641e280c60020024111109c05450d060240200241f380c600460d0041f380c60020024111109c050d2d0b41041028220e450d17200e4100360000200f2d000c41e000460d080c1f0b0240200241b480c600460d0041b480c6002002410e109c050d2c0b41081028220e450d13200e4200370000200f2d000c41e000460d020c1d0b41021028220e450d11200e41003b0000200f2d000c41e000470d1b200f2802084102470d1b0240200f2802002214200e460d0041002102034020024102460d01200e20026a2108201420026a210c200241016a2102200c2d000020082d0000470d1d0c000b0b200f2d000d4104470d1b200e102a201121020c2c0b200241c280c600460d0141c280c60020024110109c05450d01200241d280c600460d0241d280c60020024110109c05450d020240200241b781c600460d0041b781c60020024110109c050d2a0b4126210c419c90c400210e200f2d000c41e000470d28200f2802080d2820112102200f2d000d4104460d2b0c280b200f2802084108470d1a0240200f2802002214200e460d0041002102034020024108460d01200e20026a2108201420026a210c200241016a2102200c2d000020082d0000470d1c0c000b0b200f2d000d4104470d1a200e102a201121020c2a0b4126210c419c90c400210e200f2d000c41e000470d26200f2802080d26200f2d000d22014104460d2620112102200141fb0171450d290c260b41031028220e450d0f200e41003a0002200e41003b0000200f2d000c41e000470d16200f2802084103470d160240200f2802002214200e460d0041002102034020024103460d01200e20026a2108201420026a210c200241016a2102200c2d000020082d0000470d180c000b0b200f2d000d4104470d16200e102a201121020c280b41021028220e450d0f200e41003b0000200f2d000c41e000470d14200f2802084102470d140240200f2802002214200e460d0041002102034020024102460d01200e20026a2108201420026a210c200241016a2102200c2d000020082d0000470d160c000b0b200f2d000d4104470d14200e102a201121020c270b02402002418481c600460d00418481c60020024116109c050d250b41021028220e450d10200e41003b0000200f2d000c41e000460d020c120b200f2802084104470d160240200f2802002214200e460d0041002102034020024104460d01200e20026a2108201420026a210c200241016a2102200c2d000020082d0000470d180c000b0b200f2d000d4104470d16200e102a201121020c250b02402002419a81c600460d00419a81c60020024112109c050d230b4126210c419c90c400210e200f2d000c41e000470d21200f2802080d2120112102200f2d000d4104460d240c210b200f2802084102470d0f0240200f2802002214200e460d0041002102034020024102460d01200e20026a2108201420026a210c200241016a2102200c2d000020082d0000470d110c000b0b200f2d000d4104470d0f200e102a201121020c230b024020130d0041002116410021170c0e0b024020132802040d002000418992c400360204413221010c260b024020132802002216201341086a28020022174d0d00200041bb92c40036020441c90021010c260b201720032802644d0d0d2000418493c40036020441c10021010c250b410141011037000b410441011037000b410141011037000b410741011037000b410741011037000b410241011037000b410241011037000b410241011037000b410841011037000b410341011037000b410241011037000b410441011037000b410241011037000b20092903082118200441c0036a41086a22024200370300200441f8b9c0003602c4032009290310211920042018a7417f2018428080808010541b3602d00320042019a7417f2019428080808010541b3602c003200441c0036a4104722201410d10fb032001410c10fb032001410710fb032001410f10fb03200441d8006a41106a20042802d003360200200441d8006a41086a2002290300370300200420042903c003370358200441c0036a41106a22082007360200200441c0036a410c6a200a3602002004200b3602c803200420053602c403200420063602c003200441f0006a200441c0036a10fc03024002400240410110282201450d00200141003a0000200420042f01c003220d3b01b002200841e0083b01002002428180808010370300200420013602c403200441013602c0032004200d3b01d203200441f0006a200441c0036a10fd03210c0240410310282202450d00200241026a41002d00fae2453a0000200241002f00f8e2453b00000240410310282208450d00200841026a41002d00f1fe453a0000200841002f00effe453b0000200441b0026a41026a200441c0036a41026a220b2d000022073a0000200420042f00c003220e3b01b00220044184016a280200210d200441f0006a41106a2802002101200b20073a00002004200e3b01c00302400240024002400240024002400240200d2001470d00200141016a220d2001490d012001410174220b200d200b200d4b1b220dad42287e2218422088a70d012018a7220b4100480d010240024020010d00200b102821010c010b200428027c200141286c200b102c21010b2001450d072004200d360280012004200136027c200428028401210d0b200428027c200d41286c6a220141003a00182001200836020c200142838080803037020420012002360200200141106a428380808030370200200141196a20042f01c0033b00002001411b6a200441c2036a2d00003a00002001411c6a200c360200200420042802840141016a36028401200441c0036a200441f0006a418c01109a051a20044180026a200441c0036a10fe0320044180026a41106a280200220e41306c2101200428028802220741546a210202400340410021082001450d01200141506a21012002412c6a210d200241306a220c2102200d2d00004103470d000b200c41086a2802002201450d00200141286c2102200c28020041186a2101410021080340200820012d0000456a2108200141286a2101200241586a22020d000b0b200e41306c2101200741546a21022008417f6a210d02400340410021082001450d01200141506a21012002412c6a210c200241306a220b2102200c2d00004103470d000b200b41086a2802002201450d00200141286c2102200b28020041186a2101410021080340200820012d0000456a2108200141286a2101200241586a22020d000b0b200e41306c21012007415c6a21020240034041002111024020010d00410021010c020b200141506a2101200241246a210c200241306a220b2102200c2d00004104470d000b200b28020021010b0240024002400240200e450d00200120086a211a2007200e41306c6a2112200441d8006a410472211b4100211c4100211d0340024020072d000041786a220141044b0d00024002400240024020010e050301020400030b200728020c2201450d032007280204220c200141186c6a211e201d210103402001211d0240200c22082802144104742202450d00200828020c21010340024020012d0000410b470d00200141046a220c280200220b200d490d00200c200b41016a3602000b200141106a2101200241706a22020d000b0b200442003703d00320044280808080c0003703c803200442043703c003024002400240411010282201450d0020042802c8032102200420013602c003200441013602c403200120024104746a22014200370200200141056a4200370000200420042802c80341016a3602c80302402008280214221f450d0041002106201f210103400240024002400240024002400240024002400240024002400240200620014f0d004110210c0240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240200828020c222020064104746a2d000022140eac010001020202020202020202020202020303030404050506060707080809090a0a0b0b0c0d0d0e0e0f0f1010111213131414151516161717181819191a1a1b1b1c1c1d1d1e1e1f1f2020212122222323242425252627272828292a2a2b2b2c2d2d2e2e2f2f303031313232333434353536363737383839393a3a3b3b3c3c3d3d3e3e3f3f40404141424243434444454546464747484a4a4a4a49494a4a4a4a4a4a4a4a4a4a4a4a4a4a4b4b4b4b000b4111210c0c4a0b4112210c0c490b410a210c0c480b4108210c0c470b4108210c0c460b4104210c0c450b4104210c0c440b4104210c0c430b4104210c0c420b4104210c0c410b4104210c0c400b4104210c0c3f0b4105210c0c3e0b4105210c0c3d0b4105210c0c3c0b4105210c0c3b0b4105210c0c3a0b4113210c0c390b4114210c0c380b4106210c0c370b4107210c0c360b410b210c0c350b410b210c0c340b410b210c0c330b410b210c0c320b410b210c0c310b410b210c0c300b410b210c0c2f0b410b210c0c2e0b410b210c0c2d0b410b210c0c2c0b410b210c0c2b0b410c210c0c2a0b410c210c0c290b410c210c0c280b410c210c0c270b410c210c0c260b410c210c0c250b4100210c0c240b4100210c0c230b4101210c0c220b4102210c0c210b4103210c0c200b4103210c0c1f0b4100210c0c1e0b4100210c0c1d0b4100210c0c1c0b4100210c0c1b0b4100210c0c1a0b4100210c0c190b4101210c0c180b4102210c0c170b4103210c0c160b4103210c0c150b4100210c0c140b4100210c0c130b4100210c0c120b4100210c0c110b410d210c0c100b410d210c0c0f0b410d210c0c0e0b410d210c0c0d0b410d210c0c0c0b410d210c0c0b0b410d210c0c0a0b410d210c0c090b410d210c0c080b410d210c0c070b410d210c0c060b410d210c0c050b410d210c0c040b410d210c0c030b410e210c0c020b410e210c0c010b410f210c0b200641016a210a2004280260210f201b2101024003402001280200221141086a210520112f0106210b41002102024002400340200b20022201460d01200141016a210202404100417f4101200520016a2d00002213200c4b1b2013200c461b41016a0e03000301000b0b2002417f6a210b0b0240200f0d00200441d8006a21020c030b200f417f6a210f2011200b4102746a41ec006a21010c010b0b200441d8006a21020240201120014103746a41146a22012802000e04010d0001010b200141046a21020b20022802002102024002400240024002400240024002402014417e6a220141084b0d0020010e09010302120405050607010b20042802c8032201417f6a220c20014f0d12200c20014b0d1220042802c003200c4104746a220c280208220120026a22022001490d12200c41086a20023602000c130b20042802c8032201417f6a220c20014f0d11200c20014b0d1120042802c003200c4104746a220c280208220120026a22022001490d11200c41086a200236020020042802c8032201417f6a220c20014f0d11200c20014b0d1120042802c0032202200c4104746a280204210c02400240200120042802c403460d002001210b0c010b200141016a220b2001490d2320014101742211200b2011200b4b1b220b41ffffffff0071200b470d23200b41047422114100480d23200220014104742011102c2202450d082004200b3602c403200420023602c00320042802c803210b0b2002200b4104746a2202200e3b000d200241003a000c2002200c360204200220013602002002410f6a200e4110763a0000200241086a4100360200200420042802c80341016a3602c8030c120b20042802c8032201417f6a220c20014f0d10200c20014b0d1020042802c003200c4104746a220c280208220120026a22022001490d10200c41086a200236020020042802c803220221010240200220042802c403470d00200241016a22012002490d222002410174220c2001200c20014b1b220141ffffffff00712001470d222001410474220b4100480d220240024020020d00200b1028210c0c010b20042802c0032002410474200b102c210c0b200c450d08200420013602c4032004200c3602c00320042802c80321010b20042802c00320014104746a2201200e3b000d200141003a000c2001200a360204200120023602002001410f6a200e4110763a0000200141086a4100360200200420042802c80341016a3602c8030c110b20042802c8032201417f6a220c20014f0d0f200c20014b0d0f20042802c003200c4104746a220c280208220120026a22022001490d0f200c41086a200236020020042802c803220221010240200220042802c403470d00200241016a22012002490d212002410174220c2001200c20014b1b220141ffffffff00712001470d212001410474220b4100480d210240024020020d00200b1028210c0c010b20042802c0032002410474200b102c210c0b200c450d08200420013602c4032004200c3602c00320042802c80321010b20042802c00320014104746a2201200e3b000d200141013a000c2001200a360204200120023602002001410f6a200e4110763a0000200141086a4100360200200420042802c80341016a3602c8030c100b200441c0036a200610ff030d0e20042802c8032202450d0e20042002417f6a22013602c80320042802c003220c20014104746a220b2d000c4102460d0e2001450d0f2002417e6a220220014f0d0e200c20024104746a220c200b2802002202200c280200220c200c20024b1b360200200220014f0d0f200441c0036a200610ff030d0e0c0f0b20042802c8032201417f6a220c20014f0d0d200c20014b0d0d20042802c003200c4104746a220c280208220120026a22022001490d0d202020064104746a41046a280200210b200c41086a200236020020042802c8032201417f6a220220014b0d0d2002200b6b220120024b0d0d200441c0036a200610ff030d0d20042802c803220220014d0d0d20042802c003220c20014104746a2d000c0d0e2002410474200c6a41706a2202200120022802002202200220014b1b3602000c0e0b20042802c8032201417f6a220c20014f0d0c200c20014b0d0c20042802c003200c4104746a220c280208220120026a22022001490d0c200c41086a200236020020042802c8032201417f6a220520014b0d0c202020064104746a41046a280200220128020021022001280204210c2004200520012802086b220b20054b22013a00b00220010d0c410410282213450d052013200b36020002400240200c4104490d00200520022802006b220f20054b0d08200241046a21010c010b0240200c0d0041012102410121110c0b0b200520022802006b220f20054b0d07200241046a21010b2002200c4102746a2120410121114104210c4102210b41022102034002402002417f6a22142011470d00201441016a22112014490d1f200b2011200b20114b1b221141ffffffff03712011470d1f201141027422144100480d1f0240024020024101470d002014102821130c010b2013200c2014102c21130b2013450d090b2013200c6a200f36020002400240202020016b410d490d000240200520012802006b220f20054b0d00200141046a21010c020b200441013a00b0020c0d0b20202001460d0b200520012802006b220f20054b0d0a200141046a21010b200b41026a210b200241016a2102200c41046a210c0c000b0b20042802c8032201417f6a220c20014f0d0b200c20014b0d0b20042802c003200c4104746a220c280208220120026a22022001490d0b200c41086a2002360200200441c0036a200610ff030d0b20042802c8032201450d0b20042802c00322022d000c0d0c200141047420026a41706a41003602000c0c0b41fce2c500200620011034000b201141041037000b200b41041037000b200b41041037000b410441041037000b41012111200441013a00b0020c030b201441041037000b200441013a00b0020c010b20042d00b0020d002013450d022002ad4220862011ad842118410121050240200441c0036a200610ff030d0002402018422088a72201450d002001410274210c20132101034020042802c803220b200128020022024d0d02024020042802c003221120024104746a2d000c0d00200b41047420116a41706a220b2002200b280200220b200b20024b1b3602000b200141046a2101200c417c6a220c0d000b0b410021050b02402018a7450d002013102a0b20050d020c030b2011450d012013102a0c010b200441c0036a200610ff03450d010b024020042802c403450d0020042802c003102a0b024020042802d003450d0020042802cc03102a0b4101211c0c0a0b200a201f460d0120082802142101200a21060c000b0b20042802cc0320042802d4032201410041202001676b10800420042903d003212120042802cc03211f024020042802c403450d0020042802c003102a0b0240201f0d004101211c0c080b0240200828021422022021422088a722114101746a220141ffffffff00712001470d002001410474220c417f4c0d00024002400240200c0d004108210b0c010b200c1028220b450d01200828021421020b20084100360214200828020c21222008200b36020c200841106a220b2802002123200b2001360200202220024104746a210f201f20114103746a212041022111024020020d00201f210a202221010c040b41002101201f210a4100210c20222102024002400340200241016a2f0000200241036a2d000041107472210e024020022d0000221341ac01470d00200241106a21010c070b200241086a2900002118200241046a280000210502400240024020114102470d000240200a2020470d00410021112020210a0c020b200a2902002219422088a721152019a7211041012111200a41086a210a0b20114101470d00200c2010470d0002402001200b280200470d00200141016a22112001490d15200141017422062011200620114b1b221141ffffffff00712011470d15201141047422064100480d150240024020010d002006102821010c010b200828020c20014104742006102c21010b2001450d022008200136020c200b2011360200200828021421010b200828020c20014104746a220120042f00c0033b00012001412d3a000020012015360204200141036a200441c0036a41026a2d00003a00002008200828021441016a220136021402402001200b280200470d00200141016a22112001490d15200141017422062011200620114b1b221141ffffffff00712011470d15201141047422064100480d150240024020010d002006102821010c010b200828020c20014104742006102c21010b2001450d042008200136020c200b2011360200200828021421010b200828020c20014104746a220120042f00c0033b00012001410b3a00002001200d36020441022111200141036a200441c0036a41026a2d00003a00002008200828021441016a2201360214200c21100b02402001200b280200470d00200141016a22062001490d14200141017422142006201420064b1b220641ffffffff00712006470d14200641047422144100480d140240024020010d002014102821010c010b200828020c20014104742014102c21010b2001450d042008200136020c200b2006360200200828021421010b200c41016a210c200828020c20014104746a22012018370308200120053602042001200e3b0001200120133a0000200141036a200e4110763a00002008200828021441016a2201360214200241106a2202200f470d010c080b0b200641081037000b200641081037000b201441081037000b200c41081037000b1036000b411041041037000b2001200f460d0003400240024020012d000022024109460d00200241ac01470d010c030b0240200141046a280200220228020441ffffffff0371450d002002280200102a0b2002102a0b200141106a2201200f470d000b0b2021a7210102402023450d002022102a0b200a202047201120114102461b210202402001450d00201f102a0b024020024101470d004101211c0c050b200841186a210c024002402004280268450d0020082802142202450d00200828020c210120024104742102410021080340024020012d0000412c470d002001410b3a0000200141046a201a360200200841016a21080b200141106a2101200241706a22020d000b4101210120080d010b201d21010b200c201e470d000b2001211d0c030b20072802042201200d490d022007200141016a3602040c020b200728020c2201450d012007280204220c2001411c6c6a210b0340200c2201411c6a210c024020012802182202450d0020012802102101200241027421020340024020012802002208200d490d002001200841016a3602000b200141046a21012002417c6a22020d000b0b200c200b460d020c000b0b200728020c2201450d00200141146c2102200728020441106a2101034002402001417c6a2802000d0020012802002208200d490d002001200841016a3602000b200141146a21012002416c6a22020d000b0b200741306a22072012470d000b201c4101710d02201d4101710d01200428029002211120042802880221070b2004418c026a280200210f20042802840221132004280280022105410021060c020b200441c0036a41106a20044180026a41106a280200360200200441c0036a41086a20044180026a41086a29030037030020042004290380023703c003200441b0026a200441c0036a10fc03411010282202450d07200241063a0000410110282201450d06200141003a000041011028220c450d05200c20012d00003a00002001102a411010282208450d04200841063a000041f00010282201450d03200141063a00602001412c3b01502001200d3602442001410b3a0040200141d8003a0030200120042802683602242001412d3a0020200141003602142001410f3a0010200141003602042001410f3a0000024020082d00004109470d0002402008280204220d28020441ffffffff0371450d00200d280200102a2008280204210d0b200d102a0b2008102a024020022d00004109470d0002402002280204220828020441ffffffff0371450d002008280200102a200228020421080b2008102a0b2002102a200441e4036a4287808080f000370200200441e0036a2001360200200441dc036a4100360200200441c0036a410c6a4281808080800c370200200441c8036a4101360200200441003602ec03200442043702d4032004200c3602c403200441013602c003200441b0026a200441c0036a108104200441c0036a200441b0026a418c01109a051a20044198026a200441c0036a10fe0320044198026a410c6a280200210f200441a8026a28020021112004280298022105200428029c02211320042802a0022107410021060c010b2004418c026a280200210f200428028802210702402004280290022211450d00201141306c21022007210103402001108204200141306a2101200241506a22020d000b0b41012106411a211341f28cc60021050240200f450d002007102a0b0b200441e4006a280200210e200428025c21080240200441e0006a2802002201450d000340200828026c21082001417f6a22010d000b0b4100210d4100210102400340200e450d0102400240200120082f01064f0d00200820014103746a41146a2902002118200141016a21010c010b02400240200828020022010d00200dad21184100210c410021010c010b2008330104422086200dad8421184101210c0b2008102a2018a7210d024002402018422088a7220b20012f01064f0d00200121020c010b034002400240200128020022020d00200dad2118410021020c010b200c41016a210c2001330104422086200dad8421180b2001102a2018a7210d200221012018422088a7220b20022f01064f0d000b0b200b41027420026a41f0006a28020021082002200b4103746a41146a29020021180240200c417f6a2201450d000340200828026c21082001417f6a22010d000b0b410021010b200e417f6a210e2018a74103470d000b0b0240200841f8b9c000460d00200828020021012008102a2001450d00200128020021022001102a2002450d00024020022802002201450d0003402002102a2001210220012802002208210120080d000b0b2002102a0b02402006450d002000200536020420004101360200200041086a20133602000c250b200441b0026a41106a2011360200200441b0026a410c6a200f360200200420073602b802200420133602b402200420053602b002200441c0036a200441b0026a2009280260108304024020042802c0034101470d000240200441c0036a41086a280200450d0020042802c403102a0b2000418c8dc60036020420004101360200200041086a41233602000c250b200441d4036a2802002102200441c0036a41106a280200210f200441c0036a410c6a2802002106200441c8036a280200210d20042802c403210820032802582110200441003602a002200442013703980202400240410410282201450d002004410436029c02200420042802a002220c41046a3602a00220042001360298022001200c6a200836000002400240200428029c02220820042802a00222016b4104490d0020042802980221080c010b200141046a220c2001490d0320084101742201200c2001200c4b1b22014100480d030240024020080d002001102821080c010b20042802980220082001102c21080b2008450d022004200136029c02200420083602980220042802a00221010b2004200141046a3602a002200820016a200d3600002006200241306c22016a210d024020020d00200621010c0e0b200141506a2111200441c0036a4101722102200441c0036a41276a210c200441c0036a41206a210b200441c0036a41186a2107200441c0036a41086a210e20062101034020012d00002108200c200141286a290000370000200b200141216a2900003703002007200141196a290000370300200441c0036a41106a2203200141116a290000370300200e200141096a2900003703002004200141016a2900003703c003024020084110470d00200141306a21010c0f0b200441b0026a41276a2213200c290000370000200441b0026a41206a2205200b290300370300200441b0026a41186a20072903002218370300200441b0026a41106a20032903002219370300200441b0026a41086a200e2903002221370300200420042903c00322243703b00220022024370000200241086a2021370000200241106a2019370000200241186a2018370000200241206a2005290300370000200241276a2013290000370000200420083a00c003200441f0006a200441c0036a20044198026a10840420042d00702208411f470d0d201141506a2111200141306a2201200d470d000b200d21010c0d0b410441011037000b200141011037000b1031000b41f00041081037000b411041081037000b410141011037000b410141011037000b411041081037000b200b41041037000b410341011037000b410341011037000b410141011037000b200428027421122004280278211002402011450d00200141306a2101200441c0036a4101722102200441c0036a41276a210b200441c0036a41206a2107200441c0036a41186a210e200441c0036a41086a2111034020012d0000210c200b200141286a2900003700002007200141216a290000370300200e200141196a290000370300200441c0036a41106a2203200141116a2900003703002011200141096a2900003703002004200141016a2900003703c003200c4110460d01200441b0026a41276a2213200b290000370000200441b0026a41206a22052007290300370300200441b0026a41186a200e2903002218370300200441b0026a41106a20032903002219370300200441b0026a41086a20112903002221370300200420042903c00322243703b00220022024370000200241086a2021370000200241106a2019370000200241186a2018370000200241206a2005290300370000200241276a20132900003700002004200c3a00c003200441c0036a108204200141306a2201200d470d000b0b0240200f450d002006102a0b0240200428029c02450d00200428029802102a0b024020084105470d002010450d002012102a0b200041cd8fc60036020420004101360200200041086a41253602000c190b02402001200d460d00200441c0036a4101722102200441c0036a41276a210c200441c0036a41206a210b200441c0036a41186a2107200441c0036a41086a210e034020012d00002108200c200141286a290000370000200b200141216a2900003703002007200141196a290000370300200441c0036a41106a2211200141116a290000370300200e200141096a2900003703002004200141016a2900003703c00320084110460d01200441b0026a41276a2203200c290000370000200441b0026a41206a2213200b290300370300200441b0026a41186a20072903002218370300200441b0026a41106a20112903002219370300200441b0026a41086a200e2903002221370300200420042903c00322243703b00220022024370000200241086a2021370000200241106a2019370000200241186a2018370000200241206a2013290300370000200241276a2003290000370000200420083a00c003200441c0036a108204200141306a2201200d470d000b0b0240200f450d002006102a0b2004280298022101200429029c0221182000411c6a41003a0000200041146a2018370200200041106a20013602002000410c6a2017360200200041086a2016360200200020103602042000411d6a20042f0080023b0000200041003602002000411f6a20044182026a2d00003a00000c180b200e102a2000419c90c4003602040c160b200e102a2000419c90c4003602040c150b200e102a2000419c90c4003602040c140b200e102a2000419c90c4003602040c130b200e102a2000419c90c4003602040c120b200e102a2000419c90c4003602040c110b200e102a2000419c90c4003602040c100b200e102a2000419c90c4003602040c0f0b200f2d000d22024104460d05200241fb01710d05200e102a201121020c0b0b200f2d000d22024104460d02200241fb01710d02200e102a201121020c0a0b200f2d000d22024104460d00200241fb01710d00200e102a201121020c090b200e102a2000419c90c4003602040c0b0b200e102a2000419c90c4003602040c0a0b200e102a2000419c90c4003602040c090b200e102a2000419c90c4003602040c080b200e102a2000419c90c4003602040c070b02400240200241bbffc500460d0041bbffc5002002410b109c050d010b4126210c419c90c400210e200f2d000c41e000470d01200f2802080d0120112102200f2d000d4104460d040c010b0240200241dfffc500460d0041dfffc5002002410b109c050d030b4126210c419c90c400210e200f2d000c41e000470d00200f2802080d0020112102200f2d000d4104460d030b200e2108200c21010b200020083602040c040b0240200241ac81c600460d0041ac81c6002002410b109c050d030b024041021028220c450d00200c41003b0000200f2d000c41e000470d02200f2802084102470d020240200f280200220e200c460d0041002101034020014102460d01200c20016a2102200e20016a2108200141016a210120082d000020022d0000470d040c000b0b200f2d000d4104470d02200c102a201121020c010b0b410241011037000b200c102a0b412621012000419c90c4003602040b20004101360200200041086a200136020002402007450d00200b200741306c6a2111200b210703402007220041306a21070240024020002d00002201410e4b0d00024002400240024002400240024002400240024002400240024020010e0f0001020304050607080e090e0a0b0c000b200041086a280200450d0d200041046a280200102a0c0d0b0240200041086a280200450d00200041046a280200102a0b200041146a280200450d0c200041106a280200102a0c0c0b02402000410c6a2802002202450d00200041046a28020021012002410474210203400240200141046a280200450d002001280200102a0b200141106a2101200241706a22020d000b0b200041086a280200450d0b2000280204102a0c0b0b02402000410c6a2802002202450d00200041046a2802002101200241286c210203400240200141046a280200450d002001280200102a0b0240200141106a280200450d002001410c6a280200102a0b200141286a2101200241586a22020d000b0b200041086a280200450d0a2000280204102a0c0a0b200041086a280200450d09200041046a280200102a0c090b200041086a280200450d08200041046a280200102a0c080b200041086a280200450d07200041046a280200102a0c070b02402000410c6a2802002201450d00200041046a280200220c20014104746a210e03400240200c2802082202450d00200c2802002101200241047421020340024020012d00004109470d000240200141046a220d280200220828020441ffffffff0371450d002008280200102a200d28020021080b2008102a0b200141106a2101200241706a22020d000b0b200c41106a21010240200c41046a280200450d00200c280200102a0b2001210c2001200e470d000b0b200041086a280200450d062000280204102a0c060b02402000410c6a2802002202450d00200041046a2802002101200241146c210203400240200141046a280200450d002001280200102a0b200141146a21012002416c6a22020d000b0b200041086a280200450d052000280204102a0c050b02402000410c6a2802002201450d00200041046a280200220c2001411c6c6a210e03400240200c2802042201450d000240200c410c6a2802002202450d00200241047421020340024020012d00004109470d000240200141046a220d280200220828020441ffffffff0371450d002008280200102a200d28020021080b2008102a0b200141106a2101200241706a22020d000b0b200c41086a280200450d00200c280204102a0b200c411c6a21010240200c41146a280200450d00200c280210102a0b2001210c2001200e470d000b0b200041086a280200450d042000280204102a0c040b02402000410c6a2802002201450d00200041046a280200220c200141186c6a210e03400240200c41046a280200450d00200c280200102a0b0240200c41146a2802002202450d00200c28020c2101200241047421020340024020012d00004109470d000240200141046a220d280200220828020441ffffffff0371450d002008280200102a200d28020021080b2008102a0b200141106a2101200241706a22020d000b0b200c41186a21010240200c41106a280200450d00200c28020c102a0b2001210c2001200e470d000b0b200041086a280200450d032000280204102a0c030b02402000410c6a2802002201450d00200041046a280200220c2001411c6c6a210e03400240200c2802042201450d000240200c410c6a2802002202450d00200241047421020340024020012d00004109470d000240200141046a220d280200220828020441ffffffff0371450d002008280200102a200d28020021080b2008102a0b200141106a2101200241706a22020d000b0b200c41086a280200450d00200c280204102a0b200c411c6a21010240200c41146a280200450d00200c280210102a0b2001210c2001200e470d000b0b200041086a280200450d022000280204102a0c020b0240200041046a2802002201450d00200041086a280200450d002001102a0b0240200041146a2802002201450d0002402000411c6a2802002202450d002002410c6c21020340024020012802002208450d00200141046a280200450d002008102a0b2001410c6a2101200241746a22020d000b0b200041186a280200450d002000280214102a0b200041246a280200220c450d0102402000412c6a2802002201450d00200c20014104746a210e0340200c220d41106a210c0240200d2802042201450d000240200d410c6a2802002202450d002002410c6c21020340024020012802002208450d00200141046a280200450d002008102a0b2001410c6a2101200241746a22020d000b0b200d41086a280200450d00200d280204102a0b200c200e470d000b0b200041286a280200450d012000280224102a0c010b0240200041086a280200450d00200041046a280200102a0b0240200041146a2802002201450d00200041186a280200450d002001102a0b200041246a280200450d00200041206a280200102a0b20072011470d000b0b200a450d00200b102a0b200441d0046a24000ba20301067f230041106b2202240020024100360208200242013703002000200210a001200041046a200210a001200041086a200210a00120002d0018210302400240024002400240200228020420022802082204460d00200228020021050c010b200441016a22052004490d03200441017422062005200620054b1b22064100480d030240024020040d002006102821050c010b200228020020042006102c21050b2005450d0120022006360204200220053602000b2002200441016a360208200520046a20033a0000200028020c2106200041146a2802002204200210b4010240024020022802042203200228020822056b2004490d00200228020021000c010b200520046a22002005490d03200341017422072000200720004b1b22074100480d030240024020030d002007102821000c010b200228020020032007102c21000b2000450d022002200736020420022000360200200721030b200020056a20062004109a051a200128020020012802042000200520046a100702402003450d002000102a0b200241106a24000f0b200641011037000b200741011037000b1031000bd60801037f024002400240024002400240024002400240410110282202450d00200220002d00003a0000200241014102102c2202450d01200220002d00013a0001200241024104102c2202450d02200220002d00023a0002200220002d00033a0003200241044108102c2202450d03200220002d00043a0004200220002d00053a0005200220002d00063a0006200220002d00073a0007200241084110102c2202450d04200220002d00083a0008200220002d00093a0009200220002d000a3a000a200220002d000b3a000b200220002d000c3a000c200220002d000d3a000d200220002d000e3a000e200220002d000f3a000f200241104120102c2202450d05200220002d00103a0010200220002d00113a0011200220002d00123a0012200220002d00133a0013200220002d00143a0014200220002d00153a0015200220002d00163a0016200220002d00173a0017200220002d00183a0018200220002d00193a0019200220002d001a3a001a200220002d001b3a001b200220002d001c3a001c200220002d001d3a001d200220002d001e3a001e200220002d001f3a001f2002412041c000102c2202450d06200220002d00203a0020200220002d00213a0021200220002d00223a0022200220002d00233a0023200220002d00243a0024200220002d00253a0025200220002d00263a0026200220002d00273a0027200220002d00283a0028200220002d00293a0029200220002d002a3a002a200220002d002b3a002b200220002d002c3a002c200220002d002d3a002d200220002d002e3a002e200220002d002f3a002f200220002d00303a0030200220002d00313a0031200220002d00323a0032200220002d00333a0033200220002d00343a0034200220002d00353a0035200220002d00363a0036200220002d00373a0037200220002d00383a0038200220002d00393a0039200220002d003a3a003a200220002d003b3a003b200220002d003c3a003c200220002d003d3a003d200220002d003e3a003e200220002d003f3a003f024002402001280200220041046a2802002203200041086a28020022016b41c000490d00200028020021030c010b200141c0006a22042001490d09200341017422012004200120044b1b22014100480d090240024020030d002001102821030c010b200028020020032001102c21030b2003450d0820002003360200200041046a2001360200200041086a28020021010b200041086a200141c0006a360200200320016a220041386a200241386a290000370000200041306a200241306a290000370000200041286a200241286a290000370000200041206a200241206a290000370000200041186a200241186a290000370000200041106a200241106a290000370000200041086a200241086a290000370000200020022900003700002002102a0f0b410141011037000b410241011037000b410441011037000b410841011037000b411041011037000b412041011037000b41c00041011037000b200141011037000b1031000bc32205017f057e097f047e0f7f230041c0056b22032400200241206a2903002104200241186a2903002105200241106a2903002106200241c8006a29030021072002290308210820022802002109200341086a41186a220a200241c0006a220b290300370300200341086a41106a220c200241386a220d290300370300200341086a41086a220e200241306a220f2903003703002003200241286a2202290300370308200341286a41186a2210200b290300370300200341286a41106a2211200d290300370300200341286a41086a220d200f290300370300200320022903003703282001280200210b20034180026a41186a2202200a29030037030020034180026a41106a220f200c29030037030020034180026a41086a220c200e2903003703002003200329030837038002024002400240024041381028220a450d00200a4200370308200a4200370300200a2009360210200a2003290328370214200a411c6a200d290300370200200a41246a2011290300370200200a412c6a2010290300370200200341d0016a41086a200c290300370300200341d0016a41106a200f290300370300200341d0016a41186a200229030037030020032003290380023703d001024002400240200b2802082202200b41046a280200470d00200241016a220c2002490d012002410174220d200c200d200c4b1b220cad42d0007e2212422088a70d012012a7220d4100480d010240024020020d00200d102821020c010b200b280200200241d0006c200d102c21020b2002450d02200b2002360200200b41046a200c360200200b28020821020b200b280200200241d0006c6a2202420037031020022004370308200220053703002002200a360220200220032903d00137022c200241186a4200370300200241246a428180808010370200200241346a200341d0016a41086a220a2903003702002002413c6a200341d0016a41106a220e290300370200200241c4006a200341d0016a41186a2202290300370200200b200b28020841016a3602082001280204210f20034190016a41186a200341286a41186a29030037030020034190016a41106a200341286a41106a29030037030020034190016a41086a200341286a41086a2903003703002003200329032837039001024002400240200f280200220c41f8b9c000460d00200f280204210d0c010b4100210d20034180026a410041e0021099051a200341f8016a220b4100360200200341f0016a2201420037030020024200370300200e4200370300200a4200370300200342003703d0014194031028220c450d01200c41003b0106200c4100360200200c41086a20034180026a41e002109a051a200c4190036a200b280200360200200c4188036a2001290300370200200c4180036a200341e8016a290300370200200c41f8026a200341e0016a290300370200200c41f0026a200341d0016a41086a290300370200200c20032903d0013702e802200f4100360204200f200c3602000b02400340200c41086a210a200c41066a2110200c2f0106220e41057421024100210b0240024003402002450d0120034190016a200a4120109c052201450d02200241606a2102200b41016a210b200a41206a210a2001417f4a0d000b200b417f6a210e0b200d450d02200d417f6a210d200c200e4102746a4194036a280200210c0c010b0b200c200b4102746a41e8026a20093602000c060b200341c8006a41186a20034190016a41186a22022903002212370300200341c8006a41106a20034190016a41106a220a2903002213370300200341c8006a41086a20034190016a41086a220b290300221437030020032003290390012215370348200f200f28020841016a36020820022012370300200a2013370300200b20143703002003201537039001024002400240024020102f0100220d410b490d0020034180026a410041e0021099051a200341f8016a22024100360200200341f0016a220a4200370300200341d0016a41186a4200370300200341d0016a41106a4200370300200341d0016a41086a4200370300200342003703d00141940310282211450d03201141003b010620114100360200201141086a20034180026a41e002109a05210b20114190036a200228020036020020114188036a200a29030037020020114180036a200341d0016a41186a290300370200201141f8026a200341d0016a41106a290300370200201141f0026a200341d0016a41086a290300370200201120032903d0013702e8022003200c2f00c8013b01cc012003200c41ca016a2d00003a00ce01200c41cb016a2800002116200c41cf016a2800002117200c41d3016a2800002118200c41d7016a28000021192003200c41e0016a2900003700bd012003200c2900db013703b801200c28028003211a200b200c41e8016a200c2f010641796a2202410574109a05210b201141e8026a200c4184036a2002410274109a052101200c41063b0106201120023b0106200320032f01cc013b01b401200320032d00ce013a00b601200320032903b8013703d001200320032900bd013700d501200e4107490d01201141066a2110200b200e417a6a220d4105746a200b200e41796a220a4105746a220b200241ffff0371200a6b410574109b051a200b41186a20034190016a41186a290300370000200b41106a20034190016a41106a290300370000200b41086a20034190016a41086a290300370000200b2003290390013700002001200d4102746a210b2001200a4102746a21020c020b200c41086a2201200e41016a220f4105746a2001200e4105746a2201200d200e6b410574109b051a200141186a2002290300370000200141106a200a290300370000200141086a200b2903003700002001200329039001370000200c41e8026a2202200f4102746a2002200e4102746a2202200c2f0106200e6b410274109b051a20022009360200200c200c2f010641016a3b01060c080b200c41086a2202200e41016a220a4105746a2002200e4105746a220220102f0100200e6b410574109b051a200241186a20034190016a41186a290300370000200241106a20034190016a41106a290300370000200241086a20034190016a41086a2903003700002002200329039001370000200c41e8026a220b200e4102746a2102200b200a4102746a210b200e210a0b200b200220102f0100200a6b410274109b051a20022009360200201020102f010041016a3b0100200341b0016a41026a221b20032d00b60122023a0000200341fc006a41026a221c20023a0000200320032900d50137008501200320032903d00137038001200320032f01b40122023b01b001200320032900850137006d2003200329038001370368200320023b017c200c280200220d450d05200c2f0104211020034180026a410272211d0340201b201c2d00003a0000200320032f017c3b01b00120032003290368370390012003200329006d37009501201041ffff0371210c02400240024002400240200d2f01062202410b490d00201d410041be031099051a41c40310282201450d0320014100360200200141046a20034180026a41c003109a051a2003200d2f00c8013b01cc012003200d41ca016a2d00003a00ce012003200d41db016a2900003703b8012003200d41e0016a2900003700bd01200d41cb016a280000211e200d41cf016a280000211f200d41d3016a2800002120200d41d7016a2800002121200d4180036a2802002122200141086a200d41e8016a200d2f0106220a41796a2202410574109a052123200141e8026a200d4184036a2002410274109a05212420014194036a200d41b0036a200a417a6a220e410274109a052109200d41063b0106200120023b01060240200e450d00410021022009210a0340200a280200220b20023b0104200b2001360200200a41046a210a200e200241016a2202470d000b0b200320032d00ce0122023a00b601200320032f01cc01220a3b01b401200320032903b8013703d001200320032900bd013700d50120034180016a41026a220e20023a00002003200a3b018001200320032903d00137038002200320032900d50137008502201041ffff0371220a4107490d012023200c417a6a220b4105746a2023200c41796a22024105746a220a20012f010620026b410574109b051a200a41186a200329009501370000200a201936000f200a201836000b200a2017360007200a2016360003200a41026a201b2d00003a0000200a20032f01b0013b0000200a2003290390013700132024200b410274220a6a202420024102746a221020012f0106221620026b410274109b051a2010201a3602002001201641016a22103b0106200c410274221620096a416c6a2009200a6a220a201041ffff0371220c200b6b410274109b051a200a2011360200200c200b490d02200120166a41fc026a210a0340200a280200220b200241016a22023b0104200b2001360200200a41046a210a2002200c490d000c030b0b200d41086a220a200c41016a220b4105746a200a200c4105746a220a2002200c6b410574109b051a200a41186a200329009501370000200a201936000f200a201836000b200a2017360007200a2016360003200a41026a200341b0016a41026a2d00003a0000200a20032f01b0013b0000200a200329039001370013200d41e8026a2202200b410274220a6a2002200c41027422016a2202200d2f0106220e200c6b410274109b051a2002201a360200200d200e41016a22023b01062001200d4194036a220c6a41086a200c200a6a220a200241ffff03712201200b6b410274109b051a200a2011360200201041ffff037120014f0d0b200d200b417f6a22024102746a4198036a210a0340200a280200220b200241016a22023b0104200b200d360200200a41046a210a20022001490d000c0c0b0b200d41086a2202200c41016a22104105746a2002200c4105746a2202200d2f0106200c6b410574109b051a200241186a2003290095013700002002201936000f2002201836000b2002201736000720022016360003200241026a201b2d00003a0000200220032f01b0013b00002002200329039001370013200d41e8026a220b201041027422096a200b200c41027422026a220b200d2f01062216200c6b410274109b051a200b201a360200200d201641016a220b3b01062002200d4194036a22166a41086a201620096a2209200b41ffff0371220b20106b410274109b051a20092011360200200a200b4f0d00200d20026a4198036a210203402002280200220a200c41016a220c3b0104200a200d360200200241046a2102200b200c470d000b0b201c200e2d00003a0000200320032f0180013b017c2003200329038002370368200320032900850237006d200d28020022020d01201e21162021211920202118201f2117200121112022211a0c080b41c40341041037000b200d2f01042110201e21162021211920202118201f21172002210d2022211a200121110c000b0b41940341041037000b41940341041037000b1031000b200d41081037000b413841081037000b20034180026a410272410041be031099051a41c40310282202450d0120024100360200200241046a20034180026a41c003109a051a2002200f280200220a36029403200f2002360200200f200f28020441016a360204200a41003b0104200a2002360200200220022f0106220b4105746a220a41086a20032f017c3b0000200a410a6a200341fc006a41026a2d00003a0000200a41176a2019360000200a41136a2018360000200a410f6a2017360000200a410b6a2016360000200a411b6a2003290368370000200a41206a200329006d37000020024194036a200b41016a220a4102746a20113602002002200b4102746a41e8026a201a3602002002200a3b01062011200a3b0104201120023602000b20002005370310200020083703002000200329032837032020002007370340200041186a200437030020002006370308200041286a200341306a290300370300200041306a200341386a290300370300200041386a200341286a41186a290300370300200341c0056a24000f0b41c40341041037000b0a0041c8c2c2001032000b5101027e024002402003450d002002280200450d010b41b698c40041f4031050000b2001280218220342002003290308220420023502047d2205200520045622021b37030820004105410420021b3602000bee0201047f024002400240024002402002417f4c0d000240024020020d00410121060c010b200210282206450d020b200620012002109a0521062004417f4c0d000240024020040d0041012101410021070c010b20042107200410282201450d030b200120032004109a052103024020002802082201200041046a280200470d00200141016a22082001490d05200141017422092008200920084b1b220841ffffff3f712008470d05200841057422094100480d050240024020010d002009102821010c010b200028020020014105742009102c21010b2001450d0420002001360200200041046a2008360200200028020821010b200028020020014105746a220141003602182001200336020c2001200236020820012002360204200120063602002001411c6a2005360200200141146a2004360200200141106a20073602002000200028020841016a3602080f0b1036000b200241011037000b200441011037000b200941041037000b1031000bf90e05047f027e027f017e027f230041c00c6b2204240002400240024002400240024002402003450d0020022802000d0020034101460d0120022802100d0120034102460d0220022802200d0220034103460d0320022802300d0320022802042105200241246a2802002106200241346a280200210302400240200241146a2802002207450d004105210220012802002802182802402802bc012003490d010b200441286a4200370300200441206a4200370300200441186a420037030020012802182202420020022903082208427f20012802102903482209420586200942ffffffffffffffff07832009521b7d22092009200856220a1b3703082004420037031041052102200a0d000240024020012802142802082005200441106a4120101741026a220a41024b0d00200a0e03020001020b41a0fac5001032000b0240024020070d00410121034100210b0c010b2004200128021029034842002003ad220c4200109f052001280218220a4200200a2903082209427f200429030020042903084200521b7d22082008200956220a1b370308200a0d012003417f4c0d060240024020030d004101210b02402001280214280208200641014100101741026a220341024b0d0020030e03040002040b41a0fac5001032000b024002402003102e220b450d00024020012802142802082006200b2003101741026a220341024b0d0020030e03020003020b41a0fac5001032000b200341011037000b200b102a0c020b200c422086200c842109200b4521030b20012802002101200441306a41186a220a200441106a41186a290300370300200441306a41106a2205200441106a41106a290300370300200441306a41086a2206200441106a41086a2903003703002004200429031037033020012802182107024020030d0020072802402802bc012009422088a74f0d002009a7450d01200b102a0c010b200441d0006a41186a200a290300370300200441d0006a41106a2005290300370300200441d0006a41086a20062903003703002004200429033037035020072802180d062007417f360218200441a8016a200741e8006a290000370300200441a0016a200741e0006a29000037030020044198016a200741d8006a2900003703002004200729005037039001024002402007411c6a220d280200220a41f8b9c000460d00200741206a28020021060c010b41002106200441e0096a410041e0021099051a200441c0016a410041a0081099051a41880b1028220a450d08200a41003b0106200a4100360200200a41086a200441e0096a41e002109a051a200a41e8026a200441c0016a41a008109a051a200741206a41003602002007200a36021c0b024002400340200a2f0106220e4105742105410021024100210302400240034020052002460d0120044190016a200a20026a41086a4120109c052201450d02200241206a2102200341016a21032001417f4a0d000b2003417f6a210e0b2006450d022006417f6a2106200a200e4102746a41880b6a280200210a0c010b0b200741246a2101410121020c010b200441f0006a41186a20044190016a41186a290300370300200441f0006a41106a20044190016a41106a290300370300200441f0006a41086a20044190016a41086a2903003703002004200429039001370370200741246a210141002106200e2103410021020b0240024020020d00200441fc096a200441f0006a41086a290300370200200441840a6a200441f0006a41106a2903003702002004418c0a6a200441f0006a41186a290300370200200420013602f009200420033602ec092004200d3602e8092004200a3602e409200420063602e009200420042903703702f409200441e0016a20042903b001370300200441e8016a200441b0016a41086a290300370300200441f4016a4200370200200442003703d801200442003703c001200441f8b9c0003602f001200441003a00fc01200441fd016a20042900900137000020044185026a20044190016a41086a2900003700002004418d026a20044190016a41106a29000037000020044195026a20044190016a41186a290000370000200441003a009d02200441e0096a200441c0016a10b70121020c010b200441d8016a4200370300200441d4016a41f8b9c000360200200441003602e001200441003602d001200442003703c801200441f8b9c0003602c401200441003602c001200a200341e0006c6a41e8026a2102200441c0016a1095010b200441c0016a41186a200441d0006a41186a290300370300200441c0016a41106a200441d0006a41106a290300370300200441c0016a41086a200441d0006a41086a290300370300200420042903503703c00120042009370294012004200b36029001200441e0096a200241306a200441c0016a20044190016a10bd01024020042802e009450d0020042802e4092202450d00200441e8096a280200450d002002102a0b2007200728021841016a360218410421020b20002002360200200441c00c6a24000f0b41b698c40041f4031050000b41b698c40041f4031050000b41b698c40041f4031050000b41b698c40041f4031050000b1036000b41a8b8c0004110200441c0016a41d0b8c0001038000b41880b41081037000b900302017f027e230041c0006b22042400024002402003450d0020022802000d0020022802042103200441186a4200370300200441106a4200370300200441086a420037030020012802182202420020022903082205427f20012802102903482206420586200642ffffffffffffffff07832006521b7d2206200620055622021b3703082004420037030002400240024020020d00024002402001280214280208200320044120101741026a220241024b0d0020020e03020001020b41a0fac5001032000b200441206a2001280200280218220241186a200241d0006a2002410c6a4100200228020c1b200410a7012004280220450d01200441306a41086a2203200441206a41086a28020036020020042004290320370330200141046a21020240200141086a280200450d002002280200102a0b20022004290330370200200241086a2003280200360200410021010c020b200041053602000c030b2001410c6a4100360200410121010b20004100360200200020013602040c010b41b698c40041f4031050000b200441c0006a24000bae0f06017f017e057f027e037f027e230041d0016b220424000240024002400240024002400240024002400240024002402003450d0020022802000d0020034101460d0120022802100d0120034102460d0220022802204101470d0220034103460d0320022802300d0320034104460d0420022802400d0420034105460d0520022802500d0520034106460d0620022802600d0620022802042103200241286a2903002105200241346a2802002106200241c4006a2802002107200241d4006a2802002108200241e4006a2802002109200441286a20012802102903484200200241146a280200220aad4200109f052001280218220242002002290308220b427f200429032820042903304200521b7d220c200c200b5622021b370308024020020d00200a417f4c0d0802400240024002400240200a0d004101210d02402001280214280208200341014100101741026a220241024b0d00200141146a210e20020e03060002060b41a0fac5001032000b0240200a102e220d450d00024020012802142802082003200d200a101741026a220241024b0d00200141146a210e20020e03030002030b41a0fac5001032000b200a41011037000b41002102200441003a00980102400340200a2002460d01200441f8006a20026a200d20026a2d00003a00002004200241016a22033a0098012003210220034120470d000b200441a0016a41186a2202200441f8006a41186a290300370300200441a0016a41106a2203200441f8006a41106a290300370300200441a0016a41086a220f200441f8006a41086a290300370300200420042903783703a0010240200a450d00200d102a0b200441386a41086a200f290300370300200441386a41106a2003290300370300200441386a41186a2002290300370300200420042903a001370338200441186a200128021029034842002007ad4200109f052001280218220242002002290308220b427f200429031820042903204200521b7d220c200c200b5622021b37030820020d042007417f4c0d0c20070d03200e280200280208200641014100101741026a220241024b0d0220020e03040204040b0240200241ff0171450d00200441003a0098010b200a450d030b200d102a0c020b41a0fac5001032000b0240024002402007102e2202450d000240200e280200280208200620022007101741026a220341024b0d0020030e03030002030b41a0fac5001032000b200741011037000b2007410f4d0d00200241086a2900002110200229000021112002102a200441086a200128021029034842002009ad4200109f052001280218220242002002290308220b427f200429030820042903104200521b7d220c200c200b5622021b37030820020d01200141046a210a0240024020092001410c6a220d28020022034b0d00200921020c010b02400240200141086a280200220220036b200920036b2206490d00200a2802002107200321020c010b200320066a22072003490d0d2002410174220e2007200e20074b1b220e4100480d0d0240024020020d00200e102821070c010b200a2802002002200e102c21070b2007450d0c20012007360204200141086a200e3602002001410c6a28020021020b200720026a210e0240024020064102490d00200e410020092003417f7322036a22061099051a2007200920026a20036a6a210e200620026a21020c010b2006450d010b200e41003a0000200241016a21020b200d2002360200024002402001280214280208200820012802042002101741026a220241024b0d0020020e03030001030b41a0fac5001032000b2001410c6a2202280200210720024100360200200141086a28020021032001280204210d2001420137020420012802182202290308220c210b024002402005500d002005210b200c2005540d010b2002200c200b7d3703082002290310210c200441a0016a41186a200241186a2903003703002004200b3703a8012004200b3703a0012004200c3703b001200128020041186a2802002106200441f8006a41186a200441386a41186a290300370300200441f8006a41106a200441386a41106a290300370300200441f8006a41086a200441386a41086a29030037030020042004290338370378200420073602c801200420033602c4012004200d3602c001200441d8006a2006200441f8006a20112010200441a0016a200441c0016a10c101410121090240024020042802584101460d00200441d8006a410472210d200441d8006a41106a2d00002107200441e4006a2802002106200441e0006a2802002103410021090c010b200441e4006a210d200441ec006a2802002106200441d8006a41106a2802002103410021070b200d280200210d200220042903a80120022903087c370308200141086a2802002102024020090d0002402002450d00200a280200102a0b200a200d3602000c0e0b2002450d00200a280200102a0b200a200d3602004180022107410021060c0c0b2002102a0b200041053602000c0b0b41b698c40041f4031050000b41b698c40041f4031050000b41b698c40041f4031050000b41b698c40041f4031050000b41b698c40041f4031050000b41b698c40041f4031050000b41b698c40041f4031050000b1036000b200e41011037000b1031000b2001410c6a2006360200200141086a200336020020004100360200200020073602040b200441d0016a24000bc71006017f017e057f027e037f027e230041e0016b2204240002400240024002400240024002400240024002402003450d0020022802000d0020034101460d0120022802100d0120034102460d0220022802204101470d0220034103460d0320022802300d0320034104460d0420022802400d0420034105460d0520022802500d0520034106460d0620022802600d0620022802042103200241286a2903002105200241346a2802002106200241c4006a2802002107200241d4006a2802002108200241e4006a2802002109200441206a20012802102903484200200241146a280200220aad4200109f052001280218220242002002290308220b427f200429032020042903284200521b7d220c200c200b5622021b3703080240024020020d00200a417f4c0d0902400240024002400240200a0d004101210d02402001280214280208200341014100101741026a220241024b0d00200141146a210e20020e03060002060b41a0fac5001032000b0240200a102e220d450d00024020012802142802082003200d200a101741026a220241024b0d00200141146a210e20020e03030002030b41a0fac5001032000b200a41011037000b41002102200441003a00c80102400340200a2002460d01200441a8016a20026a200d20026a2d00003a00002004200241016a22033a00c8012003210220034120470d000b20044188016a41186a2202200441a8016a41186a29030037030020044188016a41106a2203200441a8016a41106a29030037030020044188016a41086a220f200441a8016a41086a290300370300200420042903a801370388010240200a450d00200d102a0b200441306a41086a200f290300370300200441306a41106a2003290300370300200441306a41186a20022903003703002004200429038801370330200441106a200128021029034842002007ad4200109f052001280218220242002002290308220b427f200429031020042903184200521b7d220c200c200b5622021b37030820020d042007417f4c0d0d20070d03200e280200280208200641014100101741026a220241024b0d0220020e03040204040b0240200241ff0171450d00200441003a00c8010b200a450d030b200d102a0c020b41a0fac5001032000b0240024002402007102e2202450d000240200e280200280208200620022007101741026a220341024b0d0020030e03030002030b41a0fac5001032000b200741011037000b2007410f4d0d00200241086a2900002110200229000021112002102a2004200128021029034842002009ad4200109f052001280218220242002002290308220b427f200429030020042903084200521b7d220c200c200b5622021b37030820020d01200141046a21070240024020092001410c6a220a28020022034b0d00200921020c010b02400240200141086a280200220220036b200920036b2206490d002007280200210d200321020c010b200320066a220d2003490d0e2002410174220e200d200e200d4b1b220e4100480d0e0240024020020d00200e1028210d0c010b20072802002002200e102c210d0b200d450d0d2001200d360204200141086a200e3602002001410c6a28020021020b200d20026a210e0240024020064102490d00200e410020092003417f7322036a22061099051a200d200920026a20036a6a210e200620026a21020c010b2006450d010b200e41003a0000200241016a21020b200a2002360200024002402001280214280208200820012802042002101741026a220241024b0d0020020e03030001030b41a0fac5001032000b2001410c6a2202280200210d20024100360200200141086a28020021032001280204210a2001420137020420012802182202290308220c210b0240024002402005500d002005210b200c2005540d010b2002200c200b7d3703082002290310210c20044188016a41186a200241186a2903003703002004200b370390012004200b370388012004200c37039801200128020041186a28020021062004200d360258200420033602542004200a360250200441a8016a20062011201020044188016a200441306a200441d0006a10b5014101210d0240024020042802a8014101460d00200441d0006a41086a200441a8016a41186a290300370300200441d0006a41106a200441c8016a2802003602002004200441a8016a41106a290300370350200441d8016a2d00002106200441d0016a2802002109200441cc016a2802002108200441b4016a280200210e200441a8016a41086a28020021034100210d20042802ac01210a0c010b200441bc016a280200210e200441b8016a2802002103200441b4016a280200210a410021060b200220042903900120022903087c370308200441f0006a41086a2202200441d0006a41086a290300370300200441f0006a41106a220f200441d0006a41106a280200360200200420042903503703700240200d0d00200441bc016a2002290300370200200441c4016a200f2802003602002004200e3602b001200420033602ac012004200a3602a801200420042903703702b4010240200141086a280200450d002007280200102a0b200120083602042001410c6a4100360200200141086a2009360200200641ff017122020d02200441a8016a2007108f010c020b200141086a280200450d002007280200102a0b2001200a3602042001410c6a4100360200200141086a200336020041800221020b20004100360200200020023602040c020b2002102a0b200041053602000b200441e0016a24000f0b41b698c40041f4031050000b41b698c40041f4031050000b41b698c40041f4031050000b41b698c40041f4031050000b41b698c40041f4031050000b41b698c40041f4031050000b41b698c40041f4031050000b1036000b200e41011037000b1031000b9d0503027f037e057f230041206b2204240002400240024002402003450d0020022802000d0020034101460d0120022802100d0120022802042105200441106a20012802102903184200200241146a2802002203ad22064200109f0520012802182202420020022903082207427f200429031020042903184200521b7d2208200820075622021b370308024020020d0020042001280210290348420020064200109f0520012802182202420020022903082207427f200429030020042903084200521b7d2208200820075622021b37030820020d000240024020032001410c6a2209280200220a4b0d00200321020c010b02400240200141086a2802002202200a6b2003200a6b220b490d002001280204210c200a21020c010b200a200b6a220c200a490d062002410174220d200c200d200c4b1b220d4100480d060240024020020d00200d1028210c0c010b20012802042002200d102c210c0b200c450d052001200c360204200141086a200d3602002001410c6a28020021020b200c20026a210d02400240200b4102490d00200d41002003200a417f73220a6a220b1099051a200c200320026a200a6a6a210d200b20026a21020c010b200b450d010b200d41003a0000200241016a21020b20092002360200024002402001280214280208200520012802042002101741026a220241024b0d0020020e03020001020b41a0fac5001032000b2001410c6a2202280200210320024100360200200141086a280200210220012802042105200142013702040240200128021c220a450d00200141206a280200450d00200a102a0b2001200536021c200141246a2003360200200141206a20023602000b20004105360200200441206a24000f0b41b698c40041f4031050000b41b698c40041f4031050000b200d41011037000b1031000b23002001410c6a4100360200200128020041206a200141046a108f01200041043602000b27002001410c6a4100360200200128020028021841d0006a200141046a108f01200041043602000bd50102027f027e410021042001410c6a41003602002001280218220541186a2903002106200529031021070240024002400240200141086a28020022054110490d00200128020421050c010b200541017422044110200441104b1b22044100480d020240024020050d002004102821050c010b200128020420052004102c21050b2005450d0120012005360204200141086a20043602002001410c6a28020021040b2001410c6a200441106a360200200520046a2201200637000820012007370000200041043602000f0b200441011037000b1031000bc20103017f017e017f410021042001410c6a4100360200200128021829030821050240024002400240200141086a28020022064108490d00200128020421060c010b200641017422044108200441084b1b22044100480d020240024020060d002004102821060c010b200128020420062004102c21060b2006450d0120012006360204200141086a20043602002001410c6a28020021040b2001410c6a200441086a360200200620046a2005370000200041043602000f0b200441011037000b1031000bb804020b7f027e230041206b220424002001410c6a41003602000240024002402001280200280218220528021841016a220641004c0d00200541d0006a2107200520063602182005411c6a2108200541206a28020021090240024003402008280200220a41086a210b200a2f0106220c41057421084100210d0240024003402008450d012007200b4120109c05220e450d02200841606a2108200d41016a210d200b41206a210b200e417f4a0d000b200d417f6a210c0b2009450d022009417f6a2109200a200c4102746a41880b6a21080c010b0b200a200d41e0006c6a220841c5036a310000200841e8026a290300220f200f50220b1ba7450d004200200841f8026a290300200b1b210f4200200841f0026a290300200b1b21100c010b200441086a200541286a28020020072005412c6a28020028021c110500200441106a290300210f20052802182106200429030821100b20052006417f6a36021802400240200141086a280200220b2001410c6a28020022086b4110490d002001280204210b0c010b200841106a220d2008490d03200b4101742208200d2008200d4b1b22084100480d0302400240200b0d0020081028210b0c010b2001280204200b2008102c210b0b200b450d022001200b360204200141086a20083602002001410c6a28020021080b2001410c6a200841106a360200200b20086a2208200f3700082008201037000020004104360200200441206a24000f0b41b8b8c0004118200441186a41e0b8c0001038000b200841011037000b1031000bd50102027f027e410021042001410c6a41003602002001280200220541086a2903002106200529030021070240024002400240200141086a28020022054110490d00200128020421050c010b200541017422044110200441104b1b22044100480d020240024020050d002004102821050c010b200128020420052004102c21050b2005450d0120012005360204200141086a20043602002001410c6a28020021040b2001410c6a200441106a360200200520046a2201200637000820012007370000200041043602000f0b200441011037000b1031000b860302047f027e230041c0006b220424000240024002402003450d0020022802000d0020034101460d0120022802100d01410521050240200241146a28020022032001280210220628026c4b0d0020022802042107200441086a200629034842002003ad4200109f0520012802182202420020022903082208427f200429030820042903104200521b7d2209200920085622021b37030820020d002003417f4c0d0302400240024020030d004101210202402001280214280208200741014100101741026a220641024b0d0020060e03040002040b41a0fac5001032000b02402003102e2202450d0002402001280214280208200720022003101741026a220641024b0d0020060e03030002030b41a0fac5001032000b200341011037000b2001410c6a4100360200200441186a2002200310a803410421052004200141046a36023c200441186a2004413c6a10c8012003450d010b2002102a0b20002005360200200441c0006a24000f0b41b698c40041f4031050000b41b698c40041f4031050000b1036000bc20103017f017e017f410021042001410c6a4100360200200128020029031021050240024002400240200141086a28020022064108490d00200128020421060c010b200641017422044108200441084b1b22044100480d020240024020060d002004102821060c010b200128020420062004102c21060b2006450d0120012006360204200141086a20043602002001410c6a28020021040b2001410c6a200441086a360200200620046a2005370000200041043602000f0b200441011037000b1031000bdc0102027f027e410021042001410c6a4100360200200128020028021828024022054180016a2903002106200529037821070240024002400240200141086a28020022054110490d00200128020421050c010b200541017422044110200441104b1b22044100480d020240024020050d002004102821050c010b200128020420052004102c21050b2005450d0120012005360204200141086a20043602002001410c6a28020021040b2001410c6a200441106a360200200520046a2201200637000820012007370000200041043602000f0b200441011037000b1031000bb20803027f047e027f230041e0046b2204240002400240024002400240024002402003450d0020022802000d0020034101460d0120022802100d0120022802042105200441286a20012802102903484200200241146a2802002202ad4200109f0520012802182203420020032903082206427f200429032820042903304200521b7d2207200720065622031b3703080240024020030d002002417f4c0d0402400240024020020d004101210302402001280214280208200541014100101741026a220541024b0d0020050e03040002040b41a0fac5001032000b02402002102e2203450d0002402001280214280208200520032002101741026a220541024b0d0020050e03030002030b41a0fac5001032000b200241011037000b2004200236023c20042003360238200441d0036a200441386a108101024020042802d00322054113460d00200441c8026a200441d0036a410472418401109a051a02402002450d002003102a0b200441c0016a200441c8026a418401109a051a20042005360238200441386a410472200441c0016a418401109a051a200441003602d803200442013703d003200441386a200441d0036a10eb0120042802d8032103024020042802d403450d0020042802d003102a0b200128021822022903102206200241186a2903002207844200510d07200441186a2003ad42004280c8afa0254200109f05200441086a200429031822084280a094a58d1d7c2209200441186a41086a2903002009200854ad7c2006200710a00520024200200229030822062004290308427f200441086a41086a290300501b7d220720072006561b37030820072006580d03200441386a106a0c020b2002450d010b2003102a0b410521020c070b20012802002102200441c8026a200441386a418801109a051a200441c0016a41086a2002280218220241d8006a290000370300200441d0016a2203200241e0006a290000370300200441d8016a2205200241e8006a290000370300200420022900503703c001200441d7036a200441c8026a418801109a051a02402002413c6a2802002201200241386a280200470d00200141016a220a2001490d062001410174220b200a200b200a4b1b220aad42b0017e2206422088a70d062006a7220b4100480d060240024020010d00200b102821010c010b2002280234200141b0016c200b102c21010b2001450d0520022001360234200241386a200a360200200228023c21010b2002280234200141b0016c6a220141013a0000200120042903c001370001200141096a200441c8016a290300370000200141116a2003290300370000200141196a2005290300370000200141216a200441d0036a418f01109a051a2002200228023c41016a36023c410421020c060b41b698c40041f4031050000b41b698c40041f4031050000b1036000b419cb7c0001032000b200b41081037000b1031000b20002002360200200441e0046a24000b8c1705087f027e037f027e047f230041a0026b22042400024002400240024002400240024002400240024002400240024002402003450d0020022802000d0020034101460d0120022802100d0120034102460d0220022802200d0220034103460d0320022802300d0320034104460d0420022802400d0420034105460d0520022802500d0520034106460d0620022802600d0620034107460d0720022802700d0720022802042103200241246a2802002105200241346a2802002106200241c4006a2802002107200241d4006a2802002108200241e4006a2802002109200241f4006a280200210a200441206a20012802102903484200200241146a280200220bad4200109f052001280218220242002002290308220c427f200429032020042903284200521b7d220d200d200c5622021b3703080240024020020d00200b417f4c0d0a024002400240200b0d004101210e02402001280214280208200341014100101741026a220241024b0d00200141146a210f20020e03040002040b41a0fac5001032000b0240200b102e220e450d00024020012802142802082003200e200b101741026a220241024b0d00200141146a210f20020e03030002030b41a0fac5001032000b200b41011037000b41002102200441003a00f00102400340200b2002460d01200441d0016a20026a200e20026a2d00003a00002004200241016a22033a00f0012003210220034120470d000b20044180026a41086a2202200441d0016a41086a29030037030020044180026a41106a2203200441d0016a41106a29030037030020044180026a41186a2210200441d0016a41186a290300370300200420042903d001370380020240200b450d00200e102a0b200441306a41086a2002290300370300200441306a41106a2003290300370300200441306a41186a20102903003703002004200429038002370330200441106a200128021029034842002006ad4200109f052001280218220242002002290308220c427f200429031020042903184200521b7d220d200d200c5622021b3703082002450d030c100b0240200241ff0171450d00200441003a00f0010b200b450d010b200e102a0b200441f0006a41186a20044180026a41186a290300370300200441f0006a41106a20044180026a41106a290300370300200441f0006a41086a20044180026a41086a2903003703002004200429038002370370410521020c0e0b2006417f4c0d080240024002400240024020060d004101210b0240200f280200280208200541014100101741026a220241024b0d0020020e03120002120b41a0fac5001032000b02402006102e220b450d000240200f2802002802082005200b2006101741026a220241024b0d0020020e03030002030b41a0fac5001032000b200641011037000b41002102200441003a00f0010240034020062002460d01200441d0016a20026a200b20026a2d00003a00002004200241016a22033a00f0012003210220034120470d000b20044180026a41086a2202200441d0016a41086a29030037030020044180026a41106a2203200441d0016a41106a29030037030020044180026a41186a220e200441d0016a41186a290300370300200420042903d0013703800202402006450d00200b102a0b200441d0006a41086a2002290300370300200441d0006a41106a2003290300370300200441d0006a41186a200e29030037030020042004290380023703502004200128021029034842002008ad4200109f052001280218220242002002290308220c427f200429030020042903084200521b7d220d200d200c5622031b3703084105210220030d112008417f4c0d0c20080d03200f280200280208200741014100101741026a220341024b0d0220030e03110211110b0240200241ff0171450d00200441003a00f0010b2006450d0f0b200b102a410521020c0f0b41a0fac5001032000b024002400240024002402008102e2203450d000240200f280200280208200720032008101741026a220b41024b0d00200b0e03030002030b41a0fac5001032000b200841011037000b2008410f4d0d00200341086a2900002111200329000021122003102a024002400240200a0d00410121064100210b4100210e0c010b20044180026a41186a210320044180026a41106a210520044180026a41086a210841002110410021024100210b4100210e4101210603402003420037030020054200370300200842003703002001280218220742002007290308220d427f2001280210290348220c420586200c42ffffffffffffffff0783200c521b7d220c200c200d5622071b370308200442003703800220070d1102400240200f280200280208200920026a221320044180026a4120101741026a220741024b0d0020070e03130001130b41a0fac5001032000b200441d0016a41186a22142003290300370300200441d0016a41106a22152005290300370300200441d0016a41086a2216200829030037030020042004290380023703d0010240200b200e470d002010200b41016a220e2010200e4b1b220e41ffffff3f71200e470d03200e41057422074100480d0302400240200b0d002007102821060c010b200620022007102c21060b2006450d100b200620026a220720042903d001370000200741186a2014290300370000200741106a2015290300370000200741086a2016290300370000201341206a2013490d11201041026a2110200241206a2102200a200b41016a220b470d000b0b2001280200280218210320044190016a41086a200441306a41086a29030037030020044190016a41106a2201200441306a41106a29030037030020044190016a41186a2205200441306a41186a290300370300200441b0016a41086a200341d8006a290000370300200441b0016a41106a2208200341e0006a290000370300200441b0016a41186a2207200341e8006a2900003703002004200429033037039001200420032900503703b00120044180026a41186a220a200441d0006a41186a29030037030020044180026a41106a2209200441d0006a41106a29030037030020044180026a41086a200441d0006a41086a29030037030020042004290350370380022003413c6a2802002202200341386a280200470d03200241016a220f2002490d0020024101742210200f2010200f4b1b220fad42b0017e220c422088a70d00200ca7221041004e0d020b1031000b2003102a0c0f0b0240024020020d002010102821020c010b2003280234200241b0016c2010102c21020b2002450d0b20032002360234200341386a200f360200200328023c21020b2003280234200241b0016c6a220241023a0000200220042903b0013700012002200429039001370021200241096a200441b0016a41086a290300370000200241116a2008290300370000200241196a2007290300370000200241296a20044190016a41086a290300370000200241316a2001290300370000200241396a2005290300370000200220063600642002200e3600682002200b36006c20022012370370200241f8006a20113703002002200429038002370041200241c9006a20044180026a41086a290300370000200241d1006a2009290300370000200241d9006a200a290300370000200220042f00703b0061200241e3006a200441f0006a41026a2d00003a0000200220042903d0013703800120024188016a200441d0016a41086a29030037030020024190016a200441d0016a41106a29030037030020024198016a200441d0016a41186a290300370300200241a0016a200441f0016a290300370300200241a8016a200441f8016a2903003703002003200328023c41016a36023c410421020c0d0b41b698c40041f4031050000b41b698c40041f4031050000b41b698c40041f4031050000b41b698c40041f4031050000b41b698c40041f4031050000b41b698c40041f4031050000b41b698c40041f4031050000b41b698c40041f4031050000b1036000b200741011037000b201041081037000b41052102200e450d012006102a0c010b410521020b20002002360200200441a0026a24000b16002000410036020020002001410c6a2802003602040bab0202057f027e230041106b220424000240024002402003450d0020022802000d0020034101460d0120022802100d0120034102460d0220022802200d024105210302402001410c6a2802002205200241146a2802002206490d00200520066b200241246a2802002205470d0020022802042107200128020421082004200128021029035042002005ad4200109f0520012802182202420020022903082209427f200429030020042903084200521b7d220a200a20095622021b37030820020d000240024020012802142802082007200820066a2005101841026a220241024b0d0020020e03020001020b41b0fbc5001032000b410421030b20002003360200200441106a24000f0b41b698c40041f4031050000b41b698c40041f4031050000b41b698c40041f4031050000bf90303027f027e067f230041106b2204240002400240024002402003450d0020022802000d0020034101460d0120022802100d0120022802042105200420012802102903484200200241146a2802002203ad4200109f0520012802182202420020022903082206427f200429030020042903084200521b7d2207200720065622021b37030841052108024020020d000240024020032001410c6a2209280200220a4b0d00200321020c010b02400240200141086a2802002202200a6b2003200a6b220b490d002001280204210c200a21020c010b200a200b6a220c200a490d062002410174220d200c200d200c4b1b220d4100480d060240024020020d00200d1028210c0c010b20012802042002200d102c210c0b200c450d052001200c360204200141086a200d3602002001410c6a28020021020b200c20026a210d02400240200b4102490d00200d41002003200a417f73220a6a220b1099051a200c200320026a200a6a6a210d200b20026a21020c010b200b450d010b200d41003a0000200241016a21020b20092002360200024002402001280214280208200520012802042002101741026a220141024b0d0020010e03020001020b41a0fac5001032000b410421080b20002008360200200441106a24000f0b41b698c40041f4031050000b41b698c40041f4031050000b200d41011037000b1031000bbb0b05047f027e037f017e037f230041e0016b2204240002400240024002400240024002400240024002402003450d0020022802000d0020034101460d0120022802100d0120034102460d0220022802200d0220034103460d0320022802300d03200241246a2802002105200241346a280200210602400240024002400240200241146a2802002203450d0020022802042107200441306a200128021029034842002003ad4200109f0520012802182202420020022903082208427f200429033020042903384200521b7d22092009200856220a1b37030841052102200a0d0e2003417f4c0d092003102e220a450d0a024020012802142802082007200a2003101741026a220741024b0d0020070e03040002040b41a0fac5001032000b4101210b410021074100210c0c010b2004200336028c012004200a36028801200441c0006a20044188016a106d200429024421082004280240210b200a102a200b450d0c2008a7210c200128021028025c2008422088a72207490d0b0b200b2007410041202007676b10c402024020074102490d00200b21022007210303402002200241206a220a4120109c05450d0c200a21022003417f6a220341024f0d000b0b200441206a200128021029034842002006ad220d4200109f0520012802182202420020022903082208427f200429032020042903284200521b7d2209200920085622021b37030820020d0a2006417f4c0d060240024020060d004101210a02402001280214280208200541014100101741026a220241024b0d0020020e030d00020d0b41a0fac5001032000b024002402006102e220a450d00024020012802142802082005200a2006101741026a220241024b0d0020020e03020003020b41a0fac5001032000b200641011037000b200a102a0c0b0b20042001280210220329032842002007ad4200109f05200441106a20032903204200200d4200109f0520012802182102427f2109024020042903184200520d0020042903084200520d002004290310220820042903007c220d2008540d00427f200d20032903307c22082008200d541b21090b200242002002290308220820097d220920092008561b37030820092008580d012006450d0a200a102a0c0a0b200a102a0c0a0b200441b8016a41086a22052001280200280218220341d8006a290000370300200441b8016a41106a2201200341e0006a290000370300200441b8016a41186a220e200341e8006a290000370300200420032900503703b80102402003413c6a2802002202200341386a280200470d00200241016a220f2002490d0820024101742210200f2010200f4b1b2210ad42b0017e2208422088a70d082008a7220f4100480d080240024020020d00200f102821020c010b2003280234200241b0016c200f102c21020b2002450d0720032002360234200341386a2010360200200328023c21020b2003280234200241b0016c6a220241003a0000200220042f00dd013b0001200241053a00102002200736000c2002200c3600082002200b360004200220042903b801370011200241036a200441dd016a41026a2d00003a0000200241196a2005290300370000200241216a2001290300370000200241296a200e2903003700002002200a360034200220063600382002200636003c200220042f00b5013b0031200241336a200441b5016a41026a2d00003a00002002200429038801370340200241c8006a20044188016a41086a290300370300200241d0006a20044188016a41106a290300370300200241d8006a20044188016a41186a290300370300200241e0006a200441a8016a290300370300200241e8006a200441c0006a41c800109a051a2003200328023c41016a36023c410421020c090b41b698c40041f4031050000b41b698c40041f4031050000b41b698c40041f4031050000b41b698c40041f4031050000b1036000b200341011037000b200f41081037000b1031000b41052102200c450d00200b102a0b20002002360200200441e0016a24000b8e0a03027f027e057f230041e00b6b220424000240024002400240024002402003450d0020022802000d0020034101460d0120022802100d0120022802042105200420012802102903484200200241146a2802002202ad4200109f0520012802182203420020032903082206427f200429030020042903084200521b7d2207200720065622081b3703084105210320080d052002417f4c0d02024020020d0002402001280214280208200541014100101741026a220241024b0d0020020e03070007070b41a0fac5001032000b02400240024002402002102e2208450d0002402001280214280208200520082002101741026a220541024b0d0020050e03030002030b41a0fac5001032000b200241011037000b2002410f4b0d010b2008102a0c060b200841086a2900002106200829000021072008102a200128020028021822092802180d032009417f360218200441c8006a200941e8006a290000370300200441c0006a200941e0006a290000370300200441306a41086a200941d8006a29000037030020042009290050370330024002402009411c6a220a280200220841f8b9c000460d00200941206a280200210b0c010b4100210b20044180096a410041e0021099051a200441e0006a410041a0081099051a41880b10282208450d05200841003b010620084100360200200841086a20044180096a41e002109a051a200841e8026a200441e0006a41a008109a051a200941206a41003602002009200836021c0b02400240034020082f0106220c4105742105410021024100210102400240034020052002460d01200441306a200820026a41086a4120109c052203450d02200241206a2102200141016a21012003417f4a0d000b2001417f6a210c0b200b450d02200b417f6a210b2008200c4102746a41880b6a28020021080c010b0b200941246a2103410121020c010b200441106a41186a200441306a41186a290300370300200441106a41106a200441306a41106a290300370300200441106a41086a200441306a41086a29030037030020042004290330370310200941246a21034100210b200c2101410021020b0240024020020d002004419c096a200441106a41086a290300370200200441a4096a200441106a41106a290300370200200441ac096a200441106a41186a29030037020020042003360290092004200136028c092004200a3602880920042008360284092004200b36028009200420042903103702940920044180016a200429035037030020044188016a200441d0006a41086a29030037030020044194016a42003702002004420037037820044200370360200441f8b9c00036029001200441003a009c012004419d016a2004290030370000200441a5016a200441306a41086a290000370000200441ad016a200441306a41106a290000370000200441b5016a200441306a41186a290000370000200441003a00bd0120044180096a200441e0006a10b70121020c010b200441f8006a4200370300200441f4006a41f8b9c00036020020044100360280012004410036027020044200370368200441f8b9c000360264200441003602602008200141e0006c6a41e8026a2102200441e0006a1095010b200241286a2006370300200241206a2007370300200242013703182009200928021841016a360218410421030c050b41b698c40041f4031050000b41b698c40041f4031050000b1036000b41a8b8c0004110200441e0006a41d0b8c0001038000b41880b41081037000b20002003360200200441e00b6a24000ba30203037f027e027f230041206b220424002001410c6a22054100360200200441086a2001280200280218220641186a200641d0006a10a801200441086a41106a290300210720042802082106200429031021080240024002400240200141086a2802002209200528020022056b4110490d00200128020421090c010b200541106a220a2005490d0220094101742205200a2005200a4b1b22054100480d020240024020090d002005102821090c010b200128020420092005102c21090b2009450d0120012009360204200141086a20053602002001410c6a28020021050b2001410c6a200541106a360200200920056a22012007427f20061b37000820012008427f20061b37000020004104360200200441206a24000f0b200541011037000b1031000bee0203027f027e017f230041206b220424000240024002402003450d0020022802000d0020034101460d0120022802100d0120022802042105200420012802102903484200200241146a2802002202ad4200109f0520012802182203420020032903082206427f200429030020042903084200521b7d2207200720065622081b37030841052103024020080d002002417f4c0d0302400240024020020d004101210802402001280214280208200541014100101741026a220141024b0d0020010e03040002040b41a0fac5001032000b02402002102e2208450d0002402001280214280208200520082002101741026a220141024b0d0020010e03030002030b41a0fac5001032000b200241011037000b200441106a200820021054024020042802100d002004280214200441186a280200100b0b410421032002450d010b2008102a0b20002003360200200441206a24000f0b41b698c40041f4031050000b41b698c40041f4031050000b1036000bbe0101037f410021042001410c6a4100360200200128020028021c21050240024002400240200141086a28020022064104490d00200128020421060c010b200641017422044104200441044b1b22044100480d020240024020060d002004102821060c010b200128020420062004102c21060b2006450d0120012006360204200141086a20043602002001410c6a28020021040b2001410c6a200441046a360200200620046a2005360000200041043602000f0b200441011037000b1031000bc205020a7f017e230041c0006b220424002004200136020c20042000410120011b3602082004200441086a106c024020042802000d000240024002400240024002400240200428020c22014170712200417f4c0d002004280204210502400240200141047622060d00410821070c010b200010282207450d020b02402005450d00200441206a4104722108410021094100210a410021000340200441206a200441086a109803200441306a41086a220b200841086a2802003602002004200829020037033002402004280220220c4104470d002006450d0a2007102a0c0a0b200041016a2101200441106a41086a220d200b28020036020020042004290330370310024020002006470d0020092001200920014b1b220641ffffffff00712006470d062006410474220b4100480d060240024020000d00200b102821070c010b2007200a200b102c21070b2007450d050b2007200a6a2200200c360200200041046a20042903103702002000410c6a200d280200360200200941026a2109200a41106a210a2001210020052001470d000b0b2007450d07200441206a200220072005200311060020042802202100410110282201450d042004428180808010370234200420013602300240024020004105460d00200141003a0000200141014102102c2101024020004104470d002001450d08200141003a00012004428280808020370234200420013602304202210e0c020b2001450d08200141013a0001200442828080802037023420042001360230200441206a200441306a1099032004350238210e200428023021010c010b200141013a00004201210e0b2001ad422086200e84210e02402006450d002007102a0b200441c0006a2400200e0f0b1036000b200041081037000b200b41081037000b1031000b410141011037000b410241011037000b410241011037000b41b8c6c20041f000200441206a41c0c5c2001038000bde0202047f017e02400240024002400240024020012802042202450d00200128020022032d0000210420012002417f6a22053602042001200341016a3602002004417f6a220441034b0d0520040e0401020304010b200041043602000f0b0240200541034b0d00200041043602000f0b200041003602002003280001210420012002417b6a3602042001200341056a360200200020043602040f0b024020054108490d0020004101360200200329000121062001200241776a3602042001200341096a360200200041086a20063703000f0b200041043602000f0b0240200541034b0d00200041043602000f0b200041023602002003280001210420012002417b6a3602042001200341056a360200200020043602040f0b024020054108490d0020004103360200200329000121062001200241776a3602042001200341096a360200200041086a20063703000f0b200041043602000f0b200041043602000b840b02037f017e024002400240024002400240024002400240024002400240024020002802000e0400010203000b02400240200141046a280200200141086a2802002202460d00200128020021030c010b200241016a22032002490d0c200241017422042003200420034b1b22044100480d0c0240024020020d002004102821030c010b200128020020022004102c21030b2003450d0420012003360200200141046a2004360200200141086a28020021020b200141086a2204200241016a360200200320026a41013a00002000280204210302400240200141046a2802002202200428020022006b4104490d00200128020021020c010b200041046a22042000490d0c200241017422002004200020044b1b22004100480d0c0240024020020d002000102821020c010b200128020020022000102c21020b2002450d0520012002360200200141046a2000360200200141086a28020021000b200141086a200041046a360200200220006a20033600000f0b02400240200141046a280200200141086a2802002202460d00200128020021030c010b200241016a22032002490d0b200241017422042003200420034b1b22044100480d0b0240024020020d002004102821030c010b200128020020022004102c21030b2003450d0520012003360200200141046a2004360200200141086a28020021020b200141086a2204200241016a360200200320026a41023a00002000290308210502400240200141046a2802002202200428020022006b4108490d00200128020021020c010b200041086a22032000490d0b200241017422002003200020034b1b22004100480d0b0240024020020d002000102821020c010b200128020020022000102c21020b2002450d0620012002360200200141046a2000360200200141086a28020021000b200141086a200041086a360200200220006a20053700000f0b02400240200141046a280200200141086a2802002202460d00200128020021030c010b200241016a22032002490d0a200241017422042003200420034b1b22044100480d0a0240024020020d002004102821030c010b200128020020022004102c21030b2003450d0620012003360200200141046a2004360200200141086a28020021020b200141086a2204200241016a360200200320026a41033a00002000280204210302400240200141046a2802002202200428020022006b4104490d00200128020021020c010b200041046a22042000490d0a200241017422002004200020044b1b22004100480d0a0240024020020d002000102821020c010b200128020020022000102c21020b2002450d0720012002360200200141046a2000360200200141086a28020021000b200141086a200041046a360200200220006a20033600000f0b02400240200141046a280200200141086a2802002202460d00200128020021030c010b200241016a22032002490d09200241017422042003200420034b1b22044100480d090240024020020d002004102821030c010b200128020020022004102c21030b2003450d0720012003360200200141046a2004360200200141086a28020021020b200141086a2204200241016a360200200320026a41043a00002000290308210502400240200141046a2802002202200428020022006b4108490d00200128020021020c010b200041086a22032000490d09200241017422002003200020034b1b22004100480d090240024020020d002000102821020c010b200128020020022000102c21020b2002450d0820012002360200200141046a2000360200200141086a28020021000b200141086a200041086a360200200220006a20053700000f0b200441011037000b200041011037000b200441011037000b200041011037000b200441011037000b200041011037000b200441011037000b200041011037000b1031000bfd0201057f230041d0006b220224002002410036022820014110200241286a10062103024002400240024020022802282204417f460d0020030d010b200041023a00000c010b2004450d0120032d0000220541014b0d01410021010240024020050e020100010b41002101200241003a00482004417f6a2105200341016a21060340024020052001470d00200141ff0171450d04200241003a00480c040b200241286a20016a200620016a2d00003a00002002200141016a22043a00482004210120044120470d000b200241086a41186a200241286a41186a290300370300200241086a41106a200241286a41106a290300370300200241086a41086a200241286a41086a29030037030020022002290328370308410121010b200020013a000020002002290308370001200041096a200241106a290300370000200041116a200241186a290300370000200041196a200241206a2903003700002003102a0b200241d0006a24000f0b41c4d1c3004133200241286a419cd9c3001038000b1300200041013602042000418cc8c2003602000b340020004195c9c20036020420004100360200200041146a4103360200200041106a41a0c9c200360200200041086a420a3702000b2f01017f02404101102822020d00410141011037000b200042818080801037020420002002360200200241003a00000b8b5606077f017e067f027e037f037e230041e0036b22012400200141d8006a41086a220242003703002001420037035841e7fcc5004110200141d8006a100820014190016a41086a20022903003703002001200129035837039001200141e8026a20014190016a109a0302400240024002400240024002400240024002400240024020012d00e80222024102470d00200141d8006a21030c010b20014190016a4110100920014188026a41086a200141f1026a29000037030020014188026a41106a200141e8026a41116a29000037030020014188026a41186a220420014181036a290000370300200120012900e90237038802200141d8006a21030240200241037122024103460d0020020e03010001010b200141a0016a41186a2004290300370300200141a0016a41106a20014188026a41106a290300370300200141a0016a41086a20014188026a41086a29030037030020012001290388023703a001200141d8006a41086a220242003703002001420037035841c0fcc5004111200141d8006a100820014190016a41086a2002290300370300200120012903583703900141002105200141003602e80220014190016a4110200141e8026a10062102024020012802e8022204417f460d002002450d0020044104490d02200228000021052002102a0b411610282202450d022002410e6a41002900dffc45370000200241086a41002900d9fc45370000200241002900d1fc4537000020024116412c102c2202450d0320022005360016200141d8006a41186a22044200370300200141d8006a41106a22064200370300200141d8006a41086a22074200370300200142003703582002411a200141d8006a1000200141e8026a41186a2004290300370300200141e8026a41106a2006290300370300200141e8026a41086a2007290300370300200120012903583703e8022002102a20014100360258200141e8026a4120200141d8006a1006210202400240024020012802582206417f460d002002450d0020012006360294012001200236029001200141d8006a20014190016a107320012802582204450d07200129025c210802402006450d002002102a0b200120043602782001200837027c2008a721022008422088a72206418002490d01412010282206450d08200620012903a001370000200641186a200141a0016a41186a290300370000200641106a200141a0016a41106a290300370000200641086a200141a0016a41086a29030037000020014281808080103702ec02200120063602e802200541016a2205200141e8026a109f032006102a200141d8006a41086a220642003703002001420037035841c0fcc5004111200141d8006a100820014190016a41086a20062903003703002001200129035837039001200120053602e80220014190016a4110200141e8026a410410070c020b4100210620014100360280012001420137037841012104410021020b200141e8026a41186a2209200141a0016a41186a290300370300200141e8026a41106a220a200141a0016a41106a290300370300200141e8026a41086a220b200141a0016a41086a290300370300200120012903a0013703e802024020062002470d00200241016a22072002490d0c2002410174220c2007200c20074b1b220741ffffff3f712007470d0c2007410574220c4100480d0c0240024020020d00200c102821040c010b20042002410574200c102c21040b2004450d082001200736027c20012004360278200721020b200420064105746a220720012903e802370000200741186a2009290300370000200741106a200a290300370000200741086a200b2903003700002001200641016a360280012005200141f8006a109f030b2002450d002004102a0b200141d8006a41086a220242003703002001420037035841d8a1c6004113200141d8006a1008200141e8026a41086a2002290300370300200120012903583703e802200141003602a001200141e8026a4110200141a0016a1006210202400240024020012802a0012204417f460d002002450d002004450d0120022d000021042002102a200141e8026a4110100920044102460d0020044101710d020b41c0acc3001032000b41c4d1c3004133200141d8036a419cd9c3001038000b200141d8006a41086a220242003703002001420037035841afc5c2004111200141d8006a100820014190016a41086a22042002290300370300200120012903583703900120014190016a41101009200242003703002001420037035841c8fbc5004117200141d8006a100820042002290300370300200120012903583703900120014190016a41101009200242003703002001420037035841feadc4004117200141d8006a1008200141e8026a41086a22042002290300370300200120012903583703e8020240200141e8026a41104101410041001003417f470d0010a0032108200242003703002001420037035841feadc4004117200141d8006a100820042002290300370300200120012903583703e802200120083703a001200141e8026a4110200141a0016a410810070b2002420037030020014200370358418194c1004110200141d8006a1008200141a0016a41086a2002290300370300200120012903583703a001200141003602e802200141a0016a4110200141e8026a1006210220012802e8022204417f460d072002450d0720044104490d062002280000210d2002102a200141a0016a41101009410121090c080b41c4d1c3004133200141d8036a419cd9c3001038000b411641011037000b412c41011037000b41c4d1c3004133200141d8036a419cd9c3001038000b412041011037000b200c41011037000b41c4d1c3004133200141d8036a419cd9c3001038000b410021090b200141d8006a41086a220242003703002001420037035841d591c6004115200141d8006a1008200141a0016a41086a2002290300370300200120012903583703a001200141003602e802200141a0016a4110200141e8026a10062102024002400240024002400240024002400240024002400240024020012802e8022204417f460d002002450d002004450d0b20022d000021042002102a20044102460d0020044101710d010b410410282204450d0120044100360200200141d8006a41086a2202420037030020014200370358419194c1004115200141d8006a1008200141a0016a41086a2002290300370300200120012903583703a001200141003602f002200142013703e8024101200141e8026a10b401200428020021070240024020012802ec02220520012802f00222066b4104490d0020012802e80221020c010b200641046a22022006490d0d2005410174220a2002200a20024b1b220a4100480d0d0240024020050d00200a102821020c010b20012802e8022005200a102c21020b2002450d032001200a3602ec02200120023602e802200a21050b2001200641046a220a3602f002200220066a2007360000200141a0016a41102002200a100702402005450d002002102a0b2004102a410410282204450d0320044100360200200141d8006a41086a2202420037030020014200370358418898c1004116200141d8006a1008200141a0016a41086a2002290300370300200120012903583703a001200141003602f002200142013703e8024101200141e8026a10b401200428020021070240024020012802ec02220520012802f00222066b4104490d0020012802e80221020c010b200641046a22022006490d0d2005410174220a2002200a20024b1b220a4100480d0d0240024020050d00200a102821020c010b20012802e8022005200a102c21020b2002450d052001200a3602ec02200120023602e802200a21050b2001200641046a220a3602f002200220066a2007360000200141a0016a41102002200a100702402005450d002002102a0b2004102a200141d8006a41086a2202420037030020014200370358419e98c1004110200141d8006a1008200141a0016a41086a22042002290300370300200120012903583703a001200141003602e802200141a0016a4110200141e8026a41041007200141013a00e802200242003703002001420037035841d591c6004115200141d8006a100820042002290300370300200120012903583703a001200141a0016a4110200141e8026a410110070b200141d8006a41086a2202420037030020014200370358419194c1004115200141d8006a1008200141a0016a41086a2002290300370300200120012903583703a001200141003602e802200141a0016a4110200141e8026a100621020240024020012802e8022204417f460d002002450d002001200436028c022001200236028802200141e8026a20014188026a10820120012802e802220e450d0620012902ec02210f2004450d012002102a0c010b4104210e4200210f0b200141d8006a41086a2202420037030020014200370358418898c1004116200141d8006a1008200141a0016a41086a2002290300370300200120012903583703a001200141003602e802200141a0016a4110200141e8026a100621020240024020012802e8022204417f460d002002450d002001200436028c022001200236028802200141e8026a20014188026a10820120012802e8022207450d0720012902ec02211002402004450d002002102a0b20012007360288022010422088a7210c0c010b4104210720014104360288024100210c420021100b200f422088a72111024020090d002011417f6a220220114f0d07200220114b0d07200e20024102746a280200210d0b41002011419c7f6a22022002201141016a4b1b221220114b0d07200e20124102746a21132012450d0a200cad2108200e210b0340200b2802002109024002400240024002402008a7220a41014b0d0041002102200a0e020201020b41002102200a2104034020022004410176220620026a22052009200720054102746a280200491b2102200420066b220441014b0d000b0b20092007200241027422046a2802002206460d022002200920064b6a21020c010b410021020b200120023602e80241d498c100412e200141e8026a418499c1001038000b20082002ad580d09200720046a2204200441046a2002417f73200a6a410274109b051a201042ffffffff0f83200a417f6a220cad422086842110200b41046a220b2013460d0b2008427f7c210820012802880221070c000b0b410441041037000b200a41011037000b410441041037000b200a41011037000b41c4d1c3004133200141d8036a419cd9c3001038000b41c4d1c3004133200141d8036a419cd9c3001038000b41ae98c10041261050000b41e4e8c5001032000b41b0b1c0001032000b41c4d1c3004133200141d8036a419cd9c3001038000b200f42ffffffff0f8321080240201120126b2202450d0002402012450d00200e20132002410274109b051a2010422088a7210c0b20082002ad4220868421080b2001280288022107410021020240024002400240024002400240024002400240024002400240024002400240024002400240024002400240200c41014b0d00200c0e020201020b200c2104034020022004410176220620026a2205200d200720054102746a280200491b2102200420066b220441014b0d000b0b0240200d200720024102746a2802002204460d002002200d20044b6a21020b200c2002490d010b200c2010a7470d02200c41016a2204200c490d13200c41017422062004200620044b1b220441ffffffff03712004470d132004410274220641004e0d010c130b41f8b0c0001032000b02400240200c0d002006102821070c010b2007200c4102742006102c21070b2007450d0120012007360288022004ad21100b200720024102746a220441046a2004200c20026b410274109b051a2004200d36020002402008422088220fa722042008a7470d00200441016a22022004490d11200fa722054101742206200220022006491b220241ffffffff03712002470d11200241027422064100480d110240024020040d0020061028210e0c010b200e20054102742006102c210e0b200e450d022008422088a721042002ad21080b200e20044102746a200d3602000240200c41016a22130d00419499c1001032000b2013201341017622024d0d02200128028802220620024102746a280200210d024020134101710d0020132002417f6a22024d0d04200620024102746a280200200d6a410176210d0b200141d8006a41086a2202420037030020014200370358419194c1004115200141d8006a1008200141a0016a41086a2002290300370300200120012903583703a001200141003602f002200142013703e802200441016a2211200141e8026a10b4010240024020110d0020012802f002210920012802ec02210720012802e80221040c010b410020012802f00222026b2106200441027441046a210a20012802ec022107200e210503402005280200210b02400240200720066a4104490d0020012802e80221040c010b200241046a22042002490d13200741017422092004200920044b1b22094100480d130240024020070d002009102821040c010b20012802e80220072009102c21040b2004450d07200120093602ec02200120043602e802200921070b200541046a21052001200241046a22093602f002200420026a200b3600002006417c6a210620092102200a417c6a220a0d000b0b2008a72102200141a0016a411020042009100702402007450d002004102a0b02402002450d00200e102a0b200128028802210e200141d8006a41086a2202420037030020014200370358418898c1004116200141d8006a1008200141a0016a41086a2002290300370300200120012903583703a001200142013703e802200141003602f0022013200141e8026a10b401200c41027441046a2109410020012802f00222026b21062010a7210c20012802ec022107200e210503402005280200210b02400240200720066a4104490d0020012802e80221040c010b200241046a22042002490d122007410174220a2004200a20044b1b220a4100480d120240024020070d00200a102821040c010b20012802e8022007200a102c21040b2004450d072001200a3602ec02200120043602e802200a21070b200541046a21052001200241046a220a3602f002200420026a200b3600002006417c6a2106200a21022009417c6a22090d000b200141a0016a41102004200a100702402007450d002004102a0b0240200c450d00200e102a0b200141d8006a41086a2202420037030020014200370358419e98c1004110200141d8006a1008200141a0016a41086a2002290300370300200120012903583703a0012001200d3602e802200141a0016a4110200141e8026a410410070240201141e500470d00200d419a086a1098014b0d00200141d8006a41086a220442003703002001420037035841d985c2004117200141d8006a1008200141e8026a41086a2004290300370300200120012903583703e802410810282204450d072004200d360004200441e400360000200141e8026a41102004410810072004102a0b200242003703002001420037035841f9b5c200411d200141d8006a1008200141e8026a41086a2002290300370300200120012903583703e802200141003602a001200141e8026a4110200141a0016a10062102024020012802a0012204417f460d002002450d0020012002360288022001200436028c0220044104490d0c2001200241046a3602880220012004417c6a220636028c0220064104490d0c200228000021072001200441786a36028c022001200241086a360288022002280004210b200141a0016a20014188026a107720012802a001220a450d0c20012902a40121144100210502400240200128028c0222040d000c010b20012004417f6a220936028c022001200128028802220641016a36028802024020062d00004101460d000c010b20094104490d0020012004417b6a36028c022001200641056a360288022006280001210c410121050b2002102a2014422088a72109024020072000470d00024020050d002009ad42287e2208422088a70d0a2008a72202417f4c0d0a0240024020020d004108210c0c010b20021028220c450d0c0b4100210602402009450d00200941286c210541002106200c2102200a21040340200441086a2903002108200441106a2903002110200441186a290300210f20042903002115200241206a200441206a290300370300200241186a200f370300200241106a2010370300200241086a200837030020022015370300200241286a2102200641016a2106200441286a2104200541586a22050d000b0b200141b0016a200b360200200141a0016a410c6a2006360200200141a0016a41086a20093602002001200c3602a401200141003602a001200141e8026a200141a0016a10c30120014193026a200141e8026a41086a280200360000200120012903e80237008b02200141e8026a410c6a2001418f026a290000370000200141c6a4b9da043600e902200141023a00e80220012001290088023700ed02200141e8026a10ce012009450d01200c102a0c010b2009ad42287e2208422088a70d092008a72202417f4c0d090240024020020d00410821130c010b200210282213450d0c0b0240024020090d00410021060c010b200941286c21054100210620132102200a21040340200441086a2903002108200441106a2903002110200441186a290300210f20042903002115200241206a200441206a290300370300200241186a200f370300200241106a2010370300200241086a200837030020022015370300200241286a2102200641016a2106200441286a2104200541586a22050d000b0b200141b4016a200b360200200141b0016a2006360200200141a0016a410c6a2009360200200141a0016a41086a20133602002001200c3602a401200141013602a001200141e8026a200141a0016a10c30120014193026a200141e8026a41086a280200360000200120012903e80237008b02200141e8026a410c6a2001418f026a290000370000200141c6a4b9da043600e902200141023a00e80220012001290088023700ed02200141e8026a10ce012009450d002013102a0b2014a7210c0240200b20076a2000470d00200141d8006a41086a220242003703002001420037035841c694c600411b200141d8006a1008200141e8026a41086a2002290300370300200120012903583703e802200141003602a801200142013703a0012009200141a0016a10b40102402009450d00200a200941286c6a2107200a210403402004200141a0016a108f01200441206a29030021080240024020012802a401220620012802a80122026b4108490d0020012802a00121060c010b200241086a22052002490d15200641017422022005200220054b1b22024100480d150240024020060d002002102821060c010b20012802a00120062002102c21060b2006450d0f200120023602a401200120063602a00120012802a80121020b2001200241086a3602a801200620026a20083700002007200441286a2204470d000b0b20012802a4012102200141e8026a411020012802a001220420012802a801100702402002450d002004102a0b200141e8026a41106a2009360200200141f4026a200c360200200141e8026a41086a2202200a360200200141003602ec022001410a3a00e80241014100200141e8026a10cc01200141d8006a41086a220442003703002001420037035841f9b5c200411d200141d8006a100820022004290300370300200120012903583703e802200141e8026a411010090c010b200c450d00200a102a0b200141d8006a41086a22024200370300200142003703584196b6c2004115200141d8006a1008200141e8026a41086a2002290300370300200120012903583703e802200141003602a001200141e8026a4110200141a0016a1006210220012802a0012204417f460d0f2002450d0f2004450d0e20022d0000220641034b0d0e0240024020060e04010f0100010b2004417f6a41074b0d0d0c0f0b2002102a0c0f0b200641041037000b200641041037000b41ac99c100200220131034000b41ac99c100200220131034000b200941011037000b200a41011037000b410841011037000b1036000b200241081037000b200241081037000b200241011037000b41c4d1c3004133200141d8036a419cd9c3001038000b20022800052106200228000121042002102a024020042000470d00200141043602a001200120063602a401200141e8026a200141a0016a10c30120014193026a200141f0026a280200360000200120012903e80237008b02200141f4026a2001418f026a290000370000200141c6a4b9da043600e902200141023a00e80220012001290088023700ed02200141e8026a10ce010b200620046a2000470d022001410036028802200141d8006a41086a22024200370300200142003703584196b6c2004115200141d8006a1008200141e8026a41086a2002290300370300200120012903583703e802200141a0016a20014188026a10da02200141e8026a411020012802a001220220012802a8011007024020012802a401450d002002102a0b200141023602ec022001410a3a00e80241014100200141e8026a10cc010c020b2004417f6a4108490d0020022800052106200228000121042002102a024020042000470d00200141033602a001200120063602a401200141e8026a200141a0016a10c30120014193026a200141f0026a280200360000200120012903e80237008b02200141f4026a2001418f026a290000370000200141c6a4b9da043600e902200141023a00e80220012001290088023700ed02200141e8026a10ce010b200620046a2000470d012001410236028802200141d8006a41086a22024200370300200142003703584196b6c2004115200141d8006a1008200141e8026a41086a2002290300370300200120012903583703e802200141a0016a20014188026a10da02200141e8026a411020012802a001220220012802a8011007024020012802a401450d002002102a0b200141013602ec022001410a3a00e80241014100200141e8026a10cc010c010b41c4d1c3004133200141d8036a419cd9c3001038000b02400240024002400240024020004180e101700d00200141e8026a10d301200141c8006a200141e8026a1091012001200141c8006a41086a29030022083703800120012001290348221037037820014180036a2008370300200141e8026a41106a2010370300200141e8026a41086a220441013a00002001410b3a00e8024100210241014100200141e8026a10cc01200141003a008f012001420037039801200142003703900120044200370300200142003703e8024181a2c6004112200141e8026a1008200141a0016a41086a2004290300370300200120012903e8023703a001200141003602e802200141a0016a4110200141e8026a100621040240024020012802e8022206417f470d000c010b024020040d000c010b2001200636028c022001200436028802200141e8026a20014188026a10820120012802e8022202450d0620012902ec0221082006450d002004102a0b2002410420021b210c024002402008420020021b2214422088a722040d004100210b0c010b200141f1026a210d200141c8026a211320014188026a41206a210e200141a0016a41086a2109200141a0036a21114100210a4100210b41002102024003400240024002400240200b450d00200c20024102746a2106200c2002200a6a4102746a21050340200220044f0d02200141a0016a2006280200220710e90220012903a0014201520d0420014188026a200941e000109a051a2001290378220f200129038802221554200141f8006a41086a290300220820014188026a41086a29030022105420082010511b450d03200141013a008f010240200a20026a220720044f0d0020052006280200360200200641046a2106200541046a2105200241016a22022004490d010c070b0b41c4b2c000200720041034000b200c20024102746a21060340200220044f0d01200141a0016a2006280200220710e90220012903a0014201520d0320014188026a200941e000109a051a2001290378220f20012903880222155a200141f8006a41086a290300220820014188026a41086a29030022105a20082010511b0d02200641046a2106200141013a008f01200241016a22022004490d000b4100210b0c050b41e8b1c000200220041034000b2001200f20157d3703782001200820107d200f201554ad7d37038001411210282206450d05200641106a41002f008086423b0000200641086a41002900f88542370000200641002900f08542370000200641124124102c2206450d0620062007360012200341186a22054200370000200341106a22124200370000200341086a22004200370000200342003700002006411620031000200141e8026a41186a2005290000370300200141e8026a41106a2012290000370300200141e8026a41086a2000290000370300200120032900003703e8022006102a200141e8026a41201009200e20012903980220014188026a41186a29030010aa02200141386a201320012903880220014188026a41086a220629030010d00120014190016a41086a2205427f20052903002208200141386a41086a2903007c200129039001221020012903387c220f2010542205ad7c22102005201020085420102008511b22051b3703002001427f200f20051b37039001200129038802210820112006290300370300200d2013290000370000200d41086a201341086a290000370000200d41106a201341106a290000370000200d41186a201341186a2900003700002001200837039803200141023a00f0022001410b3a00e802200120073602940341014100200141e8026a10cc010b200a417f6a210a200b41016a210b200241016a22022004490d000b0b200b450d00200220044f0d00200c20024102746a2206200b4102746b2006200420026b410274109b051a0b200141e8026a41086a22024200370300200142003703e8024181a2c6004112200141e8026a1008200141a0016a41086a2002290300370300200120012903e8023703a00102400240200c0d00200141a0016a411010090c010b200141003602f002200142013703e8022004200b6b2204200141e8026a10b4010240024020040d0020012802f002210920012802ec02210720012802e80221040c010b410020012802f00222026b2106200c20044102746a210b20012802ec022107200c210503402005280200210a02400240200720066a4104490d0020012802e80221040c010b200241046a22042002490d0a200741017422092004200920044b1b22094100480d0a0240024020070d002009102821040c010b20012802e80220072009102c21040b2004450d07200120093602ec02200120043602e802200921070b2001200241046a22093602f002200420026a200a3600002006417c6a210620092102200b200541046a2205470d000b0b2014a72102200141a0016a411020042009100702402007450d002004102a0b2002450d00200c102a0b024020012d008f010d004200210f200141286a20012903782208200141f8006a41086a2202290300221042c0843d420010a005200141186a20012903282215200141286a41086a290300221442c0fb42427f109f05200141086a2015201442a0c21e4200109f05200220102010200141086a41086a29030020012903082215200820012903187c42018842ffffffff0f837c2214201554ad7c22152014200856201520105620152010511b22041b22157d20082008201420041b221054ad7d3703002001200820107d370378200141e8026a41086a22024200370300200142003703e80241ace1c0004116200141e8026a1008200141d8006a41086a2002290300370300200120012903e802370358200141003602e802200141d8006a4110200141e8026a100621020240024020012802e8022204417f470d00420021080c010b20044110490d06200241086a29000021082002290000210f2002102a0b200141e8026a41086a22044200370300200142003703e80241ace1c0004116200141e8026a1008200141d8006a41086a2004290300370300200120012903e80237035820014200200820157d200f201054ad7d2214200f20107d2216200f56201420085620142008511b22021b3703f00220014200201620021b3703e802200141d8006a4110200141e8026a4110100720014190016a41086a2206427f200629030022142008201520021b7c2001290390012208200f201020021b7c220f2008542202ad7c22082002200820145420082014511b22021b3703002001427f200f20021b3703900120014180036a2015370300200141e8026a41106a2010370300200441033a00002001410b3a00e80241014100200141e8026a10cc010b200141e8026a10d30120014188026a200141e8026a200129039001220820014190016a41086a29030022104102109802024002402001280288020d00200141a0016a41106a201020014188026a41106a29030022157d2008200129039002220f54ad7d201520107d200f200854ad7d200f2008582015201058201520105122021b22041b37030020012008200f7d200f20087d20041b3703a8012001200f200856201520105620021b2202ad3703a001200141a0016a41086a2104024020020d0020012004360258200141d8006a109c010c020b20012004360258200141d8006a109d010c010b41abb6c20041ca00100b200120103703a801200120083703a0012001200141a0016a3602880220014188026a109c010b2001290378210820014180036a200141f8006a41086a290300370300200141f8026a2008370300200141e8026a41086a41043a00002001410b3a00e80241014100200141e8026a10cc010b200141d8006a41086a220242003703002001420037035841affec5004111200141d8006a1008200141e8026a41086a2002290300370300200120012903583703e802200141e8026a41101009200141e0036a24000f0b411241011037000b412441011037000b200941011037000b41c4d1c3004133200141d8036a419cd9c3001038000b41c4d1c3004133200141d8036a419cd9c3001038000b1031000bf52901047f230041c0006b2202240002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240411610282203450d002003410e6a41002900dffc45370000200341086a41002900d9fc45370000200341002900d1fc4537000020034116412c102c2203450d0120032000360016200241206a41186a22004200370300200241206a41106a22044200370300200241206a41086a22054200370300200242003703202003411a200241206a1000200241186a2000290300370300200241106a2004290300370300200241086a2005290300370300200220022903203703002003102a200128020021032001280208210120024100360228200242013703202001200241206a10b40102402001450d00200320014105746a2105034002400240200228022420022802282201460d00200228022021000c010b200141016a22002001490d25200141017422042000200420004b1b22044100480d250240024020010d002004102821000c010b200228022020012004102c21000b2000450d052002200436022420022000360220200228022821010b2002200141016a360228200020016a20032d00003a000002400240200228022420022802282201460d00200228022021000c010b200141016a22002001490d25200141017422042000200420004b1b22044100480d250240024020010d002004102821000c010b200228022020012004102c21000b2000450d062002200436022420022000360220200228022821010b2002200141016a360228200020016a200341016a2d00003a000002400240200228022420022802282201460d00200228022021000c010b200141016a22002001490d25200141017422042000200420004b1b22044100480d250240024020010d002004102821000c010b200228022020012004102c21000b2000450d072002200436022420022000360220200228022821010b2002200141016a360228200020016a200341026a2d00003a000002400240200228022420022802282201460d00200228022021000c010b200141016a22002001490d25200141017422042000200420004b1b22044100480d250240024020010d002004102821000c010b200228022020012004102c21000b2000450d082002200436022420022000360220200228022821010b2002200141016a360228200020016a200341036a2d00003a000002400240200228022420022802282201460d00200228022021000c010b200141016a22002001490d25200141017422042000200420004b1b22044100480d250240024020010d002004102821000c010b200228022020012004102c21000b2000450d092002200436022420022000360220200228022821010b2002200141016a360228200020016a200341046a2d00003a000002400240200228022420022802282201460d00200228022021000c010b200141016a22002001490d25200141017422042000200420004b1b22044100480d250240024020010d002004102821000c010b200228022020012004102c21000b2000450d0a2002200436022420022000360220200228022821010b2002200141016a360228200020016a200341056a2d00003a000002400240200228022420022802282201460d00200228022021000c010b200141016a22002001490d25200141017422042000200420004b1b22044100480d250240024020010d002004102821000c010b200228022020012004102c21000b2000450d0b2002200436022420022000360220200228022821010b2002200141016a360228200020016a200341066a2d00003a000002400240200228022420022802282201460d00200228022021000c010b200141016a22002001490d25200141017422042000200420004b1b22044100480d250240024020010d002004102821000c010b200228022020012004102c21000b2000450d0c2002200436022420022000360220200228022821010b2002200141016a360228200020016a200341076a2d00003a000002400240200228022420022802282201460d00200228022021000c010b200141016a22002001490d25200141017422042000200420004b1b22044100480d250240024020010d002004102821000c010b200228022020012004102c21000b2000450d0d2002200436022420022000360220200228022821010b2002200141016a360228200020016a200341086a2d00003a000002400240200228022420022802282201460d00200228022021000c010b200141016a22002001490d25200141017422042000200420004b1b22044100480d250240024020010d002004102821000c010b200228022020012004102c21000b2000450d0e2002200436022420022000360220200228022821010b2002200141016a360228200020016a200341096a2d00003a000002400240200228022420022802282201460d00200228022021000c010b200141016a22002001490d25200141017422042000200420004b1b22044100480d250240024020010d002004102821000c010b200228022020012004102c21000b2000450d0f2002200436022420022000360220200228022821010b2002200141016a360228200020016a2003410a6a2d00003a000002400240200228022420022802282201460d00200228022021000c010b200141016a22002001490d25200141017422042000200420004b1b22044100480d250240024020010d002004102821000c010b200228022020012004102c21000b2000450d102002200436022420022000360220200228022821010b2002200141016a360228200020016a2003410b6a2d00003a000002400240200228022420022802282201460d00200228022021000c010b200141016a22002001490d25200141017422042000200420004b1b22044100480d250240024020010d002004102821000c010b200228022020012004102c21000b2000450d112002200436022420022000360220200228022821010b2002200141016a360228200020016a2003410c6a2d00003a000002400240200228022420022802282201460d00200228022021000c010b200141016a22002001490d25200141017422042000200420004b1b22044100480d250240024020010d002004102821000c010b200228022020012004102c21000b2000450d122002200436022420022000360220200228022821010b2002200141016a360228200020016a2003410d6a2d00003a000002400240200228022420022802282201460d00200228022021000c010b200141016a22002001490d25200141017422042000200420004b1b22044100480d250240024020010d002004102821000c010b200228022020012004102c21000b2000450d132002200436022420022000360220200228022821010b2002200141016a360228200020016a2003410e6a2d00003a000002400240200228022420022802282201460d00200228022021000c010b200141016a22002001490d25200141017422042000200420004b1b22044100480d250240024020010d002004102821000c010b200228022020012004102c21000b2000450d142002200436022420022000360220200228022821010b2002200141016a360228200020016a2003410f6a2d00003a000002400240200228022420022802282201460d00200228022021000c010b200141016a22002001490d25200141017422042000200420004b1b22044100480d250240024020010d002004102821000c010b200228022020012004102c21000b2000450d152002200436022420022000360220200228022821010b2002200141016a360228200020016a200341106a2d00003a000002400240200228022420022802282201460d00200228022021000c010b200141016a22002001490d25200141017422042000200420004b1b22044100480d250240024020010d002004102821000c010b200228022020012004102c21000b2000450d162002200436022420022000360220200228022821010b2002200141016a360228200020016a200341116a2d00003a000002400240200228022420022802282201460d00200228022021000c010b200141016a22002001490d25200141017422042000200420004b1b22044100480d250240024020010d002004102821000c010b200228022020012004102c21000b2000450d172002200436022420022000360220200228022821010b2002200141016a360228200020016a200341126a2d00003a000002400240200228022420022802282201460d00200228022021000c010b200141016a22002001490d25200141017422042000200420004b1b22044100480d250240024020010d002004102821000c010b200228022020012004102c21000b2000450d182002200436022420022000360220200228022821010b2002200141016a360228200020016a200341136a2d00003a000002400240200228022420022802282201460d00200228022021000c010b200141016a22002001490d25200141017422042000200420004b1b22044100480d250240024020010d002004102821000c010b200228022020012004102c21000b2000450d192002200436022420022000360220200228022821010b2002200141016a360228200020016a200341146a2d00003a000002400240200228022420022802282201460d00200228022021000c010b200141016a22002001490d25200141017422042000200420004b1b22044100480d250240024020010d002004102821000c010b200228022020012004102c21000b2000450d1a2002200436022420022000360220200228022821010b2002200141016a360228200020016a200341156a2d00003a000002400240200228022420022802282201460d00200228022021000c010b200141016a22002001490d25200141017422042000200420004b1b22044100480d250240024020010d002004102821000c010b200228022020012004102c21000b2000450d1b2002200436022420022000360220200228022821010b2002200141016a360228200020016a200341166a2d00003a000002400240200228022420022802282201460d00200228022021000c010b200141016a22002001490d25200141017422042000200420004b1b22044100480d250240024020010d002004102821000c010b200228022020012004102c21000b2000450d1c2002200436022420022000360220200228022821010b2002200141016a360228200020016a200341176a2d00003a000002400240200228022420022802282201460d00200228022021000c010b200141016a22002001490d25200141017422042000200420004b1b22044100480d250240024020010d002004102821000c010b200228022020012004102c21000b2000450d1d2002200436022420022000360220200228022821010b2002200141016a360228200020016a200341186a2d00003a000002400240200228022420022802282201460d00200228022021000c010b200141016a22002001490d25200141017422042000200420004b1b22044100480d250240024020010d002004102821000c010b200228022020012004102c21000b2000450d1e2002200436022420022000360220200228022821010b2002200141016a360228200020016a200341196a2d00003a000002400240200228022420022802282201460d00200228022021000c010b200141016a22002001490d25200141017422042000200420004b1b22044100480d250240024020010d002004102821000c010b200228022020012004102c21000b2000450d1f2002200436022420022000360220200228022821010b2002200141016a360228200020016a2003411a6a2d00003a000002400240200228022420022802282201460d00200228022021000c010b200141016a22002001490d25200141017422042000200420004b1b22044100480d250240024020010d002004102821000c010b200228022020012004102c21000b2000450d202002200436022420022000360220200228022821010b2002200141016a360228200020016a2003411b6a2d00003a000002400240200228022420022802282201460d00200228022021000c010b200141016a22002001490d25200141017422042000200420004b1b22044100480d250240024020010d002004102821000c010b200228022020012004102c21000b2000450d212002200436022420022000360220200228022821010b2002200141016a360228200020016a2003411c6a2d00003a000002400240200228022420022802282201460d00200228022021000c010b200141016a22002001490d25200141017422042000200420004b1b22044100480d250240024020010d002004102821000c010b200228022020012004102c21000b2000450d222002200436022420022000360220200228022821010b2002200141016a360228200020016a2003411d6a2d00003a000002400240200228022420022802282201460d00200228022021000c010b200141016a22002001490d25200141017422042000200420004b1b22044100480d250240024020010d002004102821000c010b200228022020012004102c21000b2000450d232002200436022420022000360220200228022821010b2002200141016a360228200020016a2003411e6a2d00003a000002400240200228022420022802282201460d00200228022021000c010b200141016a22002001490d25200141017422042000200420004b1b22044100480d250240024020010d002004102821000c010b200228022020012004102c21000b2000450d242002200436022420022000360220200228022821010b2002200141016a360228200020016a2003411f6a2d00003a0000200341206a22032005470d000b0b2002280224210320024120200228022022012002280228100702402003450d002001102a0b200241c0006a24000f0b411641011037000b412c41011037000b200441011037000b200441011037000b200441011037000b200441011037000b200441011037000b200441011037000b200441011037000b200441011037000b200441011037000b200441011037000b200441011037000b200441011037000b200441011037000b200441011037000b200441011037000b200441011037000b200441011037000b200441011037000b200441011037000b200441011037000b200441011037000b200441011037000b200441011037000b200441011037000b200441011037000b200441011037000b200441011037000b200441011037000b200441011037000b200441011037000b200441011037000b200441011037000b1031000bab0103017f017e027f230041206b2200240042002101200041106a41086a220242003703002000420037031041feb3c300410d200041106a1008200041086a2002290300370300200020002903103703002000410036021020004110200041106a100621020240024020002802102203417f460d002002450d0020034108490d01200229000021012002102a0b200041206a240020010f0b41c4d1c3004133200041106a419cd9c3001038000b0a0041d0c5c2001032000b3400200041bfcec20036020420004100360200200041146a4109360200200041106a41c4cec200360200200041086a42043702000bcf0101017f024002400240024002400240410110282202450d00200241003a0000200241014102102c2202450d01200241003a0001200241024104102c2202450d02200241003b0002200241044108102c2202450d0320024100360004200241084110102c2202450d0420024200370008200241104120102c2202450d052002420037001820024200370010200042a08080808004370204200020023602000f0b410141011037000b410241011037000b410441011037000b410841011037000b411041011037000b412041011037000b130020004102360204200041a0e1c2003602000b3101017f02404108102822020d00410841011037000b20004288808080800137020420002002360200200242b8173700000b3101017f02404108102822020d00410841011037000b20004288808080800137020420002002360200200242c8013700000bcb0201047f230041d0006b220324002003410036022820012002200341286a1006210402400240024020032802282205417f460d0020040d010b200041003a00000c010b41002101200341003a00480340024020052001470d000240200141ff0171450d00200341003a00480b41c4d1c3004133200341286a419cd9c3001038000b200341286a20016a200420016a2d00003a00002003200141016a22023a00482002210120024120470d000b200341086a41186a2201200341286a41186a290300370300200341086a41106a2202200341286a41106a290300370300200341086a41086a2206200341286a41086a2903003703002003200329032837030802402005450d002004102a0b20002003290308370001200041013a0000200041196a2001290300370000200041116a2002290300370000200041096a20062903003700000b200341d0006a24000bd31803017f017e2b7f230041b00d6b22032400200320023602042003200136020042002104200341086a41086a220142003703002003420037030841aef2c2004115200341086a1008200341900d6a41086a2001290300370300200320032903083703900d200341e80c6a200341900d6a10a903024002400240024020032802ec0c22050d00410121050c010b20032903f00c220442ffffffff0f560d010b20004200370000200041186a4200370000200041106a4200370000200041086a42003700000c010b20032802e80c2101200341086a410041e00c1099051a200541206a21062001411874411875210120052004422088a74105746a210741002108410021094100210a4100210b4100210c4100210d4100210e4100210f410021104100211141002112410021134100211441002115410021164100211741002118410021194100211a4100211b4100211c4100211d4100211e4100211f4100212041002121410021224100212341002124410021254100212641002127200521024100212841d1002129024003402028212a02400240024002402001450d0020072005460d01200141016a210103400240024020022007470d002006212b200621022005212c0c010b2002212c200241206a222b21020b2001417f6a22010d000c030b0b024020022007460d00200241206a212b2002212c0c030b2006212b2005212c20072005460d040c010b200141016a2101034020072002460d04200241206a21022001417f6a22010d000b200241606a212c2002212b0b202c450d020b202b21020240024002400240024002402003280204220141056a222b417f4c0d002003280200212d02400240202b450d00202b10282228450d034100212e200341003602980d2003202b3602940d200320283602900d0c010b200341003602980d2003202b3602940d200341013602900d410110282228450d03200341013602940d200320283602900d20032802980d212e0b2003202e41016a3602980d2028202e6a202a3a00002001200341900d6a10b4010240024020032802940d222e20032802980d222b6b2001490d0020032802900d212e0c010b202b20016a2228202b490d05202e410174222b2028202b20284b1b222b4100480d0502400240202e0d00202b1028212e0c010b20032802900d202e202b102c212e0b202e450d042003202b3602940d2003202e3602900d20032802980d212b0b2003202b20016a3602980d202e202b6a202d2001109a051a2003200341900d6a36028c0d202c2003418c0d6a10c80120032802940d212c20032802900d210120032802980d212b200341900d6a41186a222e4200370300200341900d6a41106a22284200370300200341900d6a41086a222d4200370300200342003703900d2001202b200341900d6a1000200341e80c6a41186a222b202e290300370300200341e80c6a41106a222e2028290300370300200341e80c6a41086a222f202d290300370300200320032903900d3703e80c0240202c450d002001102a0b2029417f6a2129202a41016a2128200341086a202a4103704105746a220120032903e80c370000200141186a202b290300370000200141106a202e290300370000200141086a202f2903003700004100212c0340202a202a41036e222b417d6c6a4102470d06200341086a202c6a220141df006a2d000022082001411f6a2d000022097120082009722001413f6a2d00007172211f200141de006a2d000022082001411e6a2d000022097120082009722001413e6a2d00007172211e200141dd006a2d000022082001411d6a2d000022097120082009722001413d6a2d00007172211d200141dc006a2d000022082001411c6a2d000022097120082009722001413c6a2d00007172211c200141db006a2d000022082001411b6a2d000022097120082009722001413b6a2d00007172211b200141da006a2d000022082001411a6a2d000022097120082009722001413a6a2d00007172211a200141d9006a2d00002208200141196a2d00002209712008200972200141396a2d000071722119200141d8006a2d00002208200141186a2d00002209712008200972200141386a2d000071722118200141d7006a2d00002208200141176a2d00002209712008200972200141376a2d000071722117200141d6006a2d00002208200141166a2d00002209712008200972200141366a2d000071722116200141d5006a2d00002208200141156a2d00002209712008200972200141356a2d000071722115200141d4006a2d00002208200141146a2d00002209712008200972200141346a2d000071722114200141d3006a2d00002208200141136a2d00002209712008200972200141336a2d000071722113200141d2006a2d00002208200141126a2d00002209712008200972200141326a2d000071722112200141d1006a2d00002208200141116a2d00002209712008200972200141316a2d000071722111200141d0006a2d00002208200141106a2d00002209712008200972200141306a2d000071722110200141cf006a2d000022082001410f6a2d000022097120082009722001412f6a2d00007172210f200141ce006a2d000022082001410e6a2d000022097120082009722001412e6a2d00007172210e200141cd006a2d000022082001410d6a2d000022097120082009722001412d6a2d00007172210d200141cc006a2d000022082001410c6a2d000022097120082009722001412c6a2d00007172210c200141cb006a2d000022082001410b6a2d000022097120082009722001412b6a2d00007172210b200141ca006a2d000022082001410a6a2d000022097120082009722001412a6a2d00007172210a200141c9006a2d00002208200141096a2d00002209712008200972200141296a2d000071722109200141c8006a2d00002208200141086a2d00002220712008202072200141286a2d000071722108200141c7006a2d00002220200141076a2d00002221712020202172200141276a2d000071722120200141c6006a2d00002221200141066a2d00002222712021202272200141266a2d000071722121200141c5006a2d00002222200141056a2d00002223712022202372200141256a2d000071722122200141c4006a2d00002223200141046a2d00002224712023202472200141246a2d000071722123200141c3006a2d00002224200141036a2d00002225712024202572200141236a2d000071722124200141c2006a2d00002225200141026a2d00002226712025202672200141226a2d000071722125200141c1006a2d00002226200141016a2d00002227712026202772200141216a2d000071722126200141c0006a2d0000222720012d0000222e712027202e72200141206a2d000071722127202c41800c460d06200341086a202c202b410574202a41096e41e0006c6b6a6a220141ff006a201f3a0000200141fe006a201e3a0000200141fd006a201d3a0000200141fc006a201c3a0000200141fb006a201b3a0000200141fa006a201a3a0000200141f9006a20193a0000200141f8006a20183a0000200141f7006a20173a0000200141f6006a20163a0000200141f5006a20153a0000200141f4006a20143a0000200141f3006a20133a0000200141f2006a20123a0000200141f1006a20113a0000200141f0006a20103a0000200141ef006a200f3a0000200141ee006a200e3a0000200141ed006a200d3a0000200141ec006a200c3a0000200141eb006a200b3a0000200141ea006a200a3a0000200141e9006a20093a0000200141e8006a20083a0000200141e7006a20203a0000200141e6006a20213a0000200141e5006a20223a0000200141e4006a20233a0000200141e3006a20243a0000200141e2006a20253a0000200141e1006a20263a0000200141e0006a20273a0000202b212a202c41e0006a222c41e00c470d000c060b0b1036000b202b41011037000b410141011037000b202b41011037000b1031000b4100210120290d000b0b2000201f3a001f2000201e3a001e2000201d3a001d2000201c3a001c2000201b3a001b2000201a3a001a200020193a0019200020183a0018200020173a0017200020163a0016200020153a0015200020143a0014200020133a0013200020123a0012200020113a0011200020103a00102000200f3a000f2000200e3a000e2000200d3a000d2000200c3a000c2000200b3a000b2000200a3a000a200020093a0009200020083a0008200020203a0007200020213a0006200020223a0005200020233a0004200020243a0003200020253a0002200020263a0001200020273a00000b02402004a7450d002005102a0b200341b00d6a24000bfd0102057f017e230041306b220224002002410036022020014110200241206a10062101024002400240024020022802202203417f460d0020010d010b200041003602040c010b20022003360214200220013602102003450d0120022003417f6a3602142002200141016a36021020012d00002103200241206a200241106a106d20022802202204450d012002410c6a41026a2002411d6a41026a2d000022053a0000200220022f001d22063b010c20022902242107200020033a0000200020063b0001200041036a20053a000020002007370208200020043602042001102a0b200241306a24000f0b41c4d1c3004133200241206a419cd9c3001038000bfb0401057f230041106b2202240002400240024002400240024020002802704101460d0002400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490d06200341017422052004200520044b1b22054100480d060240024020030d002005102821040c010b200128020020032005102c21040b2004450d0320012004360200200141046a2005360200200141086a28020021030b200141086a2205200341016a360200200420036a41003a00002000280274210602400240200141046a2802002204200528020022036b4104490d00200128020021040c010b200341046a22052003490d06200441017422032005200320054b1b22034100480d060240024020040d002003102821040c010b200128020020042003102c21040b2004450d0420012004360200200141046a2003360200200141086a28020021030b200141086a200341046a360200200420036a20063600000c010b02400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490d05200341017422052004200520044b1b22054100480d050240024020030d002005102821040c010b200128020020032005102c21040b2004450d0420012004360200200141046a2005360200200141086a28020021030b200141086a200341016a360200200420036a41013a00000b2000200110f1012000280278210320004180016a2802002200200110b40102402000450d002000410574210003402002200136020c20032002410c6a10c801200341206a2103200041606a22000d000b0b200241106a24000f0b200541011037000b200341011037000b200541011037000b1031000b860201017f0240024020002d00002201410e4b0d00024002400240024020010e0f050505050500050501050205030505050b200041086a2d00004101470d04200041146a280200450d04200041106a280200102a0c040b200041046a2d00004103470d0302402000410c6a280200450d00200041086a280200102a0b200041186a280200450d03200041146a280200102a0c030b200041046a2802000d022000410c6a280200450d02200041086a280200102a0c020b200041086a2d00004105490d01200041306a280200450d012000412c6a280200102a0c010b200041086a280200450d00200041046a280200102a0b0240200041fc006a280200450d002000280278102a0b0b130020004106360204200041c8f3c2003602000b3400200041d3f9c20036020420004100360200200041146a410f360200200041106a41dcf9c200360200200041086a42063702000b5501017f230041206b22022400200241003602082002420837030020024100360218200242013703104100200241106a10b401200041086a20022802183602002000200229031037020020021072200241206a24000b7201017f230041306b22022400200241186a4200370300200241106a4200370300200241086a42003703002002420037030020024100360228200242013703202002200241206a36022c20022002412c6a10c801200041086a200228022836020020002002290320370200200241306a24000b5d01027f230041106b2202240002404101102822030d00410141011037000b200341003a00002002428180808010370204200220033602004100200210b401200041086a200228020836020020002002290300370200200241106a24000b0900200042043702000b851805047f017e027f047e017f23004190026b22012400200141a8016a41086a22024200370300200142003703a80141f99fc6004115200141a8016a1008200141d0016a41086a22032002290300370300200120012903a8013703d001200141d0016a4110100920024200370300200142003703a801418ea0c600411a200141a8016a100820032002290300370300200120012903a8013703d00141002102200141003602a801200141d0016a4110200141a8016a100621030240024002400240024002400240024020012802a8012204417f460d002003450d0020044104490d01200328000021022003102a0b200141a8016a41086a22034200370300200142003703a80141bfa0c600411b200141a8016a1008200141d0016a41086a22042003290300370300200120012903a8013703d001200141186a200141d0016a109f02200129032021052001280218210620034200370300200142003703a80141bfa0c600411b200141a8016a1008200141086a4180e59af700200220024180e59af7004922071b20024180e59af70020071b6b2207ad2208420020084200109f0520042003290300370300200120012903a8013703d0012005420020061b2105200842a8c30180210842ffffffffffffffffff00428080808080808080807f20071b2001290308220920012903102009423f87521b42808090bbbad6adf00d7f210902400240200241ffe49af7004b0d0042ffffffffffffffffff00428080808080808080807f2005200820097d22097d22084200531b20082005427f5522022009427f554720022008427f5547711b22084280ec94a37c20084280ec94a37c551b21080c010b42ffffffffffffffffff00428080808080808080807f2005200820097c22097c22084200531b20082005427f5522022009427f554620022008427f5547711b21080b200120083703a801200141d0016a4110200141a8016a41081007200141a8016a41086a22024200370300200142003703a801418ea0c600411a200141a8016a1008200141d0016a41086a22032002290300370300200120012903a8013703d001200141d0016a4110100920024200370300200142003703a80141a8a0c6004117200141a8016a100820032002290300370300200120012903a8013703d001200141d0016a4110100920024200370300200142003703a80141d9efc200410d200141a8016a100820032002290300370300200120012903a8013703d00141002106200141003602a801200141d0016a4110200141a8016a10062102024020012802a8012203417f460d002002450d0020034104490d02200228000021062002102a200141d0016a411010090b200141a8016a41086a22024200370300200142003703a801419df2c2004111200141a8016a1008200141d0016a41086a2002290300370300200120012903a8013703d001200141a8016a200141d0016a411010a7030240024020012d00a8014101460d00200141286a41086a4200370300200141286a41106a4200370300200141286a41186a4200370300200141f0016a41186a200141c1016a290000370300200141f0016a41106a200141a8016a41116a290000370300200141f0016a41086a200141b1016a290000370300200120012900a9013703f00120014200370328200141f0016a21020c010b200141d0016a41101009200141f0016a41186a200141c1016a2900002208370300200141f0016a41106a200141a8016a41116a2900002205370300200141f0016a41086a200141b1016a2900002209370300200141286a41086a2009370300200141286a41106a2005370300200141286a41186a2008370300200120012900a90122083703f00120012008370328200141f0016a21020b42002108200141a8016a41086a22034200370300200142003703a80141b1f0c200410d200141a8016a1008200141d0016a41086a2003290300370300200120012903a8013703d001200141003602a801200141d0016a4110200141a8016a100621040240024020012802a8012203417f470d00410421070c010b200120033602f401200120043602f001200141a8016a200141f0016a107620012802a8012207450d0320012902ac01210802402003450d002004102a0b200141d0016a411010090b200141a8016a41086a22034200370300200142003703a80141e6efc2004115200141a8016a1008200141d0016a41086a2003290300370300200120012903a8013703d001200141a8016a200141d0016a411010a7030240024020012d00a8014101460d00200220012900a901370000200141c8006a41086a4200370300200141c8006a41106a4200370300200141c8006a41186a4200370300200241186a200141c1016a290000370000200241106a200141b9016a290000370000200241086a200141b1016a290000370000200142003703480c010b200141d0016a41101009200241186a200141c1016a2900002205370000200241106a200141b9016a2900002209370000200241086a200141b1016a290000220a370000200220012900a901220b370000200141c8006a41086a200a370300200141c8006a41106a2009370300200141c8006a41186a20053703002001200b3703480b0240200641fb01490d00200641857e6a2203450d00411010282202450d04200241086a41002900c6f042370000200241002900bef042370000200241104120102c2202450d0520022003360010200141a8016a41186a22034200370300200141a8016a41106a22044200370300200141a8016a41086a220c4200370300200142003703a80120024114200141a8016a1000200141f0016a41186a2003290300370300200141f0016a41106a2004290300370300200141f0016a41086a200c290300370300200120012903a8013703f0012002102a200141f0016a412010090b200141a8016a41186a22024200370300200141a8016a41106a22034200370300200141a8016a41086a22044200370300200142003703a801200141a8016a1014200141e8006a41186a2002290300370300200141e8006a41106a2003290300370300200141e8006a41086a2004290300370300200120012903a801370368200141f0016a41186a200141286a41186a290300370300200141f0016a41106a200141286a41106a290300370300200141f0016a41086a200141286a41086a290300370300200120012903283703f001200242003703002003420037030020044200370300200142003703a8010240200141f0016a4120200141a8016a1015450d0020014188016a41086a2004290300220537030020014188016a41106a2003290300220937030020014188016a41186a2002290300220a370300200120012903a801220b3703880120042005370300200320093703002002200a3703002001200b3703a8010240024020084220882205a722022008a7460d00200821090c010b200241016a22032002490d082005a74101742204200320032004491bad220942247e2205422088a70d082005a722034100480d080240024020020d002003102821070c010b2007200241246c2003102c21070b2007450d0720084220882205a721020b2007200241246c6a220241003a0000200220012903a801370001200241096a200141b0016a290300370000200241116a200141b8016a290300370000200241196a200141c0016a290300370000200220012f00f0013b0021200241236a200141f2016a2d00003a00002005422086200942ffffffff0f83844280808080107c21080b200020012903283700102000200636020020002001290368370030200041286a200141286a41186a290300370000200041206a200141286a41106a290300370000200041186a200141286a41086a290300370000200041386a200141e8006a41086a290300370000200041c0006a200141e8006a41106a290300370000200041c8006a200141e8006a41186a290300370000200041086a200837020020002007360204200041e8006a200141c8006a41186a290300370000200041e0006a200141c8006a41106a290300370000200041d8006a200141c8006a41086a2903003700002000200129034837005020014190026a24000f0b41c4d1c3004133200141a8016a419cd9c3001038000b41c4d1c3004133200141a8016a419cd9c3001038000b41c4d1c3004133200141a8016a419cd9c3001038000b411041011037000b412041011037000b200341041037000b1031000bb40202067f017e230041206b220224000240024002400240200128020422034104490d0020012802002204280000210520012003417c6a22063602042001200441046a36020020064104490d01200428000421062001200341786a3602042001200441086a360200200241106a2001106d200228021022030d02200041003602080c030b200041003602080c020b200041003602080c010b200241106a41086a280200210720022802142104200241106a2001106d02402002280210450d00200241086a200241106a41086a2802002201360200200220022903102208370300200041106a20073602002000200436020c200020033602082000200636020420002005360200200041146a20083702002000411c6a20013602000c010b200041003602082004450d002003102a0b200241206a24000ba60301067f230041106b22022400200241003602082002420137030020002802002103024002400240410410282204450d0020024284808080c0003702042002200436020020042003360000200028020421050240024020022802042206200228020822046b4104490d00200441046a2103200228020021060c010b200441046a22032004490d03200641017422072003200720034b1b22074100480d030240024020060d002007102821060c010b200228020020062007102c21060b2006450d0220022007360204200220063602000b20022003360208200620046a200536000020002802082104200041106a2802002203200210b40102402003450d0020034105742103034020042002108f01200441206a2104200341606a22030d000b0b200028021421042000411c6a2802002203200210b40102402003450d0020034105742103034020042002108f01200441206a2104200341606a22030d000b0b2002280204210420012802002001280204200228020022032002280208100702402004450d002003102a0b200241106a24000f0b410441011037000b200741011037000b1031000b1300200041043602042000418897c3003602000b3400200041879fc30036020420004100360200200041146a4105360200200041106a41a0a2c300360200200041086a42133702000b34002000418ca2c30036020420004100360200200041146a4105360200200041106a41a0a2c300360200200041086a42133702000bf90101047f230041206b22032400200341106a41086a220442003703002003420037031041a8a0c6004117200341106a1008200341086a200429030037030020032003290310370300410021042003410036021020034110200341106a100621050240024020032802102206417f460d002005450d0020064104490d01200528000021042005102a0b02400240417f200420026a220520052004491b2204418080c002418080f00120011b4b0d00200041046a2004360200410021040c010b200041800c3b0001200041036a41003a0000410121040b200020043a0000200341206a24000f0b41c4d1c3004133200341106a419cd9c3001038000b850201047f230041206b22032400200341106a41086a2204420037030020034200370310418ea0c600411a200341106a1008200341086a200429030037030020032003290310370300410021042003410036021020034110200341106a100621050240024020032802102206417f460d002005450d0020064104490d01200528000021042005102a0b02400240417f2004418094ebdc034180afd0e50220021b2205200120052001491b6a220120012004491b220420054b0d00200041046a2004360200410021040c010b200041800c3b0001200041036a41003a0000410121040b200020043a0000200341206a24000f0b41c4d1c3004133200341106a419cd9c3001038000bef1a04057f017e037f017e230041e0016b220124000240024002400240024002400240024041880110282202450d000240024002400240024002400240024002400240024002400240024002400240024002400240024002400240200028020022002802000e1500011402030405060708090a0b0c0d0e0f10111213000b0240024002400240024002400240200041086a280200417f6a220341054b0d004101210420030e06060102030405060b41e4f0c2001032000b200041146a2802002204417f4c0d1b2000410c6a28020021000240024020040d0020014200370360410121050c010b200410282205450d1d20014100360264200120043602600b20012004360264200520002004109a051a20012903602106410221040c040b200041106a2903002106410321040c030b200041146a2802002204417f4c0d192000410c6a28020021000240024020040d0020014200370360410121050c010b200410282205450d1c20014100360264200120043602600b20012004360264200520002004109a051a20012903602106410421040c020b200141e0006a2000410c6a106f2001290264210620012802602105410521040c010b200141e0006a2000410c6a10712001290264210620012802602105410621040b200220063703102002200536020c20022004360208200241003602000c140b10a103000b200141e0006a200041046a1070200241033602002002410c6a200141e8006a280200360200200220012903603702040c120b10bb03000b200141e0006a200041086a10ae02200241086a200141e0006a41e000109a051a200241053602000c100b200141e0006a200041086a10bc0320024106360200200241386a200141e0006a41306a290300370300200241306a200141e0006a41286a290300370300200241286a200141e0006a41206a290300370300200241206a200141e0006a41186a290300370300200241186a200141e0006a41106a290300370300200241106a200141e0006a41086a290300370300200220012903603703080c0f0b200141e0006a41186a200041286a290000370300200141e0006a41106a200041206a290000370300200141e8006a200041186a290000370300200141e0006a41286a200041386a290000370300200141e0006a41306a200041c0006a290000370300200141e0006a41386a200041c8006a290000370300200141e0006a41c8006a200041d8006a290000370300200141e0006a41d0006a200041e0006a290000370300200141e0006a41d8006a200041e8006a2900003703002001200041106a2900003703602001200041306a290000370380012001200041d0006a2900003703a0012000410c6a2802002205417f4c0d10200028020421030240024020050d0041012100410021040c010b20052104200510282200450d140b200020032005109a0521002001200141e0006a41e000109a0521032002200536020c2002200436020820022000360204200241106a200341e000109a051a200241073602000c0e0b200141e0006a200041086a10bd0320024108360200200241306a200141e0006a41286a290300370300200241286a200141e0006a41206a290300370300200241206a200141e0006a41186a290300370300200241186a200141e0006a41106a290300370300200241106a200141e0006a41086a290300370300200220012903603703080c0d0b02400240024002400240024020002d0004417f6a220541034b0d0020050e0401020304010b41c0f1c2001032000b200041106a280200220341ffffff3f712003470d1220034105742204417f4c0d12200041086a2802002100410121054101210702402004450d00200410282207450d170b024020030d0041002104410021030c040b2003410574210420072105034020052000290000370000200541186a200041186a290000370000200541106a200041106a290000370000200541086a200041086a290000370000200541206a2105200041206a2100200441606a22040d000b41012105200341057441606a41057641016a21040c030b200041086a10ba032107410221050c020b200041086a28020021072000410c6a10ba032103410321050c010b200141026a200041046a220541036a2d00003a0000200141e0006a41086a2000411c6a290000370300200141e0006a41106a200041246a2d00003a0000200120052f00013b01002001200041146a29000037036020002d00254100472108200041286a2802002109200041106a28000021042000410c6a2800002103200041086a2800002107410421050b200220053a0004200220012f01003b0005200220043602102002200336020c200220073602082002200129036037021420022009360228200220083a002520024109360200200241076a200141026a2d00003a00002002411c6a200141e8006a290300370200200241246a200141f0006a2d00003a00000c0c0b02400240024002400240024020002d0004417f6a220541034b0d0020050e0401020304010b41c0f1c2001032000b200041106a280200220341ffffff3f712003470d1120034105742204417f4c0d11200041086a2802002100410121054101210702402004450d00200410282207450d170b024020030d0041002104410021030c040b2003410574210420072105034020052000290000370000200541186a200041186a290000370000200541106a200041106a290000370000200541086a200041086a290000370000200541206a2105200041206a2100200441606a22040d000b41012105200341057441606a41057641016a21040c030b200041086a10ba032107410221050c020b200041086a28020021072000410c6a10ba032103410321050c010b200141026a200041046a220541036a2d00003a0000200141e0006a41086a2000411c6a290000370300200141e0006a41106a200041246a2d00003a0000200120052f00013b01002001200041146a29000037036020002d00254100472108200041286a2802002109200041106a28000021042000410c6a2800002103200041086a2800002107410421050b200220053a0004200220012f01003b0005200220043602102002200336020c200220073602082002200129036037021420022009360228200220083a00252002410a360200200241076a200141026a2d00003a00002002411c6a200141e8006a290300370200200241246a200141f0006a2d00003a00000c0b0b200141e0006a200041086a10d3022002410b360200200241c0006a200141e0006a41386a290300370300200241386a200141e0006a41306a290300370300200241306a200141e0006a41286a290300370300200241286a200141e0006a41206a290300370300200241206a200141e0006a41186a290300370300200241186a200141e0006a41106a290300370300200241106a200141e0006a41086a290300370300200220012903603703080c0a0b200141e0006a200041046a10be03200241046a200141e0006a41c400109a051a2002410c3602000c090b200028020421002002410d360200200220003602040c080b2000410c6a2802002205417f4c0d09200028020421030240024020050d0041012100410021040c010b20052104200510282200450d100b200020032005109a0521002002200536020c20022004360208200220003602042002410e3602000c070b024002400240024002400240200041086a280200417f6a220541024b0d0020050e03010203010b418486c2001032000b200041386a2903002106200041306a290300210a41012105024002402000410c6a2d00004101460d00200141e8006a2000411c6a290200370300200141e0006a41106a200041246a290200370300200141f8006a2000412c6a2d00003a00002001200041146a29020037036020002f000d2000410f6a2d0000411074722104200041106a2802002103410021050c010b200041106a28020021030b200141186a200141e0006a41186a280200360200200141106a200141e0006a41106a290300370300200141086a200141e0006a41086a29030037030020012001290360370300410121000c030b2000410c6a28020022054108762104410221000c010b2000410c6a28020022054108762104410321000b0b2002200a3703302002200336021020022000360208200220012903003702142002410f360200200241386a200637030020022004410874200541ff01717236020c2002411c6a200141086a290300370200200241246a200141106a2903003702002002412c6a200141186a2802003602000c060b200141e0006a200041086a10bf03200241086a200141e0006a418001109a051a200241103602000c050b200141e0006a200041046a10c003200241113602002002412c6a20014188016a280200360200200241246a20014180016a2903003702002002411c6a200141f8006a290300370200200241146a200141f0006a2903003702002002410c6a200141e8006a290300370200200220012903603702040c040b200141e0006a200041046a10af02200241046a200141e0006a41e400109a051a200241123602000c030b10c103000b10d501000b200041086a290300210620024102360200200220063703080b200141e0016a240020020f0b41880141081037000b1036000b200441011037000b200441011037000b200541011037000b200441011037000b200441011037000b200541011037000b0a0041acb4c3001032000b910c03047f017e057f230041206b2202240002400240024002400240024002400240024002400240024002400240024002400240024020012d0000417f6a2203410c4b0d0020030e0d0102030405060708090a0b0c0d010b41e0ffc4001032000b4101210302400240200141046a2d00004101460d002002411e6a200141076a2d00003a0000200241086a200141146a290000370300200241106a2001411c6a290000370300200241186a200141246a2d00003a00002002200141056a2f00003b011c20022001410c6a290000370300200141086a2800002104410021030c010b200141086a28020021040b200041286a2001290328370300200041046a20033a0000200041056a20022f011c3b0000200041086a20043602002000410c6a2002290300370200200041306a200141306a290300370300200041076a2002411e6a2d00003a0000200041146a200241086a2903003702002000411c6a200241106a290300370200200041246a200241186a28020036020020012d00012101200041013a0000200020013a00010c0c0b200041023a0000200041106a200141106a290300370300200041086a200141086a2903003703000c0b0b200041033a0000200041106a200141106a290300370300200041086a200141086a2903003703000c0a0b200041043a00000c090b200041053a0000200041106a200141106a290300370300200041086a200141086a2903003703000c080b2001410c6a2802002205ad42247e2206422088a70d082006a72204417f4c0d08200141046a28020021030240024020040d00410421070c010b200410282207450d0a0b0240024020050d00410021040c010b200541246c2108410021042002411e6a21092007210103400240024020032d00004101460d002009200341036a2d00003a0000200341046a280000210a200341016a2f0000210b200241086a200341106a290000370300200241106a200341186a290000370300200241186a200341206a2d00003a00002002200b3b011c2002200341086a2900003703004100210b0c010b200341046a280200210a4101210b0b200341246a21032001200b3a0000200141046a200a360200200141016a20022f011c3b0000200141036a20092d00003a0000200141086a2002290300370200200141106a200241086a290300370200200141186a200241106a290300370200200141206a200241186a280200360200200141246a2101200441016a21042008415c6a22080d000b0b200041063a00002000410c6a2004360200200041086a2005360200200041046a20073602000c070b200041073a00000c060b200041083a0000200020012d00013a00010c050b4101210302400240200141046a2d00004101460d002002411e6a200141076a2d00003a0000200241086a200141146a290000370300200241106a2001411c6a290000370300200241186a200141246a2d00003a00002002200141056a2f00003b011c20022001410c6a290000370300200141086a2800002101410021030c010b200141086a28020021010b200041093a0000200041046a20033a0000200041056a20022f011c3b0000200041086a20013602002000410c6a2002290300370200200041076a2002411e6a2d00003a0000200041146a200241086a2903003702002000411c6a200241106a290300370200200041246a200241186a2802003602000c040b2000410a3a0000200041046a200141046a2802003602000c030b2000410b3a00000c020b2000410c3a00000c010b2001410c6a280200220841ffffff3f712008470d0120084105742203417f4c0d01200141046a28020021010240024020030d004101210a0c010b20031028220a450d040b0240024020080d0041002108410021010c010b20084105742104200a2103034020032001290000370000200341186a200141186a290000370000200341106a200141106a290000370000200341086a200141086a290000370000200341206a2103200141206a2101200441606a22040d000b200841057441606a41057641016a21010b2000410d3a00002000410c6a2001360200200041086a2008360200200041046a200a3602000b200241206a24000f0b1036000b200441041037000b200341011037000bab0701017f024002400240024002400240024002400240024002400240024002400240024002400240024002400240024020012d0000417f6a220241104b0d0020020e110102030405060708090a0b0c0d0e0f1011010b41e8d0c5001032000b41880110282202450d102002200141046a28020010cf03200041046a2002360200200041013a0000200041106a200141106a290300370300200041086a200141086a2903003703000f0b200041023a0000200041046a200141046a2802003602000f0b200041033a0000200041046a200141046a280200360200200041026a200141026a2d00003a0000200020012d00014101713a00010f0b200041043a0000200041046a200141046a280200360200200041026a200141026a2d00003a0000200020012d00014101713a00010f0b200041053a0000200041046a200141046a2802003602000f0b41880110282202450d0c2002200141046a28020010cf03200041063a0000200041046a20023602000f0b41880110282202450d0c2002200141046a28020010cf03200041073a0000200041046a20023602000f0b41880110282202450d0c2002200141046a28020010cf03200041083a0000200041046a20023602000f0b200041093a000020002001290001370001200041096a200141096a290000370000200041116a200141116a290000370000200041196a200141196a290000370000200041246a200141246a2902003702000f0b2000410a3a000020002001290001370001200041196a200141196a290000370000200041116a200141116a290000370000200041096a200141096a2900003700000f0b2000410b3a0000200041046a200141046a2802003602000f0b2000410c3a00002000410c6a2001410c6a280200360200200041046a200141046a2902003702000f0b2000410d3a000020002001290001370001200041196a200141196a290000370000200041116a200141116a290000370000200041096a200141096a2900003700000f0b2000410e3a00000f0b2000410f3a000020002001290001370001200041196a200141196a290000370000200041116a200141116a290000370000200041096a200141096a2900003700000f0b200041103a000020002001290001370001200041096a200141096a290000370000200041116a200141116a290000370000200041196a200141196a290000370000200041216a200141216a2d00003a00000f0b200041113a00000f0b41880141081037000b41880141081037000b41880141081037000b41880141081037000bb60401047f0240024002400240024020012d0000417f6a220241034b0d0020020e0401020304010b4188b5c3001032000b200041013a000020002001290001370001200041196a200141196a290000370000200041116a200141116a290000370000200041096a200141096a2900003700000f0b200041023a000020002001290001370001200041196a200141196a290000370000200041116a200141116a290000370000200041096a200141096a2900003700000f0b200041033a000020002001290001370001200041196a200141196a290000370000200041116a200141116a290000370000200041096a200141096a290000370000200041216a200141216a290000370000200041296a200141296a290000370000200041316a200141316a290000370000200041396a200141396a2900003700000f0b024002402001410c6a280200220341ffffff3f712003470d0020034105742202417f4c0d00200141046a28020021010240024020020d00410121040c010b200210282204450d020b0240024020030d0041002103410021010c010b2003410574210520042102034020022001290000370000200241186a200141186a290000370000200241106a200141106a290000370000200241086a200141086a290000370000200241206a2102200141206a2101200541606a22050d000b200341057441606a41057641016a21010b200041043a00002000410c6a2001360200200041086a2003360200200041046a20043602000f0b1036000b200241011037000b8d0c07037f017e017f017e017f017e017f230041c0006b220224000240024002400240024002400240024002400240024020012d0000417f6a220341044b0d0020030e050102030405010b41d093c4001032000b200041f9006a2002280020360000200041086a200141086a290300370300200041fc006a200241236a280000360000200041106a200141106a290300370300200041186a200141186a290300370300200041206a200141206a290300370300200041286a200141286a290300370300200041306a200141306a290300370300200041386a200141386a290300370300200041c0006a200141c0006a290300370300200041c8006a200141c8006a290300370300200041d0006a200141d0006a290300370300200041d8006a200141d8006a290300370300200041e0006a200141e0006a290300370300200041e8006a200141e8006a290300370300200041f0006a200141f0006a290300370300200041f8006a200141f8006a2d00004100473a0000200041013a00000c040b2001410c6a2802002203417f4c0d04200141046a2802002104200141106a29030021050240024020030d0041002101410121060c010b20032101200310282206450d060b200620042003109a0521042000410c6a2003360200200041086a2001360200200041046a2004360200200041106a2005370300200041023a00000c030b4101210402400240200141046a2d00004101460d00200241026a200141076a2d00003a0000200241206a41086a200141146a290000370300200241306a2001411c6a290000370300200241386a200141246a2d00003a00002002200141056a2f00003b010020022001410c6a290000370320200141086a2800002106410021040c010b200141086a28020021060b200141306a2802002203417f4c0d03200141c0006a29030021052001290338210720012802282108200129034821090240024020030d00410021014101210a0c010b2003210120031028220a450d060b200a20082003109a052108200041c0006a2005370300200041386a2007370300200041046a20043a0000200041086a2006360200200041c8006a2009370300200041306a20033602002000412c6a2001360200200041286a2008360200200041056a20022f01003b0000200041076a200241026a2d00003a00002000410c6a2002290320370200200041146a200241206a41086a2903003702002000411c6a200241306a290300370200200041246a200241386a280200360200200041033a00000c020b200141386a2903002105200141306a2903002107200141c0006a2903002109200241386a200141196a290000370300200241306a200141116a290000370300200241286a200141096a290000370300200220012900013703202001412c6a2802002203417f4c0d02200141246a28020021010240024020030d0041012104410021060c010b20032106200310282204450d060b200420012003109a052101200041386a2005370300200041306a2007370300200041c0006a20093703002000412c6a2003360200200041286a2006360200200041246a2001360200200041043a000020002002290320370001200041096a200241286a290300370000200041116a200241306a290300370000200041196a200241386a2903003700000c010b200241186a2204200141196a290000370300200241106a2206200141116a290000370300200241086a2208200141096a29000037030020022001290001370300410021030240200141216a2d00004101470d00200241206a41186a2001413a6a290000370300200241206a41106a200141326a290000370300200241206a41086a2001412a6a2900003703002002200141226a290000370320410121030b20002002290300370001200041216a20033a0000200041226a2002290320370000200041196a2004290300370000200041116a2006290300370000200041096a20082903003700002000412a6a200241206a41086a290300370000200041326a200241206a41106a2903003700002000413a6a200241206a41186a290300370000200041053a00000b200241c0006a24000f0b1036000b200341011037000b200341011037000b200341011037000b920501047f230041206b2202240002400240024002400240024002402001280200417f6a220341024b0d0020030e03010203010b41dc9cc4001032000b41880110282203450d032003200128020410cf0320004101360200200020033602040c020b410121030240024020012d00044101460d002002411e6a200141046a220341036a2d00003a0000200241086a200141146a290200370300200241106a2001411c6a290200370300200241186a200141246a2d00003a0000200220032f00013b011c20022001410c6a290200370300200141086a2802002101410021030c010b200141086a28020021010b200020033a0004200020022f011c3b000520004102360200200041086a20013602002000410c6a2002290300370200200041076a2002411c6a41026a2d00003a0000200041146a200241086a2903003702002000411c6a200241106a290300370200200041246a200241186a2802003602000c010b410121040240024020012d00044101460d002002411e6a200141046a220341036a2d00003a0000200241086a200141146a290200370300200241106a2001411c6a290200370300200241186a200141246a2d00003a0000200220032f00013b011c20022001410c6a290200370300200141086a2802002105410021040c010b200141086a28020021050b41880110282203450d022003200128022810cf03200020043a0004200041086a2005360200200041286a200336020020004103360200200020022f011c3b0005200041076a2002411e6a2d00003a00002000410c6a2002290300370200200041146a200241086a2903003702002000411c6a200241106a290300370200200041246a200241186a2802003602000b200241206a24000f0b41880141081037000b41880141081037000b0a0041b095c4001032000bad0301047f230041106b22022400024002400240024002400240024002400240024002402001280200417f6a220341054b0d0020030e06010203040506010b41e4f0c2001032000b200041013602000c050b2001410c6a2802002203417f4c0d05200128020421010240024020030d0041002104410121050c010b20032104200310282205450d070b200520012003109a0521012000410c6a2003360200200041086a200436020020002001360204200041023602000c040b20004103360200200041086a200141086a2903003703000c030b2001410c6a2802002203417f4c0d03200128020421010240024020030d0041012104410021050c010b20032105200310282204450d060b200420012003109a0521012000410c6a2003360200200041086a200536020020002001360204200041043602000c020b2002200141046a106f200041053602002000410c6a200241086a280200360200200020022903003702040c010b2002200141046a1071200041063602002000410c6a200241086a280200360200200020022903003702040b200241106a24000f0b1036000b200341011037000b200341011037000bdd0301047f024002400240024002400240024020012d0000417f6a220241034b0d0020020e0401020304010b41c0f1c2001032000b2001410c6a280200220341ffffff3f712003470d0320034105742202417f4c0d03200141046a28020021010240024020020d00410121040c010b200210282204450d050b0240024020030d0041002103410021010c010b2003410574210520042102034020022001290000370000200241186a200141186a290000370000200241106a200141106a290000370000200241086a200141086a290000370000200241206a2102200141206a2101200541606a22050d000b200341057441606a41057641016a21010b200041013a00002000410c6a2001360200200041086a2003360200200041046a20043602000f0b200141046a10ba032101200041023a0000200041046a20013602000f0b200141046a2802002102200041086a200141086a10ba03360200200041046a2002360200200041033a00000f0b200041043a000020002001290001370001200041096a200141096a290000370000200041116a200141116a290000370000200041196a200141196a290000370000200041246a200141246a280200360200200041216a200141216a2d00004100473a00000f0b1036000b200241011037000b3400200041c5b6c30036020420004100360200200041146a4102360200200041106a41ccb6c300360200200041086a42073702000be40201047f230041c0006b2202240002400240410f10282203450d00200341076a4100290092b4433700002003410029008bb4433700002003410f411e102c2203450d012003200036000f200241206a41186a22004200370300200241206a41106a22044200370300200241206a41086a220542003703002002420037032020034113200241206a1000200241186a2000290300370300200241106a2004290300370300200241086a2005290300370300200220022903203703002003102a200128020021042001280208210320024100360228200242013703202003200241206a10b40102402003450d00200341057421002004210303402003200241206a108f01200341206a2103200041606a22000d000b0b2002280224210320024120200228022022002002280228100702402003450d002000102a0b0240200141046a280200450d002004102a0b200241c0006a24000f0b410f41011037000b411e41011037000b8a1401037f200141046a2802002102200141086a28020021030240024002400240024002400240024002400240024002400240024002400240024020002d00004101460d000240024020022003460d00200128020021020c010b200341016a22022003490d11200341017422042002200420024b1b22044100480d110240024020030d002004102821020c010b200128020020032004102c21020b2002450d0220012002360200200141046a2004360200200141086a28020021030b200141086a2204200341016a360200200220036a41003a00000240024002400240024002400240024020002d00010e080001020304050607000b02400240200141046a28020020042802002203460d00200128020021000c010b200341016a22002003490d18200341017422022000200220004b1b22024100480d180240024020030d002002102821000c010b200128020020032002102c21000b2000450d0a20012000360200200141046a2002360200200141086a28020021030b200141086a200341016a360200200020036a41003a00000f0b02400240200141046a28020020042802002203460d00200128020021000c010b200341016a22002003490d17200341017422022000200220004b1b22024100480d170240024020030d002002102821000c010b200128020020032002102c21000b2000450d0a20012000360200200141046a2002360200200141086a28020021030b200141086a200341016a360200200020036a41013a00000f0b02400240200141046a28020020042802002203460d00200128020021000c010b200341016a22002003490d16200341017422022000200220004b1b22024100480d160240024020030d002002102821000c010b200128020020032002102c21000b2000450d0a20012000360200200141046a2002360200200141086a28020021030b200141086a200341016a360200200020036a41023a00000f0b02400240200141046a28020020042802002203460d00200128020021000c010b200341016a22002003490d15200341017422022000200220004b1b22024100480d150240024020030d002002102821000c010b200128020020032002102c21000b2000450d0a20012000360200200141046a2002360200200141086a28020021030b200141086a200341016a360200200020036a41033a00000f0b02400240200141046a28020020042802002203460d00200128020021000c010b200341016a22002003490d14200341017422022000200220004b1b22024100480d140240024020030d002002102821000c010b200128020020032002102c21000b2000450d0a20012000360200200141046a2002360200200141086a28020021030b200141086a200341016a360200200020036a41043a00000f0b02400240200141046a28020020042802002203460d00200128020021000c010b200341016a22002003490d13200341017422022000200220004b1b22024100480d130240024020030d002002102821000c010b200128020020032002102c21000b2000450d0a20012000360200200141046a2002360200200141086a28020021030b200141086a200341016a360200200020036a41053a00000f0b02400240200141046a28020020042802002203460d00200128020021000c010b200341016a22002003490d12200341017422022000200220004b1b22024100480d120240024020030d002002102821000c010b200128020020032002102c21000b2000450d0a20012000360200200141046a2002360200200141086a28020021030b200141086a200341016a360200200020036a41063a00000f0b02400240200141046a28020020042802002203460d00200128020021020c010b200341016a22022003490d11200341017422042002200420024b1b22044100480d110240024020030d002004102821020c010b200128020020032004102c21020b2002450d0a20012002360200200141046a2004360200200141086a28020021030b200141086a2204200341016a360200200220036a41073a000002400240200141046a28020020042802002203460d00200128020021020c010b200341016a22022003490d11200341017422042002200420024b1b22044100480d110240024020030d002004102821020c010b200128020020032004102c21020b2002450d0b20012002360200200141046a2004360200200141086a28020021030b200141086a200341016a360200200220036a20002d00023a00000f0b0240024020022003460d00200128020021020c010b200341016a22022003490d10200341017422042002200420024b1b22044100480d100240024020030d002004102821020c010b200128020020032004102c21020b2002450d0b20012002360200200141046a2004360200200141086a28020021030b200141086a200341016a360200200220036a41013a0000024020002d0001220341024b0d0002400240024020030e03000102000b02400240200141046a280200200141086a2802002203460d00200128020021000c010b200341016a22002003490d13200341017422022000200220004b1b22024100480d130240024020030d002002102821000c010b200128020020032002102c21000b2000450d0f20012000360200200141046a2002360200200141086a28020021030b200141086a200341016a360200200020036a41003a00000f0b02400240200141046a280200200141086a2802002203460d00200128020021000c010b200341016a22002003490d12200341017422022000200220004b1b22024100480d120240024020030d002002102821000c010b200128020020032002102c21000b2000450d0f20012000360200200141046a2002360200200141086a28020021030b200141086a200341016a360200200020036a41013a00000f0b02400240200141046a280200200141086a2802002203460d00200128020021020c010b200341016a22022003490d11200341017422042002200420024b1b22044100480d110240024020030d002004102821020c010b200128020020032004102c21020b2002450d0f20012002360200200141046a2004360200200141086a28020021030b200141086a2204200341016a360200200220036a41023a000002400240200141046a28020020042802002203460d00200128020021020c010b200341016a22022003490d11200341017422042002200420024b1b22044100480d110240024020030d002004102821020c010b200128020020032004102c21020b2002450d1020012002360200200141046a2004360200200141086a28020021030b200141086a200341016a360200200220036a20002d00023a00000b0f0b200441011037000b200241011037000b200241011037000b200241011037000b200241011037000b200241011037000b200241011037000b200241011037000b200441011037000b200441011037000b200441011037000b200241011037000b200241011037000b200441011037000b200441011037000b1031000bac64070e7f017e047f017e047f0f7e087f230041900b6b220124004100210241002103410421040240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002402000410c6a28020041246c2205450d00200028020421064104210441002102410021030340024020062d00004101470d00200641106a2802002207417f4c0d1a200641086a2802002108200641016a28000021090240024020070d004101210a4100210b0c010b2007210b20071028220a450d040b200a20082007109a05210a20014188076a41026a220c200141f0056a41026a2d00003a0000200141a0086a41086a220d200141c0096a41086a290200370300200120012f00f0053b018807200120012902c0093703a008024020022003470d00200241016a22082002490d1d2002410174220e2008200e20084b1b2203ad42247e220f422088a70d1d200fa722084100480d1d0240024020020d002008102821040c010b2004200241246c2008102c21040b2004450d050b2004200241246c6a220841013a000020082009360001200820073600102008200b36000c2008200a360008200820012f0188073b0005200841076a200c2d00003a0000200820012903a0083702142008411c6a200d290300370200200241016a21020b200641246a21062005415c6a22050d000b0b200141003602a0084188e8c2004110200141a0086a4104100720014188076a41086a22064200370300200142003703880741d9efc200410d20014188076a1008200141f0056a41086a2208200629030037030020012001290388073703f0052001200028020022073602a008200141f0056a4110200141a0086a4104100720064200370300200142003703880741b1f0c200410d20014188076a10082008200629030037030020012001290388073703f005200141103602a4082001200141f0056a3602a00820042002200141a0086a10e102200642003703002001420037038807419df2c200411120014188076a10082008200629030037030020012001290388073703f005200141103602a4082001200141f0056a3602a008200041106a2205200141a0086a10f002411010282206450d02200641086a41002900c6f042370000200641002900bef042370000200641104120102c2208450d0320082007417f6a360010200141d8046a41186a22064200370300200141d8046a41106a22074200370300200141d8046a41086a22094200370300200142003703d80420084114200141d8046a100020014188076a41186a200629030037030020014188076a41106a200729030037030020014188076a41086a22062009290300370300200120012903d804370388072008102a200141203602a408200120014188076a3602a0082005200141a0086a10f00220064200370300200142003703880741e6efc200411520014188076a1008200141f0056a41086a2208200629030037030020012001290388073703f005200141103602a4082001200141f0056a3602a008200041d0006a200141a0086a10f00220064200370300200142003703880741aef2c200411520014188076a10082008200629030037030020012001290388073703f005200141a0086a200141f0056a10a903024020012802a40822070d00200141013602d804410021094100210641002105410021080c060b200120073602d804200141ac086a280200210620012802a008210920012802a8082105024020012903a808220f422088a741d1004f0d00200fa721080c060b200141a0086a41186a220a200041286a290000370300200141a0086a41106a220b200041206a290000370300200141a0086a41086a220c200041186a290000370300200120002900103703a00820062009411874220941187522084d0d04200720084105746a220820012903a008370000200841186a200a290300370000200841106a200b290300370000200841086a200c290300370000200941808080086a41187541d1006f21090c060b200741011037000b200841041037000b411041011037000b412041011037000b41c4f2c200200820061034000b200141a0086a41186a220a200041286a290000370300200141a0086a41106a220b200041206a290000370300200141a0086a41086a220c200041186a290000370300200120002900103703a008024020062008470d0020052006470d00200641016a22082006490d14200641017422072008200720084b1b220541ffffff3f712005470d14200541057422074100480d140240024020060d002007102821080c010b20012802d80420064105742007102c21080b2008450d02200120083602d8040b20012802d804220720064105746a220820012903a008370000200841086a200c290300370000200841106a200b290300370000200841186a200a290300370000200641016a21060b20014188076a41086a22084200370300200142003703880741aef2c200411520014188076a1008200141f0056a41086a200829030037030020012001290388073703f0050240024020070d00200141f0056a411010090c010b410110282208450d0220014281808080103702a408200120083602a008200820093a00002006200141a0086a10b40102402006450d00200641057421082007210603402001200141a0086a3602c0092006200141c0096a10c801200641206a2106200841606a22080d000b0b20012802a4082106200141f0056a411020012802a008220820012802a808100702402006450d002008102a0b2007450d002005450d002007102a0b20014188076a41086a22084200370300200142003703880741d4f2c200410d20014188076a1008200141f0056a41086a2206200829030037030020012001290388073703f005200141f0056a4110100920084200370300200142003703880741eea0c600411120014188076a10082006200829030037030020012001290388073703f005200141f0056a41101009411210282206450d02200641106a41002f00f1f2423b0000200641086a41002900e9f242370000200641002900e1f242370000200141d8046a41186a22074200370300200141d8046a41106a22054200370300200141d8046a41086a22094200370300200142003703d80420064112200141d8046a100020014188076a41186a200729030037030020014188076a41106a200529030037030020082009290300370300200120012903d804370388072006102a20014188076a4120100e2000280200211010eb0220104105490d07200141f0056a41086a22064200370300200142003703f0054193cdc2004111200141f0056a1008200141a0086a41086a2006290300370300200120012903f0053703a008200141003602c009200141a0086a4110200141c0096a100621060240024020012802c0092208417f460d002006450d002001200836028c072001200636028807200141c0096a20014188076a107b20012802c009220a450d0520012902c409210f2008450d012006102a0c010b4104210a4200210f0b2010417b6a2105200a200f422088a7220b41c4006c22066a21090240200641cd014f0d0041002106200a21080c060b200a41d0016a21084100210603400240200841b07e6a22072d00004101460d00200841b47e6a28020020054f0d080b0240200741c4006a2d00004101460d00200841f87e6a2802002005490d00200641016a21060c080b024020074188016a2d00004101460d00200841bc7f6a2802002005490d00200641026a21060c080b02400240200741cc016a2d00004101460d00200828020020054f0d010b20084190026a2108200641046a2106200920074190026a6b41cc014d0d060c010b0b200641036a21060c060b200741011037000b410141011037000b411241011037000b41c4d1c3004133200141f0056a419cd9c3001038000b200841b07e6a21080b20082009460d00200a200b41c4006c6a21070340024020082d00004101460d00200841046a28020020054f0d020b200641016a21062007200841c4006a2208470d000b0b2006200b4b0d01200f42ffffffff0f83210f0240200b20066b2208450d0002402006450d00200a200a200641c4006c6a200841c4006c109b051a0b2008ad422086200f84210f0b200141f0056a41086a22064200370300200142003703f0054193cdc2004111200141f0056a1008200141a0086a41086a2006290300370300200120012903f0053703a008200141c0096a200a200f422088a7109202200141a0086a411020012802c009220820012802c8091007200fa72106024020012802c409450d002008102a0b2006450d00200a102a0b200141003a00c009200141f0056a41086a22064200370300200142003703f00541c8fbc5004117200141f0056a1008200141a0086a41086a22082006290300370300200120012903f0053703a008200141a0086a4110200141c0096a41011007200141a0086a10f801412410282206450d01200620012903a00837000020064114360220200641186a200141a0086a41186a290300370000200641106a200141a0086a41106a290300370000200641086a200829030037000020014281808080103702c409200120063602c009200141c0096a10f901201010ea0202400240201041809c3170450d0020014188076a21110c010b200141f0056a41086a22064200370300200142003703f00541d590c600411f200141f0056a100820014188076a41086a2006290300370300200120012903f00537038807200141003602a00820014188076a4110200141a0086a1006210602400240024020012802a0082208417f460d002006450d002008450d0120062d000021082006102a20014188076a4110100920084102460d0020084101710d020b20014188076a2111201010c803450d02201010c9031a0c020b41c4d1c3004133200141f0056a419cd9c3001038000b20014188076a2111201010c903450d00201010c8031a0b200141f0056a41086a22064200370300200142003703f00541c290c6004113200141f0056a100820014188076a41086a2006290300370300200120012903f0053703880741002106200141003602a00820114110200141a0086a10062108024020012802a0082207417f460d002008450d0020074104490d03200828000021062008102a0b200141f0056a41086a22084200370300200142003703f00541a990c6004119200141f0056a100820014188076a41086a2008290300370300200120012903f0053703880741002108200141003602a00820114110200141a0086a10062107024020012802a0082205417f460d002007450d0020054104490d04200728000021082007102a0b02400240200620084f0d0002400340200141c0096a200610ca0320012802c00922074113470d012008200641016a2206470d000c020b0b20014188076a200141c0096a410472419401109a051a200141f0056a20014188076a419401109a051a200141d8046a200141f0056a419401109a051a200120073602a80820012006ad220f3703a008200141ac086a200141d8046a419401109a052105200141b0096a2802002010460d01200141a8086a106a0b4108211241002106410021130c080b200141c0036a2005419401109a051a200141a0086a200141c0036a419401109a051a41a00110282212450d04201220073602082012200f3703002012410c6a200141a0086a419401109a051a02400240200641016a220720084f0d000340200141c0096a200710ca0320012802c00922054113470d022008200741016a2207470d000b0b41012106410121130c080b20014188076a200141c0096a410472220c419401109a051a200141f0056a20014188076a419401109a051a200141d8046a200141f0056a419401109a051a200120053602a80820012007ad220f3703a008200141a0086a410c6a200141d8046a419401109a05210a41012106200141a8086a210b200141b0096a2802002010470d06200741016a2107200141c0036a200a419401109a051a41012106410121130340200141a0086a200141c0036a419401109a051a024020132006470d00200641016a22092006490d0c2006410174220d2009200d20094b1b2213ad42a0017e2214422088a70d0c2014a722094100480d0c024002402006450d002012200641a0016c2009102c21120c010b2009102821120b2012450d070b2012200641a0016c6a220920053602082009200f3703002009410c6a200141a0086a419401109a051a200641016a2106200720084f0d0802400340200141c0096a200710ca03024020012802c00922054113460d0020014188076a200c419401109a051a200141f0056a20014188076a419401109a051a200141d8046a200141f0056a419401109a051a200120053602a80820012007ad220f3703a008200a200141d8046a419401109a05210920012802b0092010470d02200741016a2107200141c0036a2009419401109a051a0c030b2008200741016a2207470d000c0a0b0b0b200b106a0c070b41e4e8c5001032000b412441041037000b41c4d1c3004133200141f0056a419cd9c3001038000b41c4d1c3004133200141f0056a419cd9c3001038000b41a00141081037000b200941081037000b200b106a410121130b2012200641a0016c6a2115024020060d00201221160c020b20014188076a4104722106200141a0086a410472211720014198026a41086a21182012211603402016280200210520162802082108200141a0086a2016410c6a419401109a051a201641a0016a211620084113460d02200141c0096a200141a0086a419401109a051a200120083602a0082017200141c0096a419401109a051a200141f0056a200510cb0320012802f005210b0240024020012802f80522080d00420021194200211a4200211b4200211c4200211d4200211e0c010b200841057421094200211d200b21084200211e4200211b4200211c420021194200211a034020014198036a2008109d0220014198036a41086a2903002114200129039803210f20062008290000370000200641086a200841086a290000370000200641106a200841106a290000370000200641186a200841186a290000370000200120053602880720014190036a20014188076a10cc0320012d00900341017121070240024020012d009103220a0d00200141d0026a200f2014420a420010a00520012903d002221f210f200141d0026a41086a290300222021140c010b200141f0026a20144200200aad221f4200109f0520014180036a200f4200201f4200109f05200141e0026a42004200200f4200109f05427f20014180036a41086a290300221f20012903f00220012903e0027c7c222020012903f80220012903e802844200522020201f5472220a1b2120427f200129038003200a1b211f0b200841206a21084200202020071b201c7c4200201f20071b2221201b7c221b202154ad7c211c2020420020071b201a7c201f420020071b221f20197c2219201f54ad7c211a2014201e7c200f201d7c221d200f54ad7c211e200941606a22090d000b0b024020012802f405450d00200b102a0b200141f0056a200510cb0320012802f00521000240024020012802f80522080d004200212142002122420021234200212442002120420021250c010b2008410574210942002120200021084200212542002123420021244200212142002122034020062008290000370000200641086a200841086a2207290000370000200641106a200841106a220a290000370000200641186a200841186a220b2900003700002001200536028807200141c8026a20014188076a10cc0320012d00c802210c20012d00c902210d20014188076a41186a200b29000037030020014188076a41106a200a29000037030020014188076a41086a20072900003703002001200829000037038807200141a8026a200520014188076a200d411010cd03200141a8026a41186a29030020257c20012903b802220f20207c2220200f54ad7c21254200200141a8026a41086a290300220f200c41017122071b20247c420020012903a802221420071b221f20237c2223201f54ad7c2124200f420020071b20227c2014420020071b220f20217c2221200f54ad7c2122200841206a2108200941606a22090d000b0b024020012802f405450d002000102a0b20014198026a10a1022018290300210f2001290398022114024002402020201d7c221f4202882025201e7c201f202054ad7c2220423e8684221d2020420288221e84500d00201d201f85201e20208584500d00410021080240034020014188026a201f2020200841046a41fe0071109e05200841026a2108200129038802221d20014188026a41086a290300221e84500d01201d201f85201e2020858450450d000b0b200141f8016a201f2020200841fe0071109e0520012903f801200141f8016a41086a29030084211d4200211e024020080d00201d420052ad211d0c020b201d420052ad211d0340200141d8016a201f202041002008417e6a2207200720084b1b220841ff0071109e05200141e8016a201d42018622264201842225201e420186201d423f8884221e2025201e109f052026202520012903e80120012903d80156200141e8016a41086a290300221d200141d8016a41086a290300222756201d2027511b1b211d20080d000c020b0b4200211e201f202084420052ad211d0b024002402014420288200f423e8684221f200f420288222084500d00201f2014852020200f8584500d004100210802400340200141c8016a2014200f200841046a41fe0071109e05200841026a210820012903c801221f200141c8016a41086a290300222084500d01201f2014852020200f858450450d000b0b200141b8016a2014200f200841fe0071109e0520012903b801200141b8016a41086a29030084211f42002120024020080d00201f420052ad211f0c020b201f420052ad211f034020014198016a2014200f41002008417e6a2207200720084b1b220841ff0071109e05200141a8016a201f420186222642018422252020420186201f423f8884222020252020109f052026202520012903a80120012903980156200141a8016a41086a290300221f20014198016a41086a290300222756201f2027511b1b211f20080d000c020b0b420021202014200f84420052ad211f0b02400240024002400240201d201e8450450d004100210b0c010b2024201c7c2023201b7c2214202354ad7c21232022201a7c202120197c220f202154ad7c212102400240024020012d00b0090e03010200010b200f201456202120235620212023511b210b0c020b0340200141c8006a20142023201d201e10a005201f22192020221a844200510d04200141c8006a41086a290300211f20012903482120200141386a200f20212019201a10a0054101210b20202001290338221b54201f200141386a41086a290300222554201f20255122081b0d020240201b2020542025201f5420081b450d004100210b0c030b200141286a2020201f201d201e109f05200141186a201b20252019201a109f050240200f2001290318221f7d22202021200141186a41086a2903007d200f201f54ad7d222584500d002023200141286a41086a2903007d211b20142001290328220f5421082014200f7d211f201d210f201e21212020211d2025211e20192114201a2123201f201b2008ad7d222084500d030c010b0b4100210b0c010b0340201e2125201d2119201f2020844200510d02200141f8006a200f20212019202510a00520014188016a20142023201f202010a0054101210b200129038801221a2001290378221b5420014188016a41086a290300221d200141f8006a41086a290300221e54201d201e5122081b0d010240201b201a54201e201d5420081b450d004100210b0c020b200141e8006a201a201d201f2020109f05200141d8006a201b201e20192025109f050240200f2001290358221d7d221e2021200141d8006a41086a2903007d200f201d54ad7d221a8450450d004100210b0c020b2023200141e8006a41086a2903007d211b20142001290368220f5421082014200f7d211d201f210f20202121201e211f201a21202019211420252123201d201b2008ad7d221e844200520d000b0b20014188076a200510cb032001280288072128200128028c0721292001280290072208450d0220282008410574222a6a212b2028210802400340200141f0056a41186a2207200841186a220c290000370300200141f0056a41106a2209200841106a220d290000370300200141f0056a41086a220a200841086a2200290000370300200120082900003703f0052008290000210f200641186a222c200c2900003700002006200f370000200641086a222d2000290000370000200641106a222e200d2900003700002001200536028807200141106a20014188076a10cc0320012d0011210e20012d0010212f20014188076a41186a220c200729030037030020014188076a41106a220d200929030037030020014188076a41086a2200200a290300370300200120012903f005370388070240200b202f41017145734101470d00200841206a21080c020b200841206a2108202a41606a222a0d000c040b0b0340200141d8046a41186a200c290300220f370300200141d8046a41106a200d2903002214370300200141d8046a41086a2000290300221f370300200120012903880722203703d804200c200f370300200d20143703002000201f370300200142e4cab5fbb6ccdcb0e3003703a8032001202037038807200141a8036a20014188076a200e41187441187541027441f48fc6006a2802004180de346c20106a10a8022008202b460d03024003402007200841186a220e2900003703002009200841106a222f290000370300200a200841086a222a290000370300200120082900003703f0052001200536028807202a290000210f202f29000021142008290000211f202c200e290000370000202e2014370000202d200f3700002006201f370000200141086a20014188076a10cc0320012d0009210e20012d0008212f200c2007290300370300200d20092903003703002000200a290300370300200120012903f00537038807200b202f41017145730d01202b200841206a2208470d000c050b0b200841206a21080c000b0b41f895c1001032000b41f895c1001032000b02402029450d002028102a0b200510ce0302400240200b0d00200141053a009007200141053a00880720012005360294074101410020014188076a10cc01200141f0056a41086a22084200370300200142003703f00541c290c6004113200141f0056a100820014188076a41086a2008290300370300200120012903f005370388072001200541016a3602f00520114110200141f0056a41041007200141a0086a106a0c010b2001200536029407200141043a009007200141053a0088074101410020014188076a10cc01024020012802ac092207450d00200141f0056a200141a0086a418801109a051a200120053602f80602400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240411710282208450d002008410f6a41002900918945220f370000200841086a410029008a89452214370000200841002900828945221f37000020084117412e102c2208450d012008200720106a2200360017200141d8046a41186a22074200370300200141d8046a41106a22094200370300200141d8046a41086a220a4200370300200142003703d8042008411b200141d8046a100020014188076a41186a220e200729030037030020014188076a41106a222f200929030037030020014188076a41086a220c200a290300370300200120012903d804370388072008102a200141003602d80420014188076a4120200141d8046a1006210b0240024020012802d8042208417f470d00200141003602e004200142013703d8044100200141d8046a10b40120012802e004210820012802dc04210d20012802d804210b0c010b2008210d0b200120083602b8032001200d3602b4032001200b3602b003024002400240024002402008450d00200141d8046a200b2008410110d60220012802d8044101460d0420012802dc04212a20012802e404220820012802e004220b460d0320012802b8032008200b6b6a220d4190016a222c417f4c0d1f202c0d014101212d0c020b4101200141b0036a10b40120012802b403210b20012802b8032108024020012802f0054113470d0002400240200b2008460d0020012802b003210b0c010b200841016a220b2008490d222008410174220d200b200d200b4b1b220d4100480d220240024020080d00200d1028210b0c010b20012802b0032008200d102c210b0b200b450d082001200d3602b4032001200b3602b00320012802b80321080b2001200841016a3602b803200b20086a41003a00000c150b02400240200b2008460d0020012802b003210b0c010b200841016a220b2008490d212008410174220d200b200d200b4b1b220d4100480d210240024020080d00200d1028210b0c010b20012802b0032008200d102c210b0b200b450d082001200d3602b4032001200b3602b00320012802b80321080b2001200841016a3602b803200b20086a41013a0000200141f0056a200141b0036a10eb01200141f0056a4188016a280200210d0240024020012802b403220b20012802b80322086b4104490d0020012802b003210b0c010b200841046a222a2008490d21200b4101742208202a2008202a4b1b22084100480d2102400240200b0d0020081028210b0c010b20012802b003200b2008102c210b0b200b450d09200120083602b4032001200b3602b00320012802b80321080b2001200841046a3602b803200b20086a200d3600000c140b202c1028222d450d080b2001202c3602dc0a2001202d3602d80a2001200d3602e00a2001200141d80a6a3602d804202a200141d8046a200810d701200d2008490d0820012802e00a222a200d490d0920012802b803222a200b490d0a20012802d80a212c20012802b003212d2001200d20086b220d3602e80a2001202a200b6b222a3602ec0a200d202a470d0b202c20086a202d200b6a200d109a051a20012802dc0a210b20012802e00a21080240024020012802f0054113470d0002400240200b2008460d0020012802d80a210b0c010b200841016a220b2008490d212008410174220d200b200d200b4b1b220d4100480d210240024020080d00200d1028210b0c010b20012802d80a2008200d102c210b0b200b450d0f2001200d3602dc0a2001200b3602d80a20012802e00a21080b2001200841016a3602e00a200b20086a41003a00000c010b02400240200b2008460d0020012802d80a210b0c010b200841016a220b2008490d202008410174220d200b200d200b4b1b220d4100480d200240024020080d00200d1028210b0c010b20012802d80a2008200d102c210b0b200b450d0f2001200d3602dc0a2001200b3602d80a20012802e00a21080b2001200841016a3602e00a200b20086a41013a0000200141f0056a200141d80a6a10eb01200141f0056a4188016a280200210d0240024020012802dc0a220b20012802e00a22086b4104490d0020012802d80a210b0c010b200841046a222a2008490d20200b4101742208202a2008202a4b1b22084100480d2002400240200b0d0020081028210b0c010b20012802d80a200b2008102c210b0b200b450d10200120083602dc0a2001200b3602d80a20012802e00a21080b2001200841046a3602e00a200b20086a200d3600000b20012802e00a210b20012802dc0a210d20012802d80a210820012802b403450d1320012802b003102a0c130b2001200141b0036a3602d804202a200141d8046a200b10d70120012802b403210b20012802b8032108024020012802f0054113470d0002400240200b2008460d0020012802b003210b0c010b200841016a220b2008490d1f2008410174220d200b200d200b4b1b220d4100480d1f0240024020080d00200d1028210b0c010b20012802b0032008200d102c210b0b200b450d102001200d3602b4032001200b3602b00320012802b80321080b2001200841016a3602b803200b20086a41003a00000c120b02400240200b2008460d0020012802b003210b0c010b200841016a220b2008490d1e2008410174220d200b200d200b4b1b220d4100480d1e0240024020080d00200d1028210b0c010b20012802b0032008200d102c210b0b200b450d102001200d3602b4032001200b3602b00320012802b80321080b2001200841016a3602b803200b20086a41013a0000200141f0056a200141b0036a10eb01200141f0056a4188016a280200210d0240024020012802b403220b20012802b80322086b4104490d0020012802b003210b0c010b200841046a222a2008490d1e200b4101742208202a2008202a4b1b22084100480d1e02400240200b0d0020081028210b0c010b20012802b003200b2008102c210b0b200b450d11200120083602b4032001200b3602b00320012802b80321080b2001200841046a3602b803200b20086a200d3600000c110b20012802b403450d1220012802b003102a0c120b411741011037000b412e41011037000b200d41011037000b200d41011037000b200841011037000b202c41011037000b2008200d1044000b200d202a103c000b200b202a1044000b200141c0036a41146a4108360200200141cc036a4125360200200141f00a6a41146a4103360200200142033702f40a200141c8afc6003602f00a200141253602c4032001200141e80a6a3602880b2001200141ec0a6a36028c0b200142043703e804200142013702dc042001419cb0c6003602d8042001200141c0036a3602800b2001200141d8046a3602d00320012001418c0b6a3602c8032001200141880b6a3602c003200141f00a6a41d8b0c600103e000b200d41011037000b200d41011037000b200841011037000b200d41011037000b200d41011037000b200841011037000b20012802b803210b20012802b403210d20012802b00321080b2008450d0020014188076a41202008200b1007200d450d012008102a0c010b41900110282208450d014113210b024020012802f0054113460d0020014188076a200141f0056a10cf032001200141f0056a4188016a28020036029008200128028807210b200141d8046a2006418c01109a051a0b2008200b360200200841046a200141d8046a418c01109a051a41171028220b450d02200b410f6a200f370000200b41086a2014370000200b201f370000200b4117412e102c220b450d03200b20003600172007420037030020094200370300200a4200370300200142003703d804200b411b200141d8046a1000200e2007290300370300202f2009290300370300200c200a290300370300200120012903d80437038807200b102a200141d8046a2008410110ac0220014188076a412020012802d804220720012802e0041007024020012802dc04450d002007102a0b024020082802004113460d002008106a0b2008102a0b024020012802f0054113460d00200141f0056a106a0b200141f0056a41086a22084200370300200142003703f00541c290c6004113200141f0056a1008200c2008290300370300200120012903f005370388072001200541016a3602f00520114110200141f0056a410410070c040b41900141081037000b411741011037000b412e41011037000b20014188076a200141a0086a418801109a051a200141003b01f005200141d8046a20014188076a200141f0056a10f401200120012d00e0044102463a009107200141073a009007200141053a00880720012005360294074101410020014188076a10cc01200141f0056a41086a22084200370300200142003703f00541c290c6004113200141f0056a100820014188076a41086a2008290300370300200120012903f005370388072001200541016a3602f00520114110200141f0056a410410070b20162015470d000b201521160c010b1036000b024020162015460d00200141a0086a41086a2108200141a0086a410c6a21070340201641086a28020021062016290300210f200141a0086a2016410c6a419401109a051a20064113460d01200141c0096a200141a0086a419401109a051a200120063602a8082001200f3703a0082007200141c0096a419401109a051a2008106a201641a0016a22162015470d000b0b02402013450d002012102a0b0240024002400240411710282206450d002006410f6a41002900918945370000200641086a410029008a894537000020064100290082894537000020064117412e102c2206450d01200620103600174200210f200141d8046a41186a22084200370300200141d8046a41106a22074200370300200141d8046a41086a22054200370300200142003703d8042006411b200141d8046a100020014188076a41186a200829030037030020014188076a41106a200729030037030020014188076a41086a2005290300370300200120012903d804370388072006102a200141003602a00820014188076a4120200141a0086a100621080240024020012802a0082206417f470d004108210b0c010b200120063602c409200120083602c009200141a0086a200141c0096a10800120012802a008220b450d0320012902a408210f02402006450d002008102a0b20014188076a412010090b200b200f422088a722084190016c22076a2105200b210602402008450d00200741f07e6a2107200141a0086a410472210a200b21060240034020062802002108200141c0096a200641046a418401109a051a20084114460d01200141a0086a200141c0096a418401109a051a02400240024020084113470d0020070d01200521060c050b20064188016a280200210920014188076a200141a0086a418401109a051a200120083602a008200a20014188076a418401109a051a200141003b01c009200141f0056a200141a0086a200141c0096a10f40120012d00f8052108200120093602ac08200120084102463a00a908200141073a00a808200141053a00a00841014100200141a0086a10cc012007450d010b20064190016a2106200741f07e6a21070c010b0b200521060c010b20064190016a21060b200fa7210920062005460d03200141a0086a4104722107034020062802002108200141a0086a200641046a418c01109a051a20084114460d04200141c0096a200141a0086a418c01109a051a200120083602a0082007200141c0096a418c01109a051a024020084113460d00200141a0086a106a0b20064190016a22062005470d000c040b0b411741011037000b412e41011037000b41c4d1c3004133200141f0056a419cd9c3001038000b02402009450d00200b102a0b201010bd0202402002450d00200241246c21082004210603400240024020062d0000220741034b0d0002400240024020070e0404000102040b2006410c6a280200450d03200641086a280200102a0c030b2006410c6a280200450d02200641086a280200102a0c020b2006410c6a280200450d01200641086a280200102a0c010b200641086a280200450d00200641046a280200102a0b200641246a21062008415c6a22080d000b0b02402003450d002004102a0b200141900b6a24000f0b1031000be80201067f230041b0026b2201240020014198016a41086a22024200370300200142003703980141988bc500411620014198016a100820014188016a41086a2203200229030037030020012001290398013703880120014198016a20014188016a10df030240024020012802980122044113470d0041ae8bc50021020c010b20014188016a41101009200141046a20014198016a4104722205418401109a051a200141a0026a2d00002106200141013a00af0220024200370300200142003703980141d590c600411f20014198016a10082003200229030037030020012001290398013703880120014188016a4110200141af026a41011007200241023a0000200141053a009801410021024101410020014198016a10cc0120012004360298012005200141046a418401109a051a20014188016a200041809c316a20014198016a20064180de3410b7042001280288014101470d00200128028c0121020b200141b0026a240020020bc01802117f187e230041f0056b22012400200141a0046a41086a22024200370300200142003703a00441ac89c5004115200141a0046a1008200141306a41086a2002290300370300200120012903a004370330200141003602a004200141306a4110200141a0046a10062103024002400240024002400240024002400240024020012802a0042204417f460d002003450d002001200436024420012003360240200141286a200141c0006a106c20012802280d09200128024441b0016e220541b0016c2202417f4c0d02200128022c21060240024020020d00410821070c010b200210282207450d040b02402006450d0020014198036a4104722108410021094100210a0340024002400240200128024422024104490d002001280240220b280000210c20012002417c6a3602442001200b41046a360240200141a0046a200141c0006a10810120012802a0044113460d00200a41016a210d20014198036a200141a0046a418801109a051a4100210b200141003a00e8052001280244417f6a2102024003402002417f460d01200141c8056a200b6a2001280240220e2d00003a00002001200e41016a3602402001200b41016a220e3a00e805200120023602442002417f6a2102200e210b200e4120470d000b200141a8056a41186a2202200141c8056a41186a290300370300200141a8056a41106a220e200141c8056a41106a290300370300200141a8056a41086a220f200141c8056a41086a290300370300200120012903c8053703a805200128029803210b20014190026a2008418401109a051a200141f0016a41086a2210200f290300370300200141f0016a41106a220f200e290300370300200141f0016a41186a220e2002290300370300200120012903a8053703f001200b4113460d01200141ec006a20014190026a418401109a051a200141c8006a41186a2211200e290300370300200141c8006a41106a220e200f290300370300200141c8006a41086a220f2010290300370300200120012903f0013703482005200a470d030240200a4101742202200d2002200d4b1b2205ad42b0017e2212422088a70d002012a7220241004e0d030b1031000b0240200b41ff0171450d00200141003a00e8050b20014198036a106a0b0240200a450d002007210203402002106a200241b0016a2102200941d07e6a22090d000b0b2005450d0d2007102a0c0d0b02400240200a0d002002102821070c010b2007200a41b0016c2002102c21070b2007450d070b2007200a41b0016c6a2202200b360200200241046a200141ec006a418401109a051a2002200c360288012002200129034837028c0120024194016a200f2903003702002002419c016a200e290300370200200241a4016a2011290300370200200941b0016a2109200d210a200d2006470d000b0b2007450d092006ad42208621122005ad211302402004450d002003102a0b201220138421140c010b41082107420021140b024002402014422088a72204450d00200141a0046a20072802880110b8040240024020012802b00422020d0042002115420021120c010b200141186a20012903a004200141a0046a41086a290300200141b8046a3502004200109f05200141186a41086a29030021122001290318211520012802b404450d002002102a0b4100210e20044101460d012007200441b0016c6a210a200741b0016a21024100210e200721034101210b0340200141a0046a20024188016a28020010b8040240024020012802b00422090d0042002116420021130c010b200141086a20012903a004200141a0046a41086a29030020013502b8044200109f05200141086a41086a29030021132001290308211620012802b404450d002009102a0b201220132015201656201220135620122013511b22091b21122015201620091b21152003200220091b2103200e200b20091b210e200b41016a210b200241b0016a2202200a470d000b20030d01200441b0016c21092007210203402002106a200241b0016a2102200941d07e6a22090d000b0b41e789c50021022014a7450d072007102a0c070b200e20044f0d0320072004417f6a220941b0016c6a22024180016a290300211320024188016a290300211520024190016a290300211620024198016a2903002117200241e0006a2903002118200241e8006a2903002119200241f0006a290300211a200241f8006a290300211b200241c0006a290300211c200241c8006a290300211d200241d0006a290300211e200241d8006a290300211f200241206a2903002120200241286a2903002121200241306a2903002122200241386a2903002123200229030021242002290308212520022903102126200241186a2903002127200241a0016a2903002112200141306a41086a220b200241a8016a29030022283703002007200e41b0016c6a220241186a220e2903002129200e2027370300200229031021272002202637031020022903082126200220253703082002290300212520022024370300200241386a220e2902002124200e2023370200200241306a220e2902002123200e2022370200200241286a220e2902002122200e2021370200200241206a220e2902002121200e2020370200200241d8006a220e2902002120200e201f370200200241d0006a220e290200211f200e201e370200200241c8006a220e290200211e200e201d370200200241c0006a220e290200211d200e201c370200200241f8006a220e290200211c200e201b370200200241f0006a220e290200211b200e201a370200200241e8006a220e290200211a200e2019370200200241e0006a220e2902002119200e201837020020024198016a201737020020024190016a201637020020024188016a2203280200210e2003201537020020024180016a220329020021152003201337020020012012370330200241a0016a2012370200200241a8016a202837020020014198036a41f8006a201c37030020014198036a41f0006a201b37030020014198036a41e8006a201a37030020014198036a41e0006a201937030020014198036a41d8006a202037030020014198036a41d0006a201f37030020014198036a41c8006a201e37030020014198036a41c0006a201d37030020014198036a41386a202437030020014198036a41306a202337030020014198036a41286a202237030020014198036a41206a202137030020014198036a41186a202937030020014198036a4180016a2015370300200120273703a803200120263703a0032001202537039803200141a0046a41086a22024200370300200142003703a00441ac89c5004115200141a0046a1008200b2002290300370300200120012903a004370330200141103602a4042001200141306a3602a00420072009200141a0046a10ef0102402009450d00200441b0016c41d07e6a21092007210203402002106a200241b0016a2102200941d07e6a22090d000b0b02402014a7450d002007102a0b411310282202450d042002410f6a41002800e38945360000200241086a41002900dc8945370000200241002900d48945370000200241134126102c2202450d052002200e360013200141a8056a41186a22094200370300200141a8056a41106a220b4200370300200141a8056a41086a22034200370300200142003703a80520024117200141a8056a100020014190026a41186a200929030037030020014190026a41106a200b29030037030020014190026a41086a2003290300370300200120012903a805370390022002102a200141a0046a20014190026a10e003024020012802b004220b450d0020014190026a412010090b02400240200b450d00200141a8046a290300211220012903a004211320012802b40421030240200141a0046a41186a280200220a4105742209450d00200b2102034020022013201210aa02200241206a2102200941606a22090d000b0b200141c8046a2012370300200141c0046a2013370300200141b8046a200a360200200141b4046a2003360200200141b0046a200b360200200141ac046a200e360200200141a8046a41013a0000200141053a00a00441014100200141a0046a10cc01200141a0046a20014198036a418801109a051a20014190026a200041809c316a200141a0046a41004180de3410b7042001280290024101470d0120012802940221020c080b20014198036a106a0b410021020c060b1036000b200241081037000b200241081037000b41c489c500200e20041034000b411341011037000b412641011037000b200141f0056a240020020f0b41c4d1c3004133200141a0046a419cd9c3001038000b810601067f230041d0026b2202240002400240024002400240411a10282203450d00200341186a41002f00ce88453b0000200341106a41002900c68845370000200341086a41002900be8845370000200341002900b688453700002003411a4134102c2203450d012003200136001a200241c0016a41186a22014200370300200241c0016a41106a22044200370300200241c0016a41086a22054200370300200242003703c0012003411e200241c0016a1000200241186a2001290300370300200241106a2004290300370300200241086a2005290300370300200220022903c0013703002003102a200241003602c00120024120200241c0016a1006210320022802c0012201417f460d032003450d03200220033602282002200136022c20014104490d022003280000210620022001417c6a36022c2002200341046a360228200241c0016a200241286a10810120022802c0014113460d02200241386a200241c0016a418801109a051a02400240200228022c2207450d00200228022822012d0000210420022007417f6a220536022c2002200141016a360228200441034f0d00200541034b0d01200241386a106a0c040b200241386a106a0c030b2001280001210520022007417b6a36022c2002200141056a36022820022802382101200241c0016a200241386a410472418401109a051a200220022800303602202002200241336a28000036002320014113460d02200241386a200241c0016a418401109a051a20022002280023360033200220022802203602302003102a0c040b411a41011037000b413441011037000b41c4d1c3004133200241c8026a419cd9c3001038000b411321010b200241c0016a200241386a418401109a051a2002200228003336002b200220022802303602280240024020014113470d00200041133602000c010b20002001360200200041046a200241c0016a418401109a051a20004190016a20043a00002000418c016a200536020020004188016a2006360200200020022802283600910120004194016a200228002b3600000b200241d0026a24000bfb0202047f017e230041d0006b22022400024002400240411310282203450d002003410f6a41002800a88945360000200341086a41002900a18945370000200341002900998945370000200341134126102c2203450d0120032001360013200241286a41186a22014200370300200241286a41106a22044200370300200241286a41086a220542003703002002420037032820034117200241286a1000200241186a2001290300370300200241106a2004290300370300200241086a2005290300370300200220022903283703002003102a2002410036022820024120200241286a100621010240024020022802282203417f460d002002200336022420022001360220200241286a200241206a106d20022802282204450d04200229022c210602402003450d002001102a0b20002006370204200020043602000c010b20004100360208200042013702000b200241d0006a24000f0b411341011037000b412641011037000b41c4d1c3004133200241c8006a419cd9c3001038000ba40301057f230041d0006b22022400024002400240411010282203450d00200341002900a68845370000200341086a41002900ae88453700002002429080808080023702242002200336022020012802002104200341104120102c2203450d0120032004360010200242a0808080c00237022420022003360220200141046a200241206a108f012002280228210320022802202101200241306a41186a22044200370300200241306a41106a22054200370300200241306a41086a220642003703002002420037033020012003200241306a1000200241186a2004290300370300200241106a2005290300370300200241086a20062903003703002002200229033037030002402002280224450d002002280220102a0b410021032002410036023020024120200241306a100621010240024020022802302204417f470d00410021010c010b2004450d0320012d0000220441ff0071220341074f0d032001102a200441077621010b200020033a0001200020013a0000200241d0006a24000f0b411041011037000b412041011037000b41c4d1c3004133200241306a419cd9c3001038000bf00b04017f047e117f087e23004190046b22052400024002400240024020040d00420021064200210742002108420021090c010b42002108200541f0036a41186a220a4200370300200541f0036a41106a220b4200370300200541f0036a41086a220c4200370300200542003703f00341e588c500411d200541f0036a100020054198036a41186a220d200a29030037030020054198036a41106a220e200b29030037030020054198036a41086a220f200c290300370300200520052903f0033703980320054198016a20054198036a412010fd01200541c0016a41206a20054198016a41206a2d00003a0000200541c0016a41186a20054198016a41186a290300370300200541c0016a41106a20054198016a41106a290300370300200541c0016a41086a20054198016a41086a29030037030020052005290398013703c001200541e8016a200541c0016a10af0142002109420021064200210720052d00a8024107460d002004417f6a2110200541b8036a4104722111200541f0026a2112200541b0026a41206a2113200541b0026a41186a211442002106420021074200210842002109034020142007370300200520063703c002200520083703b002200520093703b8022013200541e8016a41c100109a0521040240024020122002460d00201220024120109c050d010b20112004290200370200201141086a200441086a2215290200370200201141106a200441106a2216290200370200201141186a200441186a2217290200370200200520013602b803411010282218450d03201841002900a68845370000201841086a41002900ae88453700002005429080808080023702e403200520183602e00320052802b8032119201841104120102c2218450d04200541203602e403200520052802e803221a41046a3602e803200520183602e0032018201a6a20193600002011200541e0036a108f0120052802e803211820052802e0032119200a4200370300200b4200370300200c4200370300200542003703f00320192018200541f0036a1000200d200a290300370300200e200b290300370300200f200c290300370300200520052903f00337039803024020052802e403450d0020052802e003102a0b20054198036a41204101410041001003417f470d0020052d0090032118200a2017290000370300200b2016290000370300200c2015290000370300200520042900003703f00320054188016a200541f0036a109d0220054188016a41086a290300211b200529038801211c02400240201820032018200341ff0171491b220441ff01710d00200541086a201c201b420a420010a005200541b8036a41186a200a290300370300200541b8036a41106a200b290300370300200541b8036a41086a200c290300370300200520052903f0033703b803200541186a2001200541b8036a4100201010cd03200541186a41186a290300211d200541186a41086a290300211e2005290328211f2005290318212020052903082221211c200541086a41086a2903002222211b0c010b200541c8006a201b42002004ad42ff018322214200109f05200541d8006a201c420020214200109f05200541b8036a41186a200a290300370300200541b8036a41106a200b290300370300200541b8036a41086a200c290300370300200520052903f0033703b803200541e8006a2001200541b8036a2004201010cd03200541386a42004200201c4200109f05427f200541d8006a41086a2903002221200529034820052903387c7c221d2005290350200529034084420052201d2021547222041b2122427f200529035820041b2121200541e8006a41186a290300211d200541e8006a41086a290300211e2005290378211f200529036821200b201b20077c201c20067c2207201c54ad7c201d7c2007201f7c2206200754ad7c2107202220097c202120087c2209202154ad7c201e7c200920207c2208200954ad7c21090b200541e8016a200541c0016a10af0120052d00a8024107470d000b0b2000200637031020002008370300200041186a20073703002000200937030820054190046a24000f0b411041011037000b412041011037000be907030b7f047e027f230041a0016b22012400024002400240024002400240411a10282202450d00200241186a41002f00ce88453b0000200241106a41002900c68845370000200241086a41002900be8845370000200241002900b688453700002002411a4134102c2202450d012002200036001a20014180016a41186a2203420037030020014180016a41106a2204420037030020014180016a41086a2205420037030020014200370380012002411e20014180016a1000200141286a41186a2003290300370300200141286a41106a2004290300370300200141286a41086a200529030037030020012001290380013703282002102a200141286a41201009411310282202450d022002410f6a41002800a88945360000200241086a41002900a18945370000200241002900998945370000200241134126102c2202450d032002200036001320014180016a41186a2205420037030020014180016a41106a2206420037030020014180016a41086a2203420037030020014200370380012002411720014180016a1000200141286a41186a22072005290300370300200141286a41106a22082006290300370300200141286a41086a200329030037030020012001290380013703282002102a200141286a41201009200141c8006a200010cb03200128024c21092001280248210a024020012802502202450d002002410574210b200141c8006a4104722103200a21020340200141086a41186a200241186a290000220c370300200141086a41106a200241106a290000220d370300200141086a41086a200241086a290000220e37030020012002290000220f3703082003200f370200200341086a200e370200200341106a200d370200200341186a200c37020020012000360248411010282204450d06200441002900a68845370000200441086a41002900ae88453700002001429080808080023702742001200436027020012802482110200441104120102c2204450d072001412036027420012001280278221141046a36027820012004360270200420116a20103600002003200141f0006a108f012001280278210420012802702110200542003703002006420037030020014180016a41086a2211420037030020014200370380012010200420014180016a10002007200529030037030020082006290300370300200141286a41086a2011290300370300200120012903800137032802402001280274450d002001280270102a0b200241206a2102200141286a41201009200b41606a220b0d000b0b02402009450d00200a102a0b200141a0016a24000f0b411a41011037000b413441011037000b411341011037000b412641011037000b411041011037000b412041011037000b801102047f027e230041e0016b22022400024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024020012802000e1514000102030405060708090a0b0c0d0e0f10111213140b10a103000b20004102360200200041086a200141086a2903003703000c130b200241e0006a200141046a1070200041033602002000410c6a200241e8006a280200360200200020022903603702040c120b10bb03000b200241e0006a200141086a10ae02200041086a200241e0006a41e000109a051a200041053602000c100b200241e0006a200141086a10bc0320004106360200200041386a200241e0006a41306a290300370300200041306a200241e0006a41286a290300370300200041286a200241e0006a41206a290300370300200041206a200241e0006a41186a290300370300200041186a200241e0006a41106a290300370300200041106a200241e0006a41086a290300370300200041086a20022903603703000c0f0b200241e0006a41186a200141286a290000370300200241e0006a41106a200141206a290000370300200241e8006a200141186a290000370300200241e0006a41286a200141386a290000370300200241e0006a41306a200141c0006a290000370300200241e0006a41386a200141c8006a290000370300200241e0006a41c8006a200141d8006a290000370300200241e0006a41d0006a200141e0006a290000370300200241e0006a41d8006a200141e8006a2900003703002002200141106a2900003703602002200141306a290000370380012002200141d0006a2900003703a0012001410c6a2802002203417f4c0d0f200128020421010240024020030d0041012104410021050c010b20032105200310282204450d110b200420012003109a0521012002200241e0006a41e000109a0521042000410c6a2003360200200041086a200536020020002001360204200041106a200441e000109a051a200041073602000c0e0b200241e0006a200141086a10bd0320004108360200200041306a200241e0006a41286a290300370300200041286a200241e0006a41206a290300370300200041206a200241e0006a41186a290300370300200041186a200241e0006a41106a290300370300200041106a200241e0006a41086a290300370300200041086a20022903603703000c0d0b200241e0006a200141046a10c30320004109360200200041246a20024180016a2903003702002000411c6a200241f8006a290300370200200041146a200241f0006a2903003702002000410c6a200241e8006a290300370200200020022903603702040c0c0b200241e0006a200141046a10c3032000410a360200200041246a20024180016a2903003702002000411c6a200241f8006a290300370200200041146a200241f0006a2903003702002000410c6a200241e8006a290300370200200020022903603702040c0b0b200241e0006a200141086a10d3022000410b360200200041c0006a200241e0006a41386a290300370300200041386a200241e0006a41306a290300370300200041306a200241e0006a41286a290300370300200041286a200241e0006a41206a290300370300200041206a200241e0006a41186a290300370300200041186a200241e0006a41106a290300370300200041106a200241e0006a41086a290300370300200041086a20022903603703000c0a0b200241e0006a200141046a10be03200041046a200241e0006a41c400109a051a2000410c3602000c090b2000410d360200200020012802043602040c080b2001410c6a2802002203417f4c0d08200128020421010240024020030d0041002104410121050c010b20032104200310282205450d0b0b200520012003109a0521012000410c6a2003360200200041086a2004360200200020013602042000410e3602000c070b024002400240024002400240200141086a280200417f6a220341024b0d0020030e03010203010b418486c2001032000b200141386a2903002106200141306a290300210741012103024002402001410c6a2d00004101460d00200241e8006a2001411c6a290200370300200241e0006a41106a200141246a290200370300200241f8006a2001412c6a2d00003a00002002200141146a29020037036020012f000d2001410f6a2d0000411074722104200141106a2802002105410021030c010b200141106a28020021050b200241186a200241e0006a41186a280200360200200241106a200241e0006a41106a290300370300200241086a200241e0006a41086a29030037030020022002290360370300410121010c030b2001410c6a28020022034108762104410221010c010b2001410c6a28020022034108762104410321010b0b2000410f360200200041386a2006370300200041306a2007370300200041106a2005360200200041086a2001360200200041146a20022903003702002000410c6a2004410874200341ff0171723602002000411c6a200241086a290300370200200041246a200241106a2903003702002000412c6a200241186a2802003602000c060b200241e0006a200141086a10bf03200041086a200241e0006a418001109a051a200041103602000c050b200241e0006a200141046a10c003200041113602002000412c6a20024188016a280200360200200041246a20024180016a2903003702002000411c6a200241f8006a290300370200200041146a200241f0006a2903003702002000410c6a200241e8006a290300370200200020022903603702040c040b200241e0006a200141046a10af02200041046a200241e0006a41e400109a051a200041123602000c030b10c103000b10d501000b200241e0006a200141086a10c20320004100360200200041106a200241e0006a41086a290300370300200041086a20022903603703000b200241e0016a24000f0b1036000b200341011037000b200341011037000bfe1a03087f047e037f23004180076b22042400200441c8036a200141a002109a051a200441e8016a200441c8036a10d10341012105024002400240024002400240024020042d00e8014101470d00200020042f00e9013b0001200041013a0000200041036a20042d00eb013a000020032802002106410021000c010b200441106a200441e8016a41086a41d801109a051a0240024002400240024002400240024002400240024020032802002206450d00200341086a28020021072003280204210841002109200441003602c8034188e8c2004110200441c8036a10062101024020042802c8032205417f460d002001450d0020054104490d02200128000021092001102a0b411410282201450d0241002105200141106a41002800eaa046360000200141086a41002900e2a046370000200141002900daa046370000200141144128102c2201450d0320012009360014200441e8016a41186a22094200370300200441e8016a41106a220a4200370300200441e8016a41086a220b4200370300200442003703e80120014118200441e8016a1000200441c0066a41186a2009290300370300200441c0066a41106a200a290300370300200441c0066a41086a200b290300370300200420042903e8013703c0062001102a200441203602cc032004200441c0066a3602c80320062007200441c8036a10cb012008450d002006102a0b200441086a200441106a41d0006a10f3012004280208210720042d000c2108200441c8036a200441106a41d801109a051a4100210120042903e803220c4202510d0c20044198066a41186a200441c8036a41186a29030037030020044198066a41106a200441c8036a41106a29030037030020044198066a41086a200441c8036a41086a290300370300200420042903c8033703980620044188046a290300210d20044180046a290300210e20044190046a280200210920042903f003210f200441e8016a41086a22014200370300200442003703e80141d9efc200410d200441e8016a1008200441c0066a41086a2001290300370300200420042903e8013703c006200441003602e801200441c0066a4110200441e8016a10062101024020042802e801220a417f460d002001450d00200a41034d0d042001102a0b0240200c4201520d00200f4200510d050b411310282201450d05200141002900cef0423700002001410f6a41002800ddf042360000200141086a41002900d6f04237000020044293808080b0023702fc05200420013602f80520044198066a200441f8056a108f01200428028006210120042802f805210a200441e8016a41186a220b4200370300200441e8016a41106a22104200370300200441e8016a41086a22114200370300200442003703e801200a2001200441e8016a1000200441c0066a41186a200b290300370300200441c0066a41106a2010290300370300200441c0066a41086a2011290300370300200420042903e8013703c006024020042802fc05450d0020042802f805102a0b200441003602e801200441c0066a4120200441e8016a1006210a0240024020042802e8012201417f470d00410021010c010b0240200a0d00410021010c010b20014104490d07200a2800002101200a102a0b200441c8036a41d0006a210a024020012009470d00411310282201450d0820084101712108200941016a2109200141002900cef0423700002001410f6a41002800ddf042360000200141086a41002900d6f04237000020044293808080b0023702fc05200420013602f80520044198066a200441f8056a108f01200428028006210120042802f805210b200441e8016a41186a22104200370300200441e8016a41106a22114200370300200441e8016a41086a22124200370300200442003703e801200b2001200441e8016a1000200441c0066a41186a2010290300370300200441c0066a41106a2011290300370300200441c0066a41086a2012290300370300200420042903e8013703c006024020042802fc05450d0020042802f805102a0b200420093602e801200441c0066a4120200441e8016a41041007200441e8016a2008200210b803024020042903e801220ca741ff01714101460d00200441e8016a41086a22014200370300200442003703e80141a8a0c6004117200441e8016a1008200441c0066a41086a22092001290300370300200420042903e8013703c0062004200c4220883e02e801200441c0066a4110200441e8016a41041007200441e8016a2007200810b90320042903e801220ca741ff01714101460d0020014200370300200442003703e801418ea0c600411a200441e8016a100820092001290300370300200420042903e8013703c0062004200c4220883e02e801200441c0066a4110200441e8016a410410070c0a0b200c420888a7220941ff01714104460d09200c421088a721010c0a0b41034102200120094b1b2101410021090c090b41c4d1c3004133200441e8016a419cd9c3001038000b411441011037000b412841011037000b41c4d1c3004133200441e8016a419cd9c3001038000b41fcf8c5001032000b411341011037000b41c4d1c3004133200441e8016a419cd9c3001038000b411341011037000b200441e8016a200e200d20044198066a200720082002109e020240024020042d00e8014101460d0020044194026a280200210920044190026a280200210b2004418c026a280200210720044184026a280200211020044180026a2802002108024020044188026a2802002201450d002001410c6c21022008210103400240200141046a280200450d002001280200102a0b2001410c6a2101200241746a22020d000b0b02402010450d002008102a0b02402009450d002009410c6c21022007210103400240200141046a280200450d002001280200102a0b2001410c6a2101200241746a22020d000b0b200b450d012007102a0c010b20042f01ea01210120042d00e9012209417e6a220241024b0d0120020e03000100000b200441e8016a200a10d203024020042d00e8014101460d0020044194026a280200210920044190026a280200210a2004418c026a280200210720044184026a280200210b20044180026a2802002108024020044188026a2802002201450d002001410c6c21022008210103400240200141046a280200450d002001280200102a0b2001410c6a2101200241746a22020d000b0b0240200b450d002008102a0b02402009450d002009410c6c21022007210103400240200141046a280200450d002001280200102a0b2001410c6a2101200241746a22020d000b0b200a450d032007102a0c030b20042f01ea01210120042d00e9012209417e6a220241024b0d0020020e03020002020b200a106a200441f0056a41026a200441f4056a41026a2d00003a0000200420042f00f4053b01f005200041036a20014108763a000020002001410874200941ff0171723b0001200041013a000020054521000b20000d032006450d03200341046a2802000d020c030b200441e0066a41186a20044198066a41186a290300370300200441e0066a41106a20044198066a41106a290300370300200441e0066a41086a20044198066a41086a29030037030020042004290398063703e006410121010b200441f8056a41186a2208200441e0066a41186a2202290300370300200441f8056a41106a220a200441e0066a41106a2209290300370300200441f8056a41086a220b200441e0066a41086a2207290300370300200420042903e0063703f805200441e8016a200441c8036a41d0006a418801109a051a200220082903003703002009200a2903003703002007200b290300370300200420042903f8053703e0064102210802402001450d00200441c0066a41186a2002290300370300200441c0066a41106a2009290300370300200441c0066a41086a2007290300370300200420042903e0063703c006410121080b200441a2066a200441c0066a41086a290300370100200441aa066a200441c0066a41106a290300370100200441b2066a200441c0066a41186a290300370100200420083a009906200420042903c00637019a06200441003a009806200441e0066a200441e8016a20044198066a10f401200441e8016a41026a200441eb066a2d00003a0000200420042f00e9063b01e80120042903e006210c024020042d00e80622014102460d0020044198066a41026a200441e8016a41026a2d00003a0000200420042f01e8013b0198060b200441ec056a41026a220220044198066a41026a2d00003a0000200420042f0198063b01ec05024020014102460d00200441e8016a41026a20022d00003a0000200420042f01ec053b01e8010b200441d4036a20013a0000200441d5036a20042f01e8013b0000200441d7036a200441e8016a41026a2d00003a00002004200c3702cc03200441003a00c8034101210941014100200441c8036a10cc01200441003602c8034188e8c2004110200441c8036a10062102024020042802c8032207417f460d002002450d0020074104490d03200228000021092002102a200941016a21090b200420093602c8034188e8c2004110200441c8036a410410072000410c6a20013a0000200041046a200c3702002000410d6a20042f01ec053b00002000410f6a200441ee056a2d00003a0000200041003a00002006450d012005450d01200341046a280200450d010b2006102a0b20044180076a24000f0b41c4d1c3004133200441e8016a419cd9c3001038000bf41f05017f037e077f017e037f230041a00a6b22022400420221030240024002400240024002400240024002400240024002400240200129036822044202520d00200220014198016a418801109a051a0c010b20024188026a200141dc006a29000037030020024180026a200141d4006a290000370300200241f8016a200141cc006a290000370300200241d0016a41206a200141c4006a290000370300200241d0016a41186a2001413c6a290000370300200241d0016a41106a200141346a290000370300200241d0016a41086a2001412c6a290000370300200220012900243703d00120024190026a41086a20014188016a29030037030020024190026a41106a20014190016a290300370300200220014180016a29030037039002200141f8006a2903002103200129037021052001280204210620012d00002107200241800a6a41026a2208200141036a2d00003a0000200241c8026a41086a2209200141106a290200370300200241c8026a41106a220a200141186a290200370300200241c8026a41186a220b200141206a280200360200200220012f00013b01800a200220012902083703c80202400240024020074101460d00200241e0096a41026a20082d00003a0000200241b0066a41086a2009290300370300200241b0066a41106a200a290300370300200241b0066a41186a200b2d00003a0000200220022f01800a3b01e009200220022903c8023703b0060c010b200241c0076a200641067610fe0120022802c00721070240024020022802c8072006413f7122064b0d00410021080c010b200241e0096a41026a200720064105746a220641026a2d00003a0000200241b8066a2006410f6a290000370300200241c0066a200641176a290000370300200241c8066a2006411f6a2d00003a0000200220062f00003b01e009200220062900073703b00620062800032106410121080b024020022802c407450d002007102a0b20080d00410121070c010b200241c0076a41026a200241e0096a41026a2d00003a0000200241c8026a41086a200241b0066a41086a290300370300200241c8026a41106a200241b0066a41106a290300370300200241c8026a41186a200241b0066a41186a2d00003a0000200220022f01e0093b01c007200220022903b0063703c802410021070b200241c0096a41026a2208200241c0076a41026a2d00003a0000200241a0056a41086a2209200241c8026a41086a290300370300200241a0056a41106a220a200241c8026a41106a290300370300200241a0056a41186a220b200241c8026a41186a2d00003a0000200220022f01c0073b01c009200220022903c8023703a00502402007450d00200041013b0001200041013a0000200041036a41003a000020014198016a106a0c0c0b200241b7026a2009290300370000200241bf026a200a290300370000200241c7026a200b2d00003a0000200220022f01c0093b01a802200220063600ab02200220022903a0053700af02200220082d00003a00aa02200241c0076a20014198016a418801109a051a200241c8086a41106a20024190026a41106a290300370300200241c8086a41086a20024190026a41086a29030037030020022002290390023703c80841002107200241800a6a410010f701200241c0096a41086a2002418b0a6a290000370300200241c0096a41106a200241930a6a290000370300200241d5096a200241800a6a41186a290000370000200220022900830a3703c00920022f01800a210b20022d00820a210c200241800a6a41086a22014200370300200242003703800a41d9efc200410d200241800a6a1008200241e0096a41086a2001290300370300200220022903800a3703e009200241003602800a200241e0096a4110200241800a6a10062101024020022802800a2206417f460d002001450d0020064104490d02200128000021072001102a0b41002106024020044201520d0020054200510d03417f21062007ad220d20032003200d541b220d200d20037d2005827d220d42ffffffff0f560d00200da721060b411010282201450d03200141086a41002900c6f042370000200141002900bef042370000200141104120102c2201450d0420012006360010200241800a6a41186a22074200370300200241800a6a41106a22084200370300200241800a6a41086a22094200370300200242003703800a20014114200241800a6a1000200241e0096a41186a2007290300370300200241e0096a41106a220a2008290300370300200241e0096a41086a2009290300370300200220022903800a3703e0092001102a4101210102400240200241e0096a41204101410041001003417f470d000c010b200241800a6a200610f701200241a0096a41086a2002418b0a6a290000370300200241a0096a41106a200241930a6a290000370300200241a0096a41156a2007290000370000200241e0096a41086a200241c0096a41086a290300370300200a200241c0096a41106a290300370300200241e0096a41156a200241c0096a41156a290000370000200220022900830a3703a009200220022903c0093703e00920022f01800a20022d00820a411074722106410021010b20024180096a41156a2207200241e0096a41156a29000037000020024180096a41106a2208200241e0096a41106a29030037030020024180096a41086a2209200241e0096a41086a290300370300200241e0086a41086a220a200241a0096a41086a290300370300200241e0086a41106a220e200241a0096a41106a290300370300200241e0086a41156a220f200241a0096a41156a290000370000200220022903e00937038009200220022903a0093703e00802402001450d00200241c0076a106a200041036a41003a0000200041800a3b0001200041013a00000c0c0b200241e8046a41156a22012007290000370000200241e8046a41106a22072008290300370300200241e8046a41086a22082009290300370300200241c8046a41086a2209200a290300370300200241c8046a41106a220a200e290300370300200241c8046a41156a220e200f29000037000020022002290380093703e804200220022903e0083703c80420024188056a41106a220f200241c8086a41106a29030037030020024188056a41086a2210200241c8086a41086a290300370300200220022903c80837038805200241b0066a41046a200241c0076a418801109a051a200241a0056a200241b0066a418c01109a051a200241c8026a200241a0056a41046a418801109a051a20024186046a200b200c41107472220b4110763a000020024184046a220c200b3b0100200241e0036a2003370300200241d8036a2005370300200241e8036a220b200229038805370300200241f0036a2010290300370300200241f8036a2210200f29030037030020024187046a20022903e8043700002002418f046a200829030037000020024197046a20072903003700002002419c046a2001290000370000200220043703d003200241a30136028004200241a6046a20064110763a0000200241a4046a220720063b0100200241a7046a20022903c804370000200241af046a2009290300370000200241b7046a200a290300370000200241bc046a200e290000370000410410282201450d05200242043702b406200220013602b006200241c8026a200241b0066a10eb010240024020022903d0034201510d000240024020022802b40620022802b8062201460d0020022802b00621060c010b200141016a22062001490d0c200141017422082006200820064b1b22084100480d0c0240024020010d002008102821060c010b20022802b00620012008102c21060b2006450d09200220083602b406200220063602b00620022802b80621010b2002200141016a3602b806200620016a41003a00000c010b20022903e00320022903d8032203420c882204420120044201561b8021040240024020022802b406220620022802b80622016b4102490d0020022802b00621060c010b200141026a22082001490d0b200641017422012008200120084b1b22014100480d0b0240024020060d002001102821060c010b20022802b00620062001102c21060b2006450d09200220013602b406200220063602b00620022802b80621010b2002200141026a3602b806200620016a2004a741047420037aa7417f6a22014101200141014b1b2201410f2001410f491b723b00000b2010200241b0066a10a0012002200b3602a005200241a0056a200241b0066a10a30120022802800421080240024020022802b406220620022802b80622016b4104490d0020022802b00621060c010b200141046a22092001490d0a200641017422012009200120094b1b22014100480d0a0240024020060d002001102821060c010b20022802b00620062001102c21060b2006450d09200220013602b406200220063602b00620022802b80621010b2002200141046a3602b806200620016a20083600002002200241b0066a3602a005200c200241a0056a10c8012002200241b0066a3602a0052007200241a0056a10c80120022802b006210120022802b40621060240024020022802b80622074180024b0d00200241d0016a20012007200241a8026a10dd0321070c010b200241800a6a41186a22084200370300200241800a6a41106a22094200370300200241800a6a41086a220a4200370300200242003703800a20012007200241800a6a1000200241e0096a41186a2008290300370300200241e0096a41106a2009290300370300200241e0096a41086a200a290300370300200220022903800a3703e009200241d0016a200241e0096a4120200241a8026a10dd0321070b02402006450d002001102a0b2007450d0a200241b0016a41086a200241a8026a41086a290300370300200241b0016a41106a200241a8026a41106a290300370300200241b0016a41186a200241a8026a41186a29030037030020024188016a41086a200241e0036a29030037030020024188016a41106a200241e8036a29030037030020024188016a41186a200241f0036a290300370300200241a8016a200241f8036a290300370300200220022903a8023703b0012002200241d8036a2903003703880120022903d00321032002200241c8026a418801109a051a0b200041086a20022903b001370300200041286a2003370300200041306a200229038801370300200041206a200241b0016a41186a290300370300200041186a200241b0016a41106a290300370300200041106a200241b0016a41086a290300370300200041386a20024188016a41086a290300370300200041c0006a20024188016a41106a290300370300200041c8006a20024188016a41186a290300370300200041d0006a20024188016a41206a290300370300200041d8006a2002418801109a051a200041003a0000200241a00a6a24000f0b41c4d1c3004133200241800a6a419cd9c3001038000b41fcf8c5001032000b411041011037000b412041011037000b410441011037000b200841011037000b200141011037000b200141011037000b1031000b20004180083b0001200041013a0000200041036a41003a0000200241c8026a106a0b200241a00a6a24000be00402037f017e230041306b220224000240024020012802004110460d00200041003a0000200041306a41013a0000200041286a4200370300200041206a4280808080c000370300200041186a4204370300200041106a427f370300200041086a42003703000c010b024002400240024002400240200141086a2d00000e06050402010004050b200141c8006a21030c020b200141d0006a21030c010b200141186a21030b200241086a41086a220142003703002002420037030841affec5004111200241086a1008200241206a41086a20012903003703002002200229030837032020024100360208200241206a4110200241086a1006210102400240024020022802082204417f470d004280ade20421050c010b024020010d004280ade20421050c010b20044108490d01200129000021052001102a4280ade20420057d21050b024020032903002005560d00200041003a0000200041306a41013a0000200041286a4200370300200041206a4280808080c000370300200041186a4204370300200041106a427f370300200041086a42003703000c040b200041800c3b0001200041013a0000200041036a41003a00000c030b41c4d1c3004133200241086a419cd9c3001038000b200041003a0000200041306a41013a0000200041286a4200370300200041206a4280808080c000370300200041186a4204370300200041106a427f370300200041086a42003703000c010b2002411c6a41013602002002420137020c200241ccd1c50036020820024104360224200241ccd0c3003602202002200241206a360218200241086a41f0d0c300103e000b200241306a24000ba60201037f412e210241f8f4c50021030240024002402001417e6a22044102200441ff01714102491b41ff01710e03020001020b4130210241c8f4c50021030c010b20014180feff07714108762104024020014101710d00411f210241b4f5c50021030240024002400240024002400240200441ff01710e080006010203040508000b4120210241baf7c50021030c070b4127210241daf6c50021030c060b4117210241c3f6c50021030c050b41a4f6c50021030c040b4126210241fef5c50021030c030b412b210241d3f5c50021030c020b413921024181f7c50021030c010b411f210241daf7c500210302400240200441ff01710e03000102000b41c100210241baf8c50021030c010b41c100210241f9f7c50021030b20002002360204200020033602000b13002000410136020420004188bcc3003602000b3400200041e7bfc30036020420004100360200200041146a4102360200200041106a41f0bfc300360200200041086a42093702000b130020004101360204200041bcc2c3003602000b3101017f02404108102822020d00410841011037000b20004288808080800137020420002002360200200242dc0b3700000b130020004104360204200041e0c5c3003602000b3400200041beccc30036020420004100360200200041146a4101360200200041106a41d4ccc300360200200041086a42133702000beb050a067f017e017f017e017f017e017f017e017f017e230041206b2202240002400240024020014108490d00200141017641feffffff07712203417f6a220420014f0d022001410d74200173220541117620057322054105742005732206417f2001417f6a677622077122054100200120052001491b6b220520014f0d01200020044105746a22042900002108200020054105746a220541086a2209290000210a200541106a220b290000210c200541186a220d290000210e20042005290000370000200441186a220f2900002110200f200e370000200441106a220f290000210e200f200c370000200441086a2204290000210c2004200a370000200d2010370000200b200e3700002009200c37000020052008370000024020032001490d00200321040c030b2006410d7420067322054111762005732205410574200573220620077122054100200120052001491b6b220520014f0d01200020034105746a22042900002108200020054105746a220541086a2209290000210a200541106a220b290000210c200541186a220d290000210e20042005290000370000200441186a220f2900002110200f200e370000200441106a220f290000210e200f200c370000200441086a2204290000210c2004200a370000200d2010370000200b200e3700002009200c370000200520083700002003410172220420014f0d022006410d742006732205411176200573220541057420057320077122054100200120052001491b6b220520014f0d01200020044105746a22012900002108200020054105746a220041086a2205290000210a200041106a2204290000210c200041186a2203290000210e20012000290000370000200141186a220629000021102006200e370000200141106a2206290000210e2006200c370000200141086a2201290000210c2001200a370000200320103700002004200e3700002005200c370000200020083700000b200241206a24000f0b4190cec300200520011034000b4180cec300200420011034000be90609067f017e017f017e017f027e017f017e027f230041206b22022400024020014101762203450d0003402003417f6a2203210402400240024003402004410174220541017221060240200541026a220520014f0d00200620014f0d0220052006200020064105746a200020054105746a4120109c054100481b21060b200620014f0d03200420014f0d02200020044105746a2204200020064105746a22054120109c0541004e0d03200541086a22072900002108200541106a2209290000210a200541186a220b290000210c2004290000210d20042005290000370000200441186a220e290000210f200e200c370000200441106a220e290000210c200e200a370000200441086a2204290000210a20042008370000200b200f3700002009200c3700002007200a3700002005200d370000200621040c000b0b41c8cfc300200620011034000b41d8cfc300200420011034000b20030d000b0b0240024020014102490d002001210703402007417f6a220720014f0d02200241186a2209200041186a2204290000370300200241106a220b200041106a2205290000370300200241086a220e200041086a2203290000370300200020074105746a220641086a2900002108200641106a290000210a200641186a290000210c2000290000210d200020062900003700002004200c3700002005200a370000200320083700002002200d37030041002105024002400240034020062002290300370000200641186a2009290300370000200641106a200b290300370000200641086a200e2903003700002005410174220641017221040240200641026a220620074f0d00200420074f0d0220062004200020044105746a200020064105746a4120109c054100481b21040b200420074f0d03200520074f0d02200020054105746a2205200020044105746a22064120109c0541004e0d032009200541186a2203290000370300200b200541106a2210290000370300200e200541086a2211290000370300200641086a2900002108200641106a290000210a200641186a290000210c2005290000210d200520062900003700002003200c3700002010200a370000201120083700002002200d370300200421050c000b0b41c8cfc300200420071034000b41d8cfc300200520071034000b200741014b0d000b0b200241206a24000f0b4190cec300200720011034000b9009030a7f017e0a7f230041c0006b22022400200041807f6a21032001417f6a2104200141324921054101210641002107024003400240024020062001490d00410021080c010b41012108200020064105746a2209200941606a4120109c054100480d0003404101210a20042006460d03200641016a2106200941206a220a20094120109c052108200a21092008417f4a0d000b200620014921080b2006200146210a20050d0120062001460d01024002400240024002402006417f6a220920014f0d002008450d0120002006410574220b6a220a290000210c200a200020094105746a22092900003700002009200c370000200a41086a220d290000210c200d200941086a22082900003700002008200c370000200a41106a220e290000210c200e200941106a220f290000370000200f200c370000200a41186a2210290000210c2010200941186a22112900003700002011200c37000020064102490d04200920002006417e6a22124105746a22134120109c05417f4a0d042009290000210c20092013290000370000200241206a41186a22142011290000370300200241206a41106a2215200f290000370300200241206a41086a221620082900003703002008201341086a290000370000200f201341106a2900003700002011201341186a2900003700002002200c370320024020120d00410021120c040b200241206a20002006417d6a22084105746a4120109c05417f4a0d032003200b6a21090340200941d8006a200941386a290000370000200941d0006a200941306a290000370000200941c8006a200941286a290000370000200941c0006a200941206a2900003700002008450d032008417f6a2108200241206a20094120109c05210f200941606a2109200f4100480d000b200841016a21120c030b4180cec300200920011034000b4190cec300200620011034000b410021120b200020124105746a22092002290320370000200941186a2014290300370000200941106a2015290300370000200941086a20162903003700000b200741016a21070240200120066b220f4102490d00200a41206a2209200a4120109c05417f4a0d00200a290000210c200a2009290000370000200241206a41186a22112010290000370300200241206a41106a2213200e290000370300200241206a41086a2212200d290000370300200d200941086a290000370000200e200941106a2900003700002010200941186a2900003700002002200c3703204101210d0240200f4103490d00200a41c0006a2209200241206a4120109c05417f4a0d00410321084102210e02400340200e410574200a6a41606a220d2009290000370000200d41186a200941186a290000370000200d41106a200941106a290000370000200d41086a200941086a2900003700002008200f4f0d0120084105742109200e210d2008210e200841016a2108200a20096a2209200241206a4120109c054100480d000c020b0b200e210d0b200a200d4105746a22092002290320370000200941186a2011290300370000200941106a2013290300370000200941086a20122903003700000b20074105470d000b4100210a0b200241c0006a2400200a0b8305010f7f230041a0026b22042400200441c0016a41386a2205200041386a2206290000370300200441c0016a41306a2207200041306a2208290000370300200441c0016a41286a2209200041286a220a290000370300200441c0016a41206a220b200041206a220c290000370300200441c0016a41186a220d200041186a220e290000370300200441c0016a41106a220f200041106a2210290000370300200441c0016a41086a2211200041086a2212290000370300200420002900003703c0010240024020012002200441c0016a2003100a0d00410121000c010b20052006290000370300200720082900003703002009200a290000370300200b200c290000370300200d200e290000370300200f20102900003703002011201229000037030020044188026a2205200341086a29000037030020044190026a2206200341106a29000037030020044198026a2207200341186a290000370300200420002900003703c00120042003290000370380022004200441c0016a41e000109a05220041c0016a200041e000109a051a200041e0006a41386a200041386a290000370300200041e0006a41306a200041306a290000370300200041e0006a41286a200041286a290000370300200041e0006a41206a200041206a290000370300200041e0006a41186a200041186a290000370300200041e0006a41106a200041106a290000370300200041e0006a41086a200041086a29000037030020002000290000370360200041a0016a41186a2007290300370300200041a0016a41106a2006290300370300200041a0016a41086a200529030037030020002000290380023703a00120012002200041e0006a200041a0016a10164521000b200441a0026a240020000bc50101037f230041206b220224002002410036021020014110200241106a10062101024002400240024020022802102203417f460d0020010d010b200041003602040c010b200220013602082002200336020c20034104490d0120022003417c6a36020c2002200141046a36020820012800002103200241106a200241086a10820120022802102204450d012000200229021437020820002004360204200020033602002001102a0b200241206a24000f0b41c4d1c3004133200241106a419cd9c3001038000be80201057f230041b0036b22022400200241003602a80220014110200241a8026a1006210302400240024020022802a8022201417f470d00200041133602000c010b20022001360294012002200336029001200241a8026a20024190016a10810120022802a8024113460d01200241a0016a200241a8026a418801109a051a024002402002280294012204450d0020022802900122052d0000210620022004417f6a360294012002200541016a3602900120064103490d010b200241a0016a106a0c020b20022802a00121042002410c6a200241a0016a410472418401109a051a2002200228009901360204200220024199016a41036a28000036000720044113460d0120002004360200200041046a2002410c6a418401109a051a20004188016a20063a000020002002280204360089012000418c016a20022800073600002001450d002003102a0b200241b0036a24000f0b41c4d1c3004133200241a8026a419cd9c3001038000bdb0102027f037e230041206b220224002002410036021020014120200241106a10062101024002400240024020022802102203417f460d0020010d010b200041003602100c010b200220013602082002200336020c20034110490d012002200341706a36020c2002200141106a360208200141086a290000210420012900002105200241106a200241086a106d20022802102203450d0120022902142106200020043703082000200537030020002006370214200020033602102001102a0b200241206a24000f0b41c4d1c3004133200241106a419cd9c3001038000bc40101037f230041206b220224002002410036021020014120200241106a10062101024002400240024020022802102203417f460d0020010d010b200041003602040c010b200220013602082002200336020c20034104490d0120022003417c6a36020c2002200141046a36020820012800002103200241106a200241086a106d20022802102204450d012000200229021437020820002004360204200020033602002001102a0b200241206a24000f0b41c4d1c3004133200241106a419cd9c3001038000bd20101037f230041106b22022400200241003602082002420137030020012d00002103410110282104024002400240024020034101460d002004450d02200242818080801037020420022004360200200441003a0000200141086a200210e3030c010b2004450d02200242818080801037020420022004360200200441013a00002002200236020c200141016a2002410c6a10c8010b2002280204210420004120200228020022012002280208100702402004450d002001102a0b200241106a24000f0b410141011037000b410141011037000ba60a02067f027e230041106b2202240020002802102103200041186a2802002204200110b4010240024002400240024002400240024002400240200141046a2802002205200141086a28020022066b2004490d00200128020021050c010b200620046a22072006490d08200541017422062007200620074b1b22064100480d080240024020050d002006102821050c010b200128020020052006102c21050b2005450d0120012005360200200141046a2006360200200141086a28020021060b200141086a2207200620046a360200200520066a20032004109a051a200028021c210502400240200141046a2802002206200728020022046b4104490d00200128020021060c010b200441046a22032004490d08200641017422042003200420034b1b22044100480d080240024020060d002004102821060c010b200128020020062004102c21060b2006450d0220012006360200200141046a2004360200200141086a28020021040b200141086a2203200441046a360200200620046a20053600002002200136020c2000412c6a2002410c6a10c801200041086a29030021082000290300210902400240200141046a2802002206200328020022046b4110490d00200128020021060c010b200441106a22052004490d08200641017422042005200420054b1b22044100480d080240024020060d002004102821060c010b200128020020062004102c21060b2006450d0320012006360200200141046a2004360200200141086a28020021040b200141086a2205200441106a360200200620046a22042008370008200420093700002000280220210302400240200141046a2802002206200528020022046b4104490d00200128020021060c010b200441046a22052004490d08200641017422042005200420054b1b22044100480d080240024020060d002004102821060c010b200128020020062004102c21060b2006450d0420012006360200200141046a2004360200200141086a28020021040b200141086a2205200441046a360200200620046a20033600000240024020002802244101460d0002400240200141046a28020020052802002200460d00200128020021040c010b200041016a22042000490d0a200041017422062004200620044b1b22064100480d0a0240024020000d002006102821040c010b200128020020002006102c21040b2004450d0720012004360200200141046a2006360200200141086a28020021000b200141086a200041016a360200200420006a41003a00000c010b02400240200141046a28020020052802002204460d00200128020021060c010b200441016a22062004490d09200441017422052006200520064b1b22054100480d090240024020040d002005102821060c010b200128020020042005102c21060b2006450d0720012006360200200141046a2005360200200141086a28020021040b200141086a2205200441016a360200200620046a41013a00002000280228210602400240200141046a2802002204200528020022006b4104490d00200128020021040c010b200041046a22052000490d09200441017422002005200020054b1b22004100480d090240024020040d002000102821040c010b200128020020042000102c21040b2004450d0820012004360200200141046a2000360200200141086a28020021000b200141086a200041046a360200200420006a20063600000b200241106a24000f0b200641011037000b200441011037000b200441011037000b200441011037000b200641011037000b200541011037000b200041011037000b1031000b910101047f230041106b2201240041002102200141003602044188e8c2004110200141046a1006210302400240024020012802042204417f470d000c010b024020030d000c010b20044104490d01200328000021042003102a4188e8c20041101009410121020b2000200236020020002004360204200141106a24000f0b41c4d1c3004133200141086a419cd9c3001038000bfb0103017f017e027f230041206b2201240042002102200141106a41086a220342003703002001420037031041affec5004111200141106a1008200141086a2003290300370300200120012903103703002001410036021020014110200141106a100621030240024020012802102204417f460d002003450d0020044108490d01200329000021022003102a0b200141106a41086a220342003703002001420037031041affec5004111200141106a1008200141086a2003290300370300200120012903103703002001200220007c37031020014110200141106a41081007200141206a24000f0b41c4d1c3004133200141106a419cd9c3001038000b1300200041053602042000418cdac3003602000b3400200041a4d5c30036020420004100360200200041146a4107360200200041106a41e4ecc300360200200041086a42083702000b3701017f02404110102822020d00411041011037000b2002420037000820024201370000200042908080808002370204200020023602000bc70101017f23004190016b22022400200241003a00782002428080848080023703682002420137035820024201370350200242af0137034820024287013703402002420137033820024201370330200242013703282002420137032020024201370318200242013703102002420137030820024280808080c00037036020024280808180800437037020024100360288012002420137038001200241086a20024180016a10ee01200041086a200228028801360200200020022903800137020020024190016a24000b130020004110360204200041c0f6c3003602000b3301017f02404108102822020d00410841011037000b2000428880808080013702042000200236020020024280ade2043700000b3201017f02404104102822020d00410441011037000b20004284808080c000370204200020023602002002418080013600000b3101017f02404104102822020d00410441011037000b20004284808080c0003702042000200236020020024180083600000b3101017f02404108102822020d00410841011037000b20004288808080800137020420002002360200200242e8073700000b3c01017f02404110102822020d00411041011037000b2002420037000820024280a094a58d1d370000200042908080808002370204200020023602000b3b01017f02404110102822020d00411041011037000b2002420037000820024280c8afa025370000200042908080808002370204200020023602000b3e01017f02404110102822020d00411041011037000b20024200370008200242808086bdbacdd21a370000200042908080808002370204200020023602000b3f01017f02404110102822020d00411041011037000b200242003700082002428080a8ec85afd1b101370000200042908080808002370204200020023602000b3001017f02404104102822020d00410441011037000b20004284808080c00037020420002002360200200241083600000b3001017f02404104102822020d00410441011037000b20004284808080c00037020420002002360200200241023600000bc81603027f047e117f230041a0096b22072400200741e0006a41186a200141186a290000370300200741e0006a41106a200141106a290000370300200741e0006a41086a200141086a2900003703002007200129000037036020074180016a41186a200241186a29000037030020074180016a41106a200241106a29000037030020074180016a41086a200241086a2900003703002007200229000037038001200628020021012006280204210220062802082108200741d0006a10f6030240024002400240024020072903502209200741d0006a41086a290300220a8450450d004200210b4200210c0c010b200741306a200a420020054200109f05200741c0006a2009420020054200109f05200741206a4200420020094200109f0502402007290338200729032884420052200741c0006a41086a290300220b200729033020072903207c7c220c200b5472450d004127210641a6b5c00021080c020b2007290340210b0b200741c0016a200741e0006a200b200c41081098024101210d20072802c0014101470d0120072802c801210620072802c40121080b2000200836020420004101360200200041146a41003602002000410c6a4201370200200041086a20063602002002450d012001102a0c010b200741c0016a41106a290300210b20072903c801210c200741a0016a41186a220e200a370300200720093703b001200720053703a801200720053703a001200741c0016a10f703200741c0026a4200370300200741f0026a4200370300200741e0026a4200370300200741d0026a42003703002007428080e983b1de163703b80220074280a094a58d1d3703e80220074280a094a58d1d3703d80220074280a094a58d1d3703c802200742808880808080103703f8022007200741c0016a360280032007200741c0016a36028403200741d0056a41186a220f200741e0006a41186a290300370300200741d0056a41106a2206200741e0006a41106a290300370300200741d0056a41086a2210200741e0006a41086a290300370300200720072903603703d00510a00321051098012111200741c0036a4200370300200741b4036a41d0b5c000360200200741b0036a4101360200200741a8036a4200370300200741a4036a41f8b9c000360200200741e0036a2010290300370300200741e8036a2006290300370300200741f0036a200f29030037030020074200370390032007428080808080013703b803200741003602a003200720072903d0053703d803200720074184036a3602d003200720074180036a3602cc032007200741c0016a3602c803200720113602d4032007200537038803200f20074180016a41186a290300370300200620074180016a41106a290300370300201020074180016a41086a29030037030020072007290380013703d005200720083602a804200720023602a404200720013602a004200741f8036a20074188036a200741d0056a20032004200741a0016a200741a0046a10c101024020072802f8030d00200741f8036a41106a2d00000d00200741d0056a41086a200741a8036a290300370300200741a0046a41086a200741dc056a280200360200200720072903a0033703d005200720072902d4053703a00420074198096a200741a0046a1092014100210d0b200720072903b001200e29030020072903a80122054200109f0520072903a00120057d10e503200741106a200741e0006a2007290300200741086a29030010d0012006200b200741106a41086a29030022097d200c2007290310220554ad7d2009200b7d2005200c54ad7d2005200c582009200b582009200b5122021b22011b220a3703002007200c20057d2005200c7d20011b22033703d80520072005200c562009200b5620021b2202ad22053703d00541012101024020020d00200720033703a0042007200a3703a8042007200741a0046a3602e007200741e0076a109d014100210120072903d00521050b0240024020054200520d002001450d01200720103602a004200741a0046a109d010c010b200720103602a004200741a0046a109c010b20072802c403210120072802c0032106200720072802bc032202360298042007200636029404200720023602900420072002200141b0016c6a221236029c0402402001450d00200741e0076a410172211320074187076a2114200741e9076a210820074180076a4102722110200741d0056a41106a2115200741f8056a2116200741b4066a211720074191066a210f200741f1056a210e200741d0056a4101722118200741c8066a2119034020022d00002101200741a0046a200241016a41af01109a051a0240024020014103460d00200720013a00d0052018200741a0046a41af01109a052106024002400240024020010e03000102000b20072802d805211a20072802dc05210620072802d40521012014201541d800109a051a2007410c3a00e007201320074180076a41df00109a051a20012006200741e0076a10cc0141012106410021110240201a450d002001102a0b4100211a0c020b200741e8086a41186a2201200641186a2211290000370300200741e8086a41106a221a200641106a221b290000370300200741e8086a41086a221c200641086a221d290000370300200720062900003703e808200741e0076a2016418801109a051a20102006290000370000201041086a201d290000370000201041106a201b290000370000201041186a201129000037000020074180023b01800720074188096a200741e0076a20074180076a10f40120072d0090092106200820072903e808370000200841086a201c290300370000200841106a201a290300370000200841186a2001290300370000200741043a00e8072007410c3a00e007200720064102463a008908410021064101211141014100200741e0076a10cc014100211a0c010b2019290300210520072903c0062109200741e8086a41186a200641186a290000370300200741e8086a41106a200641106a290000370300200741e8086a41086a200641086a290000370300200720062900003703e80820074180076a41186a200e41186a29000037030020074180076a41106a200e41106a29000037030020074180076a41086a200e41086a2900003703002007200e29000037038007200741e0076a41186a200f41186a290000370300200741e0076a41106a200f41106a290000370300200741e0076a41086a200f41086a2900003703002007200f2900003703e00720074188096a41086a201741086a2802003602002007201729020037038809200741e8086a20074180076a200741e0076a2009200520074188096a10f80341012111410121064101211a0b024020072d00d005220141014b0d000240024020010e020001000b2011450d03024020072802d805450d0020072802d405102a0b20072d00e0054105490d03200728028806450d03200728028406102a0c030b2006450d022016106a0c020b201a20072802b80645720d0120072802b406102a0c010b2007200241b0016a360298040c020b200241b0016a22022012470d000b20072012360298040b20074190046a1069200041106a200741f8036a41106a290300370200200041086a200741f8036a41086a290300370200200020072903f80337020002402007280294032202450d0020074188036a41106a280200450d002002102a0b200d450d0020074188036a411c6a280200210220072802ac0321080240024020072802a80322060d00200221010c010b2006210020022101034020012802880b21012000417f6a22000d000b0340200220022f01064102746a41880b6a28020021022006417f6a22060d000b0b200741d0056a411c6a20022f0106360200200741e8056a4100360200200741e4056a2002360200200720083602f005200741003602e005200742003703d805200720013602d405200741003602d005200741d0056a109b010b200741a0096a24000bc70104017f017e027f017e230041206b2201240042002102200141106a41086a22034200370300200142003703104188d9c3004111200141106a1008200141086a2003290300370300200120012903103703002001410036021020014110200141106a1006210302400240024020012802102204417f470d00420121050c010b20044110490d01200341086a2900002102200329000021052003102a0b2000200537030020002002370308200141206a24000f0b41c4d1c3004133200141106a419cd9c3001038000be20301047f23004190026b2201240020014190016a41086a22024200370300200142003703900141c0fec500411820014190016a100820014180016a41086a2002290300370300200120012903900137038001200141003602900120014180016a411020014190016a100621030240024002402001280290012204417f470d00410221020c010b2001200436028c02200120033602880220014190016a20014188026a10ea0120012d00800222024102460d01200141106a20014190016a41f000109a051a200120014184026a28000036000b20012001280081023602082004450d002003102a0b20014190016a200141106a41f000109a051a2001200128000b3600830120012001280208360280010240024020024102470d002000428080818080043703682000428080848080023703602000420137035020004201370348200042af0137034020004287013703382000420137033020004201370328200042013703202000420137031820004201370310200042013703082000420137030020004280808080c000370358410021020c010b200020014190016a41f000109a05220441f4006a20012800830136000020042001280280013600710b200020023a007020014190026a24000f0b41c4d1c3004133200141106a419cd9c3001038000b891d01117f230041b0036b2206240020064190026a2000108c01410221070240024020062d00900222084102470d00410121094134210a410221080c010b20064190036a41086a2209200641a4026a29020037030020064190036a41106a220b200641ac026a29020037030020064190036a41186a220c200641b4026a290200370300200641e8026a41086a220d200641c8026a290300370300200641e8026a41106a220e200641d0026a290300370300200641e8026a41186a220f200641d8026a290300370300200641e8026a41206a2210200641e0026a29030037030020062006419c026a290200370390032006200641c0026a2903003703e80220064190026a41086a280200210a024020080d00200641bc026a2802002107200641e8016a41186a200c290300370300200641e8016a41106a200b290300370300200641e8016a41086a2009290300370300200641c0016a41086a200d290300370300200641c0016a41106a200e290300370300200641c0016a41186a200f290300370300200641c0016a41206a201029030037030020062006290390033703e801200620062903e8023703c0010b41022108024020074102470d00410121094134210a0c010b200641e8026a41186a200641e8016a41186a290300370300200641e8026a41106a200641e8016a41106a290300370300200641e8026a41086a200641e8016a41086a29030037030020064190026a41086a200641c0016a41086a29030037030020064190026a41106a200641c0016a41106a29030037030020064190026a41186a200641c0016a41186a29030037030020064190026a41206a200641c0016a41206a290300370300200620062903e8013703e802200620062903c0013703900241002109200721080b200641a0016a41086a2207200641e8026a41086a290300370300200641a0016a41106a220b200641e8026a41106a290300370300200641a0016a41186a220c200641e8026a41186a290300370300200641f8006a41086a220d20064190026a41086a290300370300200641f8006a41106a220e20064190026a41106a290300370300200641f8006a41186a220f20064190026a41186a290300370300200641f8006a41206a221020064190026a41206a290300370300200620062903e8023703a00120062006290390023703780240024020090d00200641d0006a22112006290378370300200641346a20072903003702002006413c6a200b290300370200200641c4006a200c290300370200200641d8006a200d290300370300200641e0006a200e290300370300200641e8006a200f290300370300200641f0006a20102903003703002006200a360228200620062903a00137022c2006200836024c41012109109801210d0240024020084101470d002011280200200d460d010b20064190026a2001108c010240024020062d009002220a4102470d00412e210a419d8fc400210b0c010b200641e8016a41026a20062d0093023a0000200641e8026a41086a2209200641a4026a280200360200200620062f0091023b01e80120062006419c026a2902003703e802200641ac026a2802002108200641a8026a28020021070240200a0d0041012109412e210a419d8fc400210b024020080d000c020b2007102a0c010b20064190026a41086a280200210a200628029402210b200641a0016a41026a200641e8016a41026a2d00003a0000200641c0016a41086a2009280200360200200620062f01e8013b01a001200620062903e8023703c001200641b0026a2d0000210c410021090b2006418c026a41026a200641a0016a41026a2d00003a000020064190036a41086a220e200641c0016a41086a280200360200200620062f01a0013b018c02200620062903c0013703900320090d002006418b016a200e280200360000200620062f018c023b01782006200a36007f2006200b36007b2006200629039003370083012006200c3a00970120062008360093012006200736008f0120062006418e026a2d00003a007a200628024c211220062802502113200620052802002211200541086a28020022144105746a3602940320062011360290032006200641286a3602980320064190026a20064190036a106802400240024002400240024002400240024002402006280290020d0041002109200641003602f001200642043703e801410421074100210a0c010b411010282207450d012007200629039002370200200741086a20064190026a41086a220b290300370200200641c0016a41086a20064190036a41086a28020036020020062006290390033703c001200641e8026a200641c0016a10680240024020062802e8020d00410121094101210a0c010b410121084101210a0340200b200641e8026a41086a290300370300200620062903e8023703900202400240200a2008460d00200841016a21090c010b200841016a22092008490d082008410174220a2009200a20094b1b220a41ffffffff0071200a470d08200a410474220c4100480d080240024020080d00200c102821070c010b20072008410474200c102c21070b2007450d050b200720084104746a2208200629039002370200200841086a200b290300370200200641e8026a200641c0016a10682009210820062802e8020d000b0b200620093602f0012006200a3602ec01200620073602e8010b200641286a41186a28020021082006280238210b2006410036029002200b200820064190026a100d2110200628029002220f417f460d02200641e8026a41186a200241186a290000370300200641e8026a41106a200241106a290000370300200641e8026a41086a200241086a290000370300200620022900003703e802200641003602980320064201370390032010200f20064190036a10b20202400240200628029403220e200628029803220c6b4120490d00200c41206a210b20062802900321080c010b200c41206a220b200c490d05200e4101742208200b2008200b4b1b22154100480d0502400240200e0d002015102821080c010b200628029003200e2015102c21080b2008450d04200620153602940320062008360290032015210e0b2006200b360298032008200c6a220c20062903e802370000200c41086a200641e8026a41086a290300370000200c41106a200641e8026a41106a290300370000200c41186a200641e8026a41186a29030037000020064190026a41186a220c420037030020064190026a41106a2215420037030020064190026a41086a2216420037030020064200370390022008200b20064190026a1000200641c0016a41186a200c290300370300200641c0016a41106a2015290300370300200641c0016a41086a201629030037030020062006290390023703c0010240200e450d002008102a0b0240200f450d002010102a0b0240200641c0016a200641f8006a4120109c050d000240024020090d004100210b0c010b2009410474210c2007410c6a21084100210b03402008280200200b6a210b200841106a2108200c41706a220c0d000b0b20062006280244200b6b360244411710282208450d06200d201320141b210f4101201220141b2110200641286a41106a210b200841002900f1d8433700002008410f6a4100290080d943370000200841086a41002900f9d84337000020064297808080f002370294032006200836029003200020064190036a108f012006280298032115200628029003211620064190026a41186a2208420037030020064190026a41106a220c420037030020064190026a41086a220e420037030020064200370390022016201520064190026a1000200641e8026a41186a2008290300370300200641e8026a41106a200c290300370300200641e8026a41086a200e29030037030020062006290390023703e8020240200628029403450d00200628029003102a0b200641e8026a41201009200c2004370300200641c0026a200f360200200641bc026a2010360200200641b8026a200d360200200641b4026a20062802443602002008200b29030037030020064190026a41206a200b41086a280200360200200641c4026a2002290000370200200641cc026a200241086a290000370200200641d4026a200241106a290000370200200641dc026a200241186a2900003702002006200337039802200641003a009002200120064190026a109a01200641186a2000109101200641186a41086a29030021032006290318210420064190026a200042004200109401024002402006290390024200520d002006200e3602e802200641e8026a109c010c010b2006200e3602e802200641e8026a109d010b200641086a20012004200310d0012006200641106a290300370398022006200629030837039002200620064190026a3602e802200641e8026a109c0102402009450d0020094104742109200741046a210803400240200841046a280200450d002008280200102a0b200841106a2108200941706a22090d000b0b0240200a450d002007102a0b200541046a280200450d0b2011102a0c0b0b200720094104746a2101200721082009450d0620072108034002402008280200220b0d00200841106a21080c080b200841046a2802002109200841086a28020021002008410c6a280200210c200628024021022006280238210d20064190026a41186a220e420037030020064190026a41106a220f420037030020064190026a41086a221042003703002006420037039002200b412020064190026a1000200641e8026a41186a200e290300370300200641e8026a41106a200f290300370300200641e8026a41086a201029030037030020062006290390023703e802200d2002200641e8026a41202009200c100502402000450d002009102a0b200841106a22082001470d000c080b0b411041041037000b200c41041037000b41eef3c50041381050000b201541011037000b1031000b411741011037000b20082001460d0003402008280200450d010240200841086a280200450d00200841046a280200102a0b200841106a22082001470d000b0b200a450d002007102a0b2006413c6a280200450d002006280238102a0b200541046a280200450d002005280200102a0b200641b0036a24000bf46504177f017e077f017e23004180036b2204240041002105200441003602f002200420023602ec02200420013602e8020240024002400240024002400240200241034b0d0041012106200441013a00d002200441ec016a4101360200200442013702dc01200441a4e2c5003602d801200441263602c4022004200441c0026a3602e8012004200441d0026a3602c00220044180016a200441d8016a10332004280280012107200428028401210820042802880121094105210a4100210b0c010b200441043602f002024020012800004180c2cdeb06460d004101210a410121060c010b024002402002417c714104460d00200241074b0d0141082002103c000b41012106200441013a00d002200441ec016a4101360200200442013702dc01200441a4e2c5003602d801200441263602c4022004200441c0026a3602e8012004200441d0026a3602c00220044180016a200441d8016a10332004280280012107200428028401210820042802880121094105210a410021054100210b0c010b200441083602f002410121060240200128000422074101460d004102210a0c010b200441d8016a200441e8026a10fa0402400240024020042802d8014101470d00410421084100210c410021090c010b200441d8016a410572210d41042108412c210a410021054100210c410021094100210b02400340200441d0026a41026a2201200d41026a2d00003a00002004200d2f00003b01d002200428028802210e200428028402210f200428028002211020042802fc01211120042802f801211220042802f401211320042802f001211420042802ec01211520042802e801211620042802e401211720042802e0012118024020042d00dc012206417e6a41ff0171410b4b0d0041002119024002400240024002400240024002400240024002400240024020060e100c0c000102030405060708090a0b0c0c0c0b410121190c0b0b410221190c0a0b410321190c090b410421190c080b410521190c070b410621190c060b410721190c050b410821190c040b410921190c030b410a21190c020b410b21190c010b410c21190b0240200b41ff0171221a20194d0d004113210a0c030b41002119024002400240024002400240024002400240024002400240024020060e100c0c000102030405060708090a0b0c0c0c0b410121190c0b0b410221190c0a0b410321190c090b410421190c080b410521190c070b410621190c060b410721190c050b410821190c040b410921190c030b410a21190c020b410b21190c010b410c21190b0240201a2019470d004114210a0c030b4100210b02400240024002400240024002400240024002400240024020060e100c0c000102030405060708090a0b0c0c0c0b4101210b0c0b0b4102210b0c0a0b4103210b0c090b4104210b0c080b4105210b0c070b4106210b0c060b4107210b0c050b4108210b0c040b4109210b0c030b410a210b0c020b410b210b0c010b410c210b0b20044180016a41026a221920012d00003a0000200420042f01d0023b01800102400240200c2009470d00200c41016a2201200c490d0720052001200520014b1b2209ad42307e221b422088a70d07201ba722014100480d0702400240200c0d002001102821080c010b2008200a41546a2001102c21080b2008450d010b2008200a6a220141546a20063a00002001200e3602002001417c6a200f360200200141786a2010360200200141746a2011360200200141706a20123602002001416c6a2013360200200141686a2014360200200141646a2015360200200141606a20163602002001415c6a2017360200200141586a2018360200200141556a220120042f0180013b0000200141026a20192d00003a0000200541026a2105200a41306a210a200c41016a210c200441d8016a200441e8026a10fa0420042802d8014101460d030c010b0b200141041037000b024002402006410e4b0d00024002400240024002400240024002400240024002400240024020060e0f0001020304050607080e090e0a0b0c000b2017450d0d2018102a0c0d0b02402017450d002018102a0b2014450d0c2015102a0c0c0b02402016450d00201641047421062018210103400240200141046a280200450d002001280200102a0b200141106a2101200641706a22060d000b0b2017450d0b2018102a0c0b0b02402016450d00201641286c21062018210103400240200141046a280200450d002001280200102a0b0240200141106a280200450d002001410c6a280200102a0b200141286a2101200641586a22060d000b0b2017450d0a2018102a0c0a0b2017450d092018102a0c090b2017450d082018102a0c080b2017450d072018102a0c070b02402016450d00201820164104746a2114201821160340024020162802082206450d0020162802002101200641047421060340024020012d00004109470d000240200141046a220d280200220528020441ffffffff0371450d002005280200102a200d28020021050b2005102a0b200141106a2101200641706a22060d000b0b201641106a21010240201641046a280200450d002016280200102a0b2001211620012014470d000b0b2017450d062018102a0c060b02402016450d00201641146c21062018210103400240200141046a280200450d002001280200102a0b200141146a21012006416c6a22060d000b0b2017450d052018102a0c050b02402016450d0020182016411c6c6a2114201821160340024020162802042201450d0002402016410c6a2802002206450d00200641047421060340024020012d00004109470d000240200141046a220d280200220528020441ffffffff0371450d002005280200102a200d28020021050b2005102a0b200141106a2101200641706a22060d000b0b201641086a280200450d002016280204102a0b2016411c6a21010240201641146a280200450d002016280210102a0b2001211620012014470d000b0b2017450d042018102a0c040b02402016450d002018201641186c6a21142018211603400240201641046a280200450d002016280200102a0b0240201641146a2802002206450d00201628020c2101200641047421060340024020012d00004109470d000240200141046a220d280200220528020441ffffffff0371450d002005280200102a200d28020021050b2005102a0b200141106a2101200641706a22060d000b0b201641186a21010240201641106a280200450d00201628020c102a0b2001211620012014470d000b0b2017450d032018102a0c030b02402016450d0020182016411c6c6a2114201821160340024020162802042201450d0002402016410c6a2802002206450d00200641047421060340024020012d00004109470d000240200141046a220d280200220528020441ffffffff0371450d002005280200102a200d28020021050b2005102a0b200141106a2101200641706a22060d000b0b201641086a280200450d002016280204102a0b2016411c6a21010240201641146a280200450d002016280210102a0b2001211620012014470d000b0b2017450d022018102a0c020b02402018450d002017450d002018102a0b02402014450d0002402012450d002012410c6c2106201421010340024020012802002205450d00200141046a280200450d002005102a0b2001410c6a2101200641746a22060d000b0b2013450d002014102a0b2010450d010240200e450d002010200e4104746a21172010211803402018220d41106a21180240200d2802042201450d000240200d410c6a2802002206450d002006410c6c21060340024020012802002205450d00200141046a280200450d002005102a0b2001410c6a2101200641746a22060d000b0b200d41086a280200450d00200d280204102a0b20182017470d000b0b200f450d012010102a0c010b02402017450d002018102a0b02402014450d002013450d002014102a0b2010450d002011102a0b0c010b024020042d00dc010d002008200c41306c6a21062008210102400340024020062001470d004100210d0c020b20012d0000210a200141306a220b2101200a410c470d000b200b415c6a280200210d0b2008200c41306c6a210b20082101024003404100210a0240200b2001470d00410021010c020b20012d00002106200141306a2205210120064104470d000b200441f8006a200541546a10fa03200428027c21010b0240200d2001470d004101210741e100210b41f3da012105410021060c030b0240200c450d00200c41306c210a2008210103402001108204200141306a2101200a41506a220a0d000b0b41012106411a210a024020090d000c030b2008102a0c020b20042802dc01220a4110762105200a410876210b200441d8016a41106a280200210d200441e4016a2802002118200441d8016a41086a28020021070b0240200c450d00200c41306c21062008210103402001108204200141306a2101200641506a22060d000b0b4101210602402009450d002008102a0b200d2109201821080b02402006450d00200821060c040b20042802f0022002470d022005411074200b41ff017141087472200a41ff017172211c2008200c41306c6a210a200821010240024002400240024002400240024002400240024002400340200a2001460d0120012d00002102200141306a2206210120024102470d000b200441f0006a200641546a10fa034104211d02402004280274221e0d004100211e0c020b201e41047422014100480d0c2004280270210220011028221d450d0a201e410474210641002115201d21010340200241086a280200220a417f4c0d042002410c6a2d0000210b2002280200210502400240200a0d004101210d0c010b200a1028220d450d060b200d2005200a109a0521052001410d6a2002410d6a2d00003a00002001410c6a200b3a0000200141086a200a360200200141046a200a36020020012005360200200141106a2101201541016a2115200241106a2102200641706a22060d000b201d0d020b4100211e4104211d0b410021150b2008200c41306c6a210a2008210102400340410021174104210b0240200a2001470d0041042102410021010c020b20012d00002102200141306a2206210120024103470d000b200441e8006a200641546a10fa0341042102410021012004280268220a450d00200428026c2101200a21020b024020010d004101211a41002102410021184100210541002110410121124100210a4100211141042116410021064100211f410421134100210e0c090b200141286c210d2002411c6a21014104210b410021174101211a41002102410021184100210541002110410121124100210a4100211141042116410021064100211f410421134100210e0340024002400240024002402001417c6a2d00000e0400010203000b20012802002114024020022018470d00200241016a22182002490d0f2002410174220f2018200f20184b1b221841ffffffff03712018470d0f2018410274220f4100480d0f0240024020020d00200f1028210b0c010b200b2002410274200f102c210b0b200b450d080b200b20024102746a2014360200200241016a21020c030b200441d8016a41086a2214200141086a280200360200200420012902003703d8010240200a2011470d00200a41016a2211200a490d0e200a410174220f2011200f20114b1b2211ad420c7e221b422088a70d0e201ba7220f4100480d0e02400240200a0d00200f102821160c010b2016200a410c6c200f102c21160b2016450d080b2016200a410c6c6a220f20042903d801370200200f41086a2014280200360200200a41016a210a0c020b200441d8016a41086a2214200141086a280200360200200420012902003703d80102402006201f470d00200641016a220f2006490d0d20064101742219200f2019200f4b1b221fad420c7e221b422088a70d0d201ba7220f4100480d0d0240024020060d00200f102821130c010b20132006410c6c200f102c21130b2013450d080b20132006410c6c6a220f20042903d801370200200f41086a2014280200360200200641016a21060c010b2001417e6a22142d0000210f2001417d6a22192d00002120024020052010470d00200541016a22102005490d0c200541017422212010202120104b1b221020106a22222010490d0c20224100480d0c0240024020050d002022102821120c010b201220212022102c21120b2012450d080b201220054101746a2222200f4101713a0001202220203a000020142d0000211420192d0000210f02400240200e2017460d00200e21190c010b201741016a22192017490d0c201741017422222019202220194b1b222020206a22192020490d0c20194100480d0c0240024020170d0020191028211a0c010b201a20222019102c211a0b201a450d0920172119202021170b200541016a2105201a20194101746a221920144101713a00012019200f3a0000200e41016a210e0b200141286a2101200d41586a220d450d090c000b0b1036000b200a41011037000b200f41041037000b200f41041037000b200f41041037000b202241011037000b201941011037000b200141041037000b2008200c41306c6a21142008210102400240024002400240024002400240024002400240024002400240034020142001460d0120012d0000210d200141306a220f2101200d4104470d000b200441e0006a200f41546a10fa0320042802642201450d002004280260210d2001410274210f20024101742114200241027421010340200d2802002119024020022018470d00200241016a22182002490d1020142018201420184b1b221841ffffffff03712018470d10201841027422204100480d100240024020020d0020201028210b0c010b200b20012020102c210b0b200b450d030b200d41046a210d200b20016a2019360200201441026a2114200141046a2101200241016a2102200f417c6a220f0d000b0b2008200c41306c6a21142008210102400240034020142001460d0120012d0000210d200141306a220f2101200d4105470d000b200441d8006a200f41546a10fa03200428025c410c6c2219450d0020042802582101200a4101742114200a410c6c210d0340200141086a210f024002400240200141046a2802004101470d002004200f28020022203602c0022001280200222220204b0d010b20044100360280010c010b200441023602ec01200442023702dc01200441e8a7c6003602d801200441013602f402200441013602ec02200420223602d0022004200441e8026a3602e8012004200441d0026a3602f0022004200441c0026a3602e80220044180016a200441d8016a1033200428028001450d0020044180016a21010c0e0b2001290200211b200441d8016a41086a2220200f2802003602002004201b3703d8010240200a2011470d00200a41016a2211200a490d1120142011201420114b1b2211ad420c7e221b422088a70d11201ba7220f4100480d1102400240200a0d00200f102821160c010b2016200d200f102c21160b2016450d030b2001410c6a21012016200d6a220f20042903d801370200200f41086a2020280200360200201441026a2114200d410c6a210d200a41016a210a201941746a22190d000b0b2008200c41306c6a21142008210102400240034020142001460d0120012d0000210d200141306a220f2101200d4106470d000b200441d0006a200f41546a10fa032004280254220d450d0020042802502101200d410c6c210f200641017421142006410c6c210d0340200441d8016a2001108305024020042802d801450d00200441d8016a21010c0f0b2001290200211b200441d8016a41086a2219200141086a2802003602002004201b3703d80102402006201f470d00200641016a221f2006490d122014201f2014201f4b1b221fad420c7e221b422088a70d12201ba722204100480d120240024020060d002020102821130c010b2013200d2020102c21130b2013450d030b2001410c6a21012013200d6a222020042903d801370200202041086a2019280200360200201441026a2114200d410c6a210d200641016a2106200f41746a220f0d000b0b2008200c41306c6a21142008210102400240034020142001460d0120012d0000210d200141306a220f2101200d4107470d000b200441c8006a200f41546a10fa03200428024c220d450d0020042802482201200d4104746a21222005410174210d200441d8016a41047221200340200441d8016a2001201a200e10840502400240024020042d00d8014101460d00200420042d00d90122143a00c002024020142001410c6a2d0000220f470d0020044100360280010c030b200441023602ec01200442023702dc01200441fca8c6003602d801200441273602f402200441273602ec022004200f3a00d0022004200441e8026a3602e8012004200441c0026a3602f0022004200441d0026a3602e80220044180016a200441d8016a10330c010b20044180016a41086a202041086a28020036020020042020290200370380010b0240200428028001450d0020044180016a21010c110b2001410c6a2d000021140b2001410d6a2d0000210f024020052010470d00200541016a22102005490d13200d2010200d20104b1b221020106a22192010490d1320194100480d130240024020050d002019102821120c010b2012200d2019102c21120b2012450d030b2012200d6a221920143a0000201941016a200f4101713a0000200d41026a210d200541016a2105200141106a22012022470d000b0b200441b8016a2002360200200441b4016a2018360200200441ac016a2015360200200441a8016a201e360200200441a0016a20053602002004419c016a201036020020044194016a200a36020020044190016a20113602002004200b3602b0012004201d3602a40120042012360298012004201636028c0120042006360288012004201f3602840120042013360280012008200c41306c6a210a20082101024003400240200a2001470d004100210b0c020b20012d00002102200141306a2206210120024104470d000b200441c0006a200641546a10fa032004280244210b0b2004200b3602bc012008200c41306c6a210a20082101024003400240200a2001470d00410021010c020b20012d00002102200141306a220621012002410c470d000b2006415c6a28020021010b200420013602c001200b2001470d0a024002400240200b450d002008200c41306c6a210a200821010340200a2001460d0320012d00002102200141306a2206210120024104470d000b2008200c41306c6a210b200821010340200b2001460d0220012d00002102200141306a220a21012002410c470d000b200441386a200641546a10fa03200428023c2201450d002004280238220d20014102746a2114200a415c6a2118200a41546a211620044191026a210f410021050340200420053602c4012018280200210120162802002102200442013702dc012004418487c6003602d801200441013602d402200441013602ec012004200441d0026a3602e8012004200441c4016a3602d002200441e8026a200441d8016a103320042802e802210a20042902ec02211b200120054d0d100240201ba7450d00200a102a0b2004200d28020022013602c002024002400240024020042802ac0120014b0d00200441013602ec01200442023702dc0120044188acc6003602d801200441013602d4022004200441d0026a3602e8012004200441c0026a3602d002200441e8026a200441d8016a103320042902ec02221b422088a7210120042802e8022106201ba721020c010b0240024002402002200541186c6a22022802142215450d0020042802a40120014104746a220a2d000d2110200a2802002111200228020c210120022802002113200a2802082212210602402002280208220e450d00200e410374210b201221022013210a034002402002200a2802006a220620024f0d0002404120102822060d00412041011037000b200641186a41002900e8ae46370000200641106a41002900e0ae46370000200641086a41002900d8ae46370000200641002900d0ae463700000c040b200a41086a210a20062102200b41786a220b0d000b0b0240410810282202450d0020022010ad42ff0183422886370200200441d0026a41026a220a200441e8026a41026a2d00003a0000200420042f00e8023b01d002200420103a00900220044180800136028c022004428180808010370284022004200236028002200442808080808080103703f801200442013703f001200420063602ec012004200e3602e801200420133602e401200420123602e001200420113602dc01200420044180016a3602d801200f20042f01d0023b0000200f41026a200a2d00003a00002015410474210a41002102034020042002360298022004200136029c02200441b0026a200441d8016a2001108505024020042802b002450d00200441c0026a41086a200441b0026a41086a280200360200200420042903b0023703c002200441033602e402200442033702d402200441e881c6003602d002200441283602fc02200441013602f402200441293602ec022004200441e8026a3602e0022004200441c0026a3602f802200420044198026a3602f00220042004419c026a3602e802200441a0026a200441d0026a1033024020042802c402450d0020042802c002102a0b20042802a0022206450d0020042902a402211b024020042802f401450d0020042802f001102a0b201b42208821230240200428028402450d00200428028002102a0b2023a72101201ba721020c070b200141106a2101200241016a2102200a41706a220a0d000b02402004280288020d00024020042802f401450d0020042802f001102a0b200428028402450d07200428028002102a0c070b418082c6001032000b410841041037000b412010282206450d01200641186a41002900df8146370000200641106a41002900d78146370000200641086a41002900cf8146370000200641002900c781463700000b41202102412021010c010b412041011037000b2006450d010b200420063602d00220042001ad4220862002ad843702d4022004200441d0026a3602c002200441023602ec01200442023702dc012004418c87c6003602d8012004412a3602f402200441013602ec022004200441e8026a3602e8012004200441c0026a3602f0022004200441c4016a3602e802200441c8016a200441d8016a1033024020042802d402450d0020042802d002102a0b20042802c801220a450d0020042902cc01211b0c110b200541016a2105200d41046a220d2014470d000b0b2008200c41306c6a210a200821010240024002400340200a2001460d0120012d00002102200141306a2206210120024109470d000b2004200641546a28020022013602b002024020042802b80120014b0d00200441ec016a4101360200200442023702dc01200441e4abc6003602d801200441013602d4022004200441d0026a3602e8012004200441b0026a3602d002200441e8026a200441d8016a10330c0c0b200420042802b00120014102746a28020022013602c002024020042802ac0120014b0d00200441ec016a4101360200200442023702dc0120044188acc6003602d801200441013602d4022004200441d0026a3602e8012004200441c0026a3602d002200441e8026a200441d8016a10330c0c0b20042802a40120014104746a220131000d4220862001350208844280808080c000510d00412d1028220a450d01200a41256a41002900c18746370000200a41206a41002900bc8746370000200a41186a41002900b48746370000200a41106a41002900ac8746370000200a41086a41002900a48746370000200a410029009c874637000042ad808080d005211b0c110b2008200c41306c6a210a200821010340200a2001460d0a20012d00002102200141306a2206210120024108470d000b200441306a200641546a221610fa03200428023021014100210a02400240200428023422020d004104210b410021180c010b200241ffffffff01712002470d15200241037422064100480d1520061028220b450d02200221180b02402002450d002001200241146c6a21062002410274417c6a2105200b210203402001280200210a200241046a200141086a2802003602002002200a360200200241086a2102200141146a22012006470d000b200541027641016a210a0b200b200a200441d8016a41004120200a676b10fd04200b200a4103746a2206200b460d084101210a200b2101200b2102034002400240200a450d00200620016b410376200a4d0d0b2001200a4103746a22010d010c0b0b20062001460d0a0b200420023602c00202400240200241046a280200220a200141046a280200470d00200228020022052001280200220d460d012005200d200a109c05450d010b200141086a21014100210a200241086a22022006470d010c0a0b0b200441ec016a4101360200200442013702dc01200441cc87c6003602d8012004412b3602d4022004200441d0026a3602e8012004200441c0026a3602d002200441e8026a200441d8016a10330c0c0b412d41011037000b200641041037000b41ba86c60041c8001050000b419c86c600411e1050000b201941011037000b202041041037000b200f41041037000b202041041037000b200441286a201610fa030240200428022c2201450d00200141146c2102200428022841106a210102400340024002400240024002402001417c6a2802000e0400030201000b20042001280200220a3602b002024020042802b801200a4b0d00200441ec016a4101360200200442023702dc01200441e4abc6003602d801200441013602d4022004200441d0026a3602e8012004200441b0026a3602d002200441e8026a200441d8016a10330c0b0b200420042802b001200a4102746a280200220a3602c00220042802ac01200a4b0d03200441013602ec01200442023702dc0120044188acc6003602d801200441013602d4022004200441d0026a3602e8012004200441c0026a3602d002200441e8026a200441d8016a10330c0a0b20042001280200220a3602b002024020042802a001200a4b0d00200441ec016a4101360200200442023702dc01200441a8acc6003602d801200441013602d4022004200441d0026a3602e8012004200441b0026a3602d002200441e8026a200441d8016a10330c0a0b200428029801200a4101746a2d0001450d02200441ec016a4101360200200442023702dc01200441c8acc6003602d801200441013602d4022004200441d0026a3602e8012004200441b0026a3602d002200441e8026a200441d8016a10330c090b20042001280200220a3602c002200428028801200a4b0d01200441013602ec01200442023702dc0120044194abc6003602d801200441013602d4022004200441d0026a3602e8012004200441c0026a3602d002200441e8026a200441d8016a103320042802e802220a0d090c010b20042001280200220a3602c002200428029401200a4d0d020b200141146a21012002416c6a22020d000c020b0b200441ec016a4101360200200442023702dc01200441c4abc6003602d801200441013602d4022004200441d0026a3602e8012004200441c0026a3602d002200441e8026a200441d8016a10330c040b2018450d00200b102a0b2008200c41306c6a210a2008210102400340200a2001460d0120012d00002102200141306a2206210120024103470d000b200441206a200641546a10fa0320042802242201450d0020042802202106200141286c210b41002101034002400240024002400240200620016a220241186a2d00000e0400030201000b20042002411c6a28020022023602c00220042802ac0120024b0d03200441ec016a4101360200200442023702dc0120044188acc6003602d801200441013602d4022004200441d0026a3602e8012004200441c0026a3602d002200441e8026a200441d8016a10330c060b2002411a6a2d0000450d022002410c6a2802002101200241146a2802002102200441d8016a41146a4101360200200420023602d402200420013602d002200441043602c402200442013702dc01200441d487c6003602d8012004200441d0026a3602c0022004200441c0026a3602e801200441e8026a200441d8016a10330c050b200441d8016a2002411c6a10830520042802d801220a450d0120042902dc01211b0c0a0b200241206a2802004101470d002002411c6a280200210a2004200241246a28020022023602b002200a20024d0d00200441023602ec01200442023702dc01200441e8a7c6003602d801200441013602f402200441013602ec022004200a3602c0022004200441e8026a3602e8012004200441c0026a3602f0022004200441b0026a3602e802200441d0026a200441d8016a103320042802d002220a0d080b200b200141286a2201470d000b0b02400240024002400240200428029401220141014b0d00200428028801220141014b0d012008200c41306c6a210a200821010240024002400240024002400340200a2001460d0120012d00002102200141306a220621012002410d470d000b200441186a200641546a10fa0320042802182201200428021c411c6c6a2106034020012006460d012004200128020022023602c002024020042802880120024b0d00200441013602ec01200442023702dc0120044194abc6003602d801200441013602d4022004200441d0026a3602e8012004200441c0026a3602d002200441e8026a200441d8016a103320042802e802220a450d0020042902ec02211b0c130b200141046a2201280200450d02200441d8016a200120042802980120042802a00110840520042d00d8014101460d03200141186a210120042d00d901450d000b41201028220a450d08200a41186a41002900848846370000200a41106a41002900fc8746370000200a41086a41002900f48746370000200a41002900ec874637000042a08080808004211b0c110b2008200c41306c6a210a2008210102400340200a2001460d0120012d00002102200141306a220621012002410a470d000b200441106a200641546a10fa0320042802142201450d002004280210220b2001411c6c6a21050340200b450d012004200b28020022013602c00220042802940120014d0d04200b280204450d05200441d8016a200b41046a20042802980120042802a00110840520042d00d8014101460d0620042d00d9010d0d200441086a200b10cd0402400240200428020c2201450d00200428020821022001410274210a20042802b801210603402004200228020022013602b0020240200620014b0d00200441ec016a4101360200200442023702dc01200441e4abc6003602d801200441013602d4022004200441d0026a3602e8012004200441b0026a3602d002200441e8026a200441d8016a10330c100b200420042802b00120014102746a28020022013602c00220042802ac0120014d0d02200241046a2102200a417c6a220a0d000b0b200b411c6a220b2005460d020c010b0b200441013602ec01200442023702dc0120044188acc6003602d801200441013602d4022004200441d0026a3602e8012004200441c0026a3602d002200441e8026a200441d8016a10330c0b0b0240200428028401450d00200428028001102a0b0240200428029001450d00200428028c01102a0b0240200428029c01450d00200428029801102a0b024020042802ac012202450d0020042802a40121012002410474210203400240200141046a280200450d002001280200102a0b200141106a2101200241706a22020d000b0b024020042802a801450d0020042802a401102a0b024020042802b401450d0020042802b001102a0b2017450d13201a102a0c130b41291028220a450d07200a41286a41002d00b488463a0000200a41206a41002900ac8846370000200a41186a41002900a48846370000200a41106a410029009c8846370000200a41086a41002900948846370000200a410029008c884637000042a98080809005211b0c0f0b200441e0016a290300211b20042802dc01210a0c0e0b200441ec016a4101360200200442023702dc01200441c4abc6003602d801200441013602d4022004200441d0026a3602e8012004200441c0026a3602d002200441e8026a200441d8016a10330c070b412a1028220a450d05200a41286a41002f00dd88463b0000200a41206a41002900d58846370000200a41186a41002900cd8846370000200a41106a41002900c58846370000200a41086a41002900bd8846370000200a41002900b5884637000042aa808080a005211b0c0c0b200441e0016a290300211b20042802dc01210a0c0b0b200441ec016a4101360200200442013702dc01200441dc87c6003602d801200441013602d402200420013602c0022004200441d0026a3602e8012004200441c0026a3602d002200441e8026a200441d8016a10330c040b200441ec016a4101360200200442013702dc01200441e487c6003602d801200441013602d402200420013602c0022004200441d0026a3602e8012004200441c0026a3602d002200441e8026a200441d8016a10330c030b412041011037000b412941011037000b412a41011037000b20042802e802210a20042902ec02211b0c050b024041201028220a450d00200a41186a41002900848846370000200a41106a41002900fc8746370000200a41086a41002900f48746370000200a41002900ec874637000042a08080808004211b0c050b412041011037000b20042802e802210a0b20042902ec02211b2018450d02200b102a0c020b200441ec016a4102360200200441f4026a4101360200200442023702dc012004418c86c6003602d801200441013602ec022004200441e8026a3602e8012004200441c0016a3602f0022004200441bc016a3602e802200441d0026a200441d8016a103320042802d002210a0b20042902d402211b0b0240200428028401450d00200428028001102a0b0240200428029001450d00200428028c01102a0b0240200428029c01450d00200428029801102a0b024020042802ac012202450d0020042802a40121012002410474210203400240200141046a280200450d002001280200102a0b200141106a2101200241706a22020d000b0b024020042802a801450d0020042802a401102a0b024020042802b401450d0020042802b001102a0b2017450d01201a102a200a0d040c020b2001290204211b2001280200210a02402017450d00201a102a0b0240201f450d002013102a0b02402011450d002016102a0b02402010450d002012102a0b02402015450d0020154104742102201d210103400240200141046a280200450d002001280200102a0b200141106a2101200241706a22020d000b0b0240201e450d00201d102a0b2018450d00200b102a0b200a0d020b2000201c36020420004100360200200041186a2003360200200041146a200c360200200041106a20093602002000410c6a2008360200200041086a20073602000c040b1031000b0240201ba7450d00200a102a0b200041ea8ac60036020420004101360200200041086a41133602000240200c450d00200c41306c21022008210103402001108204200141306a2101200241506a22020d000b0b2009450d022008102a0c020b200441003a00d002200441ec016a4101360200200442013702dc01200441a4e2c5003602d801200441263602c4022004200441c0026a3602e8012004200441d0026a3602c00220044180016a200441d8016a1033200428028001210720042802840121060240200c450d00200c41306c21022008210103402001108204200141306a2101200241506a22020d000b0b4105210a2009450d002008102a0b02402006450d00200a41ff01714105470d002007102a0b200041d48ac60036020420004101360200200041086a41163602000b20044180036a24000b160020002001280208360204200020012802003602000bd21301177f23004190026b220224000240024002400240024002402000280200220341f8b9c000460d00200028020421040c010b41002104200241b8016a410041d8001099051a2002411f6a220542003700002002420037011a41ec0010282203450d0120034100360200200320022902183702042003410b6a2005290000370000200341136a200241b7016a41d900109a051a20004100360204200020033602000b200141ff0171210602400340200341066a210720032f01062108410c21094100210502400240034020082005460d01200320056a210a200941086a2109200541016a210502404100417f4101200a41086a2d0000220a20064b1b200a2006461b41016a0e03000301000b0b2005417f6a21080b2004450d022004417f6a2104200320084102746a41ec006a28020021030c010b0b200320096a42013702000c030b2000200028020841016a360208024002400240024020072f01002205410b490d00200241276a41016a410041d8001099051a200241003a001941ec001028220b450d03200b4100360200200b410036000f200b4200370007200b20022f01183b0005200b41136a200241276a41d900109a051a2003410e6a2d0000210c2003280248210d2003280244210e200b41086a2003410f6a20032f010641796a2205109a052109200b41146a200341cc006a2005410374109a052106200341063b0106200b20053b010620084107490d0120092008417a6a220a6a2009200841796a22086a2209200541ffff037120086b109b051a200920013a00002006200a4103746a200620084103746a2205200b41066a22072f010020086b410374109b051a2005410136020020072f010021050c020b200341086a2209200841016a22066a200920086a2209200520086b220a109b051a200920013a0000200341146a220920064103746a200920084103746a2209200a410374109b051a200941013602002003200541016a3b01060c050b200341086a2205200841016a22096a200520086a220620072f0100220520086b220a109b051a200620013a0000200341146a220620094103746a200620084103746a2209200a410374109b051a200941013602000b2007200541016a3b01002003280200220a450d02200341046a2105200241276a41016a210f200241a8016a2101200241a0016a211020024198016a211120024190016a211220024180016a41086a2113034020052f0100210602400240024002400240200a2f01062205410b490d00200f410041d8001099051a200241003a0019200220022f01183b0108200241b7016a200241276a41d900109a051a20014200370300201042003703002011420037030020124200370300201342003703002002420037038001419c0110282209450d03200941003602002009410036000f20094200370007200920022f01083b0005200941136a200241b7016a41d900109a051a20094194016a20012903003702002009418c016a201029030037020020094184016a2011290300370200200941fc006a2012290300370200200941f4006a2013290300370200200920022903800137026c200a41c8006a2802002114200a41c4006a2802002115200a410e6a2d00002116200941086a200a410f6a200a2f0106220341796a2205109a052117200941146a200a41cc006a2005410374109a052118200941ec006a200a4188016a2003417a6a2204410274109a052107200a41063b0106200920053b010602402004450d00410021052007210303402003280200220820053b010420082009360200200341046a21032004200541016a2205470d000b0b20064107490d0120172006417a6a22036a2017200641796a22056a220820092f010620056b109b051a2008200c3a0000201820034103746a201820054103746a220820092f010620056b410374109b051a2008200e3602002008200d360204200920092f010641016a22083b01062006410274220c20076a416c6a200720034102746a2204200841ffff0371220620036b410274109b051a2004200b36020020062003490d022009200c6a41d4006a2103034020032802002208200541016a22053b010420082009360200200341046a210320052006490d000c030b0b200a41086a2209200641016a22036a200920066a2209200520066b2208109b051a2009200c3a0000200a41146a220920034103746a200920064103746a22092008410374109b051a2009200e3602002009200d360204200a200541016a22053b01062006410274200a41ec006a22096a41086a200920034102746a2209200541ffff0371220820036b410274109b051a2009200b360200200620084f0d08200a2003417f6a22054102746a41f0006a2103034020032802002209200541016a22053b01042009200a360200200341046a210320052008490d000c090b0b200a41086a2203200641016a22056a200320066a2203200a2f0106220820066b2204109b051a2003200c3a0000200a41146a220320054103746a200320064103746a22032004410374109b051a2003200e3602002003200d360204200a200841016a22033b010620064102742207200a41ec006a22086a41086a200820054102746a2204200341ffff0371220820056b410274109b051a2004200b360200200620084f0d00200a20076a41f0006a2105034020052802002203200641016a22063b01042003200a360200200541046a210520082006470d000b0b200a28020022030d012009210b2014210d2015210e2016210c0c050b419c0141041037000b200a41046a21052003210a2016210c2015210e2014210d2009210b0c000b0b41ec0041041037000b41ec0041041037000b200241b7016a41016a410041d8001099051a2002411f6a220542003700002002420037011a200220022902183703082002200529000037000f200241276a200241b7016a41d900109a051a200241a8016a22034200370300200241a0016a2209420037030020024180016a41186a2208420037030020024190016a2206420037030020024180016a41086a220a42003703002002420037038001419c0110282205450d0120054100360200200520022903083702042005410b6a200229000f370000200541136a200241276a41d900109a051a20054194016a20032903003702002005418c016a200929030037020020054184016a2008290300370200200541fc006a2006290300370200200541f4006a200a290300370200200520022903800137026c20052000280200220336026c200020053602002000200028020441016a360204200341003b010420032005360200200520052f010622034103746a220941186a200d360200200941146a200e360200200520036a41086a200c3a0000200541ec006a200341016a22034102746a200b360200200520033b0106200b20033b0104200b20053602000b20024190026a24000f0b419c0141041037000b822701377f2001410c6a28020021022001280208210341002104024002400240200141106a28020022050d00410021064100210741002108410021094100210a4100210b4100210c4100210d4100210e410021050c010b410021044100210e4100210d4100210c4100210b4100210a4100210941002108410021074100210f4100211002400340200121112010210620032005417f6a220541306c6a220128002c2112200128002821132001280024211420012800202115200128001c2116200128001821172001280014211820012800102119200128000c211a2001280008211b2001280004211c41012110024002400240024002400240024020012d0000221d417e6a221e410e4d0d004101211f0c010b4101211f4101212041012121410121224101212341012124201c21010240024002400240024002400240024002400240024002400240024002400240024002400240201e0e0f00010203040506180717080917171a000b0240200f0d002006211020112101201c210f201b2125201a21260c180b02402026450d0020264104742110200f210103400240200141046a280200450d002001280200102a0b200141106a2101201041706a22100d000b0b4101211f410021102025450d11200f102a0c110b024020070d002006211020112101201c2107201b2127201a21280c170b02402028450d00202841286c21102007210103400240200141046a280200450d002001280200102a0b0240200141106a280200450d002001410c6a280200102a0b200141286a2101201041586a22100d000b0b4100211f410121102027450d0f2007102a0c0f0b2029450d0d2008450d0d2008102a0c0d0b202a450d0b2009450d0b2009102a0c0b0b202b450d09200a450d09200a102a0c090b0240200b0d002006211020112101201c210b201b212c201a212d0c130b0240202d450d00200b202d4104746a2121200b21200340024020202802082210450d0020202802002101201041047421100340024020012d00004109470d000240200141046a221f280200222428020441ffffffff0371450d002024280200102a201f28020021240b2024102a0b200141106a2101201041706a22100d000b0b202041106a21010240202041046a280200450d002020280200102a0b2001212020012021470d000b0b4100212041012110202c450d07200b102a0c070b0240200c0d002006211020112101201c210c201b212e201a212f0c120b0240202f450d00202f41146c2110200c210103400240200141046a280200450d002001280200102a0b200141146a21012010416c6a22100d000b0b4100212141012110202e450d05200c102a0c050b0240200d0d002006211020112101201c210d201b2130201a21310c110b02402031450d00200d2031411c6c6a2121200d21200340024020202802042201450d0002402020410c6a2802002210450d00201041047421100340024020012d00004109470d000240200141046a221f280200222428020441ffffffff0371450d002024280200102a201f28020021240b2024102a0b200141106a2101201041706a22100d000b0b202041086a280200450d002020280204102a0b2020411c6a21010240202041146a280200450d002020280210102a0b2001212020012021470d000b0b41002122410121102030450d03200d102a0c030b0240200e0d002006211020112101201c210e201b2132201a21330c100b02402033450d00200e203341186c6a2121200e212003400240202041046a280200450d002020280200102a0b0240202041146a2802002210450d00202028020c2101201041047421100340024020012d00004109470d000240200141046a221f280200222428020441ffffffff0371450d002024280200102a201f28020021240b2024102a0b200141106a2101201041706a22100d000b0b202041186a21010240202041106a280200450d00202028020c102a0b2001212020012021470d000b0b41002123410121102032450d01200e102a0c010b024020040d002006211020112101201a2134201b2135201c21040c0f0b02402034450d0020042034411c6c6a2121200421200340024020202802042201450d0002402020410c6a2802002210450d00201041047421100340024020012d00004109470d000240200141046a221f280200222428020441ffffffff0371450d002024280200102a201f28020021240b2024102a0b200141106a2101201041706a22100d000b0b202041086a280200450d002020280204102a0b2020411c6a21010240202041146a280200450d002020280210102a0b2001212020012021470d000b0b410021244101211002402035450d002004102a0b201c2104201b2135201a21344101211f410121204101212141012122410121230c0d0b201a2133201b2132201c210e4101211f4101212041012121410121220c0b0b201a2131201b2130201c210d4101211f4101212041012121410121230c0a0b201a212f201b212e201c210c4101211f410121200c080b201a212d201b212c201c210b4101211f0c060b2006211020112101201c210a201b212b201a21360c090b2006211020112101201c2109201b212a201a21370c080b2006211020112101201c2108201b2129201a21380c070b201a2128201b2127201c21070c010b201a2126201b2125201c210f0b410121200b410121210b41012122410121230b410121240b024002400240201e410b4b0d000240024002400240024002400240024002400240201e0e0c000102030405060a070a0809000b2010450d0b0240201a450d00201a4104742110201c210103400240200141046a280200450d002001280200102a0b200141106a2101201041706a22100d000b0b201b450d0b0c0a0b201f450d0a0240201a450d00201a41286c2110201c210103400240200141046a280200450d002001280200102a0b0240200141106a280200450d002001410c6a280200102a0b200141286a2101201041586a22100d000b0b201b0d090c0a0b41000d09201b0d080c090b41000d08201b0d070c080b41000d07201b0d060c070b2020450d060240201a450d00201c201a4104746a211e201c21200340024020202802082210450d0020202802002101201041047421100340024020012d00004109470d000240200141046a221f280200222428020441ffffffff0371450d002024280200102a201f28020021240b2024102a0b200141106a2101201041706a22100d000b0b202041106a21010240202041046a280200450d002020280200102a0b200121202001201e470d000b0b201b0d050c060b2021450d050240201a450d00201a41146c2110201c210103400240200141046a280200450d002001280200102a0b200141146a21012010416c6a22100d000b0b201b0d040c050b2022450d040240201a450d00201c201a411c6c6a211e201c21200340024020202802042201450d0002402020410c6a2802002210450d00201041047421100340024020012d00004109470d000240200141046a221f280200222428020441ffffffff0371450d002024280200102a201f28020021240b2024102a0b200141106a2101201041706a22100d000b0b202041086a280200450d002020280204102a0b2020411c6a21010240202041146a280200450d002020280210102a0b200121202001201e470d000b0b201b0d030c040b2023450d030240201a450d00201c201a41186c6a211e201c212003400240202041046a280200450d002020280200102a0b0240202041146a2802002210450d00202028020c2101201041047421100340024020012d00004109470d000240200141046a221f280200222428020441ffffffff0371450d002024280200102a201f28020021240b2024102a0b200141106a2101201041706a22100d000b0b202041186a21010240202041106a280200450d00202028020c102a0b200121202001201e470d000b0b201b0d020c030b2024450d020240201a450d00201c201a411c6c6a211e201c21200340024020202802042201450d0002402020410c6a2802002210450d00201041047421100340024020012d00004109470d000240200141046a221f280200222428020441ffffffff0371450d002024280200102a201f28020021240b2024102a0b200141106a2101201041706a22100d000b0b202041086a280200450d002020280204102a0b2020411c6a21010240202041146a280200450d002020280210102a0b200121202001201e470d000b0b201b0d010c020b0240201d410e4b0d00200621102011210102400240024002400240024002400240024002400240201d0e0f0001020304040405060e070e08090a000b201b0d0b0c0c0b0240201b450d00201c102a0b2018450d0b2019102a0c0b0b0240201a450d00201a4104742110201c210103400240200141046a280200450d002001280200102a0b200141106a2101201041706a22100d000b0b201b0d090c0a0b201a450d00201a41286c2110201c210103400240200141046a280200450d002001280200102a0b0240200141106a280200450d002001410c6a280200102a0b200141286a2101201041586a22100d000b0b201b0d070c080b0240201a450d00201c201a4104746a211e201c21200340024020202802082210450d0020202802002101201041047421100340024020012d00004109470d000240200141046a221f280200222428020441ffffffff0371450d002024280200102a201f28020021240b2024102a0b200141106a2101201041706a22100d000b0b202041106a21010240202041046a280200450d002020280200102a0b200121202001201e470d000b0b201b0d060c070b0240201a450d00201a41146c2110201c210103400240200141046a280200450d002001280200102a0b200141146a21012010416c6a22100d000b0b201b0d050c060b0240201a450d00201c201a411c6c6a211e201c21200340024020202802042201450d0002402020410c6a2802002210450d00201041047421100340024020012d00004109470d000240200141046a221f280200222428020441ffffffff0371450d002024280200102a201f28020021240b2024102a0b200141106a2101201041706a22100d000b0b202041086a280200450d002020280204102a0b2020411c6a21010240202041146a280200450d002020280210102a0b200121202001201e470d000b0b201b0d040c050b0240201a450d00201c201a41186c6a211e201c212003400240202041046a280200450d002020280200102a0b0240202041146a2802002210450d00202028020c2101201041047421100340024020012d00004109470d000240200141046a221f280200222428020441ffffffff0371450d002024280200102a201f28020021240b2024102a0b200141106a2101201041706a22100d000b0b202041186a21010240202041106a280200450d00202028020c102a0b200121202001201e470d000b0b201b0d030c040b0240201a450d00201c201a411c6c6a211e201c21200340024020202802042201450d0002402020410c6a2802002210450d00201041047421100340024020012d00004109470d000240200141046a221f280200222428020441ffffffff0371450d002024280200102a201f28020021240b2024102a0b200141106a2101201041706a22100d000b0b202041086a280200450d002020280204102a0b2020411c6a21010240202041146a280200450d002020280210102a0b200121202001201e470d000b0b201b0d020c030b0240201c450d00201b450d00201c102a0b02402018450d0002402016450d002016410c6c2110201821010340024020012802002224450d00200141046a280200450d002024102a0b2001410c6a2101201041746a22100d000b0b2017450d002018102a0b2014450d0202402012450d00201420124104746a211c2014212003402020221f41106a21200240201f2802042201450d000240201f410c6a2802002210450d002010410c6c21100340024020012802002224450d00200141046a280200450d002024102a0b2001410c6a2101201041746a22100d000b0b201f41086a280200450d00201f280204102a0b2020201c470d000b0b2013450d022014102a0c020b0240201b450d00201c102a0b02402018450d002017450d002018102a0b2014450d012015102a0c010b201c102a0b20062110201121010b20050d000b4100210520012111201021060b200f0d010b4104210f41002125410021260b20002003360280012000200636025420002026360208200020253602042000200f36020020004188016a200536020020004184016a2002360200200041fc006a2034410020041b360200200041f8006a2035410020041b36020020002004410420041b360274200041f0006a20334100200e1b360200200041ec006a20324100200e1b3602002000200e4104200e1b360268200041e4006a20314100200d1b360200200041e0006a20304100200d1b3602002000200d4104200d1b36025c200041d8006a2011360200200041d0006a202f4100200c1b360200200041cc006a202e4100200c1b3602002000200c4104200c1b360248200041c4006a202d4100200b1b360200200041c0006a202c4100200b1b3602002000200b4104200b1b36023c200041386a20364100200a1b360200200041346a202b4100200a1b3602002000200a4104200a1b3602302000412c6a2037410020091b360200200041286a202a410020091b36020020002009410420091b360224200041206a2038410020081b3602002000411c6a2029410020081b36020020002008410420081b360218200041146a2028410020071b360200200041106a2027410020071b36020020002007410420071b36020c0bb10a010e7f230041106b2202240002400240024002400240024020012802004101470d00200141106a2d000021032001410c6a2802002104200141086a280200210520012f0112210620012d0011210720012802042108200241086a200010fa0320022802082201200228020c22094104746a210a4100210b20094104490d01200341ff0171210c02400340024020012d000c200c470d0020012802082004470d000240200128020022092008460d002004450d002004210d2008210e034020092d0000200e2d0000470d02200941016a2109200e41016a210e200d417f6a220d0d000b0b200741ff0171220941044720012d000d220e410446220d460d00200e2009460d0520094104460d05200d0d050b02400240024002402001411c6a2d0000200c470d00200141186a2802002004470d000240200128021022092008460d002004450d002004210d2008210e034020092d0000200e2d0000470d02200941016a2109200e41016a210e200d417f6a220d0d000b0b200741ff0171220941044720012d001d220e410446220d460d00200e2009460d0120094104460d01200d0d010b2001412c6a2d0000200c470d02200141286a2802002004470d02200128022022092008460d012004450d012004210d2008210e034020092d0000200e2d0000470d03200941016a2109200e41016a210e200d417f6a220d450d020c000b0b200b410172210b0c060b200741ff0171220941044720012d002d220e410446220d460d00200e2009460d0220094104460d02200d0d020b024002402001413c6a2d0000200c470d00200141386a2802002004470d000240200128023022092008460d002004450d002004210d2008210e034020092d0000200e2d0000470d02200941016a2109200e41016a210e200d417f6a220d0d000b0b200741ff0171220941044720012d003d220e410446220d460d00200e2009460d0120094104460d01200d0d010b200b41046a210b200a200141c0006a22016b41304d0d040c010b0b200b410372210b0c030b200b410272210b0c020b2001280204210b0c030b2001200a460d0102400240200741ff0171220f4104460d00200341ff0171210c0c010b200341ff0171210c0340024020012d000c200c470d0020012802082004470d000240200128020022092008460d002004450d002004210d2008210e034020092d0000200e2d0000470d02200941016a2109200e41016a210e200d417f6a220d0d000b0b20012d000d4104460d030b200b41016a210b200141106a2201200a470d000c030b0b0340024020012d000c200c470d0020012802082004470d000240200128020022092008460d002004450d002004210d2008210e034020092d0000200e2d0000470d02200941016a2109200e41016a210e200d417f6a220d0d000b0b20012d000d2209200f470d0020094104470d020b200b41016a210b200141106a2201200a460d020c000b0b2005450d012008102a0c010b024020002802082201200041046a280200470d0002400240200141016a22092001490d002001410174220e2009200e20094b1b220941ffffffff00712009470d002009410474220e41004e0d010b1031000b0240024020010d00200e102821010c010b20002802002001410474200e102c21010b2001450d0220002001360200200041046a2009360200200028020821010b200028020020014104746a220120063b010e200120073a000d200120033a000c2001200436020820012005360204200120083602002000200028020841016a3602082002200010fa032002280204417f6a210b0b200241106a2400200b0f0b200e41041037000bf722032d7f017e017f230041306b22022400200241043602002001280204210320012802002104410121050240024002400240024002400240024002400240024002400240024002400240200128020822060d0041002107410121080c010b413010282207450d012007200636000c200720033600082007200436000420022007360200200741023a000041002108410121070b200141106a2802002109200128020c210a02400240200141146a280200220b0d002007210c0c010b2007410174220d200741016a220c200d200c4b1b220c41306c210e0240024020070d00200e1028210d0c010b2002280200200741306c200e102c210d0b200d450d022002200d360200200d200741306c6a220d41033a0000200d20022f002d3b0001200d200b36000c200d2009360008200d200a360004200d2002290204370210200d41036a2002412f6a2d00003a0000200d41186a2002410c6a290200370200200d41206a200241146a290200370200200d41286a200241046a41186a290200370200200741016a2107410021050b2001411c6a280200210f200128021821104100211102400240200141206a28020022120d00200c210e410021130c010b024002402007200c460d00200c210e0c010b41000d0e41000d0e200c410174220d200c41016a220e200d200e4b1b220ead42307ea722144100480d0e02400240200c0d0020141028210d0c010b2002280200200c41306c2014102c210d0b200d450d042002200d3602000b2002280200200741306c6a220d41043a0000200d20022f002d3b0001200d201236000c200d200f360008200d2010360004200d2002290204370210200d41036a2002412f6a2d00003a0000200d41186a2002410c6a290200370200200d41206a200241146a290200370200200d41286a200241046a41186a29020037020041012113200741016a21070b200141286a280200211420012802242115024002402001412c6a28020022120d00200e210c0c010b024002402007200e460d00200e210c0c010b41000d0e41000d0e200e410174220d200e41016a220c200d200c4b1b220cad42307ea722114100480d0e02400240200e0d0020111028210d0c010b2002280200200e41306c2011102c210d0b200d450d052002200d3602000b2002280200200741306c6a220d41053a0000200d20022f002d3b0001200d201236000c200d2014360008200d2015360004200d2002290204370210200d41036a2002412f6a2d00003a0000200d41186a2002410c6a290200370200200d41206a200241146a290200370200200d41286a200241046a41186a29020037020041012111200741016a21070b200141346a28020021162001280230211702400240200141386a280200220e0d00410021180c010b02402007200c470d0041000d0e41000d0e200c410174220d200c41016a2212200d20124b1b2212ad42307ea722194100480d0e02400240200c0d0020191028210d0c010b2002280200200c41306c2019102c210d0b200d450d062002200d3602002012210c0b2002280200200741306c6a220d41063a0000200d20022f002d3b0001200d200e36000c200d2016360008200d2017360004200d2002290204370210200d41036a2002412f6a2d00003a0000200d41186a2002410c6a290200370200200d41206a200241146a290200370200200d41286a200241046a41186a29020037020041012118200741016a21070b200141c0006a280200211a200128023c211b4101211902400240200141c4006a280200221c0d00200c210e4101211d0c010b024002402007200c460d00200c210e0c010b41000d0e41000d0e200c410174220d200c41016a220e200d200e4b1b220ead42307ea722124100480d0e02400240200c0d0020121028210d0c010b2002280200200c41306c2012102c210d0b200d450d072002200d3602000b2002280200200741306c6a220d41073a0000200d20022f002d3b0001200d201c36000c200d201a360008200d201b360004200d2002290204370210200d41036a2002412f6a2d00003a0000200d41186a2002410c6a290200370200200d41206a200241146a290200370200200d41286a200241046a41186a290200370200200741016a21074100211d0b200141cc006a280200211e2001280248211f02400240200141d0006a28020022200d00200e21120c010b024002402007200e460d00200e21120c010b41000d0e41000d0e200e410174220d200e41016a220c200d200c4b1b2212ad42307ea7220c4100480d0e02400240200e0d00200c1028210d0c010b2002280200200e41306c200c102c210d0b200d450d082002200d3602000b2002280200200741306c6a220d41083a0000200d20022f002d3b0001200d202036000c200d201e360008200d201f360004200d2002290204370210200d41036a2002412f6a2d00003a0000200d41186a200241046a41086a290200370200200d41206a200241146a290200370200200d41286a200241046a41186a290200370200200741016a2107410021190b410121210240024020012802544101460d002012210c0c010b200141d8006a280200210e0240024020072012460d002012210c0c010b41000d0e41000d0e2012410174220d201241016a220c200d200c4b1b220cad42307ea722224100480d0e0240024020120d0020221028210d0c010b2002280200201241306c2022102c210d0b200d450d092002200d3602000b2002280200200741306c6a220d41093a0000200d20022f002d3b0001200d200e360204200d2002290204370208200d41036a2002412f6a2d00003a0000200d41106a2002410c6a290200370200200d41186a200241046a41106a290200370200200d41206a200241046a41186a290200370200200d41286a200241046a41206a290200370200200741016a21070b200141e0006a2802002123200128025c212402400240200141e4006a28020022250d00200c210e0c010b024002402007200c460d00200c210e0c010b41000d0e41000d0e200c410174220d200c41016a220e200d200e4b1b220ead42307ea722124100480d0e02400240200c0d0020121028210d0c010b2002280200200c41306c2012102c210d0b200d450d0a2002200d3602000b2002280200200741306c6a220d410a3a0000200d20022f002d3b0001200d202536000c200d2023360008200d2024360004200d2002290204370210200d41036a2002412f6a2d00003a0000200d41186a2002410c6a290200370200200d41206a200241146a290200370200200d41286a200241046a41186a290200370200200741016a2107410021210b200141ec006a2802002126200128026821274101212202400240200141f0006a28020022280d00200e2112410121290c010b024002402007200e460d00200e21120c010b41000d0e41000d0e200e410174220d200e41016a220c200d200c4b1b2212ad42307ea7220c4100480d0e02400240200e0d00200c1028210d0c010b2002280200200e41306c200c102c210d0b200d450d0b2002200d3602000b2002280200200741306c6a220d410c3a0000200d20022f002d3b0001200d202836000c200d2026360008200d2027360004200d2002290204370210200d41036a2002412f6a2d00003a0000200d41186a2002410c6a290200370200200d41206a200241146a290200370200200d41286a200241046a41186a290200370200200741016a2107410021290b200141f8006a280200212a2001280274212b02400240200141fc006a280200222c0d002012210c0c010b0240024020072012460d002012210c0c010b41000d0e41000d0e2012410174220d201241016a220c200d200c4b1b220cad42307ea7220e4100480d0e0240024020120d00200e1028210d0c010b2002280200201241306c200e102c210d0b200d450d0c2002200d3602000b2002280200200741306c6a220d410d3a0000200d20022f002d3b0001200d202c36000c200d202a360008200d202b360004200d2002290204370210200d41036a2002412f6a2d00003a0000200d41186a2002410c6a290200370200200d41206a200241146a290200370200200d41286a200241046a41186a290200370200200741016a2107410021220b20014184016a2802002112200128028001210d02400240200c20076b20014188016a28020041306c222d41306d220e490d00200228020021010c010b2007200e6a22012007490d0d200c410174222e2001202e20014b1b222ead42307e222f422088a70d0d202fa722304100480d0d02400240200c0d002030102821010c010b2002280200200c41306c2030102c21010b2001450d0c20022001360200202e210c0b2001200741306c6a200d202d109a051a2007200e6a210702402012450d00200d102a0b2000200136020820004280c2cdeb16370200200041106a20073602002000410c6a200c3602002022450d0d0240202c450d00202b202c411c6c6a210e202b21000340024020002802042201450d0002402000410c6a2802002207450d00200741047421070340024020012d00004109470d000240200141046a220c280200220d28020441ffffffff0371450d00200d280200102a200c280200210d0b200d102a0b200141106a2101200741706a22070d000b0b200041086a280200450d002000280204102a0b2000411c6a21010240200041146a280200450d002000280210102a0b200121002001200e470d000b0b202a450d0d202b102a0c0d0b413041041037000b200e41041037000b201441041037000b201141041037000b201941041037000b201241041037000b200c41041037000b202241041037000b201241041037000b200c41041037000b200e41041037000b203041041037000b1031000b02402029450d0002402028450d002027202841186c6a210e2027210003400240200041046a280200450d002000280200102a0b0240200041146a2802002207450d00200028020c2101200741047421070340024020012d00004109470d000240200141046a220c280200220d28020441ffffffff0371450d00200d280200102a200c280200210d0b200d102a0b200141106a2101200741706a22070d000b0b200041186a21010240200041106a280200450d00200028020c102a0b200121002001200e470d000b0b2026450d002027102a0b02402021450d0002402025450d0020242025411c6c6a210e202421000340024020002802042201450d0002402000410c6a2802002207450d00200741047421070340024020012d00004109470d000240200141046a220c280200220d28020441ffffffff0371450d00200d280200102a200c280200210d0b200d102a0b200141106a2101200741706a22070d000b0b200041086a280200450d002000280204102a0b2000411c6a21010240200041146a280200450d002000280210102a0b200121002001200e470d000b0b2023450d002024102a0b02402019450d0002402020450d00202041146c2107201f210103400240200141046a280200450d002001280200102a0b200141146a21012007416c6a22070d000b0b201e450d00201f102a0b0240201d450d000240201c450d00201b201c4104746a210e201b21000340024020002802082207450d0020002802002101200741047421070340024020012d00004109470d000240200141046a220c280200220d28020441ffffffff0371450d00200d280200102a200c280200210d0b200d102a0b200141106a2101200741706a22070d000b0b200041106a21010240200041046a280200450d002000280200102a0b200121002001200e470d000b0b201a450d00201b102a0b02402016410047201841017371450d002017102a0b02402014410047201141017371450d002015102a0b0240200f410047201341017371450d002010102a0b02402005450d000240200b450d00200b41286c2107200a210103400240200141046a280200450d002001280200102a0b0240200141106a280200450d002001410c6a280200102a0b200141286a2101200741586a22070d000b0b2009450d00200a102a0b02402008450d0002402006450d00200641047421072004210103400240200141046a280200450d002001280200102a0b200141106a2101200741706a22070d000b0b2003450d002004102a0b200241306a24000bee0203037f017e027f410121020240024002400240200041086a2802002203417f6a220420034f0d00200420034b0d00200028020020044104746a220329020421052003200141016aad3702042005a721012005422088a721030240200041086a28020022024101460d002002450d0220002802002002417e6a4104746a22022802042001470d002002200228020820036a36020841000f0b410021022003450d000240200041146a2802002204200041106a280200470d00200441016a22062004490d04200441017422072006200720064b1b220641ffffffff01712006470d04200641037422074100480d040240024020040d002007102821040c010b200028020c20044103742007102c21040b2004450d032000200436020c200041106a2006360200200028021421040b200028020c20044103746a22042003360204200420013602002000200028021441016a3602140b20020f0b41ede3c500413f1050000b200741041037000b1031000b8a1302147f027e23004180026b220424000240024020014115490d0041012105410121060240024002400340200121072000210820052006714101732109024002400240024002400240034002400240024002402003450d00024020054101710d002000200110de042003417f6a21030b2001410276220a41036c210b200a410174210c4100210d024020014132490d00200b200b417f6a220d2000200b4103746a280200220e2000200d4103746a280200220f4922101b2211200b41016a2212200d200b20101b200020124103746a280200220b200f200e20101b220d49220f1b200b200d200f1b200020114103746a2802004922131b210b200c200c417f6a220d2000200c4103746a28020022112000200d4103746a280200221249220e1b2214200c4101722206200d200c200e1b200020064103746a280200220c20122011200e1b220d4922111b200c200d20111b200020144103746a2802004922141b210c200a200a417f6a22122000200a4103746a2802002206200020124103746a280200221549220d1b2216200a41016a22172012200a200d1b200020174103746a280200220a20152006200d1b22064922121b200a200620121b200020164103746a2802004922061b210a41024101200d1b200d20121b20066a200e6a20116a20146a20106a200f6a20136a210d0b200d2000200c4103746a280200220e2000200a4103746a280200220f4922106a2000200b4103746a280200220d200f200e20101b221149220f6a210e200d2011200f1b2000200c200a20101b220d4103746a280200490d01200b200a200c20101b200f1b210d0c020b2000200110df040c0f0b200e41016a220e410c490d0002402001410176220b450d00200020014103746a41786a210a2000210c0340200c2902002118200c200a290200370200200a2018370200200c41086a210c200a41786a210a200b417f6a220b0d000b0b2001200d417f736a210d4101210a0c010b200e45210a0b0240200a452009724101710d002000200110e0040d0d0b2002450d02200d20014f0d01024020022802002000200d4103746a220a2802004f0d0020002108200121070c040b200029020021182000200a290200370200200a2018370200200041786a210f200041086a211120002902002218a721104100210c2001210b03400240200c200b417f6a220d4f0d002011200c4103746a210a0340200a28020020104b0d01200a41086a210a200d200c41016a220c470d000b200d210c0b200f200b4103746a210a02400340200c200b417f6a220b4f0d01200a280200210d200a41786a220e210a200d20104b0d000b2011200c4103746a220a2902002119200a200e41086a220d290200370200200d2019370200200c41016a210c0c010b0b2000201837020002402001200c41016a220a490d002000200a4103746a21002001200a6b220141154f0d010c0c0b0b200a20011044000b41b8e9c500200d20011034000b2007450d010b200d20074f0d012008290200211820082008200d4103746a220a290200370200200a2018370200200841086a210e20082902002219a72111410021142007417f6a2210450d02200e210a0340200a28020020114f0d03200a41086a210a2010201441016a2214470d000b201021140c020b4198e9c500410041001034000b41a8e9c500200d20071034000b200820074103746a210c2010210b02400340200c210d200b220a20144d22060d01200a417f6a210b200d41786a220c28020020114f0d000b0b0240200a2014490d002010200a490d0241800121054100210b410021014100210c4100210f4180012109200e20144103746a2215211003400240200d20106b220a4187104b22130d00200a410376220a41807f6a200a2001200b49200f200c49220e7222001b210a02402000450d002009200a200e1b2109200a2005200e1b21050c010b200a200a41017622096b21050b0240200f200c470d00024020090d002004220c210f0c010b4100210a2004220f210c2010210e0340200c200a3a0000200c200e28020020114f6a210c200e41086a210e2009200a41016a220a470d000b0b02402001200b470d00024020050d0020044180016a220b21010c010b200d41786a210a4100210e20044180016a2201210b0340200b200e3a0000200b200a2802002011496a210b200a41786a210a2005200e41016a220e470d000b0b0240200b20016b220a200c200f6b220e200e200a4b1b2212450d002010200f2d00004103746a220a2902002118200a200d20012d0000417f734103746a290200370200024020124101460d004100210a0340200d2001200a6a220e2d0000417f734103746a2010200f200a6a41016a22002d00004103746a290200370200201020002d00004103746a200d200e41016a2d0000417f734103746a290200370200200a41026a210e200a41016a2200210a200e2012490d000b200120006a2101200f20006a210f0b200d20012d0000417f734103746a2018370200200141016a2101200f41016a210f0b200d20054103746b200d2001200b461b210d201020094103746a2010200f200c461b211020130d000b02400240200f200c4f0d00200d210a03402010200c417f6a220c2d00004103746a220b2902002118200b200a41786a220a290200370200200a2018370200200f200c490d000c020b0b2010210a2001200b4f0d000340200a2902002118200a200d200b417f6a220b2d0000417f734103746a220c290200370200200c2018370200200a41086a210a2001200b490d000b0b200820193702002007200a20156b41037620146a22014d0d032008200820014103746a220a290200370200200a2019370200200720016b220c450d04200c20012001200c4b1b210b2007410376210d200a41086a2100024002402001200c417f6a220c490d002000200c200a2003108004200821000c010b2008200120022003108004200a2102200c21010b200b200d4f2105200141154f0d010c050b0b2014200a1044000b200a2010103c000b41a8e9c500200120071034000b41dc83c6001032000b20014102490d00200041786a21104100210e4101210b0340200b410374210c200b417f6a210a200b41016a210b02402000200c6a220d2802002000200a4103746a220f2802004f0d00200d2902002118200d200f2902003702000240200a450d00200e210c2010210a200d41706a2802002018a7220d4d0d00024002400340200a41086a200a290200370200200c4101460d01200c417f6a210c200a41786a220a280200200d4b0d000c020b0b4100210c0b2000200c4103746a210f0b200f20183702000b200e41016a210e201041086a2110200b2001470d000b0b20044180026a24000be00402097f017e230041306b22022400200241106a2203200141246a290200370300200241086a22042001411c6a29020037030020022001290214370300200241186a41106a2205200141106a280200360200200241186a41086a2206200141086a290200370300200220012902003703182000200241186a10fd0321070240024002400240200041206a28020022082000411c6a280200470d00200841016a22092008490d032008410174220a2009200a20094b1b220941ffffffff03712009470d032009410274220a4100480d030240024020080d00200a102821080c010b20002802182008410274200a102c21080b2008450d01200020083602182000411c6a2009360200200028022021080b200028021820084102746a20073602002000200028022041016a3602202005200329030037030020062004290300370300200220022903003703180240200041f0006a22032802002208200041ec006a280200470d00200841016a22042008490d03200841017422052004200520044b1b2204ad42187e220b422088a70d03200ba722054100480d030240024020080d002005102821080c010b2000280268200841186c2005102c21080b2008450d0220002008360268200041ec006a2004360200200041f0006a28020021080b2000280268200841186c6a22082002290318370200200841106a200241186a41106a290300370200200841086a200241186a41086a29030037020020032003280200220841016a360200024020012d002c450d0020004101360254200041d8006a20083602000b200241306a24000f0b200a41041037000b200541041037000b1031000bb20c01067f0240024020002d00002201410e4b0d00024002400240024002400240024002400240024002400240024020010e0f0001020304050607080e090e0a0b0c000b200041086a280200450d0d200041046a280200102a0f0b0240200041086a280200450d00200041046a280200102a0b200041146a280200450d0c200041106a280200102a0f0b02402000410c6a2802002202450d00200041046a28020021012002410474210203400240200141046a280200450d002001280200102a0b200141106a2101200241706a22020d000b0b200041086a280200450d0b2000280204102a0f0b02402000410c6a2802002202450d00200041046a2802002101200241286c210203400240200141046a280200450d002001280200102a0b0240200141106a280200450d002001410c6a280200102a0b200141286a2101200241586a22020d000b0b200041086a280200450d0a2000280204102a0f0b200041086a280200450d09200041046a280200102a0f0b200041086a280200450d08200041046a280200102a0f0b200041086a280200450d07200041046a280200102a0f0b02402000410c6a2802002201450d00200041046a280200220320014104746a21040340024020032802082202450d0020032802002101200241047421020340024020012d00004109470d000240200141046a2205280200220628020441ffffffff0371450d002006280200102a200528020021060b2006102a0b200141106a2101200241706a22020d000b0b200341106a21010240200341046a280200450d002003280200102a0b2001210320012004470d000b0b200041086a280200450d062000280204102a0f0b02402000410c6a2802002202450d00200041046a2802002101200241146c210203400240200141046a280200450d002001280200102a0b200141146a21012002416c6a22020d000b0b200041086a280200450d052000280204102a0f0b02402000410c6a2802002201450d00200041046a28020022032001411c6c6a21040340024020032802042201450d0002402003410c6a2802002202450d00200241047421020340024020012d00004109470d000240200141046a2205280200220628020441ffffffff0371450d002006280200102a200528020021060b2006102a0b200141106a2101200241706a22020d000b0b200341086a280200450d002003280204102a0b2003411c6a21010240200341146a280200450d002003280210102a0b2001210320012004470d000b0b200041086a280200450d042000280204102a0f0b02402000410c6a2802002201450d00200041046a2802002203200141186c6a210403400240200341046a280200450d002003280200102a0b0240200341146a2802002202450d00200328020c2101200241047421020340024020012d00004109470d000240200141046a2205280200220628020441ffffffff0371450d002006280200102a200528020021060b2006102a0b200141106a2101200241706a22020d000b0b200341186a21010240200341106a280200450d00200328020c102a0b2001210320012004470d000b0b200041086a280200450d032000280204102a0f0b200041046a220110f904200041086a280200450d022001280200102a0f0b0240200041046a2802002201450d00200041086a280200450d002001102a0b0240200041146a2802002201450d0002402000411c6a2802002202450d002002410c6c21020340024020012802002206450d00200141046a280200450d002006102a0b2001410c6a2101200241746a22020d000b0b200041186a280200450d002000280214102a0b200041246a2802002203450d0102402000412c6a2802002201450d00200320014104746a210403402003220541106a2103024020052802042201450d0002402005410c6a2802002202450d002002410c6c21020340024020012802002206450d00200141046a280200450d002006102a0b2001410c6a2101200241746a22020d000b0b200541086a280200450d002005280204102a0b20032004470d000b0b200041286a280200450d012000280224102a0c010b0240200041086a280200450d00200041046a280200102a0b0240200041146a2802002201450d00200041186a280200450d002001102a0b200041246a280200450d00200041206a280200102a0f0b0bff7f05077f017e277f037e0f7f23002203210420034180096b4160712203240002400240024002400240024002400240024002400240411010282205450d00200541063a0000412010282206450d01200641063a001020064100360204200620032f00f0053b00012006412d3a0000200641036a200341f2056a2d00003a0000024020052d00004109470d0002402005280204220728020441ffffffff0371450d002007280200102a200528020421070b2007102a0b2005102a200141106a28020041306c2105200128020841546a210702400340024020050d00411010282207450d0520074180023b010c200742828080802037020420072006360200200720032f01d0033b010e0240200128021022052001410c6a280200470d00200541016a22082005490d0e200541017422092008200920084b1b2208ad42307e220a422088a70d0e200aa722094100480d0e0240024020050d002009102821050c010b2001280208200541306c2009102c21050b2005450d07200120053602082001410c6a2008360200200128021021050b2001280208200541306c6a220520032f00e0043b0001200541073a0000200542818080801037000820052007360004200520032902f005370210200541036a200341e2046a2d00003a0000200541186a200341f8056a290200370200200541206a20034180066a290200370200200541286a200341f0056a41186a2902003702002001200128021041016a220b3602104100210c0c020b200541506a21052007412c6a2108200741306a2209210720082d00004107470d000b200320032f01d0033b01f0050240200941086a22072802002205200941046a280200470d00200541016a22082005490d0c2005410174220d2008200d20084b1b220841ffffffff00712008470d0c2008410474220d4100480d0c0240024020050d00200d102821050c010b20092802002005410474200d102c21050b2005450d0620092005360200200941046a2008360200200941086a28020021050b200928020020054104746a22054180023b010c200542828080802037020420052006360200200520032f01f0053b010e2007200728020041016a360200200341c0006a200910fa032003280244417f6a210c2001280210210b0b200b41306c21052001280208220e41546a210702400340410021082005450d01200541506a21052007412c6a2109200741306a2206210720092d00004103470d000b200641086a2802002205450d00200541286c2107200628020041186a2105410021080340200820052d0000456a2108200541286a2105200741586a22070d000b0b200b41306c2105200e41546a210702400340410021092005450d01200541506a21052007412c6a2106200741306a220d210720062d00004103470d000b200d41086a2802002205450d00200541286c2107200d28020041186a2105410021090340200920052d0000456a2109200541286a2105200741586a22070d000b0b200b41306c2105200e415c6a2107024003404100210f024020050d00410021050c020b200541506a2105200741246a2106200741306a220d210720062d00004104470d000b200d28020021050b200341003602e0040240200520096a220b0d0041042110410021110c080b02402008450d00200342003703f005410021050c060b200341f0056a4100200110d60420032802f405210520032802f0054101470d05200341f8056a290300210a024020032802e0042207450d0020032802e404450d002007102a0b2003200a3702e404200320053602e00441002111410421104100210f0c060b411041081037000b412041081037000b411041041037000b200941041037000b200d41041037000b0240024002400240410410282210450d0020102005360200200b4102490d02024020084102490d00200342003703f0054100210d0c020b200341f0056a4101200110d60420032802f405210d20032802f0054101470d01200341f8056a290300210a024020032802e004450d0020032802e404450d0020032802e004102a0b2003200a3702e4042003200d3602e0040c020b410441041037000b410221064104210741012109410121110340200941016a210502400240024020092011470d0020062005200620054b1b221141ffffffff03712011470d0a2011410274220e4100480d0a20102007200e102c2210450d010b201020076a200d36020002402005200b4f0d000240200820054d0d00200342003703f0054100210d0c030b200341f0056a2005200110d60420032802f405210d20032802f0054101470d0220032903f805210a024020032802e004450d0020032802e404450d0020032802e004102a0b200941016a210f2003200a3702e4042003200d3602e0040c050b200941016a210f0c040b200e41041037000b200641026a2106200741046a2107200521090c000b0b4101210f410121110b20032802e00421050b2005450d0020032902e404210a02402011450d002010102a0b2000200536020420004101360200200041086a200a3702000c010b024020012802102205450d0020012802082212200541306c6a2113200341e0046a41146a2114200341e0076a211520034194066a2116200341a4066a2117200341b4066a2118200341c4066a2119200341d4066a211a200341e4066a211b200341f4066a211c20034184076a211d20034194076a211e200341a4076a211f200341b4076a2120200341c4076a2121200341d4076a212202400240024002400340024020122d0000410c470d00201228020c2205450d0020122802042206200541186c6a212303400240200641146a220e2802002205450d002006410c6a212441002109024002400340200920054f0d014101210502402024280200200941047422256a22072d0000410b470d002003200741046a22073602c00220072802002207200f4f0d03201020074102746a2802002208450d002003200c3602d407200341133a00d007200341d7003a00c007200320083602b4072003412d3a00b0072003200c3602a407200341123a00a00720032007360294072003410b3a009007200341063a008007200341003a00f00620034184083b01e006200341373a00d006200320023602c4062003412d3a00c0062003200c3602b406200341123a00b0062003200c3602a406200341133a00a006200341d6003a00900620032008360284062003412d3a0080062003200c3602f405200341123a00f005200e280200222620094d0d09200e2009360200200628020c2105200320153602f804200320243602f0042003200520256a220b41106a220d3602e8042003200941016a22273602e0042003202620276b22283602e40420032005202741047422296a222a3602ec042003200341f0056a3602f404200d21050240200b2d0000220841ac01460d004100210502400340200b20056a21070240200841ff01714109470d000240200741046a280200220828020441ffffffff0371450d002008280200102a0b2008102a0b2005450d012003200741206a3602e804200541106a2105200741106a2d0000220841ac01470d000b200b20056a41106a21050c010b200741106a21050b02402005202a460d0003402003200541106a22073602e80420052d0000220841ac01460d01024020084109470d000240200541046a280200220528020441ffffffff0371450d002005280200102a0b2005102a0b20072105200d2007470d000b0b02400240024002402028450d000240202720062802142205470d00200341f0056a21052015210b0c030b2025200541047422056b2108200628020c20056a2107200341f0056a21052015210d0340024002402005200d470d00410021050c010b2003200541106a3602f4040b200341d0036a200510d30420032d00d00341ac01460d04200720032903d003370300200741086a200341d0036a41086a2903003703002006200628021441016a3602142008450d02200741106a2107200841706a210820032802f804210d20032802f40421050c000b0b2024201410d7040c020b20032802f804210b20032802f40421050b0240200b20056b2207450d000240024020032802f004220d41046a222a280200222520266b20074104762208490d00200d28020021070c010b202620086a22072026490d12202541017422262007202620074b1b222641ffffffff00712026470d122026410474222b4100480d120240024020250d00202b102821070c010b200d2802002025410474202b102c21070b2007450d0d200d2007360200202a20263602000b2007202720086a22254104746a200720296a2028410474109b051a200320253602e0042025200d2802082207460d00200920086a410474200741047422076b2108200d28020020076a21070340024002402005200b470d00410021050c010b2003200541106a3602f4040b200341d0036a200510d30420032d00d00341ac01460d02200720032903d003370300200741086a200341d0036a41086a290300370300200d200d28020841016a3602082008450d01200741106a2107200841706a210820032802f804210b20032802f40421050c000b0b200341003602d803200342083703d003200341d0036a201410d70420032802d003222820032802d8032207410474220b6a210d20032802d40321292028210502402007450d000240024020032802f004222541046a222a280200220520032802e404222720032802e00422076a22266b200b4104752208490d00202528020021050c010b202620086a222b2026490d1220054101742226202b2026202b4b1b222641ffffffff00712026470d122026410474222b4100480d120240024020050d00202b102821050c010b20252802002005410474202b102c21050b2005450d0e20252005360200202a20263602000b2005200720086a220841047422266a200520074104746a2027410474109b051a200320083602e00420282105200820252802082207460d002025280200220520266a212a200520074104746a21082028210703400240200b0d00200d21050c020b200341d0036a41026a2205200741036a2d00003a0000200320072f00013b01d003024020072d0000222741ac01470d00200741106a21050c020b200741046a2802002126200741086a290300210a200820273a0000200841086a200a370300200841046a202636020020032f01d0032127200841036a20052d00003a0000200841016a20273b00002025202528020841016a360208200b41706a210b200741106a22052107200841106a2208202a470d000b0b02402005200d460d0003400240024020052d000022074109460d00200741ac01470d010c030b0240200541046a280200220728020441ffffffff0371450d002007280200102a0b2007102a0b200541106a2205200d470d000b0b2029450d002028102a0b024020032802e804220520032802ec04220d460d0003402003200541106a22073602e80420052d0000220841ac01460d01024020084109470d000240200541046a280200220528020441ffffffff0371450d002005280200102a0b2005102a0b20072105200d2007470d000b0b024020032802e4042205450d00024020032802e004220d20032802f004220b41086a22082802002207460d00200b280200220b20074104746a200b200d4104746a2005410474109b051a0b2008200520076a3602000b024020032d00f0054109470d00024020032802f405220528020441ffffffff0371450d002005280200102a20032802f40521050b2005102a0b024020032d0080064109470d000240200341f0056a41146a280200220528020441ffffffff0371450d002005280200102a20032802840621050b2005102a0b024020032d0090064109470d0002402016280200220528020441ffffffff0371450d002005280200102a20032802940621050b2005102a0b024020032d00a0064109470d0002402017280200220528020441ffffffff0371450d002005280200102a20032802a40621050b2005102a0b024020032d00b0064109470d0002402018280200220528020441ffffffff0371450d002005280200102a20032802b40621050b2005102a0b024020032d00c0064109470d0002402019280200220528020441ffffffff0371450d002005280200102a20032802c40621050b2005102a0b024020032d00d0064109470d000240201a280200220528020441ffffffff0371450d002005280200102a20032802d40621050b2005102a0b024020032d00e0064109470d000240201b280200220528020441ffffffff0371450d002005280200102a20032802e40621050b2005102a0b024020032d00f0064109470d000240201c280200220528020441ffffffff0371450d002005280200102a20032802f40621050b2005102a0b024020032d0080074109470d000240201d280200220528020441ffffffff0371450d002005280200102a20032802840721050b2005102a0b024020032d0090074109470d000240201e280200220528020441ffffffff0371450d002005280200102a20032802940721050b2005102a0b024020032d00a0074109470d000240201f280200220528020441ffffffff0371450d002005280200102a20032802a40721050b2005102a0b024020032d00b0074109470d0002402020280200220528020441ffffffff0371450d002005280200102a20032802b40721050b2005102a0b024020032d00c0074109470d0002402021280200220528020441ffffffff0371450d002005280200102a20032802c40721050b2005102a0b024020032d00d0074109470d0002402022280200220528020441ffffffff0371450d002005280200102a20032802d40721050b2005102a0b410f21050b200520096a2209200e2802002205490d000c030b0b41ace4c500200920051034000b2003410136028406200342013702f405200341bce4c5003602f0052003412c3602d4032003200341d0036a360280062003200341c0026a3602d003200341e0046a200341f0056a103320032802e00422050d040b200641186a22062023470d000b0b201241306a22122013470d000c050b0b20032902e404210a2000200536020420004101360200200041086a200a3702002011450d042010102a0c040b41e4e8c5001032000b202b41081037000b202b41081037000b200341c8006a41106a200141106a2802002220360200200341c8006a41086a200141086a290200220a37030020032001290200370348202041306c2105200aa7221241546a210702400340024020050d00410021080c020b200541506a21052007412c6a2108200741306a2209210720082d00004108470d000b200341386a200910fa0320032802382108200328023c21050b2005410020081b210d202041306c2105201241546a21072008410420081b210802400340024020050d00410021090c020b200541506a21052007412c6a2109200741306a2206210720092d0000410a470d000b200341306a200610fa0320032802302109200328023421050b2005410020091b210b202041306c2105201241546a21072009410420091b211702400340024020050d004100211c0c020b200541506a21052007412c6a2109200741306a2206210720092d00004109470d000b200628020021074101211c0b20034200370274200341f8b9c0003602702017200b411c6c6a211f2008200d41146c6a210d200341e0046a410272221b41266a2121201b41186a2122201b41086a212b4104211641002124410021264100211e4100211d410021140240024002400240410041ff01710e03000102000b410021050c020b410221050c010b410121050b03400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024020050e03000104040b0240201441ff01710e03020300020b201e4101470d04410021050c0b0b201c450d0f4100211c410221284100212a200721050c1d0b034002400240024002400240200d200822056b413c4b0d002005200d470d01200521080c020b200528020c0d03200541146a2108200541106a28020021050c1f0b200541106a21090340200528020c450d02200941146a2109200541146a2205200d470d000b200d21080b201e4101470d07410021050c0a0b200941046a2108200928020021050c1c0b200541206a280200450d1a200541346a280200450d19200541d0006a2108200541c8006a280200450d180c000b0b0340024002400240200d200822056b413c4b0d00410121142005200d470d01200521080c2b0b200528020c0d01200541146a2108200541106a28020021050c180b200541106a210902400340200528020c450d01200941146a2109200541146a2205200d470d000b200d21080c2a0b200941046a2108200928020021050c170b200541206a280200450d15200541346a280200450d14200541d0006a2108200541c8006a280200450d130c000b0b024002400240201441ff01710e03010200010b201e4101470d03410021050c080b034002400240024002400240200d200822056b413c4b0d002005200d470d01200521080c020b200528020c0d03200541146a2108200541106a28020021050c160b200541106a21090340200528020c450d02200941146a2109200541146a2205200d470d000b200d21080b201e4101470d07410021050c080b200941046a2108200928020021050c130b200541206a280200450d11200541346a280200450d10200541d0006a2108200541c8006a280200450d0f0c000b0b0340024002400240200d200822056b413c4b0d002005200d460d10200541106a21090340200528020c450d02200941146a2109200541146a2205200d470d000c110b0b200528020c0d01200541146a2108200541106a28020021050c0e0b200941046a2108200928020021050c0d0b200541206a280200450d0b200541346a280200450d0a200541d0006a2108200541c8006a280200450d090c000b0b410121050c060b410121050c040b410121050c020b410121050b0340024002400240024020050e020001010b2029201d470d01410121050c030b2017201f460d0a200341206a201710cd0420032802202229450d0a2017411c6a2117202920032802244102746a211d0c010b2029450d09202928020021054101211e41022114202941046a2129410121280c160b410021050c000b0b0340024002400240024020050e020001010b2029201d470d014101211e2029211d410121050c030b410221142017201f460d22200341106a201710cd042017411c6a211720032802102205450d23200520032802144102746a211d200521290c010b202941046a2109024020290d00410221144101211e200921290c230b2029280200210541002128410221144101211e200921290c150b410021050c000b0b0340024002400240024020050e020001010b2029201d470d01410121050c030b2017201f460d08200341286a201710cd0420032802282229450d082017411c6a21172029200328022c4102746a211d0c010b2029450d07202928020021054101211e41022114202941046a2129410121280c140b410021050c000b0b0340024002400240024020050e020001010b2029201d470d014101211e2029211d410121050c030b410221142017201f460d20200341186a201710cd042017411c6a211720032802182205450d212005200328021c4102746a211d200521290c010b202941046a2109024020290d00410221144101211e200921290c210b2029280200210541002128410221144101211e200921290c130b410021050c000b0b200541cc006a28020021050c020b2005413c6a2108200541386a28020021050c010b200541286a2108200541246a28020021050b41012114410121280c0d0b200341e0006a41086a200341f0006a41086a280200360200200320032903703703602003280258220d41306c21052003280250220b41546a210702400340410021082005450d01200541506a21052007412c6a2109200741306a2206210720092d00004103470d000b200641086a2802002205450d00200541286c2107200628020041186a2105410021080340200820052d0000456a2108200541286a2105200741586a22070d000b0b200d41306c2105200b415c6a210702400340024020050d00410021050c020b200541506a2105200741246a2109200741306a2206210720092d00004104470d000b200628020021050b200341f0056a41106a2228200341c8006a41106a280200360200200341f0056a41086a200341c8006a41086a290300370300200320032903483703f005200341b0016a200341f0056a10fc0302402026450d00201620264102746a212a200520086a2125200341f0056a41e0016a210f200341f0056a41d0016a2115200341f0056a41c0016a2129200341f0056a41b0016a2114200341f0056a41a0016a2117200341f0056a4190016a2118200341f0056a4180016a2119200341f0056a41f0006a211a200341f0056a41e0006a211b200341f0056a41d0006a211c200341f0056a41c0006a211d200341f0056a41306a211e200341f0056a41206a211f200341e7046a212020034184066a212120034194066a2122200341b4066a212b200341c4066a2123200341d4066a2112200341e4066a2101200341f4066a211320034184076a212c20034194076a212d200341a4076a212e200341b4076a212f200341c4076a2130200341d4076a21312016212703402027220541046a212720052802002106200341e0006a21052003280264210b03402005280200220d41086a2107200d2f0106220e4102742105417f210802400340024020050d00200e21080c020b20072802002109200841016a21082005417c6a2105200741046a21070240417f2009200647200920064b1b41016a0e03020001020b0b200d41346a20084105746a220e2802182107200e28021c21052003200c3602d407200341133a00d007200341d7003a00c007200320053602b4072003412d3a00b0072003200c3602a407200341123a00a00720032007360294072003410b3a009007200341063a008007200341003a00f00620034184083b01e006200341373a00d006200320023602c4062003412d3a00c0062003200c3602b406200341123a00b0062003200c3602a406200341133a00a006200341d6003a00900620032005360284062003412d3a0080062003200c3602f405200341123a00f005200e280208220d41106a220541ffffffff00712005470d1220054104742207417f4c0d12200e41086a21260240024002400240024020070d00410821060c010b200710282206450d012026280200210d0b0240200d0d00410021080c030b41002109410021070340024020072005470d00200541016a22082005490d262005410174220b2008200b20084b1b220841ffffffff00712008470d262008410474220b4100480d260240024020050d00200b102821060c010b20062005410474200b102c21060b2006450d03200821050b200620096a2208410f3a0000200841046a2007360200200841016a20032f01d0033b0000200841036a200341d0036a41026a2d00003a0000200941106a2109200741016a22082107200d2008460d030c000b0b200741081037000b200b41081037000b02400240024002400240024002400240200520086b410e4d0d00200521090c010b2008410f6a22072008490d28200541017422092007200920074b1b220941ffffffff00712009470d28200941047422074100480d280240024020050d002007102821060c010b200620054104742007102c21060b2006450d010b200341e0046a200341f0056a10d904200620084104746a220520032903e004370300200541086a200341e0046a41086a2207290300370300200341e0046a202810d904200541186a2007290300370300200520032903e004370310200341e0046a201f10d904200541286a2007290300370300200541206a20032903e004370300200341e0046a201e10d904200541386a2007290300370300200541306a20032903e004370300200341e0046a201d10d904200541c8006a2007290300370300200541c0006a20032903e004370300200341e0046a201c10d904200541d8006a2007290300370300200541d0006a20032903e004370300200341e0046a201b10d904200541e8006a2007290300370300200541e0006a20032903e004370300200341e0046a201a10d904200541f8006a2007290300370300200541f0006a20032903e004370300200341e0046a201910d90420054188016a200729030037030020054180016a20032903e004370300200341e0046a201810d90420054198016a200729030037030020054190016a20032903e004370300200341e0046a201710d904200541a8016a2007290300370300200541a0016a20032903e004370300200341e0046a201410d904200541b8016a2007290300370300200541b0016a20032903e004370300200341e0046a202910d904200541c8016a2007290300370300200541c0016a20032903e004370300200341e0046a201510d904200541d8016a2007290300370300200541d0016a20032903e004370300200341e0046a200f10d904200541e8016a2007290300370300200541e0016a20032903e004370300024002402008410f6a22052009460d002009210d200521090c010b200941016a22052009490d28200941017422072005200720054b1b220d41ffffffff0071200d470d28200d41047422054100480d280240024020090d002005102821060c010b200620094104742005102c21060b2006450d020b200620094104746a220541063a0000200520032900e004370001200541086a2020290000370000200341e0046a200341b0016a418c01109a051a411010282207450d02200741063a0000200341d0036a200341e0046a418c01109a051a20262802002205417f4c0d18200e28020021090240024020050d004101210b410120092005109a05220920092005109a051a2005ad2132410021050c010b20051028220b450d04200b20092005109a05210920051028220b450d05200b20092005109a051a2009102a2005ad21320b200341e0046a200341d0036a418c01109a051a200e31000d2133200341d0036a200341e0046a418c01109a051a200341e0046a200341d0036a418c01109a051a200341c0026a200341e0046a418c01109a051a411010282209450d05200841106a2108200a428080808080804083220a2032842033422886844280808080800c842132200941063a00002009102a200341d0036a200341c0026a418c01109a051a200341e0046a200341d0036a418c01109a051a024020072d00004109470d0002402007280204220928020441ffffffff0371450d002009280200102a200728020421090b2009102a0b2007102a200341c0026a200341e0046a418c01109a051a200341e0046a200341c0026a418c01109a051a200341003602fc03200320083602f8032003200d3602f403200320063602f003200341003602ec03200342043702e403200320323702dc03200320053602d8032003200b3602d403200341013602d003200341e0046a200341d0036a108104200341b0016a200341e0046a418c01109a051a200e4101360210200e2025360214024020032d00f0054109470d00024020032802f405220528020441ffffffff0371450d002005280200102a20032802f40521050b2005102a0b024020032d0080064109470d0002402021280200220528020441ffffffff0371450d002005280200102a20032802840621050b2005102a0b024020032d0090064109470d0002402022280200220528020441ffffffff0371450d002005280200102a20032802940621050b2005102a0b024020032d00a0064109470d000240200341f0056a41346a280200220528020441ffffffff0371450d002005280200102a20032802a40621050b2005102a0b024020032d00b0064109470d000240202b280200220528020441ffffffff0371450d002005280200102a20032802b40621050b2005102a0b024020032d00c0064109470d0002402023280200220528020441ffffffff0371450d002005280200102a20032802c40621050b2005102a0b024020032d00d0064109470d0002402012280200220528020441ffffffff0371450d002005280200102a20032802d40621050b2005102a0b024020032d00e0064109470d0002402001280200220528020441ffffffff0371450d002005280200102a20032802e40621050b2005102a0b024020032d00f0064109470d0002402013280200220528020441ffffffff0371450d002005280200102a20032802f40621050b2005102a0b024020032d0080074109470d000240202c280200220528020441ffffffff0371450d002005280200102a20032802840721050b2005102a0b024020032d0090074109470d000240202d280200220528020441ffffffff0371450d002005280200102a20032802940721050b2005102a0b024020032d00a0074109470d000240202e280200220528020441ffffffff0371450d002005280200102a20032802a40721050b2005102a0b024020032d00b0074109470d000240202f280200220528020441ffffffff0371450d002005280200102a20032802b40721050b2005102a0b024020032d00c0074109470d0002402030280200220528020441ffffffff0371450d002005280200102a20032802c40721050b2005102a0b024020032d00d0074109470d0002402031280200220528020441ffffffff0371450d002005280200102a20032802d40721050b2005102a0b200a4280808080808c0184210a202541016a21252027202a470d080c090b200741081037000b200541081037000b411041081037000b200541011037000b200541011037000b411041081037000b0240200b450d00200b417f6a210b200d20084102746a4194036a21050c010b0b0b4198ebc5004180011050000b02402024450d002016102a0b200341f0056a200341b0016a418c01109a051a200341e0046a200341f0056a10fe030240200341e0046a41106a2802002205450d0020032802e8042228200541306c6a212a0340024020282d000041786a220541024b0d0002400240024020050e03000102000b202828020c2205450d0220282802042208200541146c6a210c03400240200828020c0d002008280210210d200341e0006a21052003280264210e03402005280200220b41086a2107200b2f010622244102742105417f210902400340024020050d00202421090c020b20072802002106200941016a21092005417c6a2105200741046a21070240417f2006200d472006200d4b1b41016a0e03020001020b0b0240200b41346a20094105746a2205280210450d00200820052802143602100c030b4198ecc50041351050000b200e450d01200e417f6a210e200b20094102746a4194036a21050c000b0b200841146a2208200c470d000c030b0b20282802042106200341e0006a21052003280264210b03402005280200220d41086a2107200d2f0106220e4102742105417f210802400340024020050d00200e21080c020b20072802002109200841016a21082005417c6a2105200741046a21070240417f2009200647200920064b1b41016a0e03020001020b0b0240200d41346a20084105746a2205280210450d00202820052802143602040c040b4198ecc50041351050000b200b450d02200b417f6a210b200d20084102746a4194036a21050c000b0b202828020c2205450d00202828020422272005411c6c6a21260340024020272802182205450d002027280210220e20054102746a21250340200e220c41046a210e200c2802002106200341e0006a21052003280264210b03402005280200220d41086a2107200d2f010622244102742105417f2108024002400340024020050d00202421080c020b20072802002109200841016a21082005417c6a2105200741046a21070240417f2009200647200920064b1b41016a0e03020001020b0b0240200d41346a20084105746a2205280210450d00200c20052802143602000c020b4198ecc50041351050000b200b450d00200b417f6a210b200d20084102746a4194036a21050c010b0b200e2025470d000b0b2027411c6a22272026470d000b0b202841306a2228202a470d000b0b200341ec046a290200210a20032802e004210520032902e404213220032802602003280264200328026810da04200041106a200a370200200041086a203237020020002005360204200041003602002011450d1c2010102a200424000f0b200541cc006a28020021050c020b2005413c6a2108200541386a28020021050c010b200541286a2108200541246a28020021050b41012128410021140c080b200541cc006a28020021050c020b2005413c6a2108200541386a28020021050c010b200541286a2108200541246a28020021050b41002128410121140c040b200541cc006a28020021050c020b2005413c6a2108200541386a28020021050c010b200541286a2108200541246a28020021050b41002114410021280b2007212a0b2003200536027c02402005200f490d002003410136028406200342023702f40520034188ebc5003602f005200341013602d4032003200341d0036a360280062003200341fc006a3602d003200341e0046a200341f0056a103320032902e404220a422088a7210820032802e0042125200aa7211a0c0a0b201020054102746a2802002207450d050240024020262024460d0020242115202621240c010b202441016a22092024490d10202441017422062009200620094b1b221541ffffffff03712015470d10201541027422094100480d100240024020240d002009102821160c010b201620244102742009102c21160b2016450d020b201620244102746a2005360200200341f0056a200328027c220b200341c8006a10db0420032802f805211a20032802f4052125024020032802f00522194101470d0020032802fc052108201521240c0a0b20252802082205417f4c0d002025280200210920252d000c210602400240024020050d004100210e410121240c010b2005210e200510282224450d010b202420092005109a05210920032005360288012003200e360284012003200936028001200320063a008c01200320252d000d3a008d0120034100360290012003200328027c360298012003200736029c010240024002402003280270220741f8b9c000460d00200328027421270c010b20214200370100201b41206a420037010020224200370100201b41106a4200370100202b4200370100201b4200370100200341f0056a410041e0021099051a41940310282207450d014100212720074100360200200720032903e0043702042007410c6a200341e0046a41086a290300370200200741146a200341e0046a41106a2903003702002007411c6a200341e0046a41186a290300370200200741246a200341e0046a41206a2903003702002007412c6a200341e0046a41286a290300370200200741346a200341f0056a41e002109a051a20034100360274200320073602700b202641016a2126034020072f0106221841027421244100210541142106417f210902400340024020242005470d00201821090c020b200720056a210e200941016a2109200641206a2106200541046a21050240417f200e41086a280200220e200b47200e200b4b1b41016a0e03020001020b0b200720066a2205290200210a2005200329038001370200200541186a200329039801370200200541106a220729020021322007200329039001370200200541086a200329038801370200203242ffffffff0f83420285500d08200a42808080807083500d08200aa7102a0c080b02402027450d002027417f6a2127200720094102746a4194036a28020021070c010b0b2003200328027841016a360278200329039801210a20032903900121322003290388012133200329038001213420072f01062206410b490d0420214200370100201b41206a2235420037010020224200370100201b41106a22364200370100202b4200370100201b4200370100200341f0056a410041e0021099051a024041940310282205450d0020054100360200200520032903e0043702042005410c6a200341e0046a41086a222c290300370200200541146a200341e0046a41106a222d2903003702002005411c6a200341e0046a41186a222e290300370200200541246a200341e0046a41206a22372903003702002005412c6a200341e0046a41286a2238290300370200200541346a200341f0056a41e002109a05210e200341f0056a41086a2227200741fc016a290200370300200341f0056a41106a221820074184026a290200370300200341f0056a41186a22232007418c026a290200370300200320072902f4013703f00520072802202139200541086a200741246a20072f010641796a2206410274109a052124200e20074194026a2006410574109a05210e200741063b0106200520063b0106202e2023290300370300202d2018290300370300202c2027290300370300200320032903f0053703e0040240024020094107490d0020242009417a6a22134102746a2024200941796a22014102746a2209200641ffff037120016b410274109b051a2009200b360200200e20134105746a200e20014105746a2209200541066a22062f010020016b410574109b051a200941186a200a37020020092032370210200920333702082009203437020020062f0100210e0c010b200741086a2206200941016a22244102746a200620094102746a2201200741066a22062f0100220e20096b2213410274109b051a2001200b360200200741346a220b20244105746a200b20094105746a22092013410574109b051a200941186a200a3702002009203237021020092033370208200920343702000b2006200e41016a3b0100200341d0036a41186a222f202e290300220a370300200341d0036a41106a2230202d2903002232370300200341d0036a41086a2231202c2903002233370300200341b0016a41186a223a200a370300200341b0016a41106a223b2032370300200341b0016a41086a223c2033370300200320032903e004220a3703d0032003200a3703b00102402007280200220e0d00200521090c070b20072f010421012005213d0340200341c0026a41186a223e203a290300370300200341c0026a41106a223f203b290300370300200341c0026a41086a2240203c290300370300200320032903b0013703c002200141ffff0371210b02400240024002400240200e2f01062205410b490d0020214200370100203542003701002022420037010020364200370100202b4200370100201b42003701002031202c2903003703002030202d290300370300202f202e290300370300200341d0036a41206a22052037290300370300200341d0036a41286a22072038290300370300200320032903e0043703d003200341f0056a41004190031099051a41c40310282209450d0320094100360200200920032903d0033702042009410c6a2031290300370200200941146a20302903003702002009411c6a202f290300370200200941246a20052903003702002009412c6a2007290300370200200941346a200341f0056a419003109a052107200e41206a28020021412023200e418c026a2902003703002018200e4184026a2902003703002027200e41fc016a2902003703002003200e41f4016a2902003703f005200941086a200e41246a200e2f0106220641796a2205410274109a0521422007200e4194026a2005410574109a05214320094194036a200e41b0036a2006417a6a2224410274109a052113200e41063b0106200920053b010602402024450d00410021052013210703402007280200220620053b010420062009360200200741046a21072024200541016a2205470d000b0b202e2023290300220a370300202d20182903002232370300202c20272903002233370300200320032903f00522343703e0042023200a3703002018203237030020272033370300200320343703f005200141ffff037122074107490d012042200b417a6a220641027422246a2042200b41796a22054102746a220720092f010620056b410274109b051a20072039360200204320064105746a204320054105746a220720092f010620056b410574109b051a200741186a203e290300370200200741106a203f290300370200200741086a2040290300370200200720032903c002370200200920092f010641016a22073b0106200b410274220120136a416c6a201320246a2224200741ffff0371220b20066b410274109b051a2024203d360200200b2006490d02200920016a41fc026a2107034020072802002206200541016a22053b010420062009360200200741046a21072005200b490d000c030b0b200e41086a2207200b41016a220941027422066a2007200b41027422246a22072005200b6b2227410274109b051a20072039360200200e41346a220720094105746a2007200b4105746a22072027410574109b051a200741186a203e290300370200200741106a203f290300370200200741086a2040290300370200200720032903c002370200200e200541016a22053b01062024200e4194036a22076a41086a200720066a2207200541ffff0371220620096b410274109b051a2007203d360200200b20064f0d0c200e2009417f6a22054102746a4198036a2107034020072802002209200541016a22053b01042009200e360200200741046a210720052006490d000c0d0b0b200e41086a2205200b41016a222441027422066a2005200b41027422016a2205200e2f01062213200b6b2242410274109b051a20052039360200200e41346a220520244105746a2005200b4105746a22052042410574109b051a200541186a203e290300370200200541106a203f290300370200200541086a2040290300370200200520032903c002370200200e201341016a22053b01062001200e4194036a22136a41086a201320066a2213200541ffff0371220620246b410274109b051a2013203d360200200720064f0d00200e20016a4198036a2105034020052802002207200b41016a220b3b01042007200e360200200541046a21052006200b470d000b0b203a2023290300370300203b2018290300370300203c2027290300370300200320032903f0053703b001200e28020022050d01204121390c090b41c40341041037000b200e2f010421012005210e204121392009213d0c000b0b41940341041037000b41940341041037000b200541011037000b1036000b200941041037000b200741086a2205200941016a220e4102746a200520094102746a2205200620096b2224410274109b051a2005200b360200200741346a2205200e4105746a200520094105746a22052024410574109b051a200541186a200a3702002005203237021020052033370208200520343702002007200641016a3b01060c010b20214200370100203542003701002022420037010020364200370100202b4200370100201b42003701002031202c2903003703002030202d290300370300202f202e290300370300200341d0036a41206a22072037290300370300200341d0036a41286a22062038290300370300200320032903e0043703d003200341f0056a41004190031099051a41c40310282205450d0220054100360200200520032903d0033702042005410c6a2031290300370200200541146a20302903003702002005411c6a202f290300370200200541246a20072903003702002005412c6a2006290300370200200541346a200341f0056a419003109a05210b20052003280270220736029403200320053602702003200328027441016a36027420072005360200200741003b0104200b20052f010622064105746a220720032903b001370200200741186a203a290300370200200741106a203b290300370200200741086a203c290300370200200520064102746a41086a203936020020054194036a200641016a22074102746a2009360200200520073b0106200920073b0104200920053602000b02402019450d00201a450d002025102a0b201521240b202a2107202841ff01710e03010205010b41c40341041037000b410021050c040b410221050c030b20032802702003280274200328027810da0402402024450d002016102a0b02402020450d00202041306c2107201221050340200510dc04200541306a2105200741506a22070d000b0b0240200341d4006a280200450d002012102a0b2000202536020420004101360200200041086a2008ad422086201aad843702002011450d042010102a200424000f0b201f21170b410121050c000b0b024020012802102205450d0020012802082103200541306c21050340200310dc04200341306a2103200541506a22050d000b0b2001410c6a280200450d002001280208102a0b200424000f0b1031000bfc8c0204117f017e0b7f017e230041e0006b22032400024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024020012d00000e100100021817161514130d0b0c09080706010b200141186a2802002104200141146a2802002105200141106a28020021062001410c6a2802002107200141086a2802002108200141046a28020021090240200241046a280200200241086a280200220a460d002002280200210b0c1e0b200a41016a220b200a490d1a200a410174220c200b200c200b4b1b220c4100480d1a02400240200a0d00200c1028210b0c010b2002280200200a200c102c210b0b200b450d042002200b360200200241046a200c360200200241086a280200210a0c1d0b2001410c6a280200210b200141086a2802002105200141046a280200210420012d0001210d02400240200241046a280200200241086a280200220a460d002002280200210c0c010b200a41016a220c200a490d1a200a4101742206200c2006200c4b1b22064100480d1a02400240200a0d0020061028210c0c010b2002280200200a2006102c210c0b200c450d032002200c360200200241046a2006360200200241086a280200210a0b200241086a2206200a41016a360200200c200a6a200d3a000002400240200241046a280200220c2006280200220a6b200b490d002002280200210c0c010b200a200b6a220d200a490d1a200c410174220a200d200a200d4b1b220a4100480d1a02400240200c0d00200a1028210c0c010b2002280200200c200a102c210c0b200c450d022002200c360200200241046a200a360200200241086a280200210a0b200241086a200a200b6a360200200c200a6a2004200b109a051a4100210b4101210d024020050d004101210c0c270b2004102a4101210c0c260b2001410c6a2802002106200141086a280200210e200141046a280200210f024002400240200241046a280200200241086a280200220a460d002002280200210b0c010b200a41016a220b200a490d1a200a410174220c200b200c200b4b1b220c4100480d1a02400240200a0d00200c1028210b0c010b2002280200200a200c102c210b0b200b450d012002200b360200200241046a200c360200200241086a280200210a0b200241086a200a41016a360200200b200a6a41013a0000200f20064104746a21104100210c4100210b41002105410121042006210a024003400240200b2005470d00200c200b41016a220d200c200d4b1b22054100480d1c02400240200c0d002005102821040c010b2004200b2005102c21040b2004450d020b2004200b6a200a41807f72200a41ff0071200a410776220d1b3a0000200c41026a210c200b41016a210b200d210a200d0d000b024020060d00200f21080c190b200f210a02400340200a41106a2108200a2d000d22114105460d1a200a2d000c210c200a2802082109200a2802042112200a28020021130240024002400240024002402005200b470d00200b41016a220a200b490d22200b410174220d200a200d200a4b1b22054100480d2202400240200b0d002005102821040c010b2004200b2005102c21040b2004450d010b2004200b6a200c3a0000200b41016a210a200b410174220b41046a2107200b41026a210c2009210b0340200721060240200a2005470d00200a41016a220d200a490d23200c200d200c200d4b1b22054100480d2302400240200a0d002005102821040c010b2004200a2005102c21040b2004450d030b2004200a6a200b41807f72200b41ff0071200b410776220d1b3a0000200641026a2107200c41026a210c200a41016a210a200d210b200d0d000b0240024020090d00200a210b0c010b4100210c0340200a200c6a210b41fc00210d02400240024002402013200c6a2d00000e050200010305020b41fe00210d0c020b41fd00210d0c010b41ff00210d0b0240200b2005470d00200b41016a2205200b490d2420062005200620054b1b22054100480d2402400240200b0d002005102821040c010b2004200b2005102c21040b2004450d050b2004200a6a200c6a200d3a0000200641026a21062009200c41016a220c470d000b200a200c6a210b0b20120d030c040b200541011037000b200541011037000b200541011037000b2013102a0b4100210a0240024020114104460d0002402005200b470d00200b41016a220a200b490d1f200b410174220c200a200c200a4b1b22054100480d1f02400240200b0d002005102821040c010b2004200b2005102c21040b2004450d020b2004200b6a41013a0000200b41016a210b201141077141ff0073210a0b02402005200b470d00200b41016a220c200b490d1e200b410174220d200c200d200c4b1b22054100480d1e02400240200b0d002005102821040c010b2004200b2005102c21040b2004450d030b2004200b6a200a3a0000200b41016a210b2008210a20082010470d010c1c0b0b200541011037000b200541011037000b200541011037000b200c41011037000b200a41011037000b200641011037000b200c41011037000b200141286a2802002113200141246a280200210f200141206a28020021082001411c6a2802002107200141186a2802002112200141146a28020021092001410c6a2902002114200141086a2802002110200141046a28020021110240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240200241046a280200200241086a280200220a460d002002280200210b0c010b200a41016a220b200a490d27200a410174220c200b200c200b4b1b220c4100480d2702400240200a0d00200c1028210b0c010b2002280200200a200c102c210b0b200b450d012002200b360200200241046a200c360200200241086a280200210a0b200241086a200a41016a360200200b200a6a41003a0000200341dc006a410036020020034201370254200320023602502014422088a7210d4100210a4100210b2014a72206210c034002400240200a200b460d002003280254210a0c010b200a41016a2204200a490d28200a41017422052004200520044b1b22044100480d2802400240200a0d0020041028210a0c010b2003280254200a2004102c210a0b200a450d03200320043602582003200a3602540b2003200b41016a36025c200a200b6a200c41807f72200c41ff0071200c41077622041b3a00002003280258210a200328025c210b2004210c20040d000b02400240200a200b6b2006490d00200328025421040c010b200b20066a220c200b490d27200a4101742204200c2004200c4b1b220c4100480d2702400240200a0d00200c102821040c010b2003280254200a200c102c21040b2004450d032003200c36025820032004360254200c210a0b2003200b20066a220c36025c2004200b6a20112006109a051a02402010450d002011102a0b034002400240200a200c460d002003280254210a0c010b200a41016a220b200a490d28200a4101742204200b2004200b4b1b220b4100480d2802400240200a0d00200b1028210a0c010b2003280254200a200b102c210a0b200a450d052003200b3602582003200a3602540b2003200c41016a36025c200a200c6a200d41807f72200d41ff0071200d410776220b1b3a00000240200b450d002003280258210a200328025c210c200b210d0c010b0b4101211102402009450d002007210b0340024002402003280258200328025c220a460d002003280254210c0c010b200a41016a220c200a490d29200a410174220d200c200d200c4b1b220d4100480d2902400240200a0d00200d1028210c0c010b2003280254200a200d102c210c0b200c450d072003200d3602582003200c3602540b2003200a41016a36025c200c200a6a200b41807f72200b41ff0071200b410776220a1b3a0000200a210b200a0d000b024002402003280258220b200328025c220a6b2007490d002003280254210b0c010b200a20076a220c200a490d28200b410174220d200c200d200c4b1b220c4100480d2802400240200b0d00200c1028210b0c010b2003280254200b200c102c210b0b200b450d072003200c3602582003200b3602540b2003200a20076a36025c200b200a6a20092007109a051a410021112012450d002009102a0b200820134104746a21062013210b0340024002402003280258200328025c220a460d002003280254210c0c010b200a41016a220c200a490d28200a410174220d200c200d200c4b1b220d4100480d2802400240200a0d00200d1028210c0c010b2003280254200a200d102c210c0b200c450d082003200d3602582003200c3602540b2003200a41016a36025c200c200a6a200b41807f72200b41ff0071200b410776220a1b3a0000200a210b200a0d000b2008210402402013450d00411021072008210403402004220b41106a2104200b280200220c4108460d01200b410c6a2802002102200b41086a280200210a200b280204210b024002400240024002400240024002400240200c0e080001020304050607000b024002402003280258200328025c220c460d002003280254210d0c010b200c41016a220d200c490d31200c4101742205200d2005200d4b1b22054100480d3102400240200c0d0020051028210d0c010b2003280254200c2005102c210d0b200d450d12200320053602582003200d360254200328025c210c0b2003200c41016a36025c200d200c6a41003a00000340024002402003280258200328025c220c460d002003280254210d0c010b200c41016a220d200c490d32200c4101742205200d2005200d4b1b22054100480d3202400240200c0d0020051028210d0c010b2003280254200c2005102c210d0b200d450d14200320053602582003200d360254200328025c210c0b2003200c41016a36025c200d200c6a200b41807f72200b41ff0071200b410776220c1b3a0000200c210b200c0d000b0340024002402003280258200328025c220b460d002003280254210c0c010b200b41016a220c200b490d32200b410174220d200c200d200c4b1b220d4100480d3202400240200b0d00200d1028210c0c010b2003280254200b200d102c210c0b200c450d152003200d3602582003200c360254200328025c210b0b2003200b41016a36025c200c200b6a200a41807f72200a41ff0071200a410776220b1b3a0000200b210a200b0d000c080b0b024002402003280258200328025c220c460d002003280254210d0c010b200c41016a220d200c490d30200c4101742205200d2005200d4b1b22054100480d3002400240200c0d0020051028210d0c010b2003280254200c2005102c210d0b200d450d14200320053602582003200d360254200328025c210c0b2003200c41016a36025c200d200c6a41013a00000340024002402003280258200328025c220c460d002003280254210d0c010b200c41016a220d200c490d31200c4101742205200d2005200d4b1b22054100480d3102400240200c0d0020051028210d0c010b2003280254200c2005102c210d0b200d450d16200320053602582003200d360254200328025c210c0b2003200c41016a36025c200d200c6a200b41807f72200b41ff0071200b410776220c1b3a0000200c210b200c0d000b0340024002402003280258200328025c220b460d002003280254210c0c010b200b41016a220c200b490d31200b410174220d200c200d200c4b1b220d4100480d3102400240200b0d00200d1028210c0c010b2003280254200b200d102c210c0b200c450d172003200d3602582003200c360254200328025c210b0b2003200b41016a36025c200c200b6a200a41807f72200a41ff0071200a410776220b1b3a0000200b210a200b0d000c070b0b024002402003280258200328025c220c460d002003280254210d0c010b200c41016a220d200c490d2f200c4101742205200d2005200d4b1b22054100480d2f02400240200c0d0020051028210d0c010b2003280254200c2005102c210d0b200d450d16200320053602582003200d360254200328025c210c0b2003200c41016a36025c200d200c6a41023a00000340024002402003280258200328025c220c460d002003280254210d0c010b200c41016a220d200c490d30200c4101742205200d2005200d4b1b22054100480d3002400240200c0d0020051028210d0c010b2003280254200c2005102c210d0b200d450d18200320053602582003200d360254200328025c210c0b2003200c41016a36025c200d200c6a200b41807f72200b41ff0071200b410776220c1b3a0000200c210b200c0d000b0340024002402003280258200328025c220b460d002003280254210c0c010b200b41016a220c200b490d30200b410174220d200c200d200c4b1b220d4100480d3002400240200b0d00200d1028210c0c010b2003280254200b200d102c210c0b200c450d192003200d3602582003200c360254200328025c210b0b2003200b41016a36025c200c200b6a200a41807f72200a41ff0071200a410776220b1b3a0000200b210a200b0d000c060b0b024002402003280258200328025c220c460d002003280254210d0c010b200c41016a220d200c490d2e200c4101742205200d2005200d4b1b22054100480d2e02400240200c0d0020051028210d0c010b2003280254200c2005102c210d0b200d450d18200320053602582003200d360254200328025c210c0b2003200c41016a36025c200d200c6a41033a00000340024002402003280258200328025c220c460d002003280254210d0c010b200c41016a220d200c490d2f200c4101742205200d2005200d4b1b22054100480d2f02400240200c0d0020051028210d0c010b2003280254200c2005102c210d0b200d450d1a200320053602582003200d360254200328025c210c0b2003200c41016a36025c200d200c6a200b41807f72200b41ff0071200b410776220c1b3a0000200c210b200c0d000b0340024002402003280258200328025c220b460d002003280254210c0c010b200b41016a220c200b490d2f200b410174220d200c200d200c4b1b220d4100480d2f02400240200b0d00200d1028210c0c010b2003280254200b200d102c210c0b200c450d1b2003200d3602582003200c360254200328025c210b0b2003200b41016a36025c200c200b6a200a41807f72200a41ff0071200a410776220b1b3a0000200b210a200b0d000b20032002200341d0006a10eb0420032d0000220a411f460d0420032f000120032d000341107472210d0c280b024002402003280258200328025c220c460d002003280254210d0c010b200c41016a220d200c490d2d200c4101742205200d2005200d4b1b22054100480d2d02400240200c0d0020051028210d0c010b2003280254200c2005102c210d0b200d450d1a200320053602582003200d360254200328025c210c0b2003200c41016a36025c200d200c6a41043a00000340024002402003280258200328025c220c460d002003280254210d0c010b200c41016a220d200c490d2e200c4101742205200d2005200d4b1b22054100480d2e02400240200c0d0020051028210d0c010b2003280254200c2005102c210d0b200d450d1c200320053602582003200d360254200328025c210c0b2003200c41016a36025c200d200c6a200b41807f72200b41ff0071200b410776220c1b3a0000200c210b200c0d000b0340024002402003280258200328025c220b460d002003280254210c0c010b200b41016a220c200b490d2e200b410174220d200c200d200c4b1b220d4100480d2e02400240200b0d00200d1028210c0c010b2003280254200b200d102c210c0b200c450d1d2003200d3602582003200c360254200328025c210b0b2003200b41016a36025c200c200b6a200a41807f72200a41ff0071200a410776220b1b3a0000200b210a200b0d000b20032002200341d0006a10eb0420032d0000220a411f460d0320032f000120032d000341107472210d0c270b024002402003280258200328025c220c460d002003280254210d0c010b200c41016a220d200c490d2c200c4101742205200d2005200d4b1b22054100480d2c02400240200c0d0020051028210d0c010b2003280254200c2005102c210d0b200d450d1c200320053602582003200d360254200328025c210c0b2003200c41016a36025c200d200c6a41053a00000340024002402003280258200328025c220c460d002003280254210d0c010b200c41016a220d200c490d2d200c4101742205200d2005200d4b1b22054100480d2d02400240200c0d0020051028210d0c010b2003280254200c2005102c210d0b200d450d1e200320053602582003200d360254200328025c210c0b2003200c41016a36025c200d200c6a200b41807f72200b41ff0071200b410776220c1b3a0000200c210b200c0d000b0340024002402003280258200328025c220b460d002003280254210c0c010b200b41016a220c200b490d2d200b410174220d200c200d200c4b1b220d4100480d2d02400240200b0d00200d1028210c0c010b2003280254200b200d102c210c0b200c450d1f2003200d3602582003200c360254200328025c210b0b2003200b41016a36025c200c200b6a200a41807f72200a41ff0071200a410776220b1b3a0000200b210a200b0d000b20032002200341d0006a10eb0420032d0000220a411f460d0220032f000120032d000341107472210d0c260b024002402003280258200328025c220c460d002003280254210d0c010b200c41016a220d200c490d2b200c4101742205200d2005200d4b1b22054100480d2b02400240200c0d0020051028210d0c010b2003280254200c2005102c210d0b200d450d1e200320053602582003200d360254200328025c210c0b2003200c41016a36025c200d200c6a41063a00000340024002402003280258200328025c220c460d002003280254210d0c010b200c41016a220d200c490d2c200c4101742205200d2005200d4b1b22054100480d2c02400240200c0d0020051028210d0c010b2003280254200c2005102c210d0b200d450d20200320053602582003200d360254200328025c210c0b2003200c41016a36025c200d200c6a200b41807f72200b41ff0071200b410776220c1b3a0000200c210b200c0d000b0340024002402003280258200328025c220b460d002003280254210c0c010b200b41016a220c200b490d2c200b410174220d200c200d200c4b1b220d4100480d2c02400240200b0d00200d1028210c0c010b2003280254200b200d102c210c0b200c450d212003200d3602582003200c360254200328025c210b0b2003200b41016a36025c200c200b6a200a41807f72200a41ff0071200a410776220b1b3a0000200b210a200b0d000c020b0b024002402003280258200328025c220c460d002003280254210d0c010b200c41016a220d200c490d2a200c4101742205200d2005200d4b1b22054100480d2a02400240200c0d0020051028210d0c010b2003280254200c2005102c210d0b200d450d20200320053602582003200d360254200328025c210c0b2003200c41016a36025c200d200c6a41073a00000340024002402003280258200328025c220c460d002003280254210d0c010b200c41016a220d200c490d2b200c4101742205200d2005200d4b1b22054100480d2b02400240200c0d0020051028210d0c010b2003280254200c2005102c210d0b200d450d22200320053602582003200d360254200328025c210c0b2003200c41016a36025c200d200c6a200b41807f72200b41ff0071200b410776220c1b3a0000200c210b200c0d000b0340024002402003280258200328025c220b460d002003280254210c0c010b200b41016a220c200b490d2b200b410174220d200c200d200c4b1b220d4100480d2b02400240200b0d00200d1028210c0c010b2003280254200b200d102c210c0b200c450d232003200d3602582003200c360254200328025c210b0b2003200b41016a36025c200c200b6a200a41807f72200a41ff0071200a410776220b1b3a0000200b210a200b0d000b0b200741106a210720042006470d000b200621040b0240034020062004460d012004280200210a200441106a2104200a4108470d000b0b0240200f450d002008102a0b20032802582108200328025421022003280250220441086a210d200441046a2105200328025c2207210b0340024002402005280200200d280200220a460d002004280200210c0c010b200a41016a220c200a490d28200a4101742206200c2006200c4b1b22064100480d2802400240200a0d0020061028210c0c010b2004280200200a2006102c210c0b200c450d212004200c36020020052006360200200d280200210a0b200d200a41016a360200200c200a6a200b41807f72200b41ff0071200b410776220a1b3a0000200a210b200a0d000b02400240200441046a280200220b200441086a280200220a6b2007490d002004280200210b0c010b200a20076a220c200a490d27200b410174220a200c200a200c4b1b220a4100480d2702400240200b0d00200a1028210b0c010b2004280200200b200a102c210b0b200b450d212004200b360200200441046a200a360200200441086a280200210a0b200441086a200a20076a360200200b200a6a20022007109a051a02402008450d002002102a0b410021104101210d2009450d222011450d222012450d222009102a0c220b200c41011037000b200441011037000b200c41011037000b200b41011037000b200d41011037000b200c41011037000b200d41011037000b200541011037000b200541011037000b200d41011037000b200541011037000b200541011037000b200d41011037000b200541011037000b200541011037000b200d41011037000b200541011037000b200541011037000b200d41011037000b200541011037000b200541011037000b200d41011037000b200541011037000b200541011037000b200d41011037000b200541011037000b200541011037000b200d41011037000b200541011037000b200541011037000b200d41011037000b200641011037000b200a41011037000b20032903082114200328020421042013410474210c02400340200c2007460d01200820076a210b200741106a2107200b2802004108470d000b0b0240200f450d002008102a0b02402003280258450d002003280254102a0b02402009450d002011450d002012450d002009102a0b200a411f470d17410021104101210d0b4101210b4101210c410121044101210641012105410121074101210241012112410121084101210941012113410121110c3a0b2001412c6a280200210e200141286a2802002115200141246a2802002111200141206a28020021162001411c6a2802002117200141186a2802002118200141146a28020021102001410c6a2902002114200141086a2802002119200141046a28020021120240024002400240024002400240024002400240024002400240024002400240024002400240200241046a280200200241086a280200220a460d002002280200210b0c010b200a41016a220b200a490d14200a410174220c200b200c200b4b1b220c4100480d1402400240200a0d00200c1028210b0c010b2002280200200a200c102c210b0b200b450d012002200b360200200241046a200c360200200241086a280200210a0b4101210d200241086a200a41016a36020041002109200b200a6a41003a0000024041041028220f450d00200f41eec2b5ab063600000240024002400240024020120d00410021044100211a0c010b410121074100210a410021062014a72209210b034002400240200a2006460d00200a21082006210c0c010b200a41016a220c200a490d1a200a410174220d200c200d200c4b1b22084100480d1a02400240200a0d002008102821070c010b2007200a2008102c21070b02402007450d00200a210c2008210a0c010b200841011037000b2007200c6a200b41807f72200b41ff0071200b410776220d1b3a0000200c41016a2106200d210b200d0d000b02400240024002400240200820066b20094f0d00200620096a220a2006490d1d2008410174220b200a200b200a4b1b220a4100480d1d0240024020080d00200a102821070c010b20072008200a102c21070b2007450d01200a21080b200720066a20122009109a051a02402019450d002012102a0b41011028220d450d07200d41003a0000410221054101210a41012104200620096a2213210b03400240200a2004470d002005200a41016a2204200520044b1b22044100480d1e200d200a2004102c220d450d080b200d200a6a200b41807f72200b41ff0071200b41077622061b3a0000200541026a2105200a41016a210a2006210b20060d000b2004200a6b20134f0d03200a20136a220b200a490d1c20044101742205200b2005200b4b1b220b4100480d1c20040d01200b1028210d0c020b200a41011037000b200d2004200b102c210d0b200d450d02200b21040b200d200a6a20072013109a051a4101211a2009200c6a200a6a41016a21092008450d002007102a0b0240024002400240024020100d004101211b0c010b4100211b20034100360240200342013703382003410c6a2017360200200341086a201836020020032010360204200320144220883e0200200341d0006a2003200341386a10f104024020032d00502213411f460d0020032f005120032d0053411074722108200341d0006a41086a290300211420032802542116200328023c0d140c150b024020042009470d00200941016a220a2009490d1c2009410174220b200a200b200a4b1b22044100480d1c0240024020090d0020041028210d0c010b200d20092004102c210d0b200d450d040b200d20096a41013a0000200941016a210a200941017441026a210c20032802402206210b03400240200a2004470d00200a41016a2204200a490d1d200c2004200c20044b1b22044100480d1d02400240200a0d0020041028210d0c010b200d200a2004102c210d0b200d450d040b200d200a6a200b41807f72200b41ff0071200b41077622051b3a0000200c41026a210c200a41016a210a2005210b20050d000b2003280238210b02402004200a6b20064f0d00200a20066a220c200a490d1c20044101742205200c2005200c4b1b220c4100480d1c0240024020040d00200c1028210d0c010b200d2004200c102c210d0b200d450d02200c21040b200d200a6a200b2006109a051a0240200328023c450d00200b102a0b2006200a6a21094100211b0b024020110d00410021050c0e0b2003410036024020034201370338410121064100210c4100210a2016210b024003400240200a200c470d00200c41016a2205200c490d1d200c41017422072005200720054b1b22054100480d1d02400240200c0d002005102821060c010b2006200c2005102c21060b2006450d022003200536023c200320063602382005210c0b2003200a41016a22073602402006200a6a200b41807f72200b41ff0071200b41077622051b3a00002007210a2005210b20050d000b2011200e4104746a21080240200e0d00201121050c0c0b201121052016450d0b200841706a211c4100210a2011211d0340201d210502400340200541046a28020022130d01200a41016a210a2008200541106a2205470d000c0f0b0b200541106a211d200a41016a211e2016417f6a2116200541086a29020021142005280200211f200328023c210c2003280240210b02400240034002400240200b200c460d00200328023821060c010b200c41016a2206200c490d20200c41017422072006200720064b1b22074100480d2002400240200c0d002007102821060c010b2003280238200c2007102c21060b2006450d022003200736023c200320063602382007210c0b2003200b41016a22073602402006200b6a200a41807f72200a41ff0071200a41077622061b3a00002007210b2006210a20060d000b20032014370308200320133602042003201f360200200341d0006a2003200341386a10f10420032d00502213411f460d010c0c0b200741011037000b201c2005460d0b201e210a20160d000c0b0b0b200541011037000b200c41011037000b200441011037000b200441011037000b200b41011037000b200441011037000b410141011037000b410441011037000b200c41011037000b20032d0053211d20032f0051211f20032802542116200329035821140240200841706a2005460d00200541106a210503402005220a41106a21050240200a2802042206450d00200a28020821070240200a410c6a280200220a450d00200a410c6c210b2006210a03400240200a280200220c450d00200a41046a280200450d00200c102a0b200a410c6a210a200b41746a220b0d000b0b2007450d002006102a0b20052008470d000b0b02402015450d002011102a0b2013411f460d03201f201d41107472210841012105200328023c450d0b2003280238102a0c0b0b200541106a21050b20052008460d0003402005220a41106a21050240200a2802042206450d00200a28020821070240200a410c6a280200220a450d00200a410c6c210b2006210a03400240200a280200220c450d00200a41046a280200450d00200c102a0b200a410c6a210a200b41746a220b0d000b0b2007450d002006102a0b20052008470d000b0b2015450d002011102a0b024020042009470d00200941016a220a2009490d0e2009410174220b200a200b200a4b1b22044100480d0e0240024020090d0020041028210d0c010b200d20092004102c210d0b200d450d020b200d20096a41023a0000200941016a210a200941017441026a210c20032802402206210b03400240200a2004470d00200a41016a2204200a490d0f200c2004200c20044b1b22044100480d0f02400240200a0d0020041028210d0c010b200d200a2004102c210d0b200d450d040b200d200a6a200b41807f72200b41ff0071200b41077622051b3a0000200c41026a210c200a41016a210a2005210b20050d000b2003280238210b02402004200a6b20064f0d00200a20066a220c200a490d0e20044101742205200c2005200c4b1b220c4100480d0e0240024020040d00200c1028210d0c010b200d2004200c102c210d0b200d450d04200c21040b200d200a6a200b2006109a051a0240200328023c450d00200b102a0b2006200a6a2109410121050b201a201245720d032019450d032012102a0c030b200441011037000b200441011037000b200c41011037000b02402010450d00201b4101730d0002402017450d002017410c6c210b2010210a03400240200a280200220c450d00200a41046a280200450d00200c102a0b200a410c6a210a200b41746a220b0d000b0b2018450d002010102a0b2011452005720d030240200e450d002011200e4104746a21072011210603402006220541106a210602402005280204220a450d0002402005410c6a280200220b450d00200b410c6c210b03400240200a280200220c450d00200a41046a280200450d00200c102a0b200a410c6a210a200b41746a220b0d000b0b200541086a280200450d002005280204102a0b20062007470d000b0b2015450d032011102a0c030b2003280238102a0b410021050b0240201a201245720d002019450d002012102a0b02402010450d00201b4101730d0002402017450d002017410c6c210b2010210a03400240200a280200220c450d00200a41046a280200450d00200c102a0b200a410c6a210a200b41746a220b0d000b0b2018450d002010102a0b02402005201145720d000240200e450d002011200e4104746a21072011210603402006220541106a210602402005280204220a450d0002402005410c6a280200220b450d00200b410c6c210b03400240200a280200220c450d00200a41046a280200450d00200c102a0b200a410c6a210a200b41746a220b0d000b0b200541086a280200450d002005280204102a0b20062007470d000b0b2015450d002011102a0b2013411f460d002008410874201372210a02402004450d00200d102a0b2000200a360200200041086a2014370200200041046a2016360200200f102a0c010b200341146a2009360200200341106a20043602002003200d36020c20034284808080c0003702042003200f360200200341d0006a2003200210f504200320032900513703382003200341d0006a41086a29000037003f20032d0050220a411f460d012000200a3a000020002003290338370001200041086a200329003f3700000b410021084101210d4101210c4101210b4101210441012105410121064101210741012102410121090c1f0b410021114101210d4101210b4101210c4101210441012106410121054101210741012102410121124101210841012109410121130c380b2001410c6a2802002105200141086a2802002107200141046a28020021060240024002400240200241046a280200200241086a280200220a460d002002280200210b0c010b200a41016a220b200a490d04200a410174220c200b200c200b4b1b220c4100480d0402400240200a0d00200c1028210b0c010b2002280200200a200c102c210b0b200b450d012002200b360200200241046a200c360200200241086a280200210a0b200241086a200a41016a360200200b200a6a410b3a0000200341c4006a41003602002003420137023c2003200236023820062005411c6c6a21114100210a4100210b2005210c0240034002400240200a200b460d00200328023c210a0c010b200a41016a220d200a490d06200a4101742204200d2004200d4b1b220d4100480d0602400240200a0d00200d1028210a0c010b200328023c200a200d102c210a0b200a450d022003200d3602402003200a36023c0b2003200b41016a360244200a200b6a200c41807f72200c41ff0071200c410776220c1b3a00000240200c450d002003280240210a2003280244210b200c210c0c010b0b2003201136025c2003200636025820032007360254200320063602502005450d02034020032006220a411c6a2206360258200a2802102207450d03200a410c6a2802002102200a41086a2802002108200a2802042105200a41146a2902002114200a280200210b024002400240024003400240024020032802402003280244220a460d00200328023c210c0c010b200a41016a220c200a490d0b200a410174220d200c200d200c4b1b220d4100480d0b02400240200a0d00200d1028210c0c010b200328023c200a200d102c210c0b200c450d022003200d3602402003200c36023c2003280244210a0b2003200a41016a360244200c200a6a200b41807f72200b41ff0071200b410776220a1b3a0000200a210b200a0d000b024002400240024020050d00410121130c010b200320023602302003200836022c200320053602282003200341286a200341386a10e80420032d0000220a411f470d01410021130b2014a721092014422088a72204210b03400240024020032802402003280244220a460d00200328023c210c0c010b200a41016a220c200a490d0d200a410174220d200c200d200c4b1b220d4100480d0d02400240200a0d00200d1028210c0c010b200328023c200a200d102c210c0b200c450d052003200d3602402003200c36023c2003280244210a0b2003200a41016a360244200c200a6a200b41807f72200b41ff0071200b410776220a1b3a0000200a210b200a0d000b024002402003280240220b2003280244220a6b2004490d00200328023c210b0c010b200a20046a220c200a490d0c200b410174220a200c200a200c4b1b220a4100480d0c02400240200b0d00200a1028210b0c010b200328023c200b200a102c210b0b200b450d052003200a3602402003200b36023c2003280244210a0b2003200a20046a360244200b200a6a20072004109a051a02402009450d002007102a0b2005450d0520130d010c050b20032d0003411074210b20032f0001210c200329030821202003280204210d02402014a7450d002007102a0b200c200b72210b200341d0006a10f60402402003280240450d00200328023c102a0b2000200b3b00012000200a3a0000200041036a200b4110763a0000200041086a2020370000200041046a200d360000410021024101210d4101210c4101210b410121044101210541012106410121070c250b02402002450d002002410474210b2005210a03400240200a2d00004109470d000240200a41046a220d280200220c28020441ffffffff0371450d00200c280200102a200d280200210c0b200c102a0b200a41106a210a200b41706a220b0d000b0b2008450d032005102a0c030b200d41011037000b200d41011037000b200a41011037000b20062011470d000c030b0b200d41011037000b200c41011037000b200341d0006a10f60420032802402108200328023c21022003280238220441086a210d200441046a210520032802442207210b024002400340024002402005280200200d280200220a460d002004280200210c0c010b200a41016a220c200a490d05200a4101742206200c2006200c4b1b22064100480d0502400240200a0d0020061028210c0c010b2004280200200a2006102c210c0b200c450d022004200c36020020052006360200200d280200210a0b200d200a41016a360200200c200a6a200b41807f72200b41ff0071200b410776220a1b3a0000200a210b200a0d000b02400240200441046a280200220b200441086a280200220a6b2007490d002004280200210b0c010b200a20076a220c200a490d04200b410174220a200c200a200c4b1b220a4100480d0402400240200b0d00200a1028210b0c010b2004280200200b200a102c210b0b200b450d022004200b360200200441046a200a360200200441086a280200210a0b200441086a200a20076a360200200b200a6a20022007109a051a02402008450d002002102a0b410021134101210d4101210b4101210c4101210441012106410121054101210741012102410121124101210841012109410121110c390b200641011037000b200a41011037000b2001410c6a2802002106200141086a2802002107200141046a280200210d0240024002400240200241046a280200200241086a280200220a460d002002280200210b0c010b200a41016a220b200a490d14200a410174220c200b200c200b4b1b220c4100480d1402400240200a0d00200c1028210b0c010b2002280200200a200c102c210b0b200b450d012002200b360200200241046a200c360200200241086a280200210a0b200241086a200a41016a360200200b200a6a410a3a0000200341246a41003602002003420137021c20032002360218200d200641186c6a210f4100210a4100210b2006210c0240034002400240200a200b460d00200328021c210a0c010b200a41016a2204200a490d16200a41017422052004200520044b1b22044100480d1602400240200a0d0020041028210a0c010b200328021c200a2004102c210a0b200a450d02200320043602202003200a36021c0b2003200b41016a360224200a200b6a200c41807f72200c41ff0071200c410776220c1b3a00000240200c450d002003280220210a2003280224210b200c210c0c010b0b2003200f3602342003200d3602302003200736022c2003200d3602282006450d0220034101722102200341026a2107024003402003200d41186a2213360230200d2802002208450d04200d41146a2802002111200d41106a2802002110200d28020c2109200d280208210c200d28020421124100210b200341003602442003420137023c2008200c4103746a21062003200341186a3602384100210a02400240034002400240200b200a460d00200328023c210b0c010b200b41016a220a200b490d1a200b410174220d200a200d200a4b1b220a4100480d1a02400240200b0d00200a1028210b0c010b200328023c200b200a102c210b0b200b450d022003200a3602402003200b36023c2003280244210a0b2003200a41016a360244200b200a6a200c41807f72200c41ff0071200c410776220c1b3a00000240200c450d002003280240210b2003280244210a200c210c0c010b0b024020062008470d00200821040c020b2008210a0340200a41086a2104200a2902002214422088a7220a41ff01714104460d02200a41187441187521052014a7210b02400240024003400240024020032802402003280244220a460d00200328023c210c0c010b200a41016a220c200a490d0d200a410174220d200c200d200c4b1b220d4100480d0d02400240200a0d00200d1028210c0c010b200328023c200a200d102c210c0b200c450d022003200d3602402003200c36023c2003280244210a0b2003200a41016a360244200c200a6a200b41807f72200b41ff0071200b410776220a1b3a0000200a210b200a0d000b024020032802402003280244220a460d00200328023c210b0c030b200a41016a220b200a490d0b200a410174220c200b200c200b4b1b220c4100480d0b02400240200a0d00200c1028210b0c010b200328023c200a200c102c210b0b200b450d012003200c3602402003200b36023c2003280244210a0c020b200d41011037000b200c41011037000b2003200a41016a360244200b200a6a2005417f73220a413f7141c00072200a2005417f4a1b3a00002004210a20042006470d000b200621040c010b200a41011037000b0240034020062004460d0120042d0004210a200441086a2104200a4104470d000b0b02402012450d002008102a0b20092011410474220a6a210c0240024002400240024020110d002009210a0c010b200a41706a210d2009210a0340200a2d0000210b2007200a41036a2d00003a00002003200a41016a2f00003b01000240200b41ac01470d00200a41106a210a0c020b200341cc006a41026a20072d000022043a0000200320032f010022053b014c200a41046a2802002106200a41086a2903002114200220053b0000200241026a20043a00002003200b3a00002003201437030820032006360204200341d0006a2003200341386a10f004024020032d00502204411f46220b450d00200d41706a210d200a41106a220a200c470d010c030b0b20032d0053210520032f0051210620032802542108200329035821140240200d450d00200a41106a210a034002400240200a2d0000220d4109460d00200d41ac01470d010c030b0240200a41046a280200220d28020441ffffffff0371450d00200d280200102a0b200d102a0b200a41106a220a200c470d000b0b02402010450d002009102a0b02402003280240450d00200328023c102a0b200b0d022006200541107472210a200341286a10f70402402003280220450d00200328021c102a0b2000200a3b0001200020043a0000200041036a200a4110763a0000200041086a2014370000200041046a2008360000410021074101210d4101210c4101210b4101210441012105410121060c230b200a200c460d00034002400240200a2d0000220b4109460d00200b41ac01470d010c030b0240200a41046a280200220b28020441ffffffff0371450d00200b280200102a0b200b102a0b200a41106a220a200c470d000b0b02402010450d002009102a0b20032802402111200328023c21092003280238210c20032802442208210b034002400240200c41086a2205280200200c410c6a2204280200220a460d00200c280204210d0c010b200a41016a220d200a490d09200a4101742206200d2006200d4b1b22064100480d0902400240200a0d0020061028210d0c010b200c280204200a2006102c210d0b200d450d03200c200d360204200520063602002004280200210a0b2004200a41016a360200200d200a6a200b41807f72200b41ff0071200b410776220a1b3a0000200a210b200a0d000b024002402005280200220b2004280200220a6b2008490d00200c280204210b0c010b200a20086a220d200a490d08200b410174220a200d200a200d4b1b220a4100480d0802400240200b0d00200a1028210b0c010b200c280204200b200a102c210b0b200b450d04200c200b3602042005200a3602002004280200210a0b2004200a20086a360200200b200a6a20092008109a051a2011450d002009102a0b2013210d2013200f470d010c050b0b200641011037000b200a41011037000b200441011037000b200c41011037000b200341286a10f70420032802202108200328021c21022003280218220441086a210d200441046a210520032802242207210b024002400340024002402005280200200d280200220a460d002004280200210c0c010b200a41016a220c200a490d04200a4101742206200c2006200c4b1b22064100480d0402400240200a0d0020061028210c0c010b2004280200200a2006102c210c0b200c450d022004200c36020020052006360200200d280200210a0b200d200a41016a360200200c200a6a200b41807f72200b41ff0071200b410776220a1b3a0000200a210b200a0d000b02400240200441046a280200220b200441086a280200220a6b2007490d002004280200210b0c010b200a20076a220c200a490d03200b410174220a200c200a200c4b1b220a4100480d0302400240200b0d00200a1028210b0c010b2004280200200b200a102c210b0b200b450d022004200b360200200441046a200a360200200441086a280200210a0b200441086a200a20076a360200200b200a6a20022007109a051a02402008450d002002102a0b410021094101210d4101210b4101210c410121044101210641012105410121074101210241012112410121080c280b200641011037000b200a41011037000b1031000b2001410c6a2802002105200141086a2802002106200141046a28020021080240024002400240200241046a280200200241086a280200220a460d002002280200210b0c010b200a41016a220b200a490d12200a410174220c200b200c200b4b1b220c4100480d1202400240200a0d00200c1028210b0c010b2002280200200a200c102c210b0b200b450d012002200b360200200241046a200c360200200241086a280200210a0b200241086a200a41016a360200200b200a6a41093a0000200341c4006a41003602002003420137023c2003200236023820082005411c6c6a21124100210a4100210b2005210c0240034002400240200a200b460d00200328023c210a0c010b200a41016a220d200a490d14200a4101742204200d2004200d4b1b220d4100480d1402400240200a0d00200d1028210a0c010b200328023c200a200d102c210a0b200a450d022003200d3602402003200a36023c0b2003200b41016a360244200a200b6a200c41807f72200c41ff0071200c410776220c1b3a00000240200c450d002003280240210a2003280244210b200c210c0c010b0b2003201236025c2003200836025820032006360254200320083602502005450d02034020032008220a411c6a2208360258200a2802102206450d03200a410c6a2802002102200a41086a2802002109200a2802042107200a41146a2902002114200a280200210b024002400240024003400240024020032802402003280244220a460d00200328023c210c0c010b200a41016a220c200a490d19200a410174220d200c200d200c4b1b220d4100480d1902400240200a0d00200d1028210c0c010b200328023c200a200d102c210c0b200c450d022003200d3602402003200c36023c2003280244210a0b2003200a41016a360244200c200a6a200b41807f72200b41ff0071200b410776220a1b3a0000200a210b200a0d000b024002400240024020070d00410121110c010b200320023602302003200936022c200320073602282003200341286a200341386a10e80420032d0000220a411f470d01410021110b20062014422088a7220b4102746a21052014a7211303400240024020032802402003280244220a460d00200328023c210c0c010b200a41016a220c200a490d1b200a410174220d200c200d200c4b1b220d4100480d1b02400240200a0d00200d1028210c0c010b200328023c200a200d102c210c0b200c450d052003200d3602402003200c36023c2003280244210a0b2003200a41016a360244200c200a6a200b41807f72200b41ff0071200b410776220a1b3a0000200a210b200a0d000b024020052006460d002006210403402004280200210b03400240024020032802402003280244220a460d00200328023c210c0c010b200a41016a220c200a490d1d200a410174220d200c200d200c4b1b220d4100480d1d02400240200a0d00200d1028210c0c010b200328023c200a200d102c210c0b200c450d082003200d3602402003200c36023c2003280244210a0b2003200a41016a360244200c200a6a200b41807f72200b41ff0071200b410776220a1b3a0000200a210b200a0d000b200441046a22042005470d000b0b02402013450d002006102a0b2007450d0520110d010c050b20032d0003411074210b20032f0001210c200329030821202003280204210d02402014a7450d002006102a0b200c200b72210b200341d0006a10f80402402003280240450d00200328023c102a0b2000200b3b00012000200a3a0000200041036a200b4110763a0000200041086a2020370000200041046a200d360000410021064101210d4101210c4101210b41012104410121050c200b02402002450d002002410474210b2007210a03400240200a2d00004109470d000240200a41046a220d280200220c28020441ffffffff0371450d00200c280200102a200d280200210c0b200c102a0b200a41106a210a200b41706a220b0d000b0b2009450d032007102a0c030b200d41011037000b200d41011037000b200d41011037000b20082012470d000c030b0b200d41011037000b200c41011037000b200341d0006a10f80420032802402108200328023c21022003280238220441086a210d200441046a210520032802442207210b024002400340024002402005280200200d280200220a460d002004280200210c0c010b200a41016a220c200a490d13200a4101742206200c2006200c4b1b22064100480d1302400240200a0d0020061028210c0c010b2004280200200a2006102c210c0b200c450d022004200c36020020052006360200200d280200210a0b200d200a41016a360200200c200a6a200b41807f72200b41ff0071200b410776220a1b3a0000200a210b200a0d000b02400240200441046a280200220b200441086a280200220a6b2007490d002004280200210b0c010b200a20076a220c200a490d12200b410174220a200c200a200c4b1b220a4100480d1202400240200b0d00200a1028210b0c010b2004280200200b200a102c210b0b200b450d022004200b360200200441046a200a360200200441086a280200210a0b200441086a200a20076a360200200b200a6a20022007109a051a02402008450d002002102a0b410021084101210d4101210b4101210c4101210441012106410121054101210741012102410121120c250b200641011037000b200a41011037000b200141046a280200210a024002400240024002400240200241046a280200200241086a280200220b460d002002280200210c0c010b200b41016a220c200b490d13200b410174220d200c200d200c4b1b220d4100480d1302400240200b0d00200d1028210c0c010b2002280200200b200d102c210c0b200c450d012002200c360200200241046a200d360200200241086a280200210b0b200241086a200b41016a360200200c200b6a410c3a00004100210c4100210b410021064101210503400240200b2006470d00200c200b41016a220d200c200d4b1b22064100480d1402400240200c0d002006102821050c010b2005200b2006102c21050b2005450d030b2005200b6a200a41807f72200a41ff0071200a410776220d1b3a0000200c41026a210c200b41016a210b200d210a200d0d000b200b417f6a2109200241086a2104200241046a2107200b210c03400240024020072802002004280200220a460d002002280200210d0c010b200a41016a220d200a490d14200a4101742208200d2008200d4b1b22084100480d1402400240200a0d0020081028210d0c010b2002280200200a2008102c210d0b200d450d042002200d360200200720083602002004280200210a0b2004200a41016a360200200d200a6a200c41807f72200c41ff0071200c410776220a1b3a0000200a210c200a0d000b02400240200241046a280200220c200241086a280200220a6b20094d0d002002280200210c0c010b200a200b6a220d200a490d13200c410174220a200d200a200d4b1b220a4100480d1302400240200c0d00200a1028210c0c010b2002280200200c200a102c210c0b200c450d042002200c360200200241046a200a360200200241086a280200210a0b200241086a200a200b6a360200200c200a6a2005200b109a051a4101210d2006450d052005102a0c050b200d41011037000b200641011037000b200841011037000b200a41011037000b200141046a280200210a02400240200241046a280200200241086a280200220b460d002002280200210c0c010b200b41016a220c200b490d0e200b410174220d200c200d200c4b1b220d4100480d0e02400240200b0d00200d1028210c0c010b2002280200200b200d102c210c0b200c450d022002200c360200200241046a200d360200200241086a280200210b0b200241086a200b41016a360200200c200b6a41083a00004100210c4100210b410021064101210503400240200b2006470d00200c200b41016a220d200c200d4b1b22064100480d0f02400240200c0d002006102821050c010b2005200b2006102c21050b2005450d040b2005200b6a200a41807f72200a41ff0071200a410776220d1b3a0000200c41026a210c200b41016a210b200d210a200d0d000b200b417f6a2109200241086a2104200241046a2107200b210c03400240024020072802002004280200220a460d002002280200210d0c010b200a41016a220d200a490d0f200a4101742208200d2008200d4b1b22084100480d0f02400240200a0d0020081028210d0c010b2002280200200a2008102c210d0b200d450d052002200d360200200720083602002004280200210a0b2004200a41016a360200200d200a6a200c41807f72200c41ff0071200c410776220a1b3a0000200a210c200a0d000b02400240200241046a280200220c200241086a280200220a6b20094d0d002002280200210c0c010b200a200b6a220d200a490d0e200c410174220a200d200a200d4b1b220a4100480d0e02400240200c0d00200a1028210c0c010b2002280200200c200a102c210c0b200c450d052002200c360200200241046a200a360200200241086a280200210a0b200241086a200a200b6a360200200c200a6a2005200b109a051a4101210d2006450d002005102a0b4101210b4101210c0c190b200d41011037000b200641011037000b200841011037000b200a41011037000b2001410c6a2802002106200141086a280200210f200141046a28020021100240024002400240024002400240024002400240200241046a280200200241086a280200220a460d002002280200210b0c010b200a41016a220b200a490d10200a410174220c200b200c200b4b1b220c4100480d1002400240200a0d00200c1028210b0c010b2002280200200a200c102c210b0b200b450d012002200b360200200241046a200c360200200241086a280200210a0b200241086a200a41016a360200200b200a6a41073a00002010200641146c6a2112410021044100210a4100210c4101210b2006210d03400240200a200c470d002004200a41016a220c2004200c4b1b220c4100480d110240024020040d00200c1028210b0c010b200b200a200c102c210b0b200b450d030b200b200a6a200d41807f72200d41ff0071200d41077622051b3a0000200441026a2104200a41016a210a2005210d20050d000b024020060d00201021080c070b201021040340200441146a2108200428020c22134104460d072004280204211120042802002109200a4101742105200441106a280200210d20042802082207210403400240200a200c470d00200a41016a220c200a490d122005200c2005200c4b1b220c4100480d1202400240200a0d00200c1028210b0c010b200b200a200c102c210b0b200b450d050b200b200a6a200441807f72200441ff0071200441077622061b3a0000200541026a2105200a41016a210a2006210420060d000b02400240200c200a6b2007490d00200c21040c010b200a20076a2204200a490d11200c41017422052004200520044b1b22044100480d1102400240200c0d0020041028210b0c010b200b200c2004102c210b0b200b450d050b200b200a6a20092007109a051a200720046b200a6a210c02402011450d002009102a0b02400240200c450d002004210c0c010b200441016a220c2004490d1120044101742205200c2005200c4b1b220c4100480d110240024020040d00200c1028210b0c010b200b2004200c102c210b0b200b450d060b200b20076a200a6a20133a00002007200a6a41016a210a03400240200a200c470d00200a41016a220c200a490d12200a4101742204200c2004200c4b1b220c4100480d1202400240200a0d00200c1028210b0c010b200b200a200c102c210b0b200b450d080b200b200a6a200d41807f72200d41ff0071200d41077622041b3a0000200a41016a210a2004210d20040d000b2008210420082012470d000c080b0b200c41011037000b200c41011037000b200c41011037000b200441011037000b200c41011037000b200c41011037000b20082012460d0003402008410c6a2802004104460d010240200841046a280200450d002008280200102a0b200841146a22082012470d000b0b0240200f450d002010102a0b200241086a2106200241046a2107200a210402400240024003400240024020072802002006280200220d460d00200228020021050c010b200d41016a2205200d490d0c200d41017422082005200820054b1b22084100480d0c02400240200d0d002008102821050c010b2002280200200d2008102c21050b2005450d0220022005360200200720083602002006280200210d0b2006200d41016a3602002005200d6a200441807f72200441ff00712004410776220d1b3a0000200d2104200d0d000b02400240200241046a2802002204200241086a280200220d6b200a490d00200228020021040c010b200d200a6a2205200d490d0b2004410174220d2005200d20054b1b220d4100480d0b0240024020040d00200d102821040c010b20022802002004200d102c21040b2004450d0220022004360200200241046a200d360200200241086a280200210d0b200241086a200d200a6a3602002004200d6a200b200a109a051a410021124101210d200c450d02200b102a0c020b200841011037000b200d41011037000b4101210b4101210c41012104410121064101210541012107410121020c1a0b2001410c6a2802002105200141086a2802002112200141046a2802002108024002400240024002400240024002400240200241046a280200200241086a280200220a460d002002280200210b0c010b200a41016a220b200a490d0e200a410174220c200b200c200b4b1b220c4100480d0e02400240200a0d00200c1028210b0c010b2002280200200a200c102c210b0b200b450d012002200b360200200241046a200c360200200241086a280200210a0b200241086a200a41016a360200200b200a6a41063a0000200341dc006a41003602002003420137025420032002360250200820054104746a21134100210a4100210b2005210c034002400240200a200b460d002003280254210a0c010b200a41016a220d200a490d0f200a4101742204200d2004200d4b1b220d4100480d0f02400240200a0d00200d1028210a0c010b2003280254200a200d102c210a0b200a450d032003200d3602582003200a3602540b2003200b41016a36025c200a200b6a200c41807f72200c41ff0071200c410776220c1b3a00000240200c450d002003280258210a200328025c210b200c210c0c010b0b200821042005450d05200541047421114100210c034002402008200c6a220b410d6a2d000022044102470d00200b41106a21040c070b200b2802002105200b41086a2802002106200b41046a2802002107200b410c6a2d00002102024002402003280258200328025c220a460d002003280254210d0c010b200a41016a220d200a490d0f200a4101742209200d2009200d4b1b22094100480d0f02400240200a0d0020091028210d0c010b2003280254200a2009102c210d0b200d450d04200320093602582003200d360254200328025c210a0b2003200a41016a36025c200d200a6a200241ff00733a0000024002402003280258200328025c220a460d002003280254210d0c010b200a41016a220d200a490d0f200a4101742202200d2002200d4b1b22024100480d0f02400240200a0d0020021028210d0c010b2003280254200a2002102c210d0b200d450d05200320023602582003200d360254200328025c210a0b2003200a41016a36025c200d200a6a20043a0000200320063602402003200736023c200320053602382003200341386a200341d0006a10e80420032d00002205411f470d052011200c41106a220c470d000c070b0b200c41011037000b200d41011037000b200941011037000b200241011037000b20032d0003210220032f0001210920032802042111200329030821140240200b41106a2013460d00200b41106a210403402004410d6a2d00004102460d01200428020421072004280200210602402004280208220a450d00200a410474210b2006210a03400240200a2d00004109470d000240200a41046a220d280200220c28020441ffffffff0371450d00200c280200102a200d280200210c0b200c102a0b200a41106a210a200b41706a220b0d000b0b200441106a210402402007450d002006102a0b20042013470d000b0b2002411074210a02402012450d002008102a0b2009200a72210a02402003280258450d002003280254102a0b2000200a3b0001200020053a0000200041036a200a4110763a0000200041086a2014370000200041046a2011360000410021054101210d4101210c4101210b410121040c0f0b20042013460d0003402004410d6a2d00004102460d01200428020421062004280200210502402004280208220a450d00200a410474210b2005210a03400240200a2d00004109470d000240200a41046a220d280200220c28020441ffffffff0371450d00200c280200102a200d280200210c0b200c102a0b200a41106a210a200b41706a220b0d000b0b200441106a210402402006450d002005102a0b20042013470d000b0b02402012450d002008102a0b20032802582108200328025421022003280250220441086a210d200441046a2105200328025c2207210b024002400340024002402005280200200d280200220a460d002004280200210c0c010b200a41016a220c200a490d0a200a4101742206200c2006200c4b1b22064100480d0a02400240200a0d0020061028210c0c010b2004280200200a2006102c210c0b200c450d022004200c36020020052006360200200d280200210a0b200d200a41016a360200200c200a6a200b41807f72200b41ff0071200b410776220a1b3a0000200a210b200a0d000b02400240200441046a280200220b200441086a280200220a6b2007490d002004280200210b0c010b200a20076a220c200a490d09200b410174220a200c200a200c4b1b220a4100480d0902400240200b0d00200a1028210b0c010b2004280200200b200a102c210b0b200b450d022004200b360200200441046a200a360200200441086a280200210a0b200441086a200a20076a360200200b200a6a20022007109a051a02402008450d002002102a0b410021024101210d4101210b4101210c410121044101210641012105410121070c1a0b200641011037000b200a41011037000b2001410c6a2802002107200141086a2802002108200141046a280200210602400240024002400240200241046a280200200241086a280200220a460d002002280200210b0c010b200a41016a220b200a490d09200a410174220c200b200c200b4b1b220c4100480d0902400240200a0d00200c1028210b0c010b2002280200200a200c102c210b0b200b450d012002200b360200200241046a200c360200200241086a280200210a0b200241086a200a41016a360200200b200a6a41053a0000200341d0006a410c6a4100360200200342013702542003200236025020062007410c6c6a2102410121044100210c4100210a2007210b03400240200a200c470d00200c41016a220d200c490d0a200c4101742205200d2005200d4b1b220d4100480d0a02400240200c0d00200d102821040c010b2004200c200d102c21040b2004450d04200d210c0b2004200a6a200b41807f72200b41ff0071200b410776220d1b3a0000200a41016a210a200d210b200d0d000b2003200c3602582003200a36025c200320043602542006210a2007450d012007410c6c210d4100210b0340024002402006200b6a220a41046a280200220c4102460d002003200a280200200c200a41086a280200200341d0006a10f20420032d00002204411f460d0120032f000120032d00034110747221052003290308211420032802042107200a410c6a210c200d200b6b41746a210a02400340200a450d01200a41746a210a200c280204210b200c410c6a210c200b4102470d000b0b02402008450d002006102a0b02402003280258450d002003280254102a0b200020053b0001200020043a0000200041036a20054110763a0000200041086a2014370000200041046a2007360000410021044101210d4101210c4101210b0c110b200a410c6a210a0c030b200d200b410c6a220b470d000b2002210a0c010b200c41011037000b200a410020076b410c6c6a210b024003402006200b460d01200b410c6a210b200a280204210c200a410c6a210a200c4102470d000b0b02402008450d002006102a0b20032802582108200328025421022003280250220441086a210d200441046a2105200328025c2207210b024002400340024002402005280200200d280200220a460d002004280200210c0c010b200a41016a220c200a490d0a200a4101742206200c2006200c4b1b22064100480d0a02400240200a0d0020061028210c0c010b2004280200200a2006102c210c0b200c450d022004200c36020020052006360200200d280200210a0b200d200a41016a360200200c200a6a200b41807f72200b41ff0071200b410776220a1b3a0000200a210b200a0d000b02400240200441046a280200220b200441086a280200220a6b2007490d002004280200210b0c010b200a20076a220c200a490d09200b410174220a200c200a200c4b1b220a4100480d0902400240200b0d00200a1028210b0c010b2004280200200b200a102c210b0b200b450d022004200b360200200441046a200a360200200441086a280200210a0b200441086a200a20076a360200200b200a6a20022007109a051a02402008450d002002102a0b410021074101210d4101210b4101210c4101210441012106410121050c190b200641011037000b200a41011037000b200d41011037000b2001410c6a2802002109200141086a2802002113200141046a2802002106024002400240024002400240200241046a280200200241086a280200220a460d002002280200210b0c010b200a41016a220b200a490d09200a410174220c200b200c200b4b1b220c4100480d0902400240200a0d00200c1028210b0c010b2002280200200a200c102c210b0b200b450d012002200b360200200241046a200c360200200241086a280200210a0b200241086a200a41016a360200200b200a6a41043a0000200341d0006a410c6a4100360200200342013702542003200236025020062009410c6c6a2111410121044100210c4100210a2009210b03400240200a200c470d00200c41016a220d200c490d0a200c4101742205200d2005200d4b1b220d4100480d0a02400240200c0d00200d102821040c010b2004200c200d102c21040b2004450d05200d210c0b2004200a6a200b41807f72200b41ff0071200b410776220d1b3a0000200a41016a210a200d210b200d0d000b2003200c3602582003200a36025c200320043602542006210a2009450d022009410c6c21084100210c03400240024002402006200c6a220b41046a28020022044102460d00200b2802002105200b41086a28020021072003280258200328025c220a460d012003280254210d0c020b200b410c6a210a0c050b200a41016a220d200a490d0a200a4101742202200d2002200d4b1b22024100480d0a02400240200a0d0020021028210d0c010b2003280254200a2002102c210d0b200d450d03200320023602582003200d3602540b2003200a41016a36025c200d200a6a41f0003a00002003200520042007200341d0006a10f204024020032d0000220d411f460d0020032f000120032d00034110747221042003290308211420032802042105200b410c6a210b2008200c6b41746a210a02400340200a450d01200a41746a210a200b280204210c200b410c6a210b200c4102470d000b0b02402013450d002006102a0b02402003280258450d002003280254102a0b200020043b00012000200d3a0000200041036a20044110763a0000200041086a2014370000200041046a20053600004100210b4101210d4101210c0c0f0b2008200c410c6a220c470d000b2011210a0c020b200c41011037000b200241011037000b200a410020096b410c6c6a210b024003402006200b460d01200b410c6a210b200a280204210c200a410c6a210a200c4102470d000b0b02402013450d002006102a0b20032802582108200328025421022003280250220441086a210d200441046a2105200328025c2207210b024002400340024002402005280200200d280200220a460d002004280200210c0c010b200a41016a220c200a490d09200a4101742206200c2006200c4b1b22064100480d0902400240200a0d0020061028210c0c010b2004280200200a2006102c210c0b200c450d022004200c36020020052006360200200d280200210a0b200d200a41016a360200200c200a6a200b41807f72200b41ff0071200b410776220a1b3a0000200a210b200a0d000b02400240200441046a280200220b200441086a280200220a6b2007490d002004280200210b0c010b200a20076a220c200a490d08200b410174220a200c200a200c4b1b220a4100480d0802400240200b0d00200a1028210b0c010b2004280200200b200a102c210b0b200b450d022004200b360200200441046a200a360200200441086a280200210a0b200441086a200a20076a360200200b200a6a20022007109a051a02402008450d002002102a0b410021054101210d4101210b4101210c41012104410121060c170b200641011037000b200a41011037000b200d41011037000b2001410c6a2802002106200141086a2802002109200141046a280200210802400240024002400240024002400240200241046a280200200241086a280200220a460d002002280200210b0c010b200a41016a220b200a490d0a200a410174220c200b200c200b4b1b220c4100480d0a02400240200a0d00200c1028210b0c010b2002280200200a200c102c210b0b200b450d012002200b360200200241046a200c360200200241086a280200210a0b200241086a200a41016a360200200b200a6a41033a0000200820064102746a21074100210c4100210a41002105410121042006210b03400240200a2005470d00200c200a41016a220d200c200d4b1b22054100480d0b02400240200c0d002005102821040c010b2004200a2005102c21040b2004450d030b2004200a6a200b41807f72200b41ff0071200b410776220d1b3a0000200c41026a210c200a41016a210a200d210b200d0d000b02402006450d00200821060340200a410174210c2006280200210b03400240200a2005470d00200a41016a220d200a490d0d200c200d200c200d4b1b22054100480d0d02400240200a0d002005102821040c010b2004200a2005102c21040b2004450d060b2004200a6a200b41807f72200b41ff0071200b410776220d1b3a0000200c41026a210c200a41016a210a200d210b200d0d000b200641046a22062007470d000b0b02402009450d002008102a0b200241086a2106200241046a2107200a210c03400240024020072802002006280200220b460d002002280200210d0c010b200b41016a220d200b490d0b200b4101742208200d2008200d4b1b22084100480d0b02400240200b0d0020081028210d0c010b2002280200200b2008102c210d0b200d450d052002200d360200200720083602002006280200210b0b2006200b41016a360200200d200b6a200c41807f72200c41ff0071200c410776220b1b3a0000200b210c200b0d000b02400240200241046a280200220c200241086a280200220b6b200a490d002002280200210c0c010b200b200a6a220d200b490d0a200c410174220b200d200b200d4b1b220b4100480d0a02400240200c0d00200b1028210c0c010b2002280200200c200b102c210c0b200c450d052002200c360200200241046a200b360200200241086a280200210b0b200241086a200b200a6a360200200c200b6a2004200a109a051a410021064101210d2005450d052004102a0c050b200c41011037000b200541011037000b200541011037000b200841011037000b200b41011037000b4101210b4101210c410121040c120b2001410c6a2802002106200141086a2802002117200141046a280200210e0240024002400240024002400240024002400240024002400240024002400240024002400240200241046a280200200241086a280200220a460d002002280200210b0c010b200a41016a220b200a490d14200a410174220c200b200c200b4b1b220c4100480d1402400240200a0d00200c1028210b0c010b2002280200200a200c102c210b0b200b450d012002200b360200200241046a200c360200200241086a280200210a0b200241086a200a41016a360200200b200a6a41023a0000200341dc006a41003602002003420137025420032002360250200e200641286c6a21094100210a4100210b2006210c034002400240200a200b460d002003280254210a0c010b200a41016a220d200a490d15200a4101742204200d2004200d4b1b220d4100480d1502400240200a0d00200d1028210a0c010b2003280254200a200d102c210a0b200a450d032003200d3602582003200a3602540b2003200b41016a36025c200a200b6a200c41807f72200c41ff0071200c410776220c1b3a00000240200c450d002003280258210a200328025c210b200c210c0c010b0b200e21052006450d0f200e210503402005220a41286a2105200a2d001822134104460d10200a41206a2900002114200a411c6a2800002104200a411a6a2d0000210f200a41196a2c00002110200a41146a2802002106200a41106a2802002111200a28020c2102200a2802042112200a2802002108200a2802082207210b0340024002402003280258200328025c220a460d002003280254210c0c010b200a41016a220c200a490d16200a410174220d200c200d200c4b1b220d4100480d1602400240200a0d00200d1028210c0c010b2003280254200a200d102c210c0b200c450d052003200d3602582003200c360254200328025c210a0b2003200a41016a36025c200c200a6a200b41807f72200b41ff0071200b410776220a1b3a0000200a210b200a0d000b024002402003280258220b200328025c220a6b2007490d002003280254210b0c010b200a20076a220c200a490d15200b410174220a200c200a200c4b1b220a4100480d1502400240200b0d00200a1028210b0c010b2003280254200b200a102c210b0b200b450d052003200a3602582003200b360254200328025c210a0b2003200a20076a36025c200b200a6a20082007109a051a02402012450d002008102a0b2006210b0340024002402003280258200328025c220a460d002003280254210c0c010b200a41016a220c200a490d16200a410174220d200c200d200c4b1b220d4100480d1602400240200a0d00200d1028210c0c010b2003280254200a200d102c210c0b200c450d072003200d3602582003200c360254200328025c210a0b2003200a41016a36025c200c200a6a200b41807f72200b41ff0071200b410776220a1b3a0000200a210b200a0d000b024002402003280258220b200328025c220a6b2006490d002003280254210b0c010b200a20066a220c200a490d15200b410174220a200c200a200c4b1b220a4100480d1502400240200b0d00200a1028210b0c010b2003280254200b200a102c210b0b200b450d072003200a3602582003200b360254200328025c210a0b2003200a20066a36025c200b200a6a20022006109a051a02402011450d002002102a0b0240024002400240024020130e0400010203000b024002402003280258200328025c220a460d002003280254210b0c010b200a41016a220b200a490d19200a410174220c200b200c200b4b1b220c4100480d1902400240200a0d00200c1028210b0c010b2003280254200a200c102c210b0b200b450d0c2003200c3602582003200b360254200328025c210a0b2003200a41016a36025c200b200a6a41003a00000340024002402003280258200328025c220a460d002003280254210b0c010b200a41016a220b200a490d1a200a410174220c200b200c200b4b1b220c4100480d1a02400240200a0d00200c1028210b0c010b2003280254200a200c102c210b0b200b450d0e2003200c3602582003200b360254200328025c210a0b2003200a41016a36025c200b200a6a200441807f72200441ff00712004410776220a1b3a0000200a2104200a0d000c040b0b024002402003280258200328025c220a460d002003280254210b0c010b200a41016a220b200a490d18200a410174220c200b200c200b4b1b220c4100480d1802400240200a0d00200c1028210b0c010b2003280254200a200c102c210b0b200b450d0d2003200c3602582003200b360254200328025c210a0b2003200a41016a36025c200b200a6a41013a0000024002402003280258200328025c220a460d002003280254210b0c010b200a41016a220b200a490d18200a410174220c200b200c200b4b1b220c4100480d1802400240200a0d00200c1028210b0c010b2003280254200a200c102c210b0b200b450d0e2003200c3602582003200b360254200328025c210a0b2003200a41016a36025c200b200a6a41f0003a0000200320042014a72014422088a7200341d0006a10f20420032d0000220a411f460d0220032f000120032d000341107472210d0c120b024002402003280258200328025c220a460d002003280254210b0c010b200a41016a220b200a490d17200a410174220c200b200c200b4b1b220c4100480d1702400240200a0d00200c1028210b0c010b2003280254200a200c102c210b0b200b450d0e2003200c3602582003200b360254200328025c210a0b2003200a41016a36025c200b200a6a41023a0000200320042014a72014422088a7200341d0006a10f20420032d0000220a411f460d0120032f000120032d000341107472210d0c110b024002402003280258200328025c220a460d002003280254210b0c010b200a41016a220b200a490d16200a410174220c200b200c200b4b1b220c4100480d1602400240200a0d00200c1028210b0c010b2003280254200a200c102c210b0b200b450d0e2003200c3602582003200b360254200328025c210a0b2003200a41016a36025c200b200a6a41033a0000024002402003280258200328025c220a460d002003280254210b0c010b200a41016a220b200a490d16200a410174220c200b200c200b4b1b220c4100480d1602400240200a0d00200c1028210b0c010b2003280254200a200c102c210b0b200b450d0f2003200c3602582003200b360254200328025c210a0b2003200a41016a36025c200b200a6a2010417f73220a413f7141c00072200a2010417f4a1b3a0000024002402003280258200328025c220a460d002003280254210b0c010b200a41016a220b200a490d16200a410174220c200b200c200b4b1b220c4100480d1602400240200a0d00200c1028210b0c010b2003280254200a200c102c210b0b200b450d102003200c3602582003200b360254200328025c210a0b2003200a41016a36025c200b200a6a200f41ff01714100473a00000b20052009470d000c110b0b200c41011037000b200d41011037000b200d41011037000b200a41011037000b200d41011037000b200a41011037000b200c41011037000b200c41011037000b200c41011037000b200c41011037000b200c41011037000b200c41011037000b200c41011037000b200c41011037000b2003290308211420032802042104024020052009460d000340200541186a2d00004104460d01200541106a280200210b2005410c6a280200210c0240200541046a280200450d002005280200102a0b0240200b450d00200c102a0b200541286a22052009470d000b0b02402017450d00200e102a0b02402003280258450d002003280254102a0b2000200d3b00012000200a3a0000200041036a200d4110763a0000200041086a2014370000200041046a20043600004100210c4101210d0c080b20052009460d000340200541186a2d00004104460d01200541106a280200210a2005410c6a280200210b0240200541046a280200450d002005280200102a0b0240200a450d00200b102a0b200541286a22052009470d000b0b02402017450d00200e102a0b20032802582108200328025421022003280250220441086a210d200441046a2105200328025c2207210b024002400340024002402005280200200d280200220a460d002004280200210c0c010b200a41016a220c200a490d06200a4101742206200c2006200c4b1b22064100480d0602400240200a0d0020061028210c0c010b2004280200200a2006102c210c0b200c450d022004200c36020020052006360200200d280200210a0b200d200a41016a360200200c200a6a200b41807f72200b41ff0071200b410776220a1b3a0000200a210b200a0d000b02400240200441046a280200220b200441086a280200220a6b2007490d002004280200210b0c010b200a20076a220c200a490d05200b410174220a200c200a200c4b1b220a4100480d0502400240200b0d00200a1028210b0c010b2004280200200b200a102c210b0b200b450d022004200b360200200441046a200a360200200441086a280200210a0b200441086a200a20076a360200200b200a6a20022007109a051a02402008450d002002102a0b410021044101210d4101210b4101210c0c120b200641011037000b200a41011037000b20082010460d0003402008410d6a2d00004105460d010240200841046a280200450d002008280200102a0b200841106a22082010470d000b0b0240200e450d00200f102a0b200241086a2106200241046a2107200b210c0240024003400240024020072802002006280200220a460d002002280200210d0c010b200a41016a220d200a490d04200a4101742208200d2008200d4b1b22084100480d0402400240200a0d0020081028210d0c010b2002280200200a2008102c210d0b200d450d022002200d360200200720083602002006280200210a0b2006200a41016a360200200d200a6a200c41807f72200c41ff0071200c410776220a1b3a0000200a210c200a0d000b02400240200241046a280200220c200241086a280200220a6b200b490d002002280200210c0c010b200a200b6a220d200a490d03200c410174220a200d200a200d4b1b220a4100480d0302400240200c0d00200a1028210c0c010b2002280200200c200a102c210c0b200c450d022002200c360200200241046a200a360200200241086a280200210a0b200241086a200a200b6a360200200c200a6a2004200b109a051a4100210c4101210d2005450d032004102a0c030b200841011037000b200a41011037000b1031000b4101210b0c0b0b2000200d3b00012000200a3a0000200041036a200d4110763a0000200041086a2014370000200041046a2004360000410021094101210d4101210c4101210b4101210441012105410121064101210741012102410121080c080b4101210c200241086a200a41016a3602004100210d200b200a6a41003a0000200341146a2004360200200341106a20053602002003200636020c200320073602082003200836020420032009360200200341d0006a2003200210f504200320032900513703382003200341d0006a41086a29000037003f20032d0050220a411f460d082000200a3a000020002003290338370001200041086a200329003f3700000b4101210b0b410121040b410121050b410121060b410121070b410121020b41012108410121090b20012d0000220a410f4b0d18200a0e100a0b0c0d0e0f101112181318141516170a0b4101210b4100210d4101210c0b410121040b410121060b410121050b410121070b410121020b410121120b410121080b410121090b41012113410121110c0f0b200141086a280200450d10200141046a280200102a0c100b200d450d0f0240200141086a280200450d00200141046a280200102a0b200141146a280200450d0f200141106a280200102a0c0f0b02402001410c6a280200220b450d00200141046a280200210a200b410474210b03400240200a41046a280200450d00200a280200102a0b200a41106a210a200b41706a220b0d000b0b200141086a280200450d0e2001280204102a0c0e0b200c450d0d02402001410c6a280200220b450d00200141046a280200210a200b41286c210b03400240200a41046a280200450d00200a280200102a0b0240200a41106a280200450d00200a410c6a280200102a0b200a41286a210a200b41586a220b0d000b0b200141086a280200450d0d2001280204102a0c0d0b200141086a280200450d0c200141046a280200102a0c0c0b200b450d0b200141086a280200450d0b200141046a280200102a0c0b0b2004450d0a200141086a280200450d0a200141046a280200102a0c0a0b2005450d0902402001410c6a280200220a450d00200141046a2802002204200a4104746a2105034002402004280208220b450d002004280200210a200b410474210b03400240200a2d00004109470d000240200a41046a220d280200220c28020441ffffffff0371450d00200c280200102a200d280200210c0b200c102a0b200a41106a210a200b41706a220b0d000b0b200441106a210a0240200441046a280200450d002004280200102a0b200a2104200a2005470d000b0b200141086a280200450d092001280204102a0c090b02402001410c6a280200220b450d00200141046a280200210a200b41146c210b03400240200a41046a280200450d00200a280200102a0b200a41146a210a200b416c6a220b0d000b0b200141086a280200450d082001280204102a0c080b2006450d0702402001410c6a280200220a450d00200141046a2802002204200a411c6c6a2105034002402004280204220a450d0002402004410c6a280200220b450d00200b410474210b03400240200a2d00004109470d000240200a41046a220d280200220c28020441ffffffff0371450d00200c280200102a200d280200210c0b200c102a0b200a41106a210a200b41706a220b0d000b0b200441086a280200450d002004280204102a0b2004411c6a210a0240200441146a280200450d002004280210102a0b200a2104200a2005470d000b0b200141086a280200450d072001280204102a0c070b2007450d0602402001410c6a280200220a450d00200141046a2802002204200a41186c6a210503400240200441046a280200450d002004280200102a0b0240200441146a280200220b450d00200428020c210a200b410474210b03400240200a2d00004109470d000240200a41046a220d280200220c28020441ffffffff0371450d00200c280200102a200d280200210c0b200c102a0b200a41106a210a200b41706a220b0d000b0b200441186a210a0240200441106a280200450d00200428020c102a0b200a2104200a2005470d000b0b200141086a280200450d062001280204102a0c060b2002450d05200141046a220a10f904200141086a280200450d05200a280200102a0c050b2008450d040240200141046a280200220a450d00200141086a280200450d00200a102a0b0240200141146a280200220a450d0002402001411c6a280200220b450d00200b410c6c210b03400240200a280200220c450d00200a41046a280200450d00200c102a0b200a410c6a210a200b41746a220b0d000b0b200141186a280200450d002001280214102a0b200141246a2802002204450d0402402001412c6a280200220a450d002004200a4104746a210503402004220d41106a21040240200d280204220a450d000240200d410c6a280200220b450d00200b410c6c210b03400240200a280200220c450d00200a41046a280200450d00200c102a0b200a410c6a210a200b41746a220b0d000b0b200d41086a280200450d00200d280204102a0b20042005470d000b0b200141286a280200450d042001280224102a0c040b2009450d030240200141086a280200450d00200141046a280200102a0b0240200141146a280200220a450d00200141186a280200450d00200a102a0b200141246a280200450d03200141206a280200102a0c030b20011082040c020b410121100b2000411f3a0000024020012d0000220a410f4b0d0002400240024002400240024002400240024002400240024002400240200a0e100001020304050607080e090e0a0b0c0d000b200b450d0e200141086a280200450d0e200141046a280200102a0c0e0b200d450d0d0240200141086a280200450d00200141046a280200102a0b200141146a280200450d0d200141106a280200102a0c0d0b200c450d0c02402001410c6a280200220b450d00200141046a280200210a200b410474210b03400240200a41046a280200450d00200a280200102a0b200a41106a210a200b41706a220b0d000b0b200141086a280200450d0c2001280204102a0c0c0b2004450d0b02402001410c6a280200220b450d00200141046a280200210a200b41286c210b03400240200a41046a280200450d00200a280200102a0b0240200a41106a280200450d00200a410c6a280200102a0b200a41286a210a200b41586a220b0d000b0b200141086a280200450d0b2001280204102a0c0b0b2006450d0a200141086a280200450d0a200141046a280200102a0c0a0b2005450d09200141086a280200450d09200141046a280200102a0c090b2007450d08200141086a280200450d08200141046a280200102a0c080b2002450d0702402001410c6a280200220a450d00200141046a2802002204200a4104746a2105034002402004280208220b450d002004280200210a200b410474210b03400240200a2d00004109470d000240200a41046a220d280200220c28020441ffffffff0371450d00200c280200102a200d280200210c0b200c102a0b200a41106a210a200b41706a220b0d000b0b200441106a210a0240200441046a280200450d002004280200102a0b200a2104200a2005470d000b0b200141086a280200450d072001280204102a0c070b2012450d0602402001410c6a280200220b450d00200141046a280200210a200b41146c210b03400240200a41046a280200450d00200a280200102a0b200a41146a210a200b416c6a220b0d000b0b200141086a280200450d062001280204102a0c060b2008450d0502402001410c6a280200220a450d00200141046a2802002204200a411c6c6a2105034002402004280204220a450d0002402004410c6a280200220b450d00200b410474210b03400240200a2d00004109470d000240200a41046a220d280200220c28020441ffffffff0371450d00200c280200102a200d280200210c0b200c102a0b200a41106a210a200b41706a220b0d000b0b200441086a280200450d002004280204102a0b2004411c6a210a0240200441146a280200450d002004280210102a0b200a2104200a2005470d000b0b200141086a280200450d052001280204102a0c050b2009450d0402402001410c6a280200220a450d00200141046a2802002204200a41186c6a210503400240200441046a280200450d002004280200102a0b0240200441146a280200220b450d00200428020c210a200b410474210b03400240200a2d00004109470d000240200a41046a220d280200220c28020441ffffffff0371450d00200c280200102a200d280200210c0b200c102a0b200a41106a210a200b41706a220b0d000b0b200441186a210a0240200441106a280200450d00200428020c102a0b200a2104200a2005470d000b0b200141086a280200450d042001280204102a0c040b2013450d03200141046a220a10f904200141086a280200450d03200a280200102a0c030b2011450d020240200141046a280200220a450d00200141086a280200450d00200a102a0b0240200141146a280200220a450d0002402001411c6a280200220b450d00200b410c6c210b03400240200a280200220c450d00200a41046a280200450d00200c102a0b200a410c6a210a200b41746a220b0d000b0b200141186a280200450d002001280214102a0b200141246a2802002204450d0202402001412c6a280200220a450d002004200a4104746a210503402004220d41106a21040240200d280204220a450d000240200d410c6a280200220b450d00200b410c6c210b03400240200a280200220c450d00200a41046a280200450d00200c102a0b200a410c6a210a200b41746a220b0d000b0b200d41086a280200450d00200d280204102a0b20042005470d000b0b200141286a280200450d022001280224102a0c020b2010450d010240200141086a280200450d00200141046a280200102a0b0240200141146a280200220a450d00200141186a280200450d00200a102a0b200141246a280200450d01200141206a280200102a0c010b20011082040b200341e0006a24000bb309010a7f230041b0016b2202240041002103024020012802102204450d0020012802082205200128020c460d00200128021421062001200541246a360208200241c4006a41026a2207200541036a2d00003a0000200241286a41086a2208200541106a290000370300200241286a41106a2209200541186a290000370300200241286a41186a220a200541206a280000360200200220052f00013b01442002200541086a29000037032820052d0000220b4102460d00200541046a280000210520012004417f6a360210200241086a41026a20072d00003a000020024190016a41086a200829030037030020024190016a41106a200929030037030020024190016a41186a200a280200360200200220022f01443b01082002200229032837039001024002400240200b4101460d002002418c016a41026a200241086a41026a2d00003a0000200241f0006a41086a20024190016a41086a290300370300200241f0006a41106a20024190016a41106a290300370300200241f0006a41186a20024190016a41186a2d00003a0000200220022f01083b018c0120022002290390013703700c010b200241c8006a200541067610fe01200228024821040240024020022802502005413f7122014b0d00410021010c010b2002418c016a41026a200420014105746a220141026a2d00003a0000200241f8006a2001410f6a29000037030020024180016a200141176a29000037030020024188016a2001411f6a2d00003a0000200220012f00003b018c012002200129000737037020012800032105410121010b0240200228024c450d002004102a0b20010d00410121010c010b200241ec006a41026a2002418c016a41026a2d00003a000020024190016a41086a200241f0006a41086a29030037030020024190016a41106a200241f0006a41106a29030037030020024190016a41186a200241f0006a41186a2d00003a0000200220022f018c013b016c2002200229037037039001410021010b200241e8006a41026a2204200241ec006a41026a2d00003a0000200241c8006a41086a220720024190016a41086a290300370300200241c8006a41106a220820024190016a41106a290300370300200241c8006a41186a220920024190016a41186a2d00003a0000200220022f016c3b016820022002290390013703480240024020010d002002418c016a41026a20042d00003a0000200241f0006a41086a2007290300370300200241f0006a41106a2008290300370300200241f0006a41186a20092d00003a0000200220022f01683b018c0120022002290348370370410121010c010b200641013a0000410021010b200241246a41026a22042002418c016a41026a2d00003a0000200241086a41086a2207200241f0006a41086a290300370300200241086a41106a2208200241f0006a41106a290300370300200241086a41186a2209200241f0006a41186a2d00003a0000200220022f018c013b0124200220022903703703082001450d00200020022f01243b0001200041046a2005360000200041086a2002290308370000200041036a20042d00003a0000200041106a2007290300370000200041186a2008290300370000200041206a20092d00003a0000410121030b200020033a0000200241b0016a24000bd50505067f017e047f017e027f23004180026b22022400024002400240024002402000280200220320002802044f0d00200028020c2104200141086a2105200241a0016a4102722106024003402000200341016a360200200241186a20002802082802002207109b0220022d00184101460d0120022900192108200241086a2007106c20022802080d012007280204200228020c2203490d012003417f4c0d0302400240024020030d00410121090c010b2003102e2209450d0820072802042003490d01200920072802002003109a051a2007280204220a2003490d062007200a20036b3602042007200728020020036a3602000b20022008370310024002402001280200220b41f8b9c000460d002001280204210c0c010b2006410041da001099051a200241186a41004184011099051a41e4011028220b450d074100210c200b4100360200200b41046a200241a0016a41dc00109a051a200b41e0006a200241186a418401109a051a200141003602042001200b3602000b2003ad220d422086200d84210d024002400340200b41086a2107200b2f0106220e41037421034100210a024003402003450d01200241106a20074108109c05220f450d03200341786a2103200a41016a210a200741086a2107200f417f4a0d000b200a417f6a210e0b0240200c450d00200c417f6a210c200b200e4102746a41e4016a280200210b0c010b0b2002200837022c200220053602282002200e360224200220013602202002200b36021c200241003602182002200d3702a401200220093602a001200241186a200241a0016a10bb020c010b200b200a410c6c6a220341e4006a2207280200210a2007200d370200200341e0006a22072802002103200720093602002003450d00200a450d002003102a0b200028020022032000280204490d010c030b0b2009102a0b200441013a00000b20024180026a24000f0b1036000b2003200a1044000b41e40141041037000b200341011037000bfd0e03047f027e087f230041206b2202240002400240024002400240024002400240024002400240024002400240024041a20210282203450d00200241a20236020420022003360200200341003b0000200241023602080240024020012903684202520d00024020022802044102470d00200228020041024104102c2203450d0420024104360204200220033602000b200228020041033a00022002200228020841016a3602080c010b024020022802044102470d00200228020041024104102c2203450d0420024104360204200220033602000b20022802004183013a00022002200228020841016a3602082001200210a60120022002360210200141246a200241106a10fa020240024020012903684201510d0002400240200228020420022802082203460d00200228020021040c010b200341016a22042003490d12200341017422052004200520044b1b22054100480d120240024020030d002005102821040c010b200228020020032005102c21040b2004450d072002200536020420022004360200200228020821030b2002200341016a360208200420036a41003a00000c010b200141f8006a29030020012903702206420c882207420120074201561b8021070240024020022802042204200228020822036b4102490d00200228020021040c010b200341026a22052003490d11200441017422032005200320054b1b22034100480d110240024020040d002003102821040c010b200228020020042003102c21040b2004450d072002200336020420022004360200200228020821030b2002200341026a360208200420036a2007a741047420067aa7417f6a22034101200341014b1b2203410f2003410f491b723b00000b20014190016a200210a001200220014180016a360210200241106a200210a3010b20014198016a200210eb012002280208210120024100360218200242013703102001417e6a200241106a10b4012002280208220341014d0d052002280218210520022802142108200228021021092002410036020820022802002101024002402003417e6a220a450d004102210b2005450d0d200120092d00003a00004101210c2002200228020841016a36020820054101460d0d200920056a210d200120092d00013a00012002200228020841016a3602084102210b200941026a21042005417e6a220e0d014100210e0c0b0b0240024002402002280204220320054f0d00200341017422042005200420054b1b22044100480d120240024020030d002004102821010c010b200120032004102c21010b2001450d0a20022004360204200220013602002002280208210b0c010b4100210b2005450d010b2001200b6a220320092d00003a0000024020054101470d00200b41016a210b0c010b2005417f6a2104200941016a2101200341016a21030340200320012d00003a0000200341016a2103200141016a21012004417f6a22040d000b200b20056a210b0b2002200b3602084102210b0c0b0b024002402002280204220120036b200e490d00200228020021010c010b2003200e6a220b2003490d0f20014101742203200b2003200b4b1b22034100480d0f0240024020010d002003102821010c010b200228020020012003102c21010b2001450d0820022003360204200220013602000b200120056a200141026a200a109b051a0240200520022802082201460d00200520016b210b2005417e6a2103200228020020016a210c410021010340024020032001470d002005210b0c0d0b200c20016a20042d00003a00002002200228020841016a360208200441016a2104200b200141016a2201470d000b200d20046b220e0d004100210e4101210c0c090b200e4100480d0e200e1028220c0d08200e41011037000b41a20241011037000b410441011037000b410441011037000b200541011037000b200341011037000b41e4e8c5001032000b200441011037000b200341011037000b2005210b0b0240200d2004460d00200c20042d00003a00004101210f02400240200441016a2201200d470d00200c41016a21050c010b200c41016a21032009200520046b6a21040340200320012d00003a0000200341016a2103200d200141016a2201470d000b2004450d01200c20046a21052004210f0b0240024020022802042201200a200b6a22036b200f490d00200228020021010c010b2003200f6a22042003490d06200141017422032004200320044b1b22034100480d060240024020010d002003102821010c010b200228020020012003102c21010b2001450d0520022003360204200220013602000b2001200b200f6a220d6a2001200b6a200a109b051a0240200d20022802082201460d00200228020020016a2103200b200f6a20016b2104200c2101034020052001460d01200320012d00003a00002002200228020841016a360208200141016a2101200341016a21032004417f6a22040d000b0b200d210b0b200e450d00200c102a0b200a450d010b0240200b20022802082201460d002002280200220320016a2003200b6a200a109b051a0b2002200a20016a3602080b02402008450d002009102a0b20002002290300370200200041086a200241086a280200360200200241206a24000f0b200341011037000b1031000b130020004103360204200041889fc4003602000b340020004196a6c40036020420004100360200200041146a4101360200200041106a419ca6c400360200200041086a42043702000b4001017f230041206b22022400200241186a4200370300200241106a4200370300200241086a42003703002002420037030020002002108b04200241206a24000bde0301017f024002400240024002400240410110282202450d00200220012d00003a0000200241014102102c2202450d01200220012d00013a0001200241024104102c2202450d02200220012d00023a0002200220012d00033a0003200241044108102c2202450d03200220012d00043a0004200220012d00053a0005200220012d00063a0006200220012d00073a0007200241084110102c2202450d04200220012d00083a0008200220012d00093a0009200220012d000a3a000a200220012d000b3a000b200220012d000c3a000c200220012d000d3a000d200220012d000e3a000e200220012d000f3a000f200241104120102c2202450d05200220012d00103a0010200220012d00113a0011200220012d00123a0012200220012d00133a0013200220012d00143a0014200220012d00153a0015200220012d00163a0016200220012d00173a0017200220012d00183a0018200220012d00193a0019200220012d001a3a001a200220012d001b3a001b200220012d001c3a001c200220012d001d3a001d200220012d001e3a001e200220012d001f3a001f200042a08080808004370204200020023602000f0b410141011037000b410241011037000b410441011037000b410841011037000b411041011037000b412041011037000bb31102077f027e230041106b2202240020024100360208200242013703004104200210b4010240024002400240024002400240024002400240024002400240024002400240024020022802042203200228020822046b4104490d00200441046a2105200228020021030c010b200441046a22052004490d0f200341017422062005200620054b1b22064100480d0f0240024020030d002006102821030c010b200228020020032006102c21030b2003450d0120022006360204200220033602000b20022005360208200320046a41eede91ab06360000410e200210b4010240024020022802042203200228020822066b410e490d002006410e6a2104200228020021050c010b2006410e6a22042006490d0f200341017422052004200520044b1b22074100480d0f0240024020030d002007102821050c010b200228020020032007102c21050b2005450d022002200736020420022005360200200721030b20022004360208200520066a220641002900e4c740370000200641066a41002900eac7403700000240200320046b41034b0d00200441046a22062004490d0f200341017422072006200720064b1b22064100480d0f0240024020030d002006102821050c010b200520032006102c21050b2005450d0320022006360204200220053602000b2002200441046a360208200520046a410a3600000240024020022802042205200228020822046b4104490d00200228020021050c010b200441046a22032004490d0f200541017422062003200620034b1b22034100480d0f0240024020050d002003102821050c010b200228020020052003102c21050b2005450d0420022003360204200220053602000b2002200441046a360208200520046a41a3013600000240024020022802042205200228020822046b4104490d00200228020021050c010b200441046a22032004490d0f200541017422062003200620034b1b22034100480d0f0240024020050d002003102821050c010b200228020020052003102c21050b2005450d0520022003360204200220053602000b2002200441046a360208200520046a41a301360000410b200210b40141f4c7c0002104034002400240200228020420022802082205460d00200228020021030c010b200541016a22032005490d10200541017422062003200620034b1b22064100480d100240024020050d002006102821030c010b200228020020052006102c21030b2003450d0720022006360204200220033602000b2002200541016a360208200320056a20042d00003a000002400240200228020420022802082205460d00200228020021030c010b200541016a22032005490d10200541017422062003200620034b1b22064100480d100240024020050d002006102821030c010b200228020020052006102c21030b2003450d0820022006360204200220033602000b2002200541016a360208200320056a200441016a2d00003a000002400240200228020420022802082205460d00200228020021030c010b200541016a22032005490d10200541017422062003200620034b1b22064100480d100240024020050d002006102821030c010b200228020020052006102c21030b2003450d0920022006360204200220033602000b2002200541016a360208200320056a200441026a2d00003a000002400240200228020420022802082205460d00200228020021030c010b200541016a22032005490d10200541017422062003200620034b1b22064100480d100240024020050d002006102821030c010b200228020020052006102c21030b2003450d0a20022006360204200220033602000b2002200541016a360208200320056a200441036a2d00003a000002400240200228020420022802082205460d00200228020021030c010b200541016a22032005490d10200541017422062003200620034b1b22064100480d100240024020050d002006102821030c010b200228020020052006102c21030b2003450d0b20022006360204200220033602000b2002200541016a360208200320056a200441046a2d00003a000002400240200228020420022802082205460d00200228020021030c010b200541016a22032005490d10200541017422062003200620034b1b22064100480d100240024020050d002006102821030c010b200228020020052006102c21030b2003450d0c20022006360204200220033602000b2002200541016a360208200320056a200441056a2d00003a000002400240200228020420022802082205460d00200228020021030c010b200541016a22032005490d10200541017422062003200620034b1b22064100480d100240024020050d002006102821030c010b200228020020052006102c21030b2003450d0d20022006360204200220033602000b2002200541016a360208200320056a200441066a2d00003a000002400240200228020420022802082205460d00200228020021030c010b200541016a22032005490d10200541017422062003200620034b1b22064100480d100240024020050d002006102821030c010b200228020020052006102c21030b2003450d0e20022006360204200220033602000b2002200541016a360208200320056a200441076a2d00003a0000200441086a28020021060240024020022802042203200228020822056b4104490d00200228020021030c010b200541046a22072005490d10200341017422082007200820074b1b22074100480d100240024020030d002007102821030c010b200228020020032007102c21030b2003450d0f20022007360204200220033602000b2002200541046a360208200320056a20063600002004410c6a220441f8c8c000470d000b200235020821092002350200210a200241106a2400200a2009422086840f0b200641011037000b200741011037000b200641011037000b200341011037000b200341011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200741011037000b1031000b961b04057f017e037f017e230041800a6b22022400024002402001450d00200220003602180c010b200241013602180b2002200136021c200241e0076a200241186a107f024020022802e4072203450d00200241e0076a410c6a280200210120022802e807210420022802e0072100200241b0046a200241e0076a41106a41e000109a051a200241e0076a200241186a1079024020022802e007450d0020024180036a41086a2205200241e0076a41086a280200360200200220022903e00737038003200241e0076a200241b0046a41e000109a051a200241306a200241e0076a41e000109a051a200241206a41086a22062005280200360200200220022903800337032020024190016a410c6a200136020020024190016a41086a20043602002002200336029401200220003602900120024190016a41106a200241306a41e000109a05210120024188026a2006280200360200200220022903203703800220024190016a10c703024002402002280290012200450d00200241e0076a2000417f6a10f701200241e0076a20014120109c050d000240024020024188026a28020022030d004100210341042104410021010c010b024002402003ad420c7e2207422088a70d002007a722014100480d0020022802800221002001102822040d01200141041037000b1031000b200341a0026c210520034105742106200421010340200241e0076a2000108704200141086a200241e0076a41086a280200360200200120022903e0073702002001410c6a2101200041a0026a2100200541e07d6a22050d000b200641606a41057641016a21010b200220013602b804200220033602b404200220043602b004200241e0076a200241b0046a108e040240200241e0016a2201200241e0076a4120109c05450d004190fac500410e100b200141201019200241e0076a412010190b02402001200241e0076a4120109c050d0020024184026a28020021082002280280022109200228028802210520024190026a20024190016a41f000109a051a2009200541a0026c6a2100200228029002210a20092101024002402005450d00200241b0046a41f0006a21042009210102400340200241f8066a200141e800109a051a200141e8006a290300210720024180036a200141f0006a41b001109a051a20074203510d01200241b0046a200241f8066a41e800109a051a2002200737039805200420024180036a41b001109a051a200241e0076a200241b0046a10870420022802e8072105024020022802e407450d0020022802e007102a0b200241e0076a200241b0046a41a002109a051a200241003602e006200241d0066a200241e0076a2005200241e0066a10d00320022d00d0064101460d03024020022d00dc0622054102460d0020023100de06210720023100dd06210b20022802d806210620022802d406210341f19ec600410d100b02402005450d00200b100c0b2007100c2003450d0020032006100b0b200141a0026a22012000470d000b200021010c010b200141a0026a21010b20012000460d03200241f8086a2105200241e0076a41f0006a2103034020024180036a200141e800109a051a200141e8006a2903002107200241e0076a200141f0006a41b001109a051a20074203510d04200241f8066a20024180036a41e800109a051a200241b0046a200241e0076a41b001109a051a200241e0076a200241f8066a41e800109a051a200220073703c8082003200241b0046a41b001109a051a2005106a200141a0026a22012000470d000c040b0b200241106a20022f00d10620022d00d3064110747210d30320022903102107200241ec076a42c4808080d01b370200200241323602f407200241b8b9c3003602e807200220073703e007200241e0076a1032000b41a0b9c3001032000b4188b9c3001032000b02402008450d002009102a0b200241086a10e403200228020c210120022802082100200241e0076a41086a22054200370300200242003703e00741f99fc6004115200241e0076a1008200241b0046a41086a2005290300370300200220022903e0073703b00420022001410020001b3602e007200241b0046a4110200241e0076a41041007200a109e03200241e0076a10b203200220024190026a410c6a28020022033602f00620022802940221062002200241e0076a410c6a28020022013602f406024020032001470d0002402003450d0020022802e407210941002105034002400240024002400240024002400240200620056a22012d00002204200920056a22002d0000470d000240024002400240024020040e050001020304000b20012000460d09200141016a200041016a4120109c050d040c090b024020012000460d00200141016a280000200041016a280000470d040b200141106a2802002204200041106a280200470d03200141086a2802002208200041086a280200220a460d072008200a2004109c050d030c070b024020012000460d00200141016a280000200041016a280000470d030b200141106a2802002204200041106a280200470d02200141086a2802002208200041086a280200220a460d052008200a2004109c050d020c050b024020012000460d00200141016a280000200041016a280000470d020b200141106a2802002204200041106a280200470d01200141086a2802002208200041086a280200220a460d032008200a2004109c050d010c030b2001410c6a28020022042000410c6a280200470d00200141046a2802002208200041046a280200220a460d012008200a2004109c05450d010b41df86c2004114100b200241b0046a200110ec0120022802b004220420022802b8041019024020022802b404450d002004102a0b200241b0046a200010ec0120022802b004220420022802b8041019024020022802b404450d002004102a0b20012d000020002d00002204470d0520040e050403020100040b2001410c6a28020022042000410c6a280200470d04200141046a2802002201200041046a2802002200460d05200120002004109c050d040c050b024020012000460d00200141016a280000200041016a280000470d040b200141106a2802002204200041106a280200470d03200141086a2802002201200041086a2802002200460d04200120002004109c05450d040c030b024020012000460d00200141016a280000200041016a280000470d030b200141106a2802002204200041106a280200470d02200141086a2802002201200041086a2802002200460d03200120002004109c050d020c030b024020012000460d00200141016a280000200041016a280000470d020b200141106a2802002204200041106a280200470d01200141086a2802002201200041086a2802002200460d02200120002004109c050d010c020b20012000460d01200141016a200041016a4120109c05450d010b4194bac3001032000b200541246a21052003417f6a22030d000b0b024020024190026a41306a2201200241e0076a41306a22004120109c05450d004190fac500410e100b2001412010192000412010190b0240200120004120109c05450d0041acbac3001032000b024020022802ec072200450d0020022802e4072101200041246c210003400240024020012d0000220541034b0d0002400240024020050e0404000102040b2001410c6a280200450d03200141086a280200102a0c030b2001410c6a280200450d02200141086a280200102a0c020b2001410c6a280200450d01200141086a280200102a0c010b200141086a280200450d00200141046a280200102a0b200141246a21012000415c6a22000d000b0b0240200241e8076a280200450d0020022802e407102a0b0240200228029c022200450d002002280294022101200041246c210003400240024020012d0000220541034b0d0002400240024020050e0404000102040b2001410c6a280200450d03200141086a280200102a0c030b2001410c6a280200450d02200141086a280200102a0c020b2001410c6a280200450d01200141086a280200102a0c010b200141086a280200450d00200141046a280200102a0b200141246a21012000415c6a22000d000b0b024020024198026a280200450d00200228029402102a0b200241800a6a240042010f0b20024180036a41146a410836020020024180036a410c6a4125360200200241f8066a41146a4103360200200242033702fc06200241c8afc6003602f80620024125360284032002200241f0066a3602e0062002200241f4066a3602d006200242043703c004200242013702b404200241fcb9c3003602b004200220024180036a360288072002200241b0046a360290032002200241d0066a360288032002200241e0066a36028003200241f8066a4184bac300103e000b02402001450d00200141246c21002003210103400240024020012d0000220541034b0d0002400240024020050e0404000102040b2001410c6a280200450d03200141086a280200102a0c030b2001410c6a280200450d02200141086a280200102a0c020b2001410c6a280200450d01200141086a280200102a0c010b200141086a280200450d00200141046a280200102a0b200141246a21012000415c6a22000d000b0b2004450d002003102a0b200241f4076a4102360200200241bc046a4104360200200242023702e407200241bca7c4003602e007200241043602b404200241b4a7c4003602b0042002410036028403200241b8aec600360280032002200241b0046a3602f007200220024180036a3602b804200241e0076a41cca7c400103e000b8d05030b7f017e037f230041206b220224002001280200220320012802082204410c6c6a21052001280204210602400240024020040d00410421074100210841012109410021014100210a200321040c010b41012109410021084100210441042107410021014100210a2003210b0240024003400240200b280200220c0d00200b410c6a21040c040b024002400240200820046b200b41046a290200220d422088a7220e490d002004200e6a210f0c010b2004200e6a220f2004490d0420084101742210200f2010200f4b1b22104100480d040240024020080d002010102821090c010b200920082010102c21090b2009450d01201021080b200920046a200c200e109a051a02400240200a2001460d0020012110200a21010c010b200141016a22042001490d04200141017422102004201020044b1b221041ffffffff03712010470d04201041027422044100480d040240024020010d002004102821070c010b200720014102742004102c21070b2007450d030b200720014102746a200e3602000240200da7450d00200c102a0b200a41016a210a200f210420102101200b410c6a220b2005470d010c050b0b201041011037000b200441041037000b1031000b024020042005460d0003402004280200220b450d010240200441046a280200450d00200b102a0b2004410c6a22042005470d000b0b200121100b02402006450d002003102a0b200241186a22014200370300200241106a22044200370300200241086a220b42003703002002420037030020092007200a20021023200041186a2001290300370000200041106a2004290300370000200041086a200b2903003700002000200229030037000002402010450d002007102a0b02402008450d002009102a0b200241206a24000ba10301027f23004180026b22022400024002402001450d00200220003602000c010b200241013602000b20022001360204200241f8006a2002107f0240200228027c450d00200241086a200241f8006a41f000109a051a200241086a10c7030240200241086a410c6a2802002200450d00200228020c2101200041246c210003400240024020012d0000220341034b0d0002400240024020030e0404000102040b2001410c6a280200450d03200141086a280200102a0c030b2001410c6a280200450d02200141086a280200102a0c020b2001410c6a280200450d01200141086a280200102a0c010b200141086a280200450d00200141046a280200102a0b200141246a21012000415c6a22000d000b0b0240200241106a280200450d00200228020c102a0b20024180026a240042010f0b200241f4016a41043602002002411c6a41023602002002420237020c200241bca7c400360208200241043602ec01200241c8a8c4003602e801200241003602fc01200241b8aec6003602f8012002200241e8016a3602182002200241f8016a3602f001200241086a41cca7c400103e000be328010b7f230041d0006b220224002002410036022820024201370320024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240410410282203450d0020024284808080c00037022420022003360220200341edcad18b0636000002400240200228022420022802282203460d00200228022021040c010b200341016a22042003490d1b200341017422052004200520044b1b22054100480d1b0240024020030d002005102821040c010b200228022020032005102c21040b2004450d0220022005360224200220043602200b2002200341016a360228200420036a41073a00004115200241206a10b40141accbc000210603402006280204210720062802082203200241206a10b4010240024020022802242205200228022822046b2003490d00200228022021050c010b200420036a22082004490d1c200541017422042008200420084b1b22044100480d1c0240024020050d002004102821050c010b200228022020052004102c21050b2005450d042002200436022420022005360220200228022821040b2002200420036a360228200520046a20072003109a051a200228022421042002280228210302400240200628020c4102470d000240024020042003460d00200228022021040c010b200341016a22042003490d1e200341017422052004200520044b1b22054100480d1e0240024020030d002005102821040c010b200228022020032005102c21040b2004450d072002200536022420022004360220200228022821030b2002200341016a360228200420036a41003a00000c010b0240024020042003460d00200228022021040c010b200341016a22042003490d1d200341017422052004200520044b1b22054100480d1d0240024020030d002005102821040c010b200228022020032005102c21040b2004450d072002200536022420022004360220200228022821030b2002200341016a360228200420036a41013a00000240200628020c4101460d00200241306a20062802101103002002280234210720022802382203200241206a10b4010240024020022802242205200228022822046b2003490d00200228022021050c010b200420036a22082004490d1e200541017422042008200420084b1b22044100480d1e0240024020050d002004102821050c010b200228022020052004102c21050b2005450d092002200436022420022005360220200228022821040b2002200420036a360228200520046a20072003109a051a200228024021050240200228023c4101460d0020052002280244200241206a1091040c020b200520022802482203200241206a10910402402003450d00200341d8006c21074100210403400240200520046a220341346a280200450d002003413c6a280200450d00200341386a280200102a0b0240200341c4006a280200450d00200341cc006a280200450d00200341c8006a280200102a0b2007200441d8006a2204470d000b0b2002280244450d012005102a0c010b2006280214210720062802182203200241206a10b4010240024020022802242205200228022822046b2003490d00200228022021050c010b200420036a22082004490d1d200541017422042008200420084b1b22044100480d1d0240024020050d002004102821050c010b200228022020052004102c21050b2005450d092002200436022420022005360220200228022821040b2002200420036a360228200520046a20072003109a051a200628022021030240200628021c4101460d002003200641246a280200200241206a1091040c010b20032006280228200241206a1091040b200228022421042002280228210302400240200628022c4102470d000240024020042003460d00200228022021040c010b200341016a22042003490d1e200341017422052004200520044b1b22054100480d1e0240024020030d002005102821040c010b200228022020032005102c21040b2004450d0b2002200536022420022004360220200228022821030b2002200341016a360228200420036a41003a00000c010b0240024020042003460d00200228022021040c010b200341016a22042003490d1d200341017422052004200520044b1b22054100480d1d0240024020030d002005102821040c010b200228022020032005102c21040b2004450d0b2002200536022420022004360220200228022821030b2002200341016a360228200420036a41013a00000240200628022c4101460d00200241186a200628023011030020022802182104200228021c2203200241206a10b4012003450d012003412c6c21082004411c6a21030340200341686a28020021092003416c6a2802002204200241206a10b4010240024020022802242207200228022822056b2004490d00200228022021070c010b200520046a220a2005490d1f20074101742205200a2005200a4b1b22054100480d1f0240024020070d002005102821070c010b200228022020072005102c21070b2007450d0e2002200536022420022007360220200228022821050b2002200520046a360228200720056a20092004109a051a200341706a200241206a1092042003200241206a1093042003412c6a2103200841546a22080d000c020b0b2006280230210420062802382203200241206a10b4012003450d002003412c6c21082004411c6a21030340200341686a28020021092003416c6a2802002204200241206a10b4010240024020022802242207200228022822056b2004490d00200228022021070c010b200520046a220a2005490d1e20074101742205200a2005200a4b1b22054100480d1e0240024020070d002005102821070c010b200228022020072005102c21070b2007450d0e2002200536022420022007360220200228022821050b2002200520046a360228200720056a20092004109a051a200341706a200241206a1092042003200241206a1093042003412c6a2103200841546a22080d000b0b200228022421042002280228210302400240200628023c4102470d000240024020042003460d00200228022021040c010b200341016a22042003490d1e200341017422052004200520044b1b22054100480d1e0240024020030d002005102821040c010b200228022020032005102c21040b2004450d0f2002200536022420022004360220200228022821030b2002200341016a360228200420036a41003a00000c010b0240024020042003460d00200228022021040c010b200341016a22042003490d1d200341017422052004200520044b1b22054100480d1d0240024020030d002005102821040c010b200228022020032005102c21040b2004450d0f2002200536022420022004360220200228022821030b2002200341016a360228200420036a41013a00000240200628023c4101460d00200241106a20062802401103002002280210210420022802142203200241206a10b4012003450d012003412c6c21082004411c6a21030340200341686a28020021092003416c6a2802002204200241206a10b4010240024020022802242207200228022822056b2004490d00200228022021070c010b200520046a220a2005490d1f20074101742205200a2005200a4b1b22054100480d1f0240024020070d002005102821070c010b200228022020072005102c21070b2007450d122002200536022420022007360220200228022821050b2002200520046a360228200720056a20092004109a051a200341706a200241206a1093042003200241206a1093042003412c6a2103200841546a22080d000c020b0b2006280240210420062802482203200241206a10b4012003450d002003412c6c21082004411c6a21030340200341686a28020021092003416c6a2802002204200241206a10b4010240024020022802242207200228022822056b2004490d00200228022021070c010b200520046a220a2005490d1e20074101742205200a2005200a4b1b22054100480d1e0240024020070d002005102821070c010b200228022020072005102c21070b2007450d122002200536022420022007360220200228022821050b2002200520046a360228200720056a20092004109a051a200341706a200241206a1093042003200241206a1093042003412c6a2103200841546a22080d000b0b02400240200628024c4101460d00200241086a20062802501103002002280208210b200228020c2203200241206a10b4012003450d01200341386c210c410021070340200b20076a220341046a2802002109200341086a2802002204200241206a10b4010240024020022802242208200228022822056b2004490d00200228022021080c010b200520046a220a2005490d1f20084101742205200a2005200a4b1b22054100480d1f0240024020080d002005102821080c010b200228022020082005102c21080b2008450d142002200536022420022008360220200228022821050b2002200520046a360228200820056a20092004109a051a200341106a2802002109200341146a2802002204200241206a10b4010240024020022802242208200228022822056b2004490d00200228022021080c010b200520046a220a2005490d1f20084101742205200a2005200a4b1b22054100480d1f0240024020080d002005102821080c010b200228022020082005102c21080b2008450d152002200536022420022008360220200228022821050b2002200520046a360228200820056a20092004109a051a02400240200341186a2802004101460d00200241306a2003411c6a280200200341206a28020028020c1102002002280230210920022802382204200241206a10b4010240024020022802242208200228022822056b2004490d00200228022021080c010b200520046a220a2005490d2120084101742205200a2005200a4b1b22054100480d210240024020080d002005102821080c010b200228022020082005102c21080b2008450d182002200536022420022008360220200228022821050b2002200520046a360228200820056a20092004109a051a2002280234450d012009102a0c010b2003411c6a2802002109200341246a2802002204200241206a10b4010240024020022802242208200228022822056b2004490d00200228022021080c010b200520046a220a2005490d2020084101742205200a2005200a4b1b22054100480d200240024020080d002005102821080c010b200228022020082005102c21080b2008450d182002200536022420022008360220200228022821050b2002200520046a360228200820056a20092004109a051a0b200341286a200241206a109304200c200741386a2207470d000c020b0b2006280250210b20062802582203200241206a10b4012003450d00200341386c210c410021070340200b20076a220341046a2802002109200341086a2802002204200241206a10b4010240024020022802242208200228022822056b2004490d00200228022021080c010b200520046a220a2005490d1e20084101742205200a2005200a4b1b22054100480d1e0240024020080d002005102821080c010b200228022020082005102c21080b2008450d172002200536022420022008360220200228022821050b2002200520046a360228200820056a20092004109a051a200341106a2802002109200341146a2802002204200241206a10b4010240024020022802242208200228022822056b2004490d00200228022021080c010b200520046a220a2005490d1e20084101742205200a2005200a4b1b22054100480d1e0240024020080d002005102821080c010b200228022020082005102c21080b2008450d182002200536022420022008360220200228022821050b2002200520046a360228200820056a20092004109a051a02400240200341186a2802004101460d00200241306a2003411c6a280200200341206a28020028020c1102002002280230210920022802382204200241206a10b4010240024020022802242208200228022822056b2004490d00200228022021080c010b200520046a220a2005490d2020084101742205200a2005200a4b1b22054100480d200240024020080d002005102821080c010b200228022020082005102c21080b2008450d1b2002200536022420022008360220200228022821050b2002200520046a360228200820056a20092004109a051a2002280234450d012009102a0c010b2003411c6a2802002109200341246a2802002204200241206a10b4010240024020022802242208200228022822056b2004490d00200228022021080c010b200520046a220a2005490d1f20084101742205200a2005200a4b1b22054100480d1f0240024020080d002005102821080c010b200228022020082005102c21080b2008450d1b2002200536022420022008360220200228022821050b2002200520046a360228200820056a20092004109a051a0b200341286a200241206a109304200c200741386a2207470d000b0b200641dc006a220641b8dac000470d000b2002280228220341046a2204417f4c0d1720022802242108200228022021070240024020040d00410121050c010b200410282205450d190b2002410036023820022004360234200220053602302003200241306a10b4010240024020022802342205200228023822046b2003490d00200228023021050c010b200420036a22092004490d1b2005410174220a2009200a20094b1b22094100480d1b0240024020050d002009102821050c010b200228023020052009102c21050b2005450d1a20022009360234200220053602300b200520046a20072003109a051a200420036a210302402008450d002007102a0b200241d0006a24002003ad4220862005ad840f0b410441011037000b200541011037000b200441011037000b200541011037000b200541011037000b200441011037000b200441011037000b200541011037000b200541011037000b200541011037000b200541011037000b200541011037000b200541011037000b200541011037000b200541011037000b200541011037000b200541011037000b200541011037000b200541011037000b200541011037000b200541011037000b200541011037000b200541011037000b1036000b200441011037000b200941011037000b1031000b9c1d010a7f230041106b220324002001200210b401024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002402001450d00200141d8006c2104410021050340200020056a220641046a2802002107200641086a2802002208200210b40102400240200241046a2209280200220a200241086a2201280200220b6b2008490d002002280200210a0c010b200b20086a220c200b490d18200a410174220b200c200b200c4b1b220b4100480d1802400240200a0d00200b1028210a0c010b2002280200200a200b102c210a0b200a450d032002200a3602002009200b3602002001280200210b0b2001200b20086a360200200a200b6a20072008109a051a200641d4006a2d0000210a02400240200928020020012802002208460d002002280200210b0c010b200841016a220b2008490d1820084101742207200b2007200b4b1b22074100480d180240024020080d0020071028210b0c010b200228020020082007102c210b0b200b450d042002200b36020020092007360200200128020021080b2001200841016a360200200b20086a200a3a000002402006410c6a2d0000220841024b0d0002400240024020080e03000102000b02400240200928020020012802002208460d002002280200210b0c010b200841016a220b2008490d1b2008410174220a200b200a200b4b1b220a4100480d1b0240024020080d00200a1028210b0c010b20022802002008200a102c210b0b200b450d082002200b3602002009200a360200200128020021080b2001200841016a360200200b20086a41003a0000200641146a2802002107200641186a2802002208200210b401024002402009280200220a2001280200220b6b2008490d002002280200210a0c010b200b20086a220c200b490d1b200a410174220b200c200b200c4b1b220b4100480d1b02400240200a0d00200b1028210a0c010b2002280200200a200b102c210a0b200a450d092002200a3602002009200b3602002001280200210b0b2001200b20086a360200200a200b6a20072008109a051a0c020b02400240200928020020012802002208460d002002280200210b0c010b200841016a220b2008490d1a2008410174220a200b200a200b4b1b220a4100480d1a0240024020080d00200a1028210b0c010b20022802002008200a102c210b0b200b450d092002200b3602002009200a360200200128020021080b2001200841016a360200200b20086a41013a00002006410d6a2d0000210a02400240200928020020012802002208460d002002280200210b0c010b200841016a220b2008490d1a20084101742207200b2007200b4b1b22074100480d1a0240024020080d0020071028210b0c010b200228020020082007102c210b0b200b450d0a2002200b36020020092007360200200128020021080b2001200841016a360200200b20086a200a3a0000200641146a2802002107200641186a2802002208200210b401024002402009280200220a2001280200220b6b2008490d002002280200210a0c010b200b20086a220c200b490d1a200a410174220b200c200b200c4b1b220b4100480d1a02400240200a0d00200b1028210a0c010b2002280200200a200b102c210a0b200a450d0b2002200a3602002009200b3602002001280200210b0b2001200b20086a360200200a200b6a20072008109a051a200641206a2802002107200641246a2802002208200210b401024002402009280200220a2001280200220b6b2008490d002002280200210a0c010b200b20086a220c200b490d1a200a410174220b200c200b200c4b1b220b4100480d1a02400240200a0d00200b1028210a0c010b2002280200200a200b102c210a0b200a450d0c2002200a3602002009200b3602002001280200210b0b2001200b20086a360200200a200b6a20072008109a051a02400240200928020020012802002208460d002002280200210b0c010b200841016a220b2008490d1a2008410174220a200b200a200b4b1b220a4100480d1a0240024020080d00200a1028210b0c010b20022802002008200a102c210b0b200b450d0d2002200b3602002009200a360200200128020021080b2001200841016a360200200b20086a2006410e6a2d00003a00000c010b02400240200928020020012802002208460d002002280200210b0c010b200841016a220b2008490d192008410174220a200b200a200b4b1b220a4100480d190240024020080d00200a1028210b0c010b20022802002008200a102c210b0b200b450d0d2002200b3602002009200a360200200128020021080b2001200841016a360200200b20086a41023a00002006410d6a2d0000210a02400240200928020020012802002208460d002002280200210b0c010b200841016a220b2008490d1920084101742207200b2007200b4b1b22074100480d190240024020080d0020071028210b0c010b200228020020082007102c210b0b200b450d0e2002200b36020020092007360200200128020021080b2001200841016a360200200b20086a200a3a0000200641146a2802002107200641186a2802002208200210b401024002402009280200220a2001280200220b6b2008490d002002280200210a0c010b200b20086a220c200b490d19200a410174220b200c200b200c4b1b220b4100480d1902400240200a0d00200b1028210a0c010b2002280200200a200b102c210a0b200a450d0f2002200a3602002009200b3602002001280200210b0b2001200b20086a360200200a200b6a20072008109a051a200641206a2802002107200641246a2802002208200210b401024002402009280200220a2001280200220b6b2008490d002002280200210a0c010b200b20086a220c200b490d19200a410174220b200c200b200c4b1b220b4100480d1902400240200a0d00200b1028210a0c010b2002280200200a200b102c210a0b200a450d102002200a3602002009200b3602002001280200210b0b2001200b20086a360200200a200b6a20072008109a051a2006412c6a2802002107200641306a2802002208200210b401024002402009280200220a2001280200220b6b2008490d002002280200210a0c010b200b20086a220c200b490d19200a410174220b200c200b200c4b1b220b4100480d1902400240200a0d00200b1028210a0c010b2002280200200a200b102c210a0b200a450d112002200a3602002009200b3602002001280200210b0b2001200b20086a360200200a200b6a20072008109a051a2006410e6a2d0000220841044b0d000240024002400240024020080e050001020304000b02400240200928020020012802002208460d002002280200210b0c010b200841016a220b2008490d1d2008410174220a200b200a200b4b1b220a4100480d1d0240024020080d00200a1028210b0c010b20022802002008200a102c210b0b200b450d162002200b3602002009200a360200200128020021080b2001200841016a360200200b20086a41003a00000c040b02400240200928020020012802002208460d002002280200210b0c010b200841016a220b2008490d1c2008410174220a200b200a200b4b1b220a4100480d1c0240024020080d00200a1028210b0c010b20022802002008200a102c210b0b200b450d162002200b3602002009200a360200200128020021080b2001200841016a360200200b20086a41013a00000c030b02400240200928020020012802002208460d002002280200210b0c010b200841016a220b2008490d1b2008410174220a200b200a200b4b1b220a4100480d1b0240024020080d00200a1028210b0c010b20022802002008200a102c210b0b200b450d162002200b3602002009200a360200200128020021080b2001200841016a360200200b20086a41023a00000c020b02400240200928020020012802002208460d002002280200210b0c010b200841016a220b2008490d1a2008410174220a200b200a200b4b1b220a4100480d1a0240024020080d00200a1028210b0c010b20022802002008200a102c210b0b200b450d162002200b3602002009200a360200200128020021080b2001200841016a360200200b20086a41033a00000c010b02400240200928020020012802002208460d002002280200210b0c010b200841016a220b2008490d192008410174220a200b200a200b4b1b220a4100480d190240024020080d00200a1028210b0c010b20022802002008200a102c210b0b200b450d162002200b3602002009200a360200200128020021080b2001200841016a360200200b20086a41043a00000b02400240200641346a2802004101460d002003200641386a2802002006413c6a28020028020c1102002003280200210720032802082208200210b401024002402009280200220a2001280200220b6b2008490d002002280200210a0c010b200b20086a220c200b490d1a200a410174220b200c200b200c4b1b220b4100480d1a02400240200a0d00200b1028210a0c010b2002280200200a200b102c210a0b200a450d182002200a3602002009200b3602002001280200210b0b2001200b20086a360200200a200b6a20072008109a051a2003280204450d012007102a0c010b200641386a2802002107200641c0006a2802002208200210b401024002402009280200220a2001280200220b6b2008490d002002280200210a0c010b200b20086a220c200b490d19200a410174220b200c200b200c4b1b220b4100480d1902400240200a0d00200b1028210a0c010b2002280200200a200b102c210a0b200a450d182002200a3602002009200b3602002001280200210b0b2001200b20086a360200200a200b6a20072008109a051a0b200641c4006a20021093042004200541d8006a2205470d000b0b200341106a24000f0b200b41011037000b200741011037000b200a41011037000b200b41011037000b200a41011037000b200741011037000b200b41011037000b200b41011037000b200a41011037000b200a41011037000b200741011037000b200b41011037000b200b41011037000b200b41011037000b200a41011037000b200a41011037000b200a41011037000b200a41011037000b200a41011037000b200b41011037000b200b41011037000b1031000b840701087f20002802042102024002400240024002400240024020002802004101460d00200041086a2802002200200110b4012000450d01200041186c2103200241146a2100200141086a2102200141046a21040340200041706a2802002105200041746a2802002206200110b4010240024020042802002207200228020022086b2006490d00200128020021070c010b200820066a22092008490d08200741017422082009200820094b1b22084100480d080240024020070d002008102821070c010b200128020020072008102c21070b2007450d042001200736020020042008360200200228020021080b2002200820066a360200200720086a20052006109a051a2000417c6a280200210520002802002206200110b4010240024020042802002207200228020022086b2006490d00200128020021070c010b200820066a22092008490d08200741017422082009200820094b1b22084100480d080240024020070d002008102821070c010b200128020020072008102c21070b2007450d052001200736020020042008360200200228020021080b2002200820066a360200200720086a20052006109a051a200041186a2100200341686a22030d000c020b0b2000410c6a2802002200200110b4012000450d00200041186c2103200241146a2100200141086a2102200141046a21040340200041706a2802002105200041746a2802002206200110b4010240024020042802002207200228020022086b2006490d00200128020021070c010b200820066a22092008490d07200741017422082009200820094b1b22084100480d070240024020070d002008102821070c010b200128020020072008102c21070b2007450d052001200736020020042008360200200228020021080b2002200820066a360200200720086a20052006109a051a2000417c6a280200210520002802002206200110b4010240024020042802002207200228020022086b2006490d00200128020021070c010b200820066a22092008490d07200741017422082009200820094b1b22084100480d070240024020070d002008102821070c010b200128020020072008102c21070b2007450d062001200736020020042008360200200228020021080b2002200820066a360200200720086a20052006109a051a200041186a2100200341686a22030d000b0b0f0b200841011037000b200841011037000b200841011037000b200841011037000b1031000b840401087f200028020421020240024002400240024020002802004101460d00200041086a2802002200200110b40120004103742200450d01200220006a2103200141086a2104034020022802002105200241046a2802002200200110b40102400240200141046a22062802002207200428020022086b2000490d00200128020021070c010b200820006a22092008490d06200741017422082009200820094b1b22084100480d060240024020070d002008102821070c010b200128020020072008102c21070b2007450d042001200736020020062008360200200428020021080b2004200820006a360200200720086a20052000109a051a200241086a22022003470d000c020b0b2000410c6a2802002200200110b40120004103742200450d00200220006a2103200141086a2104034020022802002105200241046a2802002200200110b40102400240200141046a22062802002207200428020022086b2000490d00200128020021070c010b200820006a22092008490d05200741017422082009200820094b1b22084100480d050240024020070d002008102821070c010b200128020020072008102c21070b2007450d042001200736020020062008360200200428020021080b2004200820006a360200200720086a20052000109a051a200241086a22022003470d000b0b0f0b200841011037000b200841011037000b1031000bd10f02037f027e230041a0076b22022400024002402001450d00200220003602080c010b200241013602080b2002200136020c200241f0046a200241086a107a02400240024002400240024002400240024002400240024020022903d8054203510d00200241106a200241f0046a41a002109a051a200241c0026a200241106a41a002109a051a200241e0046a200241c0026a10870420022802e8042101200241f0046a200241c0026a41a002109a051a20024198076a20022802e804360200200220022903e00437039007200241b0026a200241f0046a200120024190076a10d0034101410220022d00b00241014622001b220310282201450d01200241003602f804200220033602f404200220013602f0040240024020000d00200241013602f804200141003a000020022802f404210020022802f80421010240200241bc026a2d000022034102470d000240024020002001460d0020022802f00421000c010b200141016a22002001490d0f200141017422032000200320004b1b22034100480d0f0240024020010d002003102821000c010b20022802f00420012003102c21000b2000450d06200220033602f404200220003602f00420022802f80421010b2002200141016a3602f804200020016a41003a00000c020b0240024020002001460d0020022802f00421000c010b200141016a22002001490d0e200141017422042000200420004b1b22044100480d0e0240024020010d002004102821000c010b20022802f00420012004102c21000b2000450d06200220043602f404200220003602f00420022802f80421010b2002200141016a3602f804200020016a41013a00000240024020034101460d000240024020022802f40420022802f8042201460d0020022802f00421000c010b200141016a22002001490d10200141017422032000200320004b1b22034100480d100240024020010d002003102821000c010b20022802f00420012003102c21000b2000450d09200220033602f404200220003602f00420022802f80421010b2002200141016a3602f804200020016a41003a00000c010b0240024020022802f40420022802f8042201460d0020022802f00421000c010b200141016a22002001490d0f200141017422032000200320004b1b22034100480d0f0240024020010d002003102821000c010b20022802f00420012003102c21000b2000450d09200220033602f404200220003602f00420022802f80421010b2002200141016a3602f804200020016a41013a00000240024020022802f40420022802f8042201460d0020022802f00421000c010b200141016a22002001490d0f200141017422032000200320004b1b22034100480d0f0240024020010d002003102821000c010b20022802f00420012003102c21000b2000450d0a200220033602f404200220003602f00420022802f80421010b2002200141016a3602f804200020016a20022d00bd023a00000b0240024020022802f40420022802f8042201460d0020022802f00421000c010b200141016a22002001490d0e200141017422032000200320004b1b22034100480d0e0240024020010d002003102821000c010b20022802f00420012003102c21000b2000450d0a200220033602f404200220003602f00420022802f80421010b2002200141016a3602f804200020016a20022d00be023a00000c010b200241013602f804200141013a000020022d00b102417e6a22014102200141ff01714102491b41ff0171220141024b0d0002400240024020010e03000102000b0240024020022802f40420022802f8042201460d0020022802f00421000c010b200141016a22002001490d0f200141017422032000200320004b1b22034100480d0f0240024020010d002003102821000c010b20022802f00420012003102c21000b2000450d0c200220033602f404200220003602f00420022802f80421010b2002200141016a3602f804200020016a41003a00000c020b0240024020022802f40420022802f8042201460d0020022802f00421000c010b200141016a22002001490d0e200141017422032000200320004b1b22034100480d0e0240024020010d002003102821000c010b20022802f00420012003102c21000b2000450d0c200220033602f404200220003602f00420022802f80421010b2002200141016a3602f804200020016a41013a00000c010b0240024020022802f40420022802f8042201460d0020022802f00421000c010b200141016a22002001490d0d200141017422032000200320004b1b22034100480d0d0240024020010d002003102821000c010b20022802f00420012003102c21000b2000450d0c200220033602f404200220003602f00420022802f80421010b2002200141016a3602f804200020016a41023a0000200241b0026a410172200241f0046a10c6030b20023502f804210520023502f0042106200241a0076a240020062005422086840f0b2002411c6a4104360200200241d4026a4102360200200242023702c402200241bca7c4003602c00220024104360214200241e0a8c400360210200241003602b402200241b8aec6003602b0022002200241106a3602d0022002200241b0026a360218200241c0026a41cca7c400103e000b200341011037000b200341011037000b200441011037000b200341011037000b200341011037000b200341011037000b200341011037000b200341011037000b200341011037000b200341011037000b1031000baf0d04067f017e057f017e230041c0016b22022400200241086a10e403200228020c21032002280208210420024180016a41086a22054200370300200242003703800141f99fc600411520024180016a1008200241106a41086a2005290300370300200220022903800137031020022003410020041b3602a001200241106a4110200241a0016a41041007109801109e0320054200370300200242003703800141f99fc600411520024180016a100820024190016a41086a20052903003703002002200229038001370390012002410036021020024190016a4110200241106a1006210502400240024002400240024020022802102203417f460d002005450d00200341034d0d05200528000021062005102a20060d010b41042107410021060c010b2006ad420c7e2208422088a70d012008a722054100480d01200510282207450d022007210341002104034002400240024002400240411410282205450d00200541106a41002800eaa046360000200541086a41002900e2a046370000200541002900daa046370000200541144128102c2205450d0120052004360014200241106a41186a22094200370300200241106a41106a220a4200370300200241106a41086a220b42003703002002420037031020054118200241106a1000200241a0016a41186a2009290300370300200241a0016a41106a200a290300370300200241a0016a41086a200b290300370300200220022903103703a0012005102a20024100360210200241a0016a4120200241106a1006210a2002280210220b417f460d03200a450d032002200b3602142002200a3602102002200241106a106c02400240024020022802000d002002280214220c20022802042209490d002009417f4c0d050240024020090d00410121050c010b2009102e2205450d0220052002280210220d2009109a051a2002200c20096b3602142002200d20096a3602100b20050d020b41c4d1c300413320024180016a419cd9c3001038000b200941011037000b2009ad2208422086210e0240200b450d00200a102a0b200e2008842108200241a0016a412010090c040b411441011037000b412841011037000b1036000b41012105420021080b20032005360200200341046a20083702002003410c6a21032006200441016a2204470d000b0b200220063602182002200636021420022007360210200241a0016a200241106a108e04200241106a41186a200241a0016a41186a290300370300200241106a41106a2205200241a0016a41106a290300370300200241106a41086a200241a0016a41086a290300370300200220022903a00137031020024180016a41086a22034200370300200242003703800141e6efc200411520024180016a100820024190016a41086a20032903003703002002200229038001370390012002411036028401200220024190016a36028001200241106a20024180016a10f002200241106a10b20320024100360298012002420137039001200220024190016a3602a0012005200241a0016a10c801200241106a20024190016a10a001200220024190016a3602a001200241c0006a200241a0016a10c801200220024190016a3602a001200241e0006a200241a0016a10c801200228021421042002411c6a280200220520024190016a10b401024002402005450d00200541246c210b0340200241a0016a200410ec0120022802a001210a02400240200228029401220920022802980122056b20022802a8012203490d0020022802900121090c010b200520036a22062005490d04200941017422052006200520064b1b22054100480d040240024020090d002005102821090c010b20022802900120092005102c21090b2009450d032002200536029401200220093602900120022802980121050b2002200520036a36029801200920056a200a2003109a051a024020022802a401450d00200a102a0b200441246a2104200b415c6a220b0d000b0b200235029801210820022802900121090240200228021c2203450d0020022802142105200341246c210303400240024020052d0000220441034b0d0002400240024020040e0404000102040b2005410c6a280200450d03200541086a280200102a0c030b2005410c6a280200450d02200541086a280200102a0c020b2005410c6a280200450d01200541086a280200102a0c010b200541086a280200450d00200541046a280200102a0b200541246a21052003415c6a22030d000b0b0240200241186a280200450d002002280214102a0b200241c0016a240020084220862009ad840f0b200541011037000b1031000b200541041037000b41c4d1c300413320024180016a419cd9c3001038000bee2605017f027e0d7f027e067f230041b0036b22022400024002402001450d00200220003602080c010b200241013602080b2002200136020c2002200241086a106c024020022802000d00200228020421012002200241086a36029801200241003a0090032002420037028402200241f8b9c000360280022002200136022420024100360220200220024190036a36022c200220024198016a360228200241206a20024180026a10860420022802800221012002290284022103024020022d009003450d0020012003a72003422088a710b0020c010b2001450d002002200337021420022001360210200241206a200241106a1097040240024002400240024002400240024002400240024020022802204101460d00200241206a41086a2201290300210342002104200142003703002002420037032041feb3c300410d200241206a100820024180026a41086a200129030037030020022002290320370380022002410036022020024180026a4110200241206a100621010240024020022802202200417f460d002001450d0020004108490d01200129000021042001102a0b024041a00210282205450d0020054102360298012005420237036820052003200442dc0b7c220420032004561b3703a001200241106a21012002280214210603402001280200220741086a210020072f010622084103742101410021090240024003402001450d0141bee6c20020004108109c05220a450d02200141786a2101200941016a2109200041086a2100200a417f4a0d000b2009417f6a21080b024020060d004101210b0c080b2006417f6a2106200720084102746a41e4016a21010c010b0b200220072009410c6c6a220141e8006a280200360284022002200141e0006a28020036028002200241206a20024180026a107e02402002280220220c0d004101210b0c060b2002280224210d200241206a41086a22012802002208450d0320014200370300200242003703204193cdc2004111200241206a100820024180026a41086a200129030037030020022002290320370380022002410036022020024180026a4110200241206a1006210102400240024020022802202200417f460d002001450d002002200036029c012002200136029801200241206a20024198016a107b20022802202206450d02200229022421032000450d012001102a0c010b42002103410421060b2003a7210b2006210020062101024002400240024002402003422088a7220e450d002006200e41c4006c6a21004100210902400340200620096a22012d0000210a200241206a200141016a41c300109a051a200a4102460d0120024180026a41186a200241206a41186a29000037030020024180026a41106a200241206a41106a29000037030020024180026a41086a200241206a41086a2900003703002002200229002037038002200a4101460d03200941c4006a2109200141c4006a2000470d000b200021010c010b200141c4006a21010b0240034020002001460d0120012d00002109200141c4006a210120094102470d000b0b410121074100210f0240200b0d00410021100c020b2006102a410021100c010b20024198016a41086a220a20024180026a41086a29030037030020024198016a41106a220f20024180026a41106a29030037030020024198016a41186a221120024180026a41186a290300370300200220022903800222033703f0022002200337039801412010282207450d022007200229039801370000200741186a2011290300370000200741106a200f290300370000200741086a200a2903003700004101210f024002400240200e41c4006c41bc7f6a2009470d00410121100c010b200141c4006a2d00002109200241206a200141c5006a41c300109a051a20014188016a210a024020094102470d0041012110200a21010c020b4101210f410121100340200a21010240034020024180026a41186a220a200241206a41186a29000037030020024180026a41106a220e200241206a41106a29000037030020024180026a41086a2211200241206a41086a2900003703002002200229002037038002200941ff01714101460d0120002001460d0320012d00002109200241206a200141016a41c300109a051a200141c4006a210120094102460d040c000b0b20024198016a41086a2011290300220337030020024198016a41106a200e290300220437030020024198016a41186a200a29030022123703002002200229038002221337039801200241f0026a41186a220a2012370300200241f0026a41106a220e2004370300200241f0026a41086a22112003370300200220133703f00202402010200f470d00200f41016a2209200f490d14200f41017422142009201420094b1b221041ffffff3f712010470d14201041057422094100480d1402400240200f0d002009102821070c010b2007200f4105742009102c21070b2007450d050b2007200f4105746a220920022903f002370000200941186a200a290300370000200941106a200e290300370000200941086a2011290300370000200f41016a210f20002001460d0120012d00002109200241206a200141016a41c300109a051a200141c4006a210a20094102470d000b200141c4006a21010c010b200021010b0240034020002001460d0120012d00002109200141c4006a210120094102470d000b0b200b450d002006102a0b200c200841f0006c6a210820024180026a41106a211520024180026a41086a21144200210341042116200c210a02400340200a2802042101200a2802002100200241206a200a41086a41e800109a051a200a41f0006a210a024020010d00200a2008460d0a0340200a2802042206450d0b200a41086a280200210b0240200a410c6a2802002201450d00200141246c21002006210103400240024020012d0000220941034b0d0002400240024020090e0404000102040b2001410c6a280200450d03200141086a280200102a0c030b2001410c6a280200450d02200141086a280200102a0c020b2001410c6a280200450d01200141086a280200102a0c010b200141086a280200450d00200141046a280200102a0b200141246a21012000415c6a22000d000b0b200a41f0006a210a0240200b450d002006102a0b200a2008470d000c0b0b0b20024198016a200241206a41e800109a051a20022001360284022002200036028002201420024198016a41e800109a051a109801210120024190036a20024180026a10f6010240024002400240200228028002417f6a220020014f0d00200241206a200010f701200241206a20154120109c050d00200228028002221741002001417b6a2200200020014b1b490d0020024190036a20076b220641606a210e200641406a2111200641a07f6a21182007200f41057422096a210b410021010240024002400340024002400240200b200720016a22006b41e0004b0d00200f4105742001470d01410021000c060b024020062001470d0020024190036a21000c060b200020024190036a4120109c05450d05200e2001470d0120024190036a21000c050b0340024020024190036a2000470d0020024190036a21000c060b200020024190036a4120109c05450d05200041206a2100200941606a22090d000b410021000c040b200041206a221920024190036a4120109c05450d02024020112001470d0020024190036a21000c040b200041c0006a221920024190036a4120109c05450d01024020182001470d0020024190036a21000c040b200941807f6a210920014180016a2101200041e0006a20024190036a4120109c050d000b200720016a41606a21000c020b201921000c010b201921000b200241206a201710f701200241206a20024190036a4120109c05210120000d0020010d010b0240200228028c022200450d002002280284022101200041246c210003400240024020012d0000220941034b0d0002400240024020090e0404000102040b2001410c6a280200450d03200141086a280200102a0c030b2001410c6a280200450d02200141086a280200102a0c020b2001410c6a280200450d01200141086a280200102a0c010b200141086a280200450d00200141046a280200102a0b200141246a21012000415c6a22000d000b0b200228028802450d01200228028402102a0c010b20024190036a20024180026a10f601200241206a20024180026a41f000109a051a0240024020034220882204a722012003a7460d00200121000c010b200141016a22092001490d142004a722004101742206200920092006491bad220342f0007e2204422088a70d142004a722094100480d140240024020010d002009102821160c010b2016200141f0006c2009102c21160b2016450d020b2016200041f0006c6a200241206a41f000109a051a200241206a41186a220920024190036a41186a290300370300200241206a41106a220620024190036a41106a290300370300200241206a41086a220b20024190036a41086a29030037030020022002290390033703200240200f2010470d00200f41016a2201200f490d14200f410174220e2001200e20014b1b221041ffffff3f712010470d14201041057422014100480d1402400240200f0d002001102821070c010b2007200f4105742001102c21070b2007450d040b200342ffffffff0f83200041016aad4220868421032007200f4105746a22012002290320370000200141186a2009290300370000200141106a2006290300370000200141086a200b290300370000200f41016a210f0b200a2008470d010c0a0b0b200941041037000b200141011037000b200941011037000b412041011037000b41c4d1c300413320024190036a419cd9c3001038000b41a00241081037000b41c4d1c300413320024190036a419cd9c3001038000b2002200229022437038002419db6c300412820024180026a419cb4c3001038000b4101210b200d450d01200c102a0c010b0240200d450d00200c102a0b02402010450d002007102a0b0240200342ffffffff0f560d004101210b2003a7450d012016102a0c010b024020160d004101210b0c010b200541a00241c004102c2205450d01200541a0026a20024180026a41e800109a051a2005420237038803200520033703c003200520163602bc03200541033602b80320052002290398013703900320054198036a200241a0016a290300370300200541a0036a200241a8016a290300370300200541a8036a200241b0016a290300370300200541b0036a200241b8016a290300370300200541c8036a200241206a41f800109a051a4102210b0b200241106a210120022802142106024003402001280200220741086a210020072f010622084103742101410021090240024003402001450d0141a7c5c20020004108109c05220a450d02200141786a2101200941016a2109200041086a2100200a417f4a0d000b2009417f6a21080b2006450d022006417f6a2106200720084102746a41e4016a21010c010b0b200741e0006a2009410c6c6a22012802084104490d002001280200280000210742002103200241206a41086a2201420037030020024200370320419194c1004115200241206a100820024180026a41086a200129030037030020022002290320370380022002410036022020024180026a4110200241206a100621000240024020022802202201417f460d002002200136029c012002200036029801200241206a20024198016a10820120022802202209450d04200229022421032001450d012000102a0c010b410421090b4100210002402003422088a72201417f6a220a20014b0d00200a20014f0d002009200a4102746a2201450d00200128020020074721000b02402003a7450d002009102a0b20000d030b200b210f0c030b41c00441081037000b41c4d1c300413320024190036a419cd9c3001038000b2005200b41a0026c2201200b4101742200200b41016a220f2000200f4b1b41a0026c2200102c2205450d01200520016a20024180026a41e800109a05220142023703682001200229039801370370200141f8006a200241a0016a29030037030020014180016a200241a8016a29030037030020014188016a200241b0016a29030037030020014190016a200241b8016a2903003703002001419c016a20073602002001410d36029801200141a8016a200241206a41f800109a051a0b20022802102002280214200228021810b00220024100360288022002420137038002200f20024180026a10b401200f41a0026c210b20022802840221062002280288022101200521090340200241206a20091087042002280220210802400240200620016b20022802282207490d00200120076a2100200228028002210a0c010b200120076a22002001490d042006410174220a2000200a20004b1b220e4100480d040240024020060d00200e1028210a0c010b2002280280022006200e102c210a0b200a450d032002200e360284022002200a36028002200e21060b2002200036028802200a20016a20082007109a051a02402002280224450d002008102a0b200941a0026a210920002101200b41e07d6a220b0d000b200f41a0026c210920054198016a210103402001106a200141a0026a2101200941e07d6a22090d000b2005102a200241b0036a24002000ad422086200aad840f0b200041081037000b200e41011037000b1031000b2002418c026a4104360200200241346a410236020020024202370224200241bca7c4003602202002410436028402200241f8a8c400360280022002410036029c01200241b8aec60036029801200220024180026a360230200220024198016a36028802200241206a41cca7c400103e000bf00101067f2001280204210202400240024003402001280200220341086a210420032f01062205410374210141002106024003402001450d0141ffa0c60020044108109c052207450d03200141786a2101200641016a2106200441086a21042007417f4a0d000b2006417f6a21050b02402002450d002002417f6a2102200320054102746a41e4016a21010c010b0b20004187a1c600360204200041086a41283602000c010b200341e0006a2006410c6c6a220128020841074b0d01200041afa1c600360204200041086a41293602000b200041013602000f0b200041086a2001280200290000370300200041003602000be92c06087f017e097f027e017f027e230041b0026b22022400024002402001450d00200220003602100c010b200241013602100b20022001360214200241c8006a200241106a107f02400240200228024c2203450d00200241d4006a280200210420022802502105200241c8006a200241106a1079200228024822060d0102402004450d00200441246c21002003210103400240024020012d0000220741034b0d0002400240024020070e0404000102040b2001410c6a280200450d03200141086a280200102a0c030b2001410c6a280200450d02200141086a280200102a0c020b2001410c6a280200450d01200141086a280200102a0c010b200141086a280200450d00200141046a280200102a0b200141246a21012000415c6a22000d000b0b2005450d002003102a0b200241dc016a4104360200200241dc006a41023602002002420237024c200241bca7c400360248200241043602d40120024194a9c4003602d0012002410036022c200241b8aec6003602282002200241d0016a3602582002200241286a3602d801200241c8006a41cca7c400103e000b200241d0006a2802002108200228024c2109200241086a200241106a106c0240024020022802080d00200228020c21012002200241106a360228200241003a0038200242003702d401200241f8b9c0003602d0012002200136024c200241003602482002200241386a3602542002200241286a360250200241c8006a200241d0016a10860420022802d001210120022902d401210a024020022d0038450d002001200aa7200a422088a710b0020c010b20010d010b200241dc016a4104360200200241dc006a41023602002002420237024c200241bca7c400360248200241043602d40120024194a9c4003602d0012002410036022c200241b8aec6003602282002200241d0016a3602582002200241286a3602d801200241c8006a41cca7c400103e000b2002200a37021c20022001360218200241013b01342002420037022c200241f8b9c000360228200241286a41086a210b024002400240024002402008450d002006200841a0026c6a210c200241d0016a410272210d2006210e024002400240024002400240024002400340200e41e8006a2903004202520d0902400240200e28029801410247220f0d00200e2903a001210a200241186a2101200228021c211002400240024002400240024002400240024002400240024002400240024002400240024003402001280200221141086a210020112f010622124103742101410021070240024003402001450d0141f7fcc50020004108109c052213450d02200141786a2101200741016a2107200041086a21002013417f4a0d000b2007417f6a21120b2010450d022010417f6a2110201120124102746a41e4016a21010c010b0b0240201141e0006a2007410c6c6a220128020841074b0d00201442808080807083422984210a41fffcc50021120c020b200a42b8178020012802002900002214510d0341c6e6c2002112413121100c020b201442808080807083421c84210a41a8fdc50021120b200aa721100b024002400240024020022d0035450d004131210141f7e6c20021000c010b2002280228200228022c200228023010b0022002420037022c200241f8b9c000360228200242e2c289abb68edbb7f400370338200241d0016a410272410041da001099051a200241c8006a41004184011099051a41e40110282213450d0420134100360200201341046a200241d0016a41dc00109a051a201341e0006a200241c8006a418401109a051a2002410036022c2002201336022820132f0106220e4103742111417f210041002101024002400340024020112001470d00200e21000c020b200241386a201320016a41086a4108109c052207450d02200141086a2101200041016a2100200741004e0d000b0b200242e2c289abb68edbb7f40037025c2002200b360258200220003602542002201336024c200241003602482002200241286a360250201041046a2200417f4c0d062000450d02200010282201450d07200241003602ac02200220013602d0012010413f4b0d03200120104102743a0000410121070c1b0b412d210141a8e7c20021000b2002200136024c2002200036024841d5e7c2004122200241c8006a41f8e7c2001038000b200241003602ac0241012100200241013602d001410110282201450d05200141033a0000200241013602ac02200220013602d001410521070c130b201041808001490d162010418080808004490d150c100b200f0d0e200e2903a0012115200241c8006a200241186a10970402400240024020022802484101470d002002350250210a200228024c21160c010b2002290350210a200241c8006a41086a220142003703002002420037034841feb3c300410d200241c8006a1008200241d0016a41086a2001290300370300200220022903483703d00120024100360248200241d0016a4110200241c8006a100621010240024020022802482200417f470d00420021170c010b024020010d00420021170c010b200041074d0d07200129000021172001102a0b02402015200a423c7c560d004100210f2015201742dc0b7c220a540d020c110b201842808080807083422584210a41f8b5c30021160b4101210f0b024020022d0035450d004131210141f7e6c20021000c080b0240200f450d002002280228200228022c200228023010b0022002420037022c200241f8b9c000360228200242f4d2b59bc7ae98b8303703380c060b20022802282111200242f4d2b59bc7ae98b830370338201141f8b9c000460d05200228022c21100c060b41e40141041037000b1036000b200041011037000b410141011037000b41c4d1c3004133200241c8006a419cd9c3001038000b200d410041da001099051a200241c8006a41004184011099051a41e40110282211450d034100211020114100360200201141046a200241d0016a41dc00109a051a201141e0006a200241c8006a418401109a051a2002410036022c200220113602280b0340201141086a210020112f010622124103742101410021070240024003402001450d01200241386a20004108109c052213450d02200141786a2101200741016a2107200041086a21002013417f4a0d000b2007417f6a21120b2010450d032010417f6a2110201120124102746a41e4016a28020021110c010b0b412d210141a8e7c20021000b2002200136024c2002200036024841d5e7c2004122200241c8006a41f8e7c2001038000b200242f4d2b59bc7ae98b83037025c2002200b360258200220123602542002201136024c200241003602482002200241286a360250200241003602d801200242013703d00141011028210102400240200f0d002001450d03200141003a000020024281808080103702d401200220013602d001200141014109102c2201450d042001200a3700012002428980808090013702d401200220013602d0010c010b2001450d04200141013a000020024281808080103702d401200220013602d001200aa72201200241d0016a10b4010240024020022802d401220720022802d80122006b2001490d0020022802d00121070c010b200020016a22132000490d14200741017422112013201120134b1b22134100480d140240024020070d002013102821070c010b20022802d00120072013102c21070b2007450d06200220133602d401200220073602d0010b2002200020016a3602d801200720006a20162001109a051a0b200241386a41086a200241d0016a41086a280200360200200220022903d001370338200241c8006a200241386a10bb022002200f3a0035200241003a0034200a2118200f450d05200241d0016a41086a200241286a41086a290300370300200220022903283703d0010c110b41e40141041037000b410141011037000b410941011037000b410141011037000b201341011037000b200e41a0026a220e200c470d010c0a0b0b200141033a0000200241013602ac022000417f6a41034b0d01200041017422074105200741054b1b22074100480d0a0b200120002007102c2201450d01200220013602d001200721000b20012010360001410521070c030b200741011037000b02400240200041034b0d00200041017422074104200741044b1b22074100480d08200120002007102c2201450d01200220013602d001200721000b20012010410274410272360000410421070c020b200741011037000b0240200041014b0d0020012000200041017422074102200741024b1b2207102c2201450d02200220013602d001200721000b41022107200120104102744101723b00000b200220073602ac0202400240200020076b2010490d00200021130c010b200720106a22132007490d05200041017422112013201120134b1b22134100480d05200120002013102c2201450d02200220013602d0010b2002200720106a3602ac02200120076a20122010109a051a2002201336023c200220022802d001360238200220022802ac02360240200241c8006a200241386a10bb0220024180023b0134200241d0016a41086a200241286a41086a290300370300200220022903283703d0010c030b200741011037000b201341011037000b200241d0016a41086a200b290300370300200220022903283703d0010b2002280218200228021c200228022010b00202402004450d00200441246c21002003210103400240024020012d0000220741034b0d0002400240024020070e0404000102040b2001410c6a280200450d03200141086a280200102a0c030b2001410c6a280200450d02200141086a280200102a0c020b2001410c6a280200450d01200141086a280200102a0c010b200141086a280200450d00200141046a280200102a0b200141246a21012000415c6a22000d000b0b02402005450d002003102a0b02402008450d00200841a0026c210020064198016a210103402001106a200141a0026a2101200041e07d6a22000d000b0b02402009450d002006102a0b2002410036025020024201370348410110282201450d022002410136024c20022002280250220041016a36025020022001360248200120006a20022d00dc013a000002400240200228024c20022802502201460d00200228024821000c010b200141016a22002001490d01200141017422072000200720004b1b22074100480d010240024020010d002007102821000c010b200228024820012007102c21000b2000450d022002200736024c20022000360248200228025021010b2002200141016a360250200020016a20022d00dd013a000020022802d801200241c8006a10b40120022802d00122072100024020022802d4012213450d002013210120072100034020002802e40121002001417f6a22010d000b0b0240024002400240024002400240024002400240024020022802d80122120d00410021010c010b200241d0016a210f41002113034002400240201320002f01064f0d0020002013410c6c6a41e0006a2111200020134103746a41086a2101201341016a21130c010b02400240200028020022010d00201542808080807083200fad84211541002107410021010c010b2000330104422086200fad842115410121070b201521142015210a02402015422088a7220020012f0106490d000340200a221442ffffffff0f83210a200741016a210720012f01042200200128020022012f01064f0d000b0b20012000410c6c6a2113200120004103746a2110200041027420016a41e8016a28020021002014a7210f02402007417f6a2201450d00034020002802e40121002001417f6a22010d000b0b201341e0006a2111201041086a2101410021130b02400240200228024c20022802502207460d00200228024821100c010b200741016a22102007490d0c2007410174220e2010200e20104b1b220e4100480d0c0240024020070d00200e102821100c010b20022802482007200e102c21100b2010450d032002200e36024c20022010360248200228025021070b2002200741016a360250201020076a20012d00003a000002400240200228024c20022802502207460d00200228024821100c010b200741016a22102007490d0c2007410174220e2010200e20104b1b220e4100480d0c0240024020070d00200e102821100c010b20022802482007200e102c21100b2010450d042002200e36024c20022010360248200228025021070b2002200741016a360250201020076a20012d00013a000002400240200228024c20022802502207460d00200228024821100c010b200741016a22102007490d0c2007410174220e2010200e20104b1b220e4100480d0c0240024020070d00200e102821100c010b20022802482007200e102c21100b2010450d052002200e36024c20022010360248200228025021070b2002200741016a360250201020076a20012d00023a000002400240200228024c20022802502207460d00200228024821100c010b200741016a22102007490d0c2007410174220e2010200e20104b1b220e4100480d0c0240024020070d00200e102821100c010b20022802482007200e102c21100b2010450d062002200e36024c20022010360248200228025021070b2002200741016a360250201020076a20012d00033a000002400240200228024c20022802502207460d00200228024821100c010b200741016a22102007490d0c2007410174220e2010200e20104b1b220e4100480d0c0240024020070d00200e102821100c010b20022802482007200e102c21100b2010450d072002200e36024c20022010360248200228025021070b2002200741016a360250201020076a20012d00043a000002400240200228024c20022802502207460d00200228024821100c010b200741016a22102007490d0c2007410174220e2010200e20104b1b220e4100480d0c0240024020070d00200e102821100c010b20022802482007200e102c21100b2010450d082002200e36024c20022010360248200228025021070b2002200741016a360250201020076a20012d00053a000002400240200228024c20022802502207460d00200228024821100c010b200741016a22102007490d0c2007410174220e2010200e20104b1b220e4100480d0c0240024020070d00200e102821100c010b20022802482007200e102c21100b2010450d092002200e36024c20022010360248200228025021070b2002200741016a360250201020076a20012d00063a000002400240200228024c20022802502207460d00200228024821100c010b200741016a22102007490d0c2007410174220e2010200e20104b1b220e4100480d0c0240024020070d00200e102821100c010b20022802482007200e102c21100b2010450d0a2002200e36024c20022010360248200228025021070b2002200741016a360250201020076a20012d00073a00002011280200211020112802082201200241c8006a10b40102400240200228024c2211200228025022076b2001490d00200228024821110c010b200720016a220e2007490d0c20114101742207200e2007200e4b1b22074100480d0c0240024020110d002007102821110c010b200228024820112007102c21110b2011450d0b2002200736024c20022011360248200228025021070b2002200720016a360250201120076a20102001109a051a2012417f6a22120d000b20022802d801210120022802d401211320022802d00121070b2002350248210a2002350250211420072013200110b002200241b0026a2400200a2014422086840f0b200e41011037000b200e41011037000b200e41011037000b200e41011037000b200e41011037000b200e41011037000b200e41011037000b200e41011037000b200741011037000b1031000b200741011037000b410141011037000b5702017f027e230041306b2202240020024101410010a80320024100360228200242013703202002200241206a36022c20022002412c6a10c8012002350228210320023502202104200241306a240020042003422086840bba48030b7f047e017f230041d00c6b22022400024002402001450d00200220003602100c010b200241013602100b20022001360214200241f0066a200241106a107a024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024020022903d8074203510d00200241186a200241f0066a41a002109a051a200241f0026a200241186a41a002109a051a200241f0066a200241f0026a10870420022802f8062103024020022802f406450d0020022802f006102a0b200241f0066a200241f0026a41a002109a051a20024190056a200241f0066a10d10341012100024020022d0090054101470d00200220022d0093053a00bb02200220022f0091053b00b902200241013a00b8020c180b200241f0066a20024190056a41086a41d801109a051a200241086a200241c0076a220410f301024002402002290390074202520d00200241b8026a41206a22014200370300200241b8026a41186a22004280808080c000370300200241013a00e002200242043703c8022002427f3703c002200242003703b80220024190056a41206a2203420037030020024190056a41186a22054280808080c000370300200241013a00b805200242043703a0052002427f370398052002420037039005200241c8096a200241b8026a20024190056a109b04200241b8026a41286a2206200241c8096a41286a2903003703002001200241c8096a41206a2903003703002000200241c8096a41186a290300370300200241b8026a41106a2207200241c8096a41106a290300370300200241b8026a41086a2208200241c8096a41086a290300370300200220022903c8093703b8022003420037030020054280808080c000370300200241013a00b805200242043703a0052002427f370398052002420037039005200241f8096a200241b8026a20024190056a109b042006200241f8096a41286a2903003703002001200241f8096a41206a2903003703002000200241f8096a41186a2903003703002007200241f8096a41106a2903003703002008200241f8096a41086a290300370300200220022903f8093703b8022003420037030020054280808080c000370300200241013a00b805200242043703a0052002427f370398052002420037039005200241a80a6a200241b8026a20024190056a109b042006200241a80a6a41286a2903003703002001200241a80a6a41206a2903003703002000200241a80a6a41186a2903003703002007200241a80a6a41106a2903003703002008200241a80a6a41086a290300370300200220022903a80a3703b8022003420037030020054280808080c000370300200241013a00b805200242043703a0052002427f370398052002420037039005200241d80a6a200241b8026a20024190056a109b042006200241d80a6a41286a2903003703002001200241d80a6a41206a2903003703002000200241d80a6a41186a2903003703002007200241d80a6a41106a2903003703002008200241d80a6a41086a290300370300200220022903d80a3703b8022003420037030020054280808080c000370300200241013a00b805200242043703a0052002427f370398052002420037039005200241880b6a200241b8026a20024190056a109b042006200241880b6a41286a2903003703002001200241880b6a41206a2903003703002000200241880b6a41186a2903003703002007200241880b6a41106a2903003703002008200241880b6a41086a290300370300200220022903880b3703b8022003420037030020054280808080c000370300200241013a00b805200242043703a0052002427f370398052002420037039005200241b80b6a200241b8026a20024190056a109b04200241980c6a41286a2203200241b80b6a41286a290300370300200241980c6a41206a2206200241b80b6a41206a290300370300200241980c6a41186a2205200241b80b6a41186a290300370300200241980c6a41106a2207200241b80b6a41106a290300370300200241980c6a41086a2208200241b80b6a41086a290300370300200220022903b80b3703980c2001420037030020004280808080c000370300200241013a00e002200242043703c8022002427f3703c002200242003703b802200241e80b6a200241980c6a200241b8026a109b042002419c056a2201200241e80b6a41086a290300370200200241a4056a2200200241e80b6a41106a290300370200200241ac056a2209200241e80b6a41186a290300370200200241b4056a220a200241e80b6a41206a290300370200200241bc056a220b200241e80b6a41286a290300370200200220022903e80b3702940520024198096a41286a220c200b29020037030020024198096a41206a220b200a29020037030020024198096a41186a220a200929020037030020024198096a41106a2209200029020037030020024198096a41086a220020012902003703002002200229029405370398092003200c2903003703002006200b2903003703002005200a290300370300200720092903003703002008200029030037030020022002290398093703980c418102210120022802c0074112460d010c170b20022d000c210b20022802082108200241b8026a41206a22014200370300200241b8026a41186a22004280808080c000370300200241013a00e002200242043703c8022002427f3703c002200242003703b80220024190056a41206a2205420037030020024190056a41186a22064280808080c000370300200241013a00b805200242043703a0052002427f37039805200242003703900520024198096a200241b8026a20024190056a109b04200241b8026a41286a220720024198096a41286a290300370300200120024198096a41206a290300370300200020024198096a41186a290300370300200241b8026a41106a220920024198096a41106a290300370300200241b8026a41086a220a20024198096a41086a29030037030020022002290398093703b8022005420037030020064280808080c000370300200241013a00b805200242043703a0052002427f370398052002420037039005200241c8096a200241b8026a20024190056a109b042007200241c8096a41286a2903003703002001200241c8096a41206a2903003703002000200241c8096a41186a2903003703002009200241c8096a41106a290300370300200a200241c8096a41086a290300370300200220022903c8093703b802200241b80b6a41086a22014200370300200242003703b80b41d9efc200410d200241b80b6a1008200241880b6a41086a2001290300370300200220022903b80b3703880b410021002002410036029005200241880b6a411020024190056a1006210102402002280290052205417f460d002001450d0020054104490d03200128000021002001102a0b2000ad210d427f210e02402002290390074201520d00200229039807220e4200510d04200d200241a0076a290300220f200f200d541b2210200e7c2010200f7d200e827d210e0b20024190056a41206a420037030020024190056a41186a4280808080c000370300200241bc056a2002419b0c6a280000360000200241013a00b805200242043703a0052002420037039005200220022800980c3600b90520024200200e200d7d220d200d200e561b37039805200241f8096a200241b8026a20024190056a109b04200241980c6a41286a200241f8096a41286a290300370300200241980c6a41206a200241f8096a41206a290300370300200241980c6a41186a200241f8096a41186a290300370300200241980c6a41106a200241f8096a41106a290300370300200241980c6a41086a200241f8096a41086a290300370300200220022903f8093703980c20022802b8072100411310282201450d04200141002900cef0423700002001410f6a41002800ddf042360000200141086a41002900d6f04237000020024293808080b0023702bc0b200220013602b80b200241f0066a200241b80b6a108f0120022802c00b210120022802b80b2105200241b8026a41186a22064200370300200241b8026a41106a22074200370300200241b8026a41086a22094200370300200242003703b80220052001200241b8026a1000200241e80b6a41186a2006290300370300200241e80b6a41106a2007290300370300200241e80b6a41086a2009290300370300200220022903b8023703e80b024020022802bc0b450d0020022802b80b102a0b200241003602b802200241e80b6a4120200241b8026a100621010240024020022802b8022205417f460d002001450d00024020054104490d00200128000021092001102a200920004d0d02200220022800880b3602900920022002418b0b6a28000036009309200241003a00bb0220024180063b00b902200241013a00b80220022802a80c21030240200241b00c6a2802002201450d002001410c6c21002003210103400240200141046a280200450d002001280200102a0b2001410c6a2101200041746a22000d000b0b0240200241ac0c6a280200450d002003102a0b20022802b40c21030240200241bc0c6a2802002201450d002001410c6c21002003210103400240200141046a280200450d002001280200102a0b2001410c6a2101200041746a22000d000b0b200241b80c6a280200450d1a2003102a0c1a0b41c4d1c3004133200241c80c6a419cd9c3001038000b410021090b410c10282205450d05410410282201450d06200242043702bc02200220013602b802200241f0066a200241b8026a108f010240024020022802bc02220620022802c00222016b4104490d0020022802b80221070c010b200141046a22072001490d1a200641017422012007200120074b1b22014100480d1a0240024020060d002001102821070c010b20022802b80220062001102c21070b2007450d08200220013602bc02200220073602b80220022802c00221010b410421062002200141046a3602c002200720016a2000360000200241e80b6a41086a20022802c0022201360200200220022903b802220e3703e80b200541086a20013602002005200e370200410021010240200920004f0d00410c10282206450d09410410282201450d0a200242043702bc02200220013602b802200241f0066a200241b8026a108f010240024020022802bc02220720022802c00222016b4104490d0020022802b80221070c010b200141046a22092001490d1b200741017422012009200120094b1b22014100480d1b0240024020070d002001102821070c010b20022802b80220072001102c21070b2007450d0c200220013602bc02200220073602b80220022802c00221010b2002200141046a3602c002200720016a2000417f6a360000200241e80b6a41086a20022802c0022201360200200220022903b802220e3703e80b200641086a20013602002006200e370200410121010b20024190056a41206a42818080801037030020024190056a41186a2001360200200241a4056a2001360200200220022800880b3602900920022002418b0b6a28000036009309200241bc056a200228009309360000200241013a00b805200220053602ac05200220063602a0052002427f3703980520022008ad220e3703900520022002280290093600b905200241a80a6a200241980c6a20024190056a109b04200241980c6a41286a200241a80a6a41286a290300370300200241980c6a41206a200241a80a6a41206a290300370300200241980c6a41186a200241a80a6a41186a290300370300200241980c6a41106a200241a80a6a41106a290300370300200241980c6a41086a200241a80a6a41086a290300370300200220022903a80a3703980c200241b8026a200b4101712201200310b80320022d00b8020d14200241b8026a2008200110b90320022d00b802450d1320022f00b90220022d00bb024110747221010c150b200241e4076a2802002100200241b8026a10fb01200010fc0120022802b802220120022802c00241014100410010032103024020022802bc02450d002001102a0b41800621012003417f470d1510fb01220c200241e0076a280200470d15200241b80b6a41086a22014200370300200242003703b80b41c2e1c000410d200241b80b6a1008200241880b6a41086a2001290300370300200220022903b80b3703880b200241003602b802200241880b6a4110200241b8026a100621010240024020022802b8022203417f460d002001450d00200220033602bc0b200220013602b80b200241b8026a200241b80b6a107c20022802b802220b450d0c20022902bc02210e2003450d012001102a0c010b4101210b4200210e20022802e40721000b024002402000200e422088a74f0d00200b20004105746a2211450d00200241003602c002200242013703b802200241c4076a2802002100410410282201450d0d20024284808080c0003702bc02200220013602b80220012000360000200241c8076a2802002106200241d0076a2802002201200241b8026a10b4010240024020022802bc02220320022802c00222006b2001490d0020022802b80221030c010b200020016a22072000490d1b200341017422082007200820074b1b22074100480d1b0240024020030d002007102821030c010b20022802b80220032007102c21030b2003450d0f200220073602bc02200220033602b8020b2002200020016a3602c002200320006a20062001109a051a200241d4076a2802002100200241dc076a2802002201200241b8026a10b4010240024020010d0020022802bc02210620022802c00221090c010b20002001410c6c6a210a034020002802002108200041086a2802002201200241b8026a10b4010240024020022802bc02220620022802c00222036b2001490d0020022802b80221070c010b200320016a22072003490d1d200641017422092007200920074b1b22094100480d1d0240024020060d002009102821070c010b20022802b80220062009102c21070b2007450d12200220093602bc02200220073602b802200921060b2002200320016a22093602c002200720036a20082001109a051a2000410c6a2200200a470d000b0b20022802e007210302400240200620096b4104490d0020022802b80221010c010b200941046a22012009490d1b200641017422002001200020014b1b22004100480d1b0240024020060d002000102821010c010b20022802b80220062000102c21010b2001450d11200220003602bc02200220013602b802200021060b2002200941046a22003602c002200120096a200336000020022802e407210702400240200620006b41034d0d00200621030c010b200041046a22032000490d1b200641017422082003200820034b1b22034100480d1b0240024020060d002003102821010c010b200120062003102c21010b2001450d12200220033602bc02200220013602b8020b200120006a20073600002001200941086a200241e8076a2011100a210002402003450d002001102a0b2000450d010b4180082101200ea7450d16200b102a0c160b410c10282201450d10410410282200450d1120024284808080c0003702bc02200220003602b8022000200c3600002011200241b8026a108f01200241b80b6a41086a20022802c0022200360200200220022903b802220d3703b80b200141086a20003602002001200d370200200220022800880b3602d80a20022002418b0b6a2800003600db0a0240200ea7450d00200b102a0b20024190056a41206a42818080801037030020024190056a41186a4100360200200241bc056a20022800db0a360000200241013a00b805200220013602ac05200242043703a0052002427f370398052002420037039005200220022802d80a3600b905200241e80b6a200241980c6a20024190056a109b04200241b8026a41086a20022903e80b370300200241b8026a41106a200241e80b6a41086a290300370300200241b8026a41186a200241e80b6a41106a290300370300200241b8026a41206a200241e80b6a41186a290300370300200241b8026a41286a200241e80b6a41206a290300370300200241e8026a200241e80b6a41286a290300370300200241003a00b8020c160b200241246a410436020020024184036a4102360200200242023702f402200241bca7c4003602f0022002410436021c200241aca9c4003602182002410036029405200241b8aec600360290052002200241186a36028003200220024190056a360220200241f0026a41cca7c400103e000b41c4d1c3004133200241c80c6a419cd9c3001038000b41fcf8c5001032000b411341011037000b410c41041037000b410441011037000b200141011037000b410c41041037000b410441011037000b200141011037000b41c4d1c3004133200241c80c6a419cd9c3001038000b410441011037000b200741011037000b200941011037000b200041011037000b200341011037000b410c41041037000b410441011037000b20024190056a41206a2205420037030020024190056a41186a22064280808080c000370300200220022800880b3602e80b20022002418b0b6a2800003600eb0b200241bc056a20022800eb0b360000200242043703a0052002427f370398052002427f200e20011b37039005200220022802e80b3600b905200241013a00b805200241d80a6a200241980c6a20024190056a109b04200241e80b6a41286a2207200241d80a6a41286a290300370300200241e80b6a41206a2209200241d80a6a41206a290300370300200241e80b6a41186a2200200241d80a6a41186a290300370300200241e80b6a41106a220a200241d80a6a41106a290300370300200241e80b6a41086a220b200241d80a6a41086a290300370300200220022903d80a3703e80b20024190056a20022903a807200241b0076a290300200241f0066a200820012003109e02024020022d0090054101470d00200220022d0093053a00bb02200220022f0091053b00b902200241013a00b80220022802f80b2103024020002802002201450d002001410c6c21002003210103400240200141046a280200450d002001280200102a0b2001410c6a2101200041746a22000d000b0b0240200241fc0b6a280200450d002003102a0b20022802840c210302402002418c0c6a2802002201450d002001410c6c21002003210103400240200141046a280200450d002001280200102a0b2001410c6a2101200041746a22000d000b0b200241880c6a280200450d042003102a0c040b200241980c6a41286a20024190056a41306a2201290300370300200241980c6a41206a20024190056a41286a290300370300200241980c6a41186a2005290300370300200241980c6a41106a2006290300370300200241980c6a41086a20024190056a41106a29030037030020022002290398053703980c200241880b6a200241e80b6a200241980c6a109b042007200241880b6a41286a2903003703002009200241880b6a41206a2903003703002000200241880b6a41186a290300370300200a200241880b6a41106a290300370300200b200241880b6a41086a290300370300200220022903880b3703e80b20024190056a200410d203024020022d0090054101470d00200220022d0093053a00bb02200220022f0091053b00b902200241013a00b80220022802f80b21030240200241800c6a2802002201450d002001410c6c21002003210103400240200141046a280200450d002001280200102a0b2001410c6a2101200041746a22000d000b0b0240200241fc0b6a280200450d002003102a0b20022802840c210302402002418c0c6a2802002201450d002001410c6c21002003210103400240200141046a280200450d002001280200102a0b2001410c6a2101200041746a22000d000b0b200241880c6a280200450d042003102a0c040b200241980c6a41286a2001290300370300200241980c6a41206a20024190056a41286a290300370300200241980c6a41186a20024190056a41206a290300370300200241980c6a41106a20024190056a41186a290300370300200241980c6a41086a20024190056a41106a29030037030020022002290398053703980c200241b80b6a200241e80b6a200241980c6a109b04200241b8026a41086a20022903b80b370300200241b8026a41106a200241b80b6a41086a290300370300200241b8026a41186a200241b80b6a41106a290300370300200241b8026a41206a200241b80b6a41186a290300370300200241b8026a41286a200241b80b6a41206a290300370300200241b8026a41306a200241b80b6a41286a290300370300200241003a00b8020c030b20022f00b90220022d00bb024110747221010b200220022800880b3602e80b20022002418b0b6a2800003600eb0b200241013a00b802200220013b00b902200220014110763a00bb0220022802a80c21030240200241b00c6a2802002201450d002001410c6c21002003210103400240200141046a280200450d002001280200102a0b2001410c6a2101200041746a22000d000b0b0240200241ac0c6a280200450d002003102a0b20022802b40c21030240200241bc0c6a2802002201450d002001410c6c21002003210103400240200141046a280200450d002001280200102a0b2001410c6a2101200041746a22000d000b0b200241b80c6a280200450d012003102a0c010b200241003a00bb02200220013b00b902200241013a00b80220022802a80c2103024020052802002201450d002001410c6c21002003210103400240200141046a280200450d002001280200102a0b2001410c6a2101200041746a22000d000b0b0240200241ac0c6a280200450d002003102a0b20022802b40c21030240200241bc0c6a2802002201450d002001410c6c21002003210103400240200141046a280200450d002001280200102a0b2001410c6a2101200041746a22000d000b0b200241b80c6a280200450d002003102a0b2004106a20022d00b80221000b024002400240024002400240410110282201450d00200242013702f406200220013602f00602400240200041ff01714101460d00200241013602f806200141003a0000200241c0026a290300210e024020022802f4062200417f6a41074b0d00200041017422034109200341094b1b22034100480d09200120002003102c2201450d04200220033602f406200220013602f0060b200241093602f8062001200e370001200241d0026a2802002100200241d8026a2802002201200241f0066a10b40102402001450d0020002001410c6c6a2108034020002802002106200041086a2802002201200241f0066a10b4010240024020022802f406220520022802f80622036b2001490d0020022802f00621050c010b200320016a22072003490d0b200541017422042007200420074b1b22074100480d0b0240024020050d002007102821050c010b20022802f00620052007102c21050b2005450d07200220073602f406200220053602f0060b2002200320016a3602f806200520036a20062001109a051a2000410c6a22002008470d000b0b200241dc026a2802002100200241e4026a2802002201200241f0066a10b4010240024020010d0020022802f406210620022802f80621080c010b20002001410c6c6a2104034020002802002107200041086a2802002201200241f0066a10b4010240024020022802f406220620022802f80622036b2001490d0020022802f00621050c010b200320016a22052003490d0b200641017422082005200820054b1b22084100480d0b0240024020060d002008102821050c010b20022802f00620062008102c21050b2005450d08200220083602f406200220053602f006200821060b2002200320016a22083602f806200520036a20072001109a051a2000410c6a22002004470d000b0b200241c8026a290300210e02400240200620086b4108490d0020022802f00621030c010b200841086a22012008490d09200641017422002001200020014b1b22014100480d090240024020060d002001102821030c010b20022802f00620062001102c21030b2003450d07200220013602f406200220033602f0060b2002200841086a3602f806200320086a200e370000024020022802f40620022802f8062201470d00200141016a22002001490d09200141017422052000200520004b1b22004100480d090240024020010d002000102821030c010b200320012000102c21030b2003450d08200220003602f406200220033602f0060b2002200141016a22053602f806200320016a20022d00e8023a00000c010b200241013602f806200141013a0000200241b8026a410172200241f0066a10c60320022802f806210520022802f00621030b024020022d00b8020d000240200241d8026a2802002200450d00200241d0026a28020021012000410c6c210003400240200141046a280200450d002001280200102a0b2001410c6a2101200041746a22000d000b0b0240200241d4026a280200450d0020022802d002102a0b0240200241e4026a2802002200450d00200241dc026a28020021012000410c6c210003400240200141046a280200450d002001280200102a0b2001410c6a2101200041746a22000d000b0b200241e0026a280200450d0020022802dc02102a0b200241d00c6a24002005ad4220862003ad840f0b410141011037000b200341011037000b200741011037000b200841011037000b200141011037000b200041011037000b1031000bd40505017f027e077f017e017f230041206b220324002002290300210420012903002105200141106a2106200228021021070240024002400240024002400240200141146a2802002208200141186a28020022096b200241186a280200220a490d00200628020021080c010b2009200a6a220b2009490d032008410174220c200b200c200b4b1b220bad420c7e220d422088a70d03200da7220c4100480d030240024020080d00200c102821080c010b20062802002008410c6c200c102c21080b2008450d0120012008360210200141146a200b3602000b20082009410c6c6a2007200a410c6c109a051a200141186a2009200a6a36020020024100360218200341086a200641086a280200360200200320062902003703002001411c6a2106200228021c210b02400240200141206a2802002208200141246a28020022096b200241246a280200220a490d00200628020021080c010b2009200a6a220c2009490d032008410174220e200c200e200c4b1b220cad420c7e220d422088a70d03200da7220e4100480d030240024020080d00200e102821080c010b20062802002008410c6c200e102c21080b2008450d022001200836021c200141206a200c3602000b427f200520047c220420042005541b210520082009410c6c6a200b200a410c6c109a051a200141246a2009200a6a36020020024100360224200341106a41086a200641086a28020036020020032006290200370310200229030822042001290308220d200d2004561b210420012d0028450d034101210120022d0028450d030c040b200c41041037000b200e41041037000b1031000b410021010b20002005370300200020032903003702102000200329031037021c200020013a002820002004370308200041186a200341086a280200360200200041246a200341106a41086a2802003602000240200241146a280200450d002007102a0b0240200241206a280200450d00200b102a0b200341206a24000ba13507037f017e037f017e147f027e107f230041d0036b2202240002400240024002400240024002400240024020014104490d0020002800002103101a4101470d07200241a8016a41086a22004200370300200242003703a801419be1c0004111200241a8016a1008200241e8006a41086a2000290300370300200220022903a80137036841002101200241003602a801200241e8006a4110200241a8016a100621000240024020022802a8012204417f460d002000450d0020044104490d01200028000021012000102a0b200241003602a801410141838ac100411c200241a8016a101b2100024002400240024020022802a8012204417f470d00410121040c010b2004ad22054220862005842105200045210420000d010b41002100410121060c010b2005422088a74105490d04200028000121070240024020002d00000d0020072003460d0141002106200720034f0d02410121060c020b4101210620072001490d010b410021060b200120034f0d022006450d020240410110282201450d00200141003a00000240200141014105102c2201450d0020012003360001410141838ac100411c4100200020041b22062005422088a7417f20061b20014105101c21062001102a024020042005a745720d002000102a0b20060d0a200241a8016a41086a22004200370300200242003703a80141c2e1c000410d200241a8016a1008200241e8006a41086a2000290300370300200220022903a801370368200241003602a801200241e8006a4110200241a8016a1006210002400240024020022802a8012201417f460d002000450d002002200136022c20022000360228200241a8016a200241286a107c20022802a8012208450d0220022902ac0121092001450d012000102a0c010b42002109410121080b200241186a109d042002280218210a2002280220220b4115490d07200b410176220c41ffffff3f71200c470d09200c4105742200417f4c0d094101210d024002402000450d0020001028220d450d010b200a41606a210e200a41a07f6a210f41002110410021114104211241002113200b211403400240024020142215417f6a22040d0041012107410021140c010b024002400240024002400240200a20044105746a20154105742216200a6a41406a4120109c054100480d002015417e6a2106200f20166a210041002114410021010340024020062001470d00201521070c080b200141016a2101200041206a20004120109c052104200041606a21002004417f4a0d000b200141016a21072001417f7320156a21040c010b200f20166a210002400340024020044101470d00410021040c020b2004417f6a2104200041206a20004120109c052101200041606a210020014100480d000b0b20152004490d012015200b4b0d03201520046b22074101762206450d00200e20166a2100200a20044105746a21010340200241a8016a41186a2216200141186a2217290000370300200241a8016a41106a2218200141106a2219290000370300200241a8016a41086a221a200141086a221b290000370300200220012900003703a801200041086a221c2900002105200041106a221d290000211e200041186a2214290000211f200120002900003700002017201f3700002019201e370000201b200537000020142016290300370000201d2018290300370000201c201a290300370000200020022903a801370000200041606a2100200141206a21012006417f6a22060d000b0b024020040d00200421140c050b0240200741094d0d00200421140c050b2015200b4b0d01201520046b2106200a20044105746a2116034020152004417f6a2214490d040240201520146b22074102490d00200a20044105746a2200200a20144105746a22044120109c05417f4a0d002004290000210520042000290000370000200241a8016a41186a221a200441186a2201290000370300200241a8016a41106a221b200441106a2217290000370300200241a8016a41086a221c200441086a22182900003703002018200041086a2900003700002017200041106a2900003700002001200041186a290000370000200220053703a80141012119024020074103490d00200441c0006a200241a8016a4120109c05417f4a0d00410221012016210002400340200041186a200041386a290000370000200041106a200041306a290000370000200041086a200041286a2900003700002000200041206a221729000037000020062001460d01200041c0006a21182001211920172100200141016a21012018200241a8016a4120109c05417f4a0d020c000b0b200121190b200420194105746a220020022903a801370000200041186a201a290300370000200041106a201b290300370000200041086a201c2903003700000b2014450d05201641606a2116200641016a2106201421042007410a4f0d050c000b0b200420151044000b20152004417f6a2214490d010b2015200b103c000b201420151044000b02400240024020132011470d00201141016a22002011490d11201141017422012000200120004b1b220041ffffffff01712000470d11200041037422014100480d110240024020110d002001102821120c010b201220114103742001102c21120b2012450d0120002111201021130b201220134103746a2200200736020420002014360200201041016a2213211020134102490d0102400340024002400240024020122013417f6a22104103746a2200280200450d00201341037420126a220641746a2802002204200028020422014d0d000240201341024b0d0020132110410221130c080b20122013417d6a221a4103746a2802042200200120046a4d0d010240201341034b0d0020132110410321130c080b200641646a280200200020046a4d0d01201321100c070b20134103490d012000280204210120122013417d6a221a4103746a28020421000b20002001490d010b2013417e6a211a0b0240024002400240024002402013201a41016a22204b2221450d002013201a4b2222450d012012201a4103746a221b2802042223201b2802006a2200201220204103746a221c280200221d490d022000200b4b0d03200a201d4105746a2218201c280204221941057422016a2106200041057421042000201d6b221520196b220020194f0d04200d200620004105742201109a05221720016a21070240024020194101480d00200041014e0d010b20062100201721010c060b200e20046a21042006210003402004200041606a2206200741606a2215201520064120109c0541004822161b2201290000370000200441186a200141186a290000370000200441106a200141106a290000370000200441086a200141086a2900003700002007201520161b2107024020182006200020161b2200490d00201721010c070b200441606a21042017210120172007490d000c060b0b41b8dbc000202020131034000b41b8dbc000201a20131034000b201d20001044000b2000200b103c000b200d20182001109a05221720016a21070240024020194101480d00201520194a0d010b20182100201721010c010b200a20046a211620172101201821000340200020062001200620014120109c0541004822151b2204290000370000200041186a200441186a290000370000200041106a200441106a290000370000200041086a200441086a2900003700002001200141206a20151b2101200041206a2100200641206a200620151b220620164f0d01200720014b0d000b0b20002001200720016b416071109a051a02402022450d00201b201d360200201b41046a202320196a3602002021450d02201c201c41086a20132020417f736a410374109b051a20102113201041014d0d040c010b0b41c8dbc000201a20131034000b41b0b1c0001032000b200141041037000b20140d000b02402011450d002012102a0b200c450d09200d102a0c090b200041011037000b41c4d1c3004133200241186a419cd9c3001038000b410541011037000b410141011037000b41c4d1c3004133200241186a419cd9c3001038000b200241f4006a4104360200200241bc016a4102360200200242023702ac01200241bca7c4003602a8012002410436026c200241c8a9c4003602682002410036022c200241b8aec6003602282002200241e8006a3602b8012002200241286a360270200241a8016a41cca7c400103e000b20042005a745720d052000102a0c050b02402005a7450d002000102a0b41e695c600412d100b0c040b200b4102490d00200a200b417f6a22014105746a21074101210403400240024002400240200b20012200417f6a2201490d00200b20016b22154102490d03200a20004105746a2200200a20014105746a22064120109c05417f4a0d032006290000210520062000290000370000200241a8016a41186a2213200641186a2216290000370300200241a8016a41106a2219200641106a2217290000370300200241a8016a41086a2212200641086a22182900003703002018200041086a2900003700002017200041106a2900003700002016200041186a290000370000200220053703a8014101210020154103490d02200641c0006a200241a8016a4120109c05417f4a0d0241002115200721000340200041186a200041386a290000370000200041106a200041306a290000370000200041086a200041286a2900003700002000200041206a2217290000370000200420152216460d022016417f6a2115200041c0006a2118201721002018200241a8016a4120109c05417f4a0d020c000b0b2001200b1044000b410220166b21000b200620004105746a220020022903a801370000200041186a2013290300370000200041106a2019290300370000200041086a20122903003700000b200741606a21072004417f6a210420010d000b0b2009a721102009422088a72200450d01200820004105746a2118200241a8016a41016a211a200241c0026a2124200241e9026a211b200241e0016a2125200241a8016a41306a2126200241a8016a41286a212741002115200821070240024002400240024002400340024002400240200b41014b0d000240200b0e020c000c0b0340200241a8016a41186a200741186a290000370300200241a8016a41106a200741106a290000370300200241a8016a41086a200741086a290000370300200220072900003703a801200a200241a8016a4120109c05450d02201541016a21152018200741206a2207470d000c0c0b0b0340200241a8016a41186a200741186a290000370300200241a8016a41106a200741106a290000370300200241a8016a41086a200741086a290000370300200220072900003703a801200741206a21070240200b450d0041002100200b210103402001410176220420006a22062000200a20064105746a200241a8016a4120109c054101481b2100200120046b220141014b0d000b200a20004105746a200241a8016a4120109c05450d030b201541016a211520072018460d0b0c000b0b200741206a2107410021000b0240024002400240024002400240200b20004d0d0020024100360268200241e8006a101d2104024020022802682201417f470d00410221060c0a0b200220013602ac01200220043602a8012001450d0320042d0000210620022001417f6a3602ac012002200441016a3602a801200641014b0d030240024020060e020100010b410021202021210c2012211c2019211420132128201721292016211d2021212a2012212b2019212c2013212d2017212e2016212f0c060b200241106a200241a8016a106c20022802100d0320022802ac0122062002280214222b490d03202b417f4c0d0e02400240202b0d004101212041010d010c050b202b102e2220450d02202020022802a801221c202b109a05211d20022006202b6b3602ac012002201c202b6a3602a801201d450d040b200241086a200241a8016a106c20022802080d0220022802ac01410c6e222e410c6c2206417f4c0d0e200228020c212f0240024002400240024020060d004104212d0c010b20061028222d450d010b024002400240202f0d00202d212c0c010b4100210c4100211c41002114202d212c03402002200241a8016a106c20022802000d0220022802ac01221d20022802042206490d022006417f4c0d140240024020060d00410121290c010b2006102e2229450d05202920022802a80122282006109a051a2002201d20066b3602ac012002202820066a3602a8010b201441016a211d02402014202e470d00200c201d200c201d4b1b222ead420c7e2205422088a70d182005a722284100480d180240024020140d0020281028212d0c010b202d201c2028102c212d0b202d450d06202d212c0b202c201c6a22142029360200201441046a2006ad2205422086200584370200200c41026a210c201c410c6a211c201d2114202f201d470d000b0b202c450d06202b212a202f211d202e2129202d2128202c2114202b211c202b210c20200d080c070b02402014450d004100210603400240202c20066a221d41046a280200450d00201d280200102a0b201c2006410c6a2206470d000b0b202e450d05202d102a0c050b200641041037000b200641011037000b202841041037000b41a08ac1002000200b1034000b202b41011037000b202b450d002020102a0b410021202016212f2017212e2013212d2019212c2012212b2021212a2022211d20232129200d212820112114200e211c200f210c0b2001450d010b2004102a0b024020200d00410221060c030b10fb012121200241003602b001200242013703a80102400240024002400240410410282201450d0020024284808080c0003702ac01200220013602a80120012003360000201c200241a8016a10b4010240024020022802ac01220420022802b00122016b201c490d0020022802a80121040c010b2001201c6a22062001490d10200441017422162006201620064b1b22064100480d100240024020040d002006102821040c010b20022802a80120042006102c21040b2004450d02200220063602ac01200220043602a8010b20022001201c6a3602b001200420016a2020201c109a051a201d200241a8016a10b401201d450d022014201d410c6c6a211220142104034020042802002113200441086a2802002201200241a8016a10b4010240024020022802ac01221620022802b00122066b2001490d0020022802a80121170c010b200620016a22172006490d11201641017422192017201920174b1b22194100480d110240024020160d002019102821170c010b20022802a80120162019102c21170b2017450d05200220193602ac01200220173602a801201921160b2002200620016a22193602b001201720066a20132001109a051a2004410c6a22042012470d000c050b0b410441011037000b200641011037000b20022802ac01211620022802b00121190c010b201941011037000b02400240201620196b4104490d0020022802a80121010c010b201941046a22012019490d0b201641017422042001200420014b1b22044100480d0b0240024020160d002004102821010c010b20022802a80120162004102c21010b2001450d04200220043602ac01200220013602a801200421160b2002201941046a22043602b001200120196a202136000002400240201620046b41034d0d00201621060c010b200441046a22062004490d0b201641017422172006201720064b1b22064100480d0b0240024020160d002006102821010c010b200120162006102c21010b2001450d05200220063602ac01200220013602a8010b200120046a2015360000200241e9dabdf3063602cc03202542003703002026420037030020274200370300200241a8016a41206a4200370300200241a8016a41186a4200370300200241a8016a41106a4200370300200241a8016a41086a4200370300200242003703a8010240200241cc036a200a20004105746a2001201941086a200241a8016a101e0d00200241e8006a41086a2200201a41086a290000370300200241e8006a41106a2204201a41106a290000370300200241e8006a41186a2216201a41186a290000370300200241e8006a41206a2217201a41206a290000370300200241e8006a41286a2213201a41286a290000370300200241e8006a41306a2219201a41306a290000370300200241e8006a41376a2212201a41376a2900003700002002201a29000037036820022d00a8012122200241286a41086a22232000290300370300200241286a41106a22002004290300370300200241286a41186a22042016290300370300200241286a41206a22162017290300370300200241286a41286a22172013290300370300200241286a41306a22132019290300370300200241286a41376a221920122900003700002002200229036837032802402006450d002001102a0b201b2002290328370000201b41086a2023290300370000201b41106a2000290300370000201b41186a2004290300370000201b41206a2016290300370000201b41286a2017290300370000201b41306a2013290300370000201b41376a2019290000370000200220223a00e802200220153602e402200220213602e0022002201d3602dc02200220293602d802200220283602d4022002201c3602d0022002200c3602cc02200220203602c802200220033602c402200241123602c0022002420237039002200241e8006a200241a8016a108704200228026c2100200228026822042002280270101f210102402000450d002004102a0b2024106a20010d02410110282200450d06200041013a0000200041014105102c2200450d07201541016a211520002003360001410141838ac100411c2000410510202000102a202f2116202e2117202d2113202c2119202b2112202a2121201d2122202921232028210d20142111201c210e200c210f20072018470d010c090b0b02402006450d002001102a0b0240200c450d002020102a0b0240201d450d00201d410c6c210003400240201441046a280200450d002014280200102a0b2014410c6a2114200041746a22000d000b0b410121062029450d012028102a0c010b410321060b02402010450d002008102a0b0240200228021c450d00200a102a0b412e2104419396c6002100200241186a2101024002400240024020060e0400010203000b412d210441e695c6002100200241286a21010c020b411f210441c795c6002100200241e8006a21010c010b419995c6002100200241a8016a21010b200120043602042001200036020020002004100b0c060b200441011037000b200641011037000b410141011037000b410541011037000b1036000b02402010450d002008102a0b200228021c450d00200a102a0b200241d0036a240042010f0b1031000bcb06020d7f037e230041e0006b22012400200141e9dabdf306360208410021022001410036020c200141086a2001410c6a102621032001200128020c360214200120033602102001200141106a106c2001280204210441002105024002400240024020012802000d00200128021422034160712206417f4c0d0202400240200341057622070d00410121050c010b200610282205450d020b2004450d0041002108034020032109200141003a00582008220a41016a2108410021030240024002400240034020092003460d01200141386a20036a200128021022062d00003a00002001200641016a3602102001200341016a22063a00582006210320064120470d000b200141186a41186a220b200141386a41186a290300370300200141186a41106a220c200141386a41106a290300370300200141186a41086a220d200141386a41086a290300370300200120012903383703182007200a470d03200a41017422032008200320084b1b220741ffffff3f712007470d082007410574220341004e0d010c080b200141003602140240200341ff0171450d00200141003a00580b2007450d012005102a0c010b02400240200a0d002003102821050c010b2005200a4105742003102c21050b20050d01200341011037000b410021050c020b200920066b21032005200a4105746a220a2001290318370000200a41186a200b290300370000200a41106a200c290300370000200a41086a200d29030037000020082004470d000b2001200920066b3602140b4101210a2005410120051b21084100210302402004410020051b2206450d0020064105742203410575220241ffffff3f712002470d03200241057422094100480d03024020091028220a0d00200941011037000b200820036a210420064105742109200a2103200821060340200641086a290000210e200641106a290000210f20062900002110200341186a200641186a290000370000200341106a200f370000200341086a200e37000020032010370000200341206a2103200641206a2106200941606a22090d000b200420086b41606a41057641016a21030b02402005450d002007450d002008102a0b20002003360208200020023602042000200a360200200141e0006a24000f0b200641011037000b1036000b1031000bf80303047f027e037f230041306b22022400200241106a41086a220342003703002002420037031041c694c600411b200241106a1008200241086a200329030037030020022002290310370300410021032002410036021020024110200241106a100621040240024002400240024020022802102205417f470d000c010b2002200536022420022004360220200241106a200241206a107720022802102203450d01200229021421062005450d002004102a0b20024100360218200242013703102006420020031b2207422088a72205200241106a10b4012003410820031b210802402005450d002008200541286c6a21092008210503402005200241106a108f01200541206a29030021060240024020022802142204200228021822036b4108490d00200228021021040c010b200341086a220a2003490d0520044101742203200a2003200a4b1b22034100480d050240024020040d002003102821040c010b200228021020042003102c21040b2004450d042002200336021420022004360210200228021821030b2002200341086a360218200420036a20063700002009200541286a2205470d000b0b200235021821062002280210210302402007a7450d002008102a0b200241306a240020064220862003ad840f0b41c4d1c3004133200241286a419cd9c3001038000b200341011037000b1031000b9d0d04047f017e027f017e230041c0016b22022400200241086a41086a220342003703002002420037030841eefbc5004110200241086a1008200241a0016a41086a2003290300370300200220022903083703a0014100210320024100360208200241a0016a4110200241086a10062104024002400240024002400240024002400240024020022802082205417f470d000c010b024020040d000c010b2002200536027c20022004360278200241086a200241f8006a107720022802082203450d01200229020c21062005450d002004102a0b200241086a41086a2205420037030020024200370308419efcc500410f200241086a1008200241a0016a41086a22042005290300370300200220022903083703a001200241f8006a200241a0016a10ef0220022d00782105200241a0016a41186a220720024191016a290000370300200241a0016a41106a220820024189016a290000370300200420024181016a290000370300200220022900793703a0012006420020031b21062003410820031b21030240024020054101460d00200241d8006a41186a4200370300200241d8006a41106a4200370300200241d8006a41086a4200370300200242003703580c010b200241d8006a41186a2007290300370300200241d8006a41106a2008290300370300200241d8006a41086a2004290300370300200220022903a0013703580b2002412c6a2006370200200241086a41186a42043703002002413c6a200241d8006a41086a290300370200200241c4006a200241e8006a290300370200200241cc006a200241d8006a41186a2903003702002002200336022820024201370318200242c801370310200242b81737030820022002290358370234200241013a0054200241003602800120024201370378410810282203450d012002410836027c2002200228028001220441086a3602800120022003360278200320046a42b8173700002002290310210602400240200228027c220420022802800122036b4108490d00200228027821040c010b200341086a22052003490d08200441017422032005200320054b1b22034100480d080240024020040d002003102821040c010b200228027820042003102c21040b2004450d032002200336027c2002200436027820022802800121030b2002200341086a36028001200420036a20063700002002290318210602400240200228027c220420022802800122036b4108490d00200228027821040c010b200341086a22052003490d08200441017422032005200320054b1b22034100480d080240024020040d002003102821040c010b200228027820042003102c21040b2004450d042002200336027c2002200436027820022802800121030b2002200341086a36028001200420036a20063700002002290320210602400240200228027c220420022802800122036b4108490d00200228027821040c010b200341086a22052003490d08200441017422032005200320054b1b22034100480d080240024020040d002003102821040c010b200228027820042003102c21040b2004450d052002200336027c2002200436027820022802800121030b2002200341086a36028001200420036a200637000020022802282104200241086a41286a2802002203200241f8006a10b40102402003450d002004200341286c6a210803402004200241f8006a108f01200441206a290300210602400240200228027c220520022802800122036b4108490d00200228027821050c010b200341086a22072003490d0a200541017422032007200320074b1b22034100480d0a0240024020050d002003102821050c010b200228027820052003102c21050b2005450d082002200336027c2002200536027820022802800121030b2002200341086a36028001200520036a20063700002008200441286a2204470d000b0b200241346a200241f8006a10f10202400240200228027c2002280280012203460d00200228027821040c010b200341016a22042003490d08200341017422052004200520044b1b22054100480d080240024020030d002005102821040c010b200228027820032005102c21040b2004450d072002200536027c2002200436027820022802800121030b2002200341016a36028001200420036a20022d00543a00002002350280012106200235027821090240200228022c450d002002280228102a0b200241c0016a240020064220862009840f0b41c4d1c3004133200241d8006a419cd9c3001038000b410841011037000b200341011037000b200341011037000b200341011037000b200341011037000b200541011037000b1031000baa0607017f017e077f017e027f017e027f230041c0006b2202240042002103200241086a2204420037030020024200370300419695c400411720021008200241206a41086a20042903003703002002200229030037032020024100360200200241206a411020021006210502400240024002400240024020022802002204417f460d0020022004360234200220053602302002200241306a107c20022802002206450d02200229020421032004450d012005102a0c010b410121060b41002107024002402003422088a7220441057422080d00410421094100210a0c010b2008410575220aad420c7e220b422088a70d04200ba722054100480d04200510282209450d020b2003a7210c02402004450d00200841606a210d20092105200621040340200441086a2900002103200441106a290000210b2004290000210e200241186a200441186a290000370300200241106a200b370300200241086a20033703002002200e370300200241206a2002108b04200541086a200241206a41086a280200360200200520022903203702002005410c6a2105200441206a2104200841606a22080d000b200d41057641016a21070b0240200c450d002006102a0b20024100360208200242013703002007200210b4010240024020070d002002280208210d200228020021060c010b20092007410c6c6a210f2009210503402005280200210c200541086a2802002204200210b4010240024020022802042206200228020822086b2004490d00200228020021060c010b200820046a220d2008490d0620064101742210200d2010200d4b1b220d4100480d060240024020060d00200d102821060c010b20022802002006200d102c21060b2006450d052002200d360204200220063602000b2002200820046a220d360208200620086a200c2004109a051a2005410c6a2205200f470d000b2007410c6c21052009210403400240200441046a280200450d002004280200102a0b2004410c6a2104200541746a22050d000b0b0240200a450d002009102a0b200241c0006a2400200dad4220862006ad840f0b41c4d1c3004133200241386a419cd9c3001038000b200541041037000b200d41011037000b1031000baf1905047f017e057f037e3c7f230041d0016b22022400024002402001450d00200220003602100c010b200241013602100b20022001360214200241086a200241106a106c024002400240024002400240024002400240024002400240024020022802080d0020022802142201200228020c2200490d002000417f4c0d010240024020000d00410121030c010b2000102e2203450d032003200228021022042000109a051a2002200120006b3602142002200420006a3602100b2003450d0020024188016a41086a220142003703002002420037038801419695c400411720024188016a1008200241e8006a41086a200129030037030020022002290388013703682002410036028801200241e8006a411020024188016a10062101024002402002280288012204417f460d002001450d002002200436025c2002200136025820024188016a200241d8006a107c2002280288012205450d05200229028c0121062004450d012001102a0c010b41012105420021060b200241d8006a109d044100210702402006422088a72201450d00200520014105746a21082002280258220920022802604105746a210a2005210b0340200b41086a290000210c200b41106a290000210d200b290000210e20024188016a41186a200b41186a29000037030020024188016a41106a200d37030020024188016a41086a200c3703002002200e37038801200b41206a210b20092101024003400240200a20016b41e0004b0d0002402001200a460d00034020024188016a2001460d04200120024188016a4120109c05450d04200a200141206a2201470d000b0b200b2008470d030c040b200120024188016a460d01200120024188016a4120109c05450d01200141206a220420024188016a460d01200420024188016a4120109c05450d01200141c0006a220420024188016a460d01200420024188016a4120109c05450d01200141e0006a220420024188016a460d0120014180016a2101200420024188016a4120109c050d000b0b0b200241e8006a41186a20024188016a41186a290300220c370300200241386a41086a20024188016a41086a290300370300200241386a41106a20024188016a41106a290300370300200241386a41186a200c3703002002200229038801370338410121070b2006a721010240200228025c450d002002280258102a0b02402001450d002005102a0b200241e8006a41186a2201200241386a41186a290300370300200241e8006a41106a2204200241386a41106a290300370300200241e8006a41086a220b200241386a41086a290300370300200220022903383703682007450d0b200241186a41186a2001290300370300200241186a41106a2004290300370300200241186a41086a200b29030037030020022002290368370318200241e9dabdf306360268200241c0016a4200370300200241b8016a4200370300200241b0016a4200370300200241a8016a420037030020024188016a41186a420037030020024188016a41106a420037030020024188016a41086a4200370300200242003703880102400240200241e8006a200241186a2003200020024188016a101e450d00410021010c010b4101210120022d00c701210f20022d00c601211020022d00c501211120022d00c401211220022d00c301211320022d00c201211420022d00c101211520022d00c001211620022d00bf01211720022d00be01211820022d00bd01211920022d00bc01211a20022d00bb01211b20022d00ba01211c20022d00b901211d20022d00b801211e20022d00b701211f20022d00b601212020022d00b501212120022d00b401212220022d00b301212320022d00b201212420022d00b101212520022d00b001212620022d00af01212720022d00ae01212820022d00ad01212920022d00ac01212a20022d00ab01212b20022d00aa01212c20022d00a901212d20022d00a801212e20022d00a701212f20022d00a601213020022d00a501213120022d00a401213220022d00a301213320022d00a201213420022d00a101213520022d00a001213620022d009f01213720022d009e01213820022d009d01213920022d009c01213a20022d009b01213b20022d009a01213c20022d009901213d20022d009801213e20022d009701213f20022d009601214020022d009501214120022d009401214220022d009301214320022d009201214420022d009101214520022d009001214620022d008f01214720022d008e01214820022d008d01214920022d008c01214a20022d008b01210820022d008a01210920022d008901210720022d00880121050b20024188016a41186a2204200241186a41186a29030037030020024188016a41106a220b200241186a41106a29030037030020024188016a41086a220a200241186a41086a29030037030020022002290318370388012001450d0b200241e8006a41186a20042903002206370300200241e8006a41106a200b290300220c370300200241e8006a41086a200a290300220d3703002002200229038801220e37036820042006370300200b200c370300200a200d3703002002200e37038801410110282201450d04200120053a0000200141014102102c2201450d05200120073a0001200141024104102c2201450d06200120083a0003200120093a0002200141044108102c2201450d07200120473a0007200120483a0006200120493a00052001204a3a0004200141084110102c2201450d082001203f3a000f200120403a000e200120413a000d200120423a000c200120433a000b200120443a000a200120453a0009200120463a0008200141104120102c2201450d092001202f3a001f200120303a001e200120313a001d200120323a001c200120333a001b200120343a001a200120353a0019200120363a0018200120373a0017200120383a0016200120393a00152001203a3a00142001203b3a00132001203c3a00122001203d3a00112001203e3a00102001412041c000102c2201450d0a2001200f3a003f200120103a003e200120113a003d200120123a003c200120133a003b200120143a003a200120153a0039200120163a0038200120173a0037200120183a0036200120193a00352001201a3a00342001201b3a00332001201c3a00322001201d3a00312001201e3a00302001201f3a002f200120203a002e200120213a002d200120223a002c200120233a002b200120243a002a200120253a0029200120263a0028200120273a0027200120283a0026200120293a00252001202a3a00242001202b3a00232001202c3a00222001202d3a00212001202e3a0020200241386a20024188016a108b042002280240210b200228023c2109200228023821050c0c0b200241f4006a41043602002002419c016a41023602002002420237028c01200241bca7c400360288012002410436026c200241e0a9c4003602682002410036023c200241b8aec6003602382002200241e8006a360298012002200241386a36027020024188016a41cca7c400103e000b1036000b200041011037000b41c4d1c3004133200241c8016a419cd9c3001038000b410141011037000b410241011037000b410441011037000b410841011037000b411041011037000b412041011037000b41c00041011037000b410021010b0240024002400240410110282204450d00200242818080801037028c0120022004360288010240024020010d00200441003a000042808080801021060c010b200441013a000041c00020024188016a10b40102400240200228028c01220720022802900122046b41c000490d00200441c0006a210a20022802880121070c010b200441c0006a220a2004490d0520074101742208200a2008200a4b1b22084100480d050240024020070d002008102821070c010b20022802880120072008102c21070b2007450d032002200836028c0120022007360288010b200720046a220441086a200141086a290000370000200441106a200141106a290000370000200441186a200141186a290000370000200441206a200141206a290000370000200441286a200141286a290000370000200441306a200141306a290000370000200441386a200141386a2900003700002002200a3602900120042001290000370000200b20024188016a10b40102400240200228028c012204200228029001220a6b200b490d0020022802880121040c010b200a200b6a2207200a490d05200441017422082007200820074b1b22074100480d050240024020040d002007102821040c010b20022802880120042007102c21040b2004450d042002200736028c0120022004360288010b2002200a200b6a2207360290012004200a6a2005200b109a051a2001102a2007ad42208621062009450d002005102a0b02402000450d002003102a0b200241d0016a240020062004ad840f0b410141011037000b200841011037000b200741011037000b1031000baf0e04077f027e047f077e23004190026b22022400024002402001450d00200220003602200c010b200241013602200b20022001360224200241186a200241206a106c024002400240024020022802180d0020022802242201200228021c2203490d000240024002402003417f4c0d000240024020030d00410121040c010b2003102e2204450d022004200228022022002003109a051a2002200120036b3602242002200020036a3602200b2004450d03200241106a200241206a106c20022802100d052002280224220120022802142200490d052000417f4c0d000240024020000d00410121050c010b2000102e2205450d032005200228022022062000109a051a2002200120006b3602242002200620006a3602200b2005450d05200241086a200241206a106c024020022802080d0020022802242206200228020c2201490d002001417f4c0d010240024020010d00410121070c010b2001102e2207450d062007200228022022082001109a051a2002200620016b3602242002200820016a3602200b2007450d002001ad2209422086200984210941002101200241003a00c8012000ad220a422086200a84220a422088a72108200521000240024002400240034020082001460d0120024188016a20016a20002d00003a00002002200141016a22063a00c801200041016a210020062101200641c000470d000b200241d0016a41386a220120024188016a41386a290300370300200241d0016a41306a220020024188016a41306a290300370300200241d0016a41286a220820024188016a41286a290300370300200241d0016a41206a220b20024188016a41206a290300370300200241d0016a41186a220c20024188016a41186a290300370300200241d0016a41106a220d20024188016a41106a290300370300200241d0016a41086a220e20024188016a41086a29030037030020022002290388013703d001200641ff017141c000490d02200241c8006a41386a22062001290300370300200241c8006a41306a2000290300220f370300200241c8006a41286a20082903002210370300200241c8006a41206a200b2903002211370300200241c8006a41186a200c2903002212370300200241c8006a41106a200d2903002213370300200241c8006a41086a200e2903002214370300200220022903d00122153703482000200f37030020082010370300200b2011370300200c2012370300200d2013370300200e201437030020012006290300370300200220153703d00141002101200241003a00a8012009422088a7210820072100034020082001460d0220024188016a20016a20002d00003a00002002200141016a22063a00a801200041016a21002006210120064120470d000b200241286a41186a220120024188016a41186a2200290300370300200241286a41106a220620024188016a41106a2208290300370300200241286a41086a220b20024188016a41086a220c290300370300200220022903880137032820024188016a41386a200241d0016a41386a29030037030020024188016a41306a200241d0016a41306a29030037030020024188016a41286a200241d0016a41286a29030037030020024188016a41206a200241d0016a41206a2903003703002000200241d0016a41186a2903003703002008200241d0016a41106a290300370300200c200241d0016a41086a290300370300200220022903d00137038801200241c8006a41186a2001290300370300200241c8006a41106a2006290300370300200241c8006a41086a200b290300370300200220022903283703482004200320024188016a200241c8006a100a4521000c030b200141ff0171450d01200241003a00c8010c010b200141ff0171450d00200241003a00a8010b410021000b410110282201450d07200120003a000002402009a7450d002007102a0b0240200aa7450d002005102a0b02402003450d002004102a0b20024190026a24002001ad428080808010840f0b200241dc016a41043602002002419c016a41023602002002420237028c01200241bca7c40036028801200241043602d401200241eca9c4003602d0012002410036024c200241b8aec6003602482002200241d0016a360298012002200241c8006a3602d80120024188016a41cca7c400103e000b1036000b200341011037000b200041011037000b200241dc016a41043602002002419c016a41023602002002420237028c01200241bca7c40036028801200241043602d401200241eca9c4003602d0012002410036024c200241b8aec6003602482002200241d0016a360298012002200241c8006a3602d80120024188016a41cca7c400103e000b200141011037000b200241dc016a41043602002002419c016a41023602002002420237028c01200241bca7c40036028801200241043602d401200241eca9c4003602d0012002410036024c200241b8aec6003602482002200241d0016a360298012002200241c8006a3602d80120024188016a41cca7c400103e000b410141011037000be30503037f047e017f230041a0016b2202240041002103200241003a00482000410120011b2104024002400240024002400240034020012003460d01200241286a20036a200420036a2d00003a00002002200341016a22003a00482000210320004120470d000b200241086a41186a200241286a41186a22002903002205370300200241086a41106a200241286a41106a22012903002206370300200241086a41086a200241286a41086a22042903002207370300200220022903282208370308200241d0006a41186a2005370300200241d0006a41106a2006370300200241d0006a41086a200737030020022008370350411310282203450d03200341002900cef0423700002003410f6a41002800ddf042360000200341086a41002900d6f04237000020024293808080b002370294012002200336029001200241d0006a20024190016a108f01200228029801210320022802900121092000420037030020014200370300200442003703002002420037032820092003200241286a1000200241f0006a41186a2000290300370300200241f0006a41106a2001290300370300200241f0006a41086a2004290300370300200220022903283703700240200228029401450d00200228029001102a0b20024100360228200241f0006a4120200241286a1006210320022802282200417f470d01410021000c020b0240200341ff0171450d00200241003a00480b2002413c6a4102360200200241fc006a41043602002002420237022c200241bca7c40036022820024104360274200241fca9c40036027020024100360254200241b8aec6003602502002200241f0006a3602382002200241d0006a360278200241286a41cca7c400103e000b024020030d00410021000c010b20004104490d02200328000021002003102a0b410410282203450d0220032000360000200241a0016a24002003ad4280808080c000840f0b411341011037000b41c4d1c3004133200241286a419cd9c3001038000b410441011037000b880f03057f037e017f230041c0016b22022400024020010d00410121000b200220003602082002200136020c41002103200241003a00702001417f6a21040340024020012003470d000240200341ff0171450d00200241003a00700b200241e4006a41023602002002419c016a410436020020024202370254200241bca7c400360250200241043602940120024194aac4003602900120024100360234200241b8aec600360230200220024190016a3602602002200241306a36029801200241d0006a41cca7c400103e000b200241d0006a20036a200020036a22052d00003a00002002200541016a3602082002200341016a22053a00702002200436020c2004417f6a21042005210320054120470d000b200241106a41086a200241d0006a41086a290300370300200241106a41106a200241d0006a41106a290300370300200241106a41186a200241d0006a41186a2903003703002002200229035037031041002103200241003a0070200120056b2106200020056a2100417f21010340024020062003470d000240200341ff0171450d00200241003a00700b200241e4006a41023602002002419c016a410436020020024202370254200241bca7c400360250200241043602940120024194aac4003602900120024100360234200241b8aec600360230200220024190016a3602602002200241306a36029801200241d0006a41cca7c400103e000b200241d0006a20036a200020036a22052d00003a00002002200420036b36020c2002200541016a3602082002200341016a22053a00702001417f6a21012005210320054120470d000b200241306a41086a200241d0006a41086a290300370300200241306a41106a200241d0006a41106a290300370300200241306a41186a200241d0006a41186a290300370300200220022903503703300240024002400240024002400240024002400240024002400240200420056b220441016a4110490d002002200020056a220341106a3602082002200441716a220536020c20054108490d0220032900002107200341086a29000021082002200441696a36020c2002200341186a360208200341106a29000021092002200241086a106c20022802000d0c200228020c2205200228020422034f0d010c0c0b2002419c016a4104360200200241e4006a410236020020024202370254200241bca7c400360250200241043602940120024194aac400360290012002410036027c200241b8aec600360278200220024190016a3602602002200241f8006a36029801200241d0006a41cca7c400103e000b2003417f4c0d0302400240024020030d00410121044101450d0d0c010b2003102e2204450d012004200228020822012003109a0521002002200520036b36020c2002200120036a3602082000450d0c0b20024190016a41186a200241106a41186a29030037030020024190016a41106a200241106a41106a29030037030020024190016a41086a200241106a41086a2903003703002002200229031037039001200241d0006a41186a200241306a41186a290300370300200241d0006a41106a200241306a41106a290300370300200241d0006a41086a200241306a41086a29030037030020022002290330370350200220033602b801200220033602b401200220043602b001200241f8006a20024190016a200241d0006a200720082009200241b0016a10f50320022802784101460d0220024184016a2802002104200241f8006a41086a2802002100200228027c210520022d00880121010c030b200341011037000b2002419c016a4104360200200241e4006a410236020020024202370254200241bca7c400360250200241043602940120024194aac400360290012002410036027c200241b8aec600360278200220024190016a3602602002200241f8006a36029801200241d0006a41cca7c400103e000b0240200228028801450d0020024184016a280200102a0b410021050b200241003602582002420137035041011028210302402005450d002003450d02200242818080801037025420022003360250200341003a0000200341014102102c2203450d03200242828080802037025420022003360250200320013a00012004200241d0006a10b401024020022802542203200228025822016b2004490d00200228025021030c070b0240200120046a22062001490d002003410174220a2006200a20064b1b22064100480d000240024020030d002006102821030c010b200228025020032006102c21030b2003450d0520022006360254200220033602500c070b1031000b2003450d04200242818080801037025420022003360250200341013a000042808080801021070c060b1036000b410141011037000b410241011037000b200641011037000b410141011037000b2002200120046a2206360258200320016a20052004109a051a2006ad42208621072005450d002000450d002005102a0b200241c0016a240020072003ad840f0b2002419c016a4104360200200241e4006a410236020020024202370254200241bca7c400360250200241043602940120024194aac400360290012002410036027c200241b8aec600360278200220024190016a3602602002200241f8006a36029801200241d0006a41cca7c400103e000bc00c03047f017e067f23004180026b220224000240024020010d002002200136020c200241013602080c010b20022001417f6a36020c410121032002200041016a36020820002d0000220141014b0d0041002104410021000240024002400240024002400240024020010e020100010b2002200241086a106c20022802000d07200228020c220120022802042200490d072000417f4c0d010240024020000d00410121040c010b2000102e2204450d032004200228020822052000109a051a2002200120006b36020c2002200520006a3602080b2004450d07200241106a20042000ad22064220862006842206422088a7105420022802104101460d03200241186a280200210520022802142100410021030b2002200536021420022000360210200241e7e485f3063602b001200241d0016a41186a22074200370300200241d0016a41106a22084200370300200241d0016a41086a22094200370300200242003703d00141002101200241106a410020001b210a0240024020000d004100210b0c010b200a41046a280200210c200a280200210b0b200241b0016a200b4101200b1b200c4100200b1b200241d0016a1021200241f0006a41186a2007290300370300200241f0006a41106a2008290300370300200241f0006a41086a2009290300370300200220022903d0013703702002200536021420022000360210200241e2c289ab063602b001200742003703002008420037030020094200370300200242003703d0010240024020000d000c010b200a41046a280200210b200a28020021010b200241b0016a2001410120011b200b410020011b200241d0016a102220024190016a41186a2207200241d0016a41186a220129030037030020024190016a41106a2208200241d0016a41106a220b29030037030020024190016a41086a2209200241d0016a41086a220a290300370300200220022903d00137039001200220053602fc01200220003602f801200241e9dabdf3063602f40120014200370300200b4200370300200a4200370300200242003703d0010240024020000d00410021000c010b200241f8016a410020001b220041046a2802002105200028020021000b200241f4016a2000410120001b2005410020001b200241d0016a1022200241b0016a41186a22002001290300370300200241b0016a41106a2201200b290300370300200241b0016a41086a2205200a290300370300200241106a41086a200241f0006a41086a290300370300200241106a41106a200241f0006a41106a290300370300200241106a41186a200241f0006a41186a290300370300200220022903d0013703b00120022002290370370310200241c8006a2007290300370300200241c0006a2008290300370300200241386a20092903003703002002200229039001370330200241e8006a2000290300370300200241e0006a2001290300370300200241d8006a2005290300370300200220022903b001370350200241003602d801200242013703d001200241106a200241d0016a108f01200241306a200241d0016a108f01200241d0006a200241d0016a108f0120022802d801210020022802d401210a20022802d001210b024020032006a745720d002004102a0b200041046a2201417f4c0d000240024020010d00410121050c010b200110282205450d040b2002410036021820022001360214200220053602102000200241106a10b4010240024020022802142205200228021822016b2000490d00200228021021050c010b200120006a22042001490d06200541017422072004200720044b1b22044100480d060240024020050d002004102821050c010b200228021020052004102c21050b2005450d0520022004360214200220053602100b200520016a200b2000109a051a200120006a21000240200a450d00200b102a0b20024180026a24002000ad4220862005ad840f0b1036000b200041011037000b200220022902143703d001419fdbc0004116200241d0016a41d4c7c0001038000b200141011037000b200441011037000b1031000b200241dc016a4104360200200241246a410236020020024202370214200241bca7c400360210200241043602d4012002419caac4003602d001200241003602b401200241b8aec6003602b0012002200241d0016a3602202002200241b0016a3602d801200241106a41cca7c400103e000b823305087f017e067f037e037f23004180066b220124000240024002400240411210282202450d00200241002900c1ae44370000200241106a41002f00d1ae443b0000200241086a41002900c9ae4437000020014292808080a0023702e404200120023602e0042000200141e0046a108f0120012802e804210220012802e0042100200141a0046a41186a22034200370300200141a0046a41106a22044200370300200141a0046a41086a22054200370300200142003703a00420002002200141a0046a1000200141c8006a41186a2003290300370300200141c8006a41106a2004290300370300200141c8006a41086a2005290300370300200120012903a004370348024020012802e404450d0020012802e004102a0b200141003602e004200141c8006a4120200141e0046a1006210620012802e0042207417f460d022006450d02200120073602e405200120063602e005200141306a200141e0056a109f0120012802300d0120012802e4052202450d0120012002417f6a22033602e405200120012802e005220541016a22043602e00520052d0000220241014b0d01410021080240024020020e020100010b41002102200141003a0080050340024020032002470d00200141003602e405200241ff0171450d04200141003a0080050c040b200141e0046a20026a200520026a220041016a2d00003a00002001200041026a3602e0052001200241016a22003a0080052000210220004120470d000b200141a0046a41086a200141e0046a41086a2903002209370300200141e8016a41186a200141e0046a41186a290300370300200141e8016a41106a200141e0046a41106a290300370300200141e8016a41086a20093703002001200320006b22033602e405200120012903e00422093703a004200120093703e80141012108200520006a41016a21040b20014180046a41186a200141e8016a41186a29030037030020014180046a41106a200141e8016a41106a29030037030020014180046a41086a200141e8016a41086a290300370300200120012903e801370380042003450d0120012003417f6a22033602e4052001200441016a3602e00520042d0000220041014b0d01410021020240024020000e020100010b41002102200141003a0080050340024020032002470d00200141003602e405200241ff0171450d04200141003a0080050c040b200141e0046a20026a200420026a220041016a2d00003a00002001200041026a3602e0052001200241016a22003a0080052000210220004120470d000b200141c0046a41086a200141e0046a41086a2903002209370300200141e8016a41186a200141e0046a41186a290300370300200141e8016a41106a200141e0046a41106a290300370300200141e8016a41086a20093703002001200320006b3602e405200120012903e00422093703c004200120093703e801410121020b200141c0036a41186a2205200141e8016a41186a2200290300370300200141c0036a41106a220a200141e8016a41106a2203290300370300200141c0036a41086a220b200141e8016a41086a2204290300370300200141e0036a41086a220c20014180046a41086a290300370300200141e0036a41106a220d20014180046a41106a290300370300200141e0036a41186a220e20014180046a41186a290300370300200120012903e8013703c00320012001290380043703e003200141a0036a41186a220f200e290300370300200141a0036a41106a220e200d290300370300200141a0036a41086a220d200c290300370300200120012903e0033703a00320014180036a41186a220c200529030037030020014180036a41106a2205200a29030037030020014180036a41086a220a200b290300370300200120012903c00337038003200141e0046a41186a220b200f290300370300200141e0046a41106a220f200e290300370300200141e0046a41086a220e200d290300370300200120012903a0033703e0042000200c290300370300200320052903003703002004200a29030037030020012001290380033703e801200141c0056a41046a2205200141fa026a41046a2f01003b0100200120012801fa023602c00520084102460d01200141d8026a41186a200b290300370300200141d8026a41106a200f290300370300200141d8026a41086a200e290300370300200141b8026a41086a2004290300370300200141b8026a41106a2003290300370300200141b8026a41186a2000290300370300200141b0026a41046a20052f01003b0100200120012903e0043703d802200120012903e8013703b802200120012802c0053602b00202402007450d002006102a0b200141c8006a412010090c030b411241011037000b41c4d1c3004133200141a0046a419cd9c3001038000b410221080b20014188016a41186a2200200141d8026a41186a29030037030020014188016a41106a2203200141d8026a41106a29030037030020014188016a41086a2204200141d8026a41086a290300370300200141e8006a41086a2205200141b8026a41086a290300370300200141e8006a41106a2206200141b8026a41106a290300370300200141e8006a41186a2207200141b8026a41186a290300370300200120012903d80237038801200120012903b802370368200141c8016a41086a220a2004290300370300200141c8016a41106a22042003290300370300200141c8016a41186a2203200029030037030020012001290388013703c801200141a8016a41086a22002005290300370300200141a8016a41106a22052006290300370300200141a8016a41186a22062007290300370300200120012903683703a8010240024020084102460d002001418a026a220720012903a801370100200141f1016a200a290300370000200141f9016a200429030037000020014181026a200329030037000020014192026a20002903003701002001419a026a2005290300370100200141a2026a2006290300370100200120083a00e801200120012903c8013700e901200120023a0089024100210602400240024002400240024002400240200241ff01714101470d00200141e0046a200710ac01200141e0056a41186a200141e0046a41186a22022900002209370300200141e0056a41106a200141e0046a41106a22002900002210370300200141e0056a41086a200141e0046a41086a22032900002211370300200120012900e00422123703e005200220093703002000201037030020032011370300200120123703e004412010282206450d01200620012903e004370000200641186a2002290300370000200641106a2000290300370000200641086a200329030037000020012d00e80121080b0240200841ff01714101460d0020012d0089024101460d03200141c0056a41186a22024200370300200141c0056a41106a22004200370300200141c0056a41086a22034200370300200142003703c00541d3aec400411a200141c0056a1000200141e0046a41186a2002290300370300200141e0046a41106a2000290300370300200141e0046a41086a2003290300370300200120012903c0053703e004200141e0046a412010090c060b200141e0046a200141e8016a41017210ac01200141e0056a41186a200141e0046a41186a22022903002209370300200141e0056a41106a200141e0046a41106a22002903002210370300200141e0056a41086a200141e0046a41086a22032903002211370300200120012903e00422123703e005200220093703002000201037030020032011370300200120123703e004412010282208450d01200820012903e004370000200841186a2002290300370000200841106a2000290300370000200841086a2003290300370000200141003602e00420084120200141e0046a1006210720012802e004220b417f460d032007450d032001200b360284042001200736028004200141186a20014180046a109f012001290318a70d042001280284042202450d04200141286a29030021092001290320211020012002417f6a2203360284042001200128028004220541016a22043602800420052d0000220241014b0d044100210a0240024020020e020100010b41002102200141003a0080050340024020032002470d002001410036028404200241ff0171450d07200141003a0080050c070b200141e0046a20026a200520026a220041016a2d00003a00002001200041026a360280042001200241016a22003a0080052000210220004120470d000b200141e0056a41086a200141e0046a41086a290300370300200141e0056a41106a200141e0046a41106a290300370300200141e0056a41186a200141e0046a41186a290300370300200120012903e0043703e0052001200320006b2203360284044101210a200520006a41016a21040b200141c0056a41186a200141e0056a41186a290300370300200141c0056a41106a200141e0056a41106a290300370300200141c0056a41086a200141e0056a41086a290300370300200120012903e0053703c0052003450d0420012003417f6a2203360284042001200441016a3602800420042d0000220241014b0d040240024020020e020100010b41002102200141003a0080050340024020032002470d002001410036028404200241ff0171450d07200141003a0080050c070b200141e0046a20026a200420026a220041016a2d00003a00002001200041026a360280042001200241016a22003a0080052000210220004120470d000b200141a0046a41086a200141e0046a41086a2903002211370300200141e0056a41186a200141e0046a41186a290300370300200141e0056a41106a200141e0046a41106a290300370300200141e0056a41086a20113703002001200320006b36028404200120012903e00422113703a004200120113703e0050b200141c0036a41186a2202200141e0056a41186a2200290300370300200141c0036a41106a2203200141e0056a41106a2204290300370300200141c0036a41086a2205200141e0056a41086a220c290300370300200141e0036a41086a220d200141c0056a41086a290300370300200141e0036a41106a220e200141c0056a41106a290300370300200141e0036a41186a220f200141c0056a41186a290300370300200120012903e0053703c003200120012903c0053703e003200141a0036a41186a2213200f290300370300200141a0036a41106a220f200e290300370300200141a0036a41086a220e200d290300370300200120012903e0033703a00320014180036a41186a200229030037030020014180036a41106a200329030037030020014180036a41086a2005290300370300200120012903c00337038003200141e0046a41186a22032013290300370300200141e0046a41106a2205200f290300370300200141e0046a41086a220d200e290300370300200120012903a0033703e004200141c0056a41046a220e200141fa026a41046a2f01003b0100200120012801fa023602c005200a4102460d0420014189026a21022000200329030037030020042005290300370300200c200d290300370300200141c0046a41046a200e2f01003b0100200120012903e0043703e005200120012802c0053602c0040240200b450d002007102a0b200141f1046a20012903e005370000200141f9046a200141e0056a41086a29030037000020014181056a200141e0056a41106a29030037000020014189056a200141e0056a41186a290300370000200141b6056a200141c4046a2f01003b0100200120103703e0042001200a3a00f004200120012802c0043601b205200120093703e80420014191056a200229000037000020014199056a200241086a290000370000200141a1056a200241106a290000370000200141a9056a200241186a290000370000200141b1056a200241206a2d00003a0000200141003602e805200142013703e0052001200141e0046a3602c005200141c0056a200141e0056a10a301200141e0046a41106a200141e0056a10a90120012802e40521022008412020012802e005220020012802e805100702402002450d002000102a0b2008102a4101210a0c060b412041011037000b412041011037000b200141c0056a41186a22024200370300200141c0056a41106a22004200370300200141c0056a41086a22034200370300200142003703c00541d3aec400411a200141c0056a1000200141e0046a41186a2002290300370300200141e0046a41106a2000290300370300200141e0046a41086a2003290300370300200120012903c0053703e004200141203602e4052001200141e0046a3602e0052007200141e0056a10ff010c020b41e2bbc00041d8001050000b41c4d1c3004133200141a0046a419cd9c3001038000b410021084100210a0b0240024002400240024020060d00410021020c010b200141003602e00420064120200141e0046a1006210720012802e004220b417f460d012007450d012001200b3602bc05200120073602b8052001200141b8056a109f012001290300a70d0520012802bc052202450d05200141106a29030021092001290308211020012002417f6a22033602bc05200120012802b805220541016a22043602b80520052d0000220241014b0d054100210c0240024020020e020100010b41002102200141003a0080050340024020032002470d00200141003602bc05200241ff0171450d08200141003a0080050c080b200141e0046a20026a200520026a220041016a2d00003a00002001200041026a3602b8052001200241016a22003a0080052000210220004120470d000b20014180046a41106a200141e0046a41106a2903002211370300200141e0056a41086a200141e0046a41086a290300370300200141e0056a41106a2011370300200141e0056a41186a200141e0046a41186a2903003703002001200320006b22033602bc05200120012903e0043703e0054101210c200520006a41016a21040b200141c0056a41186a200141e0056a41186a290300370300200141c0056a41106a200141e0056a41106a290300370300200141c0056a41086a200141e0056a41086a290300370300200120012903e0053703c0052003450d0520012003417f6a22033602bc052001200441016a3602b80520042d0000220241014b0d05410021050240024020020e020100010b41002102200141003a0080050340024020032002470d00200141003602bc05200241ff0171450d08200141003a0080050c080b200141e0046a20026a200420026a220041016a2d00003a00002001200041026a3602b8052001200241016a22003a0080052000210220004120470d000b200141c0046a41086a200141e0046a41086a2903002211370300200141e0056a41186a200141e0046a41186a290300370300200141e0056a41106a200141e0046a41106a290300370300200141e0056a41086a20113703002001200320006b3602bc05200120012903e00422113703c004200120113703e005410121050b200141c0036a41186a2204200141e0056a41186a2202290300370300200141c0036a41106a220d200141e0056a41106a2200290300370300200141c0036a41086a220e200141e0056a41086a2203290300370300200141e0036a41086a220f200141c0056a41086a290300370300200141e0036a41106a2213200141c0056a41106a290300370300200141e0036a41186a2214200141c0056a41186a290300370300200120012903e0053703c003200120012903c0053703e003200141a0036a41186a22152014290300370300200141a0036a41106a22142013290300370300200141a0036a41086a2213200f290300370300200120012903e0033703a00320014180036a41186a220f200429030037030020014180036a41106a2204200d29030037030020014180036a41086a220d200e290300370300200120012903c00337038003200141e0046a41186a220e2015290300370300200141e0046a41106a22152014290300370300200141e0046a41086a22142013290300370300200120012903a0033703e0042002200f290300370300200020042903003703002003200d29030037030020012001290380033703e005200141c0056a41046a2204200141fa026a41046a2f01003b0100200120012801fa023602c005200c4102460d05200141d8026a41186a200e290300370300200141d8026a41106a2015290300370300200141d8026a41086a2014290300370300200141b8026a41086a2003290300370300200141b8026a41106a2000290300370300200141b8026a41186a2002290300370300200141b0026a41046a20042f01003b0100200120012903e0043703d802200120012903e0053703b802200120012802c0053602b0020240200b450d002007102a0b20014191056a20053a000020014192056a20012903b8023701002001419a056a200141b8026a41086a290300370100200141a2056a200141b8026a41106a290300370100200141aa056a200141b8026a41186a290300370100200141b6056a200141b4026a2f01003b0100200120103703e004200120012802b0023601b205200120093703e80420014190056a200141e8016a41206a2d00003a000020014188056a200141e8016a41186a290300370300200141e0046a41206a200141e8016a41106a290300370300200141e0046a41186a200141e8016a41086a290300370300200120012903e8013703f004200141003602e805200142013703e0052001200141e0046a3602c005200141c0056a200141e0056a10a301200141e0046a41106a200141e0056a10a90120012802e40521022006412020012802e005220020012802e805100702402002450d002000102a0b2006102a410121020b200a20084572450d010c020b41e2bbc00041d8001050000b2008102a0b2006452002720d002006102a0b20014180066a24000f0b41c4d1c3004133200141a0046a419cd9c3001038000bde3305097f017e077f037e057f230041a0056b22012400024002400240024002400240411210282202450d0020024100290095ae44370000200241106a41002f00a5ae443b0000200241086a410029009dae4437000020014292808080a00237028c042001200236028804200020014188046a108f0120012802900421022001280288042100200141c8036a41186a22034200370300200141c8036a41106a22044200370300200141c8036a41086a22054200370300200142003703c80320002002200141c8036a1000200141186a2003290300370300200141106a2004290300370300200141086a2005290300370300200120012903c8033703000240200128028c04450d00200128028804102a0b20014100360288042001412020014188046a100621032001280288042204417f460d042003450d04200120043602e404200120033602e00420014180056a200141e0046a106d2001280280052206450d02200128028405210720012802e4042202450d0120012002417f6a22053602e404200120012802e004220841016a22093602e00420082d0000220041014b0d01410021020240024020000e020100010b41002102200141003a00a8040340024020052002470d00200141003602e404200241ff0171450d04200141003a00a8040c040b20014188046a20026a200820026a220041016a2d00003a00002001200041026a3602e0042001200241016a22003a00a8042000210220004120470d000b200141c8036a41086a20014188046a41086a290300220a370300200141a0016a41186a20014188046a41186a290300370300200141a0016a41106a20014188046a41106a290300370300200141a0016a41086a200a3703002001200520006b22053602e4042001200129038804220a3703c8032001200a3703a00141012102200820006a41016a21090b200141a8036a41186a200141a0016a41186a290300370300200141a8036a41106a200141a0016a41106a290300370300200141a8036a41086a200141a0016a41086a290300370300200120012903a0013703a8032005450d0120012005417f6a22083602e4042001200941016a3602e00420092d0000220541014b0d01410021000240024020050e020100010b41002100200141003a00a8040340024020082000470d00200141003602e404200041ff0171450d04200141003a00a8040c040b20014188046a20006a200920006a220541016a2d00003a00002001200541026a3602e0042001200041016a22053a00a8042005210020054120470d000b200141e8036a41086a20014188046a41086a290300220a370300200141a0016a41186a20014188046a41186a290300370300200141a0016a41106a20014188046a41106a290300370300200141a0016a41086a200a3703002001200820056b3602e4042001200129038804220a3703e8032001200a3703a001410121000b200141e8026a41186a2205200141a0016a41186a2208290300370300200141e8026a41106a2209200141a0016a41106a220b290300370300200141e8026a41086a220c200141a0016a41086a220d29030037030020014188036a41086a220e200141a8036a41086a29030037030020014188036a41106a220f200141a8036a41106a29030037030020014188036a41186a2210200141a8036a41186a290300370300200120012903a0013703e802200120012903a80337038803200141c8026a41186a22112010290300370300200141c8026a41106a2210200f290300370300200141c8026a41086a220f200e29030037030020012001290388033703c802200141a8026a41186a220e2005290300370300200141a8026a41106a22052009290300370300200141a8026a41086a2209200c290300370300200120012903e8023703a80220014188046a41186a201129030037030020014188046a41106a201029030037030020014188046a41086a200f290300370300200120012903c802370388042008200e290300370300200b2005290300370300200d2009290300370300200120012903a8023703a0010c030b411241011037000b2007450d002006102a0b410221020b024020024102460d0020014188026a41186a20014188046a41186a29030037030020014188026a41106a20014188046a41106a29030037030020014188026a41086a20014188046a41086a290300370300200141e8016a41086a200141a0016a41086a290300370300200141e8016a41106a200141a0016a41106a290300370300200141e8016a41186a200141a0016a41186a290300370300200120012903880437038802200120012903a0013703e801200120012f0180053b01e60102402004450d002003102a0b2001412010090c020b41c4d1c3004133200141a8036a419cd9c3001038000b410221020b200141c0006a41186a220320014188026a41186a290300370300200141c0006a41106a220420014188026a41106a290300370300200141c0006a41086a220520014188026a41086a290300370300200141206a41086a2208200141e8016a41086a290300370300200141206a41106a2209200141e8016a41106a290300370300200141206a41186a220b200141e8016a41186a2903003703002001200129038802370340200120012903e80137032020014180016a41086a220c200529030037030020014180016a41106a2205200429030037030020014180016a41186a220420032903003703002001200129034037038001200141e0006a41086a22032008290300370300200141e0006a41106a22082009290300370300200141e0006a41186a2209200b29030037030020012001290320370360024020024102460d00200141c2016a220b2001290360370100200141a9016a200c290300370000200141b1016a2005290300370000200141b9016a2004290300370000200141ca016a2003290300370100200141d2016a2008290300370100200141da016a2009290300370100200120023a00a00120012001290380013700a101200120003a00c101410021030240024002400240024002400240024002400240200041ff01714101470d0020014188046a200b10ae0120014180056a41186a20014188046a41186a2202290000220a37030020014180056a41106a20014188046a41106a2200290000221237030020014180056a41086a20014188046a41086a2204290000221337030020012001290088042214370380052002200a37030020002012370300200420133703002001201437038804412010282203450d012003200129038804370000200341186a2002290300370000200341106a2000290300370000200341086a200429030037000020012d00a00121020b0240200241ff01714101460d0020012d00c1014101460d03200141e0046a41186a22024200370300200141e0046a41106a22004200370300200141e0046a41086a22044200370300200142003703e00441a7aec400411a200141e0046a100020014188046a41186a200229030037030020014188046a41106a200029030037030020014188046a41086a2004290300370300200120012903e0043703880420014188046a412010090c080b20014188046a200141a0016a41017210ae0120014180056a41186a20014188046a41186a2202290300220a37030020014180056a41106a20014188046a41106a2200290300221237030020014180056a41086a20014188046a41086a2205290300221337030020012001290388042214370380052002200a37030020002012370300200520133703002001201437038804412010282204450d012004200129038804370000200441186a2002290300370000200441106a2000290300370000200441086a200529030037000020014100360288042004412020014188046a10062109200128028804220d417f460d032009450d032001200d3602cc03200120093602c803200141e8036a200141c8036a106d20012802e8032202450d0520012802ec03210c20012802cc032200450d04200141f0036a280200210820012000417f6a220e3602cc03200120012802c803220f41016a22103602c803200f2d0000220041014b0d044100210b0240024020000e020100010b41002100200141003a00a80403400240200e2000470d00200141003602cc03200041ff0171450d07200141003a00a8040c070b20014188046a20006a200f20006a220541016a2d00003a00002001200541026a3602c8032001200041016a22053a00a8042005210020054120470d000b20014180056a41086a20014188046a41086a29030037030020014180056a41106a20014188046a41106a29030037030020014180056a41186a20014188046a41186a2903003703002001200129038804370380052001200e20056b220e3602cc034101210b200f20056a41016a21100b200141e0046a41186a20014180056a41186a290300370300200141e0046a41106a20014180056a41106a290300370300200141e0046a41086a20014180056a41086a29030037030020012001290380053703e004200e450d042001200e417f6a220e3602cc032001201041016a3602c80320102d0000220041014b0d040240024020000e020100010b41002100200141003a00a80403400240200e2000470d00200141003602cc03200041ff0171450d07200141003a00a8040c070b20014188046a20006a201020006a220541016a2d00003a00002001200541026a3602c8032001200041016a22053a00a8042005210020054120470d000b200141a8036a41106a20014188046a41106a290300220a37030020014180056a41086a20014188046a41086a29030037030020014180056a41106a200a37030020014180056a41186a20014188046a41186a2903003703002001200e20056b3602cc032001200129038804370380050b200141e8026a41186a220020014180056a41186a290300370300200141e8026a41106a220520014180056a41106a290300370300200141e8026a41086a220e20014180056a41086a29030037030020014188036a41086a220f200141e0046a41086a29030037030020014188036a41106a2210200141e0046a41106a29030037030020014188036a41186a2211200141e0046a41186a29030037030020012001290380053703e802200120012903e00437038803200141c8026a41186a22152011290300370300200141c8026a41106a22112010290300370300200141c8026a41086a2210200f29030037030020012001290388033703c802200141a8026a41186a2000290300370300200141a8026a41106a2005290300370300200141a8026a41086a200e290300370300200120012903e8023703a80220014188046a41186a201529030037030020014188046a41106a201129030037030020014188046a41086a2010290300370300200120012903c802370388040c060b412041011037000b412041011037000b200141e0046a41186a22024200370300200141e0046a41106a22004200370300200141e0046a41086a22044200370300200142003703e00441a7aec400411a200141e0046a100020014188046a41186a200229030037030020014188046a41106a200029030037030020014188046a41086a2004290300370300200120012903e004370388042001412036028405200120014188046a36028005200b20014180056a10ff010c040b41e2bbc00041d8001050000b200c450d002002102a0b4102210b0b0240200b4102460d00200141c1016a210020014180056a41186a220520014188046a41186a29030037030020014180056a41106a220e20014188046a41106a29030037030020014180056a41086a220f20014188046a41086a290300370300200120012903880437038005200120012f01e0043b01e8030240200d450d002009102a0b20014195046a2001290380053700002001419d046a200f290300370000200141a5046a200e290300370000200141ad046a20052903003700002001200b3a00940420012008360290042001200c36028c042001200236028804200120012f01e8033b01d604200141b5046a2000290000370000200141bd046a200041086a290000370000200141c5046a200041106a290000370000200141cd046a200041186a290000370000200141d5046a200041206a2d00003a000020014100360288052001420137038005200820014180056a10b40120014194046a210502402008450d00200841057421000340200220014180056a108f01200241206a2102200041606a22000d000b0b200520014180056a10a9012001280284052102200441202001280280052200200128028805100702402002450d002000102a0b0240200128028c04450d00200128028804102a0b2004102a410121090c020b41c4d1c3004133200141a8036a419cd9c3001038000b41002104410021090b0240024002400240024020030d00410021020c010b20014100360288042003412020014188046a100621080240024002400240200128028804220b417f460d002008450d002001200b3602dc04200120083602d804200141a8036a200141d8046a106d4200211220012802a8032202450d0220012802ac03211020012802dc042200450d01200141b0036a350200210a20012000417f6a220c3602dc04200120012802d804220d41016a220f3602d804200d2d0000220041014b0d014100210e0240024020000e020100010b41002100200141003a00a80403400240200c2000470d00200141003602dc04200041ff0171450d04200141003a00a8040c040b20014188046a20006a200d20006a220541016a2d00003a00002001200541026a3602d8042001200041016a22053a00a8042005210020054120470d000b200141c8036a41086a20014188046a41086a290300221337030020014180056a41186a20014188046a41186a29030037030020014180056a41106a20014188046a41106a29030037030020014180056a41086a20133703002001200c20056b220c3602dc04200120012903880422133703c80320012013370380054101210e200d20056a41016a210f0b200141e0046a41186a20014180056a41186a290300370300200141e0046a41106a20014180056a41106a290300370300200141e0046a41086a20014180056a41086a29030037030020012001290380053703e004200c450d012001200c417f6a220c3602dc042001200f41016a3602d804200f2d0000220541014b0d01410021000240024020050e020100010b41002100200141003a00a80403400240200c2000470d00200141003602dc04200041ff0171450d04200141003a00a8040c040b20014188046a20006a200f20006a220541016a2d00003a00002001200541026a3602d8042001200041016a22053a00a8042005210020054120470d000b200141e8036a41086a20014188046a41086a290300221237030020014180056a41186a20014188046a41186a29030037030020014180056a41106a20014188046a41106a29030037030020014180056a41086a20123703002001200c20056b3602dc04200120012903880422123703e8032001201237038005410121000b200141e8026a41186a220520014180056a41186a220c290300370300200141e8026a41106a220d20014180056a41106a220f290300370300200141e8026a41086a221120014180056a41086a221529030037030020014188036a41086a2216200141e0046a41086a29030037030020014188036a41106a2217200141e0046a41106a29030037030020014188036a41186a2218200141e0046a41186a29030037030020012001290380053703e802200120012903e00437038803200141c8026a41186a22192018290300370300200141c8026a41106a22182017290300370300200141c8026a41086a2217201629030037030020012001290388033703c802200141a8026a41186a22162005290300370300200141a8026a41106a2205200d290300370300200141a8026a41086a220d2011290300370300200120012903e8023703a80220014188046a41186a201929030037030020014188046a41106a201829030037030020014188046a41086a2017290300370300200120012903c80237038804200c2016290300370300200f20052903003703002015200d290300370300200120012903a80237038005200a422086210a2010ad21120c030b41e2bbc00041d8001050000b2010450d002002102a0b4102210e4200210a0b200e4102460d0120014188026a41186a20014188046a41186a29030037030020014188026a41106a20014188046a41106a29030037030020014188026a41086a20014188046a41086a290300370300200141e8016a41086a220520014180056a41086a290300370300200141e8016a41106a220c20014180056a41106a290300370300200141e8016a41186a220d20014180056a41186a29030037030020012001290388043703880220012001290380053703e801200120012f01e0043b01e601200a20128421120240200b450d002008102a0b200141b5046a20003a0000200141b6046a20012903e801370100200141be046a2005290300370100200141c6046a200c290300370100200141ce046a200d2903003701002001419c046a200141a0016a41086a290300370200200141a4046a200141a0016a41106a290300370200200141ac046a200141a0016a41186a290300370200200141b4046a200141a0016a41206a2d00003a00002001201237028c042001200236028804200120012f01e6013b01d604200120012903a0013702940420014100360288052001420137038005200a422088a7220020014180056a10b40120014194046a210502402000450d00200041057421000340200220014180056a108f01200241206a2102200041606a22000d000b0b200520014180056a10a9012001280284052102200341202001280280052200200128028805100702402002450d002000102a0b0240200128028c04450d00200128028804102a0b2003102a410121020b200920044572450d010c020b41c4d1c3004133200141a8036a419cd9c3001038000b2004102a0b02402003452002720d002003102a0b2006450d002007450d002006102a0b200141a0056a24000b13002000410d360204200041bcafc4003602000b3400200041d9dbc40036020420004100360200200041146a4113360200200041106a41e0dbc400360200200041086a42073702000b09002000410010e6020b6c01027f230041106b22022400200241003602082002420137030002404104102822030d00410441011037000b2003410036000020024284808080c000370204200220033602004100200210b401200041086a200228020836020020002002290300370200200241106a24000b3001017f02404108102822020d00410841011037000b20004288808080800137020420002002360200200242003700000b8e0201037f230041c0006b22022400200241186a4200370300200241106a22034200370300200241086a4200370300200241286a22044100360200200242003703002002420837032020024100360238200242013703302002200236023c2002413c6a200241306a10a3012002200336023c2002413c6a200241306a10a3012002280220210320042802002204200241306a10b40102402004450d00200441306c21040340200341106a200241306a108f012002200336023c200341306a21032002413c6a200241306a10a301200441506a22040d000b0b20002002290330370200200041086a200241306a41086a28020036020002402002280224450d002002280220102a0b200241c0006a24000b7001027f230041306b2202240020024200370310200242003703082002200241086a36021c02404101102822030d00410141011037000b20024201370224200220033602202002411c6a200241206a10a301200041086a200228022836020020002002290320370200200241306a24000b3001017f02404104102822020d00410441011037000b20004284808080c00037020420002002360200200241043600000b9c0402057f027e230041d0016b220224002002200110b1040240024020022d00004101470d00200241286a41186a200241196a290000370300200241286a41106a200241116a290000370300200241286a41086a200241096a2900003703002002200229000137032802400240410e10282201450d002001410029008aaf44370000200141066a4100290090af443700002002428e808080e00137026c20022001360268200241286a200241e8006a108f012002280270210120022802682103200241f8006a41186a22044200370300200241f8006a41106a22054200370300200241f8006a41086a220642003703002002420037037820032001200241f8006a1000200241c8006a41186a2004290300370300200241c8006a41106a2005290300370300200241c8006a41086a2006290300370300200220022903783703480240200228026c450d002002280268102a0b20024100360278200241c8006a4120200241f8006a100621040240024020022802782203417f470d00410021010c010b2002200336026c20022004360268200241f8006a200241e8006a108a022002280298012201450d0220024190016a29030021072002290388012108200228029c0121052003450d002004102a0b2001450d022005450d032001102a0c030b410e41011037000b41c4d1c3004133200241c8016a419cd9c3001038000b42002108420021070b2000200837030020002007370308200241d0016a24000bb70301057f230041f0006b220224000240410e10282203450d00200341002900fcae44370000200341066a4100290082af443700002002428e808080e001370254200220033602502001200241d0006a108f012002280258210320022802502101200241086a41186a22044200370300200241086a41106a22054200370300200241086a41086a220642003703002002420037030820012003200241086a1000200241306a41186a2004290300370300200241306a41106a2005290300370300200241306a41086a20062903003703002002200229030837033002402002280254450d002002280250102a0b200241086a200241306a412010fd01200241d0006a41086a200241086a41096a290000370300200241d0006a41106a200241086a41116a290000370300200241d0006a41186a200241086a41196a290000370300200220022900093703500240024020022d00084101460d00200041003a00000c010b200041013a000020002002290350370001200041096a200241d8006a290300370000200041116a200241e0006a290300370000200041196a200241e8006a2903003700000b200241f0006a24000f0b410e41011037000b13002000410236020420004184fcc4003602000b3101017f02404104102822020d00410441011037000b20004284808080c00037020420002002360200200241a0053600000bdf14030d7f077e0b7f23004180046b22042400024002400240024002400240410d10282205450d0020054100290098af44370000200541056a410029009daf443700002004428d808080d0013702ec02200420053602e8022001200441e8026a108f0120042802f002210520042802e8022106200441a8036a41186a22074200370300200441a8036a41106a22084200370300200441a8036a41086a22094200370300200442003703a80320062005200441a8036a100020044198016a41186a200729030037030020044198016a41106a200829030037030020044198016a41086a2009290300370300200420042903a80337039801024020042802ec02450d0020042802e802102a0b200441003602a80320044198016a4120200441a8036a1006210502400240024020042802a8032206417f460d002005450d002006450d0420052d0000220641034f0d042005102a20060e03000201000b200441f0006a200110b10420042d00704101470d06200441b8016a41186a20044189016a290000370300200441b8016a41106a20044181016a290000370300200441b8016a41086a200441f9006a290000370300200420042900713703b801410e10282205450d042005410029008aaf44370000200541066a4100290090af443700002004428e808080e0013702ec02200420053602e802200441b8016a200441e8026a108f0120042802f002210520042802e8022106200441a8036a41186a22074200370300200441a8036a41106a22084200370300200441a8036a41086a22094200370300200442003703a80320062005200441a8036a100020044198016a41186a200729030037030020044198016a41106a200829030037030020044198016a41086a2009290300370300200420042903a80337039801024020042802ec02450d0020042802e802102a0b200441003602a80320044198016a4120200441a8036a100621070240024020042802a8032206417f470d00410021050c010b200420063602cc02200420073602c802200441a8036a200441c8026a108a0220042802c8032205450d06200441a8026a41186a200441a8036a41186a290300370300200441a8026a41106a200441a8036a41106a290300370300200441a8026a41086a200441a8036a41086a290300370300200441e8026a41086a200441d4036a290200370300200441e8026a41106a200441dc036a290200370300200441e8026a41186a200441e4036a29020037030020044188036a200441ec036a29020037030020044190036a200441f4036a280200360200200420042903a8033703a802200420042902cc033703e8022006450d002007102a0b200441c8026a41086a2209200441a8026a41086a290300370300200441c8026a41106a220a200441a8026a41106a290300370300200441c8026a41186a220b200441a8026a41186a290300370300200441a8036a41086a220c200441e8026a41086a2206290300370300200441a8036a41106a220d200441e8026a41106a2207290300370300200441a8036a41186a220e200441e8026a41186a2208290300370300200441a8036a41206a220f200441e8026a41206a290300370300200441a8036a41286a2210200441e8026a41286a280200360200200420042903a8023703c802200420042903e8023703a80302402005450d0020044188026a41186a200b29030037030020044188026a41106a200a29030037030020044188026a41086a2009290300370300200441d8016a41086a200c290300370300200441d8016a41106a200d290300370300200441d8016a41186a200e290300370300200441d8016a41206a200f290300370300200441d8016a41286a2010280200360200200420042903c80237038802200420042903a8033703d8010b2008200441b8016a41186a2903003703002007200441b8016a41106a2903003703002006200441b8016a41086a290300370300200420042903b8013703e8022005450d06200441306a41206a220c2004290388022211370300200441a8036a41186a2206200441e8026a41186a220d2903002212370300200441a8036a41106a2207200441e8026a41106a220e2903002213370300200441a8036a41086a2208200441e8026a41086a220f2903002214370300200441a8036a41286a20044188026a41086a2903002215370300200441a8036a41306a20044188026a41106a2903002216370300200441a8036a41386a20044188026a41186a2903002217370300200441306a41386a22102017370300200441306a41306a22182016370300200441306a41286a22192015370300200441306a41186a22092012370300200441306a41106a220a2013370300200441306a41086a220b2014370300200420042903e80222123703a803200420113703c80320042012370330200441286a221a200441d8016a41286a280200360200200441206a221b200441d8016a41206a290300370300200441186a221c200441d8016a41186a221d290300370300200441106a221e200441d8016a41106a221f290300370300200441086a2220200441d8016a41086a2221290300370300200420042903d801370300200441e8026a41386a22222010290300370300200441e8026a41306a22102018290300370300200441e8026a41286a22182019290300370300200441e8026a41206a2219200c290300370300200d2009290300370300200e200a290300370300200f200b290300370300200420042903303703e802201d2009290300370300201f200a2903003703002021200b290300370300200420042903303703d801200620222903003703002007201029030037030020082018290300370300200420053602c803200420192903003703a803200441cc036a22052004290300370200200441d4036a2020290300370200200441dc036a201e290300370200200441e4036a201c290300370200200441ec036a201b290300370200200441f4036a201a2802003602002006290300211120072007290300221220027c22133703002006201120037c2013201254ad7c37030020082903002111200420042903a803221220027c22133703a8032008201120037c2013201254ad7c370300200441f0006a20012002200310a50220043502702102200441f0006a41106a2903002111200441f0006a41086a2903002103200441d8016a200441a8036a10b50402402005280200450d0020042802c803102a0b200242018521020c070b200441a8036a200110b10420042d00a8034101470d0520044180036a200441c1036a290000370300200441e8026a41106a200441b9036a290000370300200441e8026a41086a200441b1036a290000370300200420042900a9033703e802200441306a200441e8026a2002200310a50220043502304201852102200441306a41106a2903002111200441306a41086a29030021030c060b200441a8036a20012002200310a50220043502a8034201852102200441b8036a2903002111200441b0036a29030021030c050b410d41011037000b41c4d1c3004133200441f8036a419cd9c3001038000b410e41011037000b41c4d1c3004133200441f8036a419cd9c3001038000b420021020b2000200337030820002002370300200041106a201137030020044180046a24000bc80201057f230041e0006b22022400200242f3e885db96cddbb320370308200241086a2001412c6a2001290300200141086a290300417f410f10a9020240410e10282203450d002003410029008aaf44370000200341066a4100290090af443700002002428e808080e001370234200220033602302000200241306a108f012002280238210320022802302100200241c0006a41186a22044200370300200241c0006a41106a22054200370300200241c0006a41086a220642003703002002420037034020002003200241c0006a1000200241106a41186a2004290300370300200241106a41106a2005290300370300200241106a41086a20062903003703002002200229034037031002402002280234450d002002280230102a0b200241203602442002200241106a3602402001200241c0006a10b604200241e0006a24000f0b410e41011037000bce0101027f230041106b2202240020024100360208200242013703002000412c6a2002108f012002200036020c2002410c6a200210a3012002200041106a36020c2002410c6a200210a30120002802202103200041286a2802002200200210b40102402000450d002003200041186c6a210003402002200336020c2002410c6a200210a301200341106a200210a0012000200341186a2203470d000b0b2002280204210320012802002001280204200228020022002002280208100702402003450d002000102a0b200241106a24000bf30901047f230041e0026b22052400200541a0016a41086a22064200370300200542003703a00141a990c6004119200541a0016a1008200541086a41086a2006290300370300200520052903a00137030841002106200541003602a001200541086a4110200541a0016a10062107024002400240024020052802a0012208417f460d002007450d0020084104490d01200728000021062007102a0b02402006417f6a220720064d0d00200541133602080c020b200541086a200710ca0320052802084113460d01200541a0016a200541086a419801109a051a20052802a8022107200541a0016a106a200720014d0d01200041828ac50036020420004101360200200041086a41c7003602002002106a0c020b41c4d1c3004133200541a0016a419cd9c3001038000b200541a0016a41086a22074200370300200542003703a00141a990c6004119200541a0016a1008200541086a41086a2007290300370300200520052903a0013703082005200641016a3602a001200541086a4110200541a0016a41041007200541a0016a2002418801109a051a200520033a00b002200520043602ac02200520013602a802024002400240024002400240411a10282207450d00200741186a41002f00ce88453b0000200741106a41002900c68845370000200741086a41002900be8845370000200741002900b688453700002007411a4134102c2207450d012007200636001a200541086a41186a22014200370300200541086a41106a22024200370300200541086a41086a22044200370300200542003703082007411e200541086a1000200541b8026a41186a2001290300370300200541b8026a41106a2002290300370300200541b8026a41086a2004290300370300200520052903083703b8022007102a200541003602102005420137030820052802a8022101410410282207450d022005410436020c20052005280210220241046a36021020052007360208200720026a2001360000200541a0016a200541086a10eb01024020052d00b002220741024b0d00024002400240024020070e03000102000b410021010c020b410121010c010b410221010b200520013a00df0202400240200528020c20052802102207460d00200528020821020c010b200741016a22022007490d07200741017422042002200420024b1b22044100480d070240024020070d002004102821020c010b200528020820072004102c21020b2002450d052005200436020c20052002360208200528021021070b2005200741016a360210200220076a20013a00000b20052802ac02210202400240200528020c2201200528021022076b4104490d00200528020821010c010b200741046a22042007490d06200141017422072004200720044b1b22074100480d060240024020010d002007102821010c010b200528020820012007102c21010b2001450d052005200736020c20052001360208200528021021070b2005200741046a360210200120076a2002360000200528020c2107200541b8026a4120200528020822012005280210100702402007450d002001102a0b200541a0016a106a200541ac016a2006360200200541a9016a20033a0000200541a8016a41033a0000200541053a00a00141014100200541a0016a10cc0120004100360200200020063602040c060b411a41011037000b413441011037000b410441011037000b200441011037000b200741011037000b1031000b200541e0026a24000bfe0201047f230041e0006b2202240002400240411310282203450d002003410f6a41002800e38945360000200341086a41002900dc8945370000200341002900d48945370000200341134126102c2203450d0120032001360013200241c0006a41186a22044200370300200241c0006a41106a22054200370300200241c0006a41086a220142003703002002420037034020034117200241c0006a1000200241186a2004290300370300200241106a2005290300370300200241086a2001290300370300200220022903403703002003102a200241c0006a200210e003200241306a41086a2001290300370300200241206a41086a200241c0006a411c6a2802003602002002200229034037033020022002290254370320024020022802502203450d002000200229033037030020002002290320370214200041086a200241306a41086a2903003703002000411c6a200241206a41086a2802003602000b20002003360210200241e0006a24000f0b411341011037000b412641011037000b130020004111360204200041cc8bc5003602000b3400200041f9aac50036020420004100360200200041146a410f360200200041106a4184abc500360200200041086a42093702000b4f01027f230041106b2202240002404101102822030d00410141011037000b200341003a0000200041086a4101360200200241013602042002200336020020002002290300370200200241106a24000b5b01027f23004190016b22022400200241133602000240410110282203450d00200341003a0000200042818080801037020420002003360200024020022802004113460d002002106a0b20024190016a24000f0b410141011037000bfd0201057f230041c0006b22022400200241206a4200370300200241186a4200370300200241086a41086a4200370300200241003a0028200242003703082002410036023820024201370330200241086a200241306a108f0102400240024020022d0028220341064b0d000240024002400240024002400240024020030e0700010203040506000b410021040c060b410121040c050b410221040c040b410321040c030b410421040c020b410521040c010b410621040b200220043a003f02400240200228023420022802382203460d00200228023021050c010b200341016a22052003490d03200341017422062005200620054b1b22064100480d030240024020030d002006102821050c010b200228023020032006102c21050b2005450d022002200636023420022005360230200228023821030b2002200341016a360238200520036a20043a00000b20002002290330370200200041086a200241306a41086a280200360200200241c0006a24000f0b200641011037000b1031000b4001017f230041106b2202240020024100360208200242013703004100200210b401200041086a200228020836020020002002290300370200200241106a24000b130020004106360204200041acc7c5003602000b3201017f02404104102822020d00410441011037000b20004284808080c00037020420002002360200200241809c313600000b3201017f02404104102822020d00410441011037000b20004284808080c0003702042000200236020020024180a3053600000b3e01017f02404110102822020d00411041011037000b20024200370008200242808084fea6dee111370000200042908080808002370204200020023602000b3201017f02404104102822020d00410441011037000b20004284808080c0003702042000200236020020024180de343600000ba30301047f230041c0006b22022400024002400240411310282203450d002003410f6a41002800e38945360000200341086a41002900dc8945370000200341002900d48945370000200341134126102c2203450d0120032000360013200241206a41186a22004200370300200241206a41106a22044200370300200241206a41086a220542003703002002420037032020034117200241206a1000200241186a2000290300370300200241106a2004290300370300200241086a2005290300370300200220022903203703002003102a411010282203450d02200320012903003700002003200141086a2903003700082002429080808080023702242002200336022020012802102104200141186a2802002203200241206a10b40102402003450d00200341057421002004210303402003200241206a108f01200341206a2103200041606a22000d000b0b2002280224210320024120200228022022002002280228100702402003450d002000102a0b0240200141146a280200450d002004102a0b200241c0006a24000f0b411341011037000b412641011037000b411041011037000bc01401077f230041d0016b2204240002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240411a10282205450d00200541186a41002f00ce88453b0000200541106a41002900c68845370000200541086a41002900be8845370000200541002900b688453700002005411a4134102c2205450d012005200136001a200441e0006a41186a22064200370300200441e0006a41106a22074200370300200441e0006a41086a22084200370300200442003703602005411e200441e0006a1000200441306a41186a2006290300370300200441306a41106a2007290300370300200441306a41086a2008290300370300200420042903603703302005102a0240200441306a41204101410041001003417f470d0041b7d5c50021000c110b200441146a200041086a2900003702002004411c6a200041106a290000370200200441246a200041186a290000370200200420013602082004200029000037020c411010282205450d02200541002900a68845370000200541086a41002900ae88453700002004429080808080023702b401200420053602b001200541104120102c2205450d03200441203602b401200420042802b801220641046a3602b801200420053602b001200520066a2001360000200441086a410472200441b0016a108f0120042802b801210520042802b0012106200441e0006a41186a22074200370300200441e0006a41106a22084200370300200441e0006a41086a220942003703002004420037036020062005200441e0006a1000200441306a41186a2007290300370300200441306a41106a2008290300370300200441306a41086a200929030037030020042004290360370330024020042802b401450d0020042802b001102a0b200441306a41204101410041001003417f470d0f200441086a41186a200041186a290000370300200441086a41106a200041106a290000370300200441086a41086a200041086a29000037030020042000290000370308411310282205450d042005410f6a41002800a88945360000200541086a41002900a18945370000200541002900998945370000200541134126102c2205450d0520052001360013200441e0006a41186a22064200370300200441e0006a41106a22074200370300200441e0006a41086a220842003703002004420037036020054117200441e0006a1000200441306a41186a2006290300370300200441306a41106a2007290300370300200441306a41086a2008290300370300200420042903603703302005102a20044100360260200441306a4120200441e0006a100621050240024020042802602207417f460d002007210620050d010b20044100360268200442013703604100200441e0006a10b4012004280268210620042802642107200428026021050b200420063602582004200736025420042005360250024002402006450d00200441e0006a20052006410110d60220042802604101470d012004280254450d102004280250102a0c100b4101200441d0006a10b401200441086a200441d0006a108f010c0d0b200428026421080240200441ec006a2802002205200441e8006a2802002206460d002004280258200520066b6a220741206a2209417f4c0d070240024020090d004101210a0c010b20091028220a450d090b20042009360284012004200a360280012004200736028801200420044180016a3602602008200441e0006a200510d70120072005490d0920042802880122082007490d0a200428025822082006490d0b20042802800121092004280250210a2004200720056b2207360290012004200820066b22083602940120072008470d0c200920056a200a20066a2007109a051a200441086a20044180016a108f012004280288012106200428028401210720042802800121052004280254450d0e2004280250102a0c0e0b2004200441d0006a3602602008200441e0006a200610d701200441086a200441d0006a108f010c0c0b411a41011037000b413441011037000b411041011037000b412041011037000b411341011037000b412641011037000b1036000b200941011037000b200520071044000b20072008103c000b200620081044000b200441b0016a41146a4108360200200441bc016a412536020020044198016a41146a41033602002004420337029c01200441c8afc60036029801200441253602b401200420044190016a3602c801200420044194016a3602cc0120044204370370200442013702642004419cb0c6003602602004200441b0016a3602a8012004200441e0006a3602c0012004200441cc016a3602b8012004200441c8016a3602b00120044198016a41d8b0c600103e000b2004280258210620042802542107200428025021050b2005450d00200441306a41202005200610072007450d012005102a0c010b412010282206450d0220062004290308370000200641186a200441086a41186a290300370000200641106a200441086a41106a290300370000200641086a200441086a41086a290300370000411310282207450d03410021052007410f6a41002800a88945360000200741086a41002900a18945370000200741002900998945370000200741134126102c2207450d0420072001360013200441e0006a41186a22084200370300200441e0006a41106a22094200370300200441e0006a41086a220a42003703002004420037036020074117200441e0006a1000200441306a41186a2008290300370300200441306a41106a2009290300370300200441306a41086a200a290300370300200420042903603703302007102a20044100360268200442013703604101200441e0006a10b4010340200620056a200441e0006a108f014120200541206a2205470d000b20042802642105200441306a4120200428026022072004280268100702402005450d002007102a0b2006102a0b200441146a200041086a2900003702002004411c6a200041106a290000370200200441246a200041186a290000370200200420013602082004200029000037020c411010282205450d04200541002900a68845370000200541086a41002900ae88453700002004429080808080023702b401200420053602b001200541104120102c2205450d05200441203602b401200420042802b801220041046a3602b801200420053602b001200520006a2001360000200441086a410472200441b0016a108f0120042802b801210520042802b0012100200441e0006a41186a22064200370300200441e0006a41106a22014200370300200441e0006a41086a220742003703002004420037036020002005200441e0006a1000200441306a41186a2006290300370300200441306a41106a2001290300370300200441306a41086a200729030037030020042004290360370330024020042802b401450d0020042802b001102a0b410110282205450d0641002100200541807f410020021b2003723a0000200441306a41202005410110072005102a0b200441d0016a240020000f0b412041011037000b411341011037000b412641011037000b411041011037000b412041011037000b410141011037000bc76501037f230041206b220224000240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024020002d00000eac010102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f80018101820183018401850186018701880189018a018b018c018d018e018f0190019101920193019401950196019701980199019a019b019c019d019e019f01a001a101a201a301a401a501a601a701a801a901aa01ab0100010b2002200128021841dfd6c50041112001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000cab010b2002200128021841f0d6c500410b2001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000caa010b2002200128021841fbd6c50041032001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000ca9010b2002200128021841fed6c50041052001411c6a28020028020c1100003a001820022001360210200241003a0019200241003602142002200041016a36020c200241106a2002410c6a4184d7c500105d21000ca8010b200220012802184194d7c50041042001411c6a28020028020c1100003a001820022001360210200241003a0019200241003602142002200041016a36020c200241106a2002410c6a4184d7c500105d21000ca7010b200220012802184198d7c50041022001411c6a28020028020c1100003a001820022001360210200241003a0019200241003602142002200041016a36020c200241106a2002410c6a4184d7c500105d21000ca6010b20022001280218419ad7c50041042001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000ca5010b20022001280218419ed7c50041032001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000ca4010b2002200128021841a1d7c50041022001411c6a28020028020c1100003a001820022001360210200241003a0019200241003602142002200041046a36020c200241106a2002410c6a41a8d6c500105d21000ca3010b2002200128021841a3d7c50041042001411c6a28020028020c1100003a001820022001360210200241003a0019200241003602142002200041046a36020c200241106a2002410c6a41a8d6c500105d21000ca2010b2002200128021841a7d7c50041072001411c6a28020028020c1100003a001820022001360210200241003a0019200241003602142002200041046a36020c200241106a2002410c6a41b0d7c500105d21000ca1010b2002200128021841c0d7c50041062001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000ca0010b2002200128021841c6d7c50041042001411c6a28020028020c1100003a001820022001360210200241003a0019200241003602142002200041046a36020c200241106a2002410c6a41a8d6c500105d21000c9f010b2002200128021841cad7c500410c2001411c6a28020028020c1100003a001820022001360210200241003a0019200241003602142002200041046a36020c200241106a2002410c6a41a8d6c500105d21012002200041016a36020c20012002410c6a41d8d7c500105d21000c9e010b2002200128021841e8d7c50041042001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000c9d010b2002200128021841ecd7c50041062001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000c9c010b2002200128021841f2d7c50041082001411c6a28020028020c1100003a001820022001360210200241003a0019200241003602142002200041046a36020c200241106a2002410c6a41a8d6c500105d21000c9b010b2002200128021841fad7c50041082001411c6a28020028020c1100003a001820022001360210200241003a0019200241003602142002200041046a36020c200241106a2002410c6a41a8d6c500105d21000c9a010b200220012802184182d8c50041082001411c6a28020028020c1100003a001820022001360210200241003a0019200241003602142002200041046a36020c200241106a2002410c6a41a8d6c500105d21000c99010b20022001280218418ad8c50041092001411c6a28020028020c1100003a001820022001360210200241003a0019200241003602142002200041046a36020c200241106a2002410c6a41a8d6c500105d21000c98010b200220012802184193d8c50041092001411c6a28020028020c1100003a001820022001360210200241003a0019200241003602142002200041046a36020c200241106a2002410c6a41a8d6c500105d21000c97010b20022001280218419cd8c50041072001411c6a28020028020c1100003a001820022001360210200241003a0019200241003602142002200041046a36020c200241106a2002410c6a41a8d6c500105d21012002200041086a36020c20012002410c6a41a8d6c500105d21000c96010b2002200128021841a3d8c50041072001411c6a28020028020c1100003a001820022001360210200241003a0019200241003602142002200041046a36020c200241106a2002410c6a41a8d6c500105d21012002200041086a36020c20012002410c6a41a8d6c500105d21000c95010b2002200128021841aad8c50041072001411c6a28020028020c1100003a001820022001360210200241003a0019200241003602142002200041046a36020c200241106a2002410c6a41a8d6c500105d21012002200041086a36020c20012002410c6a41a8d6c500105d21000c94010b2002200128021841b1d8c50041072001411c6a28020028020c1100003a001820022001360210200241003a0019200241003602142002200041046a36020c200241106a2002410c6a41a8d6c500105d21012002200041086a36020c20012002410c6a41a8d6c500105d21000c93010b2002200128021841b8d8c50041092001411c6a28020028020c1100003a001820022001360210200241003a0019200241003602142002200041046a36020c200241106a2002410c6a41a8d6c500105d21012002200041086a36020c20012002410c6a41a8d6c500105d21000c92010b2002200128021841c1d8c50041092001411c6a28020028020c1100003a001820022001360210200241003a0019200241003602142002200041046a36020c200241106a2002410c6a41a8d6c500105d21012002200041086a36020c20012002410c6a41a8d6c500105d21000c91010b2002200128021841cad8c500410a2001411c6a28020028020c1100003a001820022001360210200241003a0019200241003602142002200041046a36020c200241106a2002410c6a41a8d6c500105d21012002200041086a36020c20012002410c6a41a8d6c500105d21000c90010b2002200128021841d4d8c500410a2001411c6a28020028020c1100003a001820022001360210200241003a0019200241003602142002200041046a36020c200241106a2002410c6a41a8d6c500105d21012002200041086a36020c20012002410c6a41a8d6c500105d21000c8f010b2002200128021841ded8c50041092001411c6a28020028020c1100003a001820022001360210200241003a0019200241003602142002200041046a36020c200241106a2002410c6a41a8d6c500105d21012002200041086a36020c20012002410c6a41a8d6c500105d21000c8e010b2002200128021841e7d8c50041092001411c6a28020028020c1100003a001820022001360210200241003a0019200241003602142002200041046a36020c200241106a2002410c6a41a8d6c500105d21012002200041086a36020c20012002410c6a41a8d6c500105d21000c8d010b2002200128021841f0d8c500410a2001411c6a28020028020c1100003a001820022001360210200241003a0019200241003602142002200041046a36020c200241106a2002410c6a41a8d6c500105d21012002200041086a36020c20012002410c6a41a8d6c500105d21000c8c010b2002200128021841fad8c500410a2001411c6a28020028020c1100003a001820022001360210200241003a0019200241003602142002200041046a36020c200241106a2002410c6a41a8d6c500105d21012002200041086a36020c20012002410c6a41a8d6c500105d21000c8b010b200220012802184184d9c500410a2001411c6a28020028020c1100003a001820022001360210200241003a0019200241003602142002200041046a36020c200241106a2002410c6a41a8d6c500105d21012002200041086a36020c20012002410c6a41a8d6c500105d21000c8a010b20022001280218418ed9c500410a2001411c6a28020028020c1100003a001820022001360210200241003a0019200241003602142002200041046a36020c200241106a2002410c6a41a8d6c500105d21012002200041086a36020c20012002410c6a41a8d6c500105d21000c89010b200220012802184198d9c50041082001411c6a28020028020c1100003a001820022001360210200241003a0019200241003602142002200041046a36020c200241106a2002410c6a41a8d6c500105d21012002200041086a36020c20012002410c6a41a8d6c500105d21000c88010b2002200128021841a0d9c50041082001411c6a28020028020c1100003a001820022001360210200241003a0019200241003602142002200041046a36020c200241106a2002410c6a41a8d6c500105d21012002200041086a36020c20012002410c6a41a8d6c500105d21000c87010b2002200128021841a8d9c50041082001411c6a28020028020c1100003a001820022001360210200241003a0019200241003602142002200041046a36020c200241106a2002410c6a41a8d6c500105d21012002200041086a36020c20012002410c6a41a8d6c500105d21000c86010b2002200128021841b0d9c50041082001411c6a28020028020c1100003a001820022001360210200241003a0019200241003602142002200041046a36020c200241106a2002410c6a41a8d6c500105d21012002200041086a36020c20012002410c6a41a8d6c500105d21000c85010b2002200128021841b8d9c50041092001411c6a28020028020c1100003a001820022001360210200241003a0019200241003602142002200041046a36020c200241106a2002410c6a41a8d6c500105d21012002200041086a36020c20012002410c6a41a8d6c500105d21000c84010b2002200128021841c1d9c500410a2001411c6a28020028020c1100003a001820022001360210200241003a0019200241003602142002200041046a36020c200241106a2002410c6a41a8d6c500105d21012002200041086a36020c20012002410c6a41a8d6c500105d21000c83010b2002200128021841cbd9c50041092001411c6a28020028020c1100003a001820022001360210200241003a0019200241003602142002200041046a36020c200241106a2002410c6a41a8d6c500105d21012002200041086a36020c20012002410c6a41a8d6c500105d21000c82010b2002200128021841d4d9c500410a2001411c6a28020028020c1100003a001820022001360210200241003a0019200241003602142002200041046a36020c200241106a2002410c6a41a8d6c500105d21012002200041086a36020c20012002410c6a41a8d6c500105d21000c81010b2002200128021841ded9c500410a2001411c6a28020028020c1100003a001820022001360210200241003a0019200241003602142002200041046a36020c200241106a2002410c6a41a8d6c500105d21012002200041086a36020c20012002410c6a41a8d6c500105d21000c80010b2002200128021841e8d9c500410d2001411c6a28020028020c1100003a001820022001360210200241003a0019200241003602142002200041016a36020c200241106a2002410c6a41d8d7c500105d21000c7f0b2002200128021841f5d9c500410a2001411c6a28020028020c1100003a001820022001360210200241003a0019200241003602142002200041016a36020c200241106a2002410c6a41d8d7c500105d21000c7e0b2002200128021841ffd9c50041082001411c6a28020028020c1100003a001820022001360210200241003a0019200241003602142002200041046a36020c200241106a2002410c6a4188dac500105d21000c7d0b200220012802184198dac50041082001411c6a28020028020c1100003a001820022001360210200241003a0019200241003602142002200041086a36020c200241106a2002410c6a41a0dac500105d21000c7c0b2002200128021841b0dac50041082001411c6a28020028020c1100003a001820022001360210200241003a0019200241003602142002200041046a36020c200241106a2002410c6a41a8d6c500105d21000c7b0b2002200128021841b8dac50041082001411c6a28020028020c1100003a001820022001360210200241003a0019200241003602142002200041086a36020c200241106a2002410c6a41c0dac500105d21000c7a0b2002200128021841d0dac50041062001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000c790b2002200128021841d6dac50041052001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000c780b2002200128021841dbdac50041052001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000c770b2002200128021841e0dac50041062001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000c760b2002200128021841e6dac50041062001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000c750b2002200128021841ecdac50041062001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000c740b2002200128021841f2dac50041062001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000c730b2002200128021841f8dac50041062001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000c720b2002200128021841fedac50041062001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000c710b200220012802184184dbc50041062001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000c700b20022001280218418adbc50041062001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000c6f0b200220012802184190dbc50041062001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000c6e0b200220012802184196dbc50041052001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000c6d0b20022001280218419bdbc50041052001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000c6c0b2002200128021841a0dbc50041062001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000c6b0b2002200128021841a6dbc50041062001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000c6a0b2002200128021841acdbc50041062001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000c690b2002200128021841b2dbc50041062001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000c680b2002200128021841b8dbc50041062001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000c670b2002200128021841bedbc50041062001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000c660b2002200128021841c4dbc50041062001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000c650b2002200128021841cadbc50041062001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000c640b2002200128021841d0dbc50041052001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000c630b2002200128021841d5dbc50041052001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000c620b2002200128021841dadbc50041052001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000c610b2002200128021841dfdbc50041052001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000c600b2002200128021841e4dbc50041052001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000c5f0b2002200128021841e9dbc50041052001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000c5e0b2002200128021841eedbc50041052001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000c5d0b2002200128021841f3dbc50041052001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000c5c0b2002200128021841f8dbc50041052001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000c5b0b2002200128021841fddbc50041052001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000c5a0b200220012802184182dcc50041052001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000c590b200220012802184187dcc50041052001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000c580b20022001280218418cdcc50041062001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000c570b200220012802184192dcc50041062001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000c560b200220012802184198dcc50041092001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000c550b2002200128021841a1dcc50041062001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000c540b2002200128021841a7dcc50041062001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000c530b2002200128021841addcc50041062001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000c520b2002200128021841b3dcc50041072001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000c510b2002200128021841badcc50041072001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000c500b2002200128021841c1dcc50041072001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000c4f0b2002200128021841c8dcc50041072001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000c4e0b2002200128021841cfdcc50041062001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000c4d0b2002200128021841d5dcc50041052001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000c4c0b2002200128021841dadcc50041062001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000c4b0b2002200128021841e0dcc50041062001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000c4a0b2002200128021841e6dcc50041072001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000c490b2002200128021841eddcc50041072001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000c480b2002200128021841f4dcc50041072001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000c470b2002200128021841fbdcc50041072001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000c460b200220012802184182ddc50041062001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000c450b200220012802184188ddc50041062001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000c440b20022001280218418eddc50041092001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000c430b200220012802184197ddc50041062001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000c420b20022001280218419dddc50041062001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000c410b2002200128021841a3ddc50041062001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000c400b2002200128021841a9ddc50041072001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000c3f0b2002200128021841b0ddc50041072001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000c3e0b2002200128021841b7ddc50041072001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000c3d0b2002200128021841beddc50041072001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000c3c0b2002200128021841c5ddc50041062001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000c3b0b2002200128021841cbddc50041052001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000c3a0b2002200128021841d0ddc50041062001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000c390b2002200128021841d6ddc50041062001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000c380b2002200128021841dcddc50041072001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000c370b2002200128021841e3ddc50041072001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000c360b2002200128021841eaddc50041072001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000c350b2002200128021841f1ddc50041072001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000c340b2002200128021841f8ddc50041062001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000c330b2002200128021841feddc50041062001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000c320b200220012802184184dec50041072001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000c310b20022001280218418bdec50041082001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000c300b200220012802184193dec50041082001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000c2f0b20022001280218419bdec500410a2001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000c2e0b2002200128021841a5dec50041072001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000c2d0b2002200128021841acdec50041062001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000c2c0b2002200128021841b2dec50041062001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000c2b0b2002200128021841b8dec50041062001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000c2a0b2002200128021841bedec50041062001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000c290b2002200128021841c4dec50041062001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000c280b2002200128021841cadec50041062001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000c270b2002200128021841d0dec500410b2001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000c260b2002200128021841dbdec50041062001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000c250b2002200128021841e1dec50041062001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000c240b2002200128021841e7dec50041072001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000c230b2002200128021841eedec50041082001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000c220b2002200128021841f6dec50041082001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000c210b2002200128021841fedec500410a2001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000c200b200220012802184188dfc50041072001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000c1f0b20022001280218418fdfc50041062001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000c1e0b200220012802184195dfc50041062001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000c1d0b20022001280218419bdfc50041062001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000c1c0b2002200128021841a1dfc50041062001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000c1b0b2002200128021841a7dfc50041062001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000c1a0b2002200128021841addfc50041062001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000c190b2002200128021841b3dfc500410b2001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000c180b2002200128021841bedfc500410a2001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000c170b2002200128021841c8dfc500410c2001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000c160b2002200128021841d4dfc500410c2001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000c150b2002200128021841e0dfc500410c2001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000c140b2002200128021841ecdfc500410c2001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000c130b2002200128021841f8dfc500410d2001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000c120b200220012802184185e0c500410d2001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000c110b200220012802184192e0c500410c2001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000c100b20022001280218419ee0c500410c2001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000c0f0b2002200128021841aae0c500410c2001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000c0e0b2002200128021841b6e0c500410c2001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000c0d0b2002200128021841c2e0c500410e2001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000c0c0b2002200128021841d0e0c500410e2001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000c0b0b2002200128021841dee0c500410e2001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000c0a0b2002200128021841ece0c500410e2001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000c090b2002200128021841fae0c500410c2001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000c080b200220012802184186e1c500410e2001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000c070b200220012802184194e1c500410e2001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000c060b2002200128021841a2e1c500410e2001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000c050b2002200128021841b0e1c500410e2001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000c040b2002200128021841bee1c500410d2001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000c030b2002200128021841cbe1c50041112001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000c020b2002200128021841dce1c50041112001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000c010b2002200128021841ede1c50041112001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000b20002d00082101024020002802042203450d00200141ff0171210441012101024020040d00024020034101470d0020002d0009450d00200028020022042d00004104710d0041012101200428021841f4afc00041012004411c6a28020028020c1100000d010b2000280200220128021841c8a4c60041012001411c6a28020028020c11000021010b200020013a00080b200241206a2400200141ff01714100470bcd0203027f017e017f23004180016b220224002000280200210002400240024002400240200128020022034110710d002000280200210020034120710d012000ac22042004423f8722047c2004852000417f73411f762001103f21000c020b20002802002103410021000340200220006a41ff006a2003410f712205413072200541d7006a2005410a491b3a00002000417f6a2100200341047622030d000b20004180016a22034181014f0d0220014101419087c0004102200220006a4180016a410020006b104221000c010b410021030340200220036a41ff006a2000410f712205413072200541376a2005410a491b3a00002003417f6a2103200041047622000d000b20034180016a22004181014f0d0220014101419087c0004102200220036a4180016a410020036b104221000b20024180016a240020000f0b20034180011044000b20004180011044000bcd0202027f027e23004180016b220224002000280200210002400240024002400240200128020022034110710d002000290300210420034120710d0120042004423f8722057c2005852004427f552001103f21000c020b20002903002104410021000340200220006a41ff006a2004a7410f712203413072200341d7006a2003410a491b3a00002000417f6a2100200442048822044200520d000b20004180016a22034181014f0d0220014101419087c0004102200220006a4180016a410020006b104221000c010b410021000340200220006a41ff006a2004a7410f712203413072200341376a2003410a491b3a00002000417f6a2100200442048822044200520d000b20004180016a22034181014f0d0220014101419087c0004102200220006a4180016a410020006b104221000b20024180016a240020000f0b20034180011044000b20034180011044000bc00201037f23004180016b220224002000280200210002400240024002400240200128020022034110710d0020002d0000210420034120710d012004ad42ff018341012001103f21000c020b20002d00002104410021000340200220006a41ff006a2004410f712203413072200341d7006a2003410a491b3a00002000417f6a21002004410476410f7122040d000b20004180016a22044181014f0d0220014101419087c0004102200220006a4180016a410020006b104221000c010b410021000340200220006a41ff006a2004410f712203413072200341376a2003410a491b3a00002000417f6a21002004410476410f7122040d000b20004180016a22044181014f0d0220014101419087c0004102200220006a4180016a410020006b104221000b20024180016a240020000f0b20044180011044000b20044180011044000bd30101017f230041106b22022400024002400240024020002d00000e03010200010b2002200128021841fee1c500410b2001411c6a28020028020c11000022003a000820022001360200200241003a0009200241003602040c020b200220012802184189e2c500410c2001411c6a28020028020c11000022003a000820022001360200200241003a0009200241003602040c010b200220012802184195e2c500410d2001411c6a28020028020c11000022003a000820022001360200200241003a0009200241003602040b200241106a240020000b8a0201027f230041106b2202240020002802002802002100200128021841b8d6c500410b2001411c6a28020028020c1100002103200241003a0005200220033a0004200220013602002002200036020c200241c3d6c50041052002410c6a41c8d6c500105c21012002200041086a36020c200141d8d6c50041072002410c6a41a8d6c500105c1a20022d00042101024020022d0005450d00200141ff0171210041012101024020000d0020022802002201411c6a28020028020c210020012802182103024020012d00004104710d00200341eeafc0004102200011000021010c010b200341f0afc0004101200011000021010b200220013a00040b200241106a2400200141ff01714100470b890501047f230041d0006b220224002000280200220041046a28020021032000280200210041012104200128021841adafc00041012001411c6a28020028020c110000210502402003450d0020022000360204024020050d00024020012d0000410471450d0041012104200128021841afafc0004101200128021c28020c1100000d012001280200210541012104200241013a001720022005360218200241b0afc00036023420022001290218370308200220012d00303a00482002200128020436021c200220012902283703402002200129022037033820022001290210370328200220012902083703202002200241176a3602102002200241086a360230200241046a200241186a10d8010d01200228023041c8afc0004102200228023428020c11000021040c010b200241046a200110d80121040b024020034101470d00200421050c010b200041046a21002003410274417c6a210320042105034020022000360204200541ff0171210441012105024020040d00024020012802002204410471450d00200241013a001720022004360218200241b0afc00036023420022001290218370308200220012d00303a00482002200128020436021c200220012902283703402002200129022037033820022001290210370328200220012902083703202002200241176a3602102002200241086a360230200241046a200241186a10d8010d01200228023041c8afc0004102200228023428020c11000021050c010b200128021841caafc0004102200128021c28020c1100000d00200241046a200110d80121050b200041046a21002003417c6a22030d000b0b41012100024020050d00200128021841aeafc0004101200128021c28020c11000021000b200241d0006a240020000b19002000200141186a280200360204200020012802103602000bc50201037f230041206b2202240002400240200028020022002d00004104470d002002200128021841b7e2c50041082001411c6a28020028020c11000022003a001820022001360210200241003a0019200241003602140c010b2002200128021841bfe2c50041052001411c6a28020028020c1100003a001820022001360210200241003a0019200241003602142002200036020c200241106a2002410c6a41c4e2c500105d210120022d0018210020022802142203450d00200041ff0171210441012100024020040d00024020034101470d0020012d0009450d00200128020022042d00004104710d0041012100200428021841f4afc00041012004411c6a28020028020c1100000d010b2001280200220028021841c8a4c60041012000411c6a28020028020c11000021000b200120003a00080b200241206a2400200041ff01714100470b0c002000280200200110d0040b8f0201017f230041106b220224000240024002400240024020002d00000e0401020300010b2002200128021841d4e2c50041032001411c6a28020028020c11000022003a000820022001360200200241003a0009200241003602040c030b2002200128021841d7e2c50041032001411c6a28020028020c11000022003a000820022001360200200241003a0009200241003602040c020b2002200128021841dae2c50041032001411c6a28020028020c11000022003a000820022001360200200241003a0009200241003602040c010b2002200128021841dde2c50041032001411c6a28020028020c11000022003a000820022001360200200241003a0009200241003602040b200241106a240020000bc00201037f230041206b220224000240024020002d00004104470d002002200128021841b7e2c50041082001411c6a28020028020c11000022003a001820022001360210200241003a0019200241003602140c010b2002200128021841bfe2c50041052001411c6a28020028020c1100003a001820022001360210200241003a0019200241003602142002200036020c200241106a2002410c6a41c4e2c500105d210120022d0018210020022802142203450d00200041ff0171210441012100024020040d00024020034101470d0020012d0009450d00200128020022042d00004104710d0041012100200428021841f4afc00041012004411c6a28020028020c1100000d010b2001280200220028021841c8a4c60041012000411c6a28020028020c11000021000b200120003a00080b200241206a2400200041ff01714100470b0c002000280200200110c6040bed0902067f017e024020010d00200041ac013a00000f0b024002400240024002400240024020012d00002202414f6a41fb004f0d000c010b02400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024020020e312c2c0001022c2c0304052c06072c2c08090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292c0b20012d00012103410221020c2b0b20012d00012103410321020c2a0b20012d00012103410421020c290b200141046a2802002104410721020c270b200141046a2802002104410821020c260b200141046a2802002105410c10282204450d272005280204220641ffffffff03712006470d2820064102742201417f4c0d280240024020010d00410421070c010b200110282207450d2a0b02402006450d00200528020021012006410274210320072102034020022001280200360200200241046a2102200141046a21012003417c6a22030d000b0b200420063602042004200736020020042005280208360208410921020c250b200141046a2802002104410b21020c240b200141046a280200210420012d00012103410c21020c240b200141046a2802002104410f21020c220b200141046a2802002104411021020c210b200141046a2802002104411121020c200b200141046a2802002104411221020c1f0b200141046a2802002104411321020c1e0b200141046a280200210420013502082108411421020c1d0b200141046a280200210420013502082108411521020c1c0b200141046a280200210420013502082108411621020c1b0b200141046a280200210420013502082108411721020c1a0b200141046a280200210420013502082108411821020c190b200141046a280200210420013502082108411921020c180b200141046a280200210420013502082108411a21020c170b200141046a280200210420013502082108411b21020c160b200141046a280200210420013502082108411c21020c150b200141046a280200210420013502082108411d21020c140b200141046a280200210420013502082108411e21020c130b200141046a280200210420013502082108411f21020c120b200141046a280200210420013502082108412021020c110b200141046a280200210420013502082108412121020c100b200141046a280200210420013502082108412221020c0f0b200141046a280200210420013502082108412321020c0e0b200141046a280200210420013502082108412421020c0d0b200141046a280200210420013502082108412521020c0c0b200141046a280200210420013502082108412621020c0b0b200141046a280200210420013502082108412721020c0a0b200141046a280200210420013502082108412821020c090b200141046a280200210420013502082108412921020c080b200141046a280200210420013502082108412a21020c070b20012d00012103412b21020c070b20012d00012103412c21020c060b200141046a2802002104412d21020c040b20012903082108412e21020c020b200141046a2802002104412f21020c020b20012903082108413021020b0b0b200020033a0001200020023a0000200041086a2008370300200041046a20043602000f0b410c41041037000b1036000b200141041037000bba0201037f230041106b220224000240024020002802000d002002200128021841e0e2c50041042001411c6a28020028020c11000022003a000820022001360200200241003a0009200241003602040c010b2002200128021841e4e2c50041042001411c6a28020028020c1100003a000820022001360200200241003a0009200241003602042002200036020c20022002410c6a41e8e2c500105d210120022d0008210020022802042203450d00200041ff0171210441012100024020040d00024020034101470d0020012d0009450d00200128020022042d00004104710d0041012100200428021841f4afc00041012004411c6a28020028020c1100000d010b2001280200220028021841c8a4c60041012000411c6a28020028020c11000021000b200120003a00080b200241106a2400200041ff01714100470b22002001419daec0004198aec00020002802002d000022001b4104410520001b10450bd60501087f230041106b220324002002280208220441546a2105200241106a280200220641306c210702400340410021082007450d01200741506a21072005412c6a2109200541306a220a210520092d00004103470d000b200a41086a2802002207450d00200741286c2105200a28020041186a2107410021080340200820072d0000456a2108200741286a2107200541586a22050d000b0b02400240024002400240024002400240200120086b220a20014b0d00200641306c2107200441546a210503402007450d02200741506a21072005412c6a2108200541306a2209210520082d0000410c470d000b200941086a280200200a4b0d02411e102822070d05411e41011037000b412c102822070d02412c41011037000b412c102822070d02412c41011037000b2009280200200a41186c6a28020821072003200a200210dd0420032802004101460d0320032802042105200041003602002000200520076a3602040c040b2000200736020420004101360200200741286a41002800fee545360000200741206a41002900f6e545370000200741186a41002900eee545370000200741106a41002900e6e545370000200741086a41002900dee545370000200741002900d6e545370000200041086a42ac808080c0053702000c030b2000200736020420004101360200200741286a41002800aae645360000200741206a41002900a2e645370000200741186a410029009ae645370000200741106a4100290092e645370000200741086a410029008ae64537000020074100290082e645370000200041086a42ac808080c0053702000c020b2000200736020420004101360200200741166a41002900c4e645370000200741106a41002900bee645370000200741086a41002900b6e645370000200741002900aee645370000200041086a429e808080e0033702000c010b20002003290204370204200041013602002000410c6a2003410c6a2802003602000b200341106a24000b8d0301067f230041106b220224000240024002400240200041046a2802002203200041086a28020022046b20012802042205200128020022066b4104762207490d00200028020021030c010b200420076a22062004490d02200341017422052006200520064b1b220641ffffffff00712006470d02200641047422054100480d020240024020030d002005102821030c010b200028020020034104742005102c21030b2003450d0120002003360200200041046a2006360200200041086a280200210420012802042105200128020021060b0240024020062005470d00410021060c010b2001200641106a3602000b2002200610d304024020022d000041ac01460d00200320044104746a2106034020062002290300370300200641086a200241086a29030037030002400240200128020022052001280204470d00410021050c010b2001200541106a3602000b200441016a2104200641106a21062002200510d30420022d000041ac01470d000b0b200041086a2004360200200241106a24000f0b200541081037000b1031000b1000200028020035020041012001103f0be00a01067f024002400240024020012d00002202414f6a41fb00490d0002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024020020e312a2a0001022a2a0304052a06072a2a08090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a0b200020012d00013a0001200041023a00000f0b200020012d00013a0001200041033a00000f0b200020012d00013a0001200041043a00000f0b200041046a200141046a280200360200200041073a00000f0b200041046a200141046a280200360200200041083a00000f0b200141046a2802002103410c10282204450d252003280204220541ffffffff03712005470d2620054102742201417f4c0d260240024020010d00410421060c010b200110282206450d280b02402005450d00200328020021012005410274210720062102034020022001280200360200200241046a2102200141046a21012007417c6a22070d000b0b200420053602042004200636020020042003280208360208200041046a2004360200200041093a00000f0b200041046a200141046a2802003602002000410b3a00000f0b200020012d00013a0001200041046a200141046a2802003602002000410c3a00000f0b200041046a200141046a2802003602002000410f3a00000f0b200041046a200141046a280200360200200041103a00000f0b200041046a200141046a280200360200200041113a00000f0b200041046a200141046a280200360200200041123a00000f0b200041046a200141046a280200360200200041133a00000f0b200041046a200141046a290200370200200041143a00000f0b200041046a200141046a290200370200200041153a00000f0b200041046a200141046a290200370200200041163a00000f0b200041046a200141046a290200370200200041173a00000f0b200041046a200141046a290200370200200041183a00000f0b200041046a200141046a290200370200200041193a00000f0b200041046a200141046a2902003702002000411a3a00000f0b200041046a200141046a2902003702002000411b3a00000f0b200041046a200141046a2902003702002000411c3a00000f0b200041046a200141046a2902003702002000411d3a00000f0b200041046a200141046a2902003702002000411e3a00000f0b200041046a200141046a2902003702002000411f3a00000f0b200041046a200141046a290200370200200041203a00000f0b200041046a200141046a290200370200200041213a00000f0b200041046a200141046a290200370200200041223a00000f0b200041046a200141046a290200370200200041233a00000f0b200041046a200141046a290200370200200041243a00000f0b200041046a200141046a290200370200200041253a00000f0b200041046a200141046a290200370200200041263a00000f0b200041046a200141046a290200370200200041273a00000f0b200041046a200141046a290200370200200041283a00000f0b200041046a200141046a290200370200200041293a00000f0b200041046a200141046a2902003702002000412a3a00000f0b200020012d00013a00012000412b3a00000f0b200020012d00013a00012000412c3a00000f0b200041046a200141046a2802003602002000412d3a00000f0b200041086a200141086a2903003703002000412e3a00000f0b200041046a200141046a2802003602002000412f3a00000f0b200041086a200141086a290300370300413021020b200020023a00000f0b410c41041037000b1036000b200141041037000bea0302057f017e02402001450d00034020002802940321002001417f6a22010d000b0b02402002450d004100210341002101034002400240200120002f01064f0d00200020014105746a220441c4006a2802002105200441386a2802002106200441346a2802002107200141016a21010c010b02400240200028020022010d002003ad210841002104410021010c010b20003301044220862003ad842108410121040b2000102a2008a72103024002402008422088a7220620012f01064f0d00200121050c010b034002400240200128020022050d002003ad2108410021050c010b200441016a210420013301044220862003ad8421080b2001102a2008a72103200521012008422088a7220620052f01064f0d000b0b200641027420056a4198036a2802002100200520064105746a220141c4006a2802002105200141386a2802002106200141346a280200210702402004417f6a2201450d00034020002802940321002001417f6a22010d000b0b410021010b20054102460d012002417f6a210202402006450d002007102a0b20020d000b0b0240200041f8b9c000460d00200028020021012000102a2001450d00200128020021052001102a2005450d00024020052802002201450d0003402005102a2001210520012802002200210120000d000b0b2005102a0b0bba09010b7f230041e0006b22032400200320013602202002280208220441546a2105200241106a280200220641306c210202400340024020020d00410021070c020b200241506a21022005412c6a2107200541306a2208210520072d00004102470d000b200341186a200810fa0320032802182107200328021c21020b2002410020071b2109200641306c2102200441546a21052007410420071b210a02400340024020020d004100210b0c020b200241506a21022005412c6a2107200541306a2208210520072d00004104470d000b200341106a200810fa032003280210210b2003280214210c0b200641306c2102200441546a2105200b4104200b1b210d02400240024002400240024003402002450d01200241506a21022005412c6a2107200541306a2208210520072d00004103470d000b200841086a2802002202450d00200241286c2107200828020041186a2102410021050340200520022d0000456a2105200241286a2102200741586a22070d000b200520014d0d01200641306c2102200441546a2105024003402002450d01200241506a21022005412c6a2107200541306a2208210520072d00004103470d000b200341086a200810fa0320032802082202200328020c41286c6a21070240024002400340024002400240200720026b41f8004b0d0020022007460d0d2002411c6a2105034020022d0018450d02200541286a2105200241286a22022007470d000c0e0b0b20022d00180d01200241186a2105200241286a21080c040b2005410c6a21080c040b200241c0006a22052d0000450d010240200241e8006a22052d0000450d0020024190016a2105200241a0016a2208210220052d00000d010c030b0b200241f8006a21080c010b200241d0006a21080b200541046a21050b2001450d0303402001417f6a210120082102024002400340024002400240200720026b41f8004b0d0020022007460d0d2002411c6a2105034020022d0018450d02200541286a2105200241286a22022007460d0e0c000b0b20022d00180d01200241186a2105200241286a21080c040b2005410c6a210820010d040c080b200241c0006a22052d0000450d010240200241e8006a22052d0000450d0020024190016a2105200241a0016a2208210220052d00000d010c030b0b200241f8006a21080c010b200241d0006a21080b20010d000b200541046a21050c030b41cce6c50041c2001050000b410021050b0240200c4100200b1b200120056b22024d0d00200d20024102746a22050d010b200341cc006a41013602002003420237023c200341ece7c5003602382003410136022c2003200341286a3602482003200341206a360228200341d0006a200341386a1033200341d0006a21020c010b2003200528020022023602240240200920024d0d00200a20024104746a2202450d0020002002360204410021020c020b200341cc006a4102360200200341dc006a41013602002003420337023c200341fce7c500360238200341013602542003200341d0006a3602482003200341206a3602582003200341246a360250200341286a200341386a1033200341286a21020b20022802002105200041086a200229020437020020002005360204410121020b20002002360200200341e0006a24000f0b418ee7c50041dd001050000bf80d01067f0240024020002d00002201410e4b0d00024002400240024002400240024002400240024002400240024020010e0f0001020304050607080e090e0a0b0c000b200041086a280200450d0d200041046a280200102a0f0b0240200041086a280200450d00200041046a280200102a0b200041146a280200450d0c200041106a280200102a0f0b02402000410c6a2802002202450d00200041046a28020021012002410474210203400240200141046a280200450d002001280200102a0b200141106a2101200241706a22020d000b0b200041086a280200450d0b2000280204102a0f0b02402000410c6a2802002202450d00200041046a2802002101200241286c210203400240200141046a280200450d002001280200102a0b0240200141106a280200450d002001410c6a280200102a0b200141286a2101200241586a22020d000b0b200041086a280200450d0a2000280204102a0f0b200041086a280200450d09200041046a280200102a0f0b200041086a280200450d08200041046a280200102a0f0b200041086a280200450d07200041046a280200102a0f0b02402000410c6a2802002201450d00200041046a280200220320014104746a21040340024020032802082202450d0020032802002101200241047421020340024020012d00004109470d000240200141046a2205280200220628020441ffffffff0371450d002006280200102a200528020021060b2006102a0b200141106a2101200241706a22020d000b0b200341106a21010240200341046a280200450d002003280200102a0b2001210320012004470d000b0b200041086a280200450d062000280204102a0f0b02402000410c6a2802002202450d00200041046a2802002101200241146c210203400240200141046a280200450d002001280200102a0b200141146a21012002416c6a22020d000b0b200041086a280200450d052000280204102a0f0b02402000410c6a2802002201450d00200041046a28020022032001411c6c6a21040340024020032802042201450d0002402003410c6a2802002202450d00200241047421020340024020012d00004109470d000240200141046a2205280200220628020441ffffffff0371450d002006280200102a200528020021060b2006102a0b200141106a2101200241706a22020d000b0b200341086a280200450d002003280204102a0b2003411c6a21010240200341146a280200450d002003280210102a0b2001210320012004470d000b0b200041086a280200450d042000280204102a0f0b02402000410c6a2802002201450d00200041046a2802002203200141186c6a210403400240200341046a280200450d002003280200102a0b0240200341146a2802002202450d00200328020c2101200241047421020340024020012d00004109470d000240200141046a2205280200220628020441ffffffff0371450d002006280200102a200528020021060b2006102a0b200141106a2101200241706a22020d000b0b200341186a21010240200341106a280200450d00200328020c102a0b2001210320012004470d000b0b200041086a280200450d032000280204102a0f0b02402000410c6a2802002201450d00200041046a28020022032001411c6c6a21040340024020032802042201450d0002402003410c6a2802002202450d00200241047421020340024020012d00004109470d000240200141046a2205280200220628020441ffffffff0371450d002006280200102a200528020021060b2006102a0b200141106a2101200241706a22020d000b0b200341086a280200450d002003280204102a0b2003411c6a21010240200341146a280200450d002003280210102a0b2001210320012004470d000b0b200041086a280200450d022000280204102a0f0b0240200041046a2802002201450d00200041086a280200450d002001102a0b0240200041146a2802002201450d0002402000411c6a2802002202450d002002410c6c21020340024020012802002206450d00200141046a280200450d002006102a0b2001410c6a2101200241746a22020d000b0b200041186a280200450d002000280214102a0b200041246a2802002203450d0102402000412c6a2802002201450d00200320014104746a210403402003220541106a2103024020052802042201450d0002402005410c6a2802002202450d002002410c6c21020340024020012802002206450d00200141046a280200450d002006102a0b2001410c6a2101200241746a22020d000b0b200541086a280200450d002005280204102a0b20032004470d000b0b200041286a280200450d012000280224102a0c010b0240200041086a280200450d00200041046a280200102a0b0240200041146a2802002201450d00200041186a280200450d002001102a0b200041246a280200450d00200041206a280200102a0f0b0bd65e010c7f23004190016b220324002003200136021c2002280208220441546a2105200241106a280200220641306c21010240024002400240024002400240024002400240024002400240024003402001450d01200141506a21012005412c6a2107200541306a2208210520072d00004104470d000b200641306c2101200441546a210503402001450d02200141506a21012005412c6a2107200541306a2209210520072d0000410c470d000b200641306c2101200441546a210503402001450d03200141506a21012005412c6a2107200541306a2204210520072d00004102470d000b02404100280280b1464105490d002003410136023c20032003411c6a3602384100280284b146210120034188016a41980136020020034180016a42ed80808010370300200341f8006a4125360200200341f0006a4101360200200341e0006a4201370300200341d8006a410a360200200341fcf0c50036027c200341d7f0c500360274200341ec006a200341386a360200200341f8edc50036025c200341cdf0c500360254200341053602504188b1c60041b8aec600200141024622011b200341d0006a41c8b0c00041e0b0c00020011b2802101102000b200341106a200810fa032003280214200328021c22014d0d03200328021020014102746a2201450d03200341086a200410fa030240200328020c200128020022014d0d00200328020820014104746a22010d050b412510282201450d052001411d6a410029009dee45370000200141186a4100290098ee45370000200141106a4100290090ee45370000200141086a4100290088ee4537000020014100290080ee45370000200041086a42a5808080d00437020020002001360204200041013602000c0d0b411310282201450d082001410f6a41002800d3ed45360000200141086a41002900cced45370000200141002900c4ed45370000200041086a4293808080b00237020020002001360204200041013602000c0c0b410f10282201450d06200141076a41002900deed45370000200141002900d7ed45370000200041086a428f808080f00137020020002001360204200041013602000c0b0b410f10282201450d04200141076a41002900eded45370000200141002900e6ed45370000200041086a428f808080f00137020020002001360204200041013602000c0a0b412510282201450d022001411d6a410029009dee45370000200141186a4100290098ee45370000200141106a4100290090ee45370000200141086a4100290088ee4537000020014100290080ee45370000200041086a42a5808080d00437020020002001360204200041013602000c090b02400240200941086a280200200328021c22054b0d00412710282201450d012001411f6a41002900c4ee45370000200141186a41002900bdee45370000200141106a41002900b5ee45370000200141086a41002900adee45370000200141002900a5ee45370000200041086a42a7808080f00437020020002001360204200041013602000c0a0b20092802002109200341206a41086a420037030020034280808080c00037032020012d000d2107410021012003410036024020032007410447220a36023c2003200a360238200341003a0044024002400240024002404100280280b14641044b0d00200341d0006a41086a200341386a41086a29030037030020032003290338370350200341206a410472210b200341d0006a21070c010b2003412d36024c2003200341386a3602484100280284b146210120034188016a41cb0036020020034180016a42ed80808010370300200341f8006a4125360200200341f0006a4101360200200341e0006a4201370300200341d0006a41086a2207410a360200200341fcf0c50036027c200341d7f0c500360274200341ec006a200341c8006a360200200341cceec50036025c200341cdf0c500360254200341053602504188b1c60041b8aec600200141024622011b200341d0006a41c8b0c00041e0b0c00020011b280210110200200328022c2108200328022821012007200341386a41086a29030037030020032003290338370350200341206a410472210b200341d0006a210720082001470d010b200141016a22082001490d01200141017422062008200620084b1b220841ffffffff00712008470d01200841047422064100480d010240024020010d002006102821010c010b200b28020020014104742006102c21010b2001450d02200b200136020020032008360228200328022c21080b200b28020020084104746a22012007290200370200200141086a200741086a2902003702002003200328022c41016a36022c410021072009200541186c6a2201280214450d092009200541186c6a410c6a2109200141146a2108200341d0006a410472210c410021074100210103400240200328022020074d0d00200341d0006a200341206a410010e304024020032802504101470d00200041013602002000200c2902003702042000410c6a200c41086a2802003602000c0d0b2007200328022020032802542d000c1b21070b02400240024002400240024002402001200828020022054f0d002003200928020020014104746a220536023402404100280280b1464105490d002003412936023c2003200341346a3602384100280284b1462105200341c90136028801200342ed8080801037038001200341fcf0c50036027c20034125360278200341d7f0c5003602742003410136027020034201370360200341b0aec60036025c2003410a360258200341cdf0c500360254200341053602502003200341386a36026c4188b1c60041b8aec600200541024622051b200341d0006a41c8b0c00041e0b0c00020051b280210110200200328023421050b024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024020052d000022060eac0102220000002201030405060708090a0b0c0d0e0f1010101010101010101010101010111111111111111111121314141414151616161616161616161615161616161616161616161616161616161616161616161717171818181818181818181818181818181717171818181818181818181818181818181717171717171718181818181818171717171717171818181818181819191919191919191919191919191919191919191919191919020b20052d00012105200320032802203602402003200541044722053602382003200641034720057136023c200341003a004402404100280280b1464105490d002003412d36024c2003200341386a3602484100280284b1462105200341cb0036028801200342ed8080801037038001200341fcf0c50036027c20034125360278200341d7f0c5003602742003410136027020034201370360200341cceec50036025c2003410a360258200341cdf0c500360254200341053602502003200341c8006a36026c4188b1c60041b8aec600200541024622051b200341d0006a41c8b0c00041e0b0c00020051b2802101102000b200341d0006a41086a2206200341386a41086a290300370300200320032903383703500240200328022c22052003280228470d00200541016a220d2005490d242005410174220e200d200e200d4b1b220d41ffffffff0071200d470d24200d410474220e4100480d240240024020050d00200e102821050c010b200b2802002005410474200e102c21050b2005450d1d200b20053602002003200d360228200328022c21050b200b28020020054104746a22052003290350370200200541086a20062903003702002003200328022c41016a36022c0c210b4100210502404100280280b1464105490d000240200328022c2206417f6a220d20064b0d00200b280200200d4104746a4100200d2006491b21050b2003412e36024c200320053602382003200341386a3602484100280284b1462105200341d30036028801200342ed8080801037038001200341fcf0c50036027c20034125360278200341d7f0c5003602742003410136027020034201370360200341d4eec50036025c2003410a360258200341cdf0c500360254200341053602502003200341c8006a36026c4188b1c60041b8aec600200541024622051b200341d0006a41c8b0c00041e0b0c00020051b2802101102000b0240200328022c2205450d0020032005417f6a220536022c200b28020020054104746a22052d000c4102470d1a0b411710282201450d1c2001410f6a41002900ebee45370000200141086a41002900e4ee45370000200141002900dcee45370000200041086a4297808080f00237020020002001360204200041013602000c2c0b02404100280280b1464105490d004100280284b1462105200341c10036028801200342ed8080801037038001200341fcf0c50036027c20034125360278200341d7f0c5003602742003420437026c20034201370360200341f4eec50036025c2003410a360258200341cdf0c500360254200341053602504188b1c60041b8aec600200541024622051b200341d0006a41c8b0c00041e0b0c00020051b2802101102000b0240200328022c2205417f6a220620054f0d00200620054d0d180b411710282201450d1e2001410f6a41002900ebee45370000200141086a41002900e4ee45370000200141002900dcee45370000200041086a4297808080f00237020020002001360204200041013602000c2b0b200341d0006a200341206a200541046a28020010e304024020032802504101470d00200041013602002000200c2902003702042000410c6a200c41086a2802003602000c2b0b200341d0006a200341206a200328025428020410e40402402003280250450d0020002003290350370204200041013602002000410c6a200341d8006a2802003602000c2b0b02404100280280b1464105490d004100280284b1462105200341c10036028801200342ed8080801037038001200341fcf0c50036027c20034125360278200341d7f0c5003602742003420437026c20034201370360200341f4eec50036025c2003410a360258200341cdf0c500360254200341053602504188b1c60041b8aec600200541024622051b200341d0006a41c8b0c00041e0b0c00020051b2802101102000b024002400240200328022c2205417f6a220620054f0d00200620054d0d010b4117102822010d01411741011037000b200b28020020064104746a41013a000c0c1f0b2001410f6a41002900ebee45370000200141086a41002900e4ee45370000200141002900dcee45370000200041086a4297808080f00237020020002001360204200041013602000c2a0b200341d0006a200341206a200541046a28020010e304024020032802504101470d00200041013602002000200c2902003702042000410c6a200c41086a2802003602000c2a0b200341d0006a200341206a2003280254280204220510e40402402003280250450d0020002003290350370204200041013602002000410c6a200341d8006a2802003602000c2a0b200341d0006a200341206a410110e40402402003280250450d0020002003290350370204200041013602002000410c6a200341d8006a2802003602000c2a0b2003200536024802404100280280b1464105490d002003410136023c2003200341c8006a3602384100280284b1462105200341e30036028801200342ed8080801037038001200341fcf0c50036027c20034125360278200341d7f0c5003602742003410136027020034201370360200341fceec50036025c2003410a360258200341cdf0c500360254200341053602502003200341386a36026c4188b1c60041b8aec600200541024622051b200341d0006a41c8b0c00041e0b0c00020051b280210110200200328024821050b024002402003280220220620056a220520064f0d00410e102822010d01410e41011037000b200320053602200c1e0b200141066a410029008aef4537000020014100290084ef45370000200041086a428e808080e00137020020002001360204200041013602000c290b200341d0006a200341206a200541046a28020028020810e304024020032802504101470d00200041013602002000200c2902003702042000410c6a200c41086a2802003602000c290b2003280254280204210d2005280204220628020441027421052006280200210602400340024020050d00200341d0006a200341206a200d10e4042003280250450d0220002003290350370204200041013602002000410c6a200341d8006a2802003602000c2b0b200341d0006a200341206a200628020010e304024020032802504101470d00200041013602002000200c2902003702042000410c6a200c41086a2802003602000c2b0b2005417c6a2105200641046a21062003280254280204200d460d000b412710282201450d1a2001411f6a41002900b1ef45370000200141186a41002900aaef45370000200141106a41002900a2ef45370000200141086a410029009aef4537000020014100290092ef45370000200041086a42a7808080f00437020020002001360204200041013602000c290b02404100280280b1464105490d004100280284b1462105200341c10036028801200342ed8080801037038001200341fcf0c50036027c20034125360278200341d7f0c5003602742003420437026c20034201370360200341f4eec50036025c2003410a360258200341cdf0c500360254200341053602504188b1c60041b8aec600200541024622051b200341d0006a41c8b0c00041e0b0c00020051b2802101102000b024002400240200328022c2205417f6a220620054f0d00200620054d0d010b4117102822010d01411741011037000b200b28020020064104746a41013a000c0c1d0b2001410f6a41002900ebee45370000200141086a41002900e4ee45370000200141002900dcee45370000200041086a4297808080f00237020020002001360204200041013602000c280b200341d0006a200341206a200a10e40402402003280250450d0020002003290350370204200041013602002000410c6a200341d8006a2802003602000c280b02404100280280b1464105490d004100280284b1462105200341c10036028801200342ed8080801037038001200341fcf0c50036027c20034125360278200341d7f0c5003602742003420437026c20034201370360200341f4eec50036025c2003410a360258200341cdf0c500360254200341053602504188b1c60041b8aec600200541024622051b200341d0006a41c8b0c00041e0b0c00020051b2802101102000b024002400240200328022c2205417f6a220620054f0d00200620054d0d010b4117102822010d01411741011037000b200b28020020064104746a41013a000c0c1c0b2001410f6a41002900ebee45370000200141086a41002900e4ee45370000200141002900dcee45370000200041086a4297808080f00237020020002001360204200041013602000c270b200341d0006a200541046a280200200210db04024020032802504101470d00200041013602002000200c2902003702042000410c6a200c41086a2802003602000c270b200341d0006a200341206a2003280254220528020810e40402402003280250450d0020002003290350370204200041013602002000410c6a200341d8006a2802003602000c270b200320052d000d410447220536024802404100280280b1464105490d002003410136023c2003200341c8006a3602384100280284b1462105200341e30036028801200342ed8080801037038001200341fcf0c50036027c20034125360278200341d7f0c5003602742003410136027020034201370360200341fceec50036025c2003410a360258200341cdf0c500360254200341053602502003200341386a36026c4188b1c60041b8aec600200541024622051b200341d0006a41c8b0c00041e0b0c00020051b280210110200200328024821050b024002402003280220220620056a220520064f0d00410e102822010d01410e41011037000b200320053602200c1b0b200141066a410029008aef4537000020014100290084ef45370000200041086a428e808080e00137020020002001360204200041013602000c260b2003200410fa03024002402003280204200541046a28020022054d0d002003280200220620054104746a220d0d010b410e10282201450d18200141066a41002900bfef45370000200141002900b9ef45370000200041086a428e808080e00137020020002001360204200041013602000c260b200341d0006a200341206a200620054104746a28020810e40402402003280250450d0020002003290350370204200041013602002000410c6a200341d8006a2802003602000c260b2003200d2d000d410447220536024802404100280280b1464105490d002003410136023c2003200341c8006a3602384100280284b1462105200341e30036028801200342ed8080801037038001200341fcf0c50036027c20034125360278200341d7f0c5003602742003410136027020034201370360200341fceec50036025c2003410a360258200341cdf0c500360254200341053602502003200341386a36026c4188b1c60041b8aec600200541024622051b200341d0006a41c8b0c00041e0b0c00020051b280210110200200328024821050b024002402003280220220620056a220520064f0d00410e102822010d01410e41011037000b200320053602200c1a0b200141066a410029008aef4537000020014100290084ef45370000200041086a428e808080e00137020020002001360204200041013602000c250b200341d0006a200341206a410110e4042003280250450d1820002003290350370204200041013602002000410c6a200341d8006a2802003602000c240b200341d0006a200341206a410210e40402402003280250450d0020002003290350370204200041013602002000410c6a200341d8006a2802003602000c240b41012105200341d0006a200341206a410110e40402402003280250450d0020002003290350370204200041013602002000410c6a200341d8006a2802003602000c240b2003410136024802404100280280b1464105490d002003410136023c2003200341c8006a3602384100280284b1462105200341e30036028801200342ed8080801037038001200341fcf0c50036027c20034125360278200341d7f0c5003602742003410136027020034201370360200341fceec50036025c2003410a360258200341cdf0c500360254200341053602502003200341386a36026c4188b1c60041b8aec600200541024622051b200341d0006a41c8b0c00041e0b0c00020051b280210110200200328024821050b024002402003280220220620056a220520064f0d00410e102822010d01410e41011037000b200320053602200c180b200141066a410029008aef4537000020014100290084ef45370000200041086a428e808080e00137020020002001360204200041013602000c230b410121052003410136024802404100280280b1464105490d002003410136023c2003200341c8006a3602384100280284b1462105200341e30036028801200342ed8080801037038001200341fcf0c50036027c20034125360278200341d7f0c5003602742003410136027020034201370360200341fceec50036025c2003410a360258200341cdf0c500360254200341053602502003200341386a36026c4188b1c60041b8aec600200541024622051b200341d0006a41c8b0c00041e0b0c00020051b280210110200200328024821050b024002402003280220220620056a220520064f0d00410e102822010d01410e41011037000b200320053602200c170b200141066a410029008aef4537000020014100290084ef45370000200041086a428e808080e00137020020002001360204200041013602000c220b200341d0006a200341206a410110e4042003280250450d1520002003290350370204200041013602002000410c6a200341d8006a2802003602000c210b41012105200341d0006a200341206a410110e40402402003280250450d0020002003290350370204200041013602002000410c6a200341d8006a2802003602000c210b2003410136024802404100280280b1464105490d002003410136023c2003200341c8006a3602384100280284b1462105200341e30036028801200342ed8080801037038001200341fcf0c50036027c20034125360278200341d7f0c5003602742003410136027020034201370360200341fceec50036025c2003410a360258200341cdf0c500360254200341053602502003200341386a36026c4188b1c60041b8aec600200541024622051b200341d0006a41c8b0c00041e0b0c00020051b280210110200200328024821050b024002402003280220220620056a220520064f0d00410e102822010d01410e41011037000b200320053602200c150b200141066a410029008aef4537000020014100290084ef45370000200041086a428e808080e00137020020002001360204200041013602000c200b410121052003410136024802404100280280b1464105490d002003410136023c2003200341c8006a3602384100280284b1462105200341e30036028801200342ed8080801037038001200341fcf0c50036027c20034125360278200341d7f0c5003602742003410136027020034201370360200341fceec50036025c2003410a360258200341cdf0c500360254200341053602502003200341386a36026c4188b1c60041b8aec600200541024622051b200341d0006a41c8b0c00041e0b0c00020051b280210110200200328024821050b024002402003280220220620056a220520064f0d00410e102822010d01410e41011037000b200320053602200c140b200141066a410029008aef4537000020014100290084ef45370000200041086a428e808080e00137020020002001360204200041013602000c1f0b200341d0006a200341206a410110e4042003280250450d1220002003290350370204200041013602002000410c6a200341d8006a2802003602000c1e0b41012105200341d0006a200341206a410110e40402402003280250450d0020002003290350370204200041013602002000410c6a200341d8006a2802003602000c1e0b2003410136024802404100280280b1464105490d002003410136023c2003200341c8006a3602384100280284b1462105200341e30036028801200342ed8080801037038001200341fcf0c50036027c20034125360278200341d7f0c5003602742003410136027020034201370360200341fceec50036025c2003410a360258200341cdf0c500360254200341053602502003200341386a36026c4188b1c60041b8aec600200541024622051b200341d0006a41c8b0c00041e0b0c00020051b280210110200200328024821050b024002402003280220220620056a220520064f0d00410e102822010d01410e41011037000b200320053602200c120b200141066a410029008aef4537000020014100290084ef45370000200041086a428e808080e00137020020002001360204200041013602000c1d0b200341d0006a200341206a410210e4042003280250450d1020002003290350370204200041013602002000410c6a200341d8006a2802003602000c1c0b410121052003410136024802404100280280b1464105490d002003410136023c2003200341c8006a3602384100280284b1462105200341e30036028801200342ed8080801037038001200341fcf0c50036027c20034125360278200341d7f0c5003602742003410136027020034201370360200341fceec50036025c2003410a360258200341cdf0c500360254200341053602502003200341386a36026c4188b1c60041b8aec600200541024622051b200341d0006a41c8b0c00041e0b0c00020051b280210110200200328024821050b024002402003280220220620056a220520064f0d00410e102822010d01410e41011037000b200320053602200c100b200141066a410029008aef4537000020014100290084ef45370000200041086a428e808080e00137020020002001360204200041013602000c1b0b41012105200341d0006a200341206a410110e40402402003280250450d0020002003290350370204200041013602002000410c6a200341d8006a2802003602000c1b0b2003410136024802404100280280b1464105490d002003410136023c2003200341c8006a3602384100280284b1462105200341e30036028801200342ed8080801037038001200341fcf0c50036027c20034125360278200341d7f0c5003602742003410136027020034201370360200341fceec50036025c2003410a360258200341cdf0c500360254200341053602502003200341386a36026c4188b1c60041b8aec600200541024622051b200341d0006a41c8b0c00041e0b0c00020051b280210110200200328024821050b024002402003280220220620056a220520064f0d00410e102822010d01410e41011037000b200320053602200c0f0b200141066a410029008aef4537000020014100290084ef45370000200041086a428e808080e00137020020002001360204200041013602000c1a0b410121052003410136024802404100280280b1464105490d002003410136023c2003200341c8006a3602384100280284b1462105200341e30036028801200342ed8080801037038001200341fcf0c50036027c20034125360278200341d7f0c5003602742003410136027020034201370360200341fceec50036025c2003410a360258200341cdf0c500360254200341053602502003200341386a36026c4188b1c60041b8aec600200541024622051b200341d0006a41c8b0c00041e0b0c00020051b280210110200200328024821050b024002402003280220220620056a220520064f0d00410e102822010d01410e41011037000b200320053602200c0e0b200141066a410029008aef4537000020014100290084ef45370000200041086a428e808080e00137020020002001360204200041013602000c190b41012105200341d0006a200341206a410110e40402402003280250450d0020002003290350370204200041013602002000410c6a200341d8006a2802003602000c190b2003410136024802404100280280b1464105490d002003410136023c2003200341c8006a3602384100280284b1462105200341e30036028801200342ed8080801037038001200341fcf0c50036027c20034125360278200341d7f0c5003602742003410136027020034201370360200341fceec50036025c2003410a360258200341cdf0c500360254200341053602502003200341386a36026c4188b1c60041b8aec600200541024622051b200341d0006a41c8b0c00041e0b0c00020051b280210110200200328024821050b024002402003280220220620056a220520064f0d00410e102822010d01410e41011037000b200320053602200c0d0b200141066a410029008aef4537000020014100290084ef45370000200041086a428e808080e00137020020002001360204200041013602000c180b200341d0006a200341206a410210e40402402003280250450d0020002003290350370204200041013602002000410c6a200341d8006a2802003602000c180b410121052003410136024802404100280280b1464105490d002003410136023c2003200341c8006a3602384100280284b1462105200341e30036028801200342ed8080801037038001200341fcf0c50036027c20034125360278200341d7f0c5003602742003410136027020034201370360200341fceec50036025c2003410a360258200341cdf0c500360254200341053602502003200341386a36026c4188b1c60041b8aec600200541024622051b200341d0006a41c8b0c00041e0b0c00020051b280210110200200328024821050b024002402003280220220620056a220520064f0d00410e102822010d01410e41011037000b200320053602200c0c0b200141066a410029008aef4537000020014100290084ef45370000200041086a428e808080e00137020020002001360204200041013602000c170b41012105200341d0006a200341206a410110e40402402003280250450d0020002003290350370204200041013602002000410c6a200341d8006a2802003602000c170b2003410136024802404100280280b1464105490d002003410136023c2003200341c8006a3602384100280284b1462105200341e30036028801200342ed8080801037038001200341fcf0c50036027c20034125360278200341d7f0c5003602742003410136027020034201370360200341fceec50036025c2003410a360258200341cdf0c500360254200341053602502003200341386a36026c4188b1c60041b8aec600200541024622051b200341d0006a41c8b0c00041e0b0c00020051b280210110200200328024821050b024002402003280220220620056a220520064f0d00410e102822010d01410e41011037000b200320053602200c0b0b200141066a410029008aef4537000020014100290084ef45370000200041086a428e808080e00137020020002001360204200041013602000c160b200341d0006a200341206a410210e40402402003280250450d0020002003290350370204200041013602002000410c6a200341d8006a2802003602000c160b410121052003410136024802404100280280b1464105490d002003410136023c2003200341c8006a3602384100280284b1462105200341e30036028801200342ed8080801037038001200341fcf0c50036027c20034125360278200341d7f0c5003602742003410136027020034201370360200341fceec50036025c2003410a360258200341cdf0c500360254200341053602502003200341386a36026c4188b1c60041b8aec600200541024622051b200341d0006a41c8b0c00041e0b0c00020051b280210110200200328024821050b024002402003280220220620056a220520064f0d00410e102822010d01410e41011037000b200320053602200c0a0b200141066a410029008aef4537000020014100290084ef45370000200041086a428e808080e00137020020002001360204200041013602000c150b41012105200341d0006a200341206a410110e40402402003280250450d0020002003290350370204200041013602002000410c6a200341d8006a2802003602000c150b2003410136024802404100280280b1464105490d002003410136023c2003200341c8006a3602384100280284b1462105200341e30036028801200342ed8080801037038001200341fcf0c50036027c20034125360278200341d7f0c5003602742003410136027020034201370360200341fceec50036025c2003410a360258200341cdf0c500360254200341053602502003200341386a36026c4188b1c60041b8aec600200541024622051b200341d0006a41c8b0c00041e0b0c00020051b280210110200200328024821050b024002402003280220220620056a220520064f0d00410e102822010d01410e41011037000b200320053602200c090b200141066a410029008aef4537000020014100290084ef45370000200041086a428e808080e00137020020002001360204200041013602000c140b200b28020020064104746a41013a000c0c070b2005280200210620032005280208220536023802404100280280b1464105490d002003410136024c2003200341386a3602484100280284b1462105200341db0036028801200342ed8080801037038001200341fcf0c50036027c20034125360278200341d7f0c5003602742003410136027020034201370360200341c8efc50036025c2003410a360258200341cdf0c500360254200341053602502003200341c8006a36026c4188b1c60041b8aec600200541024622051b200341d0006a41c8b0c00041e0b0c00020051b280210110200200328023821050b200320053602202003200636024802404100280280b1464105490d002003410136023c2003200341c8006a3602384100280284b1462105200341e30036028801200342ed8080801037038001200341fcf0c50036027c20034125360278200341d7f0c5003602742003410136027020034201370360200341fceec50036025c2003410a360258200341cdf0c500360254200341053602502003200341386a36026c4188b1c60041b8aec600200541024622051b200341d0006a41c8b0c00041e0b0c00020051b28021011020020032802202105200328024821060b0240200520066a220620054f0d00410e102822010d11410e41011037000b200320063602200c060b41d0efc500200120051034000b200e41041037000b411741011037000b412741011037000b410e41011037000b411741011037000b200141016a22012008280200490d000c0a0b0b1031000b200641041037000b412741011037000b412541011037000b412541011037000b410f41011037000b410f41011037000b411341011037000b200141066a410029008aef4537000020014100290084ef45370000200041086a428e808080e00137020020002001360204200041013602000c010b20004100360200200020073602042003280228450d01200b280200102a0c010b2003280228450d00200b280200102a0b20034190016a24000bf50202057f017e02400240024020014108490d00200141017641feffffff07712202417f6a220320014f0d022001410d74200173220441117620047322044105742004732205417f2001417f6a677622067122044100200120042001491b6b220420014f0d01200020034103746a220329020021072003200020044103746a220429020037020020042007370200024020022001490d00200221030c030b2005410d7420057322044111762004732204410574200473220520067122044100200120042001491b6b220420014f0d01200020024103746a220329020021072003200020044103746a2204290200370200200420073702002002410172220320014f0d022005410d742005732204411176200473220441057420047320067122044100200120042001491b6b220420014f0d01200020034103746a220129020021072001200020044103746a2200290200370200200020073702000b0f0b41a8e9c500200420011034000b4198e9c500200320011034000bd50302047f017e024020014101762202450d0003402002417f6a2202210302400240024003402003410174220441017221050240200441026a220420014f0d00200520014f0d0220042005200020054103746a280200200020044103746a280200491b21050b200520014f0d03200320014f0d02200020034103746a2203280200200020054103746a22042802004f0d03200329020021062003200429020037020020042006370200200521030c000b0b41e8eac500200520011034000b41f8eac500200320011034000b20020d000b0b0240024020014102490d002001210403402004417f6a220420014f0d02200029020021062000200020044103746a2205290200370200200520063702004100210302400240024003402003410174220241017221050240200241026a220220044f0d00200520044f0d0220022005200020054103746a280200200020024103746a280200491b21050b200520044f0d03200320044f0d02200020034103746a2203280200200020054103746a22022802004f0d03200329020021062003200229020037020020022006370200200521030c000b0b41e8eac500200520041034000b41f8eac500200320041034000b200441014b0d000b0b0f0b41a8e9c500200420011034000bea04050a7f017e017f017e027f200041686a21022001417f6a2103200041086a2104410021052001413249210641012107024003400240024020072001490d00410021080c010b410121082000200741037422096a220a280200220b200a41786a280200490d00200420096a210803404101210a20032007460d03200741016a21072008280200220a200b4f2109200841086a2108200a210b20090d000b200720014921080b2007200146210a20060d0120072001460d010240024002400240024002402007417f6a220b20014f0d002008450d012000200b4103746a220b290200210c200b20002007410374220d6a2208290200220e3702002008200c37020020074102490d0520002007417e6a220a4103746a220f280200200ea722094d0d05200b200f290200370200200a450d0420002007417d6a220a4103746a28020020094d0d042002200d6a210b0340200b41086a200b290200370200200a450d03200a417f6a210a200b41786a220b28020020094b0d000b200a41016a210b0c030b4198e9c500200b20011034000b41a8e9c500200720011034000b4100210b0b2000200b4103746a210f0b200f200e3702000b200541016a21050240200120076b220a4102490d00200828020820082802004f0d002008290200210c20082008290208370200200841086a210f0240200a4103490d002008280210200ca722104f0d00200841106a21094103210b4102210d0340200d41037420086a220f41786a2009290200370200200b200a4f0d01200b4103742109200b210d200b41016a210b200820096a22092802002010490d000b0b200f200c3702000b20054105470d000b4100210a0b200a0bcc0201027f230041106b2202240020002802002802002100200128021841ebecc50041052001411c6a28020028020c1100002103200241003a0005200220033a00042002200136020020022000410c6a36020c200241f0ecc500410e2002410c6a4180edc500105c21012002200036020c20014190edc50041092002410c6a419cedc500105c21012002200041046a36020c200141acedc500410c2002410c6a419cedc500105c21012002200041086a36020c200141b8edc500410c2002410c6a419cedc500105c1a20022d00042100024020022d0005450d00200041ff0171210141012100024020010d0020022802002200411c6a28020028020c210120002802182103024020002d00004104710d00200341eeafc0004102200111000021000c010b200341f0afc0004101200111000021000b200220003a00040b200241106a2400200041ff01714100470bc20201027f230041106b22022400200128021841ebecc50041052001411c6a28020028020c1100002103200241003a0005200220033a00042002200136020020022000410c6a36020c200241f0ecc500410e2002410c6a4180edc500105c21012002200036020c20014190edc50041092002410c6a419cedc500105c21012002200041046a36020c200141acedc500410c2002410c6a419cedc500105c21012002200041086a36020c200141b8edc500410c2002410c6a419cedc500105c1a20022d00042100024020022d0005450d00200041ff0171210141012100024020010d0020022802002200411c6a28020028020c210120002802182103024020002d00004104710d00200341eeafc0004102200111000021000c010b200341f0afc0004101200111000021000b200220003a00040b200241106a2400200041ff01714100470b9b0201027f024002400240024002402001410c6a2802002203417f6a220420034d0d00411610282201450d01200020013602042001410e6a41002900ddf245370000200141086a41002900d7f245370000200141002900cff245370000200041086a4296808080e0023702000c040b0240200420026b220220044d0d00411b10282201450d0220002001360204200141176a41002800fcf245360000200141106a41002900f5f245370000200141086a41002900edf245370000200141002900e5f245370000200041086a429b808080b0033702000c040b200320024d0d022000200128020420024104746a360204200041003602000f0b411641011037000b411b41011037000b4180f3c500200220031034000b200041013602000bc50401027f230041d0006b220324002003200236020402404100280280b1464105490d002003410136020c2003200341046a3602084100280284b1462102200341c8006a41ef00360200200341c0006a42ed80808010370300200341386a4125360200200341306a4101360200200341206a4201370300200341186a410a360200200341fcf0c50036023c200341d7f0c5003602342003412c6a200341086a360200200341f8f1c50036021c200341cdf0c500360214200341053602104188b1c60041b8aec600200241024622021b200341106a41c8b0c00041e0b0c00020021b280210110200200328020421020b0240024002402002450d00200341106a2001410010e30420032802104101470d012000200341106a4104722202290200370200200041086a200241086a2802003602000c020b200041003602000c010b02400240024002402001280200220220032802142204280208460d00200220032802046b220420024d0d02410f102822020d01410f41011037000b024020042d000c0d00412510282202450d03200042a5808080d004370204200020023602002002411d6a410029009df245370000200241186a4100290098f245370000200241106a4100290090f245370000200241086a4100290088f24537000020024100290080f2453700000c040b200041003602000c030b2000428f808080f00137020420002002360200200241076a41002900acf245370000200241002900a5f2453700000c020b20004100360200200120043602000c010b412541011037000b200341d0006a24000bac0301047f230041c0006b2202240020002802002100410121030240200128021841baaec000410c2001411c6a28020028020c1100000d0002400240200028020822030d0020002802002203200028020428020c11070042e4aec285979ba58811520d012002200336020c2002412b36021420022002410c6a36021020012802182104200128021c2105410121032002413c6a41013602002002420237022c200241c8aec0003602282002200241106a36023820042005200241286a10350d020c010b2002200336020c2002412f36021420022002410c6a36021020012802182104200128021c2105410121032002413c6a41013602002002420237022c200241c8aec0003602282002200241106a36023820042005200241286a10350d010b200241106a41146a4101360200200241106a410c6a4101360200200241043602142002200041186a3602202002200041146a36021820022000410c6a36021020012802182100200128021c2101200241286a41146a41033602002002420337022c200241d8aec0003602282002200241106a36023820002001200241286a103521030b200241c0006a240020030b1500200120002802002200280200200028020410450b080020002001100b0bbe04020d7f017e230041c0006b22032400200128020022042001280208220541047422066a210720012802042108200421010240024002402005450d00200641706a2109200341306a410172210a200341306a41026a2106200341206a410172220b41076a210c20042101034020012d000021052006200141036a2d00003a00002003200141016a2f00003b01300240200541ac01470d00200141106a21010c020b2003410c6a41026a20062d0000220d3a0000200320032f0130220e3b010c200141046a280200210f200141086a2903002110200a200e3b0000200a41026a200d3a0000200320053a0030200320103703382003200f360234200341206a200341306a200210e9042003200b2900003703102003200c290000370017024020032d00202205411f470d00200941706a2109200141106a22012007470d010c030b0b200020053a000020002003290310370001200041086a200329001737000002402009450d00200141106a210103400240024020012d000022054109460d00200541ac01470d010c030b0240200141046a280200220528020441ffffffff0371450d002005280200102a0b2005102a0b200141106a22012007470d000b0b2008450d022004102a0c020b20012007460d0003400240024020012d000022054109460d00200541ac01470d010c030b0240200141046a280200220528020441ffffffff0371450d002005280200102a0b2005102a0b200141106a22012007470d000b0b02402008450d002004102a0b2000411f3a00000b200341c0006a24000bcbd60202097f017e230041106b22032400024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024020012d00000eac01000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f80018101820183018401850186018701880189018a018b018c018d018e018f0190019101920193019401950196019701980199019a019b019c019d019e019f01a001a101a201a301a401a501a601a701a801a901aa01ab01000b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490df701200441017422062005200620054b1b22064100480df7010240024020040d002006102821050c010b200228020420042006102c21050b2005450dad0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41003a00000cab010b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490df601200441017422062005200620054b1b22064100480df6010240024020040d002006102821050c010b200228020420042006102c21050b2005450dad0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41013a00000caa010b200241046a210620012d0001210702400240200241086a2802002002410c6a2802002204460d00200628020021050c010b200441016a22052004490df501200441017422082005200820054b1b22084100480df5010240024020040d002008102821050c010b200628020020042008102c21050b2005450dad0120022005360204200241086a20083602002002410c6a28020021040b2002410c6a2208200441016a360200200520046a41023a000002400240200241086a28020020082802002204460d00200628020021050c010b200441016a22052004490df501200441017422082005200820054b1b22084100480df5010240024020040d002008102821050c010b200628020020042008102c21050b2005450dae0120022005360204200241086a20083602002002410c6a28020021040b2002410c6a200441016a360200200520046a42c0818386fcdffffe7c2007410473ad42078342038688a7413f7141c000723a00000ca9010b200241046a210620012d0001210702400240200241086a2802002002410c6a2802002204460d00200628020021050c010b200441016a22052004490df401200441017422082005200820054b1b22084100480df4010240024020040d002008102821050c010b200628020020042008102c21050b2005450dae0120022005360204200241086a20083602002002410c6a28020021040b2002410c6a2208200441016a360200200520046a41033a000002400240200241086a28020020082802002204460d00200628020021050c010b200441016a22052004490df401200441017422082005200820054b1b22084100480df4010240024020040d002008102821050c010b200628020020042008102c21050b2005450daf0120022005360204200241086a20083602002002410c6a28020021040b2002410c6a200441016a360200200520046a42c0818386fcdffffe7c2007410473ad42078342038688a7413f7141c000723a00000ca8010b200241046a210620012d0001210702400240200241086a2802002002410c6a2802002204460d00200628020021050c010b200441016a22052004490df301200441017422082005200820054b1b22084100480df3010240024020040d002008102821050c010b200628020020042008102c21050b2005450daf0120022005360204200241086a20083602002002410c6a28020021040b2002410c6a2208200441016a360200200520046a41043a000002400240200241086a28020020082802002204460d00200628020021050c010b200441016a22052004490df301200441017422082005200820054b1b22084100480df3010240024020040d002008102821050c010b200628020020042008102c21050b2005450db00120022005360204200241086a20083602002002410c6a28020021040b2002410c6a200441016a360200200520046a42c0818386fcdffffe7c2007410473ad42078342038688a7413f7141c000723a00000ca7010b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490df201200441017422062005200620054b1b22064100480df2010240024020040d002006102821050c010b200228020420042006102c21050b2005450db00120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41053a00000ca6010b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490df101200441017422062005200620054b1b22064100480df1010240024020040d002006102821050c010b200228020420042006102c21050b2005450db00120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a410b3a00000ca5010b200241046a2109200141046a280200210502400240200241086a2802002002410c6a2802002204460d00200928020021060c010b200441016a22062004490df001200441017422072006200720064b1b22074100480df0010240024020040d002007102821060c010b200928020020042007102c21060b2006450db00120022006360204200241086a20073602002002410c6a28020021040b2002410c6a2207200441016a360200200620046a410c3a0000200241086a2108034002400240200828020020072802002204460d00200928020021060c010b200441016a22062004490df1012004410174220a2006200a20064b1b220a4100480df1010240024020040d00200a102821060c010b20092802002004200a102c21060b2006450db201200220063602042008200a360200200728020021040b2007200441016a360200200620046a200541807f72200541ff0071200541077622041b3a00002004210520040d000ca5010b0b200241046a2109200141046a280200210502400240200241086a2802002002410c6a2802002204460d00200928020021060c010b200441016a22062004490def01200441017422072006200720064b1b22074100480def010240024020040d002007102821060c010b200928020020042007102c21060b2006450db10120022006360204200241086a20073602002002410c6a28020021040b2002410c6a2207200441016a360200200620046a410d3a0000200241086a2108034002400240200828020020072802002204460d00200928020021060c010b200441016a22062004490df0012004410174220a2006200a20064b1b220a4100480df0010240024020040d00200a102821060c010b20092802002004200a102c21060b2006450db301200220063602042008200a360200200728020021040b2007200441016a360200200620046a200541807f72200541ff0071200541077622041b3a00002004210520040d000ca4010b0b200241046a210902400240200241086a2802002002410c6a2802002204460d00200928020021050c010b200441016a22052004490dee01200441017422062005200620054b1b22064100480dee010240024020040d002006102821050c010b200928020020042006102c21050b2005450db20120022005360204200241086a20063602002002410c6a28020021040b2002410c6a2207200441016a360200200520046a410e3a0000200320012802042204280204220520042802002204200420054102746a200210ea042003210420032d0000411f470d930320012802042802082105200241086a2108034002400240200828020020072802002204460d00200928020021060c010b200441016a22062004490def012004410174220a2006200a20064b1b220a4100480def010240024020040d00200a102821060c010b20092802002004200a102c21060b2006450db401200220063602042008200a360200200728020021040b2007200441016a360200200620046a200541807f72200541ff0071200541077622041b3a00002004210520040d000ca3010b0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490ded01200441017422062005200620054b1b22064100480ded010240024020040d002006102821050c010b200228020420042006102c21050b2005450db30120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a410f3a00000ca1010b200241046a2109200141046a280200210502400240200241086a2802002002410c6a2802002204460d00200928020021060c010b200441016a22062004490dec01200441017422072006200720064b1b22074100480dec010240024020040d002007102821060c010b200928020020042007102c21060b2006450db30120022006360204200241086a20073602002002410c6a28020021040b2002410c6a2207200441016a360200200620046a41103a0000200241086a2108034002400240200828020020072802002204460d00200928020021060c010b200441016a22062004490ded012004410174220a2006200a20064b1b220a4100480ded010240024020040d00200a102821060c010b20092802002004200a102c21060b2006450db501200220063602042008200a360200200728020021040b2007200441016a360200200620046a200541807f72200541ff0071200541077622041b3a00002004210520040d000ca1010b0b200241046a2109200141046a280200210520012d0001210b02400240200241086a2802002002410c6a2802002204460d00200928020021060c010b200441016a22062004490deb01200441017422072006200720064b1b22074100480deb010240024020040d002007102821060c010b200928020020042007102c21060b2006450db40120022006360204200241086a20073602002002410c6a28020021040b2002410c6a2207200441016a360200200620046a41113a0000200241086a2108034002400240200828020020072802002204460d00200928020021060c010b200441016a22062004490dec012004410174220a2006200a20064b1b220a4100480dec010240024020040d00200a102821060c010b20092802002004200a102c21060b2006450db601200220063602042008200a360200200728020021040b2007200441016a360200200620046a200541807f72200541ff0071200541077622041b3a00002004210520040d000b02400240200241086a2802002002410c6a2802002204460d00200928020021050c010b200441016a22052004490deb01200441017422062005200620054b1b22064100480deb010240024020040d002006102821050c010b200928020020042006102c21050b2005450db60120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a200b3a00000c9f010b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490dea01200441017422062005200620054b1b22064100480dea010240024020040d002006102821050c010b200228020420042006102c21050b2005450db60120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a411a3a00000c9e010b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490de901200441017422062005200620054b1b22064100480de9010240024020040d002006102821050c010b200228020420042006102c21050b2005450db60120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a411b3a00000c9d010b200241046a2109200141046a280200210502400240200241086a2802002002410c6a2802002204460d00200928020021060c010b200441016a22062004490de801200441017422072006200720064b1b22074100480de8010240024020040d002007102821060c010b200928020020042007102c21060b2006450db60120022006360204200241086a20073602002002410c6a28020021040b2002410c6a2207200441016a360200200620046a41203a0000200241086a2108034002400240200828020020072802002204460d00200928020021060c010b200441016a22062004490de9012004410174220a2006200a20064b1b220a4100480de9010240024020040d00200a102821060c010b20092802002004200a102c21060b2006450db801200220063602042008200a360200200728020021040b2007200441016a360200200620046a200541807f72200541ff0071200541077622041b3a00002004210520040d000c9d010b0b200241046a2109200141046a280200210502400240200241086a2802002002410c6a2802002204460d00200928020021060c010b200441016a22062004490de701200441017422072006200720064b1b22074100480de7010240024020040d002007102821060c010b200928020020042007102c21060b2006450db70120022006360204200241086a20073602002002410c6a28020021040b2002410c6a2207200441016a360200200620046a41213a0000200241086a2108034002400240200828020020072802002204460d00200928020021060c010b200441016a22062004490de8012004410174220a2006200a20064b1b220a4100480de8010240024020040d00200a102821060c010b20092802002004200a102c21060b2006450db901200220063602042008200a360200200728020021040b2007200441016a360200200620046a200541807f72200541ff0071200541077622041b3a00002004210520040d000c9c010b0b200241046a2109200141046a280200210502400240200241086a2802002002410c6a2802002204460d00200928020021060c010b200441016a22062004490de601200441017422072006200720064b1b22074100480de6010240024020040d002007102821060c010b200928020020042007102c21060b2006450db80120022006360204200241086a20073602002002410c6a28020021040b2002410c6a2207200441016a360200200620046a41223a0000200241086a2108034002400240200828020020072802002204460d00200928020021060c010b200441016a22062004490de7012004410174220a2006200a20064b1b220a4100480de7010240024020040d00200a102821060c010b20092802002004200a102c21060b2006450dba01200220063602042008200a360200200728020021040b2007200441016a360200200620046a200541807f72200541ff0071200541077622041b3a00002004210520040d000c9b010b0b200241046a2109200141046a280200210502400240200241086a2802002002410c6a2802002204460d00200928020021060c010b200441016a22062004490de501200441017422072006200720064b1b22074100480de5010240024020040d002007102821060c010b200928020020042007102c21060b2006450db90120022006360204200241086a20073602002002410c6a28020021040b2002410c6a2207200441016a360200200620046a41233a0000200241086a2108034002400240200828020020072802002204460d00200928020021060c010b200441016a22062004490de6012004410174220a2006200a20064b1b220a4100480de6010240024020040d00200a102821060c010b20092802002004200a102c21060b2006450dbb01200220063602042008200a360200200728020021040b2007200441016a360200200620046a200541807f72200541ff0071200541077622041b3a00002004210520040d000c9a010b0b200241046a2109200141046a280200210502400240200241086a2802002002410c6a2802002204460d00200928020021060c010b200441016a22062004490de401200441017422072006200720064b1b22074100480de4010240024020040d002007102821060c010b200928020020042007102c21060b2006450dba0120022006360204200241086a20073602002002410c6a28020021040b2002410c6a2207200441016a360200200620046a41243a0000200241086a2108034002400240200828020020072802002204460d00200928020021060c010b200441016a22062004490de5012004410174220a2006200a20064b1b220a4100480de5010240024020040d00200a102821060c010b20092802002004200a102c21060b2006450dbc01200220063602042008200a360200200728020021040b2007200441016a360200200620046a200541807f72200541ff0071200541077622041b3a00002004210520040d000c99010b0b200241046a210a200141086a2802002105200141046a280200210602400240200241086a2802002002410c6a2802002204460d00200a28020021070c010b200441016a22072004490de301200441017422082007200820074b1b22084100480de3010240024020040d002008102821070c010b200a28020020042008102c21070b2007450dbb0120022007360204200241086a20083602002002410c6a28020021040b2002410c6a2208200441016a360200200720046a41283a0000200241086a2109034002400240200928020020082802002204460d00200a28020021070c010b200441016a22072004490de4012004410174220b2007200b20074b1b220b4100480de4010240024020040d00200b102821070c010b200a2802002004200b102c21070b2007450dbd01200220073602042009200b360200200828020021040b2008200441016a360200200720046a200641807f72200641ff0071200641077622041b3a00002004210620040d000b2002410c6a2107200241086a2108034002400240200828020020072802002204460d00200a28020021060c010b200441016a22062004490de401200441017422092006200920064b1b22094100480de4010240024020040d002009102821060c010b200a28020020042009102c21060b2006450dbe012002200636020420082009360200200728020021040b2007200441016a360200200620046a200541807f72200541ff0071200541077622041b3a00002004210520040d000c98010b0b200241046a210a200141086a2802002105200141046a280200210602400240200241086a2802002002410c6a2802002204460d00200a28020021070c010b200441016a22072004490de201200441017422082007200820074b1b22084100480de2010240024020040d002008102821070c010b200a28020020042008102c21070b2007450dbd0120022007360204200241086a20083602002002410c6a28020021040b2002410c6a2208200441016a360200200720046a41293a0000200241086a2109034002400240200928020020082802002204460d00200a28020021070c010b200441016a22072004490de3012004410174220b2007200b20074b1b220b4100480de3010240024020040d00200b102821070c010b200a2802002004200b102c21070b2007450dbf01200220073602042009200b360200200828020021040b2008200441016a360200200720046a200641807f72200641ff0071200641077622041b3a00002004210620040d000b2002410c6a2107200241086a2108034002400240200828020020072802002204460d00200a28020021060c010b200441016a22062004490de301200441017422092006200920064b1b22094100480de3010240024020040d002009102821060c010b200a28020020042009102c21060b2006450dc0012002200636020420082009360200200728020021040b2007200441016a360200200620046a200541807f72200541ff0071200541077622041b3a00002004210520040d000c97010b0b200241046a210a200141086a2802002105200141046a280200210602400240200241086a2802002002410c6a2802002204460d00200a28020021070c010b200441016a22072004490de101200441017422082007200820074b1b22084100480de1010240024020040d002008102821070c010b200a28020020042008102c21070b2007450dbf0120022007360204200241086a20083602002002410c6a28020021040b2002410c6a2208200441016a360200200720046a412a3a0000200241086a2109034002400240200928020020082802002204460d00200a28020021070c010b200441016a22072004490de2012004410174220b2007200b20074b1b220b4100480de2010240024020040d00200b102821070c010b200a2802002004200b102c21070b2007450dc101200220073602042009200b360200200828020021040b2008200441016a360200200720046a200641807f72200641ff0071200641077622041b3a00002004210620040d000b2002410c6a2107200241086a2108034002400240200828020020072802002204460d00200a28020021060c010b200441016a22062004490de201200441017422092006200920064b1b22094100480de2010240024020040d002009102821060c010b200a28020020042009102c21060b2006450dc2012002200636020420082009360200200728020021040b2007200441016a360200200620046a200541807f72200541ff0071200541077622041b3a00002004210520040d000c96010b0b200241046a210a200141086a2802002105200141046a280200210602400240200241086a2802002002410c6a2802002204460d00200a28020021070c010b200441016a22072004490de001200441017422082007200820074b1b22084100480de0010240024020040d002008102821070c010b200a28020020042008102c21070b2007450dc10120022007360204200241086a20083602002002410c6a28020021040b2002410c6a2208200441016a360200200720046a412b3a0000200241086a2109034002400240200928020020082802002204460d00200a28020021070c010b200441016a22072004490de1012004410174220b2007200b20074b1b220b4100480de1010240024020040d00200b102821070c010b200a2802002004200b102c21070b2007450dc301200220073602042009200b360200200828020021040b2008200441016a360200200720046a200641807f72200641ff0071200641077622041b3a00002004210620040d000b2002410c6a2107200241086a2108034002400240200828020020072802002204460d00200a28020021060c010b200441016a22062004490de101200441017422092006200920064b1b22094100480de1010240024020040d002009102821060c010b200a28020020042009102c21060b2006450dc4012002200636020420082009360200200728020021040b2007200441016a360200200620046a200541807f72200541ff0071200541077622041b3a00002004210520040d000c95010b0b200241046a210a200141086a2802002105200141046a280200210602400240200241086a2802002002410c6a2802002204460d00200a28020021070c010b200441016a22072004490ddf01200441017422082007200820074b1b22084100480ddf010240024020040d002008102821070c010b200a28020020042008102c21070b2007450dc30120022007360204200241086a20083602002002410c6a28020021040b2002410c6a2208200441016a360200200720046a412c3a0000200241086a2109034002400240200928020020082802002204460d00200a28020021070c010b200441016a22072004490de0012004410174220b2007200b20074b1b220b4100480de0010240024020040d00200b102821070c010b200a2802002004200b102c21070b2007450dc501200220073602042009200b360200200828020021040b2008200441016a360200200720046a200641807f72200641ff0071200641077622041b3a00002004210620040d000b2002410c6a2107200241086a2108034002400240200828020020072802002204460d00200a28020021060c010b200441016a22062004490de001200441017422092006200920064b1b22094100480de0010240024020040d002009102821060c010b200a28020020042009102c21060b2006450dc6012002200636020420082009360200200728020021040b2007200441016a360200200620046a200541807f72200541ff0071200541077622041b3a00002004210520040d000c94010b0b200241046a210a200141086a2802002105200141046a280200210602400240200241086a2802002002410c6a2802002204460d00200a28020021070c010b200441016a22072004490dde01200441017422082007200820074b1b22084100480dde010240024020040d002008102821070c010b200a28020020042008102c21070b2007450dc50120022007360204200241086a20083602002002410c6a28020021040b2002410c6a2208200441016a360200200720046a412d3a0000200241086a2109034002400240200928020020082802002204460d00200a28020021070c010b200441016a22072004490ddf012004410174220b2007200b20074b1b220b4100480ddf010240024020040d00200b102821070c010b200a2802002004200b102c21070b2007450dc701200220073602042009200b360200200828020021040b2008200441016a360200200720046a200641807f72200641ff0071200641077622041b3a00002004210620040d000b2002410c6a2107200241086a2108034002400240200828020020072802002204460d00200a28020021060c010b200441016a22062004490ddf01200441017422092006200920064b1b22094100480ddf010240024020040d002009102821060c010b200a28020020042009102c21060b2006450dc8012002200636020420082009360200200728020021040b2007200441016a360200200620046a200541807f72200541ff0071200541077622041b3a00002004210520040d000c93010b0b200241046a210a200141086a2802002105200141046a280200210602400240200241086a2802002002410c6a2802002204460d00200a28020021070c010b200441016a22072004490ddd01200441017422082007200820074b1b22084100480ddd010240024020040d002008102821070c010b200a28020020042008102c21070b2007450dc70120022007360204200241086a20083602002002410c6a28020021040b2002410c6a2208200441016a360200200720046a412e3a0000200241086a2109034002400240200928020020082802002204460d00200a28020021070c010b200441016a22072004490dde012004410174220b2007200b20074b1b220b4100480dde010240024020040d00200b102821070c010b200a2802002004200b102c21070b2007450dc901200220073602042009200b360200200828020021040b2008200441016a360200200720046a200641807f72200641ff0071200641077622041b3a00002004210620040d000b2002410c6a2107200241086a2108034002400240200828020020072802002204460d00200a28020021060c010b200441016a22062004490dde01200441017422092006200920064b1b22094100480dde010240024020040d002009102821060c010b200a28020020042009102c21060b2006450dca012002200636020420082009360200200728020021040b2007200441016a360200200620046a200541807f72200541ff0071200541077622041b3a00002004210520040d000c92010b0b200241046a210a200141086a2802002105200141046a280200210602400240200241086a2802002002410c6a2802002204460d00200a28020021070c010b200441016a22072004490ddc01200441017422082007200820074b1b22084100480ddc010240024020040d002008102821070c010b200a28020020042008102c21070b2007450dc90120022007360204200241086a20083602002002410c6a28020021040b2002410c6a2208200441016a360200200720046a412f3a0000200241086a2109034002400240200928020020082802002204460d00200a28020021070c010b200441016a22072004490ddd012004410174220b2007200b20074b1b220b4100480ddd010240024020040d00200b102821070c010b200a2802002004200b102c21070b2007450dcb01200220073602042009200b360200200828020021040b2008200441016a360200200720046a200641807f72200641ff0071200641077622041b3a00002004210620040d000b2002410c6a2107200241086a2108034002400240200828020020072802002204460d00200a28020021060c010b200441016a22062004490ddd01200441017422092006200920064b1b22094100480ddd010240024020040d002009102821060c010b200a28020020042009102c21060b2006450dcc012002200636020420082009360200200728020021040b2007200441016a360200200620046a200541807f72200541ff0071200541077622041b3a00002004210520040d000c91010b0b200241046a210a200141086a2802002105200141046a280200210602400240200241086a2802002002410c6a2802002204460d00200a28020021070c010b200441016a22072004490ddb01200441017422082007200820074b1b22084100480ddb010240024020040d002008102821070c010b200a28020020042008102c21070b2007450dcb0120022007360204200241086a20083602002002410c6a28020021040b2002410c6a2208200441016a360200200720046a41303a0000200241086a2109034002400240200928020020082802002204460d00200a28020021070c010b200441016a22072004490ddc012004410174220b2007200b20074b1b220b4100480ddc010240024020040d00200b102821070c010b200a2802002004200b102c21070b2007450dcd01200220073602042009200b360200200828020021040b2008200441016a360200200720046a200641807f72200641ff0071200641077622041b3a00002004210620040d000b2002410c6a2107200241086a2108034002400240200828020020072802002204460d00200a28020021060c010b200441016a22062004490ddc01200441017422092006200920064b1b22094100480ddc010240024020040d002009102821060c010b200a28020020042009102c21060b2006450dce012002200636020420082009360200200728020021040b2007200441016a360200200620046a200541807f72200541ff0071200541077622041b3a00002004210520040d000c90010b0b200241046a210a200141086a2802002105200141046a280200210602400240200241086a2802002002410c6a2802002204460d00200a28020021070c010b200441016a22072004490dda01200441017422082007200820074b1b22084100480dda010240024020040d002008102821070c010b200a28020020042008102c21070b2007450dcd0120022007360204200241086a20083602002002410c6a28020021040b2002410c6a2208200441016a360200200720046a41313a0000200241086a2109034002400240200928020020082802002204460d00200a28020021070c010b200441016a22072004490ddb012004410174220b2007200b20074b1b220b4100480ddb010240024020040d00200b102821070c010b200a2802002004200b102c21070b2007450dcf01200220073602042009200b360200200828020021040b2008200441016a360200200720046a200641807f72200641ff0071200641077622041b3a00002004210620040d000b2002410c6a2107200241086a2108034002400240200828020020072802002204460d00200a28020021060c010b200441016a22062004490ddb01200441017422092006200920064b1b22094100480ddb010240024020040d002009102821060c010b200a28020020042009102c21060b2006450dd0012002200636020420082009360200200728020021040b2007200441016a360200200620046a200541807f72200541ff0071200541077622041b3a00002004210520040d000c8f010b0b200241046a210a200141086a2802002105200141046a280200210602400240200241086a2802002002410c6a2802002204460d00200a28020021070c010b200441016a22072004490dd901200441017422082007200820074b1b22084100480dd9010240024020040d002008102821070c010b200a28020020042008102c21070b2007450dcf0120022007360204200241086a20083602002002410c6a28020021040b2002410c6a2208200441016a360200200720046a41323a0000200241086a2109034002400240200928020020082802002204460d00200a28020021070c010b200441016a22072004490dda012004410174220b2007200b20074b1b220b4100480dda010240024020040d00200b102821070c010b200a2802002004200b102c21070b2007450dd101200220073602042009200b360200200828020021040b2008200441016a360200200720046a200641807f72200641ff0071200641077622041b3a00002004210620040d000b2002410c6a2107200241086a2108034002400240200828020020072802002204460d00200a28020021060c010b200441016a22062004490dda01200441017422092006200920064b1b22094100480dda010240024020040d002009102821060c010b200a28020020042009102c21060b2006450dd2012002200636020420082009360200200728020021040b2007200441016a360200200620046a200541807f72200541ff0071200541077622041b3a00002004210520040d000c8e010b0b200241046a210a200141086a2802002105200141046a280200210602400240200241086a2802002002410c6a2802002204460d00200a28020021070c010b200441016a22072004490dd801200441017422082007200820074b1b22084100480dd8010240024020040d002008102821070c010b200a28020020042008102c21070b2007450dd10120022007360204200241086a20083602002002410c6a28020021040b2002410c6a2208200441016a360200200720046a41333a0000200241086a2109034002400240200928020020082802002204460d00200a28020021070c010b200441016a22072004490dd9012004410174220b2007200b20074b1b220b4100480dd9010240024020040d00200b102821070c010b200a2802002004200b102c21070b2007450dd301200220073602042009200b360200200828020021040b2008200441016a360200200720046a200641807f72200641ff0071200641077622041b3a00002004210620040d000b2002410c6a2107200241086a2108034002400240200828020020072802002204460d00200a28020021060c010b200441016a22062004490dd901200441017422092006200920064b1b22094100480dd9010240024020040d002009102821060c010b200a28020020042009102c21060b2006450dd4012002200636020420082009360200200728020021040b2007200441016a360200200620046a200541807f72200541ff0071200541077622041b3a00002004210520040d000c8d010b0b200241046a210a200141086a2802002105200141046a280200210602400240200241086a2802002002410c6a2802002204460d00200a28020021070c010b200441016a22072004490dd701200441017422082007200820074b1b22084100480dd7010240024020040d002008102821070c010b200a28020020042008102c21070b2007450dd30120022007360204200241086a20083602002002410c6a28020021040b2002410c6a2208200441016a360200200720046a41343a0000200241086a2109034002400240200928020020082802002204460d00200a28020021070c010b200441016a22072004490dd8012004410174220b2007200b20074b1b220b4100480dd8010240024020040d00200b102821070c010b200a2802002004200b102c21070b2007450dd501200220073602042009200b360200200828020021040b2008200441016a360200200720046a200641807f72200641ff0071200641077622041b3a00002004210620040d000b2002410c6a2107200241086a2108034002400240200828020020072802002204460d00200a28020021060c010b200441016a22062004490dd801200441017422092006200920064b1b22094100480dd8010240024020040d002009102821060c010b200a28020020042009102c21060b2006450dd6012002200636020420082009360200200728020021040b2007200441016a360200200620046a200541807f72200541ff0071200541077622041b3a00002004210520040d000c8c010b0b200241046a210a200141086a2802002105200141046a280200210602400240200241086a2802002002410c6a2802002204460d00200a28020021070c010b200441016a22072004490dd601200441017422082007200820074b1b22084100480dd6010240024020040d002008102821070c010b200a28020020042008102c21070b2007450dd50120022007360204200241086a20083602002002410c6a28020021040b2002410c6a2208200441016a360200200720046a41353a0000200241086a2109034002400240200928020020082802002204460d00200a28020021070c010b200441016a22072004490da3022004410174220b2007200b20074b1b220b4100480da3020240024020040d00200b102821070c010b200a2802002004200b102c21070b2007450dd801200220073602042009200b360200200828020021040b2008200441016a360200200720046a200641807f72200641ff0071200641077622041b3a00002004210620040d000b2002410c6a2107200241086a2108034002400240200828020020072802002204460d00200a28020021060c010b200441016a22062004490da302200441017422092006200920064b1b22094100480da3020240024020040d002009102821060c010b200a28020020042009102c21060b2006450dd9012002200636020420082009360200200728020021040b2007200441016a360200200620046a200541807f72200541ff0071200541077622041b3a00002004210520040d000c8b010b0b200241046a210a200141086a2802002105200141046a280200210602400240200241086a2802002002410c6a2802002204460d00200a28020021070c010b200441016a22072004490da102200441017422082007200820074b1b22084100480da1020240024020040d002008102821070c010b200a28020020042008102c21070b2007450dd80120022007360204200241086a20083602002002410c6a28020021040b2002410c6a2208200441016a360200200720046a41363a0000200241086a2109034002400240200928020020082802002204460d00200a28020021070c010b200441016a22072004490da2022004410174220b2007200b20074b1b220b4100480da2020240024020040d00200b102821070c010b200a2802002004200b102c21070b2007450dda01200220073602042009200b360200200828020021040b2008200441016a360200200720046a200641807f72200641ff0071200641077622041b3a00002004210620040d000b2002410c6a2107200241086a2108034002400240200828020020072802002204460d00200a28020021060c010b200441016a22062004490da202200441017422092006200920064b1b22094100480da2020240024020040d002009102821060c010b200a28020020042009102c21060b2006450ddb012002200636020420082009360200200728020021040b2007200441016a360200200620046a200541807f72200541ff0071200541077622041b3a00002004210520040d000c8a010b0b200241046a210a200141086a2802002105200141046a280200210602400240200241086a2802002002410c6a2802002204460d00200a28020021070c010b200441016a22072004490da002200441017422082007200820074b1b22084100480da0020240024020040d002008102821070c010b200a28020020042008102c21070b2007450dda0120022007360204200241086a20083602002002410c6a28020021040b2002410c6a2208200441016a360200200720046a41373a0000200241086a2109034002400240200928020020082802002204460d00200a28020021070c010b200441016a22072004490da1022004410174220b2007200b20074b1b220b4100480da1020240024020040d00200b102821070c010b200a2802002004200b102c21070b2007450ddc01200220073602042009200b360200200828020021040b2008200441016a360200200720046a200641807f72200641ff0071200641077622041b3a00002004210620040d000b2002410c6a2107200241086a2108034002400240200828020020072802002204460d00200a28020021060c010b200441016a22062004490da102200441017422092006200920064b1b22094100480da1020240024020040d002009102821060c010b200a28020020042009102c21060b2006450ddd012002200636020420082009360200200728020021040b2007200441016a360200200620046a200541807f72200541ff0071200541077622041b3a00002004210520040d000c89010b0b200241046a210a200141086a2802002105200141046a280200210602400240200241086a2802002002410c6a2802002204460d00200a28020021070c010b200441016a22072004490d9f02200441017422082007200820074b1b22084100480d9f020240024020040d002008102821070c010b200a28020020042008102c21070b2007450ddc0120022007360204200241086a20083602002002410c6a28020021040b2002410c6a2208200441016a360200200720046a41383a0000200241086a2109034002400240200928020020082802002204460d00200a28020021070c010b200441016a22072004490da0022004410174220b2007200b20074b1b220b4100480da0020240024020040d00200b102821070c010b200a2802002004200b102c21070b2007450dde01200220073602042009200b360200200828020021040b2008200441016a360200200720046a200641807f72200641ff0071200641077622041b3a00002004210620040d000b2002410c6a2107200241086a2108034002400240200828020020072802002204460d00200a28020021060c010b200441016a22062004490da002200441017422092006200920064b1b22094100480da0020240024020040d002009102821060c010b200a28020020042009102c21060b2006450ddf012002200636020420082009360200200728020021040b2007200441016a360200200620046a200541807f72200541ff0071200541077622041b3a00002004210520040d000c88010b0b200241046a210a200141086a2802002105200141046a280200210602400240200241086a2802002002410c6a2802002204460d00200a28020021070c010b200441016a22072004490d9e02200441017422082007200820074b1b22084100480d9e020240024020040d002008102821070c010b200a28020020042008102c21070b2007450dde0120022007360204200241086a20083602002002410c6a28020021040b2002410c6a2208200441016a360200200720046a41393a0000200241086a2109034002400240200928020020082802002204460d00200a28020021070c010b200441016a22072004490d9f022004410174220b2007200b20074b1b220b4100480d9f020240024020040d00200b102821070c010b200a2802002004200b102c21070b2007450de001200220073602042009200b360200200828020021040b2008200441016a360200200720046a200641807f72200641ff0071200641077622041b3a00002004210620040d000b2002410c6a2107200241086a2108034002400240200828020020072802002204460d00200a28020021060c010b200441016a22062004490d9f02200441017422092006200920064b1b22094100480d9f020240024020040d002009102821060c010b200a28020020042009102c21060b2006450de1012002200636020420082009360200200728020021040b2007200441016a360200200620046a200541807f72200541ff0071200541077622041b3a00002004210520040d000c87010b0b200241046a210a200141086a2802002105200141046a280200210602400240200241086a2802002002410c6a2802002204460d00200a28020021070c010b200441016a22072004490d9d02200441017422082007200820074b1b22084100480d9d020240024020040d002008102821070c010b200a28020020042008102c21070b2007450de00120022007360204200241086a20083602002002410c6a28020021040b2002410c6a2208200441016a360200200720046a413a3a0000200241086a2109034002400240200928020020082802002204460d00200a28020021070c010b200441016a22072004490d9e022004410174220b2007200b20074b1b220b4100480d9e020240024020040d00200b102821070c010b200a2802002004200b102c21070b2007450de201200220073602042009200b360200200828020021040b2008200441016a360200200720046a200641807f72200641ff0071200641077622041b3a00002004210620040d000b2002410c6a2107200241086a2108034002400240200828020020072802002204460d00200a28020021060c010b200441016a22062004490d9e02200441017422092006200920064b1b22094100480d9e020240024020040d002009102821060c010b200a28020020042009102c21060b2006450de3012002200636020420082009360200200728020021040b2007200441016a360200200620046a200541807f72200541ff0071200541077622041b3a00002004210520040d000c86010b0b200241046a210a200141086a2802002105200141046a280200210602400240200241086a2802002002410c6a2802002204460d00200a28020021070c010b200441016a22072004490d9c02200441017422082007200820074b1b22084100480d9c020240024020040d002008102821070c010b200a28020020042008102c21070b2007450de20120022007360204200241086a20083602002002410c6a28020021040b2002410c6a2208200441016a360200200720046a413b3a0000200241086a2109034002400240200928020020082802002204460d00200a28020021070c010b200441016a22072004490d9d022004410174220b2007200b20074b1b220b4100480d9d020240024020040d00200b102821070c010b200a2802002004200b102c21070b2007450de401200220073602042009200b360200200828020021040b2008200441016a360200200720046a200641807f72200641ff0071200641077622041b3a00002004210620040d000b2002410c6a2107200241086a2108034002400240200828020020072802002204460d00200a28020021060c010b200441016a22062004490d9d02200441017422092006200920064b1b22094100480d9d020240024020040d002009102821060c010b200a28020020042009102c21060b2006450de5012002200636020420082009360200200728020021040b2007200441016a360200200620046a200541807f72200541ff0071200541077622041b3a00002004210520040d000c85010b0b200241046a210a200141086a2802002106200141046a280200210502400240200241086a2802002002410c6a2802002204460d00200a28020021070c010b200441016a22072004490d9b02200441017422082007200820074b1b22084100480d9b020240024020040d002008102821070c010b200a28020020042008102c21070b2007450de40120022007360204200241086a20083602002002410c6a28020021040b2002410c6a2208200441016a360200200720046a413c3a0000200241086a2109034002400240200928020020082802002204460d00200a28020021070c010b200441016a22072004490d9c022004410174220b2007200b20074b1b220b4100480d9c020240024020040d00200b102821070c010b200a2802002004200b102c21070b2007450de601200220073602042009200b360200200828020021040b2008200441016a360200200720046a200541807f72200541ff0071200541077622041b3a00002004210520040d000b2002410c6a2107200241086a2108034002400240200828020020072802002204460d00200a28020021050c010b200441016a22052004490d9c02200441017422092005200920054b1b22094100480d9c020240024020040d002009102821050c010b200a28020020042009102c21050b2005450de7012002200536020420082009360200200728020021040b2007200441016a360200200520046a200641807f72200641ff0071200641077622041b3a00002004210620040d000c84010b0b200241046a210a200141086a2802002105200141046a280200210602400240200241086a2802002002410c6a2802002204460d00200a28020021070c010b200441016a22072004490d9a02200441017422082007200820074b1b22084100480d9a020240024020040d002008102821070c010b200a28020020042008102c21070b2007450de60120022007360204200241086a20083602002002410c6a28020021040b2002410c6a2208200441016a360200200720046a413d3a0000200241086a2109034002400240200928020020082802002204460d00200a28020021070c010b200441016a22072004490d9b022004410174220b2007200b20074b1b220b4100480d9b020240024020040d00200b102821070c010b200a2802002004200b102c21070b2007450de801200220073602042009200b360200200828020021040b2008200441016a360200200720046a200641807f72200641ff0071200641077622041b3a00002004210620040d000b2002410c6a2107200241086a2108034002400240200828020020072802002204460d00200a28020021060c010b200441016a22062004490d9b02200441017422092006200920064b1b22094100480d9b020240024020040d002009102821060c010b200a28020020042009102c21060b2006450de9012002200636020420082009360200200728020021040b2007200441016a360200200620046a200541807f72200541ff0071200541077622041b3a00002004210520040d000c83010b0b200241046a210a200141086a2802002105200141046a280200210602400240200241086a2802002002410c6a2802002204460d00200a28020021070c010b200441016a22072004490d9902200441017422082007200820074b1b22084100480d99020240024020040d002008102821070c010b200a28020020042008102c21070b2007450de80120022007360204200241086a20083602002002410c6a28020021040b2002410c6a2208200441016a360200200720046a413e3a0000200241086a2109034002400240200928020020082802002204460d00200a28020021070c010b200441016a22072004490d9a022004410174220b2007200b20074b1b220b4100480d9a020240024020040d00200b102821070c010b200a2802002004200b102c21070b2007450dea01200220073602042009200b360200200828020021040b2008200441016a360200200720046a200641807f72200641ff0071200641077622041b3a00002004210620040d000b2002410c6a2107200241086a2108034002400240200828020020072802002204460d00200a28020021060c010b200441016a22062004490d9a02200441017422092006200920064b1b22094100480d9a020240024020040d002009102821060c010b200a28020020042009102c21060b2006450deb012002200636020420082009360200200728020021040b2007200441016a360200200620046a200541807f72200541ff0071200541077622041b3a00002004210520040d000c82010b0b200241046a210620012d0001210702400240200241086a2802002002410c6a2802002204460d00200628020021050c010b200441016a22052004490d9802200441017422082005200820054b1b22084100480d98020240024020040d002008102821050c010b200628020020042008102c21050b2005450dea0120022005360204200241086a20083602002002410c6a28020021040b2002410c6a2208200441016a360200200520046a413f3a000002400240200241086a28020020082802002204460d00200628020021050c010b200441016a22052004490d9802200441017422082005200820054b1b22084100480d98020240024020040d002008102821050c010b200628020020042008102c21050b2005450deb0120022005360204200241086a20083602002002410c6a28020021040b2002410c6a200441016a360200200520046a20073a00000c80010b200241046a210620012d0001210702400240200241086a2802002002410c6a2802002204460d00200628020021050c010b200441016a22052004490d9702200441017422082005200820054b1b22084100480d97020240024020040d002008102821050c010b200628020020042008102c21050b2005450deb0120022005360204200241086a20083602002002410c6a28020021040b2002410c6a2208200441016a360200200520046a41c0003a000002400240200241086a28020020082802002204460d00200628020021050c010b200441016a22052004490d9702200441017422082005200820054b1b22084100480d97020240024020040d002008102821050c010b200628020020042008102c21050b2005450dec0120022005360204200241086a20083602002002410c6a28020021040b2002410c6a200441016a360200200520046a20073a00000c7f0b200141046a280200210602400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d9602200441017422072005200720054b1b22074100480d96020240024020040d002007102821050c010b200228020420042007102c21050b2005450dec0120022005360204200241086a20073602002002410c6a28020021040b2002410c6a200441016a360200200520046a41c1003a000020032006200210eb042003210420032d0000411f470def020c7e0b200141086a290300210c02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d9502200441017422062005200620054b1b22064100480d95020240024020040d002006102821050c010b200228020420042006102c21050b2005450dec0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41c2003a00002003200c200210ec042003210420032d0000411f470dee020c7d0b200241046a2106200141046a280200210702400240200241086a2802002002410c6a2802002204460d00200628020021050c010b200441016a22052004490d9402200441017422082005200820054b1b22084100480d94020240024020040d002008102821050c010b200628020020042008102c21050b2005450dec0120022005360204200241086a20083602002002410c6a28020021040b2002410c6a2208200441016a360200200520046a41c3003a000002400240200241086a2802002205200828020022046b4104490d00200628020021050c010b200441046a22082004490d9402200541017422042008200420084b1b22044100480d94020240024020050d002004102821050c010b200628020020052004102c21050b2005450ded0120022005360204200241086a20043602002002410c6a28020021040b2002410c6a200441046a360200200520046a20073600000c7c0b200241046a2106200141086a290300210c02400240200241086a2802002002410c6a2802002204460d00200628020021050c010b200441016a22052004490d9302200441017422072005200720054b1b22074100480d93020240024020040d002007102821050c010b200628020020042007102c21050b2005450ded0120022005360204200241086a20073602002002410c6a28020021040b2002410c6a2207200441016a360200200520046a41c4003a000002400240200241086a2802002205200728020022046b4108490d00200628020021050c010b200441086a22072004490d9302200541017422042007200420074b1b22044100480d93020240024020050d002004102821050c010b200628020020052004102c21050b2005450dee0120022005360204200241086a20043602002002410c6a28020021040b2002410c6a200441086a360200200520046a200c3700000c7b0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d9202200441017422062005200620054b1b22064100480d92020240024020040d002006102821050c010b200228020420042006102c21050b2005450dee0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41c5003a00000c7a0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d9102200441017422062005200620054b1b22064100480d91020240024020040d002006102821050c010b200228020420042006102c21050b2005450dee0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41c6003a00000c790b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d9002200441017422062005200620054b1b22064100480d90020240024020040d002006102821050c010b200228020420042006102c21050b2005450dee0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41c7003a00000c780b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d8f02200441017422062005200620054b1b22064100480d8f020240024020040d002006102821050c010b200228020420042006102c21050b2005450dee0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41c8003a00000c770b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d8e02200441017422062005200620054b1b22064100480d8e020240024020040d002006102821050c010b200228020420042006102c21050b2005450dee0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41c9003a00000c760b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d8d02200441017422062005200620054b1b22064100480d8d020240024020040d002006102821050c010b200228020420042006102c21050b2005450dee0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41ca003a00000c750b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d8c02200441017422062005200620054b1b22064100480d8c020240024020040d002006102821050c010b200228020420042006102c21050b2005450dee0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41cb003a00000c740b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d8b02200441017422062005200620054b1b22064100480d8b020240024020040d002006102821050c010b200228020420042006102c21050b2005450dee0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41cc003a00000c730b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d8a02200441017422062005200620054b1b22064100480d8a020240024020040d002006102821050c010b200228020420042006102c21050b2005450dee0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41cd003a00000c720b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d8902200441017422062005200620054b1b22064100480d89020240024020040d002006102821050c010b200228020420042006102c21050b2005450dee0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41ce003a00000c710b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d8802200441017422062005200620054b1b22064100480d88020240024020040d002006102821050c010b200228020420042006102c21050b2005450dee0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41cf003a00000c700b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d8702200441017422062005200620054b1b22064100480d87020240024020040d002006102821050c010b200228020420042006102c21050b2005450dee0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41d0003a00000c6f0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d8602200441017422062005200620054b1b22064100480d86020240024020040d002006102821050c010b200228020420042006102c21050b2005450dee0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41d1003a00000c6e0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d8502200441017422062005200620054b1b22064100480d85020240024020040d002006102821050c010b200228020420042006102c21050b2005450dee0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41d2003a00000c6d0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d8402200441017422062005200620054b1b22064100480d84020240024020040d002006102821050c010b200228020420042006102c21050b2005450dee0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41d3003a00000c6c0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d8302200441017422062005200620054b1b22064100480d83020240024020040d002006102821050c010b200228020420042006102c21050b2005450dee0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41d4003a00000c6b0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d8202200441017422062005200620054b1b22064100480d82020240024020040d002006102821050c010b200228020420042006102c21050b2005450dee0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41d5003a00000c6a0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d8102200441017422062005200620054b1b22064100480d81020240024020040d002006102821050c010b200228020420042006102c21050b2005450dee0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41d6003a00000c690b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d8002200441017422062005200620054b1b22064100480d80020240024020040d002006102821050c010b200228020420042006102c21050b2005450dee0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41d7003a00000c680b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490dff01200441017422062005200620054b1b22064100480dff010240024020040d002006102821050c010b200228020420042006102c21050b2005450dee0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41d8003a00000c670b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490dfe01200441017422062005200620054b1b22064100480dfe010240024020040d002006102821050c010b200228020420042006102c21050b2005450dee0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41d9003a00000c660b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490dfd01200441017422062005200620054b1b22064100480dfd010240024020040d002006102821050c010b200228020420042006102c21050b2005450dee0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41da003a00000c650b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490dfc01200441017422062005200620054b1b22064100480dfc010240024020040d002006102821050c010b200228020420042006102c21050b2005450dee0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41db003a00000c640b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490dfb01200441017422062005200620054b1b22064100480dfb010240024020040d002006102821050c010b200228020420042006102c21050b2005450dee0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41dc003a00000c630b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490dfa01200441017422062005200620054b1b22064100480dfa010240024020040d002006102821050c010b200228020420042006102c21050b2005450dee0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41dd003a00000c620b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490df901200441017422062005200620054b1b22064100480df9010240024020040d002006102821050c010b200228020420042006102c21050b2005450dee0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41de003a00000c610b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490df801200441017422062005200620054b1b22064100480df8010240024020040d002006102821050c010b200228020420042006102c21050b2005450dee0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41df003a00000c600b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490df701200441017422062005200620054b1b22064100480df7010240024020040d002006102821050c010b200228020420042006102c21050b2005450dee0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41e0003a00000c5f0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490df601200441017422062005200620054b1b22064100480df6010240024020040d002006102821050c010b200228020420042006102c21050b2005450dee0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41e1003a00000c5e0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490df501200441017422062005200620054b1b22064100480df5010240024020040d002006102821050c010b200228020420042006102c21050b2005450dee0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41e2003a00000c5d0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490df401200441017422062005200620054b1b22064100480df4010240024020040d002006102821050c010b200228020420042006102c21050b2005450dee0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41e3003a00000c5c0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490df301200441017422062005200620054b1b22064100480df3010240024020040d002006102821050c010b200228020420042006102c21050b2005450dee0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41e4003a00000c5b0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490df201200441017422062005200620054b1b22064100480df2010240024020040d002006102821050c010b200228020420042006102c21050b2005450dee0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41e5003a00000c5a0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490df101200441017422062005200620054b1b22064100480df1010240024020040d002006102821050c010b200228020420042006102c21050b2005450dee0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41e6003a00000c590b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490df001200441017422062005200620054b1b22064100480df0010240024020040d002006102821050c010b200228020420042006102c21050b2005450dee0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41e7003a00000c580b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490def01200441017422062005200620054b1b22064100480def010240024020040d002006102821050c010b200228020420042006102c21050b2005450dee0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41e8003a00000c570b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490dba02200441017422062005200620054b1b22064100480dba020240024020040d002006102821050c010b200228020420042006102c21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41e9003a00000c560b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490db902200441017422062005200620054b1b22064100480db9020240024020040d002006102821050c010b200228020420042006102c21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41ea003a00000c550b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490db802200441017422062005200620054b1b22064100480db8020240024020040d002006102821050c010b200228020420042006102c21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41eb003a00000c540b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490db702200441017422062005200620054b1b22064100480db7020240024020040d002006102821050c010b200228020420042006102c21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41ec003a00000c530b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490db602200441017422062005200620054b1b22064100480db6020240024020040d002006102821050c010b200228020420042006102c21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41ed003a00000c520b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490db502200441017422062005200620054b1b22064100480db5020240024020040d002006102821050c010b200228020420042006102c21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41ee003a00000c510b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490db402200441017422062005200620054b1b22064100480db4020240024020040d002006102821050c010b200228020420042006102c21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41ef003a00000c500b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490db302200441017422062005200620054b1b22064100480db3020240024020040d002006102821050c010b200228020420042006102c21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41f0003a00000c4f0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490db202200441017422062005200620054b1b22064100480db2020240024020040d002006102821050c010b200228020420042006102c21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41f1003a00000c4e0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490db102200441017422062005200620054b1b22064100480db1020240024020040d002006102821050c010b200228020420042006102c21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41f2003a00000c4d0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490db002200441017422062005200620054b1b22064100480db0020240024020040d002006102821050c010b200228020420042006102c21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41f3003a00000c4c0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490daf02200441017422062005200620054b1b22064100480daf020240024020040d002006102821050c010b200228020420042006102c21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41f4003a00000c4b0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490dae02200441017422062005200620054b1b22064100480dae020240024020040d002006102821050c010b200228020420042006102c21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41f5003a00000c4a0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490dad02200441017422062005200620054b1b22064100480dad020240024020040d002006102821050c010b200228020420042006102c21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41f6003a00000c490b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490dac02200441017422062005200620054b1b22064100480dac020240024020040d002006102821050c010b200228020420042006102c21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41f7003a00000c480b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490dab02200441017422062005200620054b1b22064100480dab020240024020040d002006102821050c010b200228020420042006102c21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41f8003a00000c470b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490daa02200441017422062005200620054b1b22064100480daa020240024020040d002006102821050c010b200228020420042006102c21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41f9003a00000c460b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490da902200441017422062005200620054b1b22064100480da9020240024020040d002006102821050c010b200228020420042006102c21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41fa003a00000c450b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490da802200441017422062005200620054b1b22064100480da8020240024020040d002006102821050c010b200228020420042006102c21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41fb003a00000c440b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490da702200441017422062005200620054b1b22064100480da7020240024020040d002006102821050c010b200228020420042006102c21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41fc003a00000c430b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490da602200441017422062005200620054b1b22064100480da6020240024020040d002006102821050c010b200228020420042006102c21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41fd003a00000c420b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490da502200441017422062005200620054b1b22064100480da5020240024020040d002006102821050c010b200228020420042006102c21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41fe003a00000c410b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490da402200441017422062005200620054b1b22064100480da4020240024020040d002006102821050c010b200228020420042006102c21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41ff003a00000c400b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490da302200441017422062005200620054b1b22064100480da3020240024020040d002006102821050c010b200228020420042006102c21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a4180013a00000c3f0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490da202200441017422062005200620054b1b22064100480da2020240024020040d002006102821050c010b200228020420042006102c21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a4181013a00000c3e0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490da102200441017422062005200620054b1b22064100480da1020240024020040d002006102821050c010b200228020420042006102c21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a4182013a00000c3d0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490da002200441017422062005200620054b1b22064100480da0020240024020040d002006102821050c010b200228020420042006102c21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a4183013a00000c3c0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d9f02200441017422062005200620054b1b22064100480d9f020240024020040d002006102821050c010b200228020420042006102c21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a4184013a00000c3b0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d9e02200441017422062005200620054b1b22064100480d9e020240024020040d002006102821050c010b200228020420042006102c21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a4185013a00000c3a0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d9d02200441017422062005200620054b1b22064100480d9d020240024020040d002006102821050c010b200228020420042006102c21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a4186013a00000c390b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d9c02200441017422062005200620054b1b22064100480d9c020240024020040d002006102821050c010b200228020420042006102c21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a4187013a00000c380b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d9b02200441017422062005200620054b1b22064100480d9b020240024020040d002006102821050c010b200228020420042006102c21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a4188013a00000c370b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d9a02200441017422062005200620054b1b22064100480d9a020240024020040d002006102821050c010b200228020420042006102c21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a4189013a00000c360b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d9902200441017422062005200620054b1b22064100480d99020240024020040d002006102821050c010b200228020420042006102c21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a418a013a00000c350b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d9802200441017422062005200620054b1b22064100480d98020240024020040d002006102821050c010b200228020420042006102c21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a418b013a00000c340b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d9702200441017422062005200620054b1b22064100480d97020240024020040d002006102821050c010b200228020420042006102c21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a418c013a00000c330b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d9602200441017422062005200620054b1b22064100480d96020240024020040d002006102821050c010b200228020420042006102c21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a418d013a00000c320b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d9502200441017422062005200620054b1b22064100480d95020240024020040d002006102821050c010b200228020420042006102c21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a418e013a00000c310b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d9402200441017422062005200620054b1b22064100480d94020240024020040d002006102821050c010b200228020420042006102c21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a418f013a00000c300b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d9302200441017422062005200620054b1b22064100480d93020240024020040d002006102821050c010b200228020420042006102c21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a4190013a00000c2f0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d9202200441017422062005200620054b1b22064100480d92020240024020040d002006102821050c010b200228020420042006102c21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a4191013a00000c2e0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d9102200441017422062005200620054b1b22064100480d91020240024020040d002006102821050c010b200228020420042006102c21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a4192013a00000c2d0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d9002200441017422062005200620054b1b22064100480d90020240024020040d002006102821050c010b200228020420042006102c21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a4193013a00000c2c0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d8f02200441017422062005200620054b1b22064100480d8f020240024020040d002006102821050c010b200228020420042006102c21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a4194013a00000c2b0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d8e02200441017422062005200620054b1b22064100480d8e020240024020040d002006102821050c010b200228020420042006102c21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a4195013a00000c2a0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d8d02200441017422062005200620054b1b22064100480d8d020240024020040d002006102821050c010b200228020420042006102c21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a4196013a00000c290b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d8c02200441017422062005200620054b1b22064100480d8c020240024020040d002006102821050c010b200228020420042006102c21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a4197013a00000c280b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d8b02200441017422062005200620054b1b22064100480d8b020240024020040d002006102821050c010b200228020420042006102c21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a4198013a00000c270b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d8a02200441017422062005200620054b1b22064100480d8a020240024020040d002006102821050c010b200228020420042006102c21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a4199013a00000c260b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d8902200441017422062005200620054b1b22064100480d89020240024020040d002006102821050c010b200228020420042006102c21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a419a013a00000c250b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d8802200441017422062005200620054b1b22064100480d88020240024020040d002006102821050c010b200228020420042006102c21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a419b013a00000c240b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d8702200441017422062005200620054b1b22064100480d87020240024020040d002006102821050c010b200228020420042006102c21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a419c013a00000c230b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d8602200441017422062005200620054b1b22064100480d86020240024020040d002006102821050c010b200228020420042006102c21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a419d013a00000c220b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d8502200441017422062005200620054b1b22064100480d85020240024020040d002006102821050c010b200228020420042006102c21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a419e013a00000c210b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d8402200441017422062005200620054b1b22064100480d84020240024020040d002006102821050c010b200228020420042006102c21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a419f013a00000c200b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d8302200441017422062005200620054b1b22064100480d83020240024020040d002006102821050c010b200228020420042006102c21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41a0013a00000c1f0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d8202200441017422062005200620054b1b22064100480d82020240024020040d002006102821050c010b200228020420042006102c21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41a1013a00000c1e0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d8102200441017422062005200620054b1b22064100480d81020240024020040d002006102821050c010b200228020420042006102c21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41a2013a00000c1d0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d8002200441017422062005200620054b1b22064100480d80020240024020040d002006102821050c010b200228020420042006102c21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41a3013a00000c1c0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490dff01200441017422062005200620054b1b22064100480dff010240024020040d002006102821050c010b200228020420042006102c21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41a4013a00000c1b0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490dfe01200441017422062005200620054b1b22064100480dfe010240024020040d002006102821050c010b200228020420042006102c21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41a5013a00000c1a0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490dfd01200441017422062005200620054b1b22064100480dfd010240024020040d002006102821050c010b200228020420042006102c21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41a6013a00000c190b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490dfc01200441017422062005200620054b1b22064100480dfc010240024020040d002006102821050c010b200228020420042006102c21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41a7013a00000c180b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490dfb01200441017422062005200620054b1b22064100480dfb010240024020040d002006102821050c010b200228020420042006102c21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41a8013a00000c170b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490dfa01200441017422062005200620054b1b22064100480dfa010240024020040d002006102821050c010b200228020420042006102c21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41a9013a00000c160b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490df901200441017422062005200620054b1b22064100480df9010240024020040d002006102821050c010b200228020420042006102c21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41aa013a00000c150b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490df801200441017422062005200620054b1b22064100480df8010240024020040d002006102821050c010b200228020420042006102c21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41ab013a00000c140b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490df701200441017422062005200620054b1b22064100480df7010240024020040d002006102821050c010b200228020420042006102c21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41ac013a00000c130b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490df601200441017422062005200620054b1b22064100480df6010240024020040d002006102821050c010b200228020420042006102c21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41ad013a00000c120b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490df501200441017422062005200620054b1b22064100480df5010240024020040d002006102821050c010b200228020420042006102c21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41ae013a00000c110b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490df401200441017422062005200620054b1b22064100480df4010240024020040d002006102821050c010b200228020420042006102c21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41af013a00000c100b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490df301200441017422062005200620054b1b22064100480df3010240024020040d002006102821050c010b200228020420042006102c21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41b0013a00000c0f0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490df201200441017422062005200620054b1b22064100480df2010240024020040d002006102821050c010b200228020420042006102c21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41b1013a00000c0e0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490df101200441017422062005200620054b1b22064100480df1010240024020040d002006102821050c010b200228020420042006102c21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41b2013a00000c0d0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490df001200441017422062005200620054b1b22064100480df0010240024020040d002006102821050c010b200228020420042006102c21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41b3013a00000c0c0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490dfc01200441017422062005200620054b1b22064100480dfc010240024020040d002006102821050c010b200228020420042006102c21050b2005450df00120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41b4013a00000c0b0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490dfb01200441017422062005200620054b1b22064100480dfb010240024020040d002006102821050c010b200228020420042006102c21050b2005450df00120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41b5013a00000c0a0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490dfa01200441017422062005200620054b1b22064100480dfa010240024020040d002006102821050c010b200228020420042006102c21050b2005450df00120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41b6013a00000c090b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490df901200441017422062005200620054b1b22064100480df9010240024020040d002006102821050c010b200228020420042006102c21050b2005450df00120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41b7013a00000c080b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490df801200441017422062005200620054b1b22064100480df8010240024020040d002006102821050c010b200228020420042006102c21050b2005450df00120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41b8013a00000c070b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490df701200441017422062005200620054b1b22064100480df7010240024020040d002006102821050c010b200228020420042006102c21050b2005450df00120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41b9013a00000c060b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490df601200441017422062005200620054b1b22064100480df6010240024020040d002006102821050c010b200228020420042006102c21050b2005450df00120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41ba013a00000c050b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490df501200441017422062005200620054b1b22064100480df5010240024020040d002006102821050c010b200228020420042006102c21050b2005450df00120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41bb013a00000c040b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490df401200441017422062005200620054b1b22064100480df4010240024020040d002006102821050c010b200228020420042006102c21050b2005450df00120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41bc013a00000c030b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490df301200441017422062005200620054b1b22064100480df3010240024020040d002006102821050c010b200228020420042006102c21050b2005450df00120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41bd013a00000c020b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490df201200441017422062005200620054b1b22064100480df2010240024020040d002006102821050c010b200228020420042006102c21050b2005450df00120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41be013a00000c010b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490df101200441017422062005200620054b1b22064100480df1010240024020040d002006102821050c010b200228020420042006102c21050b2005450df00120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41bf013a00000b2000411f3a000020012d00004109470df1010240200141046a280200220228020441ffffffff0371450d002002280200102a200128020421020b2002102a0cf1010b200641011037000b200641011037000b200841011037000b200841011037000b200841011037000b200841011037000b200841011037000b200841011037000b200641011037000b200641011037000b200741011037000b200a41011037000b200741011037000b200a41011037000b200641011037000b200a41011037000b200641011037000b200741011037000b200a41011037000b200741011037000b200a41011037000b200641011037000b200641011037000b200641011037000b200741011037000b200a41011037000b200741011037000b200a41011037000b200741011037000b200a41011037000b200741011037000b200a41011037000b200741011037000b200a41011037000b200841011037000b200b41011037000b200941011037000b200841011037000b200b41011037000b200941011037000b200841011037000b200b41011037000b200941011037000b200841011037000b200b41011037000b200941011037000b200841011037000b200b41011037000b200941011037000b200841011037000b200b41011037000b200941011037000b200841011037000b200b41011037000b200941011037000b200841011037000b200b41011037000b200941011037000b200841011037000b200b41011037000b200941011037000b200841011037000b200b41011037000b200941011037000b200841011037000b200b41011037000b200941011037000b200841011037000b200b41011037000b200941011037000b200841011037000b200b41011037000b200941011037000b200841011037000b1031000b200b41011037000b200941011037000b200841011037000b200b41011037000b200941011037000b200841011037000b200b41011037000b200941011037000b200841011037000b200b41011037000b200941011037000b200841011037000b200b41011037000b200941011037000b200841011037000b200b41011037000b200941011037000b200841011037000b200b41011037000b200941011037000b200841011037000b200b41011037000b200941011037000b200841011037000b200b41011037000b200941011037000b200841011037000b200b41011037000b200941011037000b200841011037000b200841011037000b200841011037000b200841011037000b200741011037000b200641011037000b200841011037000b200441011037000b200741011037000b200441011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b1031000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b1031000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b1031000b20002004290200370200200041086a200441086a29020037020020012d00004109470d000240200141046a280200220228020441ffffffff0371450d002002280200102a200128020421020b2002102a0b200341106a24000bb60301057f2004410c6a2105200441086a2106024002400240034002400240200628020020052802002207460d00200428020421080c010b200741016a22082007490d04200741017422092008200920084b1b22094100480d040240024020070d002009102821080c010b200428020420072009102c21080b2008450d022004200836020420062009360200200528020021070b2005200741016a360200200820076a200141807f72200141ff0071200141077622071b3a00002007210120070d000b024020022003460d002004410c6a2105200441086a2106034020022802002101034002400240200628020020052802002207460d00200428020421080c010b200741016a22082007490d06200741017422092008200920084b1b22094100480d060240024020070d002009102821080c010b200428020420072009102c21080b2008450d052004200836020420062009360200200528020021070b2005200741016a360200200820076a200141807f72200141ff0071200141077622071b3a00002007210120070d000b200241046a22022003470d000b0b2000411f3a00000f0b200941011037000b200941011037000b1031000baf0301067f024002400240024020014107752203200141c00071220472452003417f4720044572460d002002410c6a2105200241086a2106034002400240200628020020052802002204460d00200228020421070c010b200441016a22072004490d05200441017422082007200820074b1b22084100480d050240024020040d002008102821070c010b200228020420042008102c21070b2007450d032002200736020420062008360200200528020021040b2005200441016a360200200720046a200141807f723a0000200341c000712104200321012003410775220721032007200472452007417f4720044572470d000b0b02400240200241086a2802002002410c6a2802002204460d00200228020421030c010b200441016a22032004490d03200441017422072003200720034b1b22074100480d030240024020040d002007102821030c010b200228020420042007102c21030b2003450d0220022003360204200241086a20073602002002410c6a28020021040b2002410c6a200441016a360200200320046a200141ff00713a00002000411f3a00000f0b200841011037000b200741011037000b1031000bb30302017e067f024002400240024020014207872203502001a7220441c00071452205712003427f52200572460d002002410c6a2106200241086a2107034002400240200728020020062802002205460d00200228020421080c010b200541016a22082005490d05200541017422092008200920084b1b22094100480d050240024020050d002009102821080c010b200228020420052009102c21080b2008450d032002200836020420072009360200200628020021050b2006200541016a360200200820056a200441807f723a00002003a72104200342078722012103200150200441c00071452205712001427f52200572470d000b0b02400240200241086a2802002002410c6a2802002205460d00200228020421080c010b200541016a22082005490d03200541017422062008200620084b1b22064100480d030240024020050d002006102821080c010b200228020420052006102c21080b2008450d0220022008360204200241086a20063602002002410c6a28020021050b2002410c6a200541016a360200200820056a200441ff00713a00002000411f3a00000f0b200941011037000b200641011037000b1031000be103010a7f230041306b22022400200241216a220341076a210441002105410021064100210741002108410821090240024002400340200241186a200110ee04024020022802184101470d002000200229021c370204200041013602002000410c6a200241186a410c6a29020037020002402007450d00200921070340024020072d00004109470d000240200741046a220a280200220528020441ffffffff0371450d002005280200102a200a28020021050b2005102a0b200741106a2107200641706a22060d000b0b2008450d042009102a0c040b200220032900003703082002200429000037000f20022d0020210a2002200229000f37001f200220022903083703180240024020072008470d00200741016a220b2007490d032005200b2005200b4b1b220841ffffffff00712008470d032008410474220b4100480d030240024020070d00200b102821090c010b20092006200b102c21090b2009450d010b200920066a220b200a3a0000200b41016a2002290318370000200b41086a200229001f370000200541026a2105200641106a2106200741016a2107200a41ff01714106460d030c010b0b200b41081037000b1031000b20002009360204200041003602002000410c6a2007360200200041086a20083602000b200241306a24000b80b601020b7f017e230041f0006b2202240002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024020012802082203200128020c2204460d00200441016a22052004490d02200320054f0d0120052003103c000b200241013a0048200241ec006a41013602002002420137025c200241a4e2c5003602582002412636023c2002200241386a3602682002200241c8006a360238200241086a200241d8006a1033200241336a200241106a2802003600002002200229030837002b2002200229002837031820022002412f6a29000037001f200041053a0004200020022903183700052000410c6a200229001f370000200041013602000c640b2001280200220620046a2d000021072001410c6a2208200536020002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240200741bf014b0d0020070ec001b902b902010203b90200000000000405060708090a00000000000000000b0c000000000d0e0f101100000012131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f80018101820183018401850186018701880189018a018b018c018d018e018f0190019101920193019401950196019701980199019a019b019c019d019e019f01a001a101a201a301a401a501a601a701a801a901b9020b2000410b3a000420004101360200200041056a20073a00000cbc020b024002400240024002400240024020032005460d00200441026a21092005417f460de00120032009490da302200620056a2c00002101200820093602004100210a0240200141004e0d00411921090c020b0240200141017441807f71200172220141ff0171220541847e6a220941034d0d0041062109200541c001470d034104210a410221070cbf020b20090e0404030506040b200241013a0047200241ec006a41013602002002420137025c200241a4e2c5003602582002412636023c2002200241386a3602682002200241c7006a360238200241c8006a200241d8006a1033200241326a200241d0006a2802003601002002200229034837012a2002200229012837031820022002412e6a29010037011e410521090b2002200229011e37010e200220022903183703080b200020013a0005200020093a000420002002290308370106200041013602002000410c6a200229010e3701000cbf020b4102210a410221070cba020b4103210a410221070cb9020b4101210a0b410221070cb7020b024002400240024002400240024020032005460d00200441026a21092005417f460de00120032009490da302200620056a2c00002101200820093602004100210a0240200141004e0d00411921090c020b0240200141017441807f71200172220141ff0171220541847e6a220941034d0d0041062109200541c001470d034104210a410321070cbe020b20090e0404030506040b200241013a0047200241ec006a41013602002002420137025c200241a4e2c5003602582002412636023c2002200241386a3602682002200241c7006a360238200241c8006a200241d8006a1033200241326a200241d0006a2802003601002002200229034837012a2002200229012837031820022002412e6a29010037011e410521090b2002200229011e37010e200220022903183703080b200020013a0005200020093a000420002002290308370106200041013602002000410c6a200229010e3701000cbe020b4102210a410321070cb9020b4103210a410321070cb8020b4101210a0b410321070cb6020b024002400240024002400240024020032005460d00200441026a21092005417f460de00120032009490da302200620056a2c00002101200820093602004100210a0240200141004e0d00411921090c020b0240200141017441807f71200172220141ff0171220541847e6a220941034d0d0041062109200541c001470d034104210a410421070cbd020b20090e0404030506040b200241013a0047200241ec006a41013602002002420137025c200241a4e2c5003602582002412636023c2002200241386a3602682002200241c7006a360238200241c8006a200241d8006a1033200241326a200241d0006a2802003601002002200229034837012a2002200229012837031820022002412e6a29010037011e410521090b2002200229011e37010e200220022903183703080b200020013a0005200020093a000420002002290308370106200041013602002000410c6a200229010e3701000cbd020b4102210a410421070cb8020b4103210a410421070cb7020b4101210a0b410421070cb5020b410621070cb4020b410021014100210902400240034002402001411f4d0d00410f21010c020b0240024020032005460d002005417f460ddd012003200541016a22074f0d01200541016a2003103c000b200241013a0018200241ec006a41013602002002420137025c200241a4e2c5003602582002412636023c2002200241386a3602682002200241186a360238200241286a200241d8006a1033410521010c020b200620056a2d0000210420082007360200200441ff00712001411f71742009722109200141076a2101200721052004418001710d000b20014120490d01410d210120044110490d010b2000200136020420004101360200200041086a2002290228370200200041106a200241286a41086a2802003602000cb8020b410721070cb3020b410021014100210902400240034002402001411f4d0d00410f21010c020b0240024020032005460d002005417f460ddd012003200541016a22074f0d01200541016a2003103c000b200241013a0018200241ec006a41013602002002420137025c200241a4e2c5003602582002412636023c2002200241386a3602682002200241186a360238200241286a200241d8006a1033410521010c020b200620056a2d0000210420082007360200200441ff00712001411f71742009722109200141076a2101200721052004418001710d000b20014120490d01410d210120044110490d010b2000200136020420004101360200200041086a2002290228370200200041106a200241286a41086a2802003602000cb7020b410821070cb2020b200241d8006a200110ef044104210a200228025822074101460da201200241e0006a280200210b41002106200228025c210c02400240200241e4006a280200220941027422050d00410021040c010b2005410275220441ffffffff03712004470dda01200441027422034100480dda0120031028220a450dd9010b02402009450d00200941027421032005417c6a2106200a2109200c2105034020092005280200360200200941046a2109200541046a21052003417c6a22030d000b200641027641016a21060b0240200b450d00200c102a0b20022d005c4105470db0022007450db00220022802640da3010cb0020b410a21070cb0020b410021014100210902400240034002402001411f4d0d00410f21010c020b0240024020032005460d002005417f460ddd012003200541016a22074f0d01200541016a2003103c000b200241013a0018200241ec006a41013602002002420137025c200241a4e2c5003602582002412636023c2002200241386a3602682002200241186a360238200241286a200241d8006a1033410521010c020b200620056a2d0000210420082007360200200441ff00712001411f71742009722109200141076a2101200721052004418001710d000b20014120490d01410d210120044110490d010b2000200136020420004101360200200041086a2002290228370200200041106a200241286a41086a2802003602000cb4020b410b21070caf020b410021014100210902400240034002402001411f4d0d00410f21010c020b0240024020032005460d002005417f460ddd012003200541016a22044f0d01200541016a2003103c000b200241013a0018200241ec006a41013602002002420137025c200241a4e2c5003602582002412636023c2002200241386a3602682002200241186a360238200241286a200241d8006a1033410521010c020b200620056a2d0000210720082004360200200741ff00712001411f71742009722109200141076a2101200421052007418001710d000b20014120490d01410d210120074110490d010b2000200136020420004101360200200041086a2002290228370200200041106a200241286a41086a2802003602000cb3020b0240024020032004460d00200441016a22012004490ddb01200320014f0d0120012003103c000b200241013a0048200241ec006a41013602002002420137025c200241a4e2c5003602582002412636023c2002200241386a3602682002200241c8006a360238200241086a200241d8006a1033200241336a200241106a2802003600002002200229030837002b2002200229002837031820022002412f6a29000037001f200041053a0004200020022903183700052000410c6a200229001f370000200041013602000cb3020b200620046a2d0000210520082001360200024020050d00410c21074100210a0caf020b200041163a000420004101360200200041056a20053a00000cb2020b410d21070cad020b410e21070cac020b410021014100210902400240034002402001411f4d0d00410f21010c020b0240024020032005460d002005417f460ddc012003200541016a22074f0d01200541016a2003103c000b200241013a0018200241ec006a41013602002002420137025c200241a4e2c5003602582002412636023c2002200241386a3602682002200241186a360238200241286a200241d8006a1033410521010c020b200620056a2d0000210420082007360200200441ff00712001411f71742009722109200141076a2101200721052004418001710d000b20014120490d01410d210120044110490d010b2000200136020420004101360200200041086a2002290228370200200041106a200241286a41086a2802003602000cb0020b410f21070cab020b410021014100210902400240034002402001411f4d0d00410f21010c020b0240024020032005460d002005417f460ddc012003200541016a22074f0d01200541016a2003103c000b200241013a0018200241ec006a41013602002002420137025c200241a4e2c5003602582002412636023c2002200241386a3602682002200241186a360238200241286a200241d8006a1033410521010c020b200620056a2d0000210420082007360200200441ff00712001411f71742009722109200141076a2101200721052004418001710d000b20014120490d01410d210120044110490d010b2000200136020420004101360200200041086a2002290228370200200041106a200241286a41086a2802003602000caf020b411021070caa020b410021014100210902400240034002402001411f4d0d00410f21010c020b0240024020032005460d002005417f460ddc012003200541016a22074f0d01200541016a2003103c000b200241013a0018200241ec006a41013602002002420137025c200241a4e2c5003602582002412636023c2002200241386a3602682002200241186a360238200241286a200241d8006a1033410521010c020b200620056a2d0000210420082007360200200441ff00712001411f71742009722109200141076a2101200721052004418001710d000b20014120490d01410d210120044110490d010b2000200136020420004101360200200041086a2002290228370200200041106a200241286a41086a2802003602000cae020b411121070ca9020b410021014100210902400240034002402001411f4d0d00410f21010c020b0240024020032005460d002005417f460ddc012003200541016a22074f0d01200541016a2003103c000b200241013a0018200241ec006a41013602002002420137025c200241a4e2c5003602582002412636023c2002200241386a3602682002200241186a360238200241286a200241d8006a1033410521010c020b200620056a2d0000210420082007360200200441ff00712001411f71742009722109200141076a2101200721052004418001710d000b20014120490d01410d210120044110490d010b2000200136020420004101360200200041086a2002290228370200200041106a200241286a41086a2802003602000cad020b411221070ca8020b410021014100210902400240034002402001411f4d0d00410f21010c020b0240024020032005460d002005417f460ddc012003200541016a22074f0d01200541016a2003103c000b200241013a0018200241ec006a41013602002002420137025c200241a4e2c5003602582002412636023c2002200241386a3602682002200241186a360238200241286a200241d8006a1033410521010c020b200620056a2d0000210420082007360200200441ff00712001411f71742009722109200141076a2101200721052004418001710d000b20014120490d01410d210120044110490d010b2000200136020420004101360200200041086a2002290228370200200041106a200241286a41086a2802003602000cac020b411321070ca7020b410120036b2107200441026a21014100210541002109024002400240034002402005411f4d0d00410f21010c020b02400240200720016a4102460d002001450ddd01200320014f0d0120012003103c000b200241013a0018200241ec006a41013602002002420137025c200241a4e2c5003602582002412636023c2002200241386a3602682002200241186a360238200241286a200241d8006a103320022802282109200228022c210520022802302103410521010c030b200620016a417f6a2d0000210420082001360200200441ff00712005411f71742009722109200141016a2101200541076a21052004418001710d000b20054120490d0220044110490d02410d21010b0b2000200136020420004101360200200041106a20033602002000410c6a2005360200200041086a20093602000cab020b2001417f6a2101410021054100210a034002402005411f4d0d00410f21010c9c010b20032001460d9a012001417f460dd9012003200141016a2207490d8f02200620016a2d0000210420082007360200200441ff00712005411f7174200a72210a200541076a2105200721012004418001710d000b024020054120490d00410d21012004410f4b0d9b010b200aad210d411421070ca6020b410120036b2107200441026a21014100210541002109024002400240034002402005411f4d0d00410f21010c020b02400240200720016a4102460d002001450dde01200320014f0d0120012003103c000b200241013a0018200241ec006a41013602002002420137025c200241a4e2c5003602582002412636023c2002200241386a3602682002200241186a360238200241286a200241d8006a103320022802282109200228022c210520022802302103410521010c030b200620016a417f6a2d0000210420082001360200200441ff00712005411f71742009722109200141016a2101200541076a21052004418001710d000b20054120490d0220044110490d02410d21010b0b2000200136020420004101360200200041106a20033602002000410c6a2005360200200041086a20093602000caa020b2001417f6a2101410021054100210a034002402005411f4d0d00410f21010c9d010b20032001460d9b012001417f460dda012003200141016a2207490d8f02200620016a2d0000210420082007360200200441ff00712005411f7174200a72210a200541076a2105200721012004418001710d000b024020054120490d00410d21012004410f4b0d9c010b200aad210d411521070ca5020b410120036b2107200441026a21014100210541002109024002400240034002402005411f4d0d00410f21010c020b02400240200720016a4102460d002001450ddf01200320014f0d0120012003103c000b200241013a0018200241ec006a41013602002002420137025c200241a4e2c5003602582002412636023c2002200241386a3602682002200241186a360238200241286a200241d8006a103320022802282109200228022c210520022802302103410521010c030b200620016a417f6a2d0000210420082001360200200441ff00712005411f71742009722109200141016a2101200541076a21052004418001710d000b20054120490d0220044110490d02410d21010b0b2000200136020420004101360200200041106a20033602002000410c6a2005360200200041086a20093602000ca9020b2001417f6a2101410021054100210a034002402005411f4d0d00410f21010c9e010b20032001460d9c012001417f460ddb012003200141016a2207490d8f02200620016a2d0000210420082007360200200441ff00712005411f7174200a72210a200541076a2105200721012004418001710d000b024020054120490d00410d21012004410f4b0d9d010b200aad210d411621070ca4020b410120036b2107200441026a21014100210541002109024002400240034002402005411f4d0d00410f21010c020b02400240200720016a4102460d002001450de001200320014f0d0120012003103c000b200241013a0018200241ec006a41013602002002420137025c200241a4e2c5003602582002412636023c2002200241386a3602682002200241186a360238200241286a200241d8006a103320022802282109200228022c210520022802302103410521010c030b200620016a417f6a2d0000210420082001360200200441ff00712005411f71742009722109200141016a2101200541076a21052004418001710d000b20054120490d0220044110490d02410d21010b0b2000200136020420004101360200200041106a20033602002000410c6a2005360200200041086a20093602000ca8020b2001417f6a2101410021054100210a034002402005411f4d0d00410f21010c9f010b20032001460d9d012001417f460ddc012003200141016a2207490d8f02200620016a2d0000210420082007360200200441ff00712005411f7174200a72210a200541076a2105200721012004418001710d000b024020054120490d00410d21012004410f4b0d9e010b200aad210d411721070ca3020b410120036b2107200441026a21014100210541002109024002400240034002402005411f4d0d00410f21010c020b02400240200720016a4102460d002001450de101200320014f0d0120012003103c000b200241013a0018200241ec006a41013602002002420137025c200241a4e2c5003602582002412636023c2002200241386a3602682002200241186a360238200241286a200241d8006a103320022802282109200228022c210520022802302103410521010c030b200620016a417f6a2d0000210420082001360200200441ff00712005411f71742009722109200141016a2101200541076a21052004418001710d000b20054120490d0220044110490d02410d21010b0b2000200136020420004101360200200041106a20033602002000410c6a2005360200200041086a20093602000ca7020b2001417f6a2101410021054100210a034002402005411f4d0d00410f21010ca0010b20032001460d9e012001417f460ddd012003200141016a2207490d8f02200620016a2d0000210420082007360200200441ff00712005411f7174200a72210a200541076a2105200721012004418001710d000b024020054120490d00410d21012004410f4b0d9f010b200aad210d411821070ca2020b410120036b2107200441026a21014100210541002109024002400240034002402005411f4d0d00410f21010c020b02400240200720016a4102460d002001450de201200320014f0d0120012003103c000b200241013a0018200241ec006a41013602002002420137025c200241a4e2c5003602582002412636023c2002200241386a3602682002200241186a360238200241286a200241d8006a103320022802282109200228022c210520022802302103410521010c030b200620016a417f6a2d0000210420082001360200200441ff00712005411f71742009722109200141016a2101200541076a21052004418001710d000b20054120490d0220044110490d02410d21010b0b2000200136020420004101360200200041106a20033602002000410c6a2005360200200041086a20093602000ca6020b2001417f6a2101410021054100210a034002402005411f4d0d00410f21010ca1010b20032001460d9f012001417f460dde012003200141016a2207490d8f02200620016a2d0000210420082007360200200441ff00712005411f7174200a72210a200541076a2105200721012004418001710d000b024020054120490d00410d21012004410f4b0da0010b200aad210d411921070ca1020b410120036b2107200441026a21014100210541002109024002400240034002402005411f4d0d00410f21010c020b02400240200720016a4102460d002001450de301200320014f0d0120012003103c000b200241013a0018200241ec006a41013602002002420137025c200241a4e2c5003602582002412636023c2002200241386a3602682002200241186a360238200241286a200241d8006a103320022802282109200228022c210520022802302103410521010c030b200620016a417f6a2d0000210420082001360200200441ff00712005411f71742009722109200141016a2101200541076a21052004418001710d000b20054120490d0220044110490d02410d21010b0b2000200136020420004101360200200041106a20033602002000410c6a2005360200200041086a20093602000ca5020b2001417f6a2101410021054100210a034002402005411f4d0d00410f21010ca2010b20032001460da0012001417f460ddf012003200141016a2207490d8f02200620016a2d0000210420082007360200200441ff00712005411f7174200a72210a200541076a2105200721012004418001710d000b024020054120490d00410d21012004410f4b0da1010b200aad210d411a21070ca0020b410120036b2107200441026a21014100210541002109024002400240034002402005411f4d0d00410f21010c020b02400240200720016a4102460d002001450de401200320014f0d0120012003103c000b200241013a0018200241ec006a41013602002002420137025c200241a4e2c5003602582002412636023c2002200241386a3602682002200241186a360238200241286a200241d8006a103320022802282109200228022c210520022802302103410521010c030b200620016a417f6a2d0000210420082001360200200441ff00712005411f71742009722109200141016a2101200541076a21052004418001710d000b20054120490d0220044110490d02410d21010b0b2000200136020420004101360200200041106a20033602002000410c6a2005360200200041086a20093602000ca4020b2001417f6a2101410021054100210a034002402005411f4d0d00410f21010ca3010b20032001460da1012001417f460de0012003200141016a2207490d8f02200620016a2d0000210420082007360200200441ff00712005411f7174200a72210a200541076a2105200721012004418001710d000b024020054120490d00410d21012004410f4b0da2010b200aad210d411b21070c9f020b410120036b2107200441026a21014100210541002109024002400240034002402005411f4d0d00410f21010c020b02400240200720016a4102460d002001450de501200320014f0d0120012003103c000b200241013a0018200241ec006a41013602002002420137025c200241a4e2c5003602582002412636023c2002200241386a3602682002200241186a360238200241286a200241d8006a103320022802282109200228022c210520022802302103410521010c030b200620016a417f6a2d0000210420082001360200200441ff00712005411f71742009722109200141016a2101200541076a21052004418001710d000b20054120490d0220044110490d02410d21010b0b2000200136020420004101360200200041106a20033602002000410c6a2005360200200041086a20093602000ca3020b2001417f6a2101410021054100210a034002402005411f4d0d00410f21010ca4010b20032001460da2012001417f460de1012003200141016a2207490d8f02200620016a2d0000210420082007360200200441ff00712005411f7174200a72210a200541076a2105200721012004418001710d000b024020054120490d00410d21012004410f4b0da3010b200aad210d411c21070c9e020b410120036b2107200441026a21014100210541002109024002400240034002402005411f4d0d00410f21010c020b02400240200720016a4102460d002001450de601200320014f0d0120012003103c000b200241013a0018200241ec006a41013602002002420137025c200241a4e2c5003602582002412636023c2002200241386a3602682002200241186a360238200241286a200241d8006a103320022802282109200228022c210520022802302103410521010c030b200620016a417f6a2d0000210420082001360200200441ff00712005411f71742009722109200141016a2101200541076a21052004418001710d000b20054120490d0220044110490d02410d21010b0b2000200136020420004101360200200041106a20033602002000410c6a2005360200200041086a20093602000ca2020b2001417f6a2101410021054100210a034002402005411f4d0d00410f21010ca5010b20032001460da3012001417f460de2012003200141016a2207490d8f02200620016a2d0000210420082007360200200441ff00712005411f7174200a72210a200541076a2105200721012004418001710d000b024020054120490d00410d21012004410f4b0da4010b200aad210d411d21070c9d020b410120036b2107200441026a21014100210541002109024002400240034002402005411f4d0d00410f21010c020b02400240200720016a4102460d002001450de701200320014f0d0120012003103c000b200241013a0018200241ec006a41013602002002420137025c200241a4e2c5003602582002412636023c2002200241386a3602682002200241186a360238200241286a200241d8006a103320022802282109200228022c210520022802302103410521010c030b200620016a417f6a2d0000210420082001360200200441ff00712005411f71742009722109200141016a2101200541076a21052004418001710d000b20054120490d0220044110490d02410d21010b0b2000200136020420004101360200200041106a20033602002000410c6a2005360200200041086a20093602000ca1020b2001417f6a2101410021054100210a034002402005411f4d0d00410f21010ca6010b20032001460da4012001417f460de3012003200141016a2207490d8f02200620016a2d0000210420082007360200200441ff00712005411f7174200a72210a200541076a2105200721012004418001710d000b024020054120490d00410d21012004410f4b0da5010b200aad210d411e21070c9c020b410120036b2107200441026a21014100210541002109024002400240034002402005411f4d0d00410f21010c020b02400240200720016a4102460d002001450de801200320014f0d0120012003103c000b200241013a0018200241ec006a41013602002002420137025c200241a4e2c5003602582002412636023c2002200241386a3602682002200241186a360238200241286a200241d8006a103320022802282109200228022c210520022802302103410521010c030b200620016a417f6a2d0000210420082001360200200441ff00712005411f71742009722109200141016a2101200541076a21052004418001710d000b20054120490d0220044110490d02410d21010b0b2000200136020420004101360200200041106a20033602002000410c6a2005360200200041086a20093602000ca0020b2001417f6a2101410021054100210a034002402005411f4d0d00410f21010ca7010b20032001460da5012001417f460de4012003200141016a2207490d8f02200620016a2d0000210420082007360200200441ff00712005411f7174200a72210a200541076a2105200721012004418001710d000b024020054120490d00410d21012004410f4b0da6010b200aad210d411f21070c9b020b410120036b2107200441026a21014100210541002109024002400240034002402005411f4d0d00410f21010c020b02400240200720016a4102460d002001450de901200320014f0d0120012003103c000b200241013a0018200241ec006a41013602002002420137025c200241a4e2c5003602582002412636023c2002200241386a3602682002200241186a360238200241286a200241d8006a103320022802282109200228022c210520022802302103410521010c030b200620016a417f6a2d0000210420082001360200200441ff00712005411f71742009722109200141016a2101200541076a21052004418001710d000b20054120490d0220044110490d02410d21010b0b2000200136020420004101360200200041106a20033602002000410c6a2005360200200041086a20093602000c9f020b2001417f6a2101410021054100210a034002402005411f4d0d00410f21010ca8010b20032001460da6012001417f460de5012003200141016a2207490d8f02200620016a2d0000210420082007360200200441ff00712005411f7174200a72210a200541076a2105200721012004418001710d000b41202107024020054120490d00410d21012004410f4b0da7010b200aad210d0c9a020b410120036b2107200441026a21014100210541002109024002400240034002402005411f4d0d00410f21010c020b02400240200720016a4102460d002001450dea01200320014f0d0120012003103c000b200241013a0018200241ec006a41013602002002420137025c200241a4e2c5003602582002412636023c2002200241386a3602682002200241186a360238200241286a200241d8006a103320022802282109200228022c210520022802302103410521010c030b200620016a417f6a2d0000210420082001360200200441ff00712005411f71742009722109200141016a2101200541076a21052004418001710d000b20054120490d0220044110490d02410d21010b0b2000200136020420004101360200200041106a20033602002000410c6a2005360200200041086a20093602000c9e020b2001417f6a2101410021054100210a034002402005411f4d0d00410f21010ca9010b20032001460da7012001417f460de6012003200141016a2207490d8f02200620016a2d0000210420082007360200200441ff00712005411f7174200a72210a200541076a2105200721012004418001710d000b024020054120490d00410d21012004410f4b0da8010b200aad210d412121070c99020b410120036b2107200441026a21014100210541002109024002400240034002402005411f4d0d00410f21010c020b02400240200720016a4102460d002001450deb01200320014f0d0120012003103c000b200241013a0018200241ec006a41013602002002420137025c200241a4e2c5003602582002412636023c2002200241386a3602682002200241186a360238200241286a200241d8006a103320022802282109200228022c210520022802302103410521010c030b200620016a417f6a2d0000210420082001360200200441ff00712005411f71742009722109200141016a2101200541076a21052004418001710d000b20054120490d0220044110490d02410d21010b0b2000200136020420004101360200200041106a20033602002000410c6a2005360200200041086a20093602000c9d020b2001417f6a2101410021054100210a034002402005411f4d0d00410f21010caa010b20032001460da8012001417f460de7012003200141016a2207490d8f02200620016a2d0000210420082007360200200441ff00712005411f7174200a72210a200541076a2105200721012004418001710d000b024020054120490d00410d21012004410f4b0da9010b200aad210d412221070c98020b410120036b2107200441026a21014100210541002109024002400240034002402005411f4d0d00410f21010c020b02400240200720016a4102460d002001450dec01200320014f0d0120012003103c000b200241013a0018200241ec006a41013602002002420137025c200241a4e2c5003602582002412636023c2002200241386a3602682002200241186a360238200241286a200241d8006a103320022802282109200228022c210520022802302103410521010c030b200620016a417f6a2d0000210420082001360200200441ff00712005411f71742009722109200141016a2101200541076a21052004418001710d000b20054120490d0220044110490d02410d21010b0b2000200136020420004101360200200041106a20033602002000410c6a2005360200200041086a20093602000c9c020b2001417f6a2101410021054100210a034002402005411f4d0d00410f21010cab010b20032001460da9012001417f460de8012003200141016a2207490d8f02200620016a2d0000210420082007360200200441ff00712005411f7174200a72210a200541076a2105200721012004418001710d000b024020054120490d00410d21012004410f4b0daa010b200aad210d412321070c97020b410120036b2107200441026a21014100210541002109024002400240034002402005411f4d0d00410f21010c020b02400240200720016a4102460d002001450ded01200320014f0d0120012003103c000b200241013a0018200241ec006a41013602002002420137025c200241a4e2c5003602582002412636023c2002200241386a3602682002200241186a360238200241286a200241d8006a103320022802282109200228022c210520022802302103410521010c030b200620016a417f6a2d0000210420082001360200200441ff00712005411f71742009722109200141016a2101200541076a21052004418001710d000b20054120490d0220044110490d02410d21010b0b2000200136020420004101360200200041106a20033602002000410c6a2005360200200041086a20093602000c9b020b2001417f6a2101410021054100210a034002402005411f4d0d00410f21010cac010b20032001460daa012001417f460de9012003200141016a2207490d8f02200620016a2d0000210420082007360200200441ff00712005411f7174200a72210a200541076a2105200721012004418001710d000b024020054120490d00410d21012004410f4b0dab010b200aad210d412421070c96020b410120036b2107200441026a21014100210541002109024002400240034002402005411f4d0d00410f21010c020b02400240200720016a4102460d002001450dee01200320014f0d0120012003103c000b200241013a0018200241ec006a41013602002002420137025c200241a4e2c5003602582002412636023c2002200241386a3602682002200241186a360238200241286a200241d8006a103320022802282109200228022c210520022802302103410521010c030b200620016a417f6a2d0000210420082001360200200441ff00712005411f71742009722109200141016a2101200541076a21052004418001710d000b20054120490d0220044110490d02410d21010b0b2000200136020420004101360200200041106a20033602002000410c6a2005360200200041086a20093602000c9a020b2001417f6a2101410021054100210a034002402005411f4d0d00410f21010cad010b20032001460dab012001417f460dea012003200141016a2207490d8f02200620016a2d0000210420082007360200200441ff00712005411f7174200a72210a200541076a2105200721012004418001710d000b024020054120490d00410d21012004410f4b0dac010b200aad210d412521070c95020b410120036b2107200441026a21014100210541002109024002400240034002402005411f4d0d00410f21010c020b02400240200720016a4102460d002001450def01200320014f0d0120012003103c000b200241013a0018200241ec006a41013602002002420137025c200241a4e2c5003602582002412636023c2002200241386a3602682002200241186a360238200241286a200241d8006a103320022802282109200228022c210520022802302103410521010c030b200620016a417f6a2d0000210420082001360200200441ff00712005411f71742009722109200141016a2101200541076a21052004418001710d000b20054120490d0220044110490d02410d21010b0b2000200136020420004101360200200041106a20033602002000410c6a2005360200200041086a20093602000c99020b2001417f6a2101410021054100210a034002402005411f4d0d00410f21010cae010b20032001460dac012001417f460deb012003200141016a2207490d8f02200620016a2d0000210420082007360200200441ff00712005411f7174200a72210a200541076a2105200721012004418001710d000b024020054120490d00410d21012004410f4b0dad010b200aad210d412621070c94020b410120036b2107200441026a21014100210541002109024002400240034002402005411f4d0d00410f21010c020b02400240200720016a4102460d002001450df001200320014f0d0120012003103c000b200241013a0018200241ec006a41013602002002420137025c200241a4e2c5003602582002412636023c2002200241386a3602682002200241186a360238200241286a200241d8006a103320022802282109200228022c210520022802302103410521010c030b200620016a417f6a2d0000210420082001360200200441ff00712005411f71742009722109200141016a2101200541076a21052004418001710d000b20054120490d0220044110490d02410d21010b0b2000200136020420004101360200200041106a20033602002000410c6a2005360200200041086a20093602000c98020b2001417f6a2101410021054100210a034002402005411f4d0d00410f21010caf010b20032001460dad012001417f460dec012003200141016a2207490d8f02200620016a2d0000210420082007360200200441ff00712005411f7174200a72210a200541076a2105200721012004418001710d000b024020054120490d00410d21012004410f4b0dae010b200aad210d412721070c93020b410120036b2107200441026a21014100210541002109024002400240034002402005411f4d0d00410f21010c020b02400240200720016a4102460d002001450df101200320014f0d0120012003103c000b200241013a0018200241ec006a41013602002002420137025c200241a4e2c5003602582002412636023c2002200241386a3602682002200241186a360238200241286a200241d8006a103320022802282109200228022c210520022802302103410521010c030b200620016a417f6a2d0000210420082001360200200441ff00712005411f71742009722109200141016a2101200541076a21052004418001710d000b20054120490d0220044110490d02410d21010b0b2000200136020420004101360200200041106a20033602002000410c6a2005360200200041086a20093602000c97020b2001417f6a2101410021054100210a034002402005411f4d0d00410f21010cb0010b20032001460dae012001417f460ded012003200141016a2207490d8f02200620016a2d0000210420082007360200200441ff00712005411f7174200a72210a200541076a2105200721012004418001710d000b024020054120490d00410d21012004410f4b0daf010b200aad210d412821070c92020b410120036b2107200441026a21014100210541002109024002400240034002402005411f4d0d00410f21010c020b02400240200720016a4102460d002001450df201200320014f0d0120012003103c000b200241013a0018200241ec006a41013602002002420137025c200241a4e2c5003602582002412636023c2002200241386a3602682002200241186a360238200241286a200241d8006a103320022802282109200228022c210520022802302103410521010c030b200620016a417f6a2d0000210420082001360200200441ff00712005411f71742009722109200141016a2101200541076a21052004418001710d000b20054120490d0220044110490d02410d21010b0b2000200136020420004101360200200041106a20033602002000410c6a2005360200200041086a20093602000c96020b2001417f6a2101410021054100210a034002402005411f4d0d00410f21010cb1010b20032001460daf012001417f460dee012003200141016a2207490d8f02200620016a2d0000210420082007360200200441ff00712005411f7174200a72210a200541076a2105200721012004418001710d000b024020054120490d00410d21012004410f4b0db0010b200aad210d412921070c91020b410120036b2107200441026a21014100210541002109024002400240034002402005411f4d0d00410f21010c020b02400240200720016a4102460d002001450df301200320014f0d0120012003103c000b200241013a0018200241ec006a41013602002002420137025c200241a4e2c5003602582002412636023c2002200241386a3602682002200241186a360238200241286a200241d8006a103320022802282109200228022c210520022802302103410521010c030b200620016a417f6a2d0000210420082001360200200441ff00712005411f71742009722109200141016a2101200541076a21052004418001710d000b20054120490d0220044110490d02410d21010b0b2000200136020420004101360200200041106a20033602002000410c6a2005360200200041086a20093602000c95020b2001417f6a2101410021054100210a034002402005411f4d0d00410f21010cb2010b20032001460db0012001417f460def012003200141016a2207490d8f02200620016a2d0000210420082007360200200441ff00712005411f7174200a72210a200541076a2105200721012004418001710d000b024020054120490d00410d21012004410f4b0db1010b200aad210d412a21070c90020b0240024020032005460d00200441026a21012005417f460df001200320014f0d0120012003103c000b200241013a0048200241ec006a41013602002002420137025c200241a4e2c5003602582002412636023c2002200241386a3602682002200241c8006a360238200241086a200241d8006a1033200241336a200241106a2802003600002002200229030837002b2002200229002837031820022002412f6a29000037001f200041053a0004200020022903183700052000410c6a200229001f370000200041013602000c94020b200620056a2d0000210920082001360200024020090d00412b21074100210a0c90020b200041153a000420004101360200200041056a20093a00000c93020b0240024020032005460d00200441026a21012005417f460df001200320014f0d0120012003103c000b200241013a0048200241ec006a41013602002002420137025c200241a4e2c5003602582002412636023c2002200241386a3602682002200241c8006a360238200241086a200241d8006a1033200241336a200241106a2802003600002002200229030837002b2002200229002837031820022002412f6a29000037001f200041053a0004200020022903183700052000410c6a200229001f370000200041013602000c93020b200620056a2d0000210920082001360200024020090d00412c21074100210a0c8f020b200041153a000420004101360200200041056a20093a00000c92020b41002101410021090240024002400340410d210a2001411f4b0d010240024020032005460d002005417f460df4012003200541016a22074f0d01200541016a2003103c000b200241013a0018200241ec006a41013602002002420137025c200241a4e2c5003602582002412636023c2002200241386a3602682002200241186a360238200241286a200241d8006a10334105210a0c020b200620056a2c0000210420082007360200200441ff00712001411f71742009722109200141076a21012007210520044100480d000b200441c00071210502402001411f4b0d0020050d020b0240024020014120490d0020050d010b200441ff01714108490d0320014120490d032005450d010c030b20044180017241ff017141f7014b0d020b2000200a36020420004101360200200041086a2002290228370200200041106a200241286a41086a2802003602000c93020b2009417f2001411f71747221090b412d21070c8d020b4200210d4100210102400240024002400340410e21072001413f4b0d010240024020032005460d002005417f460df5012003200541016a22094f0d01200541016a2003103c000b200241013a0008200241ec006a41013602002002420137025c200241a4e2c5003602582002412636023c2002200241386a3602682002200241086a360238200241286a200241d8006a10332002290328210d20022802302101410521070c030b200620056a2d0000210420082009360200200441ff0071220aad2001413f71ad86200d84210d200141076a210120092105200441187441187522094100480d000b200941c00071210502402001413f4b0d0020050d030b02400240200141c000490d0020050d010b200141c000490d0420090d010c040b200a41ff00460d030b0b200020073a0004200020022f00183b000520004101360200200041106a2001360200200041086a200d370200200041076a2002411a6a2d00003a00000c92020b200d427f2001413f71ad8684210d0b412e21070c8c020b02400240200320056b4104490d00200441056a21012005417b4b0df001200320014f0d0120012003103c000b200241013a0018200241ec006a41013602002002420137025c200241a4e2c5003602582002412636023c2002200241386a3602682002200241186a360238200241286a200241d8006a103320004281808080d000370300200041086a2002290228370200200041106a200241286a41086a2802003602000c90020b200620056a280000210920082001360200412f21070c8b020b02400240200320056b4108490d00200441096a2101200541774b0df001200320014f0d0120012003103c000b200241013a0018200241ec006a41013602002002420137025c200241a4e2c5003602582002412636023c2002200241386a3602682002200241186a360238200241286a200241d8006a10332002290328210d200041106a2002280230360200200041086a200d37020020004281808080d0003703000c8f020b200620056a290000210d20082001360200413021070c8a020b413121070c89020b413221070c88020b413321070c87020b413421070c86020b413521070c85020b413621070c84020b413721070c83020b413821070c82020b413921070c81020b413a21070c80020b413b21070cff010b413c21070cfe010b413d21070cfd010b413e21070cfc010b413f21070cfb010b41c00021070cfa010b41c10021070cf9010b41c20021070cf8010b41c30021070cf7010b41c40021070cf6010b41c50021070cf5010b41c60021070cf4010b41c70021070cf3010b41c80021070cf2010b41c90021070cf1010b41ca0021070cf0010b41cb0021070cef010b41cc0021070cee010b41cd0021070ced010b41ce0021070cec010b41cf0021070ceb010b41d00021070cea010b41d10021070ce9010b41d20021070ce8010b41d30021070ce7010b41d40021070ce6010b41d50021070ce5010b41d60021070ce4010b41d70021070ce3010b41d80021070ce2010b41d90021070ce1010b41da0021070ce0010b41db0021070cdf010b41dc0021070cde010b41dd0021070cdd010b41de0021070cdc010b41df0021070cdb010b41e00021070cda010b41e10021070cd9010b41e20021070cd8010b41e30021070cd7010b41e40021070cd6010b41e50021070cd5010b41e60021070cd4010b41e70021070cd3010b41e80021070cd2010b41e90021070cd1010b41ea0021070cd0010b41eb0021070ccf010b41ec0021070cce010b41ed0021070ccd010b41ee0021070ccc010b41ef0021070ccb010b41f00021070cca010b41f10021070cc9010b41f20021070cc8010b41f30021070cc7010b41f40021070cc6010b41f50021070cc5010b41f60021070cc4010b41f70021070cc3010b41f80021070cc2010b41f90021070cc1010b41fa0021070cc0010b41fb0021070cbf010b41fc0021070cbe010b41fd0021070cbd010b41fe0021070cbc010b41ff0021070cbb010b41800121070cba010b41810121070cb9010b41820121070cb8010b41830121070cb7010b41840121070cb6010b41850121070cb5010b41860121070cb4010b41870121070cb3010b41880121070cb2010b41890121070cb1010b418a0121070cb0010b418b0121070caf010b418c0121070cae010b418d0121070cad010b418e0121070cac010b418f0121070cab010b41900121070caa010b41910121070ca9010b41920121070ca8010b41930121070ca7010b41940121070ca6010b41950121070ca5010b41960121070ca4010b41970121070ca3010b41980121070ca2010b41990121070ca1010b419a0121070ca0010b419b0121070c9f010b419c0121070c9e010b419d0121070c9d010b419e0121070c9c010b419f0121070c9b010b41a00121070c9a010b41a10121070c99010b41a20121070c98010b41a30121070c97010b41a40121070c96010b41a50121070c95010b41a60121070c94010b41a70121070c93010b41a80121070c92010b41a90121070c91010b41aa0121070c90010b41ab0121070c8f010b200041013602002000200241d8006a41047222012902003702042000410c6a200141086a2902003702000c92010b2002280260102a0c8c010b200241013a0018200241ec006a41013602002002420137025c200241a4e2c5003602582002412636023c2002200241386a3602682002200241186a360238200241286a200241d8006a1033410521010b2000200136020420004101360200200041086a2002290228370200200041106a200241286a41086a2802003602000c8f010b200241013a0018200241ec006a41013602002002420137025c200241a4e2c5003602582002412636023c2002200241386a3602682002200241186a360238200241286a200241d8006a1033410521010b2000200136020420004101360200200041086a2002290228370200200041106a200241286a41086a2802003602000c8d010b200241013a0018200241ec006a41013602002002420137025c200241a4e2c5003602582002412636023c2002200241386a3602682002200241186a360238200241286a200241d8006a1033410521010b2000200136020420004101360200200041086a2002290228370200200041106a200241286a41086a2802003602000c8b010b200241013a0018200241ec006a41013602002002420137025c200241a4e2c5003602582002412636023c2002200241386a3602682002200241186a360238200241286a200241d8006a1033410521010b2000200136020420004101360200200041086a2002290228370200200041106a200241286a41086a2802003602000c89010b200241013a0018200241ec006a41013602002002420137025c200241a4e2c5003602582002412636023c2002200241386a3602682002200241186a360238200241286a200241d8006a1033410521010b2000200136020420004101360200200041086a2002290228370200200041106a200241286a41086a2802003602000c87010b200241013a0018200241ec006a41013602002002420137025c200241a4e2c5003602582002412636023c2002200241386a3602682002200241186a360238200241286a200241d8006a1033410521010b2000200136020420004101360200200041086a2002290228370200200041106a200241286a41086a2802003602000c85010b200241013a0018200241ec006a41013602002002420137025c200241a4e2c5003602582002412636023c2002200241386a3602682002200241186a360238200241286a200241d8006a1033410521010b2000200136020420004101360200200041086a2002290228370200200041106a200241286a41086a2802003602000c83010b200241013a0018200241ec006a41013602002002420137025c200241a4e2c5003602582002412636023c2002200241386a3602682002200241186a360238200241286a200241d8006a1033410521010b2000200136020420004101360200200041086a2002290228370200200041106a200241286a41086a2802003602000c81010b200241013a0018200241ec006a41013602002002420137025c200241a4e2c5003602582002412636023c2002200241386a3602682002200241186a360238200241286a200241d8006a1033410521010b2000200136020420004101360200200041086a2002290228370200200041106a200241286a41086a2802003602000c7f0b200241013a0018200241ec006a41013602002002420137025c200241a4e2c5003602582002412636023c2002200241386a3602682002200241186a360238200241286a200241d8006a1033410521010b2000200136020420004101360200200041086a2002290228370200200041106a200241286a41086a2802003602000c7d0b200241013a0018200241ec006a41013602002002420137025c200241a4e2c5003602582002412636023c2002200241386a3602682002200241186a360238200241286a200241d8006a1033410521010b2000200136020420004101360200200041086a2002290228370200200041106a200241286a41086a2802003602000c7b0b200241013a0018200241ec006a41013602002002420137025c200241a4e2c5003602582002412636023c2002200241386a3602682002200241186a360238200241286a200241d8006a1033410521010b2000200136020420004101360200200041086a2002290228370200200041106a200241286a41086a2802003602000c790b200241013a0018200241ec006a41013602002002420137025c200241a4e2c5003602582002412636023c2002200241386a3602682002200241186a360238200241286a200241d8006a1033410521010b2000200136020420004101360200200041086a2002290228370200200041106a200241286a41086a2802003602000c770b200241013a0018200241ec006a41013602002002420137025c200241a4e2c5003602582002412636023c2002200241386a3602682002200241186a360238200241286a200241d8006a1033410521010b2000200136020420004101360200200041086a2002290228370200200041106a200241286a41086a2802003602000c750b200241013a0018200241ec006a41013602002002420137025c200241a4e2c5003602582002412636023c2002200241386a3602682002200241186a360238200241286a200241d8006a1033410521010b2000200136020420004101360200200041086a2002290228370200200041106a200241286a41086a2802003602000c730b200241013a0018200241ec006a41013602002002420137025c200241a4e2c5003602582002412636023c2002200241386a3602682002200241186a360238200241286a200241d8006a1033410521010b2000200136020420004101360200200041086a2002290228370200200041106a200241286a41086a2802003602000c710b200241013a0018200241ec006a41013602002002420137025c200241a4e2c5003602582002412636023c2002200241386a3602682002200241186a360238200241286a200241d8006a1033410521010b2000200136020420004101360200200041086a2002290228370200200041106a200241286a41086a2802003602000c6f0b200241013a0018200241ec006a41013602002002420137025c200241a4e2c5003602582002412636023c2002200241386a3602682002200241186a360238200241286a200241d8006a1033410521010b2000200136020420004101360200200041086a2002290228370200200041106a200241286a41086a2802003602000c6d0b200241013a0018200241ec006a41013602002002420137025c200241a4e2c5003602582002412636023c2002200241386a3602682002200241186a360238200241286a200241d8006a1033410521010b2000200136020420004101360200200041086a2002290228370200200041106a200241286a41086a2802003602000c6b0b200241013a0018200241ec006a41013602002002420137025c200241a4e2c5003602582002412636023c2002200241386a3602682002200241186a360238200241286a200241d8006a1033410521010b2000200136020420004101360200200041086a2002290228370200200041106a200241286a41086a2802003602000c690b200241013a0018200241ec006a41013602002002420137025c200241a4e2c5003602582002412636023c2002200241386a3602682002200241186a360238200241286a200241d8006a1033410521010b2000200136020420004101360200200041086a2002290228370200200041106a200241286a41086a2802003602000c670b200241013a0018200241ec006a41013602002002420137025c200241a4e2c5003602582002412636023c2002200241386a3602682002200241186a360238200241286a200241d8006a1033410521010b2000200136020420004101360200200041086a2002290228370200200041106a200241286a41086a2802003602000c650b200241013a0018200241ec006a41013602002002420137025c200241a4e2c5003602582002412636023c2002200241386a3602682002200241186a360238200241286a200241d8006a1033410521010b2000200136020420004101360200200041086a2002290228370200200041106a200241286a41086a2802003602000c630b417f20051044000b417f20091044000b417f20091044000b417f20091044000b417f200541016a1044000b417f200541016a1044000b200341041037000b1031000b417f200541016a1044000b417f200541016a1044000b417f20011044000b417f200541016a1044000b417f200541016a1044000b417f200541016a1044000b417f200541016a1044000b417f200541016a1044000b417f20011044000b417f200141016a1044000b417f20011044000b417f200141016a1044000b417f20011044000b417f200141016a1044000b417f20011044000b417f200141016a1044000b417f20011044000b417f200141016a1044000b417f20011044000b417f200141016a1044000b417f20011044000b417f200141016a1044000b417f20011044000b417f200141016a1044000b417f20011044000b417f200141016a1044000b417f20011044000b417f200141016a1044000b417f20011044000b417f200141016a1044000b417f20011044000b417f200141016a1044000b417f20011044000b417f200141016a1044000b417f20011044000b417f200141016a1044000b417f20011044000b417f200141016a1044000b417f20011044000b417f200141016a1044000b417f20011044000b417f200141016a1044000b417f20011044000b417f200141016a1044000b417f20011044000b417f200141016a1044000b417f20011044000b417f200141016a1044000b417f20011044000b417f200141016a1044000b417f20011044000b417f200141016a1044000b417f20011044000b417f200141016a1044000b417f20011044000b417f20011044000b417f200541016a1044000b417f200541016a1044000b200520011044000b200520011044000b20092003103c000b20092003103c000b20092003103c000b200141016a2003103c000b200141016a2003103c000b200141016a2003103c000b200141016a2003103c000b200141016a2003103c000b200141016a2003103c000b200141016a2003103c000b200141016a2003103c000b200141016a2003103c000b200141016a2003103c000b200141016a2003103c000b200141016a2003103c000b200141016a2003103c000b200141016a2003103c000b200141016a2003103c000b200141016a2003103c000b200141016a2003103c000b200141016a2003103c000b200141016a2003103c000b200141016a2003103c000b200141016a2003103c000b200141016a2003103c000b200141016a2003103c000b02400240024002400240024020042006460d0020042006490d01024020060d00024020040d004104210a0c020b200a102a4104210a0c010b200a200441027420064102742209102c220a450d020b4100210941002104034002402009411f4d0d00410f21010c0a0b20012802082207200128020c2205460d08200541016a22032005490d0320072003490d04200128020020056a2d0000210520082003360200200541ff00712009411f71742004722104200941076a21092005418001710d000b20094120490d04410d21012005410f4b0d080c040b41dcfdc5001032000b200941041037000b417f20031044000b20032007103c000b410c10282209450d0120092004360208200920063602042009200a360200410921070b20004100360200200041106a200d3703002000410c6a2009360200200041096a200a3a0000200041086a20073a00000c030b410c41041037000b200241013a0018200241ec006a41013602002002420137025c200241a4e2c5003602582002412636023c2002200241386a3602682002200241186a360238200241286a200241d8006a1033410521010b2000200136020420004101360200200041086a2002290228370200200041106a200241286a41086a280200360200200641ffffffff0371450d00200a102a0b200241f0006a24000bd60703067f017e067f230041d0006b220224004100210341002104024002400240024002400240024002400240024002400240034002402003411f4d0d00410f21030c020b0240024020012802082205200128020c2206460d00200641016a22072006490d05200520074f0d0120072005103c000b200241013a0027200241cc006a41013602002002420137023c200241a4e2c5003602382002412636021c2002200241186a3602482002200241276a360218200241286a200241386a1033410521030c020b200128020020066a2d000021062001200736020c200641ff00712003411f71742004722104200341076a21032006418001710d000b20034120490d01410d210320064110490d010b200241086a41086a200241286a41086a280200220136020020022002290228220837030820002003360204200041086a2008370200200041106a2001360200200041013602000c0a0b20024100360210200242043703082004450d0841042109410021034100210a03402003210b200a220c41016a210a410021034100210503402003411f4b0d04024002402001280208220d200128020c2206460d00200641016a22072006490d05200d20074f0d012007200d103c000b2002200b36020c2002200c360210200241013a0027200241cc006a41013602002002420137023c200241a4e2c5003602382002412636021c2002200241186a3602482002200241276a360218200241286a200241386a103320022802282103200228022c2106200228023021074100210e410521010c090b200128020020066a2d000021062001200736020c200641ff00712003411f71742005722105200341076a21032006418001710d000b024020034120490d002006410f4d0d002002200b36020c2002200c360210410d21010c070b02400240200c200b460d00200b2103200c210b0c010b200b41016a2203200b490d06200b41017422062003200620034b1b220341ffffffff03712003470d06200341027422064100480d0602400240200b0d002006102821090c010b2009200b4102742006102c21090b2009450d05200220093602080b2005410876210e2009200b4102746a2005360200200a2004460d080c000b0b417f20071044000b417f20071044000b2002200b36020c2002200c360210410f21010c020b200641041037000b1031000b0b20004101360200200041106a20073602002000410c6a2006360200200041086a20033602002000200e410874200172360204200b450d022009102a0c020b2002200336020c2002200a3602100b20002002290308370204200041003602002000410c6a200241106a2802003602000b200241d0006a24000bcbd60202097f017e230041106b22032400024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024020012d00000eac01000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f80018101820183018401850186018701880189018a018b018c018d018e018f0190019101920193019401950196019701980199019a019b019c019d019e019f01a001a101a201a301a401a501a601a701a801a901aa01ab01000b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490df701200441017422062005200620054b1b22064100480df7010240024020040d002006102821050c010b200228020420042006102c21050b2005450dad0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41003a00000cab010b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490df601200441017422062005200620054b1b22064100480df6010240024020040d002006102821050c010b200228020420042006102c21050b2005450dad0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41013a00000caa010b200241046a210620012d0001210702400240200241086a2802002002410c6a2802002204460d00200628020021050c010b200441016a22052004490df501200441017422082005200820054b1b22084100480df5010240024020040d002008102821050c010b200628020020042008102c21050b2005450dad0120022005360204200241086a20083602002002410c6a28020021040b2002410c6a2208200441016a360200200520046a41023a000002400240200241086a28020020082802002204460d00200628020021050c010b200441016a22052004490df501200441017422082005200820054b1b22084100480df5010240024020040d002008102821050c010b200628020020042008102c21050b2005450dae0120022005360204200241086a20083602002002410c6a28020021040b2002410c6a200441016a360200200520046a42c0818386fcdffffe7c2007410473ad42078342038688a7413f7141c000723a00000ca9010b200241046a210620012d0001210702400240200241086a2802002002410c6a2802002204460d00200628020021050c010b200441016a22052004490df401200441017422082005200820054b1b22084100480df4010240024020040d002008102821050c010b200628020020042008102c21050b2005450dae0120022005360204200241086a20083602002002410c6a28020021040b2002410c6a2208200441016a360200200520046a41033a000002400240200241086a28020020082802002204460d00200628020021050c010b200441016a22052004490df401200441017422082005200820054b1b22084100480df4010240024020040d002008102821050c010b200628020020042008102c21050b2005450daf0120022005360204200241086a20083602002002410c6a28020021040b2002410c6a200441016a360200200520046a42c0818386fcdffffe7c2007410473ad42078342038688a7413f7141c000723a00000ca8010b200241046a210620012d0001210702400240200241086a2802002002410c6a2802002204460d00200628020021050c010b200441016a22052004490df301200441017422082005200820054b1b22084100480df3010240024020040d002008102821050c010b200628020020042008102c21050b2005450daf0120022005360204200241086a20083602002002410c6a28020021040b2002410c6a2208200441016a360200200520046a41043a000002400240200241086a28020020082802002204460d00200628020021050c010b200441016a22052004490df301200441017422082005200820054b1b22084100480df3010240024020040d002008102821050c010b200628020020042008102c21050b2005450db00120022005360204200241086a20083602002002410c6a28020021040b2002410c6a200441016a360200200520046a42c0818386fcdffffe7c2007410473ad42078342038688a7413f7141c000723a00000ca7010b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490df201200441017422062005200620054b1b22064100480df2010240024020040d002006102821050c010b200228020420042006102c21050b2005450db00120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41053a00000ca6010b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490df101200441017422062005200620054b1b22064100480df1010240024020040d002006102821050c010b200228020420042006102c21050b2005450db00120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a410b3a00000ca5010b200241046a2109200141046a280200210502400240200241086a2802002002410c6a2802002204460d00200928020021060c010b200441016a22062004490df001200441017422072006200720064b1b22074100480df0010240024020040d002007102821060c010b200928020020042007102c21060b2006450db00120022006360204200241086a20073602002002410c6a28020021040b2002410c6a2207200441016a360200200620046a410c3a0000200241086a2108034002400240200828020020072802002204460d00200928020021060c010b200441016a22062004490df1012004410174220a2006200a20064b1b220a4100480df1010240024020040d00200a102821060c010b20092802002004200a102c21060b2006450db201200220063602042008200a360200200728020021040b2007200441016a360200200620046a200541807f72200541ff0071200541077622041b3a00002004210520040d000ca5010b0b200241046a2109200141046a280200210502400240200241086a2802002002410c6a2802002204460d00200928020021060c010b200441016a22062004490def01200441017422072006200720064b1b22074100480def010240024020040d002007102821060c010b200928020020042007102c21060b2006450db10120022006360204200241086a20073602002002410c6a28020021040b2002410c6a2207200441016a360200200620046a410d3a0000200241086a2108034002400240200828020020072802002204460d00200928020021060c010b200441016a22062004490df0012004410174220a2006200a20064b1b220a4100480df0010240024020040d00200a102821060c010b20092802002004200a102c21060b2006450db301200220063602042008200a360200200728020021040b2007200441016a360200200620046a200541807f72200541ff0071200541077622041b3a00002004210520040d000ca4010b0b200241046a210902400240200241086a2802002002410c6a2802002204460d00200928020021050c010b200441016a22052004490dee01200441017422062005200620054b1b22064100480dee010240024020040d002006102821050c010b200928020020042006102c21050b2005450db20120022005360204200241086a20063602002002410c6a28020021040b2002410c6a2207200441016a360200200520046a410e3a0000200320012802042204280204220520042802002204200420054102746a200210ea042003210420032d0000411f470d930320012802042802082105200241086a2108034002400240200828020020072802002204460d00200928020021060c010b200441016a22062004490def012004410174220a2006200a20064b1b220a4100480def010240024020040d00200a102821060c010b20092802002004200a102c21060b2006450db401200220063602042008200a360200200728020021040b2007200441016a360200200620046a200541807f72200541ff0071200541077622041b3a00002004210520040d000ca3010b0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490ded01200441017422062005200620054b1b22064100480ded010240024020040d002006102821050c010b200228020420042006102c21050b2005450db30120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a410f3a00000ca1010b200241046a2109200141046a280200210502400240200241086a2802002002410c6a2802002204460d00200928020021060c010b200441016a22062004490dec01200441017422072006200720064b1b22074100480dec010240024020040d002007102821060c010b200928020020042007102c21060b2006450db30120022006360204200241086a20073602002002410c6a28020021040b2002410c6a2207200441016a360200200620046a41103a0000200241086a2108034002400240200828020020072802002204460d00200928020021060c010b200441016a22062004490ded012004410174220a2006200a20064b1b220a4100480ded010240024020040d00200a102821060c010b20092802002004200a102c21060b2006450db501200220063602042008200a360200200728020021040b2007200441016a360200200620046a200541807f72200541ff0071200541077622041b3a00002004210520040d000ca1010b0b200241046a2109200141046a280200210520012d0001210b02400240200241086a2802002002410c6a2802002204460d00200928020021060c010b200441016a22062004490deb01200441017422072006200720064b1b22074100480deb010240024020040d002007102821060c010b200928020020042007102c21060b2006450db40120022006360204200241086a20073602002002410c6a28020021040b2002410c6a2207200441016a360200200620046a41113a0000200241086a2108034002400240200828020020072802002204460d00200928020021060c010b200441016a22062004490dec012004410174220a2006200a20064b1b220a4100480dec010240024020040d00200a102821060c010b20092802002004200a102c21060b2006450db601200220063602042008200a360200200728020021040b2007200441016a360200200620046a200541807f72200541ff0071200541077622041b3a00002004210520040d000b02400240200241086a2802002002410c6a2802002204460d00200928020021050c010b200441016a22052004490deb01200441017422062005200620054b1b22064100480deb010240024020040d002006102821050c010b200928020020042006102c21050b2005450db60120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a200b3a00000c9f010b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490dea01200441017422062005200620054b1b22064100480dea010240024020040d002006102821050c010b200228020420042006102c21050b2005450db60120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a411a3a00000c9e010b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490de901200441017422062005200620054b1b22064100480de9010240024020040d002006102821050c010b200228020420042006102c21050b2005450db60120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a411b3a00000c9d010b200241046a2109200141046a280200210502400240200241086a2802002002410c6a2802002204460d00200928020021060c010b200441016a22062004490de801200441017422072006200720064b1b22074100480de8010240024020040d002007102821060c010b200928020020042007102c21060b2006450db60120022006360204200241086a20073602002002410c6a28020021040b2002410c6a2207200441016a360200200620046a41203a0000200241086a2108034002400240200828020020072802002204460d00200928020021060c010b200441016a22062004490de9012004410174220a2006200a20064b1b220a4100480de9010240024020040d00200a102821060c010b20092802002004200a102c21060b2006450db801200220063602042008200a360200200728020021040b2007200441016a360200200620046a200541807f72200541ff0071200541077622041b3a00002004210520040d000c9d010b0b200241046a2109200141046a280200210502400240200241086a2802002002410c6a2802002204460d00200928020021060c010b200441016a22062004490de701200441017422072006200720064b1b22074100480de7010240024020040d002007102821060c010b200928020020042007102c21060b2006450db70120022006360204200241086a20073602002002410c6a28020021040b2002410c6a2207200441016a360200200620046a41213a0000200241086a2108034002400240200828020020072802002204460d00200928020021060c010b200441016a22062004490de8012004410174220a2006200a20064b1b220a4100480de8010240024020040d00200a102821060c010b20092802002004200a102c21060b2006450db901200220063602042008200a360200200728020021040b2007200441016a360200200620046a200541807f72200541ff0071200541077622041b3a00002004210520040d000c9c010b0b200241046a2109200141046a280200210502400240200241086a2802002002410c6a2802002204460d00200928020021060c010b200441016a22062004490de601200441017422072006200720064b1b22074100480de6010240024020040d002007102821060c010b200928020020042007102c21060b2006450db80120022006360204200241086a20073602002002410c6a28020021040b2002410c6a2207200441016a360200200620046a41223a0000200241086a2108034002400240200828020020072802002204460d00200928020021060c010b200441016a22062004490de7012004410174220a2006200a20064b1b220a4100480de7010240024020040d00200a102821060c010b20092802002004200a102c21060b2006450dba01200220063602042008200a360200200728020021040b2007200441016a360200200620046a200541807f72200541ff0071200541077622041b3a00002004210520040d000c9b010b0b200241046a2109200141046a280200210502400240200241086a2802002002410c6a2802002204460d00200928020021060c010b200441016a22062004490de501200441017422072006200720064b1b22074100480de5010240024020040d002007102821060c010b200928020020042007102c21060b2006450db90120022006360204200241086a20073602002002410c6a28020021040b2002410c6a2207200441016a360200200620046a41233a0000200241086a2108034002400240200828020020072802002204460d00200928020021060c010b200441016a22062004490de6012004410174220a2006200a20064b1b220a4100480de6010240024020040d00200a102821060c010b20092802002004200a102c21060b2006450dbb01200220063602042008200a360200200728020021040b2007200441016a360200200620046a200541807f72200541ff0071200541077622041b3a00002004210520040d000c9a010b0b200241046a2109200141046a280200210502400240200241086a2802002002410c6a2802002204460d00200928020021060c010b200441016a22062004490de401200441017422072006200720064b1b22074100480de4010240024020040d002007102821060c010b200928020020042007102c21060b2006450dba0120022006360204200241086a20073602002002410c6a28020021040b2002410c6a2207200441016a360200200620046a41243a0000200241086a2108034002400240200828020020072802002204460d00200928020021060c010b200441016a22062004490de5012004410174220a2006200a20064b1b220a4100480de5010240024020040d00200a102821060c010b20092802002004200a102c21060b2006450dbc01200220063602042008200a360200200728020021040b2007200441016a360200200620046a200541807f72200541ff0071200541077622041b3a00002004210520040d000c99010b0b200241046a210a200141086a2802002105200141046a280200210602400240200241086a2802002002410c6a2802002204460d00200a28020021070c010b200441016a22072004490de301200441017422082007200820074b1b22084100480de3010240024020040d002008102821070c010b200a28020020042008102c21070b2007450dbb0120022007360204200241086a20083602002002410c6a28020021040b2002410c6a2208200441016a360200200720046a41283a0000200241086a2109034002400240200928020020082802002204460d00200a28020021070c010b200441016a22072004490de4012004410174220b2007200b20074b1b220b4100480de4010240024020040d00200b102821070c010b200a2802002004200b102c21070b2007450dbd01200220073602042009200b360200200828020021040b2008200441016a360200200720046a200641807f72200641ff0071200641077622041b3a00002004210620040d000b2002410c6a2107200241086a2108034002400240200828020020072802002204460d00200a28020021060c010b200441016a22062004490de401200441017422092006200920064b1b22094100480de4010240024020040d002009102821060c010b200a28020020042009102c21060b2006450dbe012002200636020420082009360200200728020021040b2007200441016a360200200620046a200541807f72200541ff0071200541077622041b3a00002004210520040d000c98010b0b200241046a210a200141086a2802002105200141046a280200210602400240200241086a2802002002410c6a2802002204460d00200a28020021070c010b200441016a22072004490de201200441017422082007200820074b1b22084100480de2010240024020040d002008102821070c010b200a28020020042008102c21070b2007450dbd0120022007360204200241086a20083602002002410c6a28020021040b2002410c6a2208200441016a360200200720046a41293a0000200241086a2109034002400240200928020020082802002204460d00200a28020021070c010b200441016a22072004490de3012004410174220b2007200b20074b1b220b4100480de3010240024020040d00200b102821070c010b200a2802002004200b102c21070b2007450dbf01200220073602042009200b360200200828020021040b2008200441016a360200200720046a200641807f72200641ff0071200641077622041b3a00002004210620040d000b2002410c6a2107200241086a2108034002400240200828020020072802002204460d00200a28020021060c010b200441016a22062004490de301200441017422092006200920064b1b22094100480de3010240024020040d002009102821060c010b200a28020020042009102c21060b2006450dc0012002200636020420082009360200200728020021040b2007200441016a360200200620046a200541807f72200541ff0071200541077622041b3a00002004210520040d000c97010b0b200241046a210a200141086a2802002105200141046a280200210602400240200241086a2802002002410c6a2802002204460d00200a28020021070c010b200441016a22072004490de101200441017422082007200820074b1b22084100480de1010240024020040d002008102821070c010b200a28020020042008102c21070b2007450dbf0120022007360204200241086a20083602002002410c6a28020021040b2002410c6a2208200441016a360200200720046a412a3a0000200241086a2109034002400240200928020020082802002204460d00200a28020021070c010b200441016a22072004490de2012004410174220b2007200b20074b1b220b4100480de2010240024020040d00200b102821070c010b200a2802002004200b102c21070b2007450dc101200220073602042009200b360200200828020021040b2008200441016a360200200720046a200641807f72200641ff0071200641077622041b3a00002004210620040d000b2002410c6a2107200241086a2108034002400240200828020020072802002204460d00200a28020021060c010b200441016a22062004490de201200441017422092006200920064b1b22094100480de2010240024020040d002009102821060c010b200a28020020042009102c21060b2006450dc2012002200636020420082009360200200728020021040b2007200441016a360200200620046a200541807f72200541ff0071200541077622041b3a00002004210520040d000c96010b0b200241046a210a200141086a2802002105200141046a280200210602400240200241086a2802002002410c6a2802002204460d00200a28020021070c010b200441016a22072004490de001200441017422082007200820074b1b22084100480de0010240024020040d002008102821070c010b200a28020020042008102c21070b2007450dc10120022007360204200241086a20083602002002410c6a28020021040b2002410c6a2208200441016a360200200720046a412b3a0000200241086a2109034002400240200928020020082802002204460d00200a28020021070c010b200441016a22072004490de1012004410174220b2007200b20074b1b220b4100480de1010240024020040d00200b102821070c010b200a2802002004200b102c21070b2007450dc301200220073602042009200b360200200828020021040b2008200441016a360200200720046a200641807f72200641ff0071200641077622041b3a00002004210620040d000b2002410c6a2107200241086a2108034002400240200828020020072802002204460d00200a28020021060c010b200441016a22062004490de101200441017422092006200920064b1b22094100480de1010240024020040d002009102821060c010b200a28020020042009102c21060b2006450dc4012002200636020420082009360200200728020021040b2007200441016a360200200620046a200541807f72200541ff0071200541077622041b3a00002004210520040d000c95010b0b200241046a210a200141086a2802002105200141046a280200210602400240200241086a2802002002410c6a2802002204460d00200a28020021070c010b200441016a22072004490ddf01200441017422082007200820074b1b22084100480ddf010240024020040d002008102821070c010b200a28020020042008102c21070b2007450dc30120022007360204200241086a20083602002002410c6a28020021040b2002410c6a2208200441016a360200200720046a412c3a0000200241086a2109034002400240200928020020082802002204460d00200a28020021070c010b200441016a22072004490de0012004410174220b2007200b20074b1b220b4100480de0010240024020040d00200b102821070c010b200a2802002004200b102c21070b2007450dc501200220073602042009200b360200200828020021040b2008200441016a360200200720046a200641807f72200641ff0071200641077622041b3a00002004210620040d000b2002410c6a2107200241086a2108034002400240200828020020072802002204460d00200a28020021060c010b200441016a22062004490de001200441017422092006200920064b1b22094100480de0010240024020040d002009102821060c010b200a28020020042009102c21060b2006450dc6012002200636020420082009360200200728020021040b2007200441016a360200200620046a200541807f72200541ff0071200541077622041b3a00002004210520040d000c94010b0b200241046a210a200141086a2802002105200141046a280200210602400240200241086a2802002002410c6a2802002204460d00200a28020021070c010b200441016a22072004490dde01200441017422082007200820074b1b22084100480dde010240024020040d002008102821070c010b200a28020020042008102c21070b2007450dc50120022007360204200241086a20083602002002410c6a28020021040b2002410c6a2208200441016a360200200720046a412d3a0000200241086a2109034002400240200928020020082802002204460d00200a28020021070c010b200441016a22072004490ddf012004410174220b2007200b20074b1b220b4100480ddf010240024020040d00200b102821070c010b200a2802002004200b102c21070b2007450dc701200220073602042009200b360200200828020021040b2008200441016a360200200720046a200641807f72200641ff0071200641077622041b3a00002004210620040d000b2002410c6a2107200241086a2108034002400240200828020020072802002204460d00200a28020021060c010b200441016a22062004490ddf01200441017422092006200920064b1b22094100480ddf010240024020040d002009102821060c010b200a28020020042009102c21060b2006450dc8012002200636020420082009360200200728020021040b2007200441016a360200200620046a200541807f72200541ff0071200541077622041b3a00002004210520040d000c93010b0b200241046a210a200141086a2802002105200141046a280200210602400240200241086a2802002002410c6a2802002204460d00200a28020021070c010b200441016a22072004490ddd01200441017422082007200820074b1b22084100480ddd010240024020040d002008102821070c010b200a28020020042008102c21070b2007450dc70120022007360204200241086a20083602002002410c6a28020021040b2002410c6a2208200441016a360200200720046a412e3a0000200241086a2109034002400240200928020020082802002204460d00200a28020021070c010b200441016a22072004490dde012004410174220b2007200b20074b1b220b4100480dde010240024020040d00200b102821070c010b200a2802002004200b102c21070b2007450dc901200220073602042009200b360200200828020021040b2008200441016a360200200720046a200641807f72200641ff0071200641077622041b3a00002004210620040d000b2002410c6a2107200241086a2108034002400240200828020020072802002204460d00200a28020021060c010b200441016a22062004490dde01200441017422092006200920064b1b22094100480dde010240024020040d002009102821060c010b200a28020020042009102c21060b2006450dca012002200636020420082009360200200728020021040b2007200441016a360200200620046a200541807f72200541ff0071200541077622041b3a00002004210520040d000c92010b0b200241046a210a200141086a2802002105200141046a280200210602400240200241086a2802002002410c6a2802002204460d00200a28020021070c010b200441016a22072004490ddc01200441017422082007200820074b1b22084100480ddc010240024020040d002008102821070c010b200a28020020042008102c21070b2007450dc90120022007360204200241086a20083602002002410c6a28020021040b2002410c6a2208200441016a360200200720046a412f3a0000200241086a2109034002400240200928020020082802002204460d00200a28020021070c010b200441016a22072004490ddd012004410174220b2007200b20074b1b220b4100480ddd010240024020040d00200b102821070c010b200a2802002004200b102c21070b2007450dcb01200220073602042009200b360200200828020021040b2008200441016a360200200720046a200641807f72200641ff0071200641077622041b3a00002004210620040d000b2002410c6a2107200241086a2108034002400240200828020020072802002204460d00200a28020021060c010b200441016a22062004490ddd01200441017422092006200920064b1b22094100480ddd010240024020040d002009102821060c010b200a28020020042009102c21060b2006450dcc012002200636020420082009360200200728020021040b2007200441016a360200200620046a200541807f72200541ff0071200541077622041b3a00002004210520040d000c91010b0b200241046a210a200141086a2802002105200141046a280200210602400240200241086a2802002002410c6a2802002204460d00200a28020021070c010b200441016a22072004490ddb01200441017422082007200820074b1b22084100480ddb010240024020040d002008102821070c010b200a28020020042008102c21070b2007450dcb0120022007360204200241086a20083602002002410c6a28020021040b2002410c6a2208200441016a360200200720046a41303a0000200241086a2109034002400240200928020020082802002204460d00200a28020021070c010b200441016a22072004490ddc012004410174220b2007200b20074b1b220b4100480ddc010240024020040d00200b102821070c010b200a2802002004200b102c21070b2007450dcd01200220073602042009200b360200200828020021040b2008200441016a360200200720046a200641807f72200641ff0071200641077622041b3a00002004210620040d000b2002410c6a2107200241086a2108034002400240200828020020072802002204460d00200a28020021060c010b200441016a22062004490ddc01200441017422092006200920064b1b22094100480ddc010240024020040d002009102821060c010b200a28020020042009102c21060b2006450dce012002200636020420082009360200200728020021040b2007200441016a360200200620046a200541807f72200541ff0071200541077622041b3a00002004210520040d000c90010b0b200241046a210a200141086a2802002105200141046a280200210602400240200241086a2802002002410c6a2802002204460d00200a28020021070c010b200441016a22072004490dda01200441017422082007200820074b1b22084100480dda010240024020040d002008102821070c010b200a28020020042008102c21070b2007450dcd0120022007360204200241086a20083602002002410c6a28020021040b2002410c6a2208200441016a360200200720046a41313a0000200241086a2109034002400240200928020020082802002204460d00200a28020021070c010b200441016a22072004490ddb012004410174220b2007200b20074b1b220b4100480ddb010240024020040d00200b102821070c010b200a2802002004200b102c21070b2007450dcf01200220073602042009200b360200200828020021040b2008200441016a360200200720046a200641807f72200641ff0071200641077622041b3a00002004210620040d000b2002410c6a2107200241086a2108034002400240200828020020072802002204460d00200a28020021060c010b200441016a22062004490ddb01200441017422092006200920064b1b22094100480ddb010240024020040d002009102821060c010b200a28020020042009102c21060b2006450dd0012002200636020420082009360200200728020021040b2007200441016a360200200620046a200541807f72200541ff0071200541077622041b3a00002004210520040d000c8f010b0b200241046a210a200141086a2802002105200141046a280200210602400240200241086a2802002002410c6a2802002204460d00200a28020021070c010b200441016a22072004490dd901200441017422082007200820074b1b22084100480dd9010240024020040d002008102821070c010b200a28020020042008102c21070b2007450dcf0120022007360204200241086a20083602002002410c6a28020021040b2002410c6a2208200441016a360200200720046a41323a0000200241086a2109034002400240200928020020082802002204460d00200a28020021070c010b200441016a22072004490dda012004410174220b2007200b20074b1b220b4100480dda010240024020040d00200b102821070c010b200a2802002004200b102c21070b2007450dd101200220073602042009200b360200200828020021040b2008200441016a360200200720046a200641807f72200641ff0071200641077622041b3a00002004210620040d000b2002410c6a2107200241086a2108034002400240200828020020072802002204460d00200a28020021060c010b200441016a22062004490dda01200441017422092006200920064b1b22094100480dda010240024020040d002009102821060c010b200a28020020042009102c21060b2006450dd2012002200636020420082009360200200728020021040b2007200441016a360200200620046a200541807f72200541ff0071200541077622041b3a00002004210520040d000c8e010b0b200241046a210a200141086a2802002105200141046a280200210602400240200241086a2802002002410c6a2802002204460d00200a28020021070c010b200441016a22072004490dd801200441017422082007200820074b1b22084100480dd8010240024020040d002008102821070c010b200a28020020042008102c21070b2007450dd10120022007360204200241086a20083602002002410c6a28020021040b2002410c6a2208200441016a360200200720046a41333a0000200241086a2109034002400240200928020020082802002204460d00200a28020021070c010b200441016a22072004490dd9012004410174220b2007200b20074b1b220b4100480dd9010240024020040d00200b102821070c010b200a2802002004200b102c21070b2007450dd301200220073602042009200b360200200828020021040b2008200441016a360200200720046a200641807f72200641ff0071200641077622041b3a00002004210620040d000b2002410c6a2107200241086a2108034002400240200828020020072802002204460d00200a28020021060c010b200441016a22062004490dd901200441017422092006200920064b1b22094100480dd9010240024020040d002009102821060c010b200a28020020042009102c21060b2006450dd4012002200636020420082009360200200728020021040b2007200441016a360200200620046a200541807f72200541ff0071200541077622041b3a00002004210520040d000c8d010b0b200241046a210a200141086a2802002105200141046a280200210602400240200241086a2802002002410c6a2802002204460d00200a28020021070c010b200441016a22072004490dd701200441017422082007200820074b1b22084100480dd7010240024020040d002008102821070c010b200a28020020042008102c21070b2007450dd30120022007360204200241086a20083602002002410c6a28020021040b2002410c6a2208200441016a360200200720046a41343a0000200241086a2109034002400240200928020020082802002204460d00200a28020021070c010b200441016a22072004490dd8012004410174220b2007200b20074b1b220b4100480dd8010240024020040d00200b102821070c010b200a2802002004200b102c21070b2007450dd501200220073602042009200b360200200828020021040b2008200441016a360200200720046a200641807f72200641ff0071200641077622041b3a00002004210620040d000b2002410c6a2107200241086a2108034002400240200828020020072802002204460d00200a28020021060c010b200441016a22062004490dd801200441017422092006200920064b1b22094100480dd8010240024020040d002009102821060c010b200a28020020042009102c21060b2006450dd6012002200636020420082009360200200728020021040b2007200441016a360200200620046a200541807f72200541ff0071200541077622041b3a00002004210520040d000c8c010b0b200241046a210a200141086a2802002105200141046a280200210602400240200241086a2802002002410c6a2802002204460d00200a28020021070c010b200441016a22072004490dd601200441017422082007200820074b1b22084100480dd6010240024020040d002008102821070c010b200a28020020042008102c21070b2007450dd50120022007360204200241086a20083602002002410c6a28020021040b2002410c6a2208200441016a360200200720046a41353a0000200241086a2109034002400240200928020020082802002204460d00200a28020021070c010b200441016a22072004490da3022004410174220b2007200b20074b1b220b4100480da3020240024020040d00200b102821070c010b200a2802002004200b102c21070b2007450dd801200220073602042009200b360200200828020021040b2008200441016a360200200720046a200641807f72200641ff0071200641077622041b3a00002004210620040d000b2002410c6a2107200241086a2108034002400240200828020020072802002204460d00200a28020021060c010b200441016a22062004490da302200441017422092006200920064b1b22094100480da3020240024020040d002009102821060c010b200a28020020042009102c21060b2006450dd9012002200636020420082009360200200728020021040b2007200441016a360200200620046a200541807f72200541ff0071200541077622041b3a00002004210520040d000c8b010b0b200241046a210a200141086a2802002105200141046a280200210602400240200241086a2802002002410c6a2802002204460d00200a28020021070c010b200441016a22072004490da102200441017422082007200820074b1b22084100480da1020240024020040d002008102821070c010b200a28020020042008102c21070b2007450dd80120022007360204200241086a20083602002002410c6a28020021040b2002410c6a2208200441016a360200200720046a41363a0000200241086a2109034002400240200928020020082802002204460d00200a28020021070c010b200441016a22072004490da2022004410174220b2007200b20074b1b220b4100480da2020240024020040d00200b102821070c010b200a2802002004200b102c21070b2007450dda01200220073602042009200b360200200828020021040b2008200441016a360200200720046a200641807f72200641ff0071200641077622041b3a00002004210620040d000b2002410c6a2107200241086a2108034002400240200828020020072802002204460d00200a28020021060c010b200441016a22062004490da202200441017422092006200920064b1b22094100480da2020240024020040d002009102821060c010b200a28020020042009102c21060b2006450ddb012002200636020420082009360200200728020021040b2007200441016a360200200620046a200541807f72200541ff0071200541077622041b3a00002004210520040d000c8a010b0b200241046a210a200141086a2802002105200141046a280200210602400240200241086a2802002002410c6a2802002204460d00200a28020021070c010b200441016a22072004490da002200441017422082007200820074b1b22084100480da0020240024020040d002008102821070c010b200a28020020042008102c21070b2007450dda0120022007360204200241086a20083602002002410c6a28020021040b2002410c6a2208200441016a360200200720046a41373a0000200241086a2109034002400240200928020020082802002204460d00200a28020021070c010b200441016a22072004490da1022004410174220b2007200b20074b1b220b4100480da1020240024020040d00200b102821070c010b200a2802002004200b102c21070b2007450ddc01200220073602042009200b360200200828020021040b2008200441016a360200200720046a200641807f72200641ff0071200641077622041b3a00002004210620040d000b2002410c6a2107200241086a2108034002400240200828020020072802002204460d00200a28020021060c010b200441016a22062004490da102200441017422092006200920064b1b22094100480da1020240024020040d002009102821060c010b200a28020020042009102c21060b2006450ddd012002200636020420082009360200200728020021040b2007200441016a360200200620046a200541807f72200541ff0071200541077622041b3a00002004210520040d000c89010b0b200241046a210a200141086a2802002105200141046a280200210602400240200241086a2802002002410c6a2802002204460d00200a28020021070c010b200441016a22072004490d9f02200441017422082007200820074b1b22084100480d9f020240024020040d002008102821070c010b200a28020020042008102c21070b2007450ddc0120022007360204200241086a20083602002002410c6a28020021040b2002410c6a2208200441016a360200200720046a41383a0000200241086a2109034002400240200928020020082802002204460d00200a28020021070c010b200441016a22072004490da0022004410174220b2007200b20074b1b220b4100480da0020240024020040d00200b102821070c010b200a2802002004200b102c21070b2007450dde01200220073602042009200b360200200828020021040b2008200441016a360200200720046a200641807f72200641ff0071200641077622041b3a00002004210620040d000b2002410c6a2107200241086a2108034002400240200828020020072802002204460d00200a28020021060c010b200441016a22062004490da002200441017422092006200920064b1b22094100480da0020240024020040d002009102821060c010b200a28020020042009102c21060b2006450ddf012002200636020420082009360200200728020021040b2007200441016a360200200620046a200541807f72200541ff0071200541077622041b3a00002004210520040d000c88010b0b200241046a210a200141086a2802002105200141046a280200210602400240200241086a2802002002410c6a2802002204460d00200a28020021070c010b200441016a22072004490d9e02200441017422082007200820074b1b22084100480d9e020240024020040d002008102821070c010b200a28020020042008102c21070b2007450dde0120022007360204200241086a20083602002002410c6a28020021040b2002410c6a2208200441016a360200200720046a41393a0000200241086a2109034002400240200928020020082802002204460d00200a28020021070c010b200441016a22072004490d9f022004410174220b2007200b20074b1b220b4100480d9f020240024020040d00200b102821070c010b200a2802002004200b102c21070b2007450de001200220073602042009200b360200200828020021040b2008200441016a360200200720046a200641807f72200641ff0071200641077622041b3a00002004210620040d000b2002410c6a2107200241086a2108034002400240200828020020072802002204460d00200a28020021060c010b200441016a22062004490d9f02200441017422092006200920064b1b22094100480d9f020240024020040d002009102821060c010b200a28020020042009102c21060b2006450de1012002200636020420082009360200200728020021040b2007200441016a360200200620046a200541807f72200541ff0071200541077622041b3a00002004210520040d000c87010b0b200241046a210a200141086a2802002105200141046a280200210602400240200241086a2802002002410c6a2802002204460d00200a28020021070c010b200441016a22072004490d9d02200441017422082007200820074b1b22084100480d9d020240024020040d002008102821070c010b200a28020020042008102c21070b2007450de00120022007360204200241086a20083602002002410c6a28020021040b2002410c6a2208200441016a360200200720046a413a3a0000200241086a2109034002400240200928020020082802002204460d00200a28020021070c010b200441016a22072004490d9e022004410174220b2007200b20074b1b220b4100480d9e020240024020040d00200b102821070c010b200a2802002004200b102c21070b2007450de201200220073602042009200b360200200828020021040b2008200441016a360200200720046a200641807f72200641ff0071200641077622041b3a00002004210620040d000b2002410c6a2107200241086a2108034002400240200828020020072802002204460d00200a28020021060c010b200441016a22062004490d9e02200441017422092006200920064b1b22094100480d9e020240024020040d002009102821060c010b200a28020020042009102c21060b2006450de3012002200636020420082009360200200728020021040b2007200441016a360200200620046a200541807f72200541ff0071200541077622041b3a00002004210520040d000c86010b0b200241046a210a200141086a2802002105200141046a280200210602400240200241086a2802002002410c6a2802002204460d00200a28020021070c010b200441016a22072004490d9c02200441017422082007200820074b1b22084100480d9c020240024020040d002008102821070c010b200a28020020042008102c21070b2007450de20120022007360204200241086a20083602002002410c6a28020021040b2002410c6a2208200441016a360200200720046a413b3a0000200241086a2109034002400240200928020020082802002204460d00200a28020021070c010b200441016a22072004490d9d022004410174220b2007200b20074b1b220b4100480d9d020240024020040d00200b102821070c010b200a2802002004200b102c21070b2007450de401200220073602042009200b360200200828020021040b2008200441016a360200200720046a200641807f72200641ff0071200641077622041b3a00002004210620040d000b2002410c6a2107200241086a2108034002400240200828020020072802002204460d00200a28020021060c010b200441016a22062004490d9d02200441017422092006200920064b1b22094100480d9d020240024020040d002009102821060c010b200a28020020042009102c21060b2006450de5012002200636020420082009360200200728020021040b2007200441016a360200200620046a200541807f72200541ff0071200541077622041b3a00002004210520040d000c85010b0b200241046a210a200141086a2802002106200141046a280200210502400240200241086a2802002002410c6a2802002204460d00200a28020021070c010b200441016a22072004490d9b02200441017422082007200820074b1b22084100480d9b020240024020040d002008102821070c010b200a28020020042008102c21070b2007450de40120022007360204200241086a20083602002002410c6a28020021040b2002410c6a2208200441016a360200200720046a413c3a0000200241086a2109034002400240200928020020082802002204460d00200a28020021070c010b200441016a22072004490d9c022004410174220b2007200b20074b1b220b4100480d9c020240024020040d00200b102821070c010b200a2802002004200b102c21070b2007450de601200220073602042009200b360200200828020021040b2008200441016a360200200720046a200541807f72200541ff0071200541077622041b3a00002004210520040d000b2002410c6a2107200241086a2108034002400240200828020020072802002204460d00200a28020021050c010b200441016a22052004490d9c02200441017422092005200920054b1b22094100480d9c020240024020040d002009102821050c010b200a28020020042009102c21050b2005450de7012002200536020420082009360200200728020021040b2007200441016a360200200520046a200641807f72200641ff0071200641077622041b3a00002004210620040d000c84010b0b200241046a210a200141086a2802002105200141046a280200210602400240200241086a2802002002410c6a2802002204460d00200a28020021070c010b200441016a22072004490d9a02200441017422082007200820074b1b22084100480d9a020240024020040d002008102821070c010b200a28020020042008102c21070b2007450de60120022007360204200241086a20083602002002410c6a28020021040b2002410c6a2208200441016a360200200720046a413d3a0000200241086a2109034002400240200928020020082802002204460d00200a28020021070c010b200441016a22072004490d9b022004410174220b2007200b20074b1b220b4100480d9b020240024020040d00200b102821070c010b200a2802002004200b102c21070b2007450de801200220073602042009200b360200200828020021040b2008200441016a360200200720046a200641807f72200641ff0071200641077622041b3a00002004210620040d000b2002410c6a2107200241086a2108034002400240200828020020072802002204460d00200a28020021060c010b200441016a22062004490d9b02200441017422092006200920064b1b22094100480d9b020240024020040d002009102821060c010b200a28020020042009102c21060b2006450de9012002200636020420082009360200200728020021040b2007200441016a360200200620046a200541807f72200541ff0071200541077622041b3a00002004210520040d000c83010b0b200241046a210a200141086a2802002105200141046a280200210602400240200241086a2802002002410c6a2802002204460d00200a28020021070c010b200441016a22072004490d9902200441017422082007200820074b1b22084100480d99020240024020040d002008102821070c010b200a28020020042008102c21070b2007450de80120022007360204200241086a20083602002002410c6a28020021040b2002410c6a2208200441016a360200200720046a413e3a0000200241086a2109034002400240200928020020082802002204460d00200a28020021070c010b200441016a22072004490d9a022004410174220b2007200b20074b1b220b4100480d9a020240024020040d00200b102821070c010b200a2802002004200b102c21070b2007450dea01200220073602042009200b360200200828020021040b2008200441016a360200200720046a200641807f72200641ff0071200641077622041b3a00002004210620040d000b2002410c6a2107200241086a2108034002400240200828020020072802002204460d00200a28020021060c010b200441016a22062004490d9a02200441017422092006200920064b1b22094100480d9a020240024020040d002009102821060c010b200a28020020042009102c21060b2006450deb012002200636020420082009360200200728020021040b2007200441016a360200200620046a200541807f72200541ff0071200541077622041b3a00002004210520040d000c82010b0b200241046a210620012d0001210702400240200241086a2802002002410c6a2802002204460d00200628020021050c010b200441016a22052004490d9802200441017422082005200820054b1b22084100480d98020240024020040d002008102821050c010b200628020020042008102c21050b2005450dea0120022005360204200241086a20083602002002410c6a28020021040b2002410c6a2208200441016a360200200520046a413f3a000002400240200241086a28020020082802002204460d00200628020021050c010b200441016a22052004490d9802200441017422082005200820054b1b22084100480d98020240024020040d002008102821050c010b200628020020042008102c21050b2005450deb0120022005360204200241086a20083602002002410c6a28020021040b2002410c6a200441016a360200200520046a20073a00000c80010b200241046a210620012d0001210702400240200241086a2802002002410c6a2802002204460d00200628020021050c010b200441016a22052004490d9702200441017422082005200820054b1b22084100480d97020240024020040d002008102821050c010b200628020020042008102c21050b2005450deb0120022005360204200241086a20083602002002410c6a28020021040b2002410c6a2208200441016a360200200520046a41c0003a000002400240200241086a28020020082802002204460d00200628020021050c010b200441016a22052004490d9702200441017422082005200820054b1b22084100480d97020240024020040d002008102821050c010b200628020020042008102c21050b2005450dec0120022005360204200241086a20083602002002410c6a28020021040b2002410c6a200441016a360200200520046a20073a00000c7f0b200141046a280200210602400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d9602200441017422072005200720054b1b22074100480d96020240024020040d002007102821050c010b200228020420042007102c21050b2005450dec0120022005360204200241086a20073602002002410c6a28020021040b2002410c6a200441016a360200200520046a41c1003a000020032006200210eb042003210420032d0000411f470def020c7e0b200141086a290300210c02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d9502200441017422062005200620054b1b22064100480d95020240024020040d002006102821050c010b200228020420042006102c21050b2005450dec0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41c2003a00002003200c200210ec042003210420032d0000411f470dee020c7d0b200241046a2106200141046a280200210702400240200241086a2802002002410c6a2802002204460d00200628020021050c010b200441016a22052004490d9402200441017422082005200820054b1b22084100480d94020240024020040d002008102821050c010b200628020020042008102c21050b2005450dec0120022005360204200241086a20083602002002410c6a28020021040b2002410c6a2208200441016a360200200520046a41c3003a000002400240200241086a2802002205200828020022046b4104490d00200628020021050c010b200441046a22082004490d9402200541017422042008200420084b1b22044100480d94020240024020050d002004102821050c010b200628020020052004102c21050b2005450ded0120022005360204200241086a20043602002002410c6a28020021040b2002410c6a200441046a360200200520046a20073600000c7c0b200241046a2106200141086a290300210c02400240200241086a2802002002410c6a2802002204460d00200628020021050c010b200441016a22052004490d9302200441017422072005200720054b1b22074100480d93020240024020040d002007102821050c010b200628020020042007102c21050b2005450ded0120022005360204200241086a20073602002002410c6a28020021040b2002410c6a2207200441016a360200200520046a41c4003a000002400240200241086a2802002205200728020022046b4108490d00200628020021050c010b200441086a22072004490d9302200541017422042007200420074b1b22044100480d93020240024020050d002004102821050c010b200628020020052004102c21050b2005450dee0120022005360204200241086a20043602002002410c6a28020021040b2002410c6a200441086a360200200520046a200c3700000c7b0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d9202200441017422062005200620054b1b22064100480d92020240024020040d002006102821050c010b200228020420042006102c21050b2005450dee0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41c5003a00000c7a0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d9102200441017422062005200620054b1b22064100480d91020240024020040d002006102821050c010b200228020420042006102c21050b2005450dee0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41c6003a00000c790b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d9002200441017422062005200620054b1b22064100480d90020240024020040d002006102821050c010b200228020420042006102c21050b2005450dee0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41c7003a00000c780b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d8f02200441017422062005200620054b1b22064100480d8f020240024020040d002006102821050c010b200228020420042006102c21050b2005450dee0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41c8003a00000c770b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d8e02200441017422062005200620054b1b22064100480d8e020240024020040d002006102821050c010b200228020420042006102c21050b2005450dee0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41c9003a00000c760b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d8d02200441017422062005200620054b1b22064100480d8d020240024020040d002006102821050c010b200228020420042006102c21050b2005450dee0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41ca003a00000c750b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d8c02200441017422062005200620054b1b22064100480d8c020240024020040d002006102821050c010b200228020420042006102c21050b2005450dee0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41cb003a00000c740b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d8b02200441017422062005200620054b1b22064100480d8b020240024020040d002006102821050c010b200228020420042006102c21050b2005450dee0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41cc003a00000c730b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d8a02200441017422062005200620054b1b22064100480d8a020240024020040d002006102821050c010b200228020420042006102c21050b2005450dee0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41cd003a00000c720b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d8902200441017422062005200620054b1b22064100480d89020240024020040d002006102821050c010b200228020420042006102c21050b2005450dee0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41ce003a00000c710b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d8802200441017422062005200620054b1b22064100480d88020240024020040d002006102821050c010b200228020420042006102c21050b2005450dee0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41cf003a00000c700b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d8702200441017422062005200620054b1b22064100480d87020240024020040d002006102821050c010b200228020420042006102c21050b2005450dee0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41d0003a00000c6f0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d8602200441017422062005200620054b1b22064100480d86020240024020040d002006102821050c010b200228020420042006102c21050b2005450dee0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41d1003a00000c6e0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d8502200441017422062005200620054b1b22064100480d85020240024020040d002006102821050c010b200228020420042006102c21050b2005450dee0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41d2003a00000c6d0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d8402200441017422062005200620054b1b22064100480d84020240024020040d002006102821050c010b200228020420042006102c21050b2005450dee0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41d3003a00000c6c0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d8302200441017422062005200620054b1b22064100480d83020240024020040d002006102821050c010b200228020420042006102c21050b2005450dee0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41d4003a00000c6b0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d8202200441017422062005200620054b1b22064100480d82020240024020040d002006102821050c010b200228020420042006102c21050b2005450dee0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41d5003a00000c6a0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d8102200441017422062005200620054b1b22064100480d81020240024020040d002006102821050c010b200228020420042006102c21050b2005450dee0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41d6003a00000c690b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d8002200441017422062005200620054b1b22064100480d80020240024020040d002006102821050c010b200228020420042006102c21050b2005450dee0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41d7003a00000c680b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490dff01200441017422062005200620054b1b22064100480dff010240024020040d002006102821050c010b200228020420042006102c21050b2005450dee0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41d8003a00000c670b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490dfe01200441017422062005200620054b1b22064100480dfe010240024020040d002006102821050c010b200228020420042006102c21050b2005450dee0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41d9003a00000c660b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490dfd01200441017422062005200620054b1b22064100480dfd010240024020040d002006102821050c010b200228020420042006102c21050b2005450dee0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41da003a00000c650b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490dfc01200441017422062005200620054b1b22064100480dfc010240024020040d002006102821050c010b200228020420042006102c21050b2005450dee0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41db003a00000c640b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490dfb01200441017422062005200620054b1b22064100480dfb010240024020040d002006102821050c010b200228020420042006102c21050b2005450dee0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41dc003a00000c630b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490dfa01200441017422062005200620054b1b22064100480dfa010240024020040d002006102821050c010b200228020420042006102c21050b2005450dee0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41dd003a00000c620b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490df901200441017422062005200620054b1b22064100480df9010240024020040d002006102821050c010b200228020420042006102c21050b2005450dee0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41de003a00000c610b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490df801200441017422062005200620054b1b22064100480df8010240024020040d002006102821050c010b200228020420042006102c21050b2005450dee0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41df003a00000c600b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490df701200441017422062005200620054b1b22064100480df7010240024020040d002006102821050c010b200228020420042006102c21050b2005450dee0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41e0003a00000c5f0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490df601200441017422062005200620054b1b22064100480df6010240024020040d002006102821050c010b200228020420042006102c21050b2005450dee0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41e1003a00000c5e0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490df501200441017422062005200620054b1b22064100480df5010240024020040d002006102821050c010b200228020420042006102c21050b2005450dee0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41e2003a00000c5d0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490df401200441017422062005200620054b1b22064100480df4010240024020040d002006102821050c010b200228020420042006102c21050b2005450dee0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41e3003a00000c5c0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490df301200441017422062005200620054b1b22064100480df3010240024020040d002006102821050c010b200228020420042006102c21050b2005450dee0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41e4003a00000c5b0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490df201200441017422062005200620054b1b22064100480df2010240024020040d002006102821050c010b200228020420042006102c21050b2005450dee0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41e5003a00000c5a0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490df101200441017422062005200620054b1b22064100480df1010240024020040d002006102821050c010b200228020420042006102c21050b2005450dee0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41e6003a00000c590b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490df001200441017422062005200620054b1b22064100480df0010240024020040d002006102821050c010b200228020420042006102c21050b2005450dee0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41e7003a00000c580b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490def01200441017422062005200620054b1b22064100480def010240024020040d002006102821050c010b200228020420042006102c21050b2005450dee0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41e8003a00000c570b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490dba02200441017422062005200620054b1b22064100480dba020240024020040d002006102821050c010b200228020420042006102c21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41e9003a00000c560b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490db902200441017422062005200620054b1b22064100480db9020240024020040d002006102821050c010b200228020420042006102c21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41ea003a00000c550b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490db802200441017422062005200620054b1b22064100480db8020240024020040d002006102821050c010b200228020420042006102c21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41eb003a00000c540b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490db702200441017422062005200620054b1b22064100480db7020240024020040d002006102821050c010b200228020420042006102c21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41ec003a00000c530b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490db602200441017422062005200620054b1b22064100480db6020240024020040d002006102821050c010b200228020420042006102c21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41ed003a00000c520b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490db502200441017422062005200620054b1b22064100480db5020240024020040d002006102821050c010b200228020420042006102c21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41ee003a00000c510b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490db402200441017422062005200620054b1b22064100480db4020240024020040d002006102821050c010b200228020420042006102c21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41ef003a00000c500b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490db302200441017422062005200620054b1b22064100480db3020240024020040d002006102821050c010b200228020420042006102c21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41f0003a00000c4f0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490db202200441017422062005200620054b1b22064100480db2020240024020040d002006102821050c010b200228020420042006102c21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41f1003a00000c4e0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490db102200441017422062005200620054b1b22064100480db1020240024020040d002006102821050c010b200228020420042006102c21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41f2003a00000c4d0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490db002200441017422062005200620054b1b22064100480db0020240024020040d002006102821050c010b200228020420042006102c21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41f3003a00000c4c0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490daf02200441017422062005200620054b1b22064100480daf020240024020040d002006102821050c010b200228020420042006102c21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41f4003a00000c4b0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490dae02200441017422062005200620054b1b22064100480dae020240024020040d002006102821050c010b200228020420042006102c21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41f5003a00000c4a0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490dad02200441017422062005200620054b1b22064100480dad020240024020040d002006102821050c010b200228020420042006102c21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41f6003a00000c490b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490dac02200441017422062005200620054b1b22064100480dac020240024020040d002006102821050c010b200228020420042006102c21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41f7003a00000c480b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490dab02200441017422062005200620054b1b22064100480dab020240024020040d002006102821050c010b200228020420042006102c21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41f8003a00000c470b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490daa02200441017422062005200620054b1b22064100480daa020240024020040d002006102821050c010b200228020420042006102c21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41f9003a00000c460b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490da902200441017422062005200620054b1b22064100480da9020240024020040d002006102821050c010b200228020420042006102c21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41fa003a00000c450b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490da802200441017422062005200620054b1b22064100480da8020240024020040d002006102821050c010b200228020420042006102c21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41fb003a00000c440b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490da702200441017422062005200620054b1b22064100480da7020240024020040d002006102821050c010b200228020420042006102c21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41fc003a00000c430b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490da602200441017422062005200620054b1b22064100480da6020240024020040d002006102821050c010b200228020420042006102c21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41fd003a00000c420b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490da502200441017422062005200620054b1b22064100480da5020240024020040d002006102821050c010b200228020420042006102c21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41fe003a00000c410b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490da402200441017422062005200620054b1b22064100480da4020240024020040d002006102821050c010b200228020420042006102c21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41ff003a00000c400b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490da302200441017422062005200620054b1b22064100480da3020240024020040d002006102821050c010b200228020420042006102c21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a4180013a00000c3f0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490da202200441017422062005200620054b1b22064100480da2020240024020040d002006102821050c010b200228020420042006102c21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a4181013a00000c3e0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490da102200441017422062005200620054b1b22064100480da1020240024020040d002006102821050c010b200228020420042006102c21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a4182013a00000c3d0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490da002200441017422062005200620054b1b22064100480da0020240024020040d002006102821050c010b200228020420042006102c21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a4183013a00000c3c0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d9f02200441017422062005200620054b1b22064100480d9f020240024020040d002006102821050c010b200228020420042006102c21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a4184013a00000c3b0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d9e02200441017422062005200620054b1b22064100480d9e020240024020040d002006102821050c010b200228020420042006102c21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a4185013a00000c3a0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d9d02200441017422062005200620054b1b22064100480d9d020240024020040d002006102821050c010b200228020420042006102c21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a4186013a00000c390b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d9c02200441017422062005200620054b1b22064100480d9c020240024020040d002006102821050c010b200228020420042006102c21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a4187013a00000c380b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d9b02200441017422062005200620054b1b22064100480d9b020240024020040d002006102821050c010b200228020420042006102c21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a4188013a00000c370b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d9a02200441017422062005200620054b1b22064100480d9a020240024020040d002006102821050c010b200228020420042006102c21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a4189013a00000c360b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d9902200441017422062005200620054b1b22064100480d99020240024020040d002006102821050c010b200228020420042006102c21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a418a013a00000c350b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d9802200441017422062005200620054b1b22064100480d98020240024020040d002006102821050c010b200228020420042006102c21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a418b013a00000c340b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d9702200441017422062005200620054b1b22064100480d97020240024020040d002006102821050c010b200228020420042006102c21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a418c013a00000c330b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d9602200441017422062005200620054b1b22064100480d96020240024020040d002006102821050c010b200228020420042006102c21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a418d013a00000c320b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d9502200441017422062005200620054b1b22064100480d95020240024020040d002006102821050c010b200228020420042006102c21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a418e013a00000c310b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d9402200441017422062005200620054b1b22064100480d94020240024020040d002006102821050c010b200228020420042006102c21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a418f013a00000c300b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d9302200441017422062005200620054b1b22064100480d93020240024020040d002006102821050c010b200228020420042006102c21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a4190013a00000c2f0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d9202200441017422062005200620054b1b22064100480d92020240024020040d002006102821050c010b200228020420042006102c21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a4191013a00000c2e0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d9102200441017422062005200620054b1b22064100480d91020240024020040d002006102821050c010b200228020420042006102c21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a4192013a00000c2d0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d9002200441017422062005200620054b1b22064100480d90020240024020040d002006102821050c010b200228020420042006102c21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a4193013a00000c2c0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d8f02200441017422062005200620054b1b22064100480d8f020240024020040d002006102821050c010b200228020420042006102c21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a4194013a00000c2b0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d8e02200441017422062005200620054b1b22064100480d8e020240024020040d002006102821050c010b200228020420042006102c21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a4195013a00000c2a0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d8d02200441017422062005200620054b1b22064100480d8d020240024020040d002006102821050c010b200228020420042006102c21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a4196013a00000c290b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d8c02200441017422062005200620054b1b22064100480d8c020240024020040d002006102821050c010b200228020420042006102c21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a4197013a00000c280b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d8b02200441017422062005200620054b1b22064100480d8b020240024020040d002006102821050c010b200228020420042006102c21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a4198013a00000c270b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d8a02200441017422062005200620054b1b22064100480d8a020240024020040d002006102821050c010b200228020420042006102c21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a4199013a00000c260b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d8902200441017422062005200620054b1b22064100480d89020240024020040d002006102821050c010b200228020420042006102c21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a419a013a00000c250b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d8802200441017422062005200620054b1b22064100480d88020240024020040d002006102821050c010b200228020420042006102c21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a419b013a00000c240b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d8702200441017422062005200620054b1b22064100480d87020240024020040d002006102821050c010b200228020420042006102c21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a419c013a00000c230b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d8602200441017422062005200620054b1b22064100480d86020240024020040d002006102821050c010b200228020420042006102c21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a419d013a00000c220b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d8502200441017422062005200620054b1b22064100480d85020240024020040d002006102821050c010b200228020420042006102c21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a419e013a00000c210b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d8402200441017422062005200620054b1b22064100480d84020240024020040d002006102821050c010b200228020420042006102c21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a419f013a00000c200b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d8302200441017422062005200620054b1b22064100480d83020240024020040d002006102821050c010b200228020420042006102c21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41a0013a00000c1f0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d8202200441017422062005200620054b1b22064100480d82020240024020040d002006102821050c010b200228020420042006102c21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41a1013a00000c1e0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d8102200441017422062005200620054b1b22064100480d81020240024020040d002006102821050c010b200228020420042006102c21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41a2013a00000c1d0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d8002200441017422062005200620054b1b22064100480d80020240024020040d002006102821050c010b200228020420042006102c21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41a3013a00000c1c0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490dff01200441017422062005200620054b1b22064100480dff010240024020040d002006102821050c010b200228020420042006102c21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41a4013a00000c1b0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490dfe01200441017422062005200620054b1b22064100480dfe010240024020040d002006102821050c010b200228020420042006102c21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41a5013a00000c1a0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490dfd01200441017422062005200620054b1b22064100480dfd010240024020040d002006102821050c010b200228020420042006102c21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41a6013a00000c190b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490dfc01200441017422062005200620054b1b22064100480dfc010240024020040d002006102821050c010b200228020420042006102c21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41a7013a00000c180b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490dfb01200441017422062005200620054b1b22064100480dfb010240024020040d002006102821050c010b200228020420042006102c21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41a8013a00000c170b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490dfa01200441017422062005200620054b1b22064100480dfa010240024020040d002006102821050c010b200228020420042006102c21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41a9013a00000c160b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490df901200441017422062005200620054b1b22064100480df9010240024020040d002006102821050c010b200228020420042006102c21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41aa013a00000c150b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490df801200441017422062005200620054b1b22064100480df8010240024020040d002006102821050c010b200228020420042006102c21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41ab013a00000c140b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490df701200441017422062005200620054b1b22064100480df7010240024020040d002006102821050c010b200228020420042006102c21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41ac013a00000c130b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490df601200441017422062005200620054b1b22064100480df6010240024020040d002006102821050c010b200228020420042006102c21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41ad013a00000c120b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490df501200441017422062005200620054b1b22064100480df5010240024020040d002006102821050c010b200228020420042006102c21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41ae013a00000c110b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490df401200441017422062005200620054b1b22064100480df4010240024020040d002006102821050c010b200228020420042006102c21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41af013a00000c100b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490df301200441017422062005200620054b1b22064100480df3010240024020040d002006102821050c010b200228020420042006102c21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41b0013a00000c0f0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490df201200441017422062005200620054b1b22064100480df2010240024020040d002006102821050c010b200228020420042006102c21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41b1013a00000c0e0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490df101200441017422062005200620054b1b22064100480df1010240024020040d002006102821050c010b200228020420042006102c21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41b2013a00000c0d0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490df001200441017422062005200620054b1b22064100480df0010240024020040d002006102821050c010b200228020420042006102c21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41b3013a00000c0c0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490dfc01200441017422062005200620054b1b22064100480dfc010240024020040d002006102821050c010b200228020420042006102c21050b2005450df00120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41b4013a00000c0b0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490dfb01200441017422062005200620054b1b22064100480dfb010240024020040d002006102821050c010b200228020420042006102c21050b2005450df00120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41b5013a00000c0a0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490dfa01200441017422062005200620054b1b22064100480dfa010240024020040d002006102821050c010b200228020420042006102c21050b2005450df00120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41b6013a00000c090b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490df901200441017422062005200620054b1b22064100480df9010240024020040d002006102821050c010b200228020420042006102c21050b2005450df00120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41b7013a00000c080b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490df801200441017422062005200620054b1b22064100480df8010240024020040d002006102821050c010b200228020420042006102c21050b2005450df00120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41b8013a00000c070b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490df701200441017422062005200620054b1b22064100480df7010240024020040d002006102821050c010b200228020420042006102c21050b2005450df00120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41b9013a00000c060b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490df601200441017422062005200620054b1b22064100480df6010240024020040d002006102821050c010b200228020420042006102c21050b2005450df00120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41ba013a00000c050b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490df501200441017422062005200620054b1b22064100480df5010240024020040d002006102821050c010b200228020420042006102c21050b2005450df00120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41bb013a00000c040b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490df401200441017422062005200620054b1b22064100480df4010240024020040d002006102821050c010b200228020420042006102c21050b2005450df00120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41bc013a00000c030b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490df301200441017422062005200620054b1b22064100480df3010240024020040d002006102821050c010b200228020420042006102c21050b2005450df00120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41bd013a00000c020b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490df201200441017422062005200620054b1b22064100480df2010240024020040d002006102821050c010b200228020420042006102c21050b2005450df00120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41be013a00000c010b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490df101200441017422062005200620054b1b22064100480df1010240024020040d002006102821050c010b200228020420042006102c21050b2005450df00120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41bf013a00000b2000411f3a000020012d00004109470df1010240200141046a280200220228020441ffffffff0371450d002002280200102a200128020421020b2002102a0cf1010b200641011037000b200641011037000b200841011037000b200841011037000b200841011037000b200841011037000b200841011037000b200841011037000b200641011037000b200641011037000b200741011037000b200a41011037000b200741011037000b200a41011037000b200641011037000b200a41011037000b200641011037000b200741011037000b200a41011037000b200741011037000b200a41011037000b200641011037000b200641011037000b200641011037000b200741011037000b200a41011037000b200741011037000b200a41011037000b200741011037000b200a41011037000b200741011037000b200a41011037000b200741011037000b200a41011037000b200841011037000b200b41011037000b200941011037000b200841011037000b200b41011037000b200941011037000b200841011037000b200b41011037000b200941011037000b200841011037000b200b41011037000b200941011037000b200841011037000b200b41011037000b200941011037000b200841011037000b200b41011037000b200941011037000b200841011037000b200b41011037000b200941011037000b200841011037000b200b41011037000b200941011037000b200841011037000b200b41011037000b200941011037000b200841011037000b200b41011037000b200941011037000b200841011037000b200b41011037000b200941011037000b200841011037000b200b41011037000b200941011037000b200841011037000b200b41011037000b200941011037000b200841011037000b1031000b200b41011037000b200941011037000b200841011037000b200b41011037000b200941011037000b200841011037000b200b41011037000b200941011037000b200841011037000b200b41011037000b200941011037000b200841011037000b200b41011037000b200941011037000b200841011037000b200b41011037000b200941011037000b200841011037000b200b41011037000b200941011037000b200841011037000b200b41011037000b200941011037000b200841011037000b200b41011037000b200941011037000b200841011037000b200b41011037000b200941011037000b200841011037000b200841011037000b200841011037000b200841011037000b200741011037000b200641011037000b200841011037000b200441011037000b200741011037000b200441011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b1031000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b1031000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b1031000b20002004290200370200200041086a200441086a29020037020020012d00004109470d000240200141046a280200220228020441ffffffff0371450d002002280200102a200128020421020b2002102a0b200341106a24000bfb07030e7f017e017f200241086a2103200241046a210420012802002205210602400240024002400240034002400240200428020020032802002207460d00200228020021080c010b200741016a22082007490d02200741017422092008200920084b1b22094100480d020240024020070d002009102821080c010b200228020020072009102c21080b2008450d032002200836020020042009360200200328020021070b2003200741016a360200200820076a200641807f72200641ff0071200641077622071b3a00002007210620070d000b2001280204220a2001410c6a2802002206410c6c6a210b200141086a280200210c200a21072006450d03200a21072005450d03200b41746a210d200241086a210841002107200a210e02400340200e2103024003402003280200220f0d01200741016a2107200b2003410c6a2203470d000c080b0b2003410c6a210e200741016a21102005417f6a2105200341046a290200211102400240034002400240200241046a220428020020082802002206460d00200228020021090c010b200641016a22092006490d06200641017422012009200120094b1b22014100480d060240024020060d002001102821090c010b200228020020062001102c21090b2009450d022002200936020020042001360200200828020021060b2008200641016a360200200920066a200741807f72200741ff0071200741077622061b3a0000200621072006450d020c000b0b200141011037000b2011422088a7221221060240034002400240200428020020082802002207460d00200228020021090c010b200741016a22092007490d05200741017422012009200120094b1b22014100480d050240024020070d002001102821090c010b200228020020072001102c21090b2009450d022002200936020020042001360200200828020021070b2008200741016a360200200920076a200641807f72200641ff0071200641077622071b3a00002007210620070d000b0240024020042802002206200828020022076b2012490d00200228020021060c010b200720126a22092007490d04200641017422072009200720094b1b22074100480d040240024020060d002007102821060c010b200228020020062007102c21060b2006450d032002200636020020042007360200200828020021070b2008200720126a360200200620076a200f2012109a051a02402011a7450d00200f102a0b200d2003460d052010210720050d010c050b0b200141011037000b200741011037000b1031000b200941011037000b2003410c6a21070b2007200b460d000340024020072802002206450d00200741046a280200450d002006102a0b2007410c6a2207200b470d000b0b0240200c450d00200a102a0b2000411f3a00000bcb0401067f200441046a2105024002400240024002400240200441086a2802002004410c6a2802002206460d00200528020021070c010b200641016a22072006490d04200641017422082007200820074b1b22084100480d040240024020060d002008102821070c010b200528020020062008102c21070b2007450d0120042007360204200441086a20083602002004410c6a28020021060b2004410c6a2208200641016a360200200720066a20024101463a0000200441086a2109034002400240200928020020082802002206460d00200528020021070c010b200641016a22072006490d052006410174220a2007200a20074b1b220a4100480d050240024020060d00200a102821070c010b20052802002006200a102c21070b2007450d03200420073602042009200a360200200828020021060b2008200641016a360200200720066a200141807f72200141ff0071200141077622061b3a00002006210120060d000b024020024101470d002004410c6a2107200441086a2108034002400240200828020020072802002206460d00200528020021010c010b200641016a22012006490d06200641017422092001200920014b1b22094100480d060240024020060d002009102821010c010b200528020020062009102c21010b2001450d052004200136020420082009360200200728020021060b2007200641016a360200200120066a200341807f72200341ff0071200341077622061b3a00002006210320060d000b0b2000411f3a00000f0b200841011037000b200a41011037000b200941011037000b1031000bb007010a7f230041d0006b2202240002400240024002400240024020012802082203200128020c2204460d00200441016a22052004490d02200320054f0d0120052003103c000b200241013a001f200241cc006a41013602002002420137023c200241a4e2c500360238200241263602342002200241306a36024820022002411f6a360230200241206a200241386a10332002411b6a200241286a28020036000020022002290320370013200220022900103703002002200241176a290000370007200041053a0004200020022903003700052000410c6a2002290007370000200041013602000c040b2001280200220620046a2d000021072001200536020c024020074102490d00200041173a000420004101360200200041056a20073a00000c040b410120036b2108200441026a2104410021054100210902400240034002402005411f4d0d00410f21050c020b02400240200820046a4102460d002004450d06200320044f0d0120042003103c000b200241013a0000200241cc006a41013602002002420137023c200241a4e2c500360238200241263602342002200241306a36024820022002360230200241106a200241386a1033410521050c020b200620046a417f6a2d0000210a2001200436020c200a41ff00712005411f71742009722109200441016a2104200541076a2105200a418001710d000b20054120490d01410d2105200a4110490d010b2000200536020420004101360200200041086a2002290210370200200041106a200241106a41086a2802003602000c040b4100210502402007410171450d002004417f6a2104410021054100210b02400240034002402005411f4d0d00410f21040c020b0240024020032004460d002004417f460d082003200441016a22084f0d01200441016a2003103c000b200241013a0000200241cc006a41013602002002420137023c200241a4e2c500360238200241263602342002200241306a36024820022002360230200241106a200241386a1033410521040c020b200620046a2d0000210a2001200836020c200a41ff00712005411f7174200b72210b200541076a210520082104200a418001710d000b20054120490d01410d2104200a4110490d010b2000200436020420004101360200200041086a2002290210370200200041106a200241106a41086a2802003602000c050b410121050b20002009360204200041003602002000410c6a200b360200200041086a20053602000c030b417f20051044000b417f20041044000b417f200441016a1044000b200241d0006a24000bee0201067f230041c0006b2202240041002103410021040240024003400240024002402003411f4b0d002001280204220520012802082206460d01200641016a22072006490d04200520074f0d0220072005103c000b200041013602002000410f3a00040c040b200241013a000f200241346a410136020020024201370224200241a4e2c5003602202002412636023c2002200241386a36023020022002410f6a360238200241106a200241206a10332002410b6a200241186a28020036000020022002290310370003200041053a0004200020022900003700052000410c6a200241076a290000370000200041013602000c030b200128020020066a2d0000210620012007360208200641ff00712003411f71742004722104200341076a21032006418001710d000b0240024020034120490d002006410f4b0d010b20004100360200200020043602040c020b200041013602002000410d3a00040c010b417f20071044000b200241c0006a24000bd806010a7f20012802042103200128020021044100210541002106410021074101210820012802082209210a02400240024002400340024020062007470d002005200641016a220b2005200b4b1b22074100480d050240024020060d002007102821080c010b200820062007102c21080b2008450d020b200820066a200a41807f72200a41ff0071200a410776220b1b3a0000200541026a2105200641016a2106200b210a200b0d000b0240200720066b20094f0d00200620096a220a2006490d0420074101742205200a2005200a4b1b220a4100480d040240024020070d00200a102821080c010b20082007200a102c21080b2008450d02200a21070b200820066a20042009109a051a02402003450d002004102a0b200128020c210c0240200720096b20066b200141146a280200220a490d002009200a6a20066a21030c030b200920066a2205200a6a22032005490d03200741017422052003200520034b1b22054100480d030240024020070d002005102821080c010b200820072005102c21080b02402008450d00200521070c030b200541011037000b200741011037000b200a41011037000b200820096a20066a200c200a109a051a200241086a210b200241046a21092003210a024002400340024002402009280200200b2802002206460d00200228020021050c010b200641016a22052006490d04200641017422042005200420054b1b22044100480d040240024020060d002004102821050c010b200228020020062004102c21050b2005450d022002200536020020092004360200200b28020021060b200b200641016a360200200520066a200a41807f72200a41ff0071200a41077622061b3a00002006210a20060d000b02400240200241046a280200220a200241086a28020022066b2003490d002002280200210a0c010b200620036a22052006490d03200a41017422062005200620054b1b22064100480d0302400240200a0d0020061028210a0c010b2002280200200a2006102c210a0b200a450d022002200a360200200241046a2006360200200241086a28020021060b200241086a200620036a360200200a20066a20082003109a051a02402007450d002008102a0b2000411f3a00000240200141106a280200450d00200c102a0b0f0b200441011037000b200641011037000b1031000bf20103027f017e057f024020002802082201200028020c460d00034020002001411c6a36020820012802102202450d01200141146a2902002103024020012802042204450d00200141086a280200210502402001410c6a2802002201450d0020014104742106200421010340024020012d00004109470d000240200141046a2207280200220828020441ffffffff0371450d002008280200102a200728020021080b2008102a0b200141106a2101200641706a22060d000b0b2005450d002004102a0b02402003a7450d002002102a0b20002802082201200028020c470d000b0b02402000280204450d002000280200102a0b0be50101067f024020002802082201200028020c460d0003402000200141186a36020820012802002202450d01200141146a2802002103200141106a2802002104200128020c210502402001280204450d002002102a0b02402003450d0020034104742103200521010340024020012d00004109470d000240200141046a2206280200220228020441ffffffff0371450d002002280200102a200628020021020b2002102a0b200141106a2101200341706a22030d000b0b02402004450d002005102a0b20002802082201200028020c470d000b0b02402000280204450d002000280200102a0b0bf20103027f017e057f024020002802082201200028020c460d00034020002001411c6a36020820012802102202450d01200141146a2902002103024020012802042204450d00200141086a280200210502402001410c6a2802002201450d0020014104742106200421010340024020012d00004109470d000240200141046a2207280200220828020441ffffffff0371450d002008280200102a200728020021080b2008102a0b200141106a2101200641706a22060d000b0b2005450d002004102a0b02402003a7450d002002102a0b20002802082201200028020c470d000b0b02402000280204450d002000280200102a0b0bce0101057f024020002802082201450d00200028020022022001411c6c6a21030340024020022802042200450d0002402002410c6a2802002201450d00200141047421010340024020002d00004109470d000240200041046a2204280200220528020441ffffffff0371450d002005280200102a200428020021050b2005102a0b200041106a2100200141706a22010d000b0b200241086a280200450d002002280204102a0b2002411c6a21000240200241146a280200450d002002280210102a0b2000210220002003470d000b0b0b90d20106067f017e057f017e117f027e2300419081046b220224000240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002402001280204220320012802082204460d00200441016a22052004490d02200320054f0d0120052003103c000b200241013a0030200241fc006a41013602002002420137026c200241a4e2c5003602682002412636021c2002200241186a3602782002200241306a360218200241f880046a200241e8006a103320022802f88004210420022802fc8004210120004101360200200041003a00042001450d2b2004102a0c2b0b200128020020046a2d00002104200120053602082004410c4b0d03024002400240024020040e0d0001161514131211060d0c0b05000b200241e8006a200110f40441012106200228026c2107024020022802684101470d0020074108762101200241f8006a2802002104200241e8006a41086a29030021080c270b41002109200241e8006a4100418080011099051a410021034100210a2007450d20410021054100210a410121064100210b0340024002402001280204220c200128020822036b2007200b6b220441808001200441808001491b2204490d00200320046a220d2003490d05200c200d4f0d01200d200c103c000b200241013a00e880042002418c81046a4101360200200242013702fc8004200241a4e2c5003602f880042002412636021c2002200241186a36028881042002200241e880046a360218200241306a200241f880046a10332002290330210820022802382104410521070240200a450d002006102a0b0c280b200241e8006a200128020020036a2004109a051a2001200d36020802400240200a20056b2004490d00200520046a21030c010b200520046a22032005490d23200a410174220d2003200d20034b1b220d4100480d2302400240200a0d00200d102821060c010b2006200a200d102c21060b2006450d03200d210a0b200620056a200241e8006a2004109a051a2003210520072004200b6a220b4b0d000c210b0b200241e8006a200110fb04024020022802684101470d00200228026c22044108762105200241e8006a41086a2903002208422088210e200241f8006a28020021030c1f0b200241fc006a280200210f200241f8006a2802002101200241f4006a2802002103200241f0006a2802002110200228026c210b4100210441002109024002400240034002402004411f4d0d00410f21040c020b0240024020032001460d002001417f460d052003200141016a22054f0d01200141016a2003103c000b200241013a0030200241fc006a41013602002002420137026c200241a4e2c5003602682002412636021c2002200241186a3602782002200241306a360218200241c8006a200241e8006a1033410521040c020b200b20016a2d0000220641ff00712004411f71742009722109200441076a2104200521012006418001710d000b20044120490d01410d210420064110490d010b200241f880046a41086a200241c8006a41086a28020022033602002002200229034822083703f880042008422088a721092008a721060c1f0b200241003602602002420437035802400240024020090d00410421010c010b410020036b2111200b41026a2112410120036b21134100210a410421014100211441002115410021160340201621170240024020032005460d000240200541016a22042005490d000240024020032004490d000240200b20056a2d0000220441e000460d00411821050c250b201741016a211641022118200541026a210441002106410321192012211a4100211b024002400340201a21072019210c2018210d02402006411f4d0d00410f21050c020b02400240201320046a4102460d002004450d06200320044f0d0120042003103c000b200241013a00302002410136027c2002420137026c200241a4e2c5003602682002412636021c2002200241186a3602782002200241306a360218200241f880046a200241e8006a1033200241206a41086a200241f880046a41086a280200360200200220022903f88004370320410521050c020b200b20046a417f6a2d0000221c41ff00712006411f7174201b72211b200d41016a2118200c41016a2119200741016a211a200441016a2104200641076a2106201c418001710d000b20064120490d01201c4110490d01410d21050b200241e880046a41086a200241206a41086a28020022033602002002200229032022083703e880042008a721064100210420022802ec800421090c240b41002118200241003602382002420137033002400240201b0d002004417f6a21064101211c4100211a4100211d0c010b201120056a211e410021194101211c4100211a034002400240024002400240201e200d6a450d002005200c6a2204450d02200320044f0d0120042003103c000b200220193602342002201a3602382002201c360230200241013a00e880042002410136027c2002420137026c200241a4e2c5003602682002412636021c2002200241186a3602782002200241e880046a360218200241f880046a200241e8006a103320022802f88004210620022802fc80042109200228028081042103410521050c280b200720056a2c000022044100480d0102400240200441c00071450d00200441807f72220441ff017141fb014b0d010b200220193602342002201a3602382002201c360230410621050c270b0240201a2019460d002019211d201a21060c030b201941016a22062019490d2e2019410174221d2006201d20064b1b221d4100480d2e0240024020190d00201d1028211c0c010b201c2019201d102c211c0b0240201c450d0020192106201d21190c030b201d41011037000b417f20041044000b200220193602342002201a3602382002201c360230411921050c240b201c20066a2004417f733a0000200d41016a210d200c41016a210c200741016a2107201b201a41016a221a470d000b2002201d3602342002201a3602382002201c3602302005200d6a21060b201c411076411074221b201c41087641ff0171410874221972201c41ff0171221c72210c4100210d024003404100210402402018411f4d0d00410f21050c230b0240024020032006460d002006417f460d032003200641016a22054f0d01200641016a2003103c000b200241013a00302002410136027c2002420137026c200241a4e2c5003602682002412636021c2002200241186a3602782002200241306a360218200241f880046a200241e8006a103320022802f88004210620022802fc8004210920022d00808104210320022d00818104210720022f01828104210d410521050c230b200b20066a2d0000220741ff00712018411f7174200d72210d201841076a2118200521062007418001710d000b20184120490d052007410f4d0d05410d21050c210b417f200641016a1044000b20042003103c000b417f20041044000b417f20041044000b200241013a00302002410136027c2002420137026c200241a4e2c5003602682002412636021c2002200241186a3602782002200241306a360218200241f880046a200241e8006a103320022802f88004210620022802fc8004210920022d00808104210320022d00818104210720022f01828104210d410521050c200b0240200d41014d0d004104210541e885c6002106412421090c1b0b024002400240200d0e020001000b410421060c010b20032005460d1a024002400240200541016a220d2005490d002003200d490d010240200b20056a2c0000220441004e0d00411921050c200b41062105200441c00071450d02200441807f72220441ff017141fb014d0d022004417f732106200d21050c030b417f200541016a1044000b200541016a2003103c000b0c1c0b024020172015470d00024020142015460d00201421150c010b201441016a22042014490d252014410174220d2004200d20044b1b221541ffffffff00712015470d25201541047422044100480d250240024020140d002004102821010c010b200120144104742004102c21010b2001450d032002201536025c20022001360258201521140b200120174104746a2204201f4180807c71200641ff01714108747241e00072221f36020c2004201a3602082004201d36020420042019201c72201b72360200200a41106a210a2002201636026020162009470d000b0b2005200f462104200229025c2208422088210e02402010450d00200b102a0b200ea721052008a721092004450d1e2005ad4220862009ad842108410221030c2a0b200441041037000b417f200141016a1044000b200d41011037000b2003200d1044000b417f20051044000b200241e8006a200110fb04024020022802684101470d00200041013602002000200241e8006a41047222012902003702042000410c6a200141086a2902003702000c290b200241fc006a280200210d200241f8006a2802002104200241f4006a2802002105200241f0006a280200210a200228026c210b410021034100210102400240034002402003411f4d0d00410f21040c080b20052004460d062004417f460d012005200441016a2206490d02200b20046a2d0000220941ff00712003411f71742001722101200341076a2103200621042009418001710d000b20034120490d04410d21042009410f4b0d060c040b417f200441016a1044000b200441016a2005103c000b200241e8006a200110fb04024020022802684101470d00200041013602002000200241e8006a41047222012902003702042000410c6a200141086a2902003702000c280b200241fc006a280200210d200241f8006a2802002104200241f4006a2802002105200241f0006a280200210a200228026c210b410021034100210102400240034002402003411f4d0d00410f21040c0d0b20052004460d0b2004417f460d012005200441016a2206490d02200b20046a2d0000220941ff00712003411f71742001722101200341076a2103200621042009418001710d000b20034120490d09410d21042009410f4b0d0b0c090b417f200441016a1044000b200441016a2005103c000b200041123a000420004101360200200041056a20043a00000c260b200d20064621040240200a450d00200b102a0b02402004450d00410b21030c220b20024103410220041b3a00e88004200241fc006a41013602002002420137026c200241a4e2c5003602682002412636021c2002200241186a3602782002200241e880046a360218200241306a200241e8006a10332002418381046a200241386a280200360000200220022903303700fb8004200041053a0004200020022900f880043700052000410c6a200241ff80046a290000370000200041013602000c250b200241013a0030200241fc006a41013602002002420137026c200241a4e2c5003602682002412636021c2002200241186a3602782002200241306a360218200241f880046a200241e8006a1033410521040b2000200436020420004101360200200041086a20022902f88004370200200041106a200241f880046a41086a280200360200200a450d23200b102a0c230b200241e8006a200110fb040240024020022802684101470d00200228026c22014108762106200241e8006a41086a2903002208422088210e200241f8006a280200210b0c010b200241c0006a200241fc006a280200360200200241386a200241f4006a2902003703002002200229026c37033041002101410021050240024002400240024002400240034002402001411f4d0d00410f210d0c020b0240024020022802382209200228023c2204460d00200441016a22032004490d05200920034f0d0120032009103c000b200241013a00e88004200241fc006a41013602002002420137026c200241a4e2c5003602682002412636021c2002200241186a3602782002200241e880046a360218200241c8006a200241e8006a10334105210d0c020b200228023020046a2d000021042002200336023c200441ff00712001411f71742005722105200141076a21012004418001710d000b20014120490d01410d210d20044110490d010b200241f880046a41086a200241c8006a41086a280200220b3602002002200229034822083703f880042008422088a721072008a7210c410021060c040b200241003602502002420437034802400240024020050d00410421010c010b4100210d0340200d41016a210d41002101410021090240024002400240024002400240034002402001411f4d0d00410f210d0c030b20022802382206200228023c2204460d01200441016a22032004490d0420062003490d06200228023020046a2d000021042002200336023c200441ff00712001411f71742009722109200141076a21012004418001710d000b20014120490d022004410f4d0d02410d210d0c010b200241013a00582002410136027c2002420137026c200241a4e2c5003602682002412636021c2002200241186a3602782002200241d8006a360218200241f880046a200241e8006a1033200241e880046a41086a200241f880046a41086a280200360200200220022903f8800422083703e880042008a7210c4105210d0b20022802f08004210b20022802ec80042107410021060c0a0b200241e8006a200241306a10ed04024020022802684101470d00200228026c220d41087621062002280278210b200228027421072002280270210c0c0a0b200228027421192002280270211c200228026c211a410021044100210b02400240034002402004411f4d0d00410f210d0c020b0240024020022802382206200228023c2203460d00200341016a22012003490d06200620014f0d0120012006103c000b200241013a00e880042002410136027c2002420137026c200241a4e2c5003602682002412636021c2002200241186a3602782002200241e880046a360218200241f880046a200241e8006a1033200241206a41086a200241f880046a41086a280200360200200220022903f8800422083703202008a7210c4105210d0c030b2002280230220a20036a2d000021032002200136023c200341ff00712004411f7174200b72210b200441076a21042003418001710d000b20044120490d0520034110490d05410d210d0b0b2002280228210b200228022421070c080b417f20031044000b417f20011044000b20032006103c000b4100211b200241e8006a4100418080041099051a02400240200b0d00410121184100210c0c010b4100211b41012118410021034100210702400240034002400240200620016b200b20076b220441808004200441808004491b2204490d00200120046a220c2001490d032006200c4f0d01200c2006103c000b200241013a00202002410136028c8104200242013702fc8004200241a4e2c5003602f880042002412636021c2002200241186a36028881042002200241206a360218200241e880046a200241f880046a103320022802e88004210c20022802ec8004210720022802f08004210b4105210d201b450d092018102a0c090b200241e8006a200a20016a2004109a051a2002200c36023c02400240201b20036b2004490d00200320046a210c0c010b200320046a220c2003490d24201b4101742201200c2001200c4b1b22014100480d2402400240201b0d002001102821180c010b2018201b2001102c21180b2018450d032001211b0b201820036a200241e8006a2004109a051a200b200420076a22074d0d03200228023c2101200228023821062002280230210a200c21030c000b0b2001200c1044000b200141011037000b024020022802502203200228024c470d00200341016a22012003490d20200341017422042001200420014b1b2204ad421c7e2208422088a70d202008a722064100480d200240024020030d002006102821010c010b20022802482003411c6c2006102c21010b2001450d032002200436024c200220013602480b200228024822012003411c6c6a2204200941087622063b0001200420183602102004201a360204200420093a0000200441036a20064110763a0000200441186a200c360200200441146a201b3602002004410c6a2019360200200441086a201c3602002002200341016a360250200d2005470d000b0b200228023c2002280240462104200229024c2208422088210e02402002280234450d002002280230102a0b20014108762105200ea721032008a7210a2004450d052005410874200141ff01717221012003ad422086200aad842108410d21030c250b200641041037000b417f20031044000b02402019450d0020194104742104201a21010340024020012d00004109470d000240200141046a2205280200220328020441ffffffff0371450d002003280200102a200528020021030b2003102a0b200141106a2101200441706a22040d000b0b41002106201c450d00201a102a0b2002280248211b024020022802502201450d00201b2001411c6c6a210a201b21090340024020092802042201450d0002402009410c6a2802002204450d00200441047421040340024020012d00004109470d000240200141046a2205280200220328020441ffffffff0371450d002003280200102a200528020021030b2003102a0b200141106a2101200441706a22040d000b0b200941086a280200450d002009280204102a0b2009411c6a21010240200941146a280200450d002009280210102a0b200121092001200a470d000b0b200228024c450d00201b102a0b2006410874200d41ff01717221012007ad220e422086200cad8421082002280234450d012002280230102a0c010b2005410874200141ff017172210d20024103410220041b3a00e88004200241e8006a41146a41013602002002420137026c200241a4e2c5003602682002412636021c2002200241186a3602782002200241e880046a360218200241f880046a200241e8006a103320022903f88004210820022802808104210b02402003450d00200d2003411c6c6a2106200d21090340024020092802042201450d0002402009410c6a2802002204450d00200441047421040340024020012d00004109470d000240200141046a2205280200220328020441ffffffff0371450d002003280200102a200528020021030b2003102a0b200141106a2101200441706a22040d000b0b200941086a280200450d002009280204102a0b2009411c6a21010240200941146a280200450d002009280210102a0b2001210920012006470d000b0b2008422088210e4105210141002106200a450d00200d102a0b20004101360200200041106a200b360200200041086a200e422086200842ffffffff0f838437020020002006410874200141ff0171723602040c220b200241e8006a200110fb040240024020022802684101470d00200228026c220a4108762104200241e8006a41086a2903002208422088210e200241f8006a280200210d0c010b200241fc006a280200211b200241f8006a2802002101200241f4006a2802002105200241f0006a2802002107200228026c210b410021044100210902400240024002400240024002400240024002400240034002402004411f4d0d00410f210a0c020b0240024020052001460d002001417f460d052005200141016a22034f0d01200141016a2005103c000b200241013a00e88004200241fc006a41013602002002420137026c200241a4e2c5003602682002412636021c2002200241186a3602782002200241e880046a360218200241f880046a200241e8006a10334105210a0c020b200b20016a2d0000220641ff00712004411f71742009722109200441076a2104200321012006418001710d000b20044120490d01410d210a20064110490d010b200241306a41086a200241f880046a41086a280200220d360200200220022902f8800422083703302008422088a7210c2008a7211b0c080b2002410036026020024204370358024002400240024020090d00410421010c010b200241f1006a21104100211c0340201c41016a211c410021014100210602400240024002400240024002400240024002400240024002400240034002402001411f4d0d00410f210a0c020b0240024020052003460d002003417f460d062005200341016a22044f0d01200341016a2005103c000b200241013a00f880042002410136027c2002420137026c200241a4e2c5003602682002412636021c2002200241186a3602782002200241f880046a360218200241c8006a200241e8006a10334105210a2002280248211b0c030b200b20036a2d0000220a41ff00712001411f71742006722106200141076a210120042103200a418001710d000b20014120490d02200a4110490d02410d210a0b0b2002280250210d200228024c210c0c160b4100210c200241e8006a4100418080011099051a410121180240024020060d00200421034100211a4100210a0c010b4100210d4100211a41002119034002400240200520046b200620196b220141808001200141808001491b2201490d00200420016a22032004490d05200520034f0d0120032005103c000b200241013a00482002410136028c8104200242013702fc8004200241a4e2c5003602f880042002412636021c2002200241186a36028881042002200241c8006a360218200241e880046a200241f880046a103320022802e88004211b20022802ec8004210c20022802f08004210d4105210a201a450d182018102a0c180b200241e8006a200b20046a2001109a051a02400240201a200d6b2001490d00200d20016a210a0c010b200d20016a220a200d490d31201a4101742204200a2004200a4b1b22044100480d3102400240201a0d002004102821180c010b2018201a2004102c21180b2018450d052004211a0b2018200d6a200241e8006a2001109a051a20032104200a210d2006200120196a22194b0d000b0b2002200a3602402002410036023c2002200a3602382002201aad4220862018ad84370330410021014100210d02400240034002402001411f4d0d00410f210a0c020b02400240200a200c460d00200c417f460d08200a200c41016a22064f0d01200c41016a200a103c000b200241013a00482002410136027c2002420137026c200241a4e2c5003602682002412636021c2002200241186a3602782002200241c8006a360218200241f880046a200241e8006a1033200241206a41086a200241f880046a41086a280200360200200220022903f880043703204105210a0c020b2018200c6a2d000021042002200636023c200441ff00712001411f7174200d72210d200141076a21012006210c2004418001710d000b20014120490d0120044110490d01410d210a0b200241e880046a41086a200241206a41086a280200220d3602002002200229032022083703e880042008a7211b20022802ec8004210c0c150b41002119200241003602f08004200242043703e8800402400240200d0d004104210f41002118410021160c010b410021184104210f410021160340201821172016221d41016a2116410021014100210c024002400240034002402001411f4d0d00410f21040c020b0240024020022802382218200228023c2204460d00200441016a22062004490d0c201820064f0d0120062018103c000b200241013a00f880042002410136027c2002420137026c200241a4e2c5003602682002412636021c2002200241186a3602782002200241f880046a360218200241c8006a200241e8006a1033410521042002280248211b0c030b2002280230221a20046a2d0000210a2002200636023c200a41ff00712001411f7174200c72210c200141076a2101200a418001710d000b20014120490d02200a4110490d02410d21040b0b2002280250210d200228024c210c410021010c0c0b02400240024020182006460d00200441026a21042006417f460d0a20182004490d0c201a20066a2c000021012002200436023c0240200141004e0d00411921040c0f0b41062104200141c00071450d0d200141807f72220141ff017141fb014d0d0d201d2017460d0120172118201d21170c020b200241013a00482002410136027c2002420137026c200241a4e2c5003602682002412636021c2002200241186a3602782002200241c8006a360218200241f880046a200241e8006a103320022802f88004211b20022802fc8004210c20022802808104210d410521040c0d0b201741016a22042017490d31201741017422062004200620044b1b221841ffffffff01712018470d31201841037422044100480d310240024020170d0020041028210f0c010b200f20174103742004102c210f0b200f450d092002200f3602e880040b200f20174103746a2204201341807e712001417f7341ff01717222133a00042004200c3602002016200d470d000b200220183602ec8004200220163602f080040b200f20164103746a210d200f2101200f210602400340200d20066b41184d0d01201920012802006a22042019490d132004200141086a2802006a22062004490d132006200141106a2802006a22042006490d13200141186a210a200141206a220621012004200a2802006a22192004490d130c000b0b0340200d2001460d0b201920012802006a22042019492106200141086a21012004211920060d120c000b0b417f200341016a1044000b200420031044000b200441011037000b417f200c41016a1044000b417f20061044000b417f20041044000b200441041037000b20042018103c000b0b200220173602ec80042002201d3602f08004200141ff0171410874200472210a20170d090c0a0b4101210a410021044108211a410021060340200241e8006a200241306a10ee04024020022802684101470d002002280278210d2002280274210c2002280270211b200228026c210a0c070b200241f880046a41026a2201201041026a2d00003a0000200220102f00003b01f8800420022802742117200229037821080240024002400240024020022d0070220d4106470d00200a417f6a210a0c010b200d417e6a41034f0d00200a41016a220c200a4f2119200c210a20190d004115210c41c4fdc500211b4104210a200d4109460d010c0a0b200241e8006a41026a220c20012d00003a0000200220022f01f880043b016820062004460d01200421190c020b0240201728020441ffffffff0371450d002017280200102a0b2017102a0c080b200441016a22012004490d25200441017422062001200620014b1b221941ffffffff00712019470d25201941047422014100480d250240024020040d0020011028211a0c010b201a20044104742001102c211a0b201a450d0420042106201921040b201a20064104746a2201200d3a00002001200837030820012017360204200120022f01683b0001200141036a200c2d00003a0000200641016a2106200a0d000b200228023c200228024046210102402002280234450d002002280230102a0b0240024002402001450d002002280260220a200228025c470d02200a41016a2201200a490d26200a41017422042001200420014b1b220dad42187e2208422088a70d262008a7220441004e0d010c260b20024103410220011b3a00e880042002410136027c2002420137026c200241a4e2c5003602682002412636021c2002200241186a3602782002200241e880046a360218200241f880046a200241e8006a103320022802f88004211b20022802fc8004210c20022802808104210d02402006450d0020064104742104201a21010340024020012d00004109470d000240200141046a2205280200220328020441ffffffff0371450d002003280200102a200528020021030b2003102a0b200141106a2101200441706a22040d000b0b02402019450d00201a102a0b4105210a2018450d0c200f102a0c0c0b02400240200a0d002004102821010c010b2002280258200a41186c2004102c21010b2001450d042002200d36025c200220013602580b20022802582201200a41186c6a2204201a36020c20042016360208200420183602042004200f360200200441146a2006360200200441106a20193602002002200a41016a360260201c2009470d000b0b2003201b462104200229025c2208422088210e02402007450d00200b102a0b200ea721032008a721072004450d0a2003ad4220862007ad842108410c21030c290b200141081037000b200441041037000b417f200141016a1044000b02402006450d0020064104742103201a21010340024020012d00004109470d000240200141046a2209280200220528020441ffffffff0371450d002005280200102a200928020021050b2005102a0b200141106a2101200341706a22030d000b0b2004450d01201a102a0c010b20022802808104210d20022802fc8004210c411c210a0b2018450d010b200f102a0b2002280234450d002002280230102a0b20022802582118024020022802602201450d002018200141186c6a21062018210903400240200941046a280200450d002009280200102a0b0240200941146a2802002204450d00200928020c2101200441047421040340024020012d00004109470d000240200141046a2205280200220328020441ffffffff0371450d002003280200102a200528020021030b2003102a0b200141106a2101200441706a22040d000b0b200941186a21010240200941106a280200450d00200928020c102a0b2001210920012006470d000b0b200228025c450d002018102a0b200a4108762104200cad220e422086201bad8421082007450d01200b102a0c010b20024103410220041b3a0030200241e8006a41146a41013602002002420137026c200241a4e2c5003602682002412636021c2002200241186a3602782002200241306a360218200241f880046a200241e8006a103320022903f88004210820022802808104210d02402003450d002001200341186c6a210b2001210603400240200641046a280200450d002006280200102a0b0240200641146a2802002203450d00200628020c2104200341047421030340024020042d00004109470d000240200441046a2209280200220528020441ffffffff0371450d002005280200102a200928020021050b2005102a0b200441106a2104200341706a22030d000b0b200641186a21040240200641106a280200450d00200628020c102a0b200421062004200b470d000b0b2008422088210e4105210a410021042007450d002001102a0b20004101360200200041106a200d360200200041086a200e422086200842ffffffff0f838437020020002004410874200a41ff0171723602040c210b200241e8006a200110fb040240024020022802684101470d00200228026c22044108762106200241e8006a41086a2903002208422088210e200241f8006a280200210b0c010b2002418881046a200241fc006a2802003602002002418081046a200241f4006a2902003703002002200229026c3703f880044100210141002105024002400240024002400240024002400240034002402001411f4d0d00410f210d0c020b02400240200228028081042209200228028481042204460d00200441016a22032004490d05200920034f0d0120032009103c000b200241013a0058200241fc006a41013602002002420137026c200241a4e2c5003602682002412636021c2002200241186a3602782002200241d8006a360218200241306a200241e8006a1033200241e880046a41086a200241306a41086a280200360200200220022903303703e880044105210d0c020b20022802f8800420046a2d00002104200220033602848104200441ff00712001411f71742005722105200141076a21012004418001710d000b20014120490d01410d210d20044110490d010b200241c8006a41086a200241e880046a41086a280200220b360200200220022903e8800422083703482008422088a721072008a7210c410021060c060b200241003602f08004200242043703e880040240024020050d00410421010c010b4100210b0340200b41016a210b410021014100210902400240024002400240034002402001411f4d0d00410f210d0c030b200228028081042206200228028481042204460d01200441016a22032004490d0920062003490d0c20022802f8800420046a2d00002104200220033602848104200441ff00712001411f71742009722109200141076a21012004418001710d000b20014120490d022004410f4d0d02410d210d0c010b200241013a00582002410136027c2002420137026c200241a4e2c5003602682002412636021c2002200241186a3602782002200241d8006a360218200241306a200241e8006a1033200241206a41086a200241306a41086a2802003602002002200229033022083703202008a7210c4105210d0b2002280228210b20022802242107410021060c010b200241e8006a200241f880046a10ed04024020022802684101470d00200228026c220d41087621062002280278210b200228027421072002280270210c0c010b2002280274211b20022802702119200228026c2118200241e8006a200241f880046a10ef0420022802684101470d01200228026c210d2002280278210b200228027421072002280270210c0240201b450d00201b4104742104201821010340024020012d00004109470d000240200141046a2205280200220328020441ffffffff0371450d002003280200102a200528020021030b2003102a0b200141106a2101200441706a22040d000b0b200d41087621062019450d002018102a0b20022802e88004211b024020022802f080042201450d00201b2001411c6c6a210a201b21090340024020092802042201450d0002402009410c6a2802002204450d00200441047421040340024020012d00004109470d000240200141046a2205280200220328020441ffffffff0371450d002003280200102a200528020021030b2003102a0b200141106a2101200441706a22040d000b0b200941086a280200450d002009280204102a0b2009411c6a21010240200941146a280200450d002009280210102a0b200121092001200a470d000b0b20022802ec8004450d08201b102a0c080b4100210a2002280270210c200228026c2107024002402002280274220141027422030d004104210d410021060c010b2003410275220641ffffffff03712006470d1f200641027422044100480d1f20041028220d450d050b02402001450d002003417c6a210a200d210120072104034020012004280200360200200141046a2101200441046a21042003417c6a22030d000b200a41027641016a210a0b0240200c450d002007102a0b024020022802f08004220320022802ec8004470d00200341016a22012003490d1f200341017422042001200420014b1b2204ad421c7e2208422088a70d1f2008a722074100480d1f0240024020030d002007102821010c010b20022802e880042003411c6c2007102c21010b2001450d06200220043602ec8004200220013602e880040b20022802e8800422012003411c6c6a2204200941087622073b00012004200d36021020042018360204200420093a0000200441036a20074110763a0000200441186a200a360200200441146a20063602002004410c6a201b360200200441086a20193602002002200341016a3602f08004200b2005470d000b0b200228028481042002280288810446210420022902ec80042208422088210e024020022802fc8004450d0020022802f88004102a0b200ea721032008a7210d2004450d062003ad422086200dad842108410a21030c240b417f20031044000b417f20031044000b200441041037000b200741041037000b20032006103c000b2006410874200d41ff01717221042007ad220e422086200cad84210820022802fc8004450d0120022802f88004102a0c010b20024103410220041b3a00e88004200241e8006a41146a41013602002002420137026c200241a4e2c5003602682002412636021c2002200241186a3602782002200241e880046a360218200241306a200241e8006a1033200229033021082002280238210b02402003450d0020012003411c6c6a210a200121060340024020062802042204450d0002402006410c6a2802002203450d00200341047421030340024020042d00004109470d000240200441046a2209280200220528020441ffffffff0371450d002005280200102a200928020021050b2005102a0b200441106a2104200341706a22030d000b0b200641086a280200450d002006280204102a0b2006411c6a21040240200641146a280200450d002006280210102a0b200421062004200a470d000b0b2008422088210e4105210441002106200d450d002001102a0b20004101360200200041106a200b360200200041086a200e422086200842ffffffff0f838437020020002006410874200441ff0171723602040c200b200d20064621040240200a450d00200b102a0b02402004450d00410921030c1c0b20024103410220041b3a00e88004200241fc006a41013602002002420137026c200241a4e2c5003602682002412636021c2002200241186a3602782002200241e880046a360218200241306a200241e8006a10332002418381046a200241386a280200360000200220022903303700fb8004200041053a0004200020022900f880043700052000410c6a200241ff80046a290000370000200041013602000c1f0b200241013a0030200241fc006a41013602002002420137026c200241a4e2c5003602682002412636021c2002200241186a3602782002200241306a360218200241f880046a200241e8006a1033410521040b2000200436020420004101360200200041086a20022902f88004370200200041106a200241f880046a41086a280200360200200a450d1d200b102a0c1d0b200241e8006a200110fb040240024020022802684101470d00200228026c22034108762104200241e8006a41086a2903002208422088210e200241f8006a28020021090c010b2002418881046a200241fc006a2802003602002002418081046a200241f4006a2902003703002002200229026c3703f880044100210141002105024002400240024002400240024002400240024002400240024002400240024002400240034002402001411f4d0d00410f21030c020b02400240200228028081042209200228028481042204460d00200441016a22032004490d05200920034f0d0120032009103c000b200241013a0058200241fc006a41013602002002420137026c200241a4e2c5003602682002412636021c2002200241186a3602782002200241d8006a360218200241306a200241e8006a1033200241206a41086a200241306a41086a28020036020020022002290330370320410521030c020b20022802f8800420046a2d00002104200220033602848104200441ff00712001411f71742005722105200141076a21012004418001710d000b20014120490d01410d210320044110490d010b200241e880046a41086a200241206a41086a28020022093602002002200229032022083703e880042008422088a721062008a7210b0c100b20024100360260200242043703584104210102402005450d004100211b4100210c4100211a0340200241e8006a200241f880046a10fc04024020022802684101470d002002200229027422083703e880042002280270210b200228026c21032008a721060c100b20022802702118200228026c211902400240200228028081042203200228028481042209460d00200941016a22042009490d05200320044f0d0120042003103c000b200241013a00482002410136027c2002420137026c200241a4e2c5003602682002412636021c2002200241186a3602782002200241c8006a360218200241306a200241e8006a10330c0d0b2002280274211c20022802f88004220620096a2d000021072002200436028481040240200741034d0d00410a21040c0f0b0240024002400240024020070e0400010203000b410021074100210b4100210903400240200b411f4d0d00410f21040c140b20032004460d122004417f460d092003200441016a220d490d0e200620046a2d0000210a2002200d3602848104200a41ff0071200b411f71742009722109200b41076a210b200d2104200a418001710d000b41002107200b4120490d03200a410f4d0d03410d21040c120b4100210b410021090340200b411f4b0d0f0240024020032004460d002004417f460d0b2003200441016a220d4f0d01200441016a2003103c000b200241013a00482002410136027c2002420137026c200241a4e2c5003602682002412636021c2002200241186a3602782002200241c8006a360218200241306a200241e8006a10330c110b200620046a2d0000210a2002200d3602848104200a41ff0071200b411f71742009722109200b41076a210b200d2104200a418001710d000b41012107200b4120490d02200a410f4d0d020c0d0b4100210b410021090340200b411f4b0d0e0240024020032004460d002004417f460d0b2003200441016a220d4f0d01200441016a2003103c000b200241013a00482002410136027c2002420137026c200241a4e2c5003602682002412636021c2002200241186a3602782002200241c8006a360218200241306a200241e8006a10330c100b200620046a2d0000210a2002200d3602848104200a41ff0071200b411f71742009722109200b41076a210b200d2104200a418001710d000b41022107200b4120490d01200a410f4b0d0c0c010b4100210b410021090340200b411f4b0d0d0240024020032004460d002004417f460d0b2003200441016a220d4f0d01200441016a2003103c000b200241013a00482002410136027c2002420137026c200241a4e2c5003602682002412636021c2002200241186a3602782002200241c8006a360218200241306a200241e8006a10330c0f0b200620046a2d0000210a2002200d3602848104200a41ff0071200b411f71742009722109200b41076a210b200d2104200a418001710d000b41032107200b4120490d00200a410f4b0d0b0b200220093602f08004200220073602ec800420022902ec8004210802400240200c201b460d00201b21030c010b201b41016a2204201b490d24201b41017422032004200320044b1b2203ad42147e220e422088a70d24200ea722044100480d2402400240201b0d002004102821010c010b2001201b41146c2004102c21010b2001450d0920022001360258201b210c2003211b0b2001200c41146c6a2204200837020c2004201c3602082004201836020420042019360200200c41016a210c201a41016a221a2005470d000b2002200336025c2002200c3602600b2002280284810420022802888104462104200229025c2208422088210e024020022802fc8004450d0020022802f88004102a0b200ea721032008a721052004450d0e2003ad4220862005ad842108410821030c290b417f20031044000b417f20041044000b417f200441016a1044000b417f200441016a1044000b417f200441016a1044000b417f200441016a1044000b200441041037000b200441016a2003103c000b410d2104410021070c030b410f2104410021070c020b2002280230210b2002290234210841052104410021070c010b200241013a00482002410136027c2002420137026c200241a4e2c5003602682002412636021c2002200241186a3602782002200241c8006a360218200241306a200241e8006a10332002280230210b20022902342108410521040b20074108742004722103200220083703e880042008a721062018450d002019102a0b2002200c3602602002201b36025c20022802ec800421090240200c450d00200c41146c21052001210403400240200441046a280200450d002004280200102a0b200441146a21042005416c6a22050d000b0b201b450d012001102a0c010b20024103410220041b3a00e88004200241e8006a41146a41013602002002420137026c200241a4e2c5003602682002412636021c2002200241186a3602782002200241e880046a360218200241306a200241e8006a1033200229033021082002280238210902402003450d00200341146c21032001210403400240200441046a280200450d002004280200102a0b200441146a21042003416c6a22030d000b0b2008422088210e41052103410021042005450d012001102a0c010b200341087621042006ad220e422086200bad84210820022802fc8004450d0020022802f88004102a0b20004101360200200041106a2009360200200041086a200e422086200842ffffffff0f838437020020002004410874200341ff0171723602040c1c0b200241e8006a200110fb040240024020022802684101470d00200228026c220b4108762104200241e8006a41086a2903002208422088210e200241f8006a28020021060c010b200241c0006a200241fc006a280200360200200241386a200241f4006a2902003703002002200229026c37033041002101410021090240024002400240024002400240024002400240024002400240034002402001411f4d0d00410f210b0c020b0240024020022802382205200228023c2204460d00200441016a22032004490d05200520034f0d0120032005103c000b200241013a0058200241fc006a41013602002002420137026c200241a4e2c5003602682002412636021c2002200241186a3602782002200241d8006a360218200241f880046a200241e8006a1033200241206a41086a200241f880046a41086a280200360200200220022903f880043703204105210b0c020b2002280230220620046a2d000021042002200336023c200441ff00712001411f71742009722109200141076a21012004418001710d000b20014120490d01410d210b20044110490d010b200241e880046a41086a200241206a41086a28020022063602002002200229032022083703e880042008422088a721072008a7210d0c0b0b20024100360260200242043703580240024020090d00410421010c010b2009417f6a211b4104210141042110410421094104211c4104211a4100210a4100210c03400240024020052003460d00200341016a220b2003490d052005200b4f0d01200b2005103c000b2002200a36025c2002200c360260200241013a0048200241fc006a41013602002002420137026c200241a4e2c5003602682002412636021c2002200241186a3602782002200241c8006a360218200241e880046a200241e8006a103320022802e88004210d20022802ec8004210720022802f080042106410521010c090b200620036a2c000021042002200b36023c20044100480d0402400240200441c00071450d00200441807f72220441ff017141fb014b0d010b2002200a36025c2002200c360260410621010c080b024002400240024002402005200b460d00200341026a210d200b417f460d0a2005200d4f0d01200d2005103c000b2002200a36025c2002200c360260200241013a0048200241fc006a41013602002002420137026c200241a4e2c5003602682002412636021c2002200241186a3602782002200241c8006a360218200241e880046a200241e8006a103320022802e88004210d20022802ec8004210720022802f080042106410521010c010b2006200b6a2d000021032002200d36023c0240200341014b0d004100210520030e020302030b2002200a36025c2002200c360260410c21010b2002418881046a20063602002002418481046a20073602002002418081046a200d360200200220033a00fd8004200220013a00fc80040c0b0b41800221050b200241e8006a200241306a10ed04200228027421072002280270210d200228026c210b024020022802684101470d002002200a36025c2002200c360260200241f8006a28020021060c0b0b02400240200c200a460d00200a2118200c210a0c010b200a41016a2201200a490d1e200a41017422032001200320014b1b221841ffffffff00712018470d1e201841047422034100480d1e02400240200a0d002003102821010c010b201c200a4104742003102c21010b2001450d072002200136025820012110200121092001211c2001211a0b201a200a4104746a220320194180807c712004417f7341ff017172200572221936020c200320073602082003200d3602042003200b360200200a41016a210c0240201b450d00201b417f6a211b200228023c210320022802382105200228023021062018210a0c010b0b2002201836025c2002200c3602600b200228023c2002280240462104200229025c2208422088210e02402002280234450d002002280230102a0b200ea721032008a7210d2004450d092003ad422086200dad842108410721030c230b417f20031044000b417f200b1044000b2002200a36025c2002200c360260411921010c020b417f200d1044000b200341041037000b0b2002418881046a20063602002002418481046a20073602002002418081046a200d360200200220043a00fd8004200220013a00fc80040b200241013a00f8800420022802fc8004210b0b0240200c450d002009200c4104746a210c0340024020092802082204450d0020092802002101200441047421040340024020012d00004109470d000240200141046a2205280200220328020441ffffffff0371450d002003280200102a200528020021030b2003102a0b200141106a2101200441706a22040d000b0b200941106a21010240200941046a280200450d002009280200102a0b200121092001200c470d000b0b200a450d012010102a0c010b20024103410220041b3a00e88004200241fc006a41013602002002420137026c200241a4e2c5003602682002412636021c2002200241186a3602782002200241e880046a360218200241f880046a200241e8006a103320022903f88004210820022802808104210602402003450d00200120034104746a210a2001210b03400240200b2802082203450d00200b2802002104200341047421030340024020042d00004109470d000240200441046a2209280200220528020441ffffffff0371450d002005280200102a200928020021050b2005102a0b200441106a2104200341706a22030d000b0b200b41106a21040240200b41046a280200450d00200b280200102a0b2004210b2004200a470d000b0b2008422088210e4105210b41002104200d450d012001102a0c010b200b41087621042007ad220e422086200dad8421082002280234450d002002280230102a0b20004101360200200041106a2006360200200041086a200e422086200842ffffffff0f838437020020002004410874200b41ff0171723602040c1b0b200241e8006a200110fb040240024020022802684101470d00200228026c22034108762105200241e8006a41086a2903002208422088210e200241f8006a28020021040c010b2002418881046a200241fc006a2802003602002002418081046a200241f4006a29020022083703002002200229026c220e3703f88004200ea7210b2008a7210541002104200228028481042101410021030240024002400240024002400240024003402004411f4b0d010240024020052001460d002001417f460d072005200141016a22094f0d01200141016a2005103c000b200220053602848104200241013a0058200241fc006a41013602002002420137026c200241a4e2c5003602682002412636021c2002200241186a3602782002200241d8006a360218200241306a200241e8006a1033200241206a41086a200241306a41086a280200360200200220022903303703204105210b0c030b200b20016a2d0000220641ff00712004411f71742003722103200441076a2104200921012006418001710d000b200220093602848104024020044120490d00410d210b2006410f4b0d020b200241003602382002420437033020030d02410421010c030b200220013602848104410f210b0b200241e880046a41086a200241206a41086a28020022043602002002200229032022083703e880042008422088a7210a2008a7210d410021090c040b4104210141002105410021060340200241e8006a200241f880046a10f30420022f006d20022d006f4110747221092002280274210a2002280270210d20022d006c210b024020022802684101470d002002200536023420022006360238200241f8006a28020021042005450d052001102a0c050b0240024020062005460d0020052107200621040c010b200541016a22042005490d16200541017422072004200720044b1b2207ad420c7e2208422088a70d162008a722044100480d160240024020050d002004102821010c010b20012005410c6c2004102c21010b2001450d042002200136023020052104200721050b20012004410c6c6a220420093b00012004200d3602042004200b3a0000200441036a20094110763a0000200441086a200a3602002003200641016a2206470d000b20022007360234200220063602380b200228028481042002280288810446210420022902342108024020022802fc8004450d0020022802f88004102a0b2008a721092004450d032008422088a7ad4220862009ad842108410621030c1b0b417f200141016a1044000b200441041037000b200941ffffff07712205410874200b41ff0171722103200aad220e422086200dad84210820022802fc8004450d0120022802f88004102a0c010b20024103410220041b3a00e88004200241fc006a41013602002002420137026c200241a4e2c5003602682002412636021c2002200241186a3602782002200241e880046a360218200241306a200241e8006a103320022903302208422088210e2002280238210441052103410021052009450d002001102a0b20004101360200200041106a2004360200200041086a200e422086200842ffffffff0f838437020020002005410874200341ff0171723602040c1a0b200241e8006a200110fb040240024020022802684101470d00200228026c22034108762105200241e8006a41086a2903002208422088210e200241f8006a28020021040c010b2002418881046a200241fc006a2802003602002002418081046a200241f4006a29020022083703002002200229026c220e3703f88004200ea7210b2008a721034100210420022802848104210141002109024002400240024002400240024002400240024003402004411f4b0d010240024020032001460d002001417f460d072003200141016a22054f0d01200141016a2003103c000b200220033602848104200241013a0058200241fc006a41013602002002420137026c200241a4e2c5003602682002412636021c2002200241186a3602782002200241d8006a360218200241306a200241e8006a1033200241206a41086a200241306a41086a280200360200200220022903303703204105210a0c030b200b20016a2d0000220641ff00712004411f71742009722109200441076a2104200521012006418001710d000b200220053602848104024020044120490d00410d210a2006410f4b0d020b41002107200241003602f08004200242043703e8800420090d02410421014100210d0c030b200220013602848104410f210a0b200241e880046a41086a200241206a41086a28020022043602002002200229032022083703e880042008a7210b4100210320022802ec8004210d0c060b4104210141012107410021060340024002400240024020032005460d00200541016a22042005490d0720032004490d09200b20056a2c000021032002200436028481040240200341004e0d004119210a0c020b4107210a0240200341c000710d000c020b200341807f7222034170470d02200241e8006a200241f880046a10f30420022f006d20022d006f41107472210320022d006c210a20022802684101470d0320034180feff07714108762105200228027821042002280274210d2002280270210b0c020b200241013a00582002410136027c2002420137026c200241a4e2c5003602682002412636021c2002200241186a3602782002200241d8006a360218200241306a200241e8006a10332002280230210b2002280234210d200228023821044105210a0b0b200220063602ec800420022007417f6a3602f080042005410874200341ff01717221032006450d072001102a0c070b200228027421052002280270210b024002402007417f6a22042006460d002006210d200421060c010b200641016a22042006490d172006410174220d2004200d20044b1b220dad420c7e2208422088a70d172008a722044100480d170240024020060d002004102821010c010b20012006410c6c2004102c21010b2001450d05200220013602e880040b20012006410c6c6a220420033b0001200420053602082004200b3602042004200a3a0000200441036a20034110763a0000024020092007460d00200741016a210720022802848104210520022802808104210320022802f88004210b200d21060c010b0b2002200d3602ec8004200220073602f080040b2002280284810420022802888104462104024020022802fc8004450d0020022802f88004102a0b2004450d052007ad422086200dad842108410521030c1c0b417f200141016a1044000b417f20041044000b200441041037000b20042003103c000b200341ffffff07712205410874200a41ff0171722103200dad220e422086200bad84210820022802fc8004450d0120022802f88004102a0c010b20024103410220041b3a00e88004200241fc006a41013602002002420137026c200241a4e2c5003602682002412636021c2002200241186a3602782002200241e880046a360218200241306a200241e8006a103320022903302208422088210e200228023821044105210341002105200d450d002001102a0b20004101360200200041106a2004360200200041086a200e422086200842ffffffff0f838437020020002005410874200341ff0171723602040c190b200241e8006a200110fb040240024020022802684101470d00200228026c22044108762105200241e8006a41086a2903002208422088210e200241f8006a28020021030c010b200241fc006a280200210c200241f8006a2802002101200241f4006a2802002103200241f0006a2802002107200228026c210b41002104410021090240024002400240024002400240024002400240034002402004411f4d0d00410f21040c020b0240024020032001460d002001417f460d052003200141016a22054f0d01200141016a2003103c000b200241013a0030200241fc006a41013602002002420137026c200241a4e2c5003602682002412636021c2002200241186a3602782002200241306a360218200241f880046a200241e8006a1033200241206a41086a200241f880046a41086a280200360200200220022903f88004370320410521040c020b200b20016a2d0000220641ff00712004411f71742009722109200441076a2104200521012006418001710d000b20044120490d01410d210420064110490d010b200241e880046a41086a200241206a41086a28020022033602002002200229032022083703e880042008a7210520022802ec800421090c070b4100211b20024100360238200242043703300240024020090d0041042101410021060c010b41042101410021064100211b034020062118201b221941016a211b20052104410021064100210a03402006411f4b0d050240024020032004460d002004417f460d062003200441016a22054f0d01200441016a2003103c000b2002201836023420022019360238200241013a00e88004200241fc006a41013602002002420137026c200241a4e2c5003602682002412636021c2002200241186a3602782002200241e880046a360218200241f880046a200241e8006a103320022802f88004210520022802fc80042109200228028081042103410521040c090b200b20046a2d0000220d41ff00712006411f7174200a72210a200641076a210620052104200d418001710d000b024020064120490d00200d410f4d0d002002201836023420022019360238410d21040c070b0240024020192018460d0020182106201921180c010b201841016a22042018490d18201841017422062004200620044b1b220641ffffffff03712006470d18200641027422044100480d180240024020180d002004102821010c010b200120184102742004102c21010b2001450d06200220013602300b200120184102746a200a360200201b2009470d000b200220063602342002201b3602380b2005200c46210402402007450d00200b102a0b2004450d07201bad4220862006ad842108410421030c1d0b417f200141016a1044000b417f200441016a1044000b2002201836023420022019360238410f21040c010b200441041037000b0b2018450d002001102a0b2009ad220e4220862005ad842108410021052007450d01200b102a0c010b20024103410220041b3a0030200241fc006a41013602002002420137026c200241a4e2c5003602682002412636021c2002200241186a3602782002200241306a360218200241f880046a200241e8006a103320022903f880042208422088210e20022802808104210341052104410021052006450d002001102a0b20004101360200200041106a2003360200200041086a200e422086200842ffffffff0f838437020020002005410874200441ff0171723602040c180b200241e8006a200110fb040240024020022802684101470d00200228026c22034108762105200241e8006a41086a2903002208422088210e200241f8006a28020021040c010b2002418881046a200241fc006a2802003602002002418081046a200241f4006a2902003703002002200229026c3703f8800441002101410021050240024002400240024002400240024002400240034002402001411f4d0d00410f21030c020b02400240200228028081042209200228028481042204460d00200441016a22032004490d05200920034f0d0120032009103c000b200241013a0058200241fc006a41013602002002420137026c200241a4e2c5003602682002412636021c2002200241186a3602782002200241d8006a360218200241306a200241e8006a1033200241206a41086a200241306a41086a28020036020020022002290330370320410521030c020b20022802f8800420046a2d00002104200220033602848104200441ff00712001411f71742005722105200141076a21012004418001710d000b20014120490d01410d210320044110490d010b200241e880046a41086a200241206a41086a28020022043602002002200229032022083703e880042008422088a721092008a721060c080b200241003602f08004200242043703e8800402400240024020050d00410421010c010b20022802ec8004210720022802f08004210d410021100340200241e8006a200241f880046a10fc042002280274210920022802702118200228026c211a024020022802684101470d002002280278210420182106201a21030c090b200241e8006a200241f880046a10fc042002280274211320022802702119200228026c211c024020022802684101470d00200228027821042019210620132109201c21030c080b0240024002400240024002400240024002400240024002400240024002400240200228028081042203200228028481042206460d00200641016a22012006490d02200320014f0d0120012003103c000b200241013a00582002410136027c2002420137026c200241a4e2c5003602682002412636021c2002200241186a3602782002200241d8006a360218200241306a200241e8006a1033200228023021062002290234210e4105210a4100211b410021030c150b20022802f88004220c20066a2d000021042002200136028481044100211b0240200441034d0d004109210a410021030c150b024002400240024020040e0400010203000b4100211b410021044100210a034002402004411f4d0d00410f210a0c170b0240024020032001460d002001417f460d072003200141016a220b4f0d01200141016a2003103c000b200241013a00582002410136027c2002420137026c200241a4e2c5003602682002412636021c2002200241186a3602782002200241d8006a360218200241306a200241e8006a1033200228023021062002290234210e4105210a4100211b0c180b200c20016a2d000021062002200b3602848104200641ff00712004411f7174200a72210a200441076a2104200b21012006418001710d000b4100211b20044120490d0f2006410f4d0d0f410d210a0c150b0240024020032001460d00200641026a21042001417f460d0620032004490d07200c20016a2c0000210120022004360284810402402001417f4a0d00411921030c0e0b200141c000710d010c0c0b200241013a00582002410136027c2002420137026c200241a4e2c5003602682002412636021c2002200241186a3602782002200241d8006a360218200241306a200241e8006a10332002290330210820022802382104410521030c0c0b200141807f7222014170470d0a200241e8006a200241f880046a10f30420022903702108200228026c210a024020022802684101470d00200228027821040c0d0b4101211b0c0f0b200241e8006a200241f880046a10f30420022903702108200228026c210a024020022802684101460d004102211b0c0f0b20022002280278360270200a418080807871211b200a4180807c712103200a41087621040c0c0b0240024020032001460d00200641026a210b2001417f460d062003200b490d08200c20016a2c000021042002200b36028481040240200441004e0d004119210a410021030c170b200441c000710d010c090b200241013a00582002410136027c2002420137026c200241a4e2c5003602682002412636021c2002200241186a3602782002200241d8006a360218200241306a200241e8006a10334105210a2002290234210e20022802302106410021030c150b200441807f72220441ff017141fc01490d07024002402003200b460d00200641036a2101200b417f460d07200320014f0d0120012003103c000b200241013a00582002410136027c2002420137026c200241a4e2c5003602682002412636021c2002200241186a3602782002200241d8006a360218200241306a200241e8006a1033200228023021062002290234210e4105210a410021030c150b200c200b6a2d0000210b200220013602848104410021030240200b41014d0d00410c210a4100211b200b21040c150b2004417f7321064103211b0240200b0e020e000e0b410121030c0d0b417f20011044000b417f200141016a1044000b417f20041044000b20042003103c000b417f200b1044000b417f20011044000b200b2003103c000b4106210a410021030c0c0b410721030b200141ff0171410874200372210a0b20022004360270200a418080807871211b200a4180807c712103200a41087621040b20022008370368200229026c210e2008a721060c080b0b02400240200d2007460d002007210b0c010b200741016a22012007490d18200741017422042001200420014b1b220bad42287e220e422088a70d18200ea722044100480d180240024020070d002004102821010c010b20022802e88004200741286c2004102c21010b2001450d03200220013602e880042007210d200b21070b20022802e880042201200d41286c6a2204201c36020c20042009360208200420183602042004201a360200200441206a20083702002004411c6a200a3602002004411a6a20033a0000200441196a20063a0000200441186a201b3a0000200441146a2013360200200441106a2019360200200d41016a210d201041016a22102005470d000b2002200b3602ec80042002200d3602f080040b200228028481042002280288810446210420022902ec80042208422088210e024020022802fc8004450d0020022802f88004102a0b200ea721032008a721092004450d072003ad4220862009ad842108410321030c1d0b200441041037000b417f20031044000b0b41002103410021040b200a41ff0171200441ff0171410874722003418080fc077172201b722103200e422088a72104200ea721092019450d00201c102a0b2018450d00201a102a0b200220073602ec80042002200d3602f0800420022802e88004210b0240200d450d00200d41286c2105200b210103400240200141046a280200450d002001280200102a0b0240200141106a280200450d002001410c6a280200102a0b200141286a2101200541586a22050d000b0b2007450d01200b102a0c010b20024103410220041b3a00e88004200241fc006a41013602002002420137026c200241a4e2c5003602682002412636021c2002200241186a3602782002200241e880046a360218200241306a200241e8006a1033200229033021082002280238210402402003450d00200341286c21052001210303400240200341046a280200450d002003280200102a0b0240200341106a280200450d002003410c6a280200102a0b200341286a2103200541586a22050d000b0b2008422088210e41052103410021052009450d012001102a0c010b200341087621052009ad220e4220862006ad84210820022802fc8004450d0020022802f88004102a0b20004101360200200041106a2004360200200041086a200e422086200842ffffffff0f838437020020002005410874200341ff0171723602040c170b200241013a00302002410136027c2002420137026c200241a4e2c5003602682002412636021c2002200241186a3602782002200241306a360218200241f880046a200241e8006a103320022802f88004210620022802fc8004210920022d00808104210320022d00818104210720022f01828104210d410521050b0b201d450d03200c102a0c030b0b2019450d00201c102a0b2003411076210d200341087621070b200741ff0171410874200341ff0171722103200d411074210d200441ff0171410874210702402017450d002001210403400240200441046a280200450d002004280200102a0b200441106a2104200a41706a220a0d000b0b2003200d722103200720057221042014450d012001102a0c010b20024103410220041b3a0030200241fc006a41013602002002420137026c200241a4e2c5003602682002412636021c2002200241186a3602782002200241306a360218200241f880046a200241e8006a103320022903f88004210820022802808104210302402005450d00200541047421052001210403400240200441046a280200450d002004280200102a0b200441106a2104200541706a22050d000b0b2008422088210e41052104410021052009450d012001102a0c010b200441087621052009ad220e4220862006ad8421082010450d00200b102a0b20004101360200200041106a2003360200200041086a200e422086200842ffffffff0f838437020020002005410874200441ff0171723602040c0d0b41002101410021040240024002400340024020094105470d00410f21070c020b0240024020032009460d00200320094b0d01200941016a2003103c000b200241013a00f88004200241fc006a41013602002002420137026c200241a4e2c5003602682002412636021c2002200241186a3602782002200241f880046a360218200241206a200241e8006a103341052107200229032021080c030b200620096a2d0000220541ff00712001411f71742004722104200141076a2101200941016a220b21092005418001710d000b20014120490d0220054110490d02410d21070b0b2008422088a72109200228022821042008a7210d0c050b024020040d00410021054101211b410021094100210d0c080b200241e8006a41004180081099051a410021054100210d4101211b410021070340024002402003200b6b200420076b22014180082001418008491b2201490d00200b20016a220c200b490d042003200c4f0d01200c2003103c000b200241013a00e880042002418c81046a4101360200200242013702fc8004200241a4e2c5003602f880042002412636021c2002200241186a36028881042002200241e880046a360218200241306a200241f880046a103320022903302208422088a72109200228023821042008a72101410521070240200d450d00201b102a0b2001210d0c060b200241e8006a2006200b6a2001109a051a02400240200d20056b2001490d00200520016a21090c010b200520016a22092005490d02200d410174220b2009200b20094b1b220b4100480d0202400240200d0d00200b1028211b0c010b201b200d200b102c211b0b201b450d04200b210d0b201b20056a200241e8006a2001109a051a20092105200c210b2004200120076a22074d0d040c000b0b1031000b200b200c1044000b200b41011037000b200241e8006a201b2009105420022802684101470d02410821070240200d450d00201b102a0b0b2009ad422086200dad84210841002101200a450d002006102a0b20004101360200200041106a2004360200200041086a200837020020002001410874200741ff0171723602040c060b201b4108762105200c210b0b2003200b490d012003200b6b2201417f4c0d020240024020010d00410121040c010b200110282204450d040b2009ad4220862108200dad210e20042006200b6a2001109a051a2001ad222042208621210240200a450d002006102a0b2008200e8421082021202084210e2005410874201b41ff0171722101410121030b200020033a000420004100360200200041056a20022f00153b0000200041186a200e370200200041146a20043602002000410c6a2008370200200041086a2001360200200041206a2002290200370200200041076a200241176a2d00003a0000200041286a200241086a290200370200200041306a200241106a2802003602000c030b200b20031044000b1036000b200141011037000b2002419081046a24000bf304010b7f230041c080016b220224002002200110f404410121030240024020022802004101470d0020002002290204370204200041013602002000410c6a2002410c6a2902003702000c010b2002280204210420024100418080011099052105410021064100210702400240024002402004450d00410021084100210641012103410021090340024002402001280204220a200128020822076b200420096b220b41808001200b41808001491b220b490d002007200b6a220c2007490d04200a200c4f0d01200c200a103c000b200541013a008f8001200541b480016a4101360200200542013702a48001200541a4e2c5003602a08001200541263602bc80012005200541b880016a3602b0800120052005418f80016a3602b880012005419080016a200541a080016a10332005418b80016a2005419880016a2802003600002005200529039080013700838001200041053a00042000200529008080013700052000410c6a2005418780016a290000370000200041013602002006450d062003102a0c060b2005200128020020076a200b109a05210a2001200c36020802400240200620086b200b490d002008200b6a21070c010b2008200b6a22072008490d052006410174220c2007200c20074b1b220c4100480d050240024020060d00200c102821030c010b20032006200c102c21030b2003450d04200c21060b200320086a200a200b109a051a200721082004200b20096a22094b0d000b0b2000200336020420004100360200200041146a2007360200200041106a41003602002000410c6a2007360200200041086a20063602000c030b2007200c1044000b200c41011037000b1031000b200241c080016a24000b8607010b7f230041d0086b22022400410021034100210402400240024002400240024002400240034002402003411f4d0d00410f21030c020b0240024020012802082205200128020c2206460d00200641016a22072006490d05200520074f0d0120072005103c000b200241013a0089082002411c6a41013602002002420137020c200241a4e2c5003602082002412636029c08200220024198086a360218200220024189086a36029808200241b8086a200241086a1033410521030c020b2001280200220820066a2d000021062001200736020c200641ff00712003411f71742004722104200341076a21032006418001710d000b20034120490d01410d210320064110490d010b2000200336020420004101360200200041086a20022902b808370200200041106a200241b8086a41086a2802003602000c060b024020040d002000428080808010370200200041086a42003702000c060b200241086a41004180081099051a41002106410021094101210a4100210b034002400240200520076b2004200b6b22034180082003418008491b2203490d00200720036a220c2007490d042005200c4f0d01200c2005103c000b200241013a00a708200241cc086a4101360200200242013702bc08200241a4e2c5003602b8082002412636029c08200220024198086a3602c8082002200241a7086a36029808200241a8086a200241b8086a103320024194086a200241b0086a280200360000200220022903a80837008c08200041053a000420002002290089083700052000410c6a20024190086a290000370000200041013602002009450d07200a102a0c070b200241086a200820076a2003109a051a2001200c36020c02400240200920066b2003490d00200620036a210c0c010b200620036a220c2006490d0520094101742207200c2007200c4b1b22074100480d050240024020090d0020071028210a0c010b200a20092007102c210a0b200a450d04200721090b200a20066a200241086a2003109a051a20042003200b6a220b4d0d05200128020c21072001280208210520012802002108200c21060c000b0b417f20071044000b2007200c1044000b200741011037000b1031000b200241086a200a200c1054024020022802084101470d0002402009450d00200a102a0b200041083a0004200041013602000c010b2000200a3602042000410c6a200c360200200041086a2009360200200041003602000b200241d0086a24000b881f03127f017e037f23004180026b220524000240024020014115490d00410121064101210702400240034020012108200021092006200771410173210a024002400240034002400240024002402004450d00024020064101710d002000200110fe042004417f6a21040b2001410276220741036c210b2007410174210c4100210d20014132490d03200741016a210e200020074103746a220f28020020002007417f6a220d4103746a2210280200201041046a2802002210200f41046a280200220f200f20104b1b109c052211450d01417f410120114100481b21100c020b2000200110ff040c0b0b417f200f201047200f2010491b21100b2007200d2010417f4622101b210f024002402000200e4103746a22112802002000200d200720101b22124103746a2207280200200741046a2802002207201141046a280200220d200d20074b1b109c052211450d00417f410120114100481b21070c010b417f200d200747200d2007491b21070b4102410120101b20102007417f4622071b210d024002402000200e201220071b22114103746a22102802002000200f4103746a2207280200200741046a2802002207201041046a2802002210201020074b1b109c05220e450d00417f4101200e4100481b21100c010b417f201020074720102007491b21100b200c4101722107200d2010417f4622126a2113024002402000200c4103746a220d2802002000200c417f6a22104103746a220e280200200e41046a280200220e200d41046a280200220d200d200e4b1b109c052214450d00417f410120144100481b210e0c010b417f200d200e47200d200e491b210e0b200c2010200e417f46220e1b210d2013200e6a211302400240200020074103746a221428020020002010200c200e1b220e4103746a220c280200200c41046a280200220c201441046a28020022102010200c4b1b109c052214450d00417f410120144100481b210c0c010b417f2010200c472010200c491b210c0b2013200c417f46220c6a21100240024020002007200e200c1b22134103746a220c2802002000200d4103746a2207280200200741046a2802002207200c41046a280200220c200c20074b1b109c05220e450d00417f4101200e4100481b210c0c010b417f200c200747200c2007491b210c0b200b41016a21072010200c417f4622146a2115024002402000200b4103746a220e2802002000200b417f6a220c4103746a2210280200201041046a2802002210200e41046a280200220e200e20104b1b109c052216450d00417f410120164100481b21100c010b417f200e201047200e2010491b21100b200b200c2010417f4622101b210e201520106a211502400240200020074103746a22162802002000200c200b20101b22104103746a220c280200200c41046a280200220c201641046a280200220b200b200c4b1b109c052216450d00417f410120164100481b210c0c010b417f200b200c47200b200c491b210c0b2015200c417f46220c6a211502400240200020072010200c1b220b4103746a220c2802002000200e4103746a2207280200200741046a2802002207200c41046a280200220c200c20074b1b109c052210450d00417f410120104100481b21100c010b417f200c200747200c2007491b21100b200f201120121b2107200d201320141b210c200e200b2010417f4622101b210b201520106a210d0b024002402000200c4103746a220e280200200020074103746a2210280200201041046a2802002210200e41046a280200220e200e20104b1b109c05220f450d00417f4101200f4100481b21100c010b417f200e201047200e2010491b21100b200c20072010417f46220e1b2110200d200e6a210d024002402000200b4103746a220f28020020002007200c200e1b220e4103746a2207280200200741046a2802002207200f41046a280200220c200c20074b1b109c05220f450d00417f4101200f4100481b21070c010b417f200c200747200c2007491b21070b200d2007417f46220c6a2107024002400240024002402000200b200e200c1b220d4103746a220b280200200020104103746a220c280200200c41046a280200220c200b41046a280200220b200b200c4b1b109c05220e450d00200e4100480d010c020b200b200c4f0d010b200741016a2207410c490d0102402001410176220b450d00200020014103746a41786a21072000210c0340200c2902002117200c200729020037020020072017370200200c41086a210c200741786a2107200b417f6a220b0d000b0b20012010417f736a2110410121070c020b200d21100b20074521070b0240200745200a724101710d00200020011080050d090b2003450d010240201020014f0d00024002402003280200200020104103746a2207280200200741046a280200220c200341046a280200220b200b200c4b1b109c05220e450d00200e41004e0d010c050b200b200c490d040b200029020021172000200729020037020020072017370200200041786a21122000410c6a2113200041086a2114200028020421072000280200210d4100210b2001210e0340024002400240200b200e417f6a22114f0d002013200b4103746a210c034002400240200d200c417c6a280200200c28020022102007200720104b1b109c05220f450d00200f4100480d030c010b20072010490d020b200c41086a210c2011200b41016a220b470d000c020b0b0240200b20114f0d002012200e4103746a210c2011210e034002400240200d200c280200200c41046a28020022102007200720104b1b109c05220f450d00200f4100480d010c050b200720104f0d040b200c41786a210c200b200e417f6a220e490d000b0b200b21110b200020073602042000200d36020002402001201141016a2207490d00200020074103746a2100200120076b220141154f0d040c0b0b200720011044000b2014200b4103746a221029020021172010200c290200370200200c2017370200200b41016a210b0c000b0b0b41f483c600201020011034000b20080d0141bc83c600410041001034000b20002109200121080b201020084f0d02200929020021172009200920104103746a2207290200370200200720173702002009280204210c2009280200211241002100410021184100211902402008417f6a220e450d002009410c6a21074100211803400240024002402007417c6a2802002012200c2007280200220b200b200c4b1b109c052210450d00201041004e0d010c020b200b200c490d010b200e21190240200e20184d0d00200920084103746a41786a2107200e211903400240024020072802002012200c200741046a280200220b200b200c4b1b109c052210450d00201041004e0d010c030b200b200c490d020b200741786a21072019417f6a221920184b0d000b0b0240024020192018490d00200e2019490d010c040b201820191044000b2019200e103c000b200741086a2107200e201841016a2218470d000b200e2118200e21190b200941086a220720194103746a210e41800121144100211141002110410021014180012106200720184103746a221a210d03400240200e200d6b22074187104b220a0d002007410376220741807f6a200720112000492001201049220b72220f1b21070240200f450d0020062007200b1b210620072014200b1b21140c010b2007200741017622066b21140b024020012010470d00024020060d002005221021010c010b4100210720052110200d210b0340201020073a0000200741016a210702400240200b2802002012200c200b41046a280200220f200f200c4b1b109c052201450d00417f410120014100481b210f0c010b417f200f200c47200f200c491b210f0b200b41086a210b2010200f417f476a211020062007470d000b200521010b024020112000470d00024020140d0020054180016a220021110c010b200e41786a21074100210b20054180016a210003402000200b3a0000200b41016a210b0240024020072802002012200c200741046a280200220f200f200c4b1b109c052211450d00417f410120114100481b210f0c010b417f200f200c47200f200c491b210f0b200741786a21072000200f417f466a21002014200b470d000b20054180016a21110b0240200020116b2207201020016b220b200b20074b1b2213450d00200d20012d00004103746a22072802042115200728020021162007200e20112d0000417f734103746a290200370200024020134101460d00410021070340200e201120076a220b2d0000417f734103746a200d200120076a41016a220f2d00004103746a290200370200200d200f2d00004103746a200e200b41016a2d0000417f734103746a290200370200200741026a210b200741016a220f2107200b2013490d000b2011200f6a21112001200f6a21010b200e20112d0000417f734103746a2207201536020420072016360200201141016a2111200141016a21010b200e20144103746b200e20112000461b210e200d20064103746a200d20012010461b210d200a0d000b02400240200120104f0d00200e21070340200d2010417f6a22102d00004103746a220b2902002117200b200741786a22072902003702002007201737020020012010490d000c020b0b200d2107201120004f0d000340200729020021172007200e2000417f6a22002d0000417f734103746a220b290200370200200b2017370200200741086a210720112000490d000b0b2009200c36020420092012360200024020082007201a6b41037620186a22014d0d00200929020021172009200920014103746a220729020037020020072017370200200820016b220c450d02200c20012001200c4b1b210b20084103762110200741086a2100024002402001200c417f6a220c490d002000200c20022007200410fd04200921000c010b2009200120022003200410fd0420072103200c21010b200b20104f2106201920184d2107200141154f0d010c040b0b41cc83c600200120081034000b41dc83c6001032000b41cc83c600201020081034000b20014102490d00200041786a211341002114410121120340201241037421072012417f6a2110201241016a2112024002400240200020076a22072802002211200020104103746a220f280200200f41046a280200220c200741046a280200220b200b200c4b1b109c05220e450d00200e4100480d010c020b200b200c4f0d010b2007200f29020037020002402010450d002014210c20132107024003400240024020112007280200200741046a280200220e200b200b200e4b1b109c05220d450d00200d4100480d010c030b200b200e4f0d030b20002010417f6a22104103746a210f200741086a2007290200370200200741786a2107200c41016a220e200c49210d200e210c200d450d000b0b200741086a210f0b200f200b360204200f20113602000b2014417f6a2114201341086a211320122001470d000b0b20054180026a24000bf50202057f017e02400240024020014108490d00200141017641feffffff07712202417f6a220320014f0d022001410d74200173220441117620047322044105742004732205417f2001417f6a677622067122044100200120042001491b6b220420014f0d01200020034103746a220329020021072003200020044103746a220429020037020020042007370200024020022001490d00200221030c030b2005410d7420057322044111762004732204410574200473220520067122044100200120042001491b6b220420014f0d01200020024103746a220329020021072003200020044103746a2204290200370200200420073702002002410172220320014f0d022005410d742005732204411176200473220441057420047320067122044100200120042001491b6b220420014f0d01200020034103746a220129020021072001200020044103746a2200290200370200200020073702000b0f0b41cc83c600200420011034000b41bc83c600200320011034000bb20102037f017e024020014101762202450d00200020012002417f6a1081052002417e6a210203402002417f460d012000200120021081052002417f6a21020c000b0b0240024020014102490d00200141037420006a41786a21022001210303402003417f6a220420014f0d02200029020021052000200229020037020020022005370200200020044100108105200241786a210220042103200441014b0d000b0b0f0b41cc83c6002003417f6a20011034000b9a06050a7f017e017f017e037f200041686a2102200041786a2103200141324921044101210541002106024003400240024020052001490d00410021070c010b200320054103746a210841012107034002400240200841086a22092802002008280200200841046a280200220a2008410c6a28020022082008200a4b1b109c05220b450d00200b4100480d030c010b2008200a490d020b4101210a200541016a220520014921072009210820012005470d000c030b0b2005200146210a20040d0120052001460d01024002400240024002402005417f6a220820014f0d002007410171450d01200020084103746a2208290200210c200820002005410374220d6a220b290200220e370200200b200c37020020054102490d0402400240200ea7220f20002005417e6a220a4103746a2210280200201041046a2802002207200841046a2802002209200920074b1b109c052211450d0020114100480d010c060b200920074f0d050b20082010290200370200200a450d032002200d6a2108034002400240200f2008280200200841046a28020022072009200920074b1b109c05220d450d00200d4100480d010c050b200920074f0d050b2000200a417f6a220a4103746a2110200841086a2008290200370200200841786a2108200a0d000c030b0b41bc83c600200820011034000b41cc83c600200520011034000b200841086a21100b201020093602042010200f3602000b200641016a21060240200120056b220d4102490d0002400240200b280208200b280200220f200b41046a2802002209200b410c6a2802002208200820094b1b109c05220a450d00200a4100480d010c020b200820094f0d010b200b41086a2111200b200b2902083702000240200d4103490d004103210a41022107034002400240200b20074103746a2208280200200f2009200841046a2802002207200720094b1b109c052210450d00201041004e0d030c010b200720094f0d020b200841786a20082902003702000240200a200d4f0d00200a2107200a41016a210a200821110c010b0b200821110b2011200f360200201120093602040b20064105470d000b4100210a0b200a0bb60202057f017e03402002410174220341017221040240024002400240200341026a220320014f0d00200420014f0d0102400240200020044103746a2205280200200020034103746a2206280200200641046a2802002206200541046a2802002205200520064b1b109c052207450d00417f410120074100481b21060c010b417f200520064720052006491b21060b200320042006417f461b21040b0240200420014f0d00200220014f0d020240200020024103746a2202280200200020044103746a2203280200200341046a2802002206200241046a2802002205200520064b1b109c052207450d00200741004e0d010c040b20052006490d030b0f0b41c885c600200420011034000b41d885c600200220011034000b200229020021082002200329020037020020032008370200200421020c000b0b1500200120002802002200280200200028020810450bf30201037f230041c0006b22022400200141086a2802002103200128020421042002200128020022013602100240024002402001418080044b0d0002402004450d0020022003360214200120034b0d022003418080044d0d002002413c6a41013602002002420237022c200241f8a7c6003602282002410136021c200241d4a7c6003602182002200241186a3602382002200241286a10330c030b200241003602000c020b2002413c6a41013602002002420237022c200241d8a7c6003602282002410136021c200241d4a7c6003602182002200241186a3602382002200241286a10330c010b200241246a41013602002002413c6a41023602002002420237022c200241e8a7c6003602282002410136021c2002200241186a3602382002200241106a3602202002200241146a3602182002200241286a10330b024002402002280200450d0020002002290300370200200041086a200241086a2802003602000c010b200041003602000b200241c0006a24000bf80501037f230041f0006b2204240002400240024002400240024020012802084102460d00412e10282201450d01200041013a0000200141266a41002900eca946370000200141206a41002900e6a946370000200141186a41002900dea946370000200141106a41002900d6a946370000200141086a41002900cea946370000200141002900c6a946370000200041086a42ae808080e005370200200041046a20013602000c050b02400240024002400240200128020022052d0000416e6a2201411e4b0d004100210620010e1f03000000000000000000000000000000000000000000000000000008040102030b412010282201450d05200041013a0000200141186a410029008caa46370000200141106a4100290084aa46370000200141086a41002900fca946370000200141002900f4a946370000200041086a42a08080808004370200200041046a20013602000c080b410221060c060b410321060c050b20042005280204220136020c0240024020012003490d004194aac6002105200441e8006a2103200441d0006a2101200441c0006a21020c010b200220014101746a22012d0001450d0441a4aac6002105200441386a2103200441206a2101200441106a21020b20034101360204200141146a410136020020012003360210200142023702042001200536020020032004410c6a360200200220011033200041013a00002000410c6a200241086a280200360200200041046a20022902003702000c050b410121060c030b412e41011037000b412041011037000b20012d000021060b0240200541106a2d00004106470d00200041003a0000200020063a00010c010b0240412910282201450d00200041013a0000200141286a41002d00dcaa463a0000200141206a41002900d4aa46370000200141186a41002900ccaa46370000200141106a41002900c4aa46370000200141086a41002900bcaa46370000200141002900b4aa46370000200041086a42a98080809005370200200041046a20013602000c010b412941011037000b200441f0006a24000b86c30103087f027e017f230041f0006b220324000240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024020022d00000eac0100e1010102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f80018101820183018401850186018701880189018a018b018c018d018e018f0190019101920193019401950196019701980199019a019b019c019d019e019f01a001a101a201a301a401a501a601a701a801a901aa01000b02400240200141306a2802002202417f6a220420024f0d00200420024d0d010b411810282200450dab012003421837025c20032000360258200341d8006a4100411810870520032003280260220041186a3602602000200328025822016a41184196adc60041181088052003200329025c37025c200320013602584193a2c600413b200341d8006a41d0a2c6001038000b02400240200128022820044103746a22052802002204200141206a220628020022024b0d00200421010c010b024002402001411c6a280200220720026b200420026b2208490d0020012802182107200221010c010b200220086a22092002490de0012007410174220a2009200a20094b1b22094100480de0010240024020070d002009102821070c010b200128021820072009102c21070b2007450dad01200120073602182001411c6a2009360200200141206a28020021010b200720016a21090240024020084102490d002009410420042002417f736a22021099051a2007200220016a22016a21090c010b2008450d010b200941043a0000200141016a21010b20062001360200200541013a00060ce0010b0240200141306a2802002204200141346a22052802004f0d002002310001210b200141206a350200210c024020042001412c6a280200470d00200441016a22022004490ddf01200441017422052002200520024b1b220241ffffffff01712002470ddf01200241037422054100480ddf010240024020040d002005102821040c010b200128022820044103742005102c21040b2004450dad01200120043602282001412c6a2002360200200141306a28020021040b200128022820044103746a200b422886200c84370200200141306a2201200128020041016a3602000ce0010b200341ec006a220141013602002003420137025c20034190aec600360258200341013602042003200536020020032003360268200341106a200341d8006a103320032802102202450ddf012003200329021437021420032002360210200141013602002003420137025c200341c4a7c60036025820034128360204200320033602682003200341106a360200200341386a200341d8006a103302402003280214450d002003280210102a0b20032802382201450ddf012000200329023c370204200020013602000ce0010b0240200141306a2802002204200141346a22052802004f0d002002310001210b200141206a350200210c024020042001412c6a280200470d00200441016a22022004490dde01200441017422052002200520024b1b220241ffffffff01712002470dde01200241037422054100480dde010240024020040d002005102821040c010b200128022820044103742005102c21040b2004450dad01200120043602282001412c6a2002360200200141306a28020021040b200128022820044103746a200b422886200c8442808080803084370200200141306a2201200128020041016a3602000cdf010b200341ec006a220141013602002003420137025c20034190aec600360258200341013602042003200536020020032003360268200341106a200341d8006a103320032802102202450dde012003200329021437021420032002360210200141013602002003420137025c200341c4a7c60036025820034128360204200320033602682003200341106a360200200341386a200341d8006a103302402003280214450d002003280210102a0b20032802382201450dde012000200329023c370204200020013602000cdf010b2002310001210b200341d8006a200141186a200141286a22044100108905024020032d00584101470d002000200329025c370200200041086a200341e4006a2802003602000cdf010b0240200141306a2802002202200141346a22052802004f0d00200141206a350200210c024020022001412c6a280200470d00200241016a22052002490ddd01200241017422062005200620054b1b220541ffffffff01712005470ddd01200541037422064100480ddd010240024020020d002006102821020c010b200428020020024103742006102c21020b2002450dad01200120023602282001412c6a2005360200200141306a28020021020b200128022820024103746a200b422886200c8442808080801084370200200141306a2201200128020041016a3602000cde010b200341ec006a220141013602002003420137025c20034190aec600360258200341013602042003200536020020032003360268200341106a200341d8006a103320032802102202450ddd012003200329021437021420032002360210200141013602002003420137025c200341c4a7c60036025820034128360204200320033602682003200341106a360200200341386a200341d8006a103302402003280214450d002003280210102a0b20032802382201450ddd012000200329023c370204200020013602000cde010b02400240200141306a2802002202417f6a220420024f0d00200420024d0d010b411810282200450dac012003421837025c20032000360258200341d8006a4100411810870520032003280260220041186a3602602000200328025822016a41184196adc60041181088052003200329025c37025c2003200136025841e0a2c6004134200341d8006a41d0a2c6001038000b02400240200141286a220228020020044103746a22042d00044101470d002004310005210b200341d8006a200141186a2002108a052003280258450d0120002003290358370200200041086a200341d8006a41086a2802003602000cdf010b411a10282201450dad01200141186a41002f00aca3463b0000200141106a41002900a4a346370000200141086a410029009ca34637000020014100290094a3463700002000429a808080a003370204200020013602000cde010b0240200141306a2802002204200141346a22052802004f0d00200141206a350200210c024020042001412c6a280200470d00200441016a22052004490ddc01200441017422062005200620054b1b220541ffffffff01712005470ddc01200541037422064100480ddc010240024020040d002006102821020c010b200228020020044103742006102c21020b2002450daf01200120023602282001412c6a2005360200200141306a28020021040b200128022820044103746a200b422886200c8442808080802084370200200141306a2201200128020041016a3602000cdd010b200341ec006a220141013602002003420137025c20034190aec600360258200341013602042003200536020020032003360268200341106a200341d8006a103320032802102202450ddc012003200329021437021420032002360210200141013602002003420137025c200341c4a7c60036025820034128360204200320033602682003200341106a360200200341386a200341d8006a103302402003280214450d002003280210102a0b20032802382201450ddc012000200329023c370204200020013602000cdd010b02400240200141306a2802002202417f6a220420024f0d00200420024d0d010b411810282200450dae012003421837025c20032000360258200341d8006a4100411810870520032003280260220041186a3602602000200328025822016a41184196adc60041181088052003200329025c37025c2003200136025841e0a2c6004134200341d8006a41d0a2c6001038000b200141286a220628020020044103746a22042d00052105024020042d00044101470d00200541ff01714104470daf010b0240024020024101460d00200341d8006a200141186a22022006108a052003280258450d0120002003290358370200200041086a200341d8006a41086a2802003602000cde010b20012d003822024104460ddb01200341d8006a200141186a2205200620021089050240024020032d00584101460d000240200141206a2802002204200141246a22072802004f0d00024020042001411c6a280200470d00200441016a22072004490dde01200441017422082007200820074b1b22074100480dde010240024020040d002007102821040c010b200528020020042007102c21040b2004450db401200120043602182001411c6a2007360200200141206a28020021040b200128021820046a20023a0000200141206a2202200228020041016a3602000cde010b200341ec006a220241013602002003420137025c20034190aec600360258200341013602042003200736020020032003360268200341106a200341d8006a103320032802102204450ddd012003200329021437021420032004360210200241013602002003420137025c200341c4a7c60036025820034128360204200320033602682003200341106a360200200341386a200341d8006a103302402003280214450d002003280210102a0b20032802382202450ddd01200329023c210b0c010b200328025c2202450ddc01200341e0006a290300210b0b2000200b370204200020023602000cdd010b200541ff01714104460ddb010240200141206a2802002204200141246a22062802004f0d00024020042001411c6a280200470d00200441016a22062004490ddb01200441017422072006200720064b1b22064100480ddb010240024020040d002006102821020c010b200228020020042006102c21020b2002450db201200120023602182001411c6a2006360200200141206a28020021040b200128021820046a20053a0000200141206a2201200128020041016a3602000cdc010b200341ec006a220141013602002003420137025c20034190aec600360258200341013602042003200636020020032003360268200341106a200341d8006a103320032802102202450ddb012003200329021437021420032002360210200141013602002003420137025c200341c4a7c60036025820034128360204200320033602682003200341106a360200200341386a200341d8006a103302402003280214450d002003280210102a0b20032802382201450ddb012000200329023c370204200020013602000cdc010b2003200241046a280200220236024802400240200141306a280200220420024d0d0020042002417f736a22022004490d0141f2adc600411d1050000b200341ec006a220241023602002003411c6a41013602002003420237025c200341b0adc60036025820034101360214200320043602002003200341106a360268200320033602182003200341c8006a360210200341386a200341d8006a1033200328023821042003200329023c37021420032004360210200241013602002003420137025c200341c4a7c60036025820034128360204200320033602682003200341106a360200200341386a200341d8006a10332003280214450dd1012003280210102a0cd1010b200141286a220428020020024103746a22022d00044103460dd10120022d0005220241ff01714104460dd101200341d8006a200141186a220520042002108905024020032d00584101460d000240200141206a2802002204200141246a22062802004f0d00024020042001411c6a280200470d00200441016a22062004490ddb01200441017422072006200720064b1b22064100480ddb010240024020040d002006102821040c010b200528020020042006102c21040b2004450db301200120043602182001411c6a2006360200200141206a28020021040b200128021820046a20023a0000200141206a2202200228020041016a3602000cd3010b200341ec006a220241013602002003420137025c20034190aec600360258200341013602042003200636020020032003360268200341106a200341d8006a103320032802102204450dd2012003200329021437021420032004360210200241013602002003420137025c200341c4a7c60036025820034128360204200320033602682003200341106a360200200341386a200341d8006a10332003280214450dd1012003280210102a0cd1010b200328025c2202450dd101200341e0006a290300210b0cd2010b200241046a2802002102200341d8006a200141186a2206200141286a220541001089050240024020032d00584101470d00200341e0006a290300210b200328025c22010d010cdb010b200141306a28020021042003200236024802400240200420024d0d0020042002417f736a22022004490d0141f2adc600411d1050000b200341ec006a220141023602002003411c6a41013602002003420237025c200341b0adc60036025820034101360214200320043602002003200341106a360268200320033602182003200341c8006a360210200341386a200341d8006a1033200328023821022003200329023c37021420032002360210200141013602002003420137025c200341c4a7c60036025820034128360204200320033602682003200341106a360200200341386a200341d8006a103302402003280214450d002003280210102a0b200329023c210b200328023822010d010cdb010b200528020020024103746a22022d00044103460dda0120022d0005220241ff01714104460dda01200341d8006a200620052002108905024020032d00584101460d000240200141206a2802002204200141246a22052802004f0d00024020042001411c6a280200470d00200441016a22052004490ddb01200441017422072005200720054b1b22054100480ddb010240024020040d002005102821040c010b200628020020042005102c21040b2004450db401200120043602182001411c6a2005360200200141206a28020021040b200128021820046a20023a0000200141206a2201200128020041016a3602000cdc010b200341ec006a220141013602002003420137025c20034190aec600360258200341013602042003200536020020032003360268200341106a200341d8006a103320032802102202450ddb012003200329021437021420032002360210200141013602002003420137025c200341c4a7c60036025820034128360204200320033602682003200341106a360200200341386a200341d8006a103302402003280214450d002003280210102a0b20032802382201450ddb01200329023c210b0c010b200328025c2201450dda01200341e0006a290300210b0b2000200b370204200020013602000cda010b200241046a280200220228020421062002280200210420032002280208220536024802400240200141306a280200220220054d0d0020022005417f736a22052002490d0141f2adc600411d1050000b200341ec006a220441023602002003411c6a41013602002003420237025c200341b0adc60036025820034101360214200320023602002003200341106a360268200320033602182003200341c8006a360210200341386a200341d8006a1033200328023821022003200329023c37021420032002360210200441013602002003420137025c200341c4a7c60036025820034128360204200320033602682003200341106a360200200341386a200341d8006a103302402003280214450d002003280210102a0b2003200329023c370204200320032802383602000ccd010b410421090240200141286a220d280200220720054103746a22052d00044103460d0020052d000521090b200320093a00302006450dc801200941ff0171220a4104460dc701200641027421060340200320042802002205360248200220054d0dca0120022005417f736a220520024f0dce01200720054103746a22052d00044103460dcb0120052d000522084104460dcb01200a2008470dcb01200441046a21042006417c6a22060d000cc9010b0b20012d003822024104460dc501200341d8006a200141186a2205200141286a20021089050240024020032d00584101460d000240200141206a2802002204200141246a22062802004f0d00024020042001411c6a280200470d00200441016a22062004490dd901200441017422072006200720064b1b22064100480dd9010240024020040d002006102821040c010b200528020020042006102c21040b2004450db301200120043602182001411c6a2006360200200141206a28020021040b200128021820046a20023a0000200141206a2202200228020041016a3602000cc8010b200341ec006a220241013602002003420137025c20034190aec600360258200341013602042003200636020020032003360268200341106a200341d8006a103320032802102204450dc7012003200329021437021420032004360210200241013602002003420137025c200341c4a7c60036025820034128360204200320033602682003200341106a360200200341386a200341d8006a103302402003280214450d002003280210102a0b20032802382202450dc701200329023c210b0c010b200328025c2202450dc601200341e0006a290300210b0b2000200b370204200020023602000cd8010b200128020021042003200241046a2802002202360254024002400240200441386a28020020024b0d00200341ec006a41013602002003420237025c200341e4abc600360258200341013602342003200341306a3602682003200341d4006a360230200341386a200341d8006a1033200341186a200329023c370300200341013602102003200328023822043602140c010b2003200428023020024102746a2802002202360200024002402004412c6a28020020024b0d0041012105200341ec006a41013602002003420237025c20034188acc6003602582003410136024c2003200341c8006a36026820032003360248200341386a200341d8006a1033200341186a200329023c220b370300200b422088a7210720032802382104200ba721020c010b2003411c6a200428022420024104746a22042d000d22073a0000200341186a2004280208220236020020042802002104410021050b20032005360210200320043602142005450d010b200341186a21010cc3010b02402002450d002004417f6a2104200141286a2105200141186a21060340200341d8006a20062005200420026a2d0000108905024020032d00584101470d00200341e0006a2101200328025c21040cc5010b2002417f6a22020d000b0b200741ff01714104460dd6010240200141206a2802002202200141246a22042802004f0d00024020022001411c6a280200470d00200241016a22042002490dd601200241017422052004200520044b1b22044100480dd6010240024020020d002004102821020c010b200128021820022004102c21020b2002450db101200120023602182001411c6a2004360200200141206a28020021020b200128021820026a20073a0000200141206a2201200128020041016a3602000cd7010b200341ec006a220141013602002003420137025c20034190aec600360258200341013602042003200436020020032003360268200341106a200341d8006a103320032802102202450dd6012003200329021437021420032002360210200141013602002003420137025c200341c4a7c60036025820034128360204200320033602682003200341106a360200200341386a200341d8006a103302402003280214450d002003280210102a0b20032802382204450dd601200329023c210b0cc3010b200241046a28020021062001280200210220034100360238024002400240200241146a2802000d00200341d8006a41146a41013602002003420237025c200341c4abc60036025820034101360204200320033602682003200341386a360200200341106a200341d8006a10330c010b200341d8006a200141186a2204200141286a22054100108905024020032d00584101470d00200341e0006a290300210b0cc2010b20012802002207412c6a280200210220032006360238200220064b0d01200341ec006a41013602002003420237025c20034188acc60036025820034101360204200320033602682003200341386a360200200341106a200341d8006a10330b2003290214210b200328021022010dc1010cd6010b200728022420064104746a22062d000d2107024020062802082202450d002006280200417f6a21060340200341d8006a20042005200620026a2d0000108905024020032d00584101470d00200341e0006a290300210b0cc2010b2002417f6a22020d000b0b200741ff01714104460dd5010240200141206a2802002202200141246a22052802004f0d00024020022001411c6a280200470d00200241016a22052002490dd501200241017422062005200620054b1b22054100480dd5010240024020020d002005102821020c010b200428020020022005102c21020b2002450db101200120023602182001411c6a2005360200200141206a28020021020b200128021820026a20073a0000200141206a2201200128020041016a3602000cd6010b200341ec006a220141013602002003420137025c20034190aec600360258200341013602042003200536020020032003360268200341106a200341d8006a103320032802102202450dd5012003200329021437021420032002360210200141013602002003420137025c200341c4a7c60036025820034128360204200320033602682003200341106a360200200341386a200341d8006a103302402003280214450d002003280210102a0b20032802382201450dd501200329023c210b0cc0010b200341d8006a200141186a200141286a410410890520032d00584101470dd401200328025c2201450dd4012000200341e0006a290300370204200020013602000cd5010b200341d8006a200141186a2204200141286a22054100108905200341d8006a21020240024020032d00584101460d00200341d8006a200420054104108905200341d8006a210220032d00584101460d00200341d8006a2004200520032d00592206108905200341d8006a210220032d00584101460d000240200141206a2802002202200141246a22052802004f0d00024020022001411c6a280200470d00200241016a22052002490dd501200241017422072005200720054b1b22054100480dd5010240024020020d002005102821020c010b200428020020022005102c21020b2002450db201200120023602182001411c6a2005360200200141206a28020021020b200128021820026a20063a0000200141206a2201200128020041016a3602000cd6010b200341ec006a220141013602002003420137025c20034190aec600360258200341013602042003200536020020032003360268200341106a200341d8006a103320032802102202450dd5012003200329021437021420032002360210200141013602002003420137025c200341c4a7c60036025820034128360204200320033602682003200341106a360200200341386a200341d8006a103302402003280214450d002003280210102a0b20032802382201450dd501200329023c210b0c010b200241046a2802002201450dd401200241086a290200210b0b2000200b370204200020013602000cd4010b200341d8006a200141046a200241046a280200108b050240024020032d00584101460d000240200141206a2802002202200141246a22042802004f0d0020032d00592104024020022001411c6a280200470d00200241016a22052002490dd401200241017422062005200620054b1b22054100480dd4010240024020020d002005102821020c010b200128021820022005102c21020b2002450db201200120023602182001411c6a2005360200200141206a28020021020b200128021820026a20043a0000200141206a2201200128020041016a3602000cd5010b200341ec006a220141013602002003420137025c20034190aec600360258200341013602042003200436020020032003360268200341106a200341d8006a103320032802102202450dd4012003200329021437021420032002360210200141013602002003420137025c200341c4a7c60036025820034128360204200320033602682003200341106a360200200341386a200341d8006a103302402003280214450d002003280210102a0b20032802382201450dd401200329023c210b0c010b200328025c2201450dd301200341e0006a290300210b0b2000200b370204200020013602000cd3010b2003200241046a2802002202360200200341d8006a200141046a2002108b05024020032d00584101470d002003200328025c22013602382003200341e0006a290300220b37023c0cbb010b200320032d005922023a0030200341d8006a200141186a200141286a4104108905024020032d00584101470d00200341c0006a200341e4006a2802003602002003200329025c3703380cba010b200320032d005922013a004820014104460dd101200241ff01712001460dd101200341106a41146a41303602002003411c6a4127360200200341d8006a41146a41033602002003420337025c200341d0a3c600360258200341013602142003200341106a3602682003200341c8006a3602202003200341306a36021820032003360210200341386a200341d8006a10330cb9010b200341d8006a200141046a200241046a280200108b050240024020032d00584101460d00200341d8006a200141186a2205200141286a20032d00592204108905024020032d00584101460d000240200141206a2802002202200141246a22062802004f0d00024020022001411c6a280200470d00200241016a22062002490dd301200241017422072006200720064b1b22064100480dd3010240024020020d002006102821020c010b200528020020022006102c21020b2002450db201200120023602182001411c6a2006360200200141206a28020021020b200128021820026a20043a0000200141206a2201200128020041016a3602000cd4010b200341ec006a220141013602002003420137025c20034190aec600360258200341013602042003200636020020032003360268200341106a200341d8006a103320032802102202450dd3012003200329021437021420032002360210200141013602002003420137025c200341c4a7c60036025820034128360204200320033602682003200341106a360200200341386a200341d8006a103302402003280214450d002003280210102a0b20032802382201450dd301200329023c210b0c020b200328025c2201450dd201200341e0006a290300210b0c010b200328025c2201450dd101200341e0006a290300210b0b2000200b370204200020013602000cd1010b200128020021042003200241046a280200220236023802400240200441206a28020020024d0d000240200141206a2802002205200141246a22062802004f0d00200428021820024101746a2d00002102024020052001411c6a280200470d00200541016a22042005490dd101200541017422062004200620044b1b22044100480dd1010240024020050d002004102821050c010b200128021820052004102c21050b2005450db101200120053602182001411c6a2004360200200141206a28020021050b200128021820056a20023a0000200141206a2201200128020041016a3602000cd2010b200341ec006a220141013602002003420137025c20034190aec600360258200341013602042003200636020020032003360268200341106a200341d8006a103320032802102202450dd1012003200329021437021420032002360210200141013602002003420137025c200341c4a7c60036025820034128360204200320033602682003200341106a360200200341386a200341d8006a103302402003280214450d002003280210102a0b20032802382201450dd101200329023c210b0c010b200341ec006a41013602002003420237025c200341a8acc6003602582003410136024c2003200341c8006a3602682003200341386a360248200341106a200341d8006a103320032802102201450dd0012003290214210b0b2000200b370204200020013602000cd0010b2003200241046a28020022023602282001280200210420032002360254024002400240200441206a28020020024b0d00200341ec006a41013602002003420237025c200341a8acc6003602582003410136024c2003200341c8006a3602682003200341d4006a360248200341106a200341d8006a10330c010b200428021820024101746a22022d00010d01200341ec006a41013602002003420237025c200341b8acc60036025820034101360204200320033602682003200341d4006a360200200341106a200341d8006a10330b2003280210210120032003290214220b37023c200320013602380cb6010b200320022d000022023a002f200341d8006a200141186a200141286a4104108905024020032d00584101470d00200341c0006a200341e4006a2802003602002003200329025c3703380cb5010b200320032d005922013a00002001200241ff0171460dce0120014104460dce01200341106a41146a41303602002003411c6a4130360200200341d8006a41146a41033602002003420337025c200341e8a3c600360258200341013602142003200341106a3602682003200336022020032003412f6a3602182003200341286a360210200341386a200341d8006a10330cb4010b200341d8006a2001200241046a28020041044100108d052003280258450dcd0120002003290358370200200041086a200341d8006a41086a2802003602000cce010b200341d8006a2001200241046a28020041084101108d052003280258450dcc0120002003290358370200200041086a200341d8006a41086a2802003602000ccd010b200341d8006a2001200241046a28020041044102108d052003280258450dcb0120002003290358370200200041086a200341d8006a41086a2802003602000ccc010b200341d8006a2001200241046a28020041084103108d052003280258450dca0120002003290358370200200041086a200341d8006a41086a2802003602000ccb010b200341d8006a2001200241046a28020041014100108d052003280258450dc90120002003290358370200200041086a200341d8006a41086a2802003602000cca010b200341d8006a2001200241046a28020041014100108d052003280258450dc80120002003290358370200200041086a200341d8006a41086a2802003602000cc9010b200341d8006a2001200241046a28020041024100108d052003280258450dc70120002003290358370200200041086a200341d8006a41086a2802003602000cc8010b200341d8006a2001200241046a28020041024100108d052003280258450dc60120002003290358370200200041086a200341d8006a41086a2802003602000cc7010b200341d8006a2001200241046a28020041014101108d052003280258450dc50120002003290358370200200041086a200341d8006a41086a2802003602000cc6010b200341d8006a2001200241046a28020041014101108d052003280258450dc40120002003290358370200200041086a200341d8006a41086a2802003602000cc5010b200341d8006a2001200241046a28020041024101108d052003280258450dc30120002003290358370200200041086a200341d8006a41086a2802003602000cc4010b200341d8006a2001200241046a28020041024101108d052003280258450dc20120002003290358370200200041086a200341d8006a41086a2802003602000cc3010b200341d8006a2001200241046a28020041044101108d052003280258450dc10120002003290358370200200041086a200341d8006a41086a2802003602000cc2010b200341d8006a2001200241046a28020041044101108d052003280258450dc00120002003290358370200200041086a200341d8006a41086a2802003602000cc1010b200341d8006a2001200241046a28020041044100108e052003280258450dbf0120002003290358370200200041086a200341d8006a41086a2802003602000cc0010b200341d8006a2001200241046a28020041084101108e052003280258450dbe0120002003290358370200200041086a200341d8006a41086a2802003602000cbf010b200341d8006a2001200241046a28020041044102108e052003280258450dbd0120002003290358370200200041086a200341d8006a41086a2802003602000cbe010b200341d8006a2001200241046a28020041084103108e052003280258450dbc0120002003290358370200200041086a200341d8006a41086a2802003602000cbd010b200341d8006a2001200241046a28020041014100108e052003280258450dbb0120002003290358370200200041086a200341d8006a41086a2802003602000cbc010b200341d8006a2001200241046a28020041024100108e052003280258450dba0120002003290358370200200041086a200341d8006a41086a2802003602000cbb010b200341d8006a2001200241046a28020041014101108e052003280258450db90120002003290358370200200041086a200341d8006a41086a2802003602000cba010b200341d8006a2001200241046a28020041024101108e052003280258450db80120002003290358370200200041086a200341d8006a41086a2802003602000cb9010b200341d8006a2001200241046a28020041044101108e052003280258450db70120002003290358370200200041086a200341d8006a41086a2802003602000cb8010b20012802002102200341003602380240024020022802080d00200341ec006a41013602002003420237025c20034194abc60036025820034101360204200320033602682003200341386a360200200341106a200341d8006a103320032802102202450d002003290214210b0c010b0240200141206a2802002202200141246a22042802004f0d00024020022001411c6a280200470d00200241016a22042002490db701200241017422052004200520044b1b22044100480db7010240024020020d002004102821020c010b200128021820022004102c21020b2002450d9801200120023602182001411c6a2004360200200141206a28020021020b200128021820026a41003a0000200141206a2201200128020041016a3602000cb8010b200341ec006a220141013602002003420137025c20034190aec600360258200341013602042003200436020020032003360268200341106a200341d8006a103320032802102202450db7012003200329021437021420032002360210200141013602002003420137025c200341c4a7c60036025820034128360204200320033602682003200341106a360200200341386a200341d8006a103302402003280214450d002003280210102a0b20032802382202450db701200329023c210b0b2000200b370204200020023602000cb7010b20012802002102200341003602380240024020022802080d00200341ec006a41013602002003420237025c20034194abc60036025820034101360204200320033602682003200341386a360200200341106a200341d8006a103320032802102202450d002003290214210b0c010b200341d8006a200141186a2204200141286a4100108905024020032d00584101460d000240200141206a2802002202200141246a22052802004f0d00024020022001411c6a280200470d00200241016a22052002490db701200241017422062005200620054b1b22054100480db7010240024020020d002005102821020c010b200428020020022005102c21020b2002450d9901200120023602182001411c6a2005360200200141206a28020021020b200128021820026a41003a0000200141206a2201200128020041016a3602000cb8010b200341ec006a220141013602002003420137025c20034190aec600360258200341013602042003200536020020032003360268200341106a200341d8006a103320032802102202450db7012003200329021437021420032002360210200141013602002003420137025c200341c4a7c60036025820034128360204200320033602682003200341106a360200200341386a200341d8006a103302402003280214450d002003280210102a0b20032802382202450db701200329023c210b0c010b200328025c2202450db601200341e0006a290300210b0b2000200b370204200020023602000cb6010b0240200141206a2802002202200141246a22042802004f0d00024020022001411c6a280200470d00200241016a22042002490db401200241017422052004200520044b1b22044100480db4010240024020020d002004102821020c010b200128021820022004102c21020b2002450d9701200120023602182001411c6a2004360200200141206a28020021020b200128021820026a41003a0000200141206a2201200128020041016a3602000cb5010b200341ec006a220141013602002003420137025c20034190aec600360258200341013602042003200436020020032003360268200341106a200341d8006a103320032802102202450db4012003200329021437021420032002360210200141013602002003420137025c200341c4a7c60036025820034128360204200320033602682003200341106a360200200341386a200341d8006a103302402003280214450d002003280210102a0b20032802382201450db4012000200329023c370204200020013602000cb5010b0240200141206a2802002202200141246a22042802004f0d00024020022001411c6a280200470d00200241016a22042002490db301200241017422052004200520044b1b22044100480db3010240024020020d002004102821020c010b200128021820022004102c21020b2002450d9701200120023602182001411c6a2004360200200141206a28020021020b200128021820026a41013a0000200141206a2201200128020041016a3602000cb4010b200341ec006a220141013602002003420137025c20034190aec600360258200341013602042003200436020020032003360268200341106a200341d8006a103320032802102202450db3012003200329021437021420032002360210200141013602002003420137025c200341c4a7c60036025820034128360204200320033602682003200341106a360200200341386a200341d8006a103302402003280214450d002003280210102a0b20032802382201450db3012000200329023c370204200020013602000cb4010b0240200141206a2802002202200141246a22042802004f0d00024020022001411c6a280200470d00200241016a22042002490db201200241017422052004200520044b1b22044100480db2010240024020020d002004102821020c010b200128021820022004102c21020b2002450d9701200120023602182001411c6a2004360200200141206a28020021020b200128021820026a41023a0000200141206a2201200128020041016a3602000cb3010b200341ec006a220141013602002003420137025c20034190aec600360258200341013602042003200436020020032003360268200341106a200341d8006a103320032802102202450db2012003200329021437021420032002360210200141013602002003420137025c200341c4a7c60036025820034128360204200320033602682003200341106a360200200341386a200341d8006a103302402003280214450d002003280210102a0b20032802382201450db2012000200329023c370204200020013602000cb3010b0240200141206a2802002202200141246a22042802004f0d00024020022001411c6a280200470d00200241016a22042002490db101200241017422052004200520044b1b22044100480db1010240024020020d002004102821020c010b200128021820022004102c21020b2002450d9701200120023602182001411c6a2004360200200141206a28020021020b200128021820026a41033a0000200141206a2201200128020041016a3602000cb2010b200341ec006a220141013602002003420137025c20034190aec600360258200341013602042003200436020020032003360268200341106a200341d8006a103320032802102202450db1012003200329021437021420032002360210200141013602002003420137025c200341c4a7c60036025820034128360204200320033602682003200341106a360200200341386a200341d8006a103302402003280214450d002003280210102a0b20032802382201450db1012000200329023c370204200020013602000cb2010b200341d8006a20014100108f052003280258450db00120002003290358370200200041086a200341d8006a41086a2802003602000cb1010b200341d8006a200141001090052003280258450daf0120002003290358370200200041086a200341d8006a41086a2802003602000cb0010b200341d8006a200141001090052003280258450dae0120002003290358370200200041086a200341d8006a41086a2802003602000caf010b200341d8006a200141001090052003280258450dad0120002003290358370200200041086a200341d8006a41086a2802003602000cae010b200341d8006a200141001090052003280258450dac0120002003290358370200200041086a200341d8006a41086a2802003602000cad010b200341d8006a200141001090052003280258450dab0120002003290358370200200041086a200341d8006a41086a2802003602000cac010b200341d8006a200141001090052003280258450daa0120002003290358370200200041086a200341d8006a41086a2802003602000cab010b200341d8006a200141001090052003280258450da90120002003290358370200200041086a200341d8006a41086a2802003602000caa010b200341d8006a200141001090052003280258450da80120002003290358370200200041086a200341d8006a41086a2802003602000ca9010b200341d8006a200141001090052003280258450da70120002003290358370200200041086a200341d8006a41086a2802003602000ca8010b200341d8006a200141001090052003280258450da60120002003290358370200200041086a200341d8006a41086a2802003602000ca7010b200341d8006a20014101108f052003280258450da50120002003290358370200200041086a200341d8006a41086a2802003602000ca6010b200341d8006a200141011090052003280258450da40120002003290358370200200041086a200341d8006a41086a2802003602000ca5010b200341d8006a200141011090052003280258450da30120002003290358370200200041086a200341d8006a41086a2802003602000ca4010b200341d8006a200141011090052003280258450da20120002003290358370200200041086a200341d8006a41086a2802003602000ca3010b200341d8006a200141011090052003280258450da10120002003290358370200200041086a200341d8006a41086a2802003602000ca2010b200341d8006a200141011090052003280258450da00120002003290358370200200041086a200341d8006a41086a2802003602000ca1010b200341d8006a200141011090052003280258450d9f0120002003290358370200200041086a200341d8006a41086a2802003602000ca0010b200341d8006a200141011090052003280258450d9e0120002003290358370200200041086a200341d8006a41086a2802003602000c9f010b200341d8006a200141011090052003280258450d9d0120002003290358370200200041086a200341d8006a41086a2802003602000c9e010b200341d8006a200141011090052003280258450d9c0120002003290358370200200041086a200341d8006a41086a2802003602000c9d010b200341d8006a200141011090052003280258450d9b0120002003290358370200200041086a200341d8006a41086a2802003602000c9c010b200341d8006a200141021090052003280258450d9a0120002003290358370200200041086a200341d8006a41086a2802003602000c9b010b200341d8006a200141021090052003280258450d990120002003290358370200200041086a200341d8006a41086a2802003602000c9a010b200341d8006a200141021090052003280258450d980120002003290358370200200041086a200341d8006a41086a2802003602000c99010b200341d8006a200141021090052003280258450d970120002003290358370200200041086a200341d8006a41086a2802003602000c98010b200341d8006a200141021090052003280258450d960120002003290358370200200041086a200341d8006a41086a2802003602000c97010b200341d8006a200141021090052003280258450d950120002003290358370200200041086a200341d8006a41086a2802003602000c96010b200341d8006a200141031090052003280258450d940120002003290358370200200041086a200341d8006a41086a2802003602000c95010b200341d8006a200141031090052003280258450d930120002003290358370200200041086a200341d8006a41086a2802003602000c94010b200341d8006a200141031090052003280258450d920120002003290358370200200041086a200341d8006a41086a2802003602000c93010b200341d8006a200141031090052003280258450d910120002003290358370200200041086a200341d8006a41086a2802003602000c92010b200341d8006a200141031090052003280258450d900120002003290358370200200041086a200341d8006a41086a2802003602000c91010b200341d8006a200141031090052003280258450d8f0120002003290358370200200041086a200341d8006a41086a2802003602000c90010b200341d8006a200141001091052003280258450d8e0120002003290358370200200041086a200341d8006a41086a2802003602000c8f010b200341d8006a200141001091052003280258450d8d0120002003290358370200200041086a200341d8006a41086a2802003602000c8e010b200341d8006a200141001091052003280258450d8c0120002003290358370200200041086a200341d8006a41086a2802003602000c8d010b200341d8006a200141001092052003280258450d8b0120002003290358370200200041086a200341d8006a41086a2802003602000c8c010b200341d8006a200141001092052003280258450d8a0120002003290358370200200041086a200341d8006a41086a2802003602000c8b010b200341d8006a200141001092052003280258450d890120002003290358370200200041086a200341d8006a41086a2802003602000c8a010b200341d8006a200141001092052003280258450d880120002003290358370200200041086a200341d8006a41086a2802003602000c89010b200341d8006a200141001092052003280258450d870120002003290358370200200041086a200341d8006a41086a2802003602000c88010b200341d8006a200141001092052003280258450d860120002003290358370200200041086a200341d8006a41086a2802003602000c87010b200341d8006a200141001092052003280258450d850120002003290358370200200041086a200341d8006a41086a2802003602000c86010b200341d8006a200141001092052003280258450d840120002003290358370200200041086a200341d8006a41086a2802003602000c85010b200341d8006a200141001092052003280258450d830120002003290358370200200041086a200341d8006a41086a2802003602000c84010b200341d8006a200141001092052003280258450d820120002003290358370200200041086a200341d8006a41086a2802003602000c83010b200341d8006a200141001092052003280258450d810120002003290358370200200041086a200341d8006a41086a2802003602000c82010b200341d8006a200141001092052003280258450d800120002003290358370200200041086a200341d8006a41086a2802003602000c81010b200341d8006a200141001092052003280258450d7f20002003290358370200200041086a200341d8006a41086a2802003602000c80010b200341d8006a200141001092052003280258450d7e20002003290358370200200041086a200341d8006a41086a2802003602000c7f0b200341d8006a200141001092052003280258450d7d20002003290358370200200041086a200341d8006a41086a2802003602000c7e0b200341d8006a200141011091052003280258450d7c20002003290358370200200041086a200341d8006a41086a2802003602000c7d0b200341d8006a200141011091052003280258450d7b20002003290358370200200041086a200341d8006a41086a2802003602000c7c0b200341d8006a200141011091052003280258450d7a20002003290358370200200041086a200341d8006a41086a2802003602000c7b0b200341d8006a200141011092052003280258450d7920002003290358370200200041086a200341d8006a41086a2802003602000c7a0b200341d8006a200141011092052003280258450d7820002003290358370200200041086a200341d8006a41086a2802003602000c790b200341d8006a200141011092052003280258450d7720002003290358370200200041086a200341d8006a41086a2802003602000c780b200341d8006a200141011092052003280258450d7620002003290358370200200041086a200341d8006a41086a2802003602000c770b200341d8006a200141011092052003280258450d7520002003290358370200200041086a200341d8006a41086a2802003602000c760b200341d8006a200141011092052003280258450d7420002003290358370200200041086a200341d8006a41086a2802003602000c750b200341d8006a200141011092052003280258450d7320002003290358370200200041086a200341d8006a41086a2802003602000c740b200341d8006a200141011092052003280258450d7220002003290358370200200041086a200341d8006a41086a2802003602000c730b200341d8006a200141011092052003280258450d7120002003290358370200200041086a200341d8006a41086a2802003602000c720b200341d8006a200141011092052003280258450d7020002003290358370200200041086a200341d8006a41086a2802003602000c710b200341d8006a200141011092052003280258450d6f20002003290358370200200041086a200341d8006a41086a2802003602000c700b200341d8006a200141011092052003280258450d6e20002003290358370200200041086a200341d8006a41086a2802003602000c6f0b200341d8006a200141011092052003280258450d6d20002003290358370200200041086a200341d8006a41086a2802003602000c6e0b200341d8006a200141011092052003280258450d6c20002003290358370200200041086a200341d8006a41086a2802003602000c6d0b200341d8006a200141011092052003280258450d6b20002003290358370200200041086a200341d8006a41086a2802003602000c6c0b200341d8006a200141021091052003280258450d6a20002003290358370200200041086a200341d8006a41086a2802003602000c6b0b200341d8006a200141021091052003280258450d6920002003290358370200200041086a200341d8006a41086a2802003602000c6a0b200341d8006a200141021091052003280258450d6820002003290358370200200041086a200341d8006a41086a2802003602000c690b200341d8006a200141021091052003280258450d6720002003290358370200200041086a200341d8006a41086a2802003602000c680b200341d8006a200141021091052003280258450d6620002003290358370200200041086a200341d8006a41086a2802003602000c670b200341d8006a200141021091052003280258450d6520002003290358370200200041086a200341d8006a41086a2802003602000c660b200341d8006a200141021091052003280258450d6420002003290358370200200041086a200341d8006a41086a2802003602000c650b200341d8006a200141021092052003280258450d6320002003290358370200200041086a200341d8006a41086a2802003602000c640b200341d8006a200141021092052003280258450d6220002003290358370200200041086a200341d8006a41086a2802003602000c630b200341d8006a200141021092052003280258450d6120002003290358370200200041086a200341d8006a41086a2802003602000c620b200341d8006a200141021092052003280258450d6020002003290358370200200041086a200341d8006a41086a2802003602000c610b200341d8006a200141021092052003280258450d5f20002003290358370200200041086a200341d8006a41086a2802003602000c600b200341d8006a200141021092052003280258450d5e20002003290358370200200041086a200341d8006a41086a2802003602000c5f0b200341d8006a200141021092052003280258450d5d20002003290358370200200041086a200341d8006a41086a2802003602000c5e0b200341d8006a200141031091052003280258450d5c20002003290358370200200041086a200341d8006a41086a2802003602000c5d0b200341d8006a200141031091052003280258450d5b20002003290358370200200041086a200341d8006a41086a2802003602000c5c0b200341d8006a200141031091052003280258450d5a20002003290358370200200041086a200341d8006a41086a2802003602000c5b0b200341d8006a200141031091052003280258450d5920002003290358370200200041086a200341d8006a41086a2802003602000c5a0b200341d8006a200141031091052003280258450d5820002003290358370200200041086a200341d8006a41086a2802003602000c590b200341d8006a200141031091052003280258450d5720002003290358370200200041086a200341d8006a41086a2802003602000c580b200341d8006a200141031091052003280258450d5620002003290358370200200041086a200341d8006a41086a2802003602000c570b200341d8006a200141031092052003280258450d5520002003290358370200200041086a200341d8006a41086a2802003602000c560b200341d8006a200141031092052003280258450d5420002003290358370200200041086a200341d8006a41086a2802003602000c550b200341d8006a200141031092052003280258450d5320002003290358370200200041086a200341d8006a41086a2802003602000c540b200341d8006a200141031092052003280258450d5220002003290358370200200041086a200341d8006a41086a2802003602000c530b200341d8006a200141031092052003280258450d5120002003290358370200200041086a200341d8006a41086a2802003602000c520b200341d8006a200141031092052003280258450d5020002003290358370200200041086a200341d8006a41086a2802003602000c510b200341d8006a200141031092052003280258450d4f20002003290358370200200041086a200341d8006a41086a2802003602000c500b200341d8006a2001410141001093052003280258450d4e20002003290358370200200041086a200341d8006a41086a2802003602000c4f0b200341d8006a2001410241001093052003280258450d4d20002003290358370200200041086a200341d8006a41086a2802003602000c4e0b200341d8006a2001410241001093052003280258450d4c20002003290358370200200041086a200341d8006a41086a2802003602000c4d0b200341d8006a2001410341001093052003280258450d4b20002003290358370200200041086a200341d8006a41086a2802003602000c4c0b200341d8006a2001410341001093052003280258450d4a20002003290358370200200041086a200341d8006a41086a2802003602000c4b0b200341d8006a2001410041011093052003280258450d4920002003290358370200200041086a200341d8006a41086a2802003602000c4a0b200341d8006a2001410041011093052003280258450d4820002003290358370200200041086a200341d8006a41086a2802003602000c490b200341d8006a2001410241011093052003280258450d4720002003290358370200200041086a200341d8006a41086a2802003602000c480b200341d8006a2001410241011093052003280258450d4620002003290358370200200041086a200341d8006a41086a2802003602000c470b200341d8006a2001410341011093052003280258450d4520002003290358370200200041086a200341d8006a41086a2802003602000c460b200341d8006a2001410341011093052003280258450d4420002003290358370200200041086a200341d8006a41086a2802003602000c450b200341d8006a2001410041021093052003280258450d4320002003290358370200200041086a200341d8006a41086a2802003602000c440b200341d8006a2001410041021093052003280258450d4220002003290358370200200041086a200341d8006a41086a2802003602000c430b200341d8006a2001410141021093052003280258450d4120002003290358370200200041086a200341d8006a41086a2802003602000c420b200341d8006a2001410141021093052003280258450d4020002003290358370200200041086a200341d8006a41086a2802003602000c410b200341d8006a2001410341021093052003280258450d3f20002003290358370200200041086a200341d8006a41086a2802003602000c400b200341d8006a2001410041031093052003280258450d3e20002003290358370200200041086a200341d8006a41086a2802003602000c3f0b200341d8006a2001410041031093052003280258450d3d20002003290358370200200041086a200341d8006a41086a2802003602000c3e0b200341d8006a2001410141031093052003280258450d3c20002003290358370200200041086a200341d8006a41086a2802003602000c3d0b200341d8006a2001410141031093052003280258450d3b20002003290358370200200041086a200341d8006a41086a2802003602000c3c0b200341d8006a2001410241031093052003280258450d3a20002003290358370200200041086a200341d8006a41086a2802003602000c3b0b200341d8006a2001410241001093052003280258450d3920002003290358370200200041086a200341d8006a41086a2802003602000c3a0b200341d8006a2001410341011093052003280258450d3820002003290358370200200041086a200341d8006a41086a2802003602000c390b200341d8006a2001410041021093052003280258450d3720002003290358370200200041086a200341d8006a41086a2802003602000c380b200341d8006a20014101410310930520032802580d1b0c360b411841011037000b200941011037000b200541041037000b200541041037000b200641041037000b411841011037000b411a41011037000b200641041037000b411841011037000b200341ec006a41013602002003420237025c200341b0a3c6003602582003413136023c2003200441056a3602382003200341386a360268200341106a200341d8006a1033200041086a200341106a41086a280200360200200020032903103702000c2d0b200741011037000b200641011037000b200641011037000b200541011037000b200641011037000b200441011037000b200541011037000b200541011037000b200541011037000b200641011037000b200441011037000b200441011037000b200541011037000b200441011037000b200441011037000b200441011037000b200441011037000b20002003290358370200200041086a200341d8006a41086a2802003602000c1b0b200329023c210b200328023821010b2001450d182000200b370204200020013602000c190b200329023c210b200328023821010b2001450d162000200b370204200020013602000c170b200328025c2201450d150b2000200b370204200020013602000c150b2004450d132001290200210b0b2000200b370204200020043602000c130b02400240024002400240200141306a2802002202417f6a220420024f0d00200420024b0d00200128022820044103746a22052802002204200141206a220628020022024b0d01200421010c020b411810282200450d022003421837025c20032000360258200341d8006a4100411810870520032003280260220041186a3602602000200328025822016a41184196adc60041181088052003200329025c37025c200320013602584193a2c600413b200341d8006a41d0a2c6001038000b024002402001411c6a280200220720026b200420026b2208490d0020012802182107200221010c010b200220086a22092002490d132007410174220a2009200a20094b1b22094100480d130240024020070d002009102821070c010b200128021820072009102c21070b2007450d03200120073602182001411c6a2009360200200141206a28020021010b200720016a21090240024020084102490d002009410420042002417f736a22021099051a2007200220016a22016a21090c010b2008450d010b200941043a0000200141016a21010b20062001360200200541013a00060c130b411841011037000b200941011037000b200641027421060340200320042802002205360248200220054d0d0220022005417f736a220520024f0d060240200720054103746a22052d00044103460d0020052d00054104470d040b200441046a21042006417c6a22060d000b410421090b200341d8006a200141186a2202200d410010890520032d00584101470d02200341086a200341e4006a2802003602002003200329025c3703000c030b200341ec006a220441023602002003411c6a41013602002003420237025c200341b0adc60036025820034101360214200320023602002003200341106a360268200320033602182003200341c8006a360210200341386a200341d8006a1033200328023821022003200329023c37021420032002360210200441013602002003420137025c200341c4a7c60036025820034128360204200320033602682003200341106a360200200341386a200341d8006a103302402003280214450d002003280210102a0b2003200329023c370204200320032802383602000c020b2003411c6a4131360200200341ec006a41023602002003420237025c200341c0a3c6003602582003200541056a360218200341313602142003200341106a3602682003200341306a3602102003200341d8006a10330c010b0240200941ff01714104460d00200341d8006a2002200d200910890502400240024020032d00584101460d000240200141206a2802002204200141246a22052802004f0d00024020042001411c6a280200470d00200441016a22052004490d10200441017422062005200620054b1b22054100480d100240024020040d002005102821020c010b200228020020042005102c21020b2002450d04200120023602182001411c6a2005360200200141206a28020021040b200128021820046a20093a0000200141206a2202200228020041016a3602000c040b200341ec006a220241013602002003420137025c20034190aec600360258200341013602042003200536020020032003360268200341106a200341d8006a103320032802102204450d032003200329021437021420032004360210200241013602002003420137025c200341c4a7c60036025820034128360204200320033602682003200341106a360200200341386a200341d8006a103302402003280214450d002003280210102a0b20032802382202450d03200329023c210b0c010b200328025c2202450d02200341e0006a290300210b0b2003200b370204200320023602000c020b200541011037000b200341003602000b024020032802002202450d0020002003290204370204200020023602000c0d0b0240024002400240200141306a2802002202417f6a220420024f0d00200420024d0d010b411810282200450d012003421837025c20032000360258200341d8006a4100411810870520032003280260220041186a3602602000200328025822016a41184196adc60041181088052003200329025c37025c200320013602584193a2c600413b200341d8006a41d0a2c6001038000b02400240200128022820044103746a22052802002204200141206a220628020022024b0d00200421010c010b024002402001411c6a280200220720026b200420026b2208490d0020012802182107200221010c010b200220086a22092002490d0d2007410174220a2009200a20094b1b22094100480d0d0240024020070d002009102821070c010b200128021820072009102c21070b2007450d03200120073602182001411c6a2009360200200141206a28020021010b200720016a21090240024020084102490d002009410420042002417f736a22021099051a2007200220016a22016a21090c010b2008450d010b200941043a0000200141016a21010b20062001360200200541013a00060c0d0b411841011037000b200941011037000b41f2adc600411d1050000b20032802382202450d00200329023c210b0c010b200141306a2802002202417f6a220420024f0d01200420024b0d01200128022820044103746a22052802002204200141206a220628020022024b0d02200421010c030b2000200b370204200020023602000c080b411810282200450d022003421837025c20032000360258200341d8006a4100411810870520032003280260220041186a3602602000200328025822016a41184196adc60041181088052003200329025c37025c200320013602584193a2c600413b200341d8006a41d0a2c6001038000b024002402001411c6a280200220720026b200420026b2208490d0020012802182107200221010c010b200220086a22092002490d042007410174220a2009200a20094b1b22094100480d040240024020070d002009102821070c010b200128021820072009102c21070b2007450d03200120073602182001411c6a2009360200200141206a28020021010b200720016a21090240024020084102490d002009410420042002417f736a22021099051a2007200220016a22016a21090c010b2008450d010b200941043a0000200141016a21010b20062001360200200541013a00060c040b411841011037000b200941011037000b1031000b200341d8006a200141186a2006108a052003280258450d0020002003290358370200200041086a200341d8006a41086a2802003602000c010b200041003602000b200341f0006a24000b6401017f230041206b2202240020024132360204200220003602002001411c6a2802002100200128021821012002411c6a41013602002002420137020c200241b0aec6003602082002200236021820012000200241086a10352101200241206a240020010b810101017f024002400240200041046a280200220320016b20024f0d00200120026a22022001490d02200341017422012002200120024b1b22014100480d020240024020030d002001102821020c010b200028020020032001102c21020b2002450d0120002002360200200041046a20013602000b0f0b200141011037000b1031000bd90101017f230041e0006b22042400200420013602082004200336020c024020012003470d00200020022001109a051a200441e0006a24000f0b200441286a41146a4108360200200441346a4125360200200441106a41146a410336020020044203370214200441c8afc6003602102004412536022c2004200441086a36024020042004410c6a360244200442043703582004420137024c2004419cb0c6003602482004200441286a3602202004200441c8006a3602382004200441c4006a3602302004200441c0006a360228200441106a41d8b0c600103e000bb90601037f230041d0006b22042400200420033a000f0240024002400240024020022802082205417f6a220620054f0d00200620054d0d010b411810282202450d012004421837023420042002360230200441306a4100411810870520042004280238220241186a3602382002200428023022056a41184196adc6004118108805200420042902343702342004200536023041e0a2c6004134200441306a41d0a2c6001038000b200141086a2802002105200228020020064103746a2206280200210202400240024020062d0006450d0020052002460d010b024002400240200520024d0d00200141086a2005417f6a2202360200200128020020026a2d00002205417c6a220241014b0d02024020020e020400040b4118102822020d01411841011037000b412b10282202450d05200041013a0000200241276a41002800fea646360000200241206a41002900f7a646370000200241186a41002900efa646370000200241106a41002900e7a646370000200241086a41002900dfa646370000200241002900d7a646370000200041086a42ab808080b005370200200041046a20023602000c060b200241106a41002900a6ad46370000200241086a410029009ead4637000020024100290096ad4637000020044298808080800337022420042002360220200441c4006a410136020020044201370234200441c4a7c6003602302004412836024c2004200441c8006a3602402004200441206a360248200441106a200441306a103302402004280224450d002004280220102a0b200041013a0000200041046a20042903103702002000410c6a200441106a41086a2802003602000c050b0240200341ff017122024104460d0020052002470d020b200041003a0000200020053a00010c040b20004180083b01000c030b200420053a0048200441c4006a4102360200200441206a410c6a41303602002004420237023420044184a7c600360230200441303602242004200441206a3602402004200441c8006a36022820042004410f6a360220200441106a200441306a10332000410c6a200441186a280200360200200041046a2004290310370200200041013a00000c020b411841011037000b412b41011037000b200441d0006a24000bbd0502047f017e230041d0006b22032400024002400240024002400240200241086a2802002204417f6a220520044f0d00200520044d0d010b411810282202450d01200241106a41002900a6ad46370000200241086a410029009ead4637000020024100290096ad4637000020034298808080800337022420032002360220200341cc006a41013602002003420137023c200341c4a7c600360238200341283602142003200341106a3602482003200341206a3602102000200341386a10332003280224450d042003280220102a0c040b0240024002402002280200220620054103746a2d000522054104460d00200341386a200120022005108905024020032d00384101470d002000200329023c370200200041086a200341c4006a2802003602000c070b200241086a2802002204450d01200228020021060b200241086a2004417f6a2202360200200620024103746a290200220742808080808080c0ff0083428080808080808001520d010b411810282202450d02200241106a41002900a6ad46370000200241086a410029009ead4637000020024100290096ad4637000020034298808080800337022420032002360220200341cc006a41013602002003420137023c200341c4a7c600360238200341283602142003200341106a3602482003200341206a3602102000200341386a10332003280224450d042003280220102a0c040b200141086a28020021022003200737030820022007a7470d02200041003602000c030b411841011037000b411841011037000b200341cc006a41023602002003412c6a41013602002003420237023c200341a4a6c60036023820034101360224200320023602342003200341206a3602482003200341086a3602282003200341346a360220200341106a200341386a1033200041086a200341106a41086a280200360200200020032903103702000b200341d0006a24000bac0301057f230041c0006b2203240020032002360200024002402001280204220420024b0d002001280208417c6a21052001410c6a280200410374210102400340024020010d00200320043602042003412c6a4102360200200341306a410c6a41013602002003420337021c200341f0aec600360218200341013602342003200341306a3602282003200341046a36023820032003360230200341086a200341186a10332000410c6a200341106a280200360200200041046a2003290308370200200041013a00000c040b02402004200541046a2802006a220620044f0d00412010282204450d02200041013a0000200441186a41002900e8ae46370000200441106a41002900e0ae46370000200441086a41002900d8ae46370000200441002900d0ae46370000200041086a42a08080808004370200200041046a20043602000c040b200141786a2101200541086a2105200420024b21072006210420070d0020062104200620024d0d000b20052d00002104200041003a0000200020043a00010c020b412041011037000b200041003a00002000200128020020026a2d00003a00010b200341c0006a24000bbd0201037f230041106b220224000240024020002d00004104470d00200220012802184181a5c60041032001411c6a28020028020c11000022003a000820022001360200200241003a0009200241003602040c010b200220012802184184a5c60041082001411c6a28020028020c1100003a000820022001360200200241003a0009200241003602042002200036020c20022002410c6a418ca5c600105d210120022d0008210020022802042203450d00200041ff0171210441012100024020040d00024020034101470d0020012d0009450d00200128020022042d00004104710d0041012100200428021841f4afc00041012004411c6a28020028020c1100000d010b2001280200220028021841c8a4c60041012000411c6a28020028020c11000021000b200120003a00080b200241106a2400200041ff01714100470bfe0501037f230041d0006b22052400200520023602082005200336020c024002400240417f41012002411f71742002411f4b1b20034b0d00200541386a200141186a2203200141286a410010890520052d00384101470d012000200529023c370200200041086a200541c4006a2802003602000c020b200541cc006a41023602002005411c6a41013602002005420337023c20054180a4c600360238200541013602142005200541106a36024820052005410c6a3602182005200541086a360210200541206a200541386a1033200041086a200541206a41086a280200360200200020052903203702000c010b2001280200210220054100360220024020022802080d00200541cc006a41013602002005420237023c20054194abc600360238200541013602342005200541306a3602482005200541206a360230200541106a200541386a103320052802102202450d0020002005290214370204200020023602000c010b0240024002400240200141206a2802002202200141246a22062802004f0d00024020022001411c6a280200470d00200241016a22062002490d03200241017422072006200720064b1b22064100480d030240024020020d002006102821020c010b200328020020022006102c21020b2002450d02200120023602182001411c6a2006360200200141206a28020021020b200128021820026a20043a0000200141206a2202200228020041016a3602000c030b200541cc006a220241013602002005420137023c20054190aec60036023820054101360234200520063602302005200541306a360248200541106a200541386a103320052802102201450d022005200529021437021420052001360210200241013602002005420137023c200541c4a7c600360238200541283602342005200541306a3602482005200541106a360230200541206a200541386a103302402005280214450d002005280210102a0b20052802202202450d0220002005290224370204200020023602000c030b200641011037000b1031000b200041003602000b200541d0006a24000bae0301017f230041d0006b22052400200520023602082005200336020c024002400240417f41012002411f71742002411f4b1b20034b0d00200128020021022005410036023420022802080d01200541cc006a41013602002005420237023c20054194abc600360238200541013602142005200541106a3602482005200541346a360210200541206a200541386a103320052802202202450d0120002005290224370204200020023602000c020b200541cc006a41023602002005412c6a41013602002005420337023c20054180a4c600360238200541013602242005200541206a36024820052005410c6a3602282005200541086a360220200541106a200541386a1033200041086a200541106a41086a280200360200200020052903103702000c010b200541386a200141186a2202200141286a22032004108905024020052d00384101470d002000200529023c370200200041086a200541c4006a2802003602000c010b200541386a200220034100108905024020052d00384101470d002000200529023c370200200041086a200541c4006a2802003602000c010b200041003602000b200541d0006a24000be50301047f230041c0006b22032400200341286a200141186a2204200141286a20021089050240024020032d00284101470d002000200329022c370200200041086a200341346a2802003602000c010b0240024002400240200141206a2802002202200141246a22052802004f0d00024020022001411c6a280200470d00200241016a22052002490d03200241017422062005200620054b1b22054100480d030240024020020d002005102821020c010b200428020020022005102c21020b2002450d02200120023602182001411c6a2005360200200141206a28020021020b200128021820026a41003a0000200141206a2201200128020041016a3602000c030b2003413c6a220141013602002003420137022c20034190aec60036022820034101360214200320053602102003200341106a360238200341186a200341286a103320032802182202450d022003200329021c37021c20032002360218200141013602002003420137022c200341c4a7c600360228200341283602142003200341106a3602382003200341186a3602102003200341286a10330240200328021c450d002003280218102a0b20032802002201450d0220002003290204370204200020013602000c030b200541011037000b1031000b200041003602000b200341c0006a24000b9e0401047f230041c0006b22032400200341286a200141186a2204200141286a220520021089050240024020032d00284101470d002000200329022c370200200041086a200341346a2802003602000c010b200341286a200420052002108905024020032d00284101470d002000200329022c370200200041086a200341346a2802003602000c010b0240024002400240200141206a2802002202200141246a22052802004f0d00024020022001411c6a280200470d00200241016a22052002490d03200241017422062005200620054b1b22054100480d030240024020020d002005102821020c010b200428020020022005102c21020b2002450d02200120023602182001411c6a2005360200200141206a28020021020b200128021820026a41003a0000200141206a2201200128020041016a3602000c030b2003413c6a220141013602002003420137022c20034190aec60036022820034101360214200320053602102003200341106a360238200341186a200341286a103320032802182202450d022003200329021c37021c20032002360218200141013602002003420137022c200341c4a7c600360228200341283602142003200341106a3602382003200341186a3602102003200341286a10330240200328021c450d002003280218102a0b20032802002201450d0220002003290204370204200020013602000c030b200541011037000b1031000b200041003602000b200341c0006a24000be50301057f230041c0006b22032400200341286a200141186a2204200141286a20021089050240024020032d00284101470d002000200329022c370200200041086a200341346a2802003602000c010b0240024002400240200141206a2802002205200141246a22062802004f0d00024020052001411c6a280200470d00200541016a22062005490d03200541017422072006200720064b1b22064100480d030240024020050d002006102821050c010b200428020020052006102c21050b2005450d02200120053602182001411c6a2006360200200141206a28020021050b200128021820056a20023a0000200141206a2201200128020041016a3602000c030b2003413c6a220141013602002003420137022c20034190aec60036022820034101360214200320063602102003200341106a360238200341186a200341286a103320032802182202450d022003200329021c37021c20032002360218200141013602002003420137022c200341c4a7c600360228200341283602142003200341106a3602382003200341186a3602102003200341286a10330240200328021c450d002003280218102a0b20032802002201450d0220002003290204370204200020013602000c030b200641011037000b1031000b200041003602000b200341c0006a24000b9e0401057f230041c0006b22032400200341286a200141186a2204200141286a220520021089050240024020032d00284101470d002000200329022c370200200041086a200341346a2802003602000c010b200341286a200420052002108905024020032d00284101470d002000200329022c370200200041086a200341346a2802003602000c010b0240024002400240200141206a2802002205200141246a22062802004f0d00024020052001411c6a280200470d00200541016a22062005490d03200541017422072006200720064b1b22064100480d030240024020050d002006102821040c010b200428020020052006102c21040b2004450d02200120043602182001411c6a2006360200200141206a28020021050b200128021820056a20023a0000200141206a2201200128020041016a3602000c030b2003413c6a220141013602002003420137022c20034190aec60036022820034101360214200320063602102003200341106a360238200341186a200341286a103320032802182202450d022003200329021c37021c20032002360218200141013602002003420137022c200341c4a7c600360228200341283602142003200341106a3602382003200341186a3602102003200341286a10330240200328021c450d002003280218102a0b20032802002201450d0220002003290204370204200020013602000c030b200641011037000b1031000b200041003602000b200341c0006a24000be50301047f230041c0006b22042400200441286a200141186a2205200141286a20021089050240024020042d00284101470d002000200429022c370200200041086a200441346a2802003602000c010b0240024002400240200141206a2802002202200141246a22062802004f0d00024020022001411c6a280200470d00200241016a22062002490d03200241017422072006200720064b1b22064100480d030240024020020d002006102821020c010b200528020020022006102c21020b2002450d02200120023602182001411c6a2006360200200141206a28020021020b200128021820026a20033a0000200141206a2201200128020041016a3602000c030b2004413c6a220141013602002004420137022c20044190aec60036022820044101360214200420063602102004200441106a360238200441186a200441286a103320042802182202450d022004200429021c37021c20042002360218200141013602002004420137022c200441c4a7c600360228200441283602142004200441106a3602382004200441186a3602102004200441286a10330240200428021c450d002004280218102a0b20042802002201450d0220002004290204370204200020013602000c030b200641011037000b1031000b200041003602000b200441c0006a24000b02000b17000240200041046a280200450d002000280200102a0b0b15002000280200220028020020002802082001105f0b100020012000280200200028020810450bfb0101027f230041106b220224002002200128021841b8aec60041052001411c6a28020028020c1100003a000820022001360200200241003a0009200241003602042002200036020c20022002410c6a41c0aec600105d1a20022d00082101024020022802042203450d00200141ff0171210041012101024020000d00024020034101470d0020022d000941ff0171450d00200228020022002d00004104710d0041012101200028021841f4afc00041012000411c6a28020028020c1100000d010b2002280200220128021841c8a4c60041012001411c6a28020028020c11000021010b200220013a00080b200241106a2400200141ff01714100470b2c01017f02402002450d00200021030340200320013a0000200341016a21032002417f6a22020d000b0b20000b3601017f02402002450d00200021030340200320012d00003a0000200341016a2103200141016a21012002417f6a22020d000b0b20000b7101017f0240024020012000490d002002450d01200021030340200320012d00003a0000200141016a2101200341016a21032002417f6a22020d000c020b0b2002450d002001417f6a21012000417f6a21030340200320026a200120026a2d00003a00002002417f6a22020d000b0b20000b4a01037f4100210302402002450d000240034020002d0000220420012d00002205470d01200141016a2101200041016a21002002417f6a2202450d020c000b0b200420056b21030b20030b5701017e02400240200341c000710d002003450d012001410020036b413f71ad8820022003413f71ad220486842102200120048621010c010b20012003413f71ad862102420021010b20002001370300200020023703080b5701017e02400240200341c000710d002003450d0120012003413f71ad2204882002410020036b413f71ad86842101200220048821020c010b20022003413f71ad882101420021020b20002001370300200020023703080b7501027e200020034220882205200142208822067e200320027e7c200420017e7c200342ffffffff0f832203200142ffffffff0f8322017e2204422088200320067e7c22034220887c200342ffffffff0f83200520017e7c22034220887c37030820002003422086200442ffffffff0f83843703000b3e01017f230041106b2205240020052001200220032004410010a205200529030021012000200541086a29030037030820002001370300200541106a24000b4c01017f230041206b22052400200542003703182005420037031020052001200220032004200541106a10a205200529031021012000200529031837030820002001370300200541206a24000be20502037f067e230041306b2206240002400240024002400240024002400240024002402002500d002003500d012004500d02200479a7200279a76b2207413f4b0d0341ff0020076b2108200741016a21070c080b02402004500d0020050d040c060b024002402005450d0020034200510d0620054200370308200520012003823703000c010b20034200510d050b200120038021010c060b2004500d030240024002402001500d0020047b4201510d01200479a7200279a76b2207413e4b0d0241ff0020076b2108200741016a21070c090b02402005450d0020054200370300200520022004823703080b200220048021010c070b02402005450d002005200137030020052004427f7c2002833703080b200220047a423f838821010c060b2005450d040c020b024020037b4201510d0041bf7f200379a7200279a76b22076b2108200741c1006a21070c060b02402005450d002005420037030820052003427f7c2001833703000b20034201510d06200641206a2001200220037aa7109e05200641286a2903002102200629032021010c060b2005450d020b2005200137030020052002370308420021010c020b00000b420021010b420021020c010b200620012002200841ff0071109d05200641106a20012002200741ff0071109e05200641086a2903002102200641106a41086a2903002109200629030021012006290310210a0240024020070d004200210b4200210c0c010b4200210c4200210d03402009420186200a423f8884220b200b427f8520047c200a4201862002423f8884220a427f85220b20037c200b54ad7c423f87220b2004837d200a200b200383220e54ad7d2109200a200e7d210a420020024201862001423f8884842102200d2001420186842101200b420183220b210d2007417f6a22070d000b0b02402005450d002005200a370300200520093703080b200c20024201862001423f8884842102200b20014201868421010b2000200137030020002002370308200641306a24000b0b9bb1060200418080c0000b80b1061800100011000000187f11001700000009030000050000006361706163697479206f766572666c6f77000000a00010004600000063010000130000003300000004000000040000003400000035000000360000006120666f726d617474696e6720747261697420696d706c656d656e746174696f6e2072657475726e656420616e206572726f72003700000000000000010000003800000000000000000000002f72757374632f316464313838343839313633366430656235313135376431333732333030373662636632303632372f7372632f6c6962636f72652f666d742f6d6f642e72730101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000020202020202020202020202020202020202020202020202020202020202030303030303030303030303030303030404040404000000000000000000000000000802100020000000280210001200000037000000000000000100000039000000696e646578206f7574206f6620626f756e64733a20746865206c656e20697320206275742074686520696e646578206973203030303130323033303430353036303730383039313031313132313331343135313631373138313932303231323232333234323532363237323832393330333133323333333433353336333733383339343034313432343334343435343634373438343935303531353235333534353535363537353835393630363136323633363436353636363736383639373037313732373337343735373637373738373938303831383238333834383538363837383838393930393139323933393439353936393739383939000024031000060000002a031000220000006898110018000000170a000005000000696e64657820206f7574206f662072616e676520666f7220736c696365206f66206c656e677468206c03100016000000820310000d00000068981100180000001d0a000005000000736c69636520696e64657820737461727473206174202062757420656e6473206174206030785b2e2e2e5d00560410000b00000002171000160000008f0310000100000040041000160000000308000009000000e01610000e000000ee16100004000000f2161000100000008f0310000100000040041000160000000708000005000000a01610002b000000cb161000150000007a01000015000000560410000b000000610410002600000087041000080000008f041000060000008f03100001000000400410001600000014080000050000007372632f6c6962636f72652f7374722f6d6f642e72736279746520696e64657820206973206e6f742061206368617220626f756e646172793b20697420697320696e7369646520202862797465732029206f662060000000d604100002000000c0041000160000006204000011000000c00410001600000056040000280000007372632f6c6962636f72652f666d742f6d6f642e72732e2e000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ffffffffffffffffffffffffffff00000000000000000000000000000000000000000000000000000000000000000000f8030000000000000000000000000000000000000000000000000000000000000000feffffffffbfb6000000000000000000ff070000000000f8ffff0000010000000000000000000000c09f9f3d0000000002000000ffffff0700000000000000000000c0ff01000000000000f80f20801010004a000000d012100000020000d01410003a00000000010203040506070809080a0b0c0d0e0f10111213140215161718191a1b1c1d1e1f2002020202020202020202210202020202020202020202020202222324252602270228020202292a2b022c2d2e2f300202310202023202020202020202023302023402020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202023502360237020202020202020238023902020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202023a3b3c020202023d02023e3f4041424344454602020247020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202024802020202020202020202024902020202023b020001020202020302020202040205060202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020207020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020200010305050606030706080809110a1c0b190c140d120e0d0f0410031212130916011705180219031a071c021d011f1620032b042c022d0b2e01300331023201a702a902aa04ab08fa02fb05fd04fe03ff09ad78798b8da23057588b8c901c1ddd0e0f4b4cfbfc2e2f3f5c5d5fb5e2848d8e9192a9b1babbc5c6c9cadee4e5ff00041112293134373a3b3d494a5d848e92a9b1b4babbc6cacecfe4e500040d0e11122931343a3b4546494a5e646584919b9dc9cecf0d112945495764658d91a9b4babbc5c9dfe4e5f0040d1145496465808184b2bcbebfd5d7f0f183858ba4a6bebfc5c7cecfdadb4898bdcdc6cecf494e4f57595e5f898e8fb1b6b7bfc1c6c7d71116175b5cf6f7feff800d6d71dedf0e0f1f6e6f1c1d5f7d7eaeafbbbcfa16171e1f46474e4f585a5c5e7e7fb5c5d4d5dcf0f1f572738f747596972f5f262e2fa7afb7bfc7cfd7df9a409798308f1fc0c1ceff4e4f5a5b07080f10272feeef6e6f373d3f42459091feff536775c8c9d0d1d8d9e7feff00205f2282df048244081b04061181ac0e80ab351e1580e003190801042f043404070301070607110a500f1207550802041c0a090308030703020303030c0405030b06010e15053a0311070605100757070207150d500443032d03010411060f0c3a041d255f206d046a2580c80582b0031a0682fd035907150b1709140c140c6a060a061a0659072b05460a2c040c040103310b2c041a060b0380ac060a061f414c042d0374083c030f033c0738082b0582ff1118082f112d032010210f808c048297190b158894052f053b07020e180980b030740c80d61a0c0580ff0580b605240c9bc60ad23010848d033709815c1480b80880c73035040a06380846080c06740b1e035a0459098083181c0a16094808808a06aba40c170431a10481da26070c050580a511816d1078282a064c04808d0480be031b030f0d0006010103010402080809020a050b02100111041205131114021502170219041c051d0824016a036b02bc02d102d40cd509d602d702da01e005e102e802ee20f004f906fa020c273b3e4e4f8f9e9e9f060709363d3e56f3d0d104141836375657bd35cecfe01287898e9e040d0e11122931343a4546494a4e4f64655a5cb6b71b1ca8a9d8d909379091a8070a3b3e66698f926f5feeef5a629a9b2728559da0a1a3a4a7a8adbabcc4060b0c151d3a3f4551a6a7cccda007191a22253e3fc5c604202325262833383a484a4c50535556585a5c5e606365666b73787d7f8aa4aaafb0c0d00c72a3a4cbcc6e6f5e227b0503042d036504012f2e80821d03310f1c0424091e052b0544040e2a80aa06240424042808340b018090813709160a088098390363080930160521031b05014038044b052f040a070907402027040c0936033a051a07040c07504937330d33072e080a81261f808128082a808617094e041e0f430e19070a0647092709750b3f412a063b050a0651060105100305808b602048080a80a65e22450b0a060d1339070a362c041080c03c64530c0180a0451b4808531d398107460a1d03474937030e080a0639070a81361980c7320d839b66750b80c48abc842f8fd18247a1b98239072a040260260a460a28051382b05b654b0439071140041c97f80882f3a50d811f3103110408818c89046b050d03090710936080f60a73086e1746809a140c570919808781470385420f1585502b80d52d031a040281703a0501850080d7294c040a04028311444c3d80c23c06010455051b3402810e2c04640c560a0d035d033d391d0d2c040907020e06809a83d60a0d030b05740c59070c140c0438080a0628081e527703310380a60c14040305030d06856a000000601010002000000027000000190000006010100020000000280000002000000060101000200000002a0000001900000060101000200000002b0000001800000060101000200000002c0000002000000000000000000000007372632f6c6962636f72652f756e69636f64652f626f6f6c5f747269652e72730000c0fbef3e00000000000e0000000000000000000000000000f8fffbffffff0700000000000014fe21fe000c00000002000000000000501e2080000c00004006000000000000108639020000002300be2100000c0000fc02000000000000d01e20c0000c0000000400000000000040012080000000000011000000000000c0c13d60000c0000000200000000000090443060000c00000003000000000000581e2080000c00000000845c8000000000000000000000f207807f000000000000000000000000f21f003f000000000000000000030000a002000000000000fe7fdfe0fffeffffff1f40000000000000000000000000e0fd66000000c301001e006420002000000000000000e00000000000001c0000001c0000000c0000000c00000000000000b03f40fe0f200000000000380000000000006000000000020000000000008701040e00008009000000000000407fe51ff89f000000000000ff7f0f0000000000f0170400000000f80f00030000003c3b00000000000040a303000000000000f0cf000000f7fffd211003fffffffffffffffb00100000000000000000ffffffff01000000000000800300000000000000008000000000ffffffff0000000000fc00000000000600000000000000000080f73f000000c0000000000000000000000300440800006000000030000000ffff038000000000c03f000080ff030000000000070000000000c833000000002000000000000000007e660008100000000000100000000000009dc1020000000030400000000000202100000000004000000000ffff0000ffff00000000000000000001000000020003000000000000000000000000000000000000000000000000000004000005000000000000000006000000000000000007000008090a000b0c0d0e0f000010111200001314151600001718191a1b001c0000001d0000000000001e1f202100000000002200230024252600000000270000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002829000000000000000000000000000000002a2b0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002c0000000000000000000000000000000000002d2e00002f0000000000000000000000000000000000000000000000000000000000003031320000000000000000000000000000000000000000003300000029000000000000340000000000000000000000000000000000000000000000350036000000000000000000000000000000000000000000000000000037380000383838390000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000200000000001000000000000000000c0076ef0000000000087000000006000000000000000f0000000c0ff01000000000002000000000000ff7f0000000000008003000000000078060700000080ef1f000000000000000800030000000000c07f001e000000000000000000000080d34000000080f8070000030000000000005801008000c01f1f0000000000000000ff5c00004000000000000000000000f9a50d000000000000000000000000803cb00100003000000000000000000000f8a70100000000000000000000000028bf00000000e0bc0f0000000000000080ff060000f00c01000000fe0700000000f87980007e0e0000000000fc7f03000000000000000000007fbf0000fcfffffc6d000000000000007eb4bf000000000000000000a3000000000000000000000018000000000000001f000000000000007f0000800000000000000080070000000000000000600000000000000000a0c307f8e70f0000003c00001c00000000000000ffffffffffff7ff8ffffffffff1f2000100000f8feff00007ffffff9db0700000000000000f0000000007f0000000000f00700000000000000000000ffffffffffffffffffffffffffffffffffff000063616c6c656420604f7074696f6e3a3a756e77726170282960206f6e206120604e6f6e65602076616c75657372632f6c6962636f72652f6f7074696f6e2e7273626567696e203c3d20656e642028203c3d2029207768656e20736c6963696e672060206973206f7574206f6620626f756e6473206f66206066616c736574727565426f72726f774572726f72426f72726f774d75744572726f7270616e69636b6564206174200000711710000100000072171000030000003897110000000000701710000100000070171000010000003a27272c20000000cb16100015000000a60400000500000098171000150000008d040000050000007372632f6c6962636f72652f726573756c742e72735b5d0a3a0000000c000000040000003b0000003c0000003d0000002c0a2c203300000004000000040000003e0000003f0000004000000020202020207b20207b0a207d7d28280a2c0000003300000004000000040000004100000033000000040000000400000042000000557466384572726f7276616c69645f75705f746f6572726f725f6c656e00000033000000040000000400000043000000370000000000000001000000440000004500000046000000370000000000000001000000440000004500000046000000901810001e0000005074110013000000b903000009000000617373657274696f6e206661696c65643a20696e646578203c3d206c656e0000c81810001d0000005074110013000000e103000009000000617373657274696f6e206661696c65643a20696e646578203c206c656e0000000019100043000000f60a00003000000000000000000000002f72757374632f316464313838343839313633366430656235313135376431333732333030373662636632303632372f7372632f6c6962616c6c6f632f7665632e7273000019100043000000020b00002c0000002f686f6d652f616e6472652f2e636172676f2f72656769737472792f7372632f6769746875622e636f6d2d316563633632393964623965633832332f7061726974792d7363616c652d636f6465632d312e302e352f7372632f636f6d706163742e72736865616420697320736574207768656e20666972737420656c656d656e7420697320696e7365727465640a090909090909616e6420756e736574207768656e206c61737420656c656d656e742069732072656d6f7665643b0a0909090909096966206865616420697320536f6d65207468656e20697420706f696e747320746f206578697374696e67206b65793b2071656470726576696f75732f6e657874206f6e6c7920636f6e7461696e206578697374696e6720656e74697265733b0a090909090909776520656e756d6572617465207573696e67206e6578743b20656e747279206578697374733b207165646f766572666c6f77206d756c7469706c79696e6720676173206c696d69742062792070726963650000003700000000000000010000004700000048000000490000004a0000004b0000004c0000000c1b1000330000003f1b10004b000000f600000005000000636f6e74726163742073756273797374656d20726573756c74696e6720696e20706f73697469766520696d62616c616e6365212f686f6d652f616e6472652f576f726b62656e63682f706172697479746563682f7375627374726174652f73726d6c2f636f6e7472616374732f7372632f6163636f756e745f64622e72734f6666656e636573205265706f7274730000c01b100019000000e01b100048000000bb0100002d000000000000000000000000000000617474656d707420746f20646976696465206279207a65726f000000000000002f72757374632f316464313838343839313633366430656235313135376431333732333030373662636632303632372f7372632f6c6962636f72652f6f70732f61726974682e7273616c726561647920626f72726f776564616c7265616479206d757461626c7920626f72726f7765643700000000000000010000004d0000003700000000000000010000004e000000387d110028000000881c10004300000055000000010000002f686f6d652f616e6472652f576f726b62656e63682f706172697479746563682f7375627374726174652f73726d6c2f6f6666656e6365732f7372632f6c69622e727300881c1000430000005500000001000000551d10003600000054191000630000005e01000005000000000000000000000000000000181d10003d00000054191000630000006501000005000000736869667465642073756666696369656e74206269747320726967687420746f206c656164206f6e6c79206c656164696e67207a65726f733b2071656450726576696f7573206d617463682061726d206d61746368657320616e7974696e67206c657373207468616e20325e33303b2071656400551d10003600000054191000630000008a0100000500000000000000000000000000000000000000000000005419100063000000910100000500000053657373696f6e20486973746f726963616c53657373696f6e734c696e6b616765206973207570646174656420696e206361736520656e7472792069732072656d6f7665643b0a0909090909697420616c7761797320706f696e747320746f206578697374696e67206b6579733b20716564000000000000441f10000700000001010000000000004b1f10000d00000000000000581f10003400000000000000000000000000000000000000389711008c1f100000000000000000009c1f100001000000000000000000000000000000a41f10001600000002010100000000006f8c11000400000000000000738c11000e00000000000000ba1f1000120000000000000038971100cc1f10000000000000000000dc1f100001000000000000000100000000000000e41f10001200000001010000000000006f8c11000400000000000000e7ea1000070000000000000000000000000000000000000038971100f81f10000000000000000000082010000600000000000000010000005265706f7274735265706f727449644f663c543e4f6666656e636544657461696c733c543a3a4163636f756e7449642c20543a3a4964656e74696669636174696f6e5475706c653e3700000000000000010000004f000000a121100052000000436f6e63757272656e745265706f727473496e6465785665633c5265706f727449644f663c543e3e37000000000000000100000050000000572110004a0000005265706f72747342794b696e64496e646578000037000000000000000100000051000000382010004400000038971100000000007c2010002f0000003897110000000000ab20100052000000fd2010005a00000020456e756d65726174657320616c6c207265706f727473206f662061206b696e6420616c6f6e672077697468207468652074696d6520746865792068617070656e65642e20416c6c207265706f7274732061726520736f72746564206279207468652074696d65206f66206f6666656e63652e204e6f74652074686174207468652061637475616c2074797065206f662074686973206d617070696e6720697320605665633c75383e602c207468697320697320626563617573652076616c756573206f6620646966666572656e7420747970657320617265206e6f7420737570706f7274656420617420746865206d6f6d656e7420736f2077652061726520646f696e6720746865206d616e75616c2073657269616c697a6174696f6e2e204120766563746f72206f66207265706f727473206f66207468652073616d65206b696e6420746861742068617070656e6564206174207468652073616d652074696d6520736c6f742e20546865207072696d61727920737472756374757265207468617420686f6c647320616c6c206f6666656e6365207265636f726473206b65796564206279207265706f7274206964656e746966696572732e72656163686564206d6178696d756d2064657074682c2063616e6e6f7420696e7374616e7469617465520000001800000004000000530000005400000055000000560000005700000058000000696e73756666696369656e742072656d61696e696e672062616c616e6365416c69766520636f6e7472616374206f7220746f6d6273746f6e6520616c7265616479206578697374736e6f7420656e6f7567682067617320746f20706179206261736520696e7374616e7469617465206665656e6f7420656e6f7567682067617320746f20706179207472616e736665722066656572656163686564206d6178696d756d2064657074682c2063616e6e6f74206d616b6520612063616c6c6e6f7420656e6f7567682067617320746f2070617920626173652063616c6c20666565636f6e747261637420686173206265656e2065766963746564636f6e74726163742063616e6e6f742062652064657374726f79656420647572696e672072656375727369766520657865637574696f6e61206e657374656420657865637574696f6e20636f6e74657874206d7573742068617665206120706172656e743b20716564696d2d6f6e6c696e653a6f66666c696e4f6666656e63657320436f6e63757272656e745265706f727473496e6465780000005900000008000000040000005a0000007375627374726174652d6e6f64650000df6acb689907609b0200000037e397fc7c91f5e40100000040fe3ad401f8959a03000000d2bc9897eed08f1501000000f78b278be53f454c01000000ed99c5acb25eedf502000000cbca25e39f14238701000000687ad44ad37f03c201000000bc9d89904f5b923f0100000068b66ba122c93fa701000000ab3c0572291feb8b010000006772616e62616265696d6f6e0000000040787d010065cd1d00e1f505d85aae1ec0542205b0508f1f38e4750488467020d853e903603c5121d0bf760338323222a8591903402013236039cd02480ef423a82a8f0268f8d42470955c02b8dab525c05a3302d8c4962648bd1102e0b27727a855f601e8a05828e8fedf0180773929c0cacd01586d1a2af8f1be019053fb2a50d8b201d00edc2be0fca80138edbc2c48f2a001e06d9d2d80669a01c80d7e2e500f9501c0575e2f08b6900140323f30e0278d0148202031b0418a0108a3ff3120e8870120bedf32f0fb85013856c03398698401f0fda03478218301b8d87f35d8178201d8c26036183d8101b8223e37508d800188d21c38c8fc7f0168b5f93898877f01a829d139d8297f0120d6ab3ab8db7e0168ae803b389d7e0100ca9a3b68957e0100000000d3bc100006000000000000005b000000000000000000000000000000000000000000000000000000000000005c0000000000000000000000000000005d0000000000000000000000000000005e0000000000000000000000000000003fa7100004000000000000005f000000000000000000000000000000000000000000000000000000000000005e0000000000000000000000020000000000000000000000000000000000000060000000000000000000000000000000e7df10000900000000000000610000000000000000000000000000000000000000000000000000000000000062000000000000000000000002000000000000000000000000000000000000006300000000000000000000000000000095a410000a00000000000000640000000000000000000000000000000000000000000000000000000000000065000000000000000000000002000000000000000000000000000000000000005e00000000000000000000000000000045db1000070000000000000066000000000000000000000000000000000000000000000000000000000000005e000000000000000000000000000000670000000000000000000000000000005e000000000000000000000000000000b239100008000000000000006800000000000000000000000000000000000000000000000000000000000000690000000000000000000000000000006a0000000000000000000000000000006b000000000000000000000000000000d92d110007000000000000006c000000000000000000000000000000000000000000000000000000000000006d0000000000000000000000000000006e0000000000000000000000000000006f000000000000000000000000000000158b1000070000000000000070000000000000000000000000000000000000000000000000000000000000007100000000000000000000000000000072000000000000000000000000000000730000000000000000000000000000007955110009000000000000007400000000000000000000000000000000000000000000000000000000000000750000000000000000000000000000007600000000000000000000000000000077000000000000000000000000000000fe65100007000000000000007800000000000000000000000000000000000000000000000000000000000000790000000000000000000000000000007a0000000000000000000000000000005e000000000000000000000000000000382d100012000000000000007b00000000000000000000000000000000000000000000000000000000000000790000000000000000000000000000007a0000000000000000000000000000005e0000000000000000000000000000004a2d100009000000000000007c000000000000000000000000000000000000000000000000000000000000007d0000000000000000000000000000007e0000000000000000000000000000007f000000000000000000000000000000532d10001300000000000000800000000000000000000000000000000000000000000000000000000000000081000000000000000000000000000000820000000000000000000000000000005e000000000000000000000000000000662d10000f000000020000000000000000000000000000000000000000000000000000000000000000000000830000000000000000000000020000000000000000000000000000000000000084000000000000000000000000000000752d10000700000000000000850000000000000000000000000000000000000000000000000000000000000086000000000000000000000000000000870000000000000000000000000000005e0000000000000000000000000000000596100008000000000000008800000000000000000000000000000000000000000000000000000000000000890000000000000000000000000000008a0000000000000000000000000000008b0000000000000000000000000000007c2d100009000000000000008c000000000000000000000000000000000000000000000000000000000000008d0000000000000000000000000000008e0000000000000000000000000000008f000000000000000000000000000000161311000400000000000000900000000000000000000000000000000000000000000000000000000000000091000000000000000000000000000000920000000000000000000000000000005e000000000000000000000000000000314610000800000000000000930000000000000000000000000000000000000000000000000000000000000094000000000000000000000000000000950000000000000000000000000000005e000000000000000000000000000000852d1000120000000200000000000000000000000000000000000000000000000000000000000000000000005e000000000000000000000002000000000000000000000000000000000000005e000000000000000000000000000000972d1000080000000000000096000000000000000000000000000000000000000000000000000000000000005e000000000000000000000000000000970000000000000000000000000000005e0000000000000000000000546563686e6963616c436f6d6d6974746565456c656374696f6e73546563686e6963616c4d656d6265727368697046696e616c697479547261636b65724772616e647061436f6e747261637473417574686f72697479446973636f766572794f6666656e6365735365656420697320616e207574663820737472696e67000000e02d1000480000009b0a00000a000000e02d100048000000a10a00000e00000000000000000000002f72757374632f316464313838343839313633366430656235313135376431333732333030373662636632303632372f7372632f6c6962636f72652f736c6963652f6d6f642e727300000000ac2e10000a00000000000000e0151100020000000000000000000000b82e1000010000000000000000000000c02e10000d00000000000000a8431100010000000000000000000000d02e100001000000000000000000000000ea10000800000000000000d82e1000040000000000000000000000f82e100001000000000000004e65774163636f756e740000432f10001b0000005265617065644163636f756e740000002c2f100017000000d043110009000000d04311000900000011441100070000001144110007000000002f10002c000000205472616e7366657220737563636565646564202866726f6d2c20746f2c2076616c75652c2066656573292e20416e206163636f756e7420776173207265617065642e2041206e6577206163636f756e742077617320637265617465642e76657374696e672062616c616e636520746f6f206869676820746f2073656e642076616c75656163636f756e74206c6971756964697479207265737472696374696f6e732070726576656e74207769746864726177616c62656e6566696369617279206163636f756e74206d757374207072652d6578697374746f6f2066657720667265652066756e647320696e206163636f756e747061796d656e7420776f756c64206b696c6c206163636f756e740000000000003c3010001100000000000000503010000100000000000000000000005830100001000000000000004865617274626561745265636569766564000000903010000b00000060301000300000002041206e657720686561727462656174207761732072656365697665642066726f6d2060417574686f72697479496460417574686f726974794964496d4f6e6c696e6520476f73736970417442616c616e63657320546f74616c49737375616e6365496d4f6e6c696e65204b65797342616c616e636573204672656542616c616e636542616c616e63657320526573657276656442616c616e636542616c616e636573204c6f636b7342616c616e6365732056657374696e6700000000000000a03110000800000000000000a8311000020000000000000000000000d8311000170000000000000000000000903210000b000000000000009c321000030000000000000000000000e43210000d00000000000000000000004c3310000e000000000000005c331000030000000000000000000000a433100002000000000000007472616e736665720000000046f1100004000000000000004b22110023000000000000005f55110005000000000000001934100013000000ed35100036000000389711000000000023361000420000006536100048000000ad36100045000000f23610002d00000038971100000000001f371000460000003897110000000000c54d11000b000000653710004c000000b137100033000000e43710005a00000038971100000000003e3810001300000038971100000000005138100054000000a53810004b000000f03810003500000025391000370000005c391000560000003897110000000000d84d11000c0000007365745f62616c616e636500000000005712110003000000000000004b2211002300000000000000d93510000800000000000000193410001300000000000000e13510000c0000000000000019341000130000002c34100025000000389711000000000051341000480000009934100042000000db34100046000000213510003a00000038971100000000005b3510002d0000003897110000000000c54d11000b0000008835100020000000a835100031000000d84d11000c000000666f7263655f7472616e736665720000000000001334100006000000000000004b221100230000000000000046f1100004000000000000004b22110023000000000000005f55110005000000000000001934100013000000b433100054000000083410000b0000002045786163746c7920617320607472616e73666572602c2065786365707420746865206f726967696e206d75737420626520726f6f7420616e642074686520736f75726365206163636f756e74206d6179206265207370656369666965642e736f75726365436f6d706163743c543a3a42616c616e63653e20536574207468652062616c616e636573206f66206120676976656e206163636f756e742e20546869732077696c6c20616c74657220604672656542616c616e63656020616e642060526573657276656442616c616e63656020696e2073746f726167652e2069742077696c6c20616c736f2064656372656173652074686520746f74616c2069737375616e6365206f66207468652073797374656d202860546f74616c49737375616e636560292e20496620746865206e65772066726565206f722072657365727665642062616c616e63652069732062656c6f7720746865206578697374656e7469616c206465706f7369742c2069742077696c6c20726573657420746865206163636f756e74206e6f6e636520286073797374656d3a3a4163636f756e744e6f6e636560292e20546865206469737061746368206f726967696e20666f7220746869732063616c6c2069732060726f6f74602e202d20496e646570656e64656e74206f662074686520617267756d656e74732e202d20436f6e7461696e732061206c696d69746564206e756d626572206f6620726561647320616e64207772697465732e6e65775f667265656e65775f7265736572766564205472616e7366657220736f6d65206c697175696420667265652062616c616e636520746f20616e6f74686572206163636f756e742e20607472616e73666572602077696c6c207365742074686520604672656542616c616e636560206f66207468652073656e64657220616e642072656365697665722e2049742077696c6c2064656372656173652074686520746f74616c2069737375616e6365206f66207468652073797374656d2062792074686520605472616e73666572466565602e204966207468652073656e6465722773206163636f756e742069732062656c6f7720746865206578697374656e7469616c206465706f736974206173206120726573756c74206f6620746865207472616e736665722c20746865206163636f756e742077696c6c206265207265617065642e20546865206469737061746368206f726967696e20666f7220746869732063616c6c206d75737420626520605369676e65646020627920746865207472616e736163746f722e202d20446570656e64656e74206f6e20617267756d656e747320627574206e6f7420637269746963616c2c20676976656e2070726f70657220696d706c656d656e746174696f6e7320666f72202020696e70757420636f6e6669672074797065732e205365652072656c617465642066756e6374696f6e732062656c6f772e202d20497420636f6e7461696e732061206c696d69746564206e756d626572206f6620726561647320616e642077726974657320696e7465726e616c6c7920616e64206e6f20636f6d706c657820636f6d7075746174696f6e2e2052656c617465642066756e6374696f6e733a2020202d2060656e737572655f63616e5f77697468647261776020697320616c776179732063616c6c656420696e7465726e616c6c792062757420686173206120626f756e64656420636f6d706c65786974792e2020202d205472616e7366657272696e672062616c616e63657320746f206163636f756e7473207468617420646964206e6f74206578697374206265666f72652077696c6c20636175736520202020202060543a3a4f6e4e65774163636f756e743a3a6f6e5f6e65775f6163636f756e746020746f2062652063616c6c65642e2020202d2052656d6f76696e6720656e6f7567682066756e64732066726f6d20616e206163636f756e742077696c6c2074726967676572202020202060543a3a4475737452656d6f76616c3a3a6f6e5f756e62616c616e6365646020616e642060543a3a4f6e4672656542616c616e63655a65726f3a3a6f6e5f667265655f62616c616e63655f7a65726f602e42616c616e636573000000000000743b10000d0000000000000000000000813b10000a0000000000000000000000000000000000000000000000000000000000000038971100543c100000000000000000008c3b100001000000000000000100000000000000943b10000700000001010000000000000b4e11000c000000000000009b3b10002b0000000000000000000000000000000000000038971100c83b10000000000000000000d83b100001000000000000000000000000000000e03b10000b00000001010000000000000b4e11000c00000000000000813b10000a0000000000000000000000000000000000000038971100543c10000000000000000000ec3b10000b000000000000000100000000000000443c10000f00000001010000000000000b4e11000c00000000000000813b10000a0000000000000000000000000000000000000038971100543c10000000000000000000643c10000b000000000000000100000000000000bc3c10000500000001010000000000000b4e11000c00000000000000c13c10002c0000000000000000000000000000000000000038971100f03c10000000000000000000003d1000010000000000000001000000546f74616c49737375616e6365543a3a42616c616e636500314210002600000056657374696e6756657374696e675363686564756c653c543a3a42616c616e63652c20543a3a426c6f636b4e756d6265723e00003700000000000000010000004f000000fb411000360000004672656542616c616e636500813f1000270000003897110000000000a83f100050000000f83f10005d0000005540100055000000aa4010004f000000f9401000510000004a4110001500000038971100000000005f41100057000000b641100045000000526573657276656442616c616e63650037000000000000000100000098000000363d10005d000000933d1000270000003897110000000000ba3d10005b000000153e10004900000038971100000000005e3e10005d000000bb3e10002d0000003897110000000000e83e1000530000003b3f1000460000004c6f636b735665633c42616c616e63654c6f636b3c543a3a42616c616e63652c20543a3a426c6f636b4e756d6265723e3e00000037000000000000000100000050000000083d10002e00000020416e79206c6971756964697479206c6f636b73206f6e20736f6d65206163636f756e742062616c616e6365732e2054686520616d6f756e74206f66207468652062616c616e6365206f66206120676976656e206163636f756e7420746861742069732065787465726e616c6c792072657365727665643b20746869732063616e207374696c6c2067657420736c61736865642c20627574206765747320736c6173686564206c617374206f6620616c6c2e20546869732062616c616e63652069732061202772657365727665272062616c616e63652074686174206f746865722073756273797374656d732075736520696e206f7264657220746f2073657420617369646520746f6b656e73207468617420617265207374696c6c20276f776e65642720627920746865206163636f756e7420686f6c6465722c20627574207768696368206172652073757370656e6461626c652e205768656e20746869732062616c616e63652066616c6c732062656c6f77207468652076616c7565206f6620604578697374656e7469616c4465706f736974602c207468656e2074686973202772657365727665206163636f756e74272069732064656c657465643a207370656369666963616c6c792c2060526573657276656442616c616e6365602e206073797374656d3a3a4163636f756e744e6f6e63656020697320616c736f2064656c6574656420696620604672656542616c616e63656020697320616c736f207a65726f2028697420616c736f206765747320636f6c6c617073656420746f207a65726f2069662069742065766572206265636f6d6573206c657373207468616e20604578697374656e7469616c4465706f736974602e2920546865202766726565272062616c616e6365206f66206120676976656e206163636f756e742e205468697320697320746865206f6e6c792062616c616e63652074686174206d61747465727320696e207465726d73206f66206d6f7374206f7065726174696f6e73206f6e20746f6b656e732e20497420616c6f6e65206973207573656420746f2064657465726d696e65207468652062616c616e6365207768656e20696e2074686520636f6e747261637420657865637574696f6e20656e7669726f6e6d656e742e205768656e20746869732062616c616e63652066616c6c732062656c6f77207468652076616c7565206f6620604578697374656e7469616c4465706f736974602c207468656e20746865202763757272656e74206163636f756e74272069732064656c657465643a207370656369666963616c6c7920604672656542616c616e6365602e20467572746865722c2074686520604f6e4672656542616c616e63655a65726f602063616c6c6261636b20697320696e766f6b65642c20676976696e672061206368616e636520746f2065787465726e616c206d6f64756c657320746f20636c65616e2075702064617461206173736f6369617465642077697468207468652064656c65746564206163636f756e742e206073797374656d3a3a4163636f756e744e6f6e63656020697320616c736f2064656c657465642069662060526573657276656442616c616e63656020697320616c736f207a65726f2028697420616c736f206765747320636f6c6c617073656420746f207a65726f2069662069742065766572206265636f6d6573206c657373207468616e20604578697374656e7469616c4465706f736974602e20496e666f726d6174696f6e20726567617264696e67207468652076657374696e67206f66206120676976656e206163636f756e742e2054686520746f74616c20756e6974732069737375656420696e207468652073797374656d2e0000000000704310001200000000000000813b10000a000000000000003897110084431000000000000000000094431000010000000000000000000000000011000b00000000000000813b10000a00000000000000389711009c43100000000000000000000c001100010000000000000000000000140011000b00000000000000813b10000a00000000000000389711009c431000000000000000000020001100010000000000000000000000280011001200000000000000813b10000a00000000000000389711009c43100000000000000000003c001100010000000000000000000000440011001200000000000000813b10000a0000000000000038971100ac43100000000000000000006800110001000000000000004578697374656e7469616c4465706f736974000037000000000000000100000099000000bc431000350000003700000000000000010000009a0000003700000000000000010000009b00000020546865206d696e696d756d20616d6f756e7420726571756972656420746f206b65657020616e206163636f756e74206f70656e2e776520676f74207468652076616c696461746f725f69642066726f6d2063757272656e745f76616c696461746f72733b0a09090909090963757272656e745f76616c696461746f727320697320736574206f662063757272656e746c7920616374696e672076616c696461746f72733b0a090909090909746865206d617070696e67206265747765656e207468652076616c696461746f7220696420616e64206974732066756c6c206964656e74696669636174696f6e2073686f756c642062652076616c69643b0a09090909090974687573206046756c6c4964656e74696669636174696f6e4f663a3a636f6e76657274602063616e27742072657475726e20604e6f6e65603b0a09090909090971656473726d6c2f696d2d6f6e6c696e652d776f726b65722d7374617475730030451000480000009b0a00000a0000002f72757374632f316464313838343839313633366430656235313135376431333732333030373662636632303632372f7372632f6c6962636f72652f736c6963652f6d6f642e727300000000a44510000900000000000000b045100002000000000000000000000038971100000000000000000068656172746265617400000000000000a44510000900000000000000e04510001900000000000000f94510000900000000000000024610002f0000004865617274626561743c543a3a426c6f636b4e756d6265723e7369676e61747572653c543a3a417574686f7269747949642061732052756e74696d654170705075626c69633e3a3a5369676e6174757265496d4f6e6c696e650000000000000044471000080000000000000000000000925111000e00000000000000000000000000000000000000000000000000000000000000389711004c47100000000000000000005c4710000100000000000000010000000000000064471000040000000000000000000000684710001300000000000000000000000000000000000000000000000000000000000000389711007c47100000000000000000008c47100001000000000000000100000000000000944710001200000002010100000000009f8d11000c00000000000000a64710000900000000000000e7ea1000070000000000000038971100b04710000000000000000000c0471000020000000000000001000000476f7373697041743700000000000000010000009c00000061481000280000004b6579735665633c543a3a417574686f7269747949643e00370000000000000001000000500000002d4810003400000052656365697665644865617274626561747341757468496e6465780037000000000000000100000051000000d04710003a0000000a4810002300000020466f7220656163682073657373696f6e20696e646578207765206b6565702061206d617070696e67206f662060417574686f7269747949646020746f20606f6666636861696e3a3a4f70617175654e6574776f726b5374617465602e205468652063757272656e7420736574206f66206b6579732074686174206d61792069737375652061206865617274626561742e2054686520626c6f636b206e756d626572207768656e2077652073686f756c6420676f737369702e6e6f7420656e6f75676820667265652066756e64730000387d110028000000b84810004300000096010000010000002f686f6d652f616e6472652f576f726b62656e63682f706172697479746563682f7375627374726174652f73726d6c2f62616c616e6365732f7372632f6c69622e72734f75746461746564206865617274626561742072656365697665642e496e76616c696420686561727462656174207369676e61747572652e4475706c696361746564206865617274626561742e4e6f6e206578697374656e74207075626c6963206b65792eb8481000430000009601000001000000676f74206f766572666c6f7720616674657220616464696e6720612066656520746f2076616c756562616c616e636520746f6f206c6f7720746f2073656e642076616c756564657374696e6174696f6e2062616c616e636520746f6f206869676820746f20726563656976652076616c756576616c756520746f6f206c6f7720746f20637265617465206163636f756e7454696d657374616d702055706461746554696d657374616d7020526563656e7448696e74730000404a100031000000714a10004b0000007d0000000400000046696e616c2068696e74206d7573742062652075706461746564206f6e6c79206f6e636520696e2074686520626c6f636b2f686f6d652f616e6472652f576f726b62656e63682f706172697479746563682f7375627374726174652f73726d6c2f66696e616c6974792d747261636b65722f7372632f6c69622e7273d44a100023000000714a10004b0000007e0000000400000046696e616c697a6564206865696768742061626f766520626c6f636b206e756d62657200104b100019000000304b100048000000bb0100002d000000617474656d707420746f20646976696465206279207a65726f000000000000002f72757374632f316464313838343839313633366430656235313135376431333732333030373662636632303632372f7372632f6c6962636f72652f6f70732f61726974682e7273576974686472617720686173206265656e20636865636b65642061626f76653b0a090909647565735f6c696d69746564203c2072656e745f627564676574203c2062616c616e6365202d2073756273697374656e6365203c2062616c616e6365202d206578697374656e7469616c5f6465706f7369743b0a09090971656400005900000008000000040000009d00000054696d657374616d70204f72646572656448696e747354696d657374616d70204d656469616e616c77617973206174206c65617374206f6e6520726563656e742073616d706c653b20716564726563656e7420616e64206f72646572656420636f6e7461696e207468652073616d65206974656d733b2071656400003300000004000000040000009e000000084d100043000000714a10004b000000b600000004000000c04c1000480000009b0a00000a000000000000002f72757374632f316464313838343839313633366430656235313135376431333732333030373662636632303632372f7372632f6c6962636f72652f736c6963652f6d6f642e72737072756e696e672064696374617465642062792077696e646f775f73697a6520776869636820697320616c776179732073617475726174656420617420313b207165640000000000784d10000a00000000000000844d10000100000000000000000000009c4d1000020000000000000066696e616c5f68696e74000000000000f26510000400000000000000de4e110017000000ac4d10003d000000e94d10001b0000002048696e7420746861742074686520617574686f72206f66207468697320626c6f636b207468696e6b732074686520626573742066696e616c697a656420626c6f636b2069732074686520676976656e206e756d6265722e00000000744e10000a00000000000000925111000e0000000000000038971100804e10000000000000000000904e1000010000000000000000000000984e10000d00000000000000925111000e0000000000000038971100a84e10000000000000000000b84e1000010000000000000057696e646f7753697a6500003700000000000000010000009f000000074f1000460000005265706f72744c6174656e6379000000370000000000000001000000a0000000c04e100047000000205468652064656c617920616674657220776869636820706f696e74207468696e6773206265636f6d6520737573706963696f75732e2044656661756c7420697320313030302e20546865206e756d626572206f6620726563656e742073616d706c657320746f206b6565702066726f6d207468697320636861696e2e2044656661756c74206973203130312e00000000000000005010000b000000000000008c4311000200000000000000000000000c501000010000000000000000000000145010001000000000000000a8431100010000000000000000000000245010000100000000000000000000002c5010000c0000000000000068ea100001000000000000000000000038501000010000000000000000000000405010000e0000000000000050501000020000000000000000000000605010000100000000000000566f74657252656170656400fe50100015000000426164526561706572536c6173686564ef5010000f00000054616c6c7953746172746564ba5010003500000054616c6c7946696e616c697a65640000184411000e000000184411000e000000685010005200000020412074616c6c792028666f7220617070726f76616c20766f746573206f662073656174287329292068617320656e646564202877697468206f6e65206f72206d6f7265206e6577206d656d62657273292e20412074616c6c792028666f7220617070726f76616c20766f746573206f662073656174287329292068617320737461727465642e20736c6173686564207265617065722072656170656420766f7465722c20726561706572436f756e63696c205265676973746572496e666f4f66436f756e63696c204d656d62657273436f756e63696c204e65787446696e616c697a6540521000480000009b0a00000a000000436f756e63696c205465726d4475726174696f6e436f756e63696c2050726573656e746174696f6e4475726174696f6e436f756e63696c204c6561646572626f617264004052100048000000a10a00000e000000436f756e63696c2043616e64696461746573436f756e63696c20566f746572496e666f4f6647757275206d656469746174696f6e66696e616c697a652063616e206f6e6c792062652063616c6c656420616674657220612074616c6c7920697320737461727465642e436f756e63696c20417070726f76616c734f66436f756e63696c20566f746572730000000000002f72757374632f316464313838343839313633366430656235313135376431333732333030373662636632303632372f7372632f6c6962636f72652f736c6963652f6d6f642e727300000000405410000d0000000000000050541000040000000000000000000000b05410001800000000000000000000007055100013000000000000005054100004000000000000000000000084551000060000000000000000000000b45510001300000000000000c8551000040000000000000000000000285610000c0000000000000000000000885610000d0000000000000098561000010000000000000000000000b05610000a000000000000000000000000571000100000000000000010571000010000000000000000000000285710000d0000000000000000000000905710000e00000000000000a0571000030000000000000000000000e8571000090000000000000000000000305810001100000000000000445810000100000000000000000000005c581000030000000000000000000000cce310000d00000000000000745810000100000000000000000000008c581000040000000000000000000000ac5810001900000000000000c8581000010000000000000000000000e0581000020000000000000000000000f05810001100000000000000c85810000100000000000000000000000459100002000000000000007365745f617070726f76616c7300000000000000e46510000500000000000000e96510000900000000000000e4cd10000500000000000000ac5c10001200000000000000f26510000400000000000000f665100008000000000000005f55110005000000000000007a6511000c0000009161100058000000e9611000100000003897110000000000f9611000530000004c6210003000000038971100000000007c62100035000000b162100055000000066310002a00000030631000530000008363100057000000da631000510000002b6410003b0000006664100057000000bd641000370000003897110000000000f46410005400000048651000340000003897110000000000c54d11000b000000d04d1100080000007c65100027000000a365100041000000d84d11000c00000070726f78795f7365745f617070726f76616c7300e060100059000000396110001c0000003897110000000000c54d11000b000000556110003c000000d84d11000c000000726561705f696e6163746976655f766f7465720000000000b76010000e00000000000000fa4e11000c000000000000005712110003000000000000004b2211002300000000000000c56010000900000000000000fa4e11000c00000000000000ce6010001200000000000000ac5c100012000000565f100058000000ae5f100056000000046010002e00000038971100000000003260100045000000389711000000000077601000400000003897110000000000c54d11000b000000d04d1100080000002f5f100027000000d84d11000c000000726574726163745f766f74657200000000000000e4cd10000500000000000000fa4e11000c000000535e10004b00000038971100000000009e5e1000420000003897110000000000e05e10004f0000003897110000000000c54d11000b000000d04d1100080000002f5f100027000000d84d11000c0000007375626d69745f63616e646964616379000000004f5e10000400000000000000fa4e11000c000000be5c10001e0000003897110000000000dc5c1000440000003897110000000000205d100048000000685d100051000000b95d10004c000000055e10001e0000003897110000000000c54d11000b000000235e1000180000003b5e100014000000d84d11000c00000070726573656e745f77696e6e65720000000000009e5c100009000000000000004b2211002300000000000000a75c10000500000000000000645511001500000000000000e4cd10000500000000000000ac5c1000120000007b5b100058000000d35b1000580000002b5c100057000000825c1000070000003897110000000000c54d11000b000000895c100015000000b712110011000000d84d11000c0000007365745f646573697265645f736561747300000000000000d65910000500000000000000fa4e11000c000000bb5a100059000000145b100052000000665b100015000000000000005712110003000000000000004b22110023000000db591000480000003897110000000000235a1000480000006b5a1000500000007365745f70726573656e746174696f6e5f6475726174696f6e00000000000000d65910000500000000000000de4e110017000000805910005600000068591000180000007365745f7465726d5f6475726174696f6e0000001459100054000000685910001800000020536574207468652070726573656e746174696f6e206475726174696f6e2e2049662074686572652069732063757272656e74206120766f7465206265696e672070726573656e74656420666f722c2077696c6c20696e766f6b65206066696e616c697a655f766f7465602e20536574207468652070726573656e746174696f6e206475726174696f6e2e2049662074686572652069732063757272656e746c79206120766f7465206265696e672070726573656e74656420666f722c2077696c6c636f756e742052656d6f7665206120706172746963756c6172206d656d6265722066726f6d20746865207365742e20546869732069732065666665637469766520696d6d6564696174656c792e204e6f74653a20412074616c6c792073686f756c642068617070656e20696e7374616e746c7920286966206e6f7420616c726561647920696e20612070726573656e746174696f6e20706572696f642920746f2066696c6c2074686520736561742069662072656d6f76616c206d65616e732074686174207468652064657369726564206d656d6265727320617265206e6f74206d65742e20536574207468652064657369726564206d656d62657220636f756e743b206966206c6f776572207468616e207468652063757272656e7420636f756e742c207468656e2073656174732077696c6c206e6f7420626520757020656c656374696f6e207768656e2074686579206578706972652e204966206d6f72652c207468656e2061206e657720766f74652077696c6c2062652073746172746564206966206f6e65206973206e6f7420616c726561647920696e2070726f67726573732e20436c61696d2074686174206063616e64696461746560206973206f6e65206f662074686520746f70206063617272795f636f756e74202b20646573697265645f7365617473602063616e646964617465732e204f6e6c7920776f726b7320696666207468652070726573656e746174696f6e20706572696f64206973206163746976652e206063616e646964617465602073686f756c642068617665206174206c6561737420636f6c6c656374656420736f6d65206e6f6e2d7a65726f2060746f74616c6020766f74657320616e6420606f726967696e60206d757374206861766520656e6f7567682066756e647320746f2070617920666f72206120706f74656e7469616c20736c6173682e202d204f28766f746572732920636f6d707574652e63616e646964617465746f74616c436f6d706163743c566f7465496e6465783e205375626d6974206f6e6573656c6620666f722063616e6469646163792e204163636f756e74206d757374206861766520656e6f756768207472616e736665727261626c652066756e647320696e20697420746f207061792074686520626f6e642e204e4f54453a20696620606f726967696e602068617320616c72656164792061737369676e656420617070726f76616c7320766961205b607365745f617070726f76616c73605d2c2069742077696c6c204e4f54206861766520616e7920757361626c652066756e647320746f20706173732063616e64696461637920626f6e6420616e64206d75737420666972737420726574726163742e204e6f746520746861742073657474696e6720617070726f76616c732077696c6c206c6f636b2074686520656e746972652062616c616e6365206f662074686520766f74657220756e74696c2072657472616374696f6e206f72206265696e67207265706f727465642e202d20496e646570656e64656e74206f6620696e7075742e202d205468726565204442206368616e6765732e736c6f742052656d6f7665206120766f7465722e20416c6c20766f746573206172652063616e63656c6c656420616e642074686520766f746572206465706f7369742069732072657475726e65642e2054686520696e646578206d7573742062652070726f7669646564206173206578706c61696e656420696e205b60766f7465725f6174605d2066756e6374696f6e2e20416c736f2072656d6f76657320746865206c6f636b206f6e207468652062616c616e6365206f662074686520766f7465722e20536565205b60646f5f7365745f617070726f76616c732829605d2e202d2054776f20666577657220444220656e74726965732c206f6e65204442206368616e67652e2052656d6f7665206120766f7465722e20466f72206974206e6f7420746f206265206120626f6e642d636f6e73756d696e67206e6f2d6f702c20616c6c20617070726f7665642063616e64696461746520696e6469636573206d757374206e6f772062652065697468657220756e72656769737465726564206f72207265676973746572656420746f20612063616e646964617465207468617420726567697374657265642074686520736c6f742061667465722074686520766f7465722067617665207468656972206c61737420617070726f76616c207365742e20426f746820696e6469636573206d7573742062652070726f7669646564206173206578706c61696e656420696e205b60766f7465725f6174605d2066756e6374696f6e2e204d61792062652063616c6c656420627920616e796f6e652e2052657475726e732074686520766f746572206465706f73697420746f20607369676e6564602e7265706f727465725f696e64657877686f5f696e646578617373756d65645f766f74655f696e646578205365742063616e64696461746520617070726f76616c732066726f6d20612070726f78792e20417070726f76616c20736c6f747320737461792076616c6964206173206c6f6e672061732063616e6469646174657320696e2074686f736520736c6f74732061726520726567697374657265642e202d2053616d6520617320607365745f617070726f76616c73602077697468206f6e65206164646974696f6e616c2073746f7261676520726561642e205365742063616e64696461746520617070726f76616c732e20417070726f76616c20736c6f747320737461792076616c6964206173206c6f6e672061732063616e6469646174657320696e2074686f736520736c6f74732061726520726567697374657265642e204c6f636b73206076616c7565602066726f6d207468652062616c616e6365206f6620606f726967696e6020696e646566696e6974656c792e204f6e6c79205b60726574726163745f766f746572605d206f72205b60726561705f696e6163746976655f766f746572605d2063616e20756e6c6f636b207468652062616c616e63652e206068696e746020617267756d656e7420697320696e74657270726574656420646966666572656e746c79206261736564206f6e3a202d20696620606f726967696e602069732073657474696e6720617070726f76616c7320666f72207468652066697273742074696d653a2054686520696e6465782077696c6c20626520636865636b656420666f722020206265696e6720612076616c6964205f686f6c655f20696e2074686520766f746572206c6973742e2020202d206966207468652068696e7420697320636f72726563746c7920706f696e74696e6720746f206120686f6c652c206e6f206665652069732064656475637465642066726f6d20606f726967696e602e2020202d204f74686572776973652c207468652063616c6c2077696c6c2073756363656564206275742074686520696e6465782069732069676e6f72656420616e642073696d706c792061207075736820746f2074686520202020206c617374206368756e6b207769746820667265652073706163652068617070656e732e20496620746865206e65772070757368206361757365732061206e6577206368756e6b20746f2062652020202020637265617465642c20612066656520696e64696361746564206279205b60566f74696e67466565605d2069732064656475637465642e202d20696620606f726967696e6020697320616c7265616479206120766f7465723a2074686520696e646578205f5f6d7573745f5f2062652076616c696420616e6420706f696e7420746f2074686520636f7272656374202020706f736974696f6e206f662074686520606f726967696e6020696e207468652063757272656e7420766f74657273206c6973742e204e6f7465207468617420616e7920747261696c696e67206066616c73656020766f74657320696e2060766f746573602069732069676e6f7265643b20496e20617070726f76616c20766f74696e672c206e6f7420766f74696e6720666f7220612063616e64696461746520616e6420766f74696e672066616c73652c2061726520657175616c2e202d2054776f20657874726120444220656e74726965732c206f6e65204442206368616e67652e202d20417267756d656e742060766f74657360206973206c696d6974656420696e206c656e67746820746f206e756d626572206f662063616e646964617465732e766f7465735665633c626f6f6c3e68696e74536574496e646578436f756e63696c00000000000000886b1000140000000000000000000000925111000e00000000000000000000000000000000000000000000000000000000000000389711008c76100000000000000000009c6b100001000000000000000100000000000000a46b10000c0000000000000000000000925111000e00000000000000000000000000000000000000000000000000000000000000389711008c7610000000000000000000b06b100001000000000000000100000000000000b86b10000c0000000000000000000000763411000300000000000000000000000000000000000000000000000000000000000000389711008c7610000000000000000000c46b100001000000000000000100000000000000ace61000070000000000000000000000cc6b1000230000000000000000000000000000000000000000000000000000000000000038971100386d10000000000000000000f06b100004000000000000000100000000000000106c1000090000000000000000000000196c10000900000000000000000000000000000000000000000000000000000000000000389711008c7610000000000000000000246c1000010000000000000001000000000000002c6c10000b0000000101000000000000376c100018000000000000004f6c1000110000000000000000000000000000000000000038971100386d100000000000000000003897110000000000000000000100000000000000606c10000e00000001010000000000000b4e11000c000000000000006e6c1000100000000000000000000000000000000000000038971100806c10000000000000000000906c100002000000000000000000000000000000a06c10000b00000001010000000000000b4e11000c00000000000000ab6c1000170000000000000000000000000000000000000038971100c46c10000000000000000000d46c100001000000000000000000000000000000dc6c1000060000000101000000000000f66510000800000000000000e26c1000190000000000000000000000000000000000000038971100386d10000000000000000000fc6c100001000000000000000100000000000000046d10000c0000000000000000000000f66510000800000000000000000000000000000000000000000000000000000000000000389711008c7610000000000000000000106d100001000000000000000100000000000000186d10000a0000000000000000000000f66510000800000000000000000000000000000000000000000000000000000000000000389711008c7610000000000000000000246d1000010000000000000001000000000000002c6d10000a0000000000000000000000255c1100110000000000000000000000000000000000000000000000000000000000000038971100386d10000000000000000000486d100001000000000000000100000000000000506d10000e0000000000000000000000763411000300000000000000000000000000000000000000000000000000000000000000389711008c7610000000000000000000606d100001000000000000000100000000000000686d10000c0000000000000000000000746d10002800000000000000000000000000000000000000000000000000000000000000389711009c6d10000000000000000000ac6d100001000000000000000000000000000000b46d10000b0000000000000000000000bf6d1000210000000000000000000000000000000000000000000000000000000000000038971100e06d10000000000000000000f06d100003000000000000000000000000000000a85c11000500000001010000000000000b4e11000c000000000000000b4e11000c0000000000000000000000000000000000000038971100086e10000000000000000000c05c110002000000000000000000000050726573656e746174696f6e4475726174696f6e6f7210004f0000005465726d4475726174696f6e49721000260000004465736972656453656174730f7210003a0000005665633c28543a3a4163636f756e7449642c20543a3a426c6f636b4e756d626572293e00e37010005500000038711000550000008d71100054000000e17110002e000000566f7465436f756e74566f7465496e64657800009c70100047000000417070726f76616c734f6628543a3a4163636f756e7449642c20536574496e646578295665633c417070726f76616c466c61673e5265676973746572496e666f4f6628566f7465496e6465782c20753332290000370000000000000001000000a100000027701000570000007e7010001e000000566f746572496e666f4f66566f746572496e666f3c42616c616e63654f663c543e3e00003700000000000000010000004f0000000670100021000000566f746572735665633c4f7074696f6e3c543a3a4163636f756e7449643e3e00c36f1000430000004e657874566f746572536574846f10003f000000566f746572436f756e7400006a6f10001a00000043616e646964617465730000370000000000000001000000500000004e6f10001c00000043616e646964617465436f756e7400002a6f1000240000004e65787446696e616c697a6528543a3a426c6f636b4e756d6265722c207533322c205665633c543a3a4163636f756e7449643e29370000000000000001000000a2000000e26e1000480000004c6561646572626f6172645665633c2842616c616e63654f663c543e2c20543a3a4163636f756e744964293e3700000000000000010000004f000000186e100058000000706e100059000000c96e1000190000003700000000000000010000004f0000002047657420746865206c6561646572626f61726420696620776527726520696e207468652070726573656e746174696f6e2070686173652e2054686520666972737420656c656d656e742069732074686520776569676874206f66206561636820656e7472793b204974206d617920626520746865206469726563742073756d6d656420617070726f76616c207374616b65732c206f7220612077656967687465642076657273696f6e206f662069742e20536f727465642066726f6d206c6f7720746f20686967682e20546865206163636f756e747320686f6c64696e672074686520736561747320746861742077696c6c206265636f6d652066726565206f6e20746865206e6578742074616c6c792e2043757272656e74206e756d626572206f66206163746976652063616e64696461746573205468652070726573656e742063616e646964617465206c6973742e2043757272656e74206e756d626572206f6620566f746572732e20746865206e65787420667265652073657420746f2073746f7265206120766f74657220696e2e20546869732077696c6c206b6565702067726f77696e672e205468652070726573656e7420766f746572206c69737420286368756e6b656420616e6420636170706564206174205b60564f5445525f5345545f53495a45605d292e20426173696320696e666f726d6174696f6e2061626f7574206120766f7465722e2054686520766f746520696e64657820616e64206c69737420736c6f742074686174207468652063616e646964617465206077686f60207761732072656769737465726564206f7220604e6f6e6560206966207468657920617265206e6f742063757272656e746c7920726567697374657265642e2054686520746f74616c206e756d626572206f6620766f746520726f756e6473207468617420686176652068617070656e6564206f722061726520696e2070726f67726573732e20205468652063757272656e74206d656d626572736869702e205768656e2074686572652773206120766f746520676f696e67206f6e2c20746869732073686f756c64207374696c6c206265207573656420666f722020657865637574697665206d6174746572732e2054686520626c6f636b206e756d62657220287365636f6e6420656c656d656e7420696e20746865207475706c65292069732074686520626c6f636b20746861742020746865697220706f736974696f6e2069732061637469766520756e74696c202863616c63756c61746564206279207468652073756d206f662074686520626c6f636b206e756d626572207768656e2074686520206d656d6265722077617320656c656374656420616e64207468656972207465726d206475726174696f6e292e204e756d626572206f66206163636f756e747320746861742073686f756c6420636f6e737469747574652074686520636f6c6c6563746976652e20486f77206c6f6e67206561636820706f736974696f6e2069732061637469766520666f722e20486f77206c6f6e6720746f2067697665206561636820746f702063616e64696461746520746f2070726573656e74207468656d73656c7665732061667465722074686520766f746520656e64732e000000000000287510000d000000000000007a6511000c000000000000003897110038751000000000000000000048751000020000000000000000000000587510000a000000000000007a6511000c0000000000000038971100687610000000000000000000647510000100000000000000000000006c75100009000000000000007a6511000c0000000000000038971100787510000000000000000000887510000200000000000000000000009875100014000000000000007a6511000c0000000000000038971100ac7510000000000000000000bc751000020000000000000000000000cc7510000a0000000000000076341100030000000000000038971100d87510000000000000000000e8751000020000000000000000000000f87510001300000000000000196c10000900000000000000389711000c76100000000000000000001c761000030000000000000000000000586511000c00000000000000925111000e0000000000000038971100347610000000000000000000447610000200000000000000000000005476100011000000000000007a6511000c000000000000003897110068761000000000000000000078761000010000000000000000000000807610000a00000000000000763411000300000000000000389711008c76100000000000000000009c761000050000000000000000000000c47610000e0000000000000076341100030000000000000038971100d47610000000000000000000e4761000010000000000000000000000ec76100011000000000000007634110003000000000000003897110000771000000000000000000010771000010000000000000043616e646964616379426f6e64000000370000000000000001000000a30000005f7b10004e000000ad7b100014000000566f74696e67426f6e6400001d7b100042000000566f74696e67466565000000370000000000000001000000a4000000b67a10004a000000007b10001d00000050726573656e74536c617368506572566f7465723700000000000000010000009a000000527a100045000000977a10001f0000004361727279436f756e740000370000000000000001000000a5000000e4791000470000002b7a100027000000496e6163746976654772616365506572696f6400370000000000000001000000a6000000477910004c000000937910004b000000de79100006000000370000000000000001000000a7000000f5781000490000003e791000090000004d696e696d756d566f74696e674c6f636b00000037000000000000000100000099000000b67810003f0000004465636179526174696f00003700000000000000010000009c000000637710004d000000b077100041000000f177100047000000387810004a0000008278100034000000564f5445525f5345545f53495a450000370000000000000001000000a80000003f77100024000000415050524f56414c5f5345545f53495a45000000370000000000000001000000a9000000187710002700000020546865206368756e6b2073697a65206f662074686520617070726f76616c20766563746f722e20546865206368756e6b2073697a65206f662074686520766f74657220766563746f722e20446563617920666163746f72206f6620776569676874207768656e206265696e6720616363756d756c617465642e2049742073686f756c64207479706963616c6c792062652073657420746f205f5f6174206c656173745f5f20606d656d626572736869705f73697a65202d316020746f206b6565702074686520636f6c6c656374697665207365637572652e205768656e2073657420746f20604e602c20697420696e64696361746573206028312f4e295e7460206f66207374616b656420697320646563617965642061742077656967687420696e6372656d656e742073746570206074602e20302077696c6c20726573756c7420696e206e6f20776569676874206265696e6720616464656420617420616c6c20286e6f726d616c20617070726f76616c20766f74696e67292e204120726561736f6e61626c652064656661756c742076616c75652069732032342e204d696e696d756d2061626f757420746861742063616e206265207573656420617320746865206c6f636b65642076616c756520666f7220766f74696e672e20486f77206f6674656e2028696e20626c6f636b732920746f20636865636b20666f72206e657720766f7465732e204120726561736f6e61626c652064656661756c742076616c756520697320313030302e20486f77206d616e7920766f746520696e6469636573206e65656420746f20676f20627920616674657220612074617267657420766f7465722773206c61737420766f7465206265666f726520746865792063616e2062652072656170656420696620746865697220617070726f76616c7320617265206d6f6f742e204120726561736f6e61626c652064656661756c742076616c756520697320312e20486f77206d616e792072756e6e6572732d75702073686f756c64206861766520746865697220617070726f76616c73207065727369737420756e74696c20746865206e65787420766f74652e204120726561736f6e61626c652064656661756c742076616c756520697320322e205468652070756e6973686d656e742c2070657220766f7465722c20696620796f752070726f7669646520616e20696e76616c69642070726573656e746174696f6e2e204120726561736f6e61626c652064656661756c742076616c756520697320312e2054686520616d6f756e74206f662066656520706169642075706f6e206561636820766f7465207375626d697373696f6e2c20756e6c6573732069662074686579207375626d69742061205f686f6c655f20696e64657820616e64207265706c6163652069742e20486f77206d7563682073686f756c64206265206c6f636b656420757020696e206f7264657220746f2062652061626c6520746f207375626d697420766f7465732e20486f77206d7563682073686f756c64206265206c6f636b656420757020696e206f7264657220746f207375626d6974206f6e6527732063616e6469646163792e204120726561736f6e61626c652064656661756c742076616c756520697320392e000000387d110028000000dc7b1000440000000e010000010000002f686f6d652f616e6472652f576f726b62656e63682f706172697479746563682f7375627374726174652f73726d6c2f656c656374696f6e732f7372632f6c69622e7273dc7b1000440000000e01000001000000436f756e63696c2050726f787963616e6e6f74207265617020647572696e672070726573656e746174696f6e20706572696f64766f746520696e646578206e6f742063757272656e7463616e6e6f74207265617020647572696e6720677261636520706572696f6474617267657420666f7220696e616374697669747920636c65616e7570206d757374206265206163746976657265706f72746572206d757374206265206120766f746572696e76616c6964207265706f7274657220696e646578696e76616c69642074617267657420696e646578626164207265706f7274657220696e6465786261642074617267657420696e64657872657472616374696f6e20696e64657820696e76616c696472657472616374696f6e20696e646578206d69736d6174636863616e6e6f742072657472616374207768656e2070726573656e74696e6763616e6e6f742072657472616374206e6f6e2d766f7465726475706c69636174652063616e646964617465207375626d697373696f6e696e76616c69642063616e64696461746520736c6f7463616e64696461746520686173206e6f7420656e6f7567682066756e647363616e6e6f742070726573656e74206f757473696465206f662070726573656e746174696f6e20706572696f64696e646578206e6f742063757272656e747374616b65206465706f736974656420746f2070726573656e742077696e6e657220616e6420626520616464656420746f206c6561646572626f6172642073686f756c64206265206e6f6e2d7a65726f6c6561646572626f617264206d757374206578697374207768696c652070726573656e742070686173652061637469766570726573656e746572206d75737420686176652073756666696369656e7420736c61736861626c652066756e647370726573656e7465642063616e646964617465206d7573742062652063757272656e7463616e646964617465206e6f7420776f72746879206f66206c6561646572626f61726463616e646964617465206d757374206e6f7420666f726d2061206475706c696361746564206d656d62657220696620656c65637465646475706c69636174652070726573656e746174696f6e696e636f727265637420746f74616c6e6f20617070726f76616c206368616e67657320647572696e672070726573656e746174696f6e20706572696f64696e636f727265637420766f746520696e646578616d6f756e74206f662063616e6469646174657320746f207265636569766520617070726f76616c20766f7465732073686f756c64206265206e6f6e2d7a65726f616d6f756e74206f662063616e64696461746520766f7465732063616e6e6f742065786365656420616d6f756e74206f662063616e646964617465736c6f636b65642076616c7565206d757374206265206d6f7265207468616e206c696d697477726f6e6720766f74657220696e6465786e657720766f746572206d75737420686176652073756666696369656e742066756e647320746f207061792074686520626f6e64696e76616c696420766f74657220696e646578000000000000e442110008000000000000008881100001000000000000000000000090811000010000000000000000000000988110000800000000000000c8151100010000000000000000000000a0811000010000000000000000000000a88110000700000000000000b0811000030000000000000000000000c8811000010000000000000000000000d08110000500000000000000c8151100010000000000000000000000d8811000010000000000000000000000e08110000800000000000000c8151100010000000000000000000000e88110000100000000000000ccb710000d000000b98210000e0000005370656e64696e677f8210003a0000004177617264656400ccb710000d0000001144110007000000d0431100090000005f821000200000004275726e740000003c82100023000000526f6c6c6f766572f08110004c000000205370656e64696e67206861732066696e69736865643b20746869732069732074686520616d6f756e74207468617420726f6c6c73206f76657220756e74696c206e657874207370656e642e20536f6d65206f66206f75722066756e64732068617665206265656e206275726e742e20536f6d652066756e64732068617665206265656e20616c6c6f63617465642e205765206861766520656e6465642061207370656e6420706572696f6420616e642077696c6c206e6f7720616c6c6f636174652066756e64732e204e65772070726f706f73616c2e53657373696f6e2056616c696461746f72734772616e64706146696e616c697479205374616c6c656454726561737572792050726f706f73616c730000387d1100280000001c831000430000007f000000010000002f686f6d652f616e6472652f576f726b62656e63682f706172697479746563682f7375627374726174652f73726d6c2f74726561737572792f7372632f6c69622e72734469676573744974656d206e6f7420657175616c0000000000a08310001200000000000000b4831000010000000000000000000000cc83100001000000000000007265706f72745f6d69736265686176696f72000000000000ed8310000700000000000000e7ea100007000000d483100019000000205265706f727420736f6d65206d69736265686176696f722e5f7265706f72744772616e64706146696e616c697479000000000070aa10000b0000000000000000000000238a11002300000000000000000000000000000000000000000000000000000000000000389711008897100000000000000000006c8610000100000000000000010000000000000074861000050000000000000000000000798610001b0000000000000000000000000000000000000000000000000000000000000038971100948610000000000000000000a486100001000000000000000100000000000000ac8610000d0000000000000000000000b9861000230000000000000000000000000000000000000000000000000000000000000038971100b48e10000000000000000000dc86100001000000000000000000000000000000e48610000a0000000000000000000000925111000e0000000000000000000000000000000000000000000000000000000000000038971100788710000000000000000000f086100001000000000000000000000000000000f8861000070000000000000000000000ff8610002000000000000000000000000000000000000000000000000000000000000000389711002087100000000000000000003087100001000000000000000000000000000000388710000c0000000000000000000000448710000500000000000000000000000000000000000000000000000000000000000000389711004c87100000000000000000005c871000020000000000000001000000000000006c8710000c00000001010000000000004487100005000000000000009f8d11000c000000000000000000000000000000000000003897110078871000000000000000000088871000010000000000000000000000308910001b000000537461746553746f72656453746174653c543a3a426c6f636b4e756d6265723e370000000000000001000000aa0000000c8910002400000050656e64696e674368616e676553746f72656450656e64696e674368616e67653c543a3a426c6f636b4e756d6265723edb881000310000004e657874466f726365640000ac8810002f0000005374616c6c656428543a3a426c6f636b4e756d6265722c20543a3a426c6f636b4e756d6265722900370000000000000001000000a1000000888810002400000043757272656e7453657449645365744964000000370000000000000001000000ab00000000881000570000005788100031000000536574496453657373696f6e3700000000000000010000004f00000090871000700000002041206d617070696e672066726f6d206772616e6470612073657420494420746f2074686520696e646578206f6620746865202a6d6f737420726563656e742a2073657373696f6e20666f7220776869636820697473206d656d62657273207765726520726573706f6e7369626c652e20546865206e756d626572206f66206368616e6765732028626f746820696e207465726d73206f66206b65797320616e6420756e6465726c79696e672065636f6e6f6d696320726573706f6e736962696c69746965732920696e20746865202273657422206f66204772616e6470612076616c696461746f72732066726f6d2067656e657369732e20607472756560206966207765206172652063757272656e746c79207374616c6c65642e206e65787420626c6f636b206e756d6265722077686572652077652063616e20666f7263652061206368616e67652e2050656e64696e67206368616e67653a20287369676e616c65642061742c207363686564756c6564206368616e6765292e205374617465206f66207468652063757272656e7420617574686f72697479207365742e205468652063757272656e7420617574686f72697479207365742e000000000078891000080000000000000080891000020000000000000000000000b08910000a000000000000007365745f6b65797300000000dabb10000400000000000000098b10000700000000000000108b10000500000000000000e7ea100007000000008a100039000000398a100048000000818a1000310000003897110000000000b28a1000350000003897110000000000c54d11000b000000e78a100022000000f34d110016000000d84d11000c0000002053657473207468652073657373696f6e206b6579287329206f66207468652066756e6374696f6e2063616c6c657220746f20606b6579602e20416c6c6f777320616e206163636f756e7420746f20736574206974732073657373696f6e206b6579207072696f7220746f206265636f6d696e6720612076616c696461746f722e205468697320646f65736e27742074616b652065666665637420756e74696c20746865206e6578742073657373696f6e2e20546865206469737061746368206f726967696e206f6620746869732066756e6374696f6e206d757374206265207369676e65642e202d204f286c6f67206e2920696e206e756d626572206f66206163636f756e74732e543a3a4b65797370726f6f6653657373696f6e00000000543511000a0000000000000000000000848d1000130000000000000000000000000000000000000000000000000000000000000038971100889710000000000000000000988d100001000000000000000100000000000000a08d10000c00000000000000000000009f8d11000c0000000000000000000000000000000000000000000000000000000000000038971100189710000000000000000000ac8d100001000000000000000100000000000000b48d10000d0000000000000000000000f7431100040000000000000000000000000000000000000000000000000000000000000038971100c48d10000000000000000000d48d100002000000000000000100000000000000e48d10000a0000000000000000000000ee8d10001e00000000000000000000000000000000000000000000000000000000000000389711008897100000000000000000000c8e1000020000000000000001000000000000001c8e10001200000000000000000000002e8e1000080000000000000000000000000000000000000000000000000000000000000038971100889710000000000000000000388e100003000000000000000100000000000000508e1000080000000204010000000000e7ea10000700000000000000588e10000e00000000000000098b1000070000000000000038971100688e10000000000000000000788e100004000000000000000000000000000000988e1000080000000204010000000000e7ea10000700000000000000a08e10001400000000000000588e10000e0000000000000038971100b48e10000000000000000000c48e10000400000000000000000000005665633c543a3a56616c696461746f7249643e008b9110001f00000043757272656e74496e6465786d9110001e0000005175657565644368616e6765640000003700000000000000010000004f000000f69010004e00000044911000290000005175657565644b6579735665633c28543a3a56616c696461746f7249642c20543a3a4b657973293e6f9010004f000000be9010003800000044697361626c656456616c696461746f72735665633c7533323e000002901000200000003897110000000000229010004d0000004e6578744b657973543a3a56616c696461746f72496400003700000000000000010000004f000000db8f10002700000038971100000000002d8f100056000000838f1000580000004b65794f776e6572284b65795479706549642c205665633c75383e293700000000000000010000004f000000e48e10004900000038971100000000002d8f100056000000838f10005800000020546865206f776e6572206f662061206b65792e20546865207365636f6e64206b65792069732074686520604b657954797065496460202b2074686520656e636f646564206b65792e20546865206669727374206b657920697320616c77617973206044454455505f4b45595f5052454649586020746f206861766520616c6c20746865206461746120696e207468652073616d65206272616e6368206f662074686520747269652e20486176696e6720616c6c206461746120696e207468652073616d65206272616e63682073686f756c642070726576656e7420736c6f77696e6720646f776e206f7468657220717565726965732e20546865206e6578742073657373696f6e206b65797320666f7220612076616c696461746f722e20496e6469636573206f662064697361626c65642076616c696461746f72732e205468652073657420697320636c6561726564207768656e20606f6e5f73657373696f6e5f656e64696e67602072657475726e732061206e657720736574206f66206964656e7469746965732e2054686520717565756564206b65797320666f7220746865206e6578742073657373696f6e2e205768656e20746865206e6578742073657373696f6e20626567696e732c207468657365206b6579732077696c6c206265207573656420746f2064657465726d696e65207468652076616c696461746f7227732073657373696f6e206b6579732e20547275652069662074686520756e6465726c79696e672065636f6e6f6d6963206964656e746974696573206f7220776569676874696e6720626568696e64207468652076616c696461746f727320686173206368616e67656420696e20746865207175657565642076616c696461746f72207365742e2043757272656e7420696e646578206f66207468652073657373696f6e2e205468652063757272656e7420736574206f662076616c696461746f72732e000000000000e49110001000000000000000f4911000050000000000000038971100fc91100000000000000000000c921000020000000000000044454455505f4b45595f505245464958265b75385d000000370000000000000001000000ac0000001c92100059000000759210000d0000002055736564206173206669727374206b657920666f7220604e6578744b6579736020616e6420604b65794f776e65726020746f2070757420616c6c20746865206461746120696e746f207468652073616d65206272616e6368206f662074686520747269652e3a73657373696f6e3a6b65797353657373696f6e204e6578744b6579730000000000249310000d000000000000003493100002000000000000000000000064931000090000000000000000000000ac9310000f00000000000000bc931000010000000000000000000000d49310000700000000000000000000000c9410001000000000000000bc9310000100000000000000000000001c941000080000000000000070726f706f73655f7370656e64000000000000005f5511000500000000000000645511001500000000000000fa9510000b000000000000004b22110023000000289510004b000000739510004d000000c0951000150000003897110000000000c54d11000b000000d04d110008000000f111110019000000d595100025000000d84d11000c00000072656a6563745f70726f706f73616c00000000001d9510000b00000000000000e9cd100016000000de9410003f0000003897110000000000c54d11000b000000d04d110008000000f111110019000000514e110010000000d84d11000c000000617070726f76655f70726f706f73616c5c94100057000000b39410002b0000003897110000000000c54d11000b000000d04d110008000000f111110019000000b712110011000000d84d11000c00000020417070726f766520612070726f706f73616c2e2041742061206c617465722074696d652c207468652070726f706f73616c2077696c6c20626520616c6c6f636174656420746f207468652062656e656669636961727920616e6420746865206f726967696e616c206465706f7369742077696c6c2062652072657475726e65642e2052656a65637420612070726f706f736564207370656e642e20546865206f726967696e616c206465706f7369742077696c6c20626520736c61736865642e70726f706f73616c5f69642050757420666f727761726420612073756767657374696f6e20666f72207370656e64696e672e2041206465706f7369742070726f706f7274696f6e616c20746f207468652076616c756520697320726573657276656420616e6420736c6173686564206966207468652070726f706f73616c2069732072656a65637465642e2049742069732072657475726e6564206f6e6365207468652070726f706f73616c20697320617761726465642e202d204f6e65204442206368616e67652c206f6e6520657874726120444220656e7472792e62656e656669636961727954726561737572790000000000000008d010000d0000000000000000000000ccb710000d000000000000000000000000000000000000000000000000000000000000003897110018971000000000000000000028971000010000000000000001000000000000009acf1000090000000101000000000000ccb710000d000000000000003097100024000000000000000000000000000000000000003897110054971000000000000000000064971000010000000000000000000000000000006c97100009000000000000000000000075971000120000000000000000000000000000000000000000000000000000000000000038971100889710000000000000000000989710000100000000000000010000003700000000000000010000009c000000fd9710002900000050726f706f73616c3c543a3a4163636f756e7449642c2042616c616e63654f663c543e3e3700000000000000010000004f000000de9710001f000000417070726f76616c735665633c50726f706f73616c496e6465783e0037000000000000000100000050000000a09710003e0000002050726f706f73616c20696e646963657320746861742068617665206265656e20617070726f76656420627574206e6f742079657420617761726465642e2050726f706f73616c7320746861742068617665206265656e206d6164652e204e756d626572206f662070726f706f73616c7320746861742068617665206265656e206d6164652e000000000000089910000c00000000000000149910000700000000000000389711001c99100000000000000000002c9910000200000000000000000000003c99100013000000000000007a6511000c000000000000003897110050991000000000000000000060991000010000000000000000000000689910000b00000000000000925111000e0000000000000038971100749910000000000000000000849910000100000000000000000000008c991000040000000000000014991000070000000000000038971100909910000000000000000000a0991000010000000000000050726f706f73616c426f6e645065726d696c6c00370000000000000001000000ad000000609a100055000000b59a10004400000050726f706f73616c426f6e644d696e696d756d00370000000000000001000000990000000e9a1000520000005370656e64506572696f6400370000000000000001000000ae000000ec991000220000004275726e370000000000000001000000af000000a8991000440000002050657263656e74616765206f662073706172652066756e64732028696620616e7929207468617420617265206275726e7420706572207370656e6420706572696f642e20506572696f64206265747765656e2073756363657373697665207370656e64732e204d696e696d756d20616d6f756e74206f662066756e647320746861742073686f756c6420626520706c6163656420696e2061206465706f73697420666f72206d616b696e6720612070726f706f73616c2e204672616374696f6e206f6620612070726f706f73616c27732076616c756520746861742073686f756c6420626520626f6e64656420696e206f7264657220746f20706c616365207468652070726f706f73616c2e20416e2061636365707465642070726f706f73616c2067657473207468657365206261636b2e20412072656a65637465642070726f706f73616c20646f6573206e6f742e4772616e64706146696e616c6974792050656e64696e674368616e67654772616e64706146696e616c697479205374617465496e636f6e73697374656e74207374617465202d20636f756c646e277420736574746c6520696d62616c616e636520666f722066756e6473207370656e7420627920747265617375727953657373696f6e205175657565644b65797300590000000800000004000000b0000000b10000000000000000000000b20000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000590000000800000004000000b0000000b10000000000000000000000b20000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000590000000800000004000000b3000000b10000000000000000000000b40000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000590000000800000004000000b3000000b10000000000000000000000b400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004772616e64706146696e616c697479204e657874466f72636564636f6465206973206e6f7420666f756e647072697374696e6520636f6465206973206e6f7420666f756e647468657265206973206e6f7420656e6f7567682067617320666f722073746f72696e672074686520636f646553657373696f6e204b65794f776e6572000000f0a0100048000000a10a00000e000000f0a01000480000009b0a00000a00000080a0100019000000a0a01000430000003401000009000000000000000000000000000000617474656d707420746f20646976696465206279207a65726f000000000000002f686f6d652f616e6472652f576f726b62656e63682f706172697479746563682f7375627374726174652f636f72652f70687261676d656e2f7372632f6c69622e7273000000000000000000000000002f72757374632f316464313838343839313633366430656235313135376431333732333030373662636632303632372f7372632f6c6962636f72652f736c6963652f6d6f642e72733897110000000000391411000200000060a110007c000000dca11000490000007900000006000000657865632e7072656661625f6d6f64756c652e696e697469616c2063616e27742062652067726561746572207468616e20657865632e7072656661625f6d6f64756c652e6d6178696d756d3b0a09090909090974687573204d656d6f72793a3a6e6577206d757374206e6f74206661696c3b0a0909090909097165642f686f6d652f616e6472652f576f726b62656e63682f706172697479746563682f7375627374726174652f73726d6c2f636f6e7472616374732f7372632f7761736d2f6d6f642e72736e6f206173736f6369617465642076616c696461746f7220494420666f72206163636f756e742e72656769737465726564206475706c6963617465206b65791c831000430000007f0000000100000050726f706f73657227732062616c616e636520746f6f206c6f774e6f2070726f706f73616c206174207468617420696e64657866696e616c6e756d417574686f727368697020417574686f7237000000000000000100000038000000387d110028000000e8a210003f000000bf000000010000002f686f6d652f616e6472652f576f726b62656e63682f706172697479746563682f7375627374726174652f73726d6c2f626162652f7372632f6c69622e727300e8a210003f000000bf0000000100000073657269616c697a656420617267732073686f756c642062652070726f7669646564206279207468652072756e74696d653b0a090909636f72726563746c792073657269616c697a656420646174612073686f756c6420626520646573657269616c697a61626c653b0a090909716564387d110028000000607d110050000000370100000900000065706f636820696e64696365732077696c6c206e6576657220726561636820325e3634206265666f726520746865206465617468206f662074686520756e6976657273653b207165640000000000000038a410000a0000000000000044a410000100000000000000000000005ca4100001000000000000007365745f756e636c65730000000000007da410000a0000000000000087a410000e00000064a41000190000002050726f76696465206120736574206f6620756e636c65732e6e65775f756e636c65735665633c543a3a4865616465723e417574686f72736869700000000000a8a51000060000000000000000000000aea510003a0000000000000000000000000000000000000000000000000000000000000038971100e8a510000000000000000000f8a510000100000000000000010000000000000000a610000600000000000000000000000b4e11000c000000000000000000000000000000000000000000000000000000000000003897110008a61000000000000000000018a610000100000000000000000000000000000020a610000c0000000000000000000000f74311000400000000000000000000000000000000000000000000000000000000000000389711002ca6100000000000000000003ca61000010000000000000001000000556e636c65735665633c556e636c65456e7472794974656d3c543a3a426c6f636b4e756d6265722c20543a3a486173682c20543a3a4163636f756e7449643e3e370000000000000001000000500000008ca6100007000000417574686f7200003700000000000000010000004f00000073a6100019000000446964536574556e636c65733700000000000000010000004f00000044a610002f000000205768657468657220756e636c6573207765726520616c72656164792073657420696e207468697320626c6f636b2e20417574686f72206f662063757272656e7420626c6f636b2e20556e636c6573417574686f727368697020556e636c6573556e636c657320616c72656164792073657420696e20626c6f636b2e756e636c6520616c726561647920696e636c75646564756e636c652069732067656e65736973756e636c6520697320746f6f206869676820696e20636861696e756e636c6520706172656e74206e6f7420696e20636861696e756e636c65206e6f7420726563656e7420656e6f75676820746f20626520696e636c756465644261626500000000005caa10000a000000000000000000000076f91000030000000000000000000000000000000000000000000000000000000000000038971100e4aa1000000000000000000068aa10000100000000000000010000000000000070aa10000b00000000000000000000007baa1000270000000000000000000000000000000000000000000000000000000000000038971100a4aa10000000000000000000b4aa100001000000000000000100000000000000bcaa10000b000000000000000000000076f91000030000000000000000000000000000000000000000000000000000000000000038971100e4aa10000000000000000000c8aa100002000000000000000100000000000000d8aa10000b000000000000000000000076f91000030000000000000000000000000000000000000000000000000000000000000038971100e4aa10000000000000000000f4aa100001000000000000000100000000000000fcaa10000a000000000000000000000006ab100008000000000000000000000000000000000000000000000000000000000000003897110070ab1000000000000000000010ab10000a00000000000000010000000000000060ab10000e000000000000000000000006ab100008000000000000000000000000000000000000000000000000000000000000003897110070ab1000000000000000000080ab10000100000000000000010000000000000088ab10000c00000000000000000000007634110003000000000000000000000000000000000000000000000000000000000000003897110094ab10000000000000000000a4ab100009000000000000000100000000000000ecab1000110000000101000000000000763411000300000000000000fdab10000d00000000000000000000000000000000000000389711000cac1000000000000000000038971100000000000000000001000000000000001cac10000b000000000000000000000027ac100008000000000000000000000000000000000000000000000000000000000000003897110030ac1000000000000000000040ac100002000000000000000000000045706f6368496e64657800008bb0100015000000417574686f7269746965735665633c28417574686f7269747949642c2042616265417574686f72697479576569676874293e00003700000000000000010000005000000070b010001b00000047656e65736973536c6f74000eb010003e0000004cb010002400000043757272656e74536c6f7400370000000000000001000000ab000000f9af10001500000052616e646f6d6e6573735b75383b2033325d000033ae10002e000000389711000000000061ae10000b00000038971100000000006cae100041000000adae10003e000000ebae10004500000030af10004500000075af100041000000b6af1000430000004e65787452616e646f6d6e6573730000370000000000000001000000b50000001cae1000170000005365676d656e74496e6465783700000000000000010000009c000000d7ac10001f0000003897110000000000f6ac10003d00000033ad10004000000073ad100025000000389711000000000098ad10003b000000d3ad10004200000015ae100007000000556e646572436f6e737472756374696f6e5665633c5b75383b2033325d3e000037000000000000000100000050000000496e697469616c697a65644d61796265567266003700000000000000010000004f00000050ac10004000000090ac1000470000002054656d706f726172792076616c75652028636c656172656420617420626c6f636b2066696e616c697a6174696f6e292077686963682069732060536f6d6560206966207065722d626c6f636b20696e697469616c697a6174696f6e2068617320616c7265616479206265656e2063616c6c656420666f722063757272656e7420626c6f636b2e2052616e646f6d6e65737320756e64657220636f6e737472756374696f6e2e205765206d616b6520612074726164656f6666206265747765656e2073746f7261676520616363657373657320616e64206c697374206c656e6774682e2057652073746f72652074686520756e6465722d636f6e737472756374696f6e2072616e646f6d6e65737320696e207365676d656e7473206f6620757020746f2060554e4445525f434f4e535452554354494f4e5f5345474d454e545f4c454e475448602e204f6e63652061207365676d656e7420726561636865732074686973206c656e6774682c20776520626567696e20746865206e657874206f6e652e20576520726573657420616c6c207365676d656e747320616e642072657475726e20746f206030602061742074686520626567696e6e696e67206f662065766572792065706f63682e204e6578742065706f63682072616e646f6d6e6573732e205468652065706f63682072616e646f6d6e65737320666f7220746865202a63757272656e742a2065706f63682e20232053656375726974792054686973204d555354204e4f54206265207573656420666f722067616d626c696e672c2061732069742063616e20626520696e666c75656e6365642062792061206d616c6963696f75732076616c696461746f7220696e207468652073686f7274207465726d2e204974204d4159206265207573656420696e206d616e792063727970746f677261706869632070726f746f636f6c732c20686f77657665722c20736f206c6f6e67206173206f6e652072656d656d626572732074686174207468697320286c696b652065766572797468696e6720656c7365206f6e2d636861696e29206974206973207075626c69632e20466f72206578616d706c652c2069742063616e20626520757365642077686572652061206e756d626572206973206e656564656420746861742063616e6e6f742068617665206265656e2063686f73656e20627920616e206164766572736172792c20666f7220707572706f7365732073756368206173207075626c69632d636f696e207a65726f2d6b6e6f776c656467652070726f6f66732e2043757272656e7420736c6f74206e756d6265722e2054686520736c6f74206174207768696368207468652066697273742065706f63682061637475616c6c7920737461727465642e2054686973206973203020756e74696c2074686520666972737420626c6f636b206f662074686520636861696e2e2043757272656e742065706f636820617574686f7269746965732e2043757272656e742065706f636820696e6465782e0000000010b110000d0000000000000076f9100003000000000000003897110020b11000000000000000000030b1100002000000000000000000000040b110001100000000000000a3e0100009000000000000003897110054b11000000000000000000064b11000050000000000000045706f63684475726174696f6e000000370000000000000001000000b6000000bcb2100043000000ffb210003f0000004578706563746564426c6f636b54696d65000000370000000000000001000000b70000008cb1100041000000cdb110004400000011b210004100000052b210004200000094b210002800000020546865206578706563746564206176657261676520626c6f636b2074696d6520617420776869636820424142452073686f756c64206265206372656174696e6720626c6f636b732e2053696e636520424142452069732070726f626162696c6973746963206974206973206e6f74207472697669616c20746f20666967757265206f7574207768617420746865206578706563746564206176657261676520626c6f636b2074696d652073686f756c64206265206261736564206f6e2074686520736c6f74206475726174696f6e20616e642074686520736563757269747920706172616d657465722060636020287768657265206031202d20636020726570726573656e7473207468652070726f626162696c697479206f66206120736c6f74206265696e6720656d707479292e20546865206e756d626572206f66202a2a736c6f74732a2a207468617420616e2065706f63682074616b65732e20576520636f75706c652073657373696f6e7320746f2065706f6368732c20692e652e2077652073746172742061206e65772073657373696f6e206f6e636520746865206e65772065706f636820626567696e732e756e636c6573303074696d657374616d702073657420696e20626c6f636b20646f65736e2774206d6174636820736c6f7420696e207365616c4e6f206f74686572206572726f72732061726520616363657074656420616674657220616e2068617264206572726f7221496e686572656e7420776974682073616d65206964656e74696669657220616c726561647920657869737473215468657265206973206f6e6c79206f6e6520666174616c206572726f723b20716564005900000008000000040000009d0000003a65787472696e7369635f696e64657800000000e4421100080000000000000020b5100004000000000000000000000040b5100002000000000000000000000050b51000050000000000000058b5100005000000000000000000000080b5100002000000000000000000000090b51000080000000000000048ea100001000000000000000000000098b51000010000000000000000000000a0b510000b0000000000000048ea1000010000000000000000000000acb51000010000000000000000000000664311000800000000000000b4b51000020000000000000000000000c4b51000010000000000000000000000ccb510000e00000000000000b4b51000020000000000000000000000dcb510000100000000000000d043110009000000ccb710000d000000d9431100040000005eb710000b00000069b7100053000000bcb7100010000000566f746564000000d043110009000000d943110004000000f7431100040000005eb710000b0000005eb710000b000000d6b610004200000018b7100046000000417070726f766564a5b6100031000000446973617070726f7665640070b6100035000000d943110004000000f7431100040000002fb61000410000004d656d62657245786563757465640000e4b510004b00000020412073696e676c65206d656d6265722064696420736f6d6520616374696f6e3b2060626f6f6c6020697320747275652069662072657475726e656420776974686f7574206572726f722e2041206d6f74696f6e207761732065786563757465643b2060626f6f6c6020697320747275652069662072657475726e656420776974686f7574206572726f722e2041206d6f74696f6e20776173206e6f7420617070726f76656420627920746865207265717569726564207468726573686f6c642e2041206d6f74696f6e2077617320617070726f76656420627920746865207265717569726564207468726573686f6c642e2041206d6f74696f6e2028676976656e20686173682920686173206265656e20766f746564206f6e20627920676976656e206163636f756e742c206c656176696e6720612074616c6c79202879657320766f74657320616e64206e6f20766f74657320676976656e20726573706563746976656c7920617320604d656d626572436f756e7460292e4d656d626572436f756e742041206d6f74696f6e2028676976656e20686173682920686173206265656e2070726f706f7365642028627920676976656e206163636f756e742920776974682061207468726573686f6c642028676976656e20604d656d626572436f756e7460292e50726f706f73616c496e64657853797374656d204e756d62657253797374656d2045787472696e73696373526f6f74496e7374616e636531436f6c6c656374697665204d656d62657273496e7374616e636532436f6c6c656374697665204d656d6265727353797374656d2044696765737453797374656d20426c6f636b4861736853797374656d204163636f756e744e6f6e6365000000387d1100280000007cb8100041000000e9000000010000002f686f6d652f616e6472652f576f726b62656e63682f706172697479746563682f7375627374726174652f73726d6c2f73797374656d2f7372632f6c69622e7273000000387d110028000000d8b810004500000083000000010000002f686f6d652f616e6472652f576f726b62656e63682f706172697479746563682f7375627374726174652f73726d6c2f636f6c6c6563746976652f7372632f6c69622e727353797374656d20506172656e744861736853797374656d2052616e646f6d4d6174657269616c0080b9100048000000a10a00000e00000053797374656d204576656e747353797374656d204576656e74546f70696373000000000000000000000000002f72757374632f316464313838343839313633366430656235313135376431333732333030373662636632303632372f7372632f6c6962636f72652f736c6963652f6d6f642e727300000000d0ba10000a0000000000000038971100000000000000000000000000dcba1000010000000000000000000000e4ba10000600000000000000ecba100001000000000000000000000004bb10000100000000000000000000000cbb10000e000000000000001cbb100001000000000000000000000034bb10000100000000000000000000003cbb1000080000000000000044bb10000100000000000000000000005cbb100001000000000000000000000064bb10000b0000000000000070bb100001000000000000000000000088bb100001000000000000000000000090bb10000c000000000000009cbb1000010000000000000000000000b4bb1000010000000000000066696c6c5f626c6f636b00008bbc10004800000072656d61726b00000000000084bc10000700000000000000e7ea10000700000069bc10001b0000007365745f686561705f706167657300000000000064bc1000050000000000000076f910000300000025bc10003f0000007365745f636f646500000000fc2011000300000000000000e7ea10000700000013bc1000120000007365745f73746f72616765000000000001bc1000050000000000000006bc10000d000000e6bb10001b0000006b696c6c5f73746f7261676500000000dabb10000400000000000000debb100008000000bcbb10001e000000204b696c6c20736f6d65206974656d732066726f6d2073746f726167652e6b6579735665633c4b65793e2053657420736f6d65206974656d73206f662073746f726167652e6974656d735665633c4b657956616c75653e2053657420746865206e657720636f64652e2053657420746865206e756d626572206f6620706167657320696e2074686520576562417373656d626c7920656e7669726f6e6d656e74277320686561702e7061676573204d616b6520736f6d65206f6e2d636861696e2072656d61726b2e5f72656d61726b20412062696720646973706174636820746861742077696c6c20646973616c6c6f7720616e79206f74686572207472616e73616374696f6e20746f20626520696e636c756465642e53797374656d0000000000000004c210000c00000001010000000000000b4e11000c0000000000000010c21000080000000000000000000000000000000000000038971100e8d21000000000000000000018c210000100000000000000010000000000000020c210000e0000000000000000000000763411000300000000000000000000000000000000000000000000000000000000000000389711006cc21000000000000000000030c210000100000000000000000000000000000038c210001300000000000000000000004bc210000600000000000000000000000000000000000000000000000000000000000000389711006cc21000000000000000000054c21000010000000000000000000000000000005cc21000100000000000000000000000763411000300000000000000000000000000000000000000000000000000000000000000389711006cc2100000000000000000007cc210000100000000000000000000000000000084c2100014000000000000000000000098c21000100000000000000000000000000000000000000000000000000000000000000038971100a8c210000000000000000000b8c2100002000000000000000100000000000000c8c21000090000000101000000000000925111000e000000000000007c4f110007000000000000000000000000000000000000003897110078c310000000000000000000d4c2100001000000000000000100000000000000dcc210000d0000000101000000000000763411000300000000000000e7ea1000070000000000000000000000000000000000000038971100ecc210000000000000000000fcc210000100000000000000010000000000000004c310000e000000000000000000000012c3100012000000000000000000000000000000000000000000000000000000000000003897110024c31000000000000000000034c310000200000000000000010000000000000044c31000060000000000000000000000925111000e0000000000000000000000000000000000000000000000000000000000000038971100e8d2100000000000000000004cc310000100000000000000010000000000000054c310000a00000000000000000000007c4f110007000000000000000000000000000000000000000000000000000000000000003897110078c31000000000000000000060c310000100000000000000010000000000000068c310000e00000000000000000000007c4f110007000000000000000000000000000000000000000000000000000000000000003897110078c31000000000000000000088c310000100000000000000010000000000000090c3100006000000000000000000000096c310000b0000000000000000000000000000000000000000000000000000000000000038971100a4c310000000000000000000b4c3100001000000000000000100000000000000bcc31000060000000000000000000000c2c31000230000000000000000000000000000000000000000000000000000000000000038971100e8c310000000000000000000f8c310000100000000000000010000000000000000c410000a00000000000000000000000ac410000a0000000000000000000000000000000000000000000000000000000000000038971100e8d21000000000000000000014c41000010000000000000001000000000000001cc410000b000000020101000000000027c4100002000000000000007c4f1100070000000000000029c41000210000000000000038971100f8d2100000000000000000004cc410000d00000000000000010000004163636f756e744e6f6e6365543a3a496e646578f9ca10001f00000045787472696e736963436f756e740000cbca10002e000000416c6c45787472696e7369637357656967687457656967687400000086ca100045000000416c6c45787472696e736963734c656e3700000000000000010000004f00000036ca1000500000004e6578745765696768744d756c7469706c6965725765696768744d756c7469706c696572370000000000000001000000ab000000c2c91000590000001bca10001b000000426c6f636b486173680000009cc910002600000045787472696e73696344617461000000370000000000000001000000510000004dc910004f00000052616e646f6d4d6174657269616c2869382c205665633c543a3a486173683e29370000000000000001000000b800000090c8100069000000f9c81000540000004e756d62657200004ec8100042000000506172656e7448617368000032c810001c00000045787472696e73696373526f6f740000370000000000000001000000b9000000edc71000450000004469676573744469676573744f663c543e00000037000000000000000100000050000000b1c710003c0000004576656e74735665633c4576656e745265636f72643c543a3a4576656e742c20543a3a486173683e3e000000370000000000000001000000ba00000089c71000280000004576656e74436f756e744576656e74496e6465785bc710002e0000004576656e74546f7069637328295665633c28543a3a426c6f636b4e756d6265722c204576656e74496e646578293e0000b4c4100049000000fdc4100025000000389711000000000022c510004b0000006dc510002a000000389711000000000097c5100054000000ebc51000510000003cc6100039000000389711000000000075c6100053000000c8c61000530000001bc7100040000000204d617070696e67206265747765656e206120746f7069632028726570726573656e74656420627920543a3a486173682920616e64206120766563746f72206f6620696e6465786573206f66206576656e747320696e2074686520603c4576656e74733c543e3e60206c6973742e20546865206669727374206b657920736572766573206e6f20707572706f73652e2054686973206669656c64206973206465636c6172656420617320646f75626c655f6d6170206a75737420666f7220636f6e76656e69656e6365206f66207573696e67206072656d6f76655f707265666978602e20416c6c20746f70696320766563746f727320686176652064657465726d696e69737469632073746f72616765206c6f636174696f6e7320646570656e64696e67206f6e2074686520746f7069632e205468697320616c6c6f7773206c696768742d636c69656e747320746f206c6576657261676520746865206368616e67657320747269652073746f7261676520747261636b696e67206d656368616e69736d20616e6420696e2063617365206f66206368616e67657320666574636820746865206c697374206f66206576656e7473206f6620696e7465726573742e205468652076616c756520686173207468652074797065206028543a3a426c6f636b4e756d6265722c204576656e74496e646578296020626563617573652069662077652075736564206f6e6c79206a7573742074686520604576656e74496e64657860207468656e20696e20636173652069662074686520746f70696320686173207468652073616d6520636f6e74656e7473206f6e20746865206e65787420626c6f636b206e6f206e6f74696669636174696f6e2077696c6c20626520747269676765726564207468757320746865206576656e74206d69676874206265206c6f73742e20546865206e756d626572206f66206576656e747320696e2074686520604576656e74733c543e60206c6973742e204576656e7473206465706f736974656420666f72207468652063757272656e7420626c6f636b2e20446967657374206f66207468652063757272656e7420626c6f636b2c20616c736f2070617274206f662074686520626c6f636b206865616465722e2045787472696e7369637320726f6f74206f66207468652063757272656e7420626c6f636b2c20616c736f2070617274206f662074686520626c6f636b206865616465722e2048617368206f66207468652070726576696f757320626c6f636b2e205468652063757272656e7420626c6f636b206e756d626572206265696e672070726f6365737365642e205365742062792060657865637574655f626c6f636b602e20536572696573206f6620626c6f636b20686561646572732066726f6d20746865206c61737420383120626c6f636b73207468617420616374732061732072616e646f6d2073656564206d6174657269616c2e205468697320697320617272616e67656420617320612072696e6720627566666572207769746820746865206069386020707265666978206265696e672074686520696e64657820696e746f20746865206056656360206f6620746865206f6c6465737420686173682e2045787472696e73696373206461746120666f72207468652063757272656e7420626c6f636b20286d61707320616e2065787472696e736963277320696e64657820746f206974732064617461292e204d6170206f6620626c6f636b206e756d6265727320746f20626c6f636b206861736865732e20546865206e65787420776569676874206d756c7469706c6965722e20546869732073686f756c6420626520757064617465642061742074686520656e64206f66206561636820626c6f636b206261736564206f6e207468652073617475726174696f6e206c6576656c2028776569676874292e20546f74616c206c656e6774682028696e2062797465732920666f7220616c6c2065787472696e736963732070757420746f6765746865722c20666f72207468652063757272656e7420626c6f636b2e20546f74616c2077656967687420666f7220616c6c2065787472696e736963732070757420746f6765746865722c20666f72207468652063757272656e7420626c6f636b2e20546f74616c2065787472696e7369637320636f756e7420666f72207468652063757272656e7420626c6f636b2e2045787472696e73696373206e6f6e636520666f72206163636f756e74732e496e7374616e636531436f6c6c6563746976652050726f706f73616c73496e7374616e636531436f6c6c65637469766520566f74696e67496e7374616e636532436f6c6c6563746976652050726f706f73616c73496e7374616e636532436f6c6c65637469766520566f74696e6700000000000038cc10000b0000000000000044cc10000100000000000000000000005ccc10000400000000000000000000007ccc1000070000000000000084cc10000100000000000000000000009ccc1000030000000000000000000000b84811000700000000000000b4cc1000020000000000000000000000e4cc100004000000000000000000000070491100040000000000000004cd10000300000000000000000000004ccd100004000000000000007365745f6d656d6265727300000000007ccf10000b00000000000000255c110011000000fbce1000540000004fcf100017000000389711000000000066cf10001600000065786563757465000000000058531100080000000000000075ce10001e00000093ce10003d0000003897110000000000d0ce10002b0000000000000058ce1000090000000000000061ce1000140000000000000058531100080000000000000075ce10001e000000c54d11000b00000006ce1000240000002ace10002e000000d84d11000c000000000000005853110008000000000000007c4f11000700000000000000e4cd10000500000000000000e9cd10001600000000000000ffcd10000700000000000000f743110004000000c54d11000b0000006ccd1000230000008fcd100055000000d84d11000c000000202d20426f756e6465642073746f72616765207265616420616e64207772697465732e202d2057696c6c20626520736c696768746c792068656176696572206966207468652070726f706f73616c20697320617070726f766564202f20646973617070726f7665642061667465722074686520766f74652e696e646578436f6d706163743c50726f706f73616c496e6465783e617070726f7665202d20426f756e6465642073746f7261676520726561647320616e64207772697465732e202d20417267756d656e7420607468726573686f6c6460206861732062656172696e67206f6e207765696768742e7468726573686f6c64436f6d706163743c4d656d626572436f756e743e426f783c3c542061732054726169743c493e3e3a3a50726f706f73616c3e20446973706174636820612070726f706f73616c2066726f6d2061206d656d626572207573696e672074686520604d656d62657260206f726967696e2e204f726967696e206d7573742062652061206d656d626572206f662074686520636f6c6c6563746976652e205365742074686520636f6c6c6563746976652773206d656d62657273686970206d616e75616c6c7920746f20606e65775f6d656d62657273602e204265206e69636520746f2074686520636861696e20616e642070726f76696465206974207072652d736f727465642e20526571756972657320726f6f74206f726967696e2e6e65775f6d656d62657273496e7374616e636531436f6c6c65637469766550726f706f73616c735665633c543a3a486173683e00e8d010002400000050726f706f73616c4f663c542061732054726169743c493e3e3a3a50726f706f73616c00b5d0100033000000566f74696e67566f7465733c543a3a4163636f756e7449643e00000088d010002d00000050726f706f73616c436f756e7400000076d010001200000028d010004e000000205468652063757272656e74206d656d62657273206f662074686520636f6c6c6563746976652e20546869732069732073746f72656420736f7274656420286a7573742062792076616c7565292e2050726f706f73616c7320736f206661722e20566f746573206f6e206120676976656e2070726f706f73616c2c206966206974206973206f6e676f696e672e2041637475616c2070726f706f73616c20666f72206120676976656e20686173682c20696620697427732063757272656e742e2054686520686173686573206f6620746865206163746976652070726f706f73616c732e496e7374616e636532436f6c6c65637469766500000000009acf1000090000000000000000000000a3cf10000c0000000000000000000000000000000000000000000000000000000000000038971100f8d210000000000000000000b0cf100001000000000000000100000000000000b8cf10000a00000001010000000000007c4f11000700000000000000c2cf1000190000000000000000000000000000000000000038971100d8d210000000000000000000dccf100001000000000000000000000000000000e4cf10000600000001010000000000007c4f11000700000000000000eacf1000130000000000000000000000000000000000000038971100d8d21000000000000000000000d010000100000000000000000000000000000008d010000d000000000000000000000076341100030000000000000000000000000000000000000000000000000000000000000038971100e8d21000000000000000000018d0100001000000000000000100000000000000ace61000070000000000000000000000255c1100110000000000000000000000000000000000000000000000000000000000000038971100f8d21000000000000000000020d010000100000000000000010000003700000000000000010000004f0000003700000000000000010000009c000000370000000000000001000000500000007cb8100041000000e9000000010000003a6865617070616765733a636f646500d8b8100045000000830000000100000070726f706f736572206e6f742061206d656d6265726475706c69636174652070726f706f73616c73206e6f7420616c6c6f776564496e7374616e636531436f6c6c6563746976652050726f706f73616c4f66496e7374616e636531436f6c6c6563746976652050726f706f73616c436f756e7470726f706f73616c206d757374206578697374766f746572206e6f742061206d656d6265726d69736d61746368656420696e6465786475706c696361746520766f74652069676e6f726564496e7374616e636532436f6c6c6563746976652050726f706f73616c4f66496e7374616e636532436f6c6c6563746976652050726f706f73616c436f756e740000000000000064d410000f0000000000000074d4100002000000000000000000000084d4100004000000000000004e65774163636f756e74496e64657800d0431100090000001fd510000c000000a4d41000220000003897110000000000c6d410004100000007d51000180000002041206e6577206163636f756e7420696e646578207761732061737369676e65642e2054686973206576656e74206973206e6f7420747269676765726564207768656e20616e206578697374696e6720696e64657820697320726561737369676e656420746f20616e6f7468657220604163636f756e744964602e4163636f756e74496e6465780050d510001900000070d5100048000000230100000e000000000000000000000000000000617474656d707420746f20646976696465206279207a65726f000000000000002f686f6d652f616e6472652f576f726b62656e63682f706172697479746563682f7375627374726174652f636f72652f73722d7072696d6974697665732f7372632f6c69622e7273d0d510000e000000ded5100048000000220100004a0000006578706c696369742070616e69632f686f6d652f616e6472652f576f726b62656e63682f706172697479746563682f7375627374726174652f636f72652f73722d7072696d6974697665732f7372632f6c69622e72730000d0d510000e000000ded5100048000000210100004a00000058d610002b00000083d6100044000000ef0000000400000054696d657374616d70206d7573742062652075706461746564206f6e636520696e2074686520626c6f636b2f686f6d652f616e6472652f576f726b62656e63682f706172697479746563682f7375627374726174652f73726d6c2f74696d657374616d702f7372632f6c69622e727300e0d610003000000083d6100044000000e30000000400000054696d657374616d70206d7573742062652075706461746564206f6e6c79206f6e636520696e2074686520626c6f636b28d710004e00000083d6100044000000e40000000400000054696d657374616d70206d75737420696e6372656d656e74206279206174206c65617374203c4d696e696d756d506572696f643e206265747765656e2073657175656e7469616c20626c6f636b7300000000000054d810000b000000000000003897110000000000000000000000000060d8100001000000000000000000000068d810000d000000000000003897110000000000000000000000000078d8100001000000000000000000000080d810000e000000000000003897110000000000000000000000000090d8100001000000000000000000000098d810000c0000000000000038971100000000000000000000000000a4d81000010000000000000000000000acd810000500000000000000b4d81000010000000000000000000000bcd8100001000000000000004d656d626572416464656400c5d91000390000004d656d62657252656d6f7665640000008ad910003b0000004d656d6265727353776170706564000053d91000370000004d656d6265727352657365740dd910004600000044756d6d79000000e0d810002d000000c4d810001c000000205068616e746f6d206d656d6265722c206e6576657220757365642e727374643a3a6d61726b65723a3a5068616e746f6d446174613c284163636f756e7449642c204576656e74293e20546865206d656d62657273686970207761732072657365743b2073656520746865207472616e73616374696f6e20666f722077686f20746865206e6577207365742069732e2054776f206d656d62657273207765726520737761707065643b2073656520746865207472616e73616374696f6e20666f722077686f2e2054686520676976656e206d656d626572207761732072656d6f7665643b2073656520746865207472616e73616374696f6e20666f722077686f2e2054686520676976656e206d656d626572207761732061646465643b2073656520746865207472616e73616374696f6e20666f722077686f2e54696d657374616d70204e6f77496e646963657320456e756d53657400005900000008000000040000009d000000387d11002800000044da1000420000004a000000010000002f686f6d652f616e6472652f576f726b62656e63682f706172697479746563682f7375627374726174652f73726d6c2f696e64696365732f7372632f6c69622e72730000387d110028000000a0da1000450000005c000000010000002f686f6d652f616e6472652f576f726b62656e63682f706172697479746563682f7375627374726174652f73726d6c2f6d656d626572736869702f7372632f6c69622e727300000044da1000420000004a0000000100000054696d657374616d7020746f6f2066617220696e2066757475726520746f206163636570744765747320616e64206465636f6465732074696d657374616d7020696e686572656e742064617461496e646963657300000000fcdb10000b000000000000000000000007dc10000f000000000000000000000000000000000000000000000000000000000000003897110018dc1000000000000000000028dc10000100000000000000010000000000000030dc100007000000010100000000000007dc10000f00000000000000255c1100110000000000000000000000000000000000000038971100b4e61000000000000000000038dc10000100000000000000010000004e657874456e756d536574543a3a4163636f756e74496e64657800003700000000000000010000009c00000056dc10001f000000456e756d5365740040dc1000160000002054686520656e756d65726174696f6e20736574732e20546865206e657874206672656520656e756d65726174696f6e207365742e496e6469636573204e657874456e756d536574e9dd10001c000000b8dc1000440000009e00000003000000c5dd100024000000b8dc100044000000a7000000030000002f686f6d652f616e6472652f576f726b62656e63682f706172697479746563682f7375627374726174652f73726d6c2f6578656375746976652f7372632f6c69622e727393dd100032000000b8dc10004400000001010000030000006cdd100027000000b8dc100044000000090100000400000044dd100028000000b8dc1000440000000f0100000300000053746f7261676520726f6f74206d757374206d6174636820746861742063616c63756c617465642e446967657374206974656d206d757374206d6174636820746861742063616c63756c617465642e4e756d626572206f6620646967657374206974656d73206d757374206d6174636820746861742063616c63756c617465642e5472616e73616374696f6e207472696520726f6f74206d7573742062652076616c69642e506172656e7420686173682073686f756c642062652076616c69642e0000000000000034de1000030000000000000038de100001000000000000000000000050de100009000000000000007365740000000000d2df10000300000000000000d5df10001200000098de1000160000003897110000000000aede10005600000004df10003600000038971100000000003adf1000510000008bdf10001100000038971100000000009cdf10003600000020536574207468652063757272656e742074696d652e20546869732063616c6c2073686f756c6420626520696e766f6b65642065786163746c79206f6e63652070657220626c6f636b2e2049742077696c6c2070616e6963206174207468652066696e616c697a6174696f6e2070686173652c20696620746869732063616c6c206861736e2774206265656e20696e766f6b656420627920746861742074696d652e205468652074696d657374616d702073686f756c642062652067726561746572207468616e207468652070726576696f7573206f6e652062792074686520616d6f756e742073706563696669656420627920604d696e696d756d506572696f64602e20546865206469737061746368206f726967696e20666f7220746869732063616c6c206d7573742062652060496e686572656e74602e6e6f77436f6d706163743c543a3a4d6f6d656e743e54696d657374616d7000000000a0e01000030000000000000000000000a3e01000090000000000000000000000000000000000000000000000000000000000000038971100ace010000000000000000000bce0100001000000000000000100000000000000c4e01000090000000000000000000000f7431100040000000000000000000000000000000000000000000000000000000000000038971100d0e010000000000000000000e0e010000100000000000000010000004e6f77543a3a4d6f6d656e74370000000000000001000000ab00000015e11000240000004469645570646174650000003700000000000000010000004f000000e8e010002d00000020446964207468652074696d657374616d7020676574207570646174656420696e207468697320626c6f636b3f2043757272656e742074696d6520666f72207468652063757272656e7420626c6f636b2e0000000000000074e110000d00000000000000a3e0100009000000000000003897110084e11000000000000000000094e1100004000000000000004d696e696d756d506572696f64000000370000000000000001000000bb000000b4e110005a0000000ee210005a00000068e2100059000000c1e210001c00000020546865206d696e696d756d20706572696f64206265747765656e20626c6f636b732e204265776172652074686174207468697320697320646966666572656e7420746f20746865202a65787065637465642a20706572696f6420746861742074686520626c6f636b2070726f64756374696f6e206170706172617475732070726f76696465732e20596f75722063686f73656e20636f6e73656e7375732073797374656d2077696c6c2067656e6572616c6c7920776f726b2077697468207468697320746f2064657465726d696e6520612073656e7369626c6520626c6f636b2074696d652e20652e672e20466f7220417572612c2069742077696c6c20626520646f75626c65207468697320706572696f64206f6e2064656661756c742073657474696e67732e0000000000000090e310000a000000000000009ce31000010000000000000000000000b4e31000030000000000000000000000cce310000d000000000000009ce31000010000000000000000000000dce31000030000000000000000000000f4e310000b0000000000000000e4100002000000000000000000000030e4100003000000000000000000000048e410000d0000000000000058e4100001000000000000000000000070e4100004000000000000006164645f6d656d6265720000000000005712110003000000000000000b4e11000c000000f2e510001f000000389711000000000011e610002d00000072656d6f76655f6d656d6265720000009ee51000240000003897110000000000c2e5100030000000737761705f6d656d626572000000000095e5100006000000000000000b4e11000c000000000000009be5100003000000000000000b4e11000c00000037e5100030000000389711000000000067e510002e00000072657365745f6d656d626572730000000000000030e510000700000000000000255c11001100000090e4100056000000e6e410001b000000389711000000000001e510002f000000204368616e676520746865206d656d6265727368697020746f2061206e6577207365742c20646973726567617264696e6720746865206578697374696e67206d656d626572736869702e204265206e69636520616e64207061737320606d656d6265727360207072652d736f727465642e204d6179206f6e6c792062652063616c6c65642066726f6d206052657365744f726967696e60206f7220726f6f742e6d656d626572732053776170206f7574206f6e65206d656d626572206072656d6f76656020666f7220616e6f746865722060616464602e204d6179206f6e6c792062652063616c6c65642066726f6d2060537761704f726967696e60206f7220726f6f742e72656d6f76656164642052656d6f76652061206d656d626572206077686f602066726f6d20746865207365742e204d6179206f6e6c792062652063616c6c65642066726f6d206052656d6f76654f726967696e60206f7220726f6f742e204164642061206d656d626572206077686f6020746f20746865207365742e204d6179206f6e6c792062652063616c6c65642066726f6d20604164644f726967696e60206f7220726f6f742e496e7374616e6365314d656d6265727368697000000000000000ace61000070000000000000000000000255c1100110000000000000000000000000000000000000000000000000000000000000038971100b4e610000000000000000000c4e610000100000000000000010000004d656d626572730037000000000000000100000050000000cce6100032000000205468652063757272656e74206d656d626572736869702c2073746f72656420617320616e206f726465726564205665632e000080e7100048000000b10100002300000080e7100048000000b20100002300000030e7100049000000870200001d0000002f72757374632f316464313838343839313633366430656235313135376431333732333030373662636632303632372f7372632f6c6962636f72652f736c6963652f736f72742e7273000000000000002f72757374632f316464313838343839313633366430656235313135376431333732333030373662636632303632372f7372632f6c6962636f72652f736c6963652f6d6f642e727330e71000490000009d0000003a00000030e7100049000000a400000030000000a0da1000450000005c00000001000000496e7374616e6365314d656d62657273686970204d656d62657273616c72656164792061206d656d626572626164206f726967696e6e6f742061206d656d62657200000080e7100048000000a10a00000e00000054e810001c00000056617269616e74206973206e6576657220636f6e737472756374656480e81000440000000a040000220000002f686f6d652f616e6472652f576f726b62656e63682f706172697479746563682f7375627374726174652f73726d6c2f636f6e7472616374732f7372632f6c69622e727373746f72616765206973206e6f74206e756c6c2c207468657265666f7265206d75737420626520612076616c69642074797065000000000000ea1000080000000000000008ea100003000000000000000000000020ea100001000000000000000000000028ea10000c000000000000008c43110002000000000000000000000034ea10000100000000000000000000003cea10000a0000000000000048ea100001000000000000000000000050ea100001000000000000000000000058ea10000f0000000000000068ea100001000000000000000000000070ea100001000000000000000000000078ea10000a0000000000000084ea100002000000000000000000000094ea1000020000000000000000000000a4ea10000800000000000000acea1000020000000000000000000000bcea100001000000000000005472616e73666572d043110009000000d0431100090000001144110007000000eeeb10005a000000496e7374616e746961746564b7eb100037000000436f646553746f7265640000d94311000400000089eb10002e0000005363686564756c655570646174656400763411000300000059eb100030000000446973706174636865640000d043110009000000f743110004000000eeea10004e0000003ceb10001d000000436f6e7472616374d043110009000000e7ea100007000000c4ea10002300000020416e206576656e742066726f6d20636f6e7472616374206f66206163636f756e742e5665633c75383e20412063616c6c2077617320646973706174636865642066726f6d2074686520676976656e206163636f756e742e2054686520626f6f6c207369676e616c73207768657468657220697420776173207375636365737366756c20657865637574696f6e206f72206e6f742e20547269676765726564207768656e207468652063757272656e74207363686564756c6520697320757064617465642e20436f646520776974682074686520737065636966696564206861736820686173206265656e2073746f7265642e20436f6e7472616374206465706c6f7965642062792061646472657373206174207468652073706563696669656420616464726573732e205472616e736665722068617070656e6564206066726f6d6020746f2060746f60207769746820676976656e206076616c7565602061732070617274206f662061206063616c6c60206f722060696e7374616e7469617465602e436f6e7472616374205072697374696e65436f6465436f6e747261637420436f646553746f72616765436f6e747261637420436f6e7472616374496e666f4f66436f6e747261637420476173507269636500000037000000000000000100000038000000c0ec10004a0000003200000006000000000000002f686f6d652f616e6472652f576f726b62656e63682f706172697479746563682f7375627374726174652f636f72652f73722d7072696d6974697665732f7372632f63757276652e7273000000000000e8ed10000f00000000000000f8ed100001000000000000000000000010ee100003000000000000000000000028ee1000080000000000000030ee100002000000000000000000000060ee1000020000000000000000000000af861100040000000000000070ee1000040000000000000000000000d0ee100007000000000000000000000008ef10000b0000000000000014ef100004000000000000000000000074ef10000a0000000000000000000000c4ef10000f00000000000000d4ef100002000000000000000000000004f0100005000000000000007570646174655f7363686564756c65000000000054f6100008000000000000005cf6100008000000e4f510002d000000389711000000000011f61000430000007075745f636f64650000000092f3100009000000000000009bf310000c00000000000000e0f510000400000000000000e7ea10000700000054f5100057000000abf51000350000000000000046f1100004000000000000004b22110023000000000000005f551100050000000000000064551100150000000000000092f3100009000000000000009bf310000c00000000000000bbf310000400000000000000e7ea100007000000bff3100042000000389711000000000001f410004a0000004bf410002c00000077f4100046000000bdf41000520000000ff5100045000000696e7374616e7469617465000000000089f31000090000000000000064551100150000000000000092f3100009000000000000009bf310000c00000000000000a7f310000900000000000000b0f310000b00000000000000bbf310000400000000000000e7ea10000700000068f110006f0000003897110000000000d7f11000260000003897110000000000fdf11000500000004df21000410000008ef210005b000000e9f210005700000040f310002a0000006af310001f000000636c61696d5f737572636861726765000000000046f1100004000000000000000b4e11000c000000000000004af110000a0000000000000054f11000140000002cf010005c00000088f01000450000003897110000000000cdf010004e0000001bf110002b00000020416c6c6f777320626c6f636b2070726f64756365727320746f20636c61696d206120736d616c6c2072657761726420666f72206576696374696e67206120636f6e74726163742e204966206120626c6f636b2070726f6475636572206661696c7320746f20646f20736f2c206120726567756c61722075736572732077696c6c20626520616c6c6f77656420746f20636c61696d20746865207265776172642e20496620636f6e7472616374206973206e6f742065766963746564206173206120726573756c74206f6620746869732063616c6c2c206e6f20616374696f6e73206172652074616b656e20616e64207468652073656e646572206973206e6f7420656c696769626c6520666f7220746865207265776172642e646573746175785f73656e6465724f7074696f6e3c543a3a4163636f756e7449643e20496e7374616e7469617465732061206e657720636f6e74726163742066726f6d207468652060636f646568617368602067656e65726174656420627920607075745f636f6465602c206f7074696f6e616c6c79207472616e7366657272696e6720736f6d652062616c616e63652e20496e7374616e74696174696f6e20697320657865637574656420617320666f6c6c6f77733a202d205468652064657374696e6174696f6e206164647265737320697320636f6d7075746564206261736564206f6e207468652073656e64657220616e642068617368206f662074686520636f64652e202d2054686520736d6172742d636f6e7472616374206163636f756e7420697320637265617465642061742074686520636f6d707574656420616464726573732e202d20546865206063746f725f636f64656020697320657865637574656420696e2074686520636f6e74657874206f6620746865206e65776c792d63726561746564206163636f756e742e204275666665722072657475726e656420202061667465722074686520657865637574696f6e206973207361766564206173207468652060636f646560206f6620746865206163636f756e742e205468617420636f64652077696c6c20626520696e766f6b656420202075706f6e20616e792063616c6c2072656365697665642062792074686973206163636f756e742e202d2054686520636f6e747261637420697320696e697469616c697a65642e656e646f776d656e746761735f6c696d6974436f6d706163743c4761733e636f64655f68617368436f6465486173683c543e64617461204d616b657320612063616c6c20746f20616e206163636f756e742c206f7074696f6e616c6c79207472616e7366657272696e6720736f6d652062616c616e63652e202a20496620746865206163636f756e74206973206120736d6172742d636f6e7472616374206163636f756e742c20746865206173736f63696174656420636f64652077696c6c20626520657865637574656420616e6420616e792076616c75652077696c6c206265207472616e736665727265642e202a20496620746865206163636f756e74206973206120726567756c6172206163636f756e742c20616e792076616c75652077696c6c206265207472616e736665727265642e202a204966206e6f206163636f756e742065786973747320616e64207468652063616c6c2076616c7565206973206e6f74206c657373207468616e20606578697374656e7469616c5f6465706f736974602c206120726567756c6172206163636f756e742077696c6c206265206372656174656420616e6420616e792076616c75652077696c6c206265207472616e736665727265642e2053746f7265732074686520676976656e2062696e617279205761736d20636f646520696e746f2074686520636861696e27732073746f7261676520616e642072657475726e73206974732060636f646568617368602e20596f752063616e20696e7374616e746961746520636f6e747261637473206f6e6c7920776974682073746f72656420636f64652e636f6465205570646174657320746865207363686564756c6520666f72206d65746572696e6720636f6e7472616374732e20546865207363686564756c65206d7573742068617665206120677265617465722076657273696f6e207468616e207468652073746f726564207363686564756c652e7363686564756c655363686564756c6500000000ccf81000080000000000000000000000d4f810000300000000000000000000000000000000000000000000000000000000000000389711007cf910000000000000000000d8f8100001000000000000000100000000000000e0f810000f00000000000000000000005cf61000080000000000000000000000000000000000000000000000000000000000000038971100f0f81000000000000000000000f910000100000000000000010000000000000008f910000c0000000101000000000000b0f310000b00000000000000e7ea100007000000000000000000000000000000000000003897110014f91000000000000000000024f91000010000000000000000000000000000002cf910000b0000000101000000000000b0f310000b0000000000000037f9100016000000000000000000000000000000000000003897110050f91000000000000000000060f910000100000000000000000000000000000068f910000e000000000000000000000076f910000300000000000000000000000000000000000000000000000000000000000000389711007cf9100000000000000000008cf910000100000000000000010000000000000094f910000e00000001010000000000000b4e11000c00000000000000a2f910000f0000000000000000000000000000000000000038971100b4f910000000000000000000c4f9100001000000000000000000000000000000ccf910000800000000000000000000007a6511000c0000000000000000000000000000000000000000000000000000000000000038971100d4f910000000000000000000e4f910000100000000000000010000004761735370656e744761730020fb10002000000043757272656e745363686564756c6500370000000000000001000000bc000000fbfa1000250000005072697374696e65436f64653700000000000000010000004f000000a2fa100059000000436f646553746f726167657761736d3a3a5072656661625761736d4d6f64756c650000003700000000000000010000004f00000049fa1000590000004163636f756e74436f756e746572753634000000370000000000000001000000ab00000034fa100015000000436f6e7472616374496e666f4f66436f6e7472616374496e666f3c543e0000003700000000000000010000004f0000000afa10002a0000004761735072696365370000000000000001000000bd000000ecf910001e00000020546865207072696365206f66206f6e6520756e6974206f66206761732e2054686520636f6465206173736f6369617465642077697468206120676976656e206163636f756e742e20546865207375627472696520636f756e7465722e2041206d617070696e67206265747765656e20616e206f726967696e616c20636f6465206861736820616e6420696e737472756d656e746564207761736d20636f64652c20726561647920666f7220657865637574696f6e2e2041206d617070696e672066726f6d20616e206f726967696e616c20636f6465206861736820746f20746865206f726967696e616c20636f64652c20756e746f756368656420627920696e737472756d656e746174696f6e2e2043757272656e7420636f7374207363686564756c6520666f7220636f6e7472616374732e20476173207370656e7420736f2066617220696e207468697320626c6f636b2e00000000c0fe10001300000000000000925111000e0000000000000038971100d4fe10000000000000000000e4fe100004000000000000000000000004ff100010000000000000007a6511000c00000000000000389711005cff1000000000000000000014ff10000100000000000000000000001cff100011000000000000007634110003000000000000003897110030ff1000000000000000000040ff100002000000000000000000000050ff10000b000000000000007a6511000c00000000000000389711005cff100000000000000000006cff100001000000000000000000000074ff100011000000000000007a6511000c000000000000003897110088ff1000000000000000000098ff1000070000000000000000000000d0ff10000f000000000000007a6511000c0000000000000038971100e0ff10000000000000000000f0ff1000020000000000000000000000000011000b000000000000007a6511000c00000000000000389711007c00110000000000000000000c001100010000000000000000000000140011000b000000000000007a6511000c00000000000000389711007c0011000000000000000000200011000100000000000000000000002800110012000000000000007a6511000c00000000000000389711007c00110000000000000000003c0011000100000000000000000000004400110012000000000000007a6511000c000000000000003897110058001100000000000000000068001100010000000000000000000000700011000b000000000000007a6511000c00000000000000389711007c00110000000000000000008c0011000200000000000000000000009c0011000b00000000000000d4f81000030000000000000038971100cc0011000000000000000000a8001100020000000000000000000000b80011001200000000000000d4f81000030000000000000038971100cc0011000000000000000000dc001100020000000000000000000000ec001100080000000000000076341100030000000000000038971100f4001100000000000000000004011100020000000000000000000000140111000c000000000000007634110003000000000000003897110020011100000000000000000030011100010000000000000000000000380111000d00000000000000d4f810000300000000000000389711004801110000000000000000005801110002000000000000005369676e6564436c61696d48616e646963617000370000000000000001000000be000000080711003800000038971100000000004007110043000000830711001a000000546f6d6273746f6e654465706f736974d30611003500000053746f7261676553697a654f6666736574000000370000000000000001000000a90000005606110054000000aa0611002900000052656e74427974654665650037000000000000000100000099000000090611004d00000052656e744465706f7369744f6666736574000000370000000000000001000000bf0000009104110041000000d2041100160000003897110000000000e80411005a00000042051100560000009805110053000000eb0511001e00000053757263686172676552657761726400370000000000000001000000c00000003e04110039000000770411001a0000005472616e736665724665650019041100250000004372656174696f6e46656500f2031100270000005472616e73616374696f6e426173654665650000bb031100370000005472616e73616374696f6e4279746546656500003700000000000000010000009b0000007803110043000000436f6e7472616374466565003700000000000000010000009a0000002103110050000000710311000700000043616c6c4261736546656500cc02110047000000130311000e000000496e7374616e7469617465426173654665650000370000000000000001000000c1000000760211004e000000c4021100080000004d61784465707468370000000000000001000000c20000001c0211004c000000680211000e0000004d617856616c756553697a65370000000000000001000000c3000000ce0111004e000000426c6f636b4761734c696d6974000000370000000000000001000000c40000006801110049000000b10111001d00000020546865206d6178696d756d20616d6f756e74206f6620676173207468617420636f756c6420626520657870656e6465642070657220626c6f636b2e204120726561736f6e61626c652064656661756c742076616c75652069732031305f3030305f3030302e20546865206d6178696d756d2073697a65206f6620612073746f726167652076616c756520696e2062797465732e204120726561736f6e61626c652064656661756c74206973203136204b69422e20546865206d6178696d756d206e657374696e67206c6576656c206f6620612063616c6c2f696e7374616e746961746520737461636b2e204120726561736f6e61626c652064656661756c742076616c7565206973203130302e20546865206261736520666565206368617267656420666f7220696e7374616e74696174696e67206120636f6e74726163742e204120726561736f6e61626c652064656661756c742076616c7565206973203137352e20546865206261736520666565206368617267656420666f722063616c6c696e6720696e746f206120636f6e74726163742e204120726561736f6e61626c652064656661756c742076616c7565206973203133352e205468652066656520726571756972656420746f20696e7374616e7469617465206120636f6e747261637420696e7374616e63652e204120726561736f6e61626c652064656661756c742076616c75652069732032312e205468652066656520746f206265207061696420666f72206d616b696e672061207472616e73616374696f6e3b20746865207065722d6279746520706f7274696f6e2e205468652066656520746f206265207061696420666f72206d616b696e672061207472616e73616374696f6e3b2074686520626173652e205468652066656520726571756972656420746f2063726561746520616e206163636f756e742e205468652066656520726571756972656420746f206d616b652061207472616e736665722e205265776172642074686174206973207265636569766564206279207468652070617274792077686f736520746f75636820686173206c656420746f2072656d6f76616c206f66206120636f6e74726163742e2054686520616d6f756e74206f662066756e6473206120636f6e74726163742073686f756c64206465706f73697420696e206f7264657220746f206f66667365742074686520636f7374206f66206f6e6520627974652e204c6574277320737570706f736520746865206465706f73697420697320312c303030204255202862616c616e636520756e697473292f6279746520616e64207468652072656e7420697320312042552f627974652f6461792c207468656e206120636f6e7472616374207769746820312c3030302c3030302042552074686174207573657320312c303030206279746573206f662073746f7261676520776f756c6420706179206e6f2072656e742e20427574206966207468652062616c616e6365207265647563656420746f203530302c30303020425520616e64207468652073746f7261676520737461796564207468652073616d6520617420312c3030302c207468656e20697420776f756c6420706179203530302042552f6461792e205072696365206f6620612062797465206f662073746f7261676520706572206f6e6520626c6f636b20696e74657276616c2e2053686f756c642062652067726561746572207468616e20302e2053697a65206f66206120636f6e7472616374206174207468652074696d65206f6620696e7374616e746961696f6e2e205468697320697320612073696d706c652077617920746f20656e73757265207468617420656d70747920636f6e747261637473206576656e7475616c6c7920676574732064656c657465642e20546865206d696e696d756d20616d6f756e7420726571756972656420746f2067656e6572617465206120746f6d6273746f6e652e204e756d626572206f6620626c6f636b2064656c617920616e2065787472696e73696320636c61696d20737572636861726765206861732e205768656e20636c61696d207375726368617267652069732063616c6c656420627920616e2065787472696e736963207468652072656e7420697320636865636b656420666f722063757272656e745f626c6f636b202d2064656c617943616e6e6f7420726573746f726520746f20696e6578697374696e67206f7220616c69766520636f6e74726163746d656d6f727976616c69646174696f6e3a20696d706f727420656e74727920706f696e747320746f2061206e6f6e2d6578697374656e74207479706543616e6e6f7420696d706f727420676c6f62616c736d6f64756c6520696d706f7274732061206e6f6e2d6578697374656e742066756e6374696f6e6d6f64756c6520696d706f72747320606578745f7072696e746c6e60206275742064656275672066656174757265732064697361626c656443616e6e6f7420696d706f7274207461626c65736d6f64756c652068617320696d706f7274732066726f6d2061206e6f6e2d27656e7627206e616d6573706163654d656d6f727920696d706f7274206d757374206861766520746865206669656c64206e616d6520276d656d6f7279274d756c7469706c65206d656d6f727920696d706f72747320646566696e65644d6178696d756d206e756d626572206f662070616765732073686f756c6420626520616c77617973206465636c617265642e52657175657374656420696e697469616c206e756d626572206f662070616765732073686f756c64206e6f74206578636565642074686520726571756573746564206d6178696d756d4d6178696d756d206e756d626572206f662070616765732073686f756c64206e6f74206578636565642074686520636f6e66696775726564206d6178696d756d2e64656661756c743a000000387d11002800000080e8100044000000c80100000100000080e8100044000000c8010000010000006e6577207363686564756c65206d7573742068617665206120677265617465722076657273696f6e207468616e2063757272656e74496e76616c69642073757263686172676520636c61696d3a206f726967696e206d757374206265207369676e6564206f7220696e686572656e7420616e6420617578696c696172792073656e646572206f6e6c792070726f7669646564206f6e20696e686572656e74417574686f72697479446973636f76657279204b657973000000387d110028000000c80a11004e00000034000000010000002f686f6d652f616e6472652f576f726b62656e63682f706172697479746563682f7375627374726174652f73726d6c2f617574686f726974792d646973636f766572792f7372632f6c69622e72730000c80a11004e000000340000000100000000000000ac0b11000500000000000000b40b1100010000000000000000000000bc0b1100010000000000000000000000c40b11000a00000000000000a8431100010000000000000000000000d00b1100010000000000000000000000d80b11000a00000000000000b40b1100010000000000000000000000bc0b110001000000000000005375646964000000f7431100040000001e0c1100180000004b65794368616e6765640000e20b11003c0000005375646f4173446f6e6520546865207375646f6572206a757374207377697463686564206964656e746974793b20746865206f6c64206b657920697320737570706c6965642e2041207375646f206a75737420746f6f6b20706c6163652e707265636f6e646974696f6e3a20616c6c20696d706f7274732073686f756c6420626520636865636b656420616761696e737420746865207369676e617475726573206f6620636f72726573706f6e64696e670a09090909090966756e6374696f6e7320646566696e65642062792060646566696e655f656e762160206d6163726f206279207468652075736572206f6620746865206d6163726f3b0a0909090909097369676e617475726573206f662074686573652066756e6374696f6e7320646566696e6564206279206024706172616d73603b0a09090909090963616c6c7320616c77617973206d616465207769746820617267756d656e7473207479706573206f662077686963682061726520646566696e65642062792074686520636f72726573706f6e64696e6720696d706f7274733b0a09090909090974687573207479706573206f6620617267756d656e74732073686f756c6420626520657175616c20746f2074797065206c69737420696e206024706172616d736020616e640a0909090909096c656e677468206f6620617267756d656e74206c69737420616e642024706172616d732073686f756c6420626520657175616c3b0a0909090909097468757320746869732063616e206e6576657220626520604e6f6e65603b0a0909090909097165643b0a09090909090972657475726e2074797065206572726f7276616c69646174696f6e206572726f72647572696e6720657865637574696f6e00387d110028000000740e11003f00000068000000010000002f686f6d652f616e6472652f576f726b62656e63682f706172697479746563682f7375627374726174652f73726d6c2f7375646f2f7372632f6c69622e727300740e11003f00000068000000010000006f6e6c79207468652063757272656e74207375646f206b65792063616e207375646f5375646f204b65796f6e6c79207468652063757272656e74207375646f206b65792063616e206368616e676520746865207375646f206b657900400f1100480000009b0a00000a000000400f110048000000a10a00000e0000002f72757374632f316464313838343839313633366430656235313135376431333732333030373662636632303632372f7372632f6c6962636f72652f736c6963652f6d6f642e7273000000000c1011000400000000000000684a1100010000000000000000000000101011000a00000000000000000000006010110007000000000000006810110001000000000000000000000080101100090000000000000000000000c81011000700000000000000d0101100020000000000000000000000001111000b000000000000007375646fc81211004e0000003897110000000000bd111100340000003897110000000000c54d11000b000000d04d110008000000f1111100190000000a121100180000002212110035000000d84d11000c0000007365745f6b65790000000000fc20110003000000000000004b221100230000005a1211005d0000003897110000000000bd111100340000003897110000000000c54d11000b000000d04d110008000000f111110019000000b712110011000000d84d11000c0000007375646f5f617300000000005712110003000000000000004b221100230000000000000058531100080000000000000060531100100000005811110054000000ac111100110000003897110000000000bd111100340000003897110000000000c54d11000b000000d04d110008000000f1111100190000000a121100180000002212110035000000d84d11000c0000002041757468656e7469636174657320746865207375646f206b657920616e64206469737061746368657320612066756e6374696f6e2063616c6c207769746820605369676e656460206f726967696e2066726f6d206120676976656e206163636f756e742e20546865206469737061746368206f726967696e20666f7220746869732063616c6c206d757374206265205f5369676e65645f2e202d204c696d697465642073746f726167652072656164732e202d204f6e6520444220777269746520286576656e74292e202d20556e6b6e6f776e20776569676874206f662064657269766174697665206070726f706f73616c6020657865637574696f6e2e77686f2041757468656e74696361746573207468652063757272656e74207375646f206b657920616e6420736574732074686520676976656e204163636f756e7449642028606e6577602920617320746865206e6577207375646f206b65792e202d204f6e65204442206368616e67652e2041757468656e7469636174657320746865207375646f206b657920616e64206469737061746368657320612066756e6374696f6e2063616c6c20776974682060526f6f7460206f726967696e2e5375646f000000000000741311000300000000000000000000000b4e11000c0000000000000000000000000000000000000000000000000000000000000038971100781311000000000000000000881311000100000000000000010000004b657900370000000000000001000000c500000090131100210000002054686520604163636f756e74496460206f6620746865207375646f206b65792e0000003b1411000d0000001e1411001b0000003914110002000000dc131100420000001f020000010000002f686f6d652f616e6472652f576f726b62656e63682f706172697479746563682f7375627374726174652f6e6f64652f72756e74696d652f7372632f6c69622e727342616420696e70757420646174612070726f766964656420746f203a20657865637574655f626c6f636b5014110010000000696e697469616c697a655f626c6f636b681411000f0000006170706c795f65787472696e736963008014110013000000696e686572656e745f65787472696e73696373009c1411000f000000636865636b5f696e686572656e747300b41411001400000076616c69646174655f7472616e73616374696f6ed01411000f0000006f6666636861696e5f776f726b657200e8141100040000007369676ef4141100060000007665726966790000041511000d0000006163636f756e745f6e6f6e6365000000af86110004000000241511001500000067656e65726174655f73657373696f6e5f6b65797300000000000000c01511000600000000000000c8151100010000000000000000000000d0151100010000000000000000000000d81511000500000000000000e0151100020000000000000000000000f0151100010000000000000000000000f81511001a00000000000000108d110001000000000000000000000014161100020000000000000052657761726400001144110007000000c616110038000000536c617368000000d04311000900000011441100070000007d161100490000004f6c64536c617368696e675265706f7274446973636172646564000024161100470000006b1611001200000020416e206f6c6420736c617368696e67207265706f72742066726f6d2061207072696f72206572612077617320646973636172646564206265636175736520697420636f756c64206e6f742062652070726f6365737365642e204f6e652076616c696461746f722028616e6420697473206e6f6d696e61746f72732920686173206265656e20736c61736865642062792074686520676976656e20616d6f756e742e20416c6c2076616c696461746f72732068617665206265656e2072657761726465642062792074686520676976656e2062616c616e63652e5374616b696e672043757272656e7445726153746172745374616b696e67204e6f6d696e61746f727368656164206f66205374616b696e67204e6f6d696e61746f72735374616b696e672056616c696461746f727368656164206f66205374616b696e672056616c696461746f72735374616b696e67205374616b6572735374616b696e6720426f6e6465645374616b696e67204c65646765725374616b696e672050617965655374616b696e672043757272656e74456c65637465640000000000f81911000400000000000000fc191100030000000000000000000000441a11000f0000000000000000000000bc1a11000a00000000000000c81a1100010000000000000000000000e01a11000e0000000000000000000000501b11000600000000000000581b1100010000000000000000000000701b1100170000000000000000000000281c11001100000000000000389711000000000000000000000000003c1c1100100000000000000000000000bc1c11000800000000000000c41c1100010000000000000000000000dc1c11000b0000000000000000000000341d110008000000000000003c1d1100010000000000000000000000541d11000b0000000000000000000000ac1d1100050000000000000038971100000000000000000000000000b41d11000b00000000000000000000000c1e11000900000000000000181e1100010000000000000000000000301e11000b0000000000000000000000881e11000e00000000000000981e1100010000000000000000000000b01e11000b0000000000000000000000081f110013000000000000001c1f1100010000000000000000000000341f11000100000000000000000000003c1f11000d00000000000000389711000000000000000000000000004c1f1100050000000000000000000000741f11000d0000000000000038971100000000000000000000000000841f1100060000000000000000000000b41f11001100000000000000c81f1100010000000000000000000000e01f11000100000000000000626f6e6400000000412211000a000000000000004b22110023000000000000005f5511000500000000000000645511001500000000000000f12211000500000000000000f622110011000000d72b110059000000302c1100210000003897110000000000512c11004c00000038971100000000009d2c1100490000003897110000000000c54d11000b000000e62c110035000000d04d1100080000001b2d11001a0000003897110000000000352d11005b000000902d110049000000d84d11000c000000626f6e645f6578747261000000000000c92b11000e000000000000006455110015000000a32a110059000000fc2a11000d0000003897110000000000092b1100540000005d2b110059000000b62b11001300000038971100000000005a211100550000003897110000000000c54d11000b000000af2111003a000000d04d1100080000001d55110010000000d84d11000c000000756e626f6e640000000000005f55110005000000000000006455110015000000c8261100550000001d271100400000005d271100490000003897110000000000a627110052000000f8271100300000003897110000000000282811004f000000772811004f000000c62811003f00000038971100000000009c22110055000000389711000000000005291100260000003897110000000000c54d11000b0000002b29110050000000e9211100260000007b29110059000000d42911005c000000302a1100690000001d55110010000000992a11000a00000077697468647261775f756e626f6e646564000000c12411004b00000038971100000000000c2511004d000000592511001300000038971100000000009c2211005500000038971100000000006c2511001b0000003897110000000000c54d11000b0000008725110055000000dc251100510000002d2611003d0000006a2611005e0000000f22110032000000d84d11000c00000076616c696461746500000000a02411000500000000000000a52411001c000000662411003a0000003897110000000000232111003700000038971100000000009c221100550000003897110000000000c54d11000b000000af2111003a000000e9211100260000000f22110032000000d84d11000c0000006e6f6d696e617465000000003724110007000000000000003e241100280000004e231100440000003897110000000000232111003700000038971100000000009c221100550000003897110000000000c54d11000b0000009223110049000000db231100260000000124110036000000d84d11000c0000006368696c6c00000007231100320000003897110000000000232111003700000038971100000000009c221100550000003897110000000000c54d11000b000000af2111003a00000039231100150000000f22110032000000d84d11000c0000007365745f706179656500000000000000f12211000500000000000000f6221100110000006e2211002e0000003897110000000000232111003700000038971100000000009c221100550000003897110000000000c54d11000b000000af2111003a000000e9211100260000000f22110032000000d84d11000c0000007365745f636f6e74726f6c6c6572000000000000412211000a000000000000004b22110023000000ff201100240000003897110000000000232111003700000038971100000000005a211100550000003897110000000000c54d11000b000000af2111003a000000e9211100260000000f22110032000000d84d11000c0000007365745f76616c696461746f725f636f756e740000000000fc2011000300000000000000fa4e11000c000000dc20110020000000666f7263655f6e6f5f65726173000000b02011002c0000003897110000000000c54d11000b000000a020110010000000d84d11000c000000666f7263655f6e65775f657261000000252011005300000078201100280000003897110000000000c54d11000b000000a020110010000000d84d11000c0000007365745f696e76756c6e657261626c6573000000000000001b2011000a00000000000000255c110011000000e81f11003300000020536574207468652076616c696461746f72732077686f2063616e6e6f7420626520736c61736865642028696620616e79292e76616c696461746f727320466f72636520746865726520746f2062652061206e6577206572612061742074686520656e64206f6620746865206e6578742073657373696f6e2e20416674657220746869732c2069742077696c6c20626520726573657420746f206e6f726d616c20286e6f6e2d666f7263656429206265686176696f75722e202d204e6f20617267756d656e74732e20466f72636520746865726520746f206265206e6f206e6577206572617320696e646566696e6974656c792e2054686520696465616c206e756d626572206f662076616c696461746f72732e6e6577202852652d297365742074686520636f6e74726f6c6c6572206f6620612073746173682e20456666656374732077696c6c2062652066656c742061742074686520626567696e6e696e67206f6620746865206e657874206572612e20546865206469737061746368206f726967696e20666f7220746869732063616c6c206d757374206265205f5369676e65645f206279207468652073746173682c206e6f742074686520636f6e74726f6c6c65722e202d20496e646570656e64656e74206f662074686520617267756d656e74732e20496e7369676e69666963616e7420636f6d706c65786974792e202d20436f6e7461696e732061206c696d69746564206e756d626572206f662072656164732e202d2057726974657320617265206c696d6974656420746f2074686520606f726967696e60206163636f756e74206b65792e636f6e74726f6c6c65723c543a3a4c6f6f6b7570206173205374617469634c6f6f6b75703e3a3a536f75726365202852652d2973657420746865207061796d656e742074617267657420666f72206120636f6e74726f6c6c65722e20546865206469737061746368206f726967696e20666f7220746869732063616c6c206d757374206265205f5369676e65645f2062792074686520636f6e74726f6c6c65722c206e6f74207468652073746173682e706179656552657761726444657374696e6174696f6e204465636c617265206e6f2064657369726520746f206569746865722076616c6964617465206f72206e6f6d696e6174652e202d20436f6e7461696e73206f6e6520726561642e204465636c617265207468652064657369726520746f206e6f6d696e6174652060746172676574736020666f7220746865206f726967696e20636f6e74726f6c6c65722e202d20546865207472616e73616374696f6e277320636f6d706c65786974792069732070726f706f7274696f6e616c20746f207468652073697a65206f66206074617267657473602c2077686963682069732063617070656420617420604d41585f4e4f4d494e4154494f4e53602e202d20426f74682074686520726561647320616e642077726974657320666f6c6c6f7720612073696d696c6172207061747465726e2e746172676574735665633c3c543a3a4c6f6f6b7570206173205374617469634c6f6f6b75703e3a3a536f757263653e204465636c617265207468652064657369726520746f2076616c696461746520666f7220746865206f726967696e20636f6e74726f6c6c65722e707265667356616c696461746f7250726566733c42616c616e63654f663c543e3e2052656d6f766520616e7920756e6c6f636b6564206368756e6b732066726f6d207468652060756e6c6f636b696e67602071756575652066726f6d206f7572206d616e6167656d656e742e205468697320657373656e7469616c6c7920667265657320757020746861742062616c616e636520746f206265207573656420627920746865207374617368206163636f756e7420746f20646f2077686174657665722069742077616e74732e2053656520616c736f205b6043616c6c3a3a756e626f6e64605d2e202d20436f756c6420626520646570656e64656e74206f6e2074686520606f726967696e6020617267756d656e7420616e6420686f77206d7563682060756e6c6f636b696e6760206368756e6b732065786973742e2020497420696d706c6965732060636f6e736f6c69646174655f756e6c6f636b656460207768696368206c6f6f7073206f76657220604c65646765722e756e6c6f636b696e67602c2077686963682069732020696e6469726563746c7920757365722d636f6e74726f6c6c65642e20536565205b60756e626f6e64605d20666f72206d6f72652064657461696c2e202d20436f6e7461696e732061206c696d69746564206e756d626572206f662072656164732c20796574207468652073697a65206f6620776869636820636f756c64206265206c61726765206261736564206f6e20606c6564676572602e205363686564756c65206120706f7274696f6e206f662074686520737461736820746f20626520756e6c6f636b656420726561647920666f72207472616e73666572206f75742061667465722074686520626f6e6420706572696f6420656e64732e2049662074686973206c656176657320616e20616d6f756e74206163746976656c7920626f6e646564206c657373207468616e20543a3a43757272656e63793a3a6d696e696d756d5f62616c616e636528292c207468656e20697420697320696e6372656173656420746f207468652066756c6c20616d6f756e742e204f6e63652074686520756e6c6f636b20706572696f6420697320646f6e652c20796f752063616e2063616c6c206077697468647261775f756e626f6e6465646020746f2061637475616c6c79206d6f7665207468652066756e6473206f7574206f66206d616e6167656d656e7420726561647920666f72207472616e736665722e204e6f206d6f7265207468616e2061206c696d69746564206e756d626572206f6620756e6c6f636b696e67206368756e6b73202873656520604d41585f554e4c4f434b494e475f4348554e4b5360292063616e20636f2d657869737473206174207468652073616d652074696d652e20496e207468617420636173652c205b6043616c6c3a3a77697468647261775f756e626f6e646564605d206e65656420746f2062652063616c6c656420666972737420746f2072656d6f766520736f6d65206f6620746865206368756e6b732028696620706f737369626c65292e2053656520616c736f205b6043616c6c3a3a77697468647261775f756e626f6e646564605d2e202d20496e646570656e64656e74206f662074686520617267756d656e74732e204c696d697465642062757420706f74656e7469616c6c79206578706c6f697461626c6520636f6d706c65786974792e202d20456163682063616c6c20287265717569726573207468652072656d61696e646572206f662074686520626f6e6465642062616c616e636520746f2062652061626f766520606d696e696d756d5f62616c616e6365602920202077696c6c2063617573652061206e657720656e74727920746f20626520696e73657274656420696e746f206120766563746f722028604c65646765722e756e6c6f636b696e676029206b65707420696e2073746f726167652e202020546865206f6e6c792077617920746f20636c65616e207468652061666f72656d656e74696f6e65642073746f72616765206974656d20697320616c736f20757365722d636f6e74726f6c6c656420766961206077697468647261775f756e626f6e646564602e203c2f7765696768743e2041646420736f6d6520657874726120616d6f756e742074686174206861766520617070656172656420696e207468652073746173682060667265655f62616c616e63656020696e746f207468652062616c616e636520757020666f72207374616b696e672e20557365207468697320696620746865726520617265206164646974696f6e616c2066756e647320696e20796f7572207374617368206163636f756e74207468617420796f75207769736820746f20626f6e642e20556e6c696b65205b60626f6e64605d206f72205b60756e626f6e64605d20746869732066756e6374696f6e20646f6573206e6f7420696d706f736520616e79206c696d69746174696f6e206f6e2074686520616d6f756e7420746861742063616e2062652061646465642e6d61785f6164646974696f6e616c2054616b6520746865206f726967696e206163636f756e74206173206120737461736820616e64206c6f636b207570206076616c756560206f66206974732062616c616e63652e2060636f6e74726f6c6c6572602077696c6c20626520746865206163636f756e74207468617420636f6e74726f6c732069742e206076616c756560206d757374206265206d6f7265207468616e2074686520606d696e696d756d5f62616c616e636560207370656369666965642062792060543a3a43757272656e6379602e20546865206469737061746368206f726967696e20666f7220746869732063616c6c206d757374206265205f5369676e65645f20627920746865207374617368206163636f756e742e202d20496e646570656e64656e74206f662074686520617267756d656e74732e204d6f64657261746520636f6d706c65786974792e202d20546872656520657874726120444220656e74726965732e204e4f54453a2054776f206f66207468652073746f726167652077726974657320286053656c663a3a626f6e646564602c206053656c663a3a7061796565602920617265205f6e657665725f20636c65616e656420756e6c6573732074686520606f726967696e602066616c6c732062656c6f77205f6578697374656e7469616c206465706f7369745f20616e6420676574732072656d6f76656420617320647573742e5374616b696e6700000000683411000e0000000000000000000000763411000300000000000000000000000000000000000000000000000000000000000000389711006c36110000000000000000007c3411000100000000000000010000000000000084341100150000000000000000000000763411000300000000000000000000000000000000000000000000000000000000000000389711009c3411000000000000000000ac34110001000000000000000100000000000000b43411000d0000000000000000000000255c1100110000000000000000000000000000000000000000000000000000000000000038971100d03711000000000000000000c434110003000000000000000100000000000000dc3411000600000001010000000000000b4e11000c000000000000000b4e11000c00000000000000000000000000000000000000389711001c3511000000000000000000e434110001000000000000000000000000000000ec3411000600000001010000000000000b4e11000c00000000000000f23411002900000000000000000000000000000000000000389711001c35110000000000000000002c35110001000000000000000000000000000000343511000500000001010000000000000b4e11000c00000000000000f62211001100000000000000000000000000000000000000389711003c35110000000000000000004c35110001000000000000000100000000000000543511000a00000001010100000000000b4e11000c00000000000000a52411001c00000000000000000000000000000000000000389711006035110000000000000000007035110001000000000000000100000000000000783511000a00000001010100000000000b4e11000c00000000000000255c1100110000000000000000000000000000000000000038971100d0371100000000000000000084351100010000000000000001000000000000008c3511000700000001010000000000000b4e11000c0000000000000093351100240000000000000000000000000000000000000038971100b83511000000000000000000c835110004000000000000000100000000000000e83511000e0000000000000000000000255c1100110000000000000000000000000000000000000000000000000000000000000038971100d03711000000000000000000f835110001000000000000000100000000000000003611000a00000000000000000000000a3611000800000000000000000000000000000000000000000000000000000000000000389711006c361100000000000000000014361100010000000000000001000000000000001c3611000f00000000000000000000002b3611000b00000000000000000000000000000000000000000000000000000000000000389711003836110000000000000000004836110001000000000000000100000000000000503611001b00000000000000000000009f8d11000c00000000000000000000000000000000000000000000000000000000000000389711006c36110000000000000000007c36110001000000000000000100000000000000843611001600000000000000000000009a361100090000000000000000000000000000000000000000000000000000000000000038971100a43611000000000000000000b436110001000000000000000100000000000000bc3611000900000000000000000000007a6511000c0000000000000000000000000000000000000000000000000000000000000038971100c83611000000000000000000d836110003000000000000000100000000000000f0361100080000000000000000000000f83611000700000000000000000000000000000000000000000000000000000000000000389711000037110000000000000000001037110001000000000000000100000000000000183711001300000000000000000000002b37110007000000000000000000000000000000000000000000000000000000000000003897110034371100000000000000000044371100030000000000000001000000000000005c3711000a0000000000000000000000663711001d0000000000000000000000000000000000000000000000000000000000000038971100d0371100000000000000000084371100010000000000000001000000000000008c3711000f00000001010000000000000a36110008000000000000009b371100320000000000000000000000000000000000000038971100d03711000000000000000000e037110001000000000000000100000056616c696461746f72436f756e74753332000000da3d11002a0000004d696e696d756d56616c696461746f72436f756e74000000370000000000000001000000c60000008a3d110050000000496e76756c6e657261626c6573000000b63c1100560000000c3d1100530000005f3d11002b000000426f6e6465640000763c1100400000004c65646765725374616b696e674c65646765723c543a3a4163636f756e7449642c2042616c616e63654f663c543e3e003700000000000000010000004f000000253c11005100000050617965650000003700000000000000010000004f000000ec3b11003900000056616c696461746f72730000370000000000000001000000c70000009b3b1100510000004e6f6d696e61746f72730000423b1100590000005374616b6572734578706f737572653c543a3a4163636f756e7449642c2042616c616e63654f663c543e3e00370000000000000001000000c8000000853a110053000000d83a11004600000038971100000000001e3b11002400000043757272656e74456c65637465640000463a11003f00000043757272656e74457261457261496e64657800002f3a11001700000043757272656e7445726153746172744d6f6d656e744f663c543e0000370000000000000001000000ab000000113a11001e00000043757272656e74457261537461727453657373696f6e496e646578003700000000000000010000009c000000dd3911003400000043757272656e74457261506f696e74734561726e6564457261506f696e747300370000000000000001000000c90000009a39110043000000536c6f745374616b65000000370000000000000001000000980000001e3911004c00000038971100000000006a39110030000000466f726365457261466f7263696e67003700000000000000010000004f000000d738110047000000536c6173685265776172644672616374696f6e50657262696c6c0000370000000000000001000000ca000000603811003e00000038971100000000009e38110039000000426f6e646564457261735665633c28457261496e6465782c2053657373696f6e496e646578293e001738110049000000457261536c6173684a6f75726e616c5665633c536c6173684a6f75726e616c456e7472793c543a3a4163636f756e7449642c2042616c616e63654f663c543e3e3e00000037000000000000000100000050000000e83711002f00000020416c6c20736c617368657320746861742068617665206f6363757272656420696e206120676976656e206572612e2041206d617070696e672066726f6d207374696c6c2d626f6e646564206572617320746f207468652066697273742073657373696f6e20696e646578206f662074686174206572612e205468652070657263656e74616765206f662074686520736c617368207468617420697320646973747269627574656420746f207265706f72746572732e205468652072657374206f662074686520736c61736865642076616c75652069732068616e646c6564206279207468652060536c617368602e205472756520696620746865206e6578742073657373696f6e206368616e67652077696c6c2062652061206e657720657261207265676172646c657373206f6620696e6465782e2054686520616d6f756e74206f662062616c616e6365206163746976656c79206174207374616b6520666f7220656163682076616c696461746f7220736c6f742c2063757272656e746c792e2054686973206973207573656420746f20646572697665207265776172647320616e642070756e6973686d656e74732e205265776172647320666f72207468652063757272656e74206572612e205573696e6720696e6469636573206f662063757272656e7420656c6563746564207365742e205468652073657373696f6e20696e646578206174207768696368207468652063757272656e742065726120737461727465642e20546865207374617274206f66207468652063757272656e74206572612e205468652063757272656e742065726120696e6465782e205468652063757272656e746c7920656c65637465642076616c696461746f7220736574206b65796564206279207374617368206163636f756e742049442e204e6f6d696e61746f727320666f72206120706172746963756c6172206163636f756e74207468617420697320696e20616374696f6e207269676874206e6f772e20596f752063616e27742069746572617465207468726f7567682076616c696461746f727320686572652c2062757420796f752063616e2066696e64207468656d20696e207468652053657373696f6e206d6f64756c652e2054686973206973206b6579656420627920746865207374617368206163636f756e742e20546865206d61702066726f6d206e6f6d696e61746f72207374617368206b657920746f2074686520736574206f66207374617368206b657973206f6620616c6c2076616c696461746f727320746f206e6f6d696e6174652e20546865206d61702066726f6d202877616e6e616265292076616c696461746f72207374617368206b657920746f2074686520707265666572656e636573206f6620746861742076616c696461746f722e2057686572652074686520726577617264207061796d656e742073686f756c64206265206d6164652e204b657965642062792073746173682e204d61702066726f6d20616c6c2028756e6c6f636b6564292022636f6e74726f6c6c657222206163636f756e747320746f2074686520696e666f20726567617264696e6720746865207374616b696e672e204d61702066726f6d20616c6c206c6f636b65642022737461736822206163636f756e747320746f2074686520636f6e74726f6c6c6572206163636f756e742e20416e792076616c696461746f72732074686174206d6179206e6576657220626520736c6173686564206f7220666f726369626c79206b69636b65642e20497427732061205665632073696e63652074686579277265206561737920746f20696e697469616c697a6520616e642074686520706572666f726d616e636520686974206973206d696e696d616c2028776520657870656374206e6f206d6f7265207468616e20666f757220696e76756c6e657261626c65732920616e64207265737472696374656420746f20746573746e6574732e204d696e696d756d206e756d626572206f66207374616b696e67207061727469636970616e7473206265666f726520656d657267656e637920636f6e646974696f6e732061726520696d706f7365642e2054686520696465616c206e756d626572206f66207374616b696e67207061727469636970616e74732e00000000743e11000e000000000000009f8d11000c0000000000000038971100843e11000000000000000000943e11000100000000000000000000009c3e11000f000000000000000a361100080000000000000038971100ac3e11000000000000000000bc3e1100010000000000000053657373696f6e735065724572610000370000000000000001000000a5000000fd3e11001c000000426f6e64696e674475726174696f6e00370000000000000001000000cb000000c43e110039000000204e756d626572206f6620657261732074686174207374616b65642066756e6473206d7573742072656d61696e20626f6e64656420666f722e204e756d626572206f662073657373696f6e7320706572206572612e5374616b696e6720536c6f745374616b650000603f110019000000803f110048000000bb0100002d0000005374616b696e6720457261536c6173684a6f75726e616c0000000000617474656d707420746f20646976696465206279207a65726f000000000000002f72757374632f316464313838343839313633366430656235313135376431333732333030373662636632303632372f7372632f6c6962636f72652f6f70732f61726974682e72735374616b696e6720496e76756c6e657261626c6573000000387d110028000000f83f1100420000009c020000010000002f686f6d652f616e6472652f576f726b62656e63682f706172697479746563682f7375627374726174652f73726d6c2f7374616b696e672f7372632f6c69622e72730000f83f1100420000009c02000001000000636f6e74726f6c6c657220616c72656164792070616972656463616e206e6f7420626f6e6420776974682076616c7565206c657373207468616e206d696e696d756d2062616c616e6365737461736820616c726561647920626f6e6465646e6f7420612073746173686e6f74206120636f6e74726f6c6c657263616e206e6f74207363686564756c65206d6f726520756e6c6f636b206368756e6b73746172676574732063616e6e6f7420626520656d7074790000000000e44211000800000000000000ec42110002000000000000000000000038971100000000000000000000000000fc421100060000000000000004431100030000000000000000000000389711000000000000000000000000001c4311000e0000000000000038971100000000000000000000000000389711000000000000000000000000002a431100070000000000000034431100020000000000000000000000389711000000000000000000000000004443110006000000000000004c431100010000000000000000000000389711000000000000000000000000005443110009000000000000004c431100010000000000000000000000389711000000000000000000000000005d43110009000000000000004c4311000100000000000000000000003897110000000000000000000000000066431100080000000000000070431100020000000000000000000000389711000000000000000000000000008043110009000000000000008c431100020000000000000000000000389711000000000000000000000000009c4311000b00000000000000a843110001000000000000000000000038971100000000000000000000000000b04311000600000000000000b843110003000000000000000000000038971100000000000000000050726f706f736564084411000900000011441100070000005461626c6564000008441100090000001144110007000000184411000e00000045787465726e616c5461626c656453746172746564000000e84311000f000000fb4311000d0000005061737365640000e84311000f0000004e6f7450617373656443616e63656c6c656445786563757465640000e84311000f000000f74311000400000044656c656761746564000000d043110009000000d043110009000000556e64656c65676174656400d0431100090000005665746f65640000d043110009000000d943110004000000dd4311000b0000004163636f756e74496448617368426c6f636b4e756d6265725265666572656e64756d496e646578626f6f6c566f74655468726573686f6c6450726f70496e64657842616c616e63655665633c4163636f756e7449643e44656d6f637261637920566f74654f6644656d6f6372616379205265666572656e64756d496e666f4f6644656d6f63726163792044656c65676174696f6e7368656164206f662044656d6f63726163792044656c65676174696f6e7344656d6f6372616379204469737061746368517565756544656d6f637261637920566f74657273466f7244656d6f6372616379205075626c696350726f70730000005045110048000000a10a00000e00000044656d6f6372616379204465706f7369744f664e6f207075626c69632070726f706f73616c732077616974696e6743616e6e6f7420696e6a6563742061207265666572656e64756d207468617420656e6473206561726c696572207468616e2070726563656564696e67207265666572656e64756d000000000000002f72757374632f316464313838343839313633366430656235313135376431333732333030373662636632303632372f7372632f6c6962636f72652f736c6963652f6d6f642e727344656d6f6372616379204e65787445787465726e616c4e6f2065787465726e616c2070726f706f73616c2077616974696e67000000000000b84811000700000000000000c0481100020000000000000000000000f0481100060000000000000000000000204911000600000000000000284911000100000000000000000000004049110006000000000000000000000070491100040000000000000074491100020000000000000000000000a4491100070000000000000000000000dc4911000a0000000000000074491100020000000000000000000000e8491100070000000000000000000000204a11001000000000000000304a1100010000000000000000000000484a1100020000000000000000000000584a11001000000000000000684a1100010000000000000000000000804a1100020000000000000000000000904a11001900000000000000684a1100010000000000000000000000ac4a1100050000000000000000000000d44a11001800000000000000684a1100010000000000000000000000ec4a1100050000000000000000000000144b11000a00000000000000204b1100030000000000000000000000684b1100080000000000000000000000a84b11000d00000000000000b84b1100010000000000000000000000d04b1100010000000000000000000000d84b11001100000000000000ec4b1100010000000000000000000000044c11000100000000000000000000000c4c11000d000000000000001c4c1100030000000000000000000000644c11000100000000000000000000006c4c11000900000000000000784c1100010000000000000000000000904c1100050000000000000000000000b84c11000c0000000000000038971100000000000000000000000000c44c1100050000000000000000000000ec4c11000c00000000000000784c1100010000000000000000000000f84c1100050000000000000000000000204d11000800000000000000284d1100020000000000000000000000584d1100050000000000000000000000804d11000a00000000000000389711000000000000000000000000008c4d1100050000000000000070726f706f736500000000005853110008000000000000006053110010000000000000005f55110005000000000000006455110015000000f5541100280000003897110000000000c54d11000b000000d04d1100080000003f55110020000000d84d11000c0000007365636f6e640000000000005853110008000000000000002d55110012000000f5541100280000003897110000000000c54d11000b000000d04d1100080000001d55110010000000d84d11000c000000766f746500000000374f110009000000000000000a4f11001800000000000000704911000400000000000000f154110004000000755411004d000000c25411002f0000003897110000000000c54d11000b000000d04d110008000000565411001f000000d84d11000c00000070726f78795f766f74650000c453110054000000185411003e0000003897110000000000c54d11000b000000d04d110008000000565411001f000000d84d11000c000000656d657267656e63795f63616e63656c00000000374f11000900000000000000e84311000f00000070531100540000004c5311000c00000065787465726e616c5f70726f706f7365000000005853110008000000000000006053110010000000005311004c0000004c5311000c00000065787465726e616c5f70726f706f73655f6d616a6f726974790000009252110056000000e852110018000000389711000000000018521100530000006b5211002700000065787465726e616c5f70726f706f73655f64656661756c74a551110052000000f751110021000000389711000000000018521100530000006b52110027000000666173745f747261636b0000000000006f4f11000d000000000000007c4f11000700000000000000855111000d00000000000000925111000e00000000000000a05111000500000000000000925111000e000000834f110054000000d74f110059000000305011003b00000038971100000000006b5011003e000000a95011004b000000f450110055000000495111003c0000007665746f5f65787465726e616c000000000000006f4f11000d000000000000007c4f110007000000404f11002f00000063616e63656c5f7265666572656e64756d00000000000000374f110009000000000000000a4f110018000000224f11001500000063616e63656c5f71756575656400000000000000da4e11000400000000000000de4e11001700000000000000f54e11000500000000000000fa4e11000c00000000000000064f110004000000000000000a4f110018000000b24e1100280000007365745f70726f787900000000000000ad4e110005000000000000000b4e11000c000000874e1100260000003897110000000000c54d11000b000000f34d110016000000d84d11000c00000072657369676e5f70726f7879614e1100260000003897110000000000c54d11000b000000514e110010000000d84d11000c00000072656d6f76655f70726f78792b4e1100260000003897110000000000c54d11000b000000514e110010000000d84d11000c00000064656c656761746500000000094e110002000000000000000b4e11000c00000000000000174e11000a00000000000000214e11000a000000e44d11000f0000003897110000000000c54d11000b000000f34d110016000000d84d11000c000000756e64656c65676174650000b44d1100110000003897110000000000c54d11000b000000d04d110008000000d84d11000c00000020556e64656c656761746520766f74652e2023203c7765696768743e202d204f2831292e2023203c2f7765696768743e2044656c656761746520766f74652e202d204f6e6520657874726120444220656e7472792e746f543a3a4163636f756e744964636f6e76696374696f6e436f6e76696374696f6e20436c656172207468652070726f78792e2043616c6c6564206279207468652073746173682e202d204f6e6520444220636c6561722e20436c656172207468652070726f78792e2043616c6c6564206279207468652070726f78792e205370656369667920612070726f78792e2043616c6c6564206279207468652073746173682e70726f78792043616e63656c20612070726f706f73616c2071756575656420666f7220656e6163746d656e742e7768656e436f6d706163743c543a3a426c6f636b4e756d6265723e7768696368436f6d706163743c7533323e77686174436f6d706163743c5265666572656e64756d496e6465783e2052656d6f76652061207265666572656e64756d2e7265665f696e646578205665746f20616e6420626c61636b6c697374207468652065787465726e616c2070726f706f73616c20686173682e70726f706f73616c5f68617368543a3a48617368205363686564756c65207468652063757272656e746c792065787465726e616c6c792d70726f706f736564206d616a6f726974792d63617272696573207265666572656e64756d20746f206265207461626c656420696d6d6564696174656c792e204966207468657265206973206e6f2065787465726e616c6c792d70726f706f736564207265666572656e64756d2063757272656e746c792c206f72206966207468657265206973206f6e6520627574206974206973206e6f742061206d616a6f726974792d63617272696573207265666572656e64756d207468656e206974206661696c732e202d206070726f706f73616c5f68617368603a205468652068617368206f66207468652063757272656e742065787465726e616c2070726f706f73616c2e202d2060766f74696e675f706572696f64603a2054686520706572696f64207468617420697320616c6c6f77656420666f7220766f74696e67206f6e20746869732070726f706f73616c2e202d206064656c6179603a20546865206e756d626572206f6620626c6f636b20616674657220766f74696e672068617320656e64656420696e20617070726f76616c20616e6420746869732073686f756c64206265202020656e61637465642e20496e6372656173656420746f2060456d657267656e6379566f74696e67506572696f646020696620746f6f206c6f772e766f74696e675f706572696f64543a3a426c6f636b4e756d62657264656c6179205363686564756c652061206e656761746976652d7475726e6f75742d62696173207265666572656e64756d20746f206265207461626c6564206e657874206f6e6365206974206973206c6567616c20746f207363686564756c6520616e2065787465726e616c207265666572656e64756d2e20556e6c696b65206065787465726e616c5f70726f706f7365602c20626c61636b6c697374696e6720686173206e6f20656666656374206f6e207468697320616e64206974206d6179207265706c6163652061207072652d7363686564756c6564206065787465726e616c5f70726f706f7365602063616c6c2e205363686564756c652061206d616a6f726974792d63617272696573207265666572656e64756d20746f206265207461626c6564206e657874206f6e6365206974206973206c6567616c20746f207363686564756c6520616e2065787465726e616c207265666572656e64756d2e205363686564756c652061207265666572656e64756d20746f206265207461626c6564206f6e6365206974206973206c6567616c20746f207363686564756c6520616e2065787465726e616c207265666572656e64756d2e70726f706f73616c426f783c543a3a50726f706f73616c3e205363686564756c6520616e20656d657267656e63792063616e63656c6c6174696f6e206f662061207265666572656e64756d2e2043616e6e6f742068617070656e20747769636520746f207468652073616d6520566f746520696e2061207265666572656e64756d206f6e20626568616c66206f6620612073746173682e2049662060766f74652e69735f6179652829602c2074686520766f746520697320746f20656e616374207468652070726f706f73616c3b20206f7468657277697365206974206973206120766f746520746f206b65657020746865207374617475732071756f2e202d204f6e65204442206368616e67652c206f6e6520444220656e7472792e20566f746520696e2061207265666572656e64756d2e2049662060766f74652e69735f6179652829602c2074686520766f746520697320746f20656e616374207468652070726f706f73616c3b206f7468657277697365206974206973206120766f746520746f206b65657020746865207374617475732071756f2e566f74652050726f706f736520612073656e73697469766520616374696f6e20746f2062652074616b656e2e202d204f6e6520444220656e7472792e436f6d706163743c50726f70496e6465783e202d2054776f204442206368616e6765732c206f6e6520444220656e7472792e76616c7565436f6d706163743c42616c616e63654f663c543e3e44656d6f6372616379000000000000ac5a11000f0000000000000000000000084411000900000000000000000000000000000000000000000000000000000000000000389711006c5b11000000000000000000bc5a110001000000000000000100000000000000c45a11000b0000000000000000000000cf5a11002b0000000000000000000000000000000000000000000000000000000000000038971100385c11000000000000000000fc5a110001000000000000000100000000000000045b11000900000001010000000000000844110009000000000000000d5b1100210000000000000000000000000000000000000038971100305b11000000000000000000405b110001000000000000000000000000000000485b11000f0000000000000000000000e84311000f00000000000000000000000000000000000000000000000000000000000000389711006c5b11000000000000000000585b110001000000000000000100000000000000605b1100090000000000000000000000e84311000f00000000000000000000000000000000000000000000000000000000000000389711006c5b110000000000000000007c5b110001000000000000000100000000000000845b1100100000000101000000000000e84311000f00000000000000945b11002d0000000000000000000000000000000000000038971100b05c11000000000000000000c45b110001000000000000000000000000000000cc5b11000d0000000101000000000000925111000e00000000000000d95b11002b0000000000000000000000000000000000000038971100045c11000000000000000000145c1100010000000000000001000000000000001c5c1100090000000101000000000000e84311000f00000000000000255c1100110000000000000000000000000000000000000038971100385c11000000000000000000485c110001000000000000000100000000000000505c1100060000000101000000000000565c11001f00000000000000f1541100040000000000000000000000000000000000000038971100785c11000000000000000000885c110004000000000000000100000000000000a85c11000500000001010000000000000b4e11000c000000000000000b4e11000c0000000000000000000000000000000000000038971100b05c11000000000000000000c05c110002000000000000000000000000000000d05c11000b00000001010100000000000b4e11000c00000000000000db5c11001a0000000000000000000000000000000000000038971100f85c11000000000000000000085d110001000000000000000100000000000000105d1100150000000000000000000000f7431100040000000000000000000000000000000000000000000000000000000000000038971100ec5d11000000000000000000285d110002000000000000000100000000000000385d11000c0000000000000000000000445d11001c0000000000000000000000000000000000000000000000000000000000000038971100605d11000000000000000000705d110004000000000000000000000000000000905d11000900000001010000000000007c4f11000700000000000000995d1100230000000000000000000000000000000000000038971100bc5d11000000000000000000cc5d110002000000000000000000000000000000dc5d11000d00000001010000000000007c4f11000700000000000000f7431100040000000000000000000000000000000000000038971100ec5d11000000000000000000fc5d11000100000000000000010000005075626c696350726f70436f756e74006c6311003d0000005075626c696350726f70735665633c2850726f70496e6465782c20543a3a50726f706f73616c2c20543a3a4163636f756e744964293e00004c631100200000004465706f7369744f662842616c616e63654f663c543e2c205665633c543a3a4163636f756e7449643e290000370000000000000001000000a20000002b631100210000005265666572656e64756d436f756e7400df6211004c0000004e65787454616c6c790000003700000000000000010000009c000000ad621100320000005265666572656e64756d496e666f4f66285265666572656e64756d496e666f3c543a3a426c6f636b4e756d6265722c20543a3a50726f706f73616c3e29000000806211002d000000446973706174636851756575655665633c4f7074696f6e3c28543a3a50726f706f73616c2c205265666572656e64756d496e646578293e3e370000000000000001000000500000005062110030000000566f74657273466f725665633c543a3a4163636f756e7449643e0000370000000000000001000000500000002762110029000000566f74654f66285265666572656e64756d496e6465782c20543a3a4163636f756e744964290000003700000000000000010000004f000000e86011005800000040611100530000009361110057000000ea6111003d00000050726f78790000003700000000000000010000004f0000007a6011004c000000c66011002200000044656c65676174696f6e7328543a3a4163636f756e7449642c20436f6e76696374696f6e29000000370000000000000001000000cc0000002a601100500000004c6173745461626c656457617345787465726e616c000000ca5f110056000000206011000a0000004e65787445787465726e616c28543a3a50726f706f73616c2c20566f74655468726573686f6c6429370000000000000001000000cd000000dc5e110056000000325f110055000000875f110029000000b05f11001a000000426c61636b6c69737428543a3a426c6f636b4e756d6265722c205665633c543a3a4163636f756e7449643e29370000000000000001000000a20000004e5e110054000000a25e11003a00000043616e63656c6c6174696f6e730000003700000000000000010000004f000000045e11004a000000205265636f7264206f6620616c6c2070726f706f73616c7320746861742068617665206265656e207375626a65637420746f20656d657267656e63792063616e63656c6c6174696f6e2e2041207265636f7264206f662077686f207665746f656420776861742e204d6170732070726f706f73616c206861736820746f206120706f737369626c65206578697374656e7420626c6f636b206e756d6265722028756e74696c207768656e206974206d6179206e6f742062652072657375626d69747465642920616e642077686f207665746f65642069742e20546865207265666572656e64756d20746f206265207461626c6564207768656e6576657220697420776f756c642062652076616c696420746f207461626c6520616e2065787465726e616c2070726f706f73616c2e20546869732068617070656e73207768656e2061207265666572656e64756d206e6565647320746f206265207461626c656420616e64206f6e65206f662074776f20636f6e646974696f6e7320617265206d65743a202d20604c6173745461626c656457617345787465726e616c60206973206066616c7365603b206f72202d20605075626c696350726f70736020697320656d7074792e205472756520696620746865206c617374207265666572656e64756d207461626c656420776173207375626d69747465642065787465726e616c6c792e2046616c7365206966206974207761732061207075626c69632070726f706f73616c2e2047657420746865206163636f756e742028616e64206c6f636b20706572696f64732920746f20776869636820616e6f74686572206163636f756e742069732064656c65676174696e6720766f74652e2057686f2069732061626c6520746f20766f746520666f722077686f6d2e2056616c7565206973207468652066756e642d686f6c64696e67206163636f756e742c206b65792069732074686520766f74652d7472616e73616374696f6e2d73656e64696e67206163636f756e742e204765742074686520766f746520696e206120676976656e207265666572656e64756d206f66206120706172746963756c617220766f7465722e2054686520726573756c74206973206d65616e696e6766756c206f6e6c792069662060766f746572735f666f726020696e636c756465732074686520766f746572207768656e2063616c6c6564207769746820746865207265666572656e64756d2028796f75276c6c20676574207468652064656661756c742060566f7465602076616c7565206f7468657277697365292e20496620796f7520646f6e27742077616e7420746f20636865636b2060766f746572735f666f72602c207468656e20796f752063616e20616c736f20636865636b20666f722073696d706c65206578697374656e636520776974682060566f74654f663a3a657869737473602066697273742e204765742074686520766f7465727320666f72207468652063757272656e742070726f706f73616c2e205175657565206f66207375636365737366756c207265666572656e646120746f20626520646973706174636865642e20496e666f726d6174696f6e20636f6e6365726e696e6720616e7920676976656e207265666572656e64756d2e20546865206e657874207265666572656e64756d20696e64657820746861742073686f756c642062652074616c6c6965642e20546865206e6578742066726565207265666572656e64756d20696e6465782c20616b6120746865206e756d626572206f66207265666572656e6461207374617274656420736f206661722e2054686f73652077686f2068617665206c6f636b65642061206465706f7369742e20546865207075626c69632070726f706f73616c732e20556e736f727465642e20546865206e756d626572206f6620287075626c6963292070726f706f73616c7320746861742068617665206265656e206d61646520736f206661722e00000000000000fc6411000f00000000000000925111000e00000000000000389711000c65110000000000000000001c651100050000000000000000000000446511000c00000000000000925111000e0000000000000038971100e0651100000000000000000050651100010000000000000000000000586511000c00000000000000925111000e0000000000000038971100e06511000000000000000000646511000100000000000000000000006c6511000e000000000000007a6511000c000000000000003897110088651100000000000000000098651100010000000000000000000000a06511001500000000000000925111000e0000000000000038971100b86511000000000000000000c8651100010000000000000000000000d06511000d00000000000000925111000e0000000000000038971100e06511000000000000000000f06511000100000000000000456e6163746d656e74506572696f6400370000000000000001000000ce0000003f6711005c00000038971100000000009b6711004c000000e76711005a00000041681100270000004c61756e6368506572696f640667110039000000566f74696e67506572696f64d86611002e0000004d696e696d756d4465706f73697442616c616e63654f663c543e0000370000000000000001000000cf0000008b6611004d000000456d657267656e6379566f74696e67506572696f64000000370000000000000001000000d0000000506611003b000000436f6f6c6f6666506572696f64000000370000000000000001000000d1000000f86511005800000020506572696f6420696e20626c6f636b7320776865726520616e2065787465726e616c2070726f706f73616c206d6179206e6f742062652072652d7375626d6974746564206166746572206265696e67207665746f65642e204d696e696d756d20766f74696e6720706572696f6420616c6c6f77656420666f7220616e20656d657267656e6379207265666572656e64756d2e20546865206d696e696d756d20616d6f756e7420746f20626520757365642061732061206465706f73697420666f722061207075626c6963207265666572656e64756d2070726f706f73616c2e20486f77206f6674656e2028696e20626c6f636b732920746f20636865636b20666f72206e657720766f7465732e20486f77206f6674656e2028696e20626c6f636b7329206e6577207075626c6963207265666572656e646120617265206c61756e636865642e20546865206d696e696d756d20706572696f64206f66206c6f636b696e6720616e642074686520706572696f64206265747765656e20612070726f706f73616c206265696e6720617070726f76656420616e6420656e61637465642e2049742073686f756c642067656e6572616c6c792062652061206c6974746c65206d6f7265207468616e2074686520756e7374616b6520706572696f6420746f20656e73757265207468617420766f74696e67207374616b657273206861766520616e206f70706f7274756e69747920746f2072656d6f7665207468656d73656c7665732066726f6d207468652073797374656d20696e207468652063617365207768657265207468657920617265206f6e20746865206c6f73696e672073696465206f66206120766f74652e387d11002800000080681100440000004f010000010000002f686f6d652f616e6472652f576f726b62656e63682f706172697479746563682f7375627374726174652f73726d6c2f64656d6f63726163792f7372632f6c69622e7273036b110023000000d96a11002a00000080681100440000004f0100000100000076616c756520746f6f206c6f7770726f706f73657227732062616c616e636520746f6f206c6f7763616e206f6e6c79207365636f6e6420616e206578697374696e672070726f706f73616c7365636f6e64657227732062616c616e636520746f6f206c6f7744656d6f63726163792050726f78796e6f7420612070726f787944656d6f63726163792043616e63656c6c6174696f6e7370726f706f73616c207374696c6c20626c61636b6c697374656470726f706f73616c20616c7265616479206d61646544656d6f637261637920426c61636b6c697374696e76616c696420686173686e6578742065787465726e616c2070726f706f73616c206e6f742073696d706c65206d616a6f726974796e6f2070726f706f73616c206d616465756e6b6e6f776e2070726f706f73616c6e6f2065787465726e616c2070726f706f73616c6964656e74697479206d6179206e6f74207665746f20612070726f706f73616c207477696365616c726561647920612070726f787977726f6e672070726f78796e6f742064656c656761746564756e6b6e6f776e20696e64657863616e6e6f742063616e63656c207468652073616d652070726f706f73616c20747769636570726f706f73616c206e6f7420666f756e64766f746520676976656e20666f7220696e76616c6964207265666572656e64756d2e696e7465726e616c206572726f723a20656e746572656420756e726561636861626c6520636f64653a205f5f5068616e746f6d4974656d2073686f756c64206e6576657220626520757365642e00003300000004000000040000002500000042725461626c65446174617461626c65330000000400000004000000d200000064656661756c744636345265696e74657270726574493634556e726561636861626c654e6f70426c6f636b00330000000400000004000000d30000004c6f6f704966456c7365456e6442724272496642725461626c650000330000000400000004000000d400000052657475726e43616c6c43616c6c496e6469726563740000330000000400000004000000d500000044726f7053656c6563744765744c6f63616c5365744c6f63616c5465654c6f63616c476574476c6f62616c536574476c6f62616c4933324c6f61644936344c6f61644633324c6f61644636344c6f61644933324c6f616438534933324c6f616438554933324c6f61643136534933324c6f61643136554936344c6f616438534936344c6f616438554936344c6f61643136534936344c6f61643136554936344c6f61643332534936344c6f616433325549333253746f726549363453746f726546333253746f726546363453746f726549333253746f72653849333253746f7265313649363453746f72653849363453746f7265313649363453746f7265333243757272656e744d656d6f727947726f774d656d6f7279493332436f6e737400330000000400000004000000d6000000493634436f6e7374330000000400000004000000d7000000463332436f6e7374463634436f6e73743300000004000000040000000900000049333245717a49333245714933324e654933324c74534933324c74554933324774534933324774554933324c65534933324c655549333247655349333247655549363445717a49363445714936344e654936344c74534936344c74554936344774534936344774554936344c65534936344c655549363447655349363447655546333245714633324e654633324c7446333247744633324c65463332476546363445714636344e654636344c7446363447744636344c654636344765493332436c7a49333243747a493332506f70636e744933324164644933325375624933324d756c493332446976534933324469765549333252656d5349333252656d55493332416e644933324f72493332586f7249333253686c4933325368725349333253687255493332526f746c493332526f7472493634436c7a49363443747a493634506f70636e744936344164644936345375624936344d756c493634446976534936344469765549363452656d5349363452656d55493634416e644936344f72493634586f7249363453686c4936345368725349363453687255493634526f746c493634526f74724633324162734633324e65674633324365696c463332466c6f6f724633325472756e634633324e656172657374463332537172744633324164644633325375624633324d756c4633324469764633324d696e4633324d6178463332436f70797369676e4636344162734636344e65674636344365696c463634466c6f6f724636345472756e634636344e656172657374463634537172744636344164644636345375624636344d756c4636344469764636344d696e4636344d6178463634436f70797369676e493332577261704936344933325472756e63534633324933325472756e63554633324933325472756e63534636344933325472756e6355463634493634457874656e6453493332493634457874656e64554933324936345472756e63534633324936345472756e63554633324936345472756e63534636344936345472756e6355463634463332436f6e7665727453493332463332436f6e7665727455493332463332436f6e7665727453493634463332436f6e766572745549363446333244656d6f7465463634463634436f6e7665727453493332463634436f6e7665727455493332463634436f6e7665727453493634463634436f6e766572745549363446363450726f6d6f74654633324933325265696e746572707265744633324936345265696e746572707265744636344633325265696e74657270726574493332496e76616c696444617461547261696c696e6744617461556e6578706563746564456f6600002c7111000b000000492f4f204572726f723a204e6f526573756c7456616c7565330000000400000004000000d80000004636344933324936344633324e6f6e65536f6d65330000000400000004000000d9000000656e7600907111005d0000001201000016000000000000002f686f6d652f616e6472652f2e636172676f2f72656769737472792f7372632f6769746875622e636f6d2d316563633632393964623965633832332f707761736d2d7574696c732d302e31312e302f7372632f6761732f6d6f642e72736c6173745f696e6465782069732067726561746572207468616e20303b206c6173745f696e64657820697320737461636b2073697a65202d20313b2071656470721100660000001001000017000000447211002500000043616c6c20746f2066756e6374696f6e2074686174206f75742d6f662d626f756e64733a20000000000000002f686f6d652f616e6472652f2e636172676f2f72656769737472792f7372632f6769746875622e636f6d2d316563633632393964623965633832332f707761736d2d7574696c732d302e31312e302f7372632f737461636b5f6865696768742f6d6f642e7273546869732073686f756c64206265206120696e646578206f66206120646566696e65642066756e6374696f6e44756520746f2076616c69646174696f6e20636f64652073656374696f6e2073686f756c642065786973747346756e6374696f6e20626f6479206973206f7574206f6620626f756e647366756e6374696f6e20696d706f727420636f756e74206973206e6f74207a65726f3b20696d706f72742073656374696f6e206d757374206578697374733b2071656466756e635f696478206973206c657373207468616e2066756e6374696f6e20696d706f72747320636f756e743b0a090909096e74682066756e6374696f6e20696d706f7274206d7573742062652060536f6d65603b0a0909090971656400f495110012000000417411000f000000147411000a0000001e74110014000000327411000f0000005369676e61747572652020287370656369666965642062792066756e6320292069736e277420646566696e6564206973206e6f7420646566696e65647372632f6c6962616c6c6f632f7665632e7273007c7411001c0000005074110013000000cc04000009000000617373657274696f6e206661696c65643a20656e64203c3d206c656e2075110048000000b1010000230000002075110048000000b201000023000000d074110049000000870200001d00000000000000000000002f72757374632f316464313838343839313633366430656235313135376431333732333030373662636632303632372f7372632f6c6962636f72652f736c6963652f736f72742e7273000000000000002f72757374632f316464313838343839313633366430656235313135376431333732333030373662636632303632372f7372632f6c6962636f72652f736c6963652f6d6f642e7273d0741100490000009d0000003a000000d074110049000000a4000000300000004d761100120000005f7611000c0000006066756e635f696478602073686f756c6420636f6d652066726f6d20606e6565645f7468756e6b73603b0a09090909606e6565645f7468756e6b736020697320706f70756c617465642077697468207468652073616d65206974656d73207468617420696e20607265706c6163656d656e745f6d6170603b0a090909097165644174207468697320706f696e7420616e20696e646578206d7573742062652061737369676e656420746f2065616368207468756e6b66756e6374696f6e207769746820696478202069736e277420666f756e644672616d6569735f706f6c796d6f72706869630000330000000400000004000000da000000656e645f6172697479000000330000000400000004000000250000006272616e63685f617269747973746172745f6865696768744e6f2066756e6374696f6e2073656374696f6e4e6f20636f64652073656374696f6e4e6f20747970652073656374696f6e000000e47911000a00000046756e6374696f6e206973206e6f7420666f756e6420696e2066756e632073656374696f6e46756e6374696f6e20626f647920666f722074686520696e6465782069736e277420666f756e64d87911000c000000447911000b000000737461636b206d757374206265206e6f6e2d656d70747900397911000b000000f078110006000000737461636b206f766572666c6f774172697479206f6620616c6c206a756d702d74617267657473206d75737420626520657175616c54797065206e6f7420666f756e6400e978110007000000e07711006d000000c8000000110000002f686f6d652f616e6472652f2e636172676f2f72656769737472792f7372632f6769746875622e636f6d2d316563633632393964623965633832332f707761736d2d7574696c732d302e31312e302f7372632f737461636b5f6865696768742f6d61785f6865696768742e72736d61785f686569676874707761736d5f7574696c733a3a737461636b5f6865696768743a3a6d61785f6865696768742f686f6d652f616e6472652f2e636172676f2f72656769737472792f7372632f6769746875622e636f6d2d316563633632393964623965633832332f707761736d2d7574696c732d302e31312e302f7372632f737461636b5f6865696768742f6d61785f6865696768742e72737472756e633a20707573683a2000003479110005000000747279696e6720746f20706f70206d6f72652076616c756573207468616e20707573686564737461636b20756e646572666c6f77706f703a20756e726561636861626c65706f705f6672616d653a20636f6e74726f6c20737461636b20697320656d707479636f6e74726f6c20737461636b206f75742d6f662d626f756e647390791100480000009b0a00000a0000002f72757374632f316464313838343839313633366430656235313135376431333732333030373662636632303632372f7372632f6c6962636f72652f736c6963652f6d6f642e7273707573685f6672616d653a2066756e635f6964783a206578745f6368696c645f73746f726167655f726f6f74206e657665722072657475726e73207533323a3a6d61785f76616c75653b2071656452756e74696d65206d656d6f7279206578686175737465642e2041626f7274696e6753797374656d2073746174652063757272656e746c792070726576656e74732074686973207472616e73616374696f6e5472616e73616374696f6e20646f6573206e6f742068617665207265717569726564207065726d697373696f6e73496e76616c6964206f726967696e496e76616c69645472616e73616374696f6e20637573746f6d206572726f725472616e73616374696f6e20776f756c642065786861757374732074686520626c6f636b206c696d6974735472616e73616374696f6e2068617320616e20616e6369656e7420626972746820626c6f636b5472616e73616374696f6e20686173206120626164207369676e61747572655472616e73616374696f6e206973206f757464617465645472616e73616374696f6e2077696c6c2062652076616c696420696e2074686520667574757265496e6162696c69747920746f2070617920736f6d6520666565732028652e672e206163636f756e742062616c616e636520746f6f206c6f77295472616e73616374696f6e2063616c6c206973206e6f74206578706563746564556e6b6e6f776e5472616e73616374696f6e20637573746f6d206572726f72436f756c64206e6f742066696e6420616e20756e7369676e65642076616c696461746f7220666f722074686520756e7369676e6564207472616e73616374696f6e436f756c64206e6f74206c6f6f6b757020696e666f726d6174696f6e20726571756972656420746f2076616c696461746520746865207472616e73616374696f6e00a07c110019000000c07c1100500000005800000022000000000000000000000000000000617474656d707420746f20646976696465206279207a65726f000000000000002f686f6d652f616e6472652f576f726b62656e63682f706172697479746563682f7375627374726174652f636f72652f73722d7072696d6974697665732f7372632f67656e657269632f6572612e727348617368206e6f7420657175616c0000387d110028000000607d1100500000008700000009000000696e7465726e616c206572726f723a20656e746572656420756e726561636861626c6520636f64652f686f6d652f616e6472652f576f726b62656e63682f706172697479746563682f7375627374726174652f636f72652f73722d73616e64626f782f7372632f2e2e2f776974686f75745f7374642e7273387d110028000000607d1100500000009000000009000000417574686f727368697020446964536574556e636c6573426162652045706f6368496e6465784261626520417574686f726974696573426162652047656e65736973536c6f74426162652043757272656e74536c6f74426162652052616e646f6d6e65737342616265204e65787452616e646f6d6e65737342616265205365676d656e74496e6465784261626520556e646572436f6e737472756374696f6e4261626520496e697469616c697a656462616265736c6f74436f756c64206e6f74206465636f64652072657175657374656420696e686572656e742074797065214241424520696e686572656e742064617461206e6f7420666f756e64746f6f206d616e7920696e737472756374696f6e73000000f47e110024000000187f1100170000005d02000009000000547269656420746f20736872696e6b20746f2061206c61726765722063617061636974797372632f6c6962616c6c6f632f7261775f7665632e7273436f6e7472616374204761735370656e74436f6e74726163742043757272656e745363686564756c65436f6e7472616374204163636f756e74436f756e7465726761736578745f7365745f73746f726167656578745f6765745f73746f726167656578745f63616c6c6578745f696e7374616e74696174656578745f72657475726e6578745f63616c6c65726578745f616464726573736578745f6761735f70726963656578745f6761735f6c6566746578745f62616c616e63656578745f76616c75655f7472616e736665727265646578745f72616e646f6d6578745f6e6f776578745f6d696e696d756d5f62616c616e63656578745f64697370617463685f63616c6c6578745f726573746f72655f746f6578745f736372617463685f73697a656578745f736372617463685f726561646578745f736372617463685f77726974656578745f6465706f7369745f6576656e746578745f7365745f72656e745f616c6c6f77616e63656578745f72656e745f616c6c6f77616e63656578745f7072696e746c6e6578745f626c6f636b5f6e756d6265724e6f6e2d656d7074792066756e6374696f6e20626f647920657870656374656400a68111000f000000b581110002000000b7811100030000001881110030000000488111005e0000007a00000005000000617373657274696f6e206661696c65643a20636f6e746578742e6672616d655f737461636b2e69735f656d70747928292f686f6d652f616e6472652f2e636172676f2f72656769737472792f7372632f6769746875622e636f6d2d316563633632393964623965633832332f7761736d692d76616c69646174696f6e2d302e322e302f7372632f66756e632e7273417420696e737472756374696f6e202840293a2000008082110048000000b1010000230000008082110048000000b201000023000000598211001c0000006898110018000000e50300000d0000001082110049000000870200001d0000000000000000000000000000002f72757374632f316464313838343839313633366430656235313135376431333732333030373662636632303632372f7372632f6c6962636f72652f736c6963652f736f72742e7273617373657274696f6e206661696c65643a206d6964203c3d206c656e00000000000000000000002f72757374632f316464313838343839313633366430656235313135376431333732333030373662636632303632372f7372632f6c6962636f72652f736c6963652f6d6f642e727310821100490000009d0000003a0000001082110049000000a40000003000000052657475726e207479706573206c656e6774682073686f756c642062652030206f722031178511001e000000358511001f00000066756e6374696f6e5f73656374696f6e5f6c656e20213d20303b2071656466756e6374696f6e5f73656374696f6e5f6c656e20213d20303b2066756e6374696f6e5f73656374696f6e5f6c656e203d3d20636f64655f73656374696f6e5f6c656e3b207165640000fd8411001a000000d88411000a000000e28411001b00000073746172742066756e6374696f6e20657870656374656420746f20686176652074797065205b5d202d3e205b5d000000c784110011000000a78411002000000087841100200000005f841100280000007365676d656e74206f66667365742073686f756c642072657475726e2049333270617373697665206d656d6f7279207365676d656e747320617265206e6f7420737570706f727465647061737369766520656c656d656e74207365676d656e747320617265206e6f7420737570706f72746564746f6f206d616e79206d656d6f727920726567696f6e7320696e20696e6465782073706163653a20746f6f206d616e79207461626c657320696e20696e6465782073706163653a20747279696e6720746f20696d706f7274206d757461626c6520676c6f62616c206475706c6963617465206578706f72742046756e6374696f6e20232072656164696e672f76616c69646174696f6e206572726f723a204d697373696e6720626f647920666f722066756e6374696f6e206c656e677468206f662066756e6374696f6e2073656374696f6e206973202c207768696c65206c656e206f6620636f64652073656374696f6e2069732043616e2774206465636f6465207761736d20636f64654d6f64756c65206973206e6f742076616c69646d6f64756c65206465636c6172657320696e7465726e616c206d656d6f72796d756c7469706c65207461626c6573206465636c617265647461626c652065786365656473206d6178696d756d2073697a6520616c6c6f776564757365206f6620666c6f6174696e6720706f696e74207479706520696e2066756e6374696f6e20747970657320697320666f7262696464656e757365206f6620666c6f6174696e6720706f696e74207479706520696e206c6f63616c7320697320666f7262696464656e757365206f6620666c6f6174696e6720706f696e74207479706520696e20676c6f62616c7320697320666f7262696464656e67617320696e737472756d656e746174696f6e206661696c6564737461636b2068656967687420696e737472756d656e746174696f6e206661696c656463616c6c6465706c6f796465706c6f792066756e6374696f6e2069736e2774206578706f72746564756e6b6e6f776e206578706f72743a20657870656374696e67206f6e6c79206465706c6f7920616e642063616c6c2066756e6374696f6e7366756e6374696f6e206861732061206e6f6e2d6578697374656e7420747970656578706f72742072656665727320746f206e6f6e2d6578697374656e742066756e6374696f6e657870656374656420612066756e6374696f6e656e74727920706f696e7420706f696e747320746f20616e20696d706f727465642066756e6374696f6e656e74727920706f696e74206861732077726f6e67207369676e617475726563616c6c2066756e6374696f6e2069736e2774206578706f727465646572726f722073657269616c697a696e6720696e737472756d656e746564206d6f64756c6500000000000001000000020000000400000008000000100000002000000044656d6f6372616379205075626c696350726f70436f756e7444656d6f6372616379205265666572656e64756d436f756e7444656d6f6372616379204e65787454616c6c7944656d6f6372616379204c6173745461626c656457617345787465726e616c436f756e63696c20446573697265645365617473436f756e63696c20566f7465436f756e74436f756e63696c204e657874566f746572536574436f756e63696c20566f746572436f756e74436f756e63696c2043616e646964617465436f756e7454696d657374616d7020496e697469616c697a6564000000000000708911000e0000000000000080891100010000000000000000000000888911000100000000000000000000009089110006000000000000003897110000000000000000000000000098891100010000000000000000000000a0891100070000000000000038971100000000000000000000000000a889110001000000000000004e6577417574686f7269746965730000238a110023000000ff891100240000005061757365640000d889110027000000526573756d656400b0891100280000002043757272656e7420617574686f726974792073657420686173206265656e20726573756d65642e2043757272656e7420617574686f726974792073657420686173206265656e207061757365642e204e657720617574686f726974792073657420686173206265656e206170706c6965642e5665633c28417574686f7269747949642c20417574686f72697479576569676874293e4772616e64706146696e616c69747920417574686f7269746965734772616e64706146696e616c6974792043757272656e7453657449644772616e64706146696e616c69747920536574496453657373696f6e4f6666636861696e206572726f723a206665746368696e67206e6574776f726b207374617465206661696c6564214f6666636861696e206572726f723a207369676e696e67206661696c6564214f6666636861696e206572726f723a206465636f64696e6720576f726b6572537461747573206661696c6564214f6666636861696e206572726f723a207375626d697474696e67207472616e73616374696f6e206661696c656421496d4f6e6c696e65205265636569766564486561727462656174734f6666656e636573205265706f72747342794b696e64496e6465780000000000a48b11000700000000000000ac8b1100020000000000000000000000bc8b110002000000000000004f6666656e6365006f8c110004000000738c11000e000000cc8b110055000000218c11004e00000020546865726520697320616e206f6666656e6365207265706f72746564206f662074686520676976656e20606b696e64602068617070656e656420617420746865206073657373696f6e5f696e6465786020616e6420286b696e642d7370656369666963292074696d6520736c6f742e2054686973206576656e74206973206e6f74206465706f736974656420666f72206475706c696361746520736c61736865732e4b696e644f706171756554696d65536c6f7453657373696f6e2053746f72656452616e676553657373696f6e2043757272656e74496e64657853657373696f6e205175657565644368616e67656453657373696f6e2044697361626c656456616c696461746f72730000000000048d11000a00000000000000108d1100010000000000000000000000188d110002000000000000004e657753657373696f6e00009f8d11000c000000288d1100550000007d8d110022000000204e65772073657373696f6e206861732068617070656e65642e204e6f746520746861742074686520617267756d656e74206973207468652073657373696f6e20696e6465782c206e6f742074686520626c6f636b206e756d626572206173207468652074797065206d6967687420737567676573742e53657373696f6e496e64657800c08d110048000000a10a00000e000000000000002f72757374632f316464313838343839313633366430656235313135376431333732333030373662636632303632372f7372632f6c6962636f72652f736c6963652f6d6f642e72735374616b696e672056616c696461746f72436f756e745374616b696e67204d696e696d756d56616c696461746f72436f756e745374616b696e672043757272656e744572615374616b696e672043757272656e74457261537461727453657373696f6e496e6465785374616b696e672043757272656e74457261506f696e74734561726e65645374616b696e6720466f7263654572615374616b696e6720536c6173685265776172644672616374696f6e5374616b696e6720426f6e646564457261730000000000248f1100100000000000000038971100000000000000000000000000348f11000100000000000000000000003c8f11000f000000000000004c8f1100010000000000000000000000548f1100010000000000000045787472696e736963537563636573737e8f11002500000045787472696e7369634661696c656400718f11000d0000005c8f11001500000020416e2065787472696e736963206661696c65642e44697370617463684572726f7220416e2065787472696e73696320636f6d706c65746564207375636365737366756c6c792e52657175697265526f6f744f726967696e526571756972655369676e65644f726967696e426c6f636b46756c6c4261645369676e617475726543616e206e6f74206c6f6f6b7570526571756972654e6f4f726967696e53797374656d2045787472696e736963436f756e7453797374656d20416c6c45787472696e7369637357656967687453797374656d20416c6c45787472696e736963734c656e53797374656d204e6578745765696768744d756c7469706c69657253797374656d2045787472696e7369634461746153797374656d204576656e74436f756e7474696d737461703054696d657374616d7020696e686572656e742064617461206973206e6f742070726f76696465642e496e76616c69642074696d657374616d7020696e686572656e74206461746120656e636f64696e672e54696d657374616d702044696455706461746554726561737572792050726f706f73616c436f756e74547265617375727920417070726f76616c736d616b655f746f705f6672616d655f706f6c796d6f72706869632069732063616c6c6564207769746820656d707479206672616d6520737461636b0000db0000000c00000004000000dc000000746869732066756e6374696f6e2063616e27742062652063616c6c6564207769746820656d707479206672616d6520737461636b4d6973706c6163656420656c736520696e737472756374696f6e0000d8921100470000001f931100050000009c92110037000000d3921100050000006a921100170000006192110009000000b29411001400000049921100180000006192110009000000b294110014000000189211001d00000035921100130000004892110001000000546f6f206c61726765206d656d6f727920616c69676e6d656e7420325e20286578706563746564206174206d6f73742029547279696e6720746f2075706461746520676c6f62616c20206f66207479706520547279696e6720746f20757064617465206c6f63616c20416e795370656369666963330000000400000004000000d80000004c6162656c7320696e2062725f7461626c6520706f696e747320746f20626c6f636b206f6620646966666572656e742074797065733a2020616e6420496620626c6f636b20776974686f757420656c736520726571756972656420746f2068617665204e6f526573756c7420626c6f636b20747970652e204275742069742068617320207479706534931100180000004c9311000b000000556e657870656374656420737461636b20686569676874202c20657870656374656420547279696e6720746f2061636365737320706172656e74206672616d6520737461636b2076616c7565732e00009493110017000000ab9311001600000045787065637465642076616c7565206f66207479706520206f6e20746f70206f6620737461636b2e20476f7420000000cc93110007000000537461636b3a20000000010056941100240000002c94110006000000329411000e000000409411001600000008941100240000002c941100060000006d6178696d756d206d656d6f72792073697a65206d757374206265206174206d6f7374202070616765736d6178696d756d206c696d697420206973206c657373207468616e206d696e696d756d20696e697469616c206d656d6f72792073697a65206d757374206265206174206d6f73742000008c94110026000000b294110014000000547279696e6720746f20696e697469616c697a65207661726961626c65206f6620747970652020776974682076616c7565206f66207479706520496e69742065787072657373696f6e2073686f756c6420616c776179732062652077697468206c656e67746820324e6f6e20636f6e7374616e74206f70636f646520696e20696e697420657870725d951100070000006f951100220000005d95110007000000649511000b00000045787072657373696f6e20646f65736e277420656e647320776974682060656e6460206f70636f6465476c6f62616c20206973206d757461626c6520646f65736e277420657869737473206f72206e6f742079657420646566696e6564000000a495110010000000b49511000f0000004d656d6f727920617420696e6465782020646f65736e27742065786973747300d49511000f000000b49511000f0000005461626c6520617420696e6465782000f495110012000000b49511000f00000046756e6374696f6e20617420696e646578200000189611000e000000b49511000f0000005479706520617420696e6465782000008696110010000000b49511000f0000005896110010000000789611000e00000058961100100000006896110010000000457870656374656420676c6f62616c2020746f20626520696d6d757461626c6520746f206265206d757461626c65476c6f62616c20617420696e646578206e6f6e2d656d70747920737461636b2065787065637465640000c096110020000000e096110012000000747279696e6720746f206765742076616c756520617420706f736974696f6e20206f6e20737461636b206f662073697a6520636865636b656420636f75706c65206f66206c696e65732061626f7665001897110015000000657863656564656420737461636b206c696d69742000000038971100000000004572726f72000000330000000400000004000000dd0000004c6f63616c732072616e6765206e6f7420696e2033322d6269742072616e67658897110022000000aa97110015000000bf97110007000000547279696e6720746f20616363657373206c6f63616c207769746820696e64657820207768656e20746865726520617265206f6e6c7920206c6f63616c730000e09711002d0000000d9811000c0000001998110003000000617373657274696f6e206661696c65643a2060286c656674203d3d20726967687429600a20206c6566743a2060602c0a2072696768743a2060603a20249811003400000064657374696e6174696f6e20616e6420736f7572636520736c69636573206861766520646966666572656e74206c656e67746873689811001800000058080000090000007372632f6c6962636f72652f736c6963652f6d6f642e7273004180b1c6000b08000000000000000000bfbb03046e616d6501b6bb03a305000e6578745f626c616b65325f323536011f6578745f6765745f616c6c6f63617465645f6368696c645f73746f7261676502176578745f636c6561725f6368696c645f73746f7261676503146578745f6765745f73746f726167655f696e746f04166578745f6b696c6c5f6368696c645f73746f7261676505156578745f7365745f6368696c645f73746f7261676506196578745f6765745f616c6c6f63617465645f73746f72616765070f6578745f7365745f73746f72616765080c6578745f74776f785f31323809116578745f636c6561725f73746f726167650a126578745f737232353531395f7665726966790b0e6578745f7072696e745f757466380c0d6578745f7072696e745f6e756d0d166578745f6368696c645f73746f726167655f726f6f740e106578745f636c6561725f7072656669780f166578745f73616e64626f785f6d656d6f72795f6e6577101b6578745f73616e64626f785f6d656d6f72795f74656172646f776e11176578745f73616e64626f785f696e7374616e746961746512126578745f73616e64626f785f696e766f6b65131d6578745f73616e64626f785f696e7374616e63655f74656172646f776e14106578745f73746f726167655f726f6f7415186578745f73746f726167655f6368616e6765735f726f6f7416126578745f656432353531395f76657269667917166578745f73616e64626f785f6d656d6f72795f67657418166578745f73616e64626f785f6d656d6f72795f736574190d6578745f7072696e745f6865781a106578745f69735f76616c696461746f721b156578745f6c6f63616c5f73746f726167655f6765741c216578745f6c6f63616c5f73746f726167655f636f6d706172655f616e645f7365741d116578745f6e6574776f726b5f73746174651e106578745f737232353531395f7369676e1f166578745f7375626d69745f7472616e73616374696f6e20156578745f6c6f63616c5f73746f726167655f73657421146578745f656432353531395f67656e657261746522146578745f737232353531395f67656e657261746523236578745f626c616b65325f3235365f656e756d6572617465645f747269655f726f6f74240a6578745f6d616c6c6f6325086578745f6672656526176578745f737232353531395f7075626c69635f6b657973270b6578745f74776f785f3634280c5f5f727573745f616c6c6f63290a5f5f72675f616c6c6f632a0e5f5f727573745f6465616c6c6f632b0c5f5f72675f6465616c6c6f632c0e5f5f727573745f7265616c6c6f632d0c5f5f72675f7265616c6c6f632e135f5f727573745f616c6c6f635f7a65726f65642f115f5f72675f616c6c6f635f7a65726f65643009686173685f746573743134616c6c6f633a3a7261775f7665633a3a63617061636974795f6f766572666c6f773a3a68636164633139656466653965313035353229636f72653a3a70616e69636b696e673a3a70616e69633a3a68613237623135356231613762656131643325616c6c6f633a3a666d743a3a666f726d61743a3a68373139333337636638383237333534323436636f72653a3a70616e69636b696e673a3a70616e69635f626f756e64735f636865636b3a3a68613834643033333136663462356666613523636f72653a3a666d743a3a77726974653a3a68373639626232616366663461376638613648616c6c6f633a3a7261775f7665633a3a5261775665633c542c413e3a3a616c6c6f636174655f696e3a3a7b7b636c6f737572657d7d3a3a68303032666333346665303731316264303708727573745f6f6f6d382e636f72653a3a726573756c743a3a756e777261705f6661696c65643a3a6864623133323335353631653632346136393a3c266d7574205720617320636f72653a3a666d743a3a57726974653e3a3a77726974655f7374723a3a68633133653134623932623865333434343a3b3c266d7574205720617320636f72653a3a666d743a3a57726974653e3a3a77726974655f636861723a3a68373137336662316338303332343364353b3a3c266d7574205720617320636f72653a3a666d743a3a57726974653e3a3a77726974655f666d743a3a68613062616630316338386562366162373c34636f72653a3a736c6963653a3a736c6963655f696e6465785f6c656e5f6661696c3a3a68656632663938626564366266373533643d4e636f72653a3a666d743a3a6e756d3a3a696d703a3a3c696d706c20636f72653a3a666d743a3a446973706c617920666f72207533323e3a3a666d743a3a68303438303937613766373038326163303e2d636f72653a3a70616e69636b696e673a3a70616e69635f666d743a3a68346637396263373939663330393733323f2f636f72653a3a666d743a3a6e756d3a3a696d703a3a666d745f7536343a3a68383932326134393263623337346536624011727573745f626567696e5f756e77696e6441313c5420617320636f72653a3a616e793a3a416e793e3a3a747970655f69643a3a68303837626662333038396434323234304235636f72653a3a666d743a3a466f726d61747465723a3a7061645f696e74656772616c3a3a68313538353734313262386634366265634343636f72653a3a666d743a3a466f726d61747465723a3a7061645f696e74656772616c3a3a77726974655f7072656669783a3a68363936303565363538343765653566304436636f72653a3a736c6963653a3a736c6963655f696e6465785f6f726465725f6661696c3a3a6835353833396665343434333633396662452c636f72653a3a666d743a3a466f726d61747465723a3a7061643a3a6862663133663132313734343633363530462e636f72653a3a7374723a3a736c6963655f6572726f725f6661696c3a3a686237366535353838326633366137346647323c265420617320636f72653a3a666d743a3a446973706c61793e3a3a666d743a3a6830303136373764333333316431623262484a3c636f72653a3a6f70733a3a72616e67653a3a52616e67653c4964783e20617320636f72653a3a666d743a3a44656275673e3a3a666d743a3a686339373033363631643132393261316649323c6368617220617320636f72653a3a666d743a3a44656275673e3a3a666d743a3a68303731343665363835653563656332624a3d636f72653a3a756e69636f64653a3a626f6f6c5f747269653a3a426f6f6c547269653a3a6c6f6f6b75703a3a68616234336463613764383766373731634b49636f72653a3a666d743a3a6e756d3a3a3c696d706c20636f72653a3a666d743a3a446562756720666f72207573697a653e3a3a666d743a3a68373032373631646266343866333635364c34636f72653a3a666d743a3a417267756d656e7456313a3a73686f775f7573697a653a3a68303764326632623133316361643036374d453c636f72653a3a63656c6c3a3a426f72726f774572726f7220617320636f72653a3a666d743a3a44656275673e3a3a666d743a3a68326433626561393162376638333331354e483c636f72653a3a63656c6c3a3a426f72726f774d75744572726f7220617320636f72653a3a666d743a3a44656275673e3a3a666d743a3a68383634373335313833373766363262364f323c265420617320636f72653a3a666d743a3a446973706c61793e3a3a666d743a3a6836323735643962386134343631633938502e636f72653a3a6f7074696f6e3a3a6578706563745f6661696c65643a3a683163333163613936623063653034653051303c265420617320636f72653a3a666d743a3a44656275673e3a3a666d743a3a6864396534343966646163316334353532522e636f72653a3a736c6963653a3a6d656d6368723a3a6d656d6368723a3a6839323166353536393537323230396564538001636f72653a3a7374723a3a7472616974733a3a3c696d706c20636f72653a3a736c6963653a3a536c696365496e6465783c7374723e20666f7220636f72653a3a6f70733a3a72616e67653a3a52616e67653c7573697a653e3e3a3a696e6465783a3a7b7b636c6f737572657d7d3a3a68376561353565643561313134353233665427636f72653a3a7374723a3a66726f6d5f757466383a3a68393936353463313839323463653036345530636f72653a3a7074723a3a7265616c5f64726f705f696e5f706c6163653a3a683566363963313432356330613037353356533c636f72653a3a666d743a3a6275696c646572733a3a5061644164617074657220617320636f72653a3a666d743a3a57726974653e3a3a77726974655f7374723a3a6865393736373038366566313830663239572f636f72653a3a666d743a3a57726974653a3a77726974655f636861723a3a6835376138336636353030656231663365582e636f72653a3a666d743a3a57726974653a3a77726974655f666d743a3a6835616339306139346131333230656233593a3c266d7574205720617320636f72653a3a666d743a3a57726974653e3a3a77726974655f7374723a3a68306138363933663139633766366666665a3b3c266d7574205720617320636f72653a3a666d743a3a57726974653e3a3a77726974655f636861723a3a68636638393338356535396637623637615b3a3c266d7574205720617320636f72653a3a666d743a3a57726974653e3a3a77726974655f666d743a3a68383637616663663734396563326230325c3a636f72653a3a666d743a3a6275696c646572733a3a44656275675374727563743a3a6669656c643a3a68646430303731316136373965613430345d39636f72653a3a666d743a3a6275696c646572733a3a44656275675475706c653a3a6669656c643a3a68393065333464346262613566643437365e443c636f72653a3a666d743a3a417267756d656e747320617320636f72653a3a666d743a3a446973706c61793e3a3a666d743a3a68626634386164393337636464313931615f313c73747220617320636f72653a3a666d743a3a44656275673e3a3a666d743a3a686637313733623038663233376563326360303c265420617320636f72653a3a666d743a3a44656275673e3a3a666d743a3a686530393630373933333765373636363961303c265420617320636f72653a3a666d743a3a44656275673e3a3a666d743a3a683931653862363165666339613332346262423c636f72653a3a7374723a3a557466384572726f7220617320636f72653a3a666d743a3a44656275673e3a3a666d743a3a686166363337373838663261376137313063303c265420617320636f72653a3a666d743a3a44656275673e3a3a666d743a3a6833396433666631363039386537383237643e3c636f72653a3a666d743a3a4572726f7220617320636f72653a3a666d743a3a44656275673e3a3a666d743a3a686464366234323235356566653732333065383c6c6f673a3a4e6f704c6f67676572206173206c6f673a3a4c6f673e3a3a656e61626c65643a3a686365346336373635363834626464353866343c6c6f673a3a4e6f704c6f67676572206173206c6f673a3a4c6f673e3a3a6c6f673a3a686463373536653930643966306231373167363c6c6f673a3a4e6f704c6f67676572206173206c6f673a3a4c6f673e3a3a666c7573683a3a683533303838393235643430663439313868693c636f72653a3a697465723a3a61646170746572733a3a46696c7465724d61703c492c463e20617320636f72653a3a697465723a3a7472616974733a3a6974657261746f723a3a4974657261746f723e3a3a6e6578743a3a6838653863316664626539333838346163694b3c616c6c6f633a3a7665633a3a496e746f497465723c543e20617320636f72653a3a6f70733a3a64726f703a3a44726f703e3a3a64726f703a3a68663530663164396638316533336133346a30636f72653a3a7074723a3a7265616c5f64726f705f696e5f706c6163653a3a68323434346236303933336133646533306b7d7061726974795f7363616c655f636f6465633a3a636f6465633a3a696e6e65725f7475706c655f696d706c3a3a3c696d706c207061726974795f7363616c655f636f6465633a3a636f6465633a3a4465636f646520666f72202851302c205230293e3a3a6465636f64653a3a68333464663538646264396436366233626c6b3c7061726974795f7363616c655f636f6465633a3a636f6d706163743a3a436f6d706163743c7533323e206173207061726974795f7363616c655f636f6465633a3a636f6465633a3a4465636f64653e3a3a6465636f64653a3a68323661353531326466306130366630326d543c616c6c6f633a3a7665633a3a5665633c543e206173207061726974795f7363616c655f636f6465633a3a636f6465633a3a4465636f64653e3a3a6465636f64653a3a68376638333330366130393338636466636e2d616c6c6f633a3a7665633a3a5665633c543e3a3a72657461696e3a3a68356638643836666366306661623534356f443c616c6c6f633a3a7665633a3a5665633c543e20617320636f72653a3a636c6f6e653a3a436c6f6e653e3a3a636c6f6e653a3a683032363437663936366662386566376170443c616c6c6f633a3a7665633a3a5665633c543e20617320636f72653a3a636c6f6e653a3a436c6f6e653e3a3a636c6f6e653a3a683339393163366632303237333937323471443c616c6c6f633a3a7665633a3a5665633c543e20617320636f72653a3a636c6f6e653a3a436c6f6e653e3a3a636c6f6e653a3a686566656166643264633364616137393472463c616c6c6f633a3a7665633a3a5665633c543e20617320636f72653a3a6f70733a3a64726f703a3a44726f703e3a3a64726f703a3a683162353632313133646564343136383473543c616c6c6f633a3a7665633a3a5665633c543e206173207061726974795f7363616c655f636f6465633a3a636f6465633a3a4465636f64653e3a3a6465636f64653a3a683039636136373637663535386430666574543c616c6c6f633a3a7665633a3a5665633c543e206173207061726974795f7363616c655f636f6465633a3a636f6465633a3a4465636f64653e3a3a6465636f64653a3a683134393565336533346436663466623675543c616c6c6f633a3a7665633a3a5665633c543e206173207061726974795f7363616c655f636f6465633a3a636f6465633a3a4465636f64653e3a3a6465636f64653a3a683136303731343633646432653861656276543c616c6c6f633a3a7665633a3a5665633c543e206173207061726974795f7363616c655f636f6465633a3a636f6465633a3a4465636f64653e3a3a6465636f64653a3a683262653166343131363934633333326577543c616c6c6f633a3a7665633a3a5665633c543e206173207061726974795f7363616c655f636f6465633a3a636f6465633a3a4465636f64653e3a3a6465636f64653a3a683266353961316562306564306263356578543c616c6c6f633a3a7665633a3a5665633c543e206173207061726974795f7363616c655f636f6465633a3a636f6465633a3a4465636f64653e3a3a6465636f64653a3a683266666136396263346264313332613379543c616c6c6f633a3a7665633a3a5665633c543e206173207061726974795f7363616c655f636f6465633a3a636f6465633a3a4465636f64653e3a3a6465636f64653a3a68343634633337336136666331646362347a9f013c73725f7072696d6974697665733a3a67656e657269633a3a756e636865636b65645f65787472696e7369633a3a556e636865636b656445787472696e7369633c416464726573732c43616c6c2c5369676e61747572652c45787472613e206173207061726974795f7363616c655f636f6465633a3a636f6465633a3a4465636f64653e3a3a6465636f64653a3a68383962656633636262333533326338617b543c616c6c6f633a3a7665633a3a5665633c543e206173207061726974795f7363616c655f636f6465633a3a636f6465633a3a4465636f64653e3a3a6465636f64653a3a68353335363332653631633034346136637c543c616c6c6f633a3a7665633a3a5665633c543e206173207061726974795f7363616c655f636f6465633a3a636f6465633a3a4465636f64653e3a3a6465636f64653a3a68383862356330343234613539346162647d543c616c6c6f633a3a7665633a3a5665633c543e206173207061726974795f7363616c655f636f6465633a3a636f6465633a3a4465636f64653e3a3a6465636f64653a3a68393130613036323863303037356534637e543c616c6c6f633a3a7665633a3a5665633c543e206173207061726974795f7363616c655f636f6465633a3a636f6465633a3a4465636f64653e3a3a6465636f64653a3a68613962383762393439623233386535347f753c73725f7072696d6974697665733a3a67656e657269633a3a6865616465723a3a4865616465723c4e756d6265722c486173683e206173207061726974795f7363616c655f636f6465633a3a636f6465633a3a4465636f64653e3a3a6465636f64653a3a68316665643862623861336335356666388001543c616c6c6f633a3a7665633a3a5665633c543e206173207061726974795f7363616c655f636f6465633a3a636f6465633a3a4465636f64653e3a3a6465636f64653a3a686337333532366633613336356262663281017f6e6f64655f72756e74696d653a3a5f494d504c5f4445434f44455f464f525f43616c6c3a3a3c696d706c207061726974795f7363616c655f636f6465633a3a636f6465633a3a4465636f646520666f72206e6f64655f72756e74696d653a3a43616c6c3e3a3a6465636f64653a3a68333130306265306638643432366337618201543c616c6c6f633a3a7665633a3a5665633c543e206173207061726974795f7363616c655f636f6465633a3a636f6465633a3a4465636f64653e3a3a6465636f64653a3a68646332643431646231373737373966618301513c616c6c6f633a3a7665633a3a5665633c543e20617320616c6c6f633a3a7665633a3a53706563457874656e643c542c493e3e3a3a66726f6d5f697465723a3a68333930383730653562343365626334618401513c616c6c6f633a3a7665633a3a5665633c543e20617320616c6c6f633a3a7665633a3a53706563457874656e643c542c493e3e3a3a66726f6d5f697465723a3a68346235353034353038313230323761658501693c636f72653a3a697465723a3a61646170746572733a3a46696c7465724d61703c492c463e20617320636f72653a3a697465723a3a7472616974733a3a6974657261746f723a3a4974657261746f723e3a3a6e6578743a3a6864386638303832353262313639643938860168636f72653a3a6f70733a3a66756e6374696f6e3a3a696d706c733a3a3c696d706c20636f72653a3a6f70733a3a66756e6374696f6e3a3a466e4d75743c413e20666f7220266d757420463e3a3a63616c6c5f6d75743a3a68616338303437376531623137353030658701513c616c6c6f633a3a7665633a3a5665633c543e20617320616c6c6f633a3a7665633a3a53706563457874656e643c542c493e3e3a3a66726f6d5f697465723a3a68376163313434383630363561393861358801513c616c6c6f633a3a7665633a3a5665633c543e20617320616c6c6f633a3a7665633a3a53706563457874656e643c542c493e3e3a3a66726f6d5f697465723a3a6838646539353166376338633363373834890130636f72653a3a7074723a3a7265616c5f64726f705f696e5f706c6163653a3a68303032396532383461626336653161348a01793c73726d6c5f636f6e7472616374733a3a6163636f756e745f64623a3a4469726563744163636f756e7444622061732073726d6c5f636f6e7472616374733a3a6163636f756e745f64623a3a4163636f756e7444623c543e3e3a3a6765745f73746f726167653a3a68346366353833643730356531323330398b017b3c73726d6c5f636f6e7472616374733a3a6163636f756e745f64623a3a4469726563744163636f756e7444622061732073726d6c5f636f6e7472616374733a3a6163636f756e745f64623a3a4163636f756e7444623c543e3e3a3a6765745f636f64655f686173683a3a68373233336337366666386563623337638c017273726d6c5f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a6d61703a3a3c696d706c2073726d6c5f737570706f72743a3a73746f726167653a3a53746f726167654d61703c4b2c563e20666f7220473e3a3a6765743a3a68633632613631323832356230656538308d0180013c73726d6c5f636f6e7472616374733a3a6163636f756e745f64623a3a4469726563744163636f756e7444622061732073726d6c5f636f6e7472616374733a3a6163636f756e745f64623a3a4163636f756e7444623c543e3e3a3a6765745f72656e745f616c6c6f77616e63653a3a68363336343837393532646263326661308e017d3c73726d6c5f636f6e7472616374733a3a6163636f756e745f64623a3a4469726563744163636f756e7444622061732073726d6c5f636f6e7472616374733a3a6163636f756e745f64623a3a4163636f756e7444623c543e3e3a3a636f6e74726163745f6578697374733a3a68626433333036616562666336626362358f01463c58206173207061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f64653e3a3a656e636f64655f746f3a3a68653566313862323833376430363465349001793c73726d6c5f636f6e7472616374733a3a6163636f756e745f64623a3a4469726563744163636f756e7444622061732073726d6c5f636f6e7472616374733a3a6163636f756e745f64623a3a4163636f756e7444623c543e3e3a3a6765745f62616c616e63653a3a6834396339306230636239366136303838910185013c73726d6c5f62616c616e6365733a3a4d6f64756c653c542c493e2061732073726d6c5f737570706f72743a3a7472616974733a3a43757272656e63793c3c542061732073726d6c5f73797374656d3a3a54726169743e3a3a4163636f756e7449643e3e3a3a667265655f62616c616e63653a3a68383966356130363566393565373865319201743c73726d6c5f636f6e7472616374733a3a6163636f756e745f64623a3a4469726563744163636f756e7444622061732073726d6c5f636f6e7472616374733a3a6163636f756e745f64623a3a4163636f756e7444623c543e3e3a3a636f6d6d69743a3a68643530643334363435306561343137639301723c616c6c6f633a3a636f6c6c656374696f6e733a3a62747265653a3a6d61703a3a496e746f497465723c4b2c563e20617320636f72653a3a697465723a3a7472616974733a3a6974657261746f723a3a4974657261746f723e3a3a6e6578743a3a683833306434623064366665663163303194018d013c73726d6c5f62616c616e6365733a3a4d6f64756c653c542c493e2061732073726d6c5f737570706f72743a3a7472616974733a3a43757272656e63793c3c542061732073726d6c5f73797374656d3a3a54726169743e3a3a4163636f756e7449643e3e3a3a6d616b655f667265655f62616c616e63655f62653a3a68386234623564326136633936643835629501613c616c6c6f633a3a636f6c6c656374696f6e733a3a62747265653a3a6d61703a3a496e746f497465723c4b2c563e20617320636f72653a3a6f70733a3a64726f703a3a44726f703e3a3a64726f703a3a683131363062303861386164636233646296017573726d6c5f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a6d61703a3a3c696d706c2073726d6c5f737570706f72743a3a73746f726167653a3a53746f726167654d61703c4b2c563e20666f7220473e3a3a72656d6f76653a3a6866633362376362623662393231306232970191013c73726d6c5f636f6e7472616374733a3a54726965496446726f6d506172656e74436f756e7465723c543e2061732073726d6c5f636f6e7472616374733a3a54726965496447656e657261746f723c3c542061732073726d6c5f73797374656d3a3a54726169743e3a3a4163636f756e7449643e3e3a3a747269655f69643a3a686161356339313864623663376232333398013773726d6c5f73797374656d3a3a4d6f64756c653c543e3a3a626c6f636b5f6e756d6265723a3a68653533383938356333383936373334639901723c616c6c6f633a3a636f6c6c656374696f6e733a3a62747265653a3a6d61703a3a496e746f497465723c4b2c563e20617320636f72653a3a697465723a3a7472616974733a3a6974657261746f723a3a4974657261746f723e3a3a6e6578743a3a68363064383435646236353836623862669a017573726d6c5f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a6d61703a3a3c696d706c2073726d6c5f737570706f72743a3a73746f726167653a3a53746f726167654d61703c4b2c563e20666f7220473e3a3a696e736572743a3a68383232653933386530363765323330359b01613c616c6c6f633a3a636f6c6c656374696f6e733a3a62747265653a3a6d61703a3a496e746f497465723c4b2c563e20617320636f72653a3a6f70733a3a64726f703a3a44726f703e3a3a64726f703a3a68373635323739333664343963626361349c017773726d6c5f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a76616c75653a3a3c696d706c2073726d6c5f737570706f72743a3a73746f726167653a3a53746f7261676556616c75653c543e20666f7220473e3a3a6d75746174653a3a68363839653731333562643437646538339d017773726d6c5f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a76616c75653a3a3c696d706c2073726d6c5f737570706f72743a3a73746f726167653a3a53746f7261676556616c75653c543e20666f7220473e3a3a6d75746174653a3a68323138376639326134336161343632319e016b3c7061726974795f7363616c655f636f6465633a3a636f6d706163743a3a436f6d706163743c7536343e206173207061726974795f7363616c655f636f6465633a3a636f6465633a3a4465636f64653e3a3a6465636f64653a3a68616238326334383138373537326534309f016c3c7061726974795f7363616c655f636f6465633a3a636f6d706163743a3a436f6d706163743c753132383e206173207061726974795f7363616c655f636f6465633a3a636f6465633a3a4465636f64653e3a3a6465636f64653a3a6830386561633136356661396637393538a001713c7061726974795f7363616c655f636f6465633a3a636f6d706163743a3a436f6d706163745265663c7533323e206173207061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f64653e3a3a656e636f64655f746f3a3a6864653530373162386130653734333633a101713c7061726974795f7363616c655f636f6465633a3a636f6d706163743a3a436f6d706163745265663c7536343e206173207061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f64653e3a3a656e636f64655f746f3a3a6835653932376533663634393764666562a201303c265420617320636f72653a3a666d743a3a44656275673e3a3a666d743a3a6836633166636332326337613565393130a301723c7061726974795f7363616c655f636f6465633a3a636f6d706163743a3a436f6d706163745265663c753132383e206173207061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f64653e3a3a656e636f64655f746f3a3a6865323831616332613336303138303565a401303c265420617320636f72653a3a666d743a3a44656275673e3a3a666d743a3a6861393633376463316164363838343137a501783c73726d6c5f696e64696365733a3a616464726573733a3a416464726573733c4163636f756e7449642c4163636f756e74496e6465783e206173207061726974795f7363616c655f636f6465633a3a636f6465633a3a4465636f64653e3a3a6465636f64653a3a6837313537343363326237386233626138a6017b3c73726d6c5f696e64696365733a3a616464726573733a3a416464726573733c4163636f756e7449642c4163636f756e74496e6465783e206173207061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f64653e3a3a656e636f64655f746f3a3a6832626663373164323632393930636138a7017d3c73726d6c5f636f6e7472616374733a3a6163636f756e745f64623a3a4f7665726c61794163636f756e7444623c543e2061732073726d6c5f636f6e7472616374733a3a6163636f756e745f64623a3a4163636f756e7444623c543e3e3a3a6765745f73746f726167653a3a6839346337326433373239326630393437a80184013c73726d6c5f636f6e7472616374733a3a6163636f756e745f64623a3a4f7665726c61794163636f756e7444623c543e2061732073726d6c5f636f6e7472616374733a3a6163636f756e745f64623a3a4163636f756e7444623c543e3e3a3a6765745f72656e745f616c6c6f77616e63653a3a6838626464373063336465333638653932a901cd0173726d6c5f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a6c696e6b65645f6d61703a3a5f494d504c5f454e434f44455f464f525f4c696e6b6167653a3a3c696d706c207061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f646520666f722073726d6c5f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a6c696e6b65645f6d61703a3a4c696e6b6167653c4b65793e3e3a3a656e636f64655f746f3a3a6835333330396563306462363039336239aa01cd0173726d6c5f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a6c696e6b65645f6d61703a3a5f494d504c5f454e434f44455f464f525f4c696e6b6167653a3a3c696d706c207061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f646520666f722073726d6c5f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a6c696e6b65645f6d61703a3a4c696e6b6167653c4b65793e3e3a3a656e636f64655f746f3a3a6865393330353763396263376337323461ab0184013c73726d6c5f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a6c696e6b65645f6d61703a3a456e756d657261746f723c4b2c562c473e20617320636f72653a3a697465723a3a7472616974733a3a6974657261746f723a3a4974657261746f723e3a3a6e6578743a3a6838643238373730663035386262636565ac016f73726d6c5f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a6c696e6b65645f6d61703a3a53746f726167654c696e6b65644d61703a3a73746f726167655f6c696e6b65645f6d61705f66696e616c5f6b65793a3a6838383431306663323634343831633764ad0184013c73726d6c5f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a6c696e6b65645f6d61703a3a456e756d657261746f723c4b2c562c473e20617320636f72653a3a697465723a3a7472616974733a3a6974657261746f723a3a4974657261746f723e3a3a6e6578743a3a6865386566633638356136363861353930ae016f73726d6c5f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a6c696e6b65645f6d61703a3a53746f726167654c696e6b65644d61703a3a73746f726167655f6c696e6b65645f6d61705f66696e616c5f6b65793a3a6835313634396637613236326262653938af0184013c73726d6c5f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a6c696e6b65645f6d61703a3a456e756d657261746f723c4b2c562c473e20617320636f72653a3a697465723a3a7472616974733a3a6974657261746f723a3a4974657261746f723e3a3a6e6578743a3a6866396432363165633964396131623766b0016f73726d6c5f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a6c696e6b65645f6d61703a3a53746f726167654c696e6b65644d61703a3a73746f726167655f6c696e6b65645f6d61705f66696e616c5f6b65793a3a6835356235363734623230613437653865b1017d7061726974795f7363616c655f636f6465633a3a636f6465633a3a696e6e65725f7475706c655f696d706c3a3a3c696d706c207061726974795f7363616c655f636f6465633a3a636f6465633a3a4465636f646520666f72202851302c205230293e3a3a6465636f64653a3a6865373864623462383164613762393330b2013d73726d6c5f6f6666656e6365733a3a4d6f64756c653c543e3a3a73746f726167655f6d657461646174613a3a6836363030663338636433666133303631b301743c73726d6c5f6f6666656e6365733a3a5f5f476574427974655374727563745265706f72747342794b696e64496e6465783c543e2061732073726d6c5f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6831636238373936303566366365663164b4016c3c7061726974795f7363616c655f636f6465633a3a636f6d706163743a3a436f6d706163743c543e206173207061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f64653e3a3a656e636f64655f746f3a3a6832333939613538336430656438336234b5014d73726d6c5f636f6e7472616374733a3a657865633a3a457865637574696f6e436f6e746578743c542c562c4c3e3a3a696e7374616e74696174653a3a6836623966633736373531646261363534b60181013c73726d6c5f636f6e7472616374733a3a6163636f756e745f64623a3a4f7665726c61794163636f756e7444623c543e2061732073726d6c5f636f6e7472616374733a3a6163636f756e745f64623a3a4163636f756e7444623c543e3e3a3a636f6e74726163745f6578697374733a3a6836616130363564356539663732313132b7014b616c6c6f633a3a636f6c6c656374696f6e733a3a62747265653a3a6d61703a3a566163616e74456e7472793c4b2c563e3a3a696e736572743a3a6861613261623366303331336232356636b8013173726d6c5f636f6e7472616374733a3a657865633a3a7472616e736665723a3a6837373362356236396662646161313137b9013973726d6c5f636f6e7472616374733a3a7761736d3a3a636f64655f63616368653a3a6c6f61643a3a6866323337613535386232383836373039ba01593c73726d6c5f636f6e7472616374733a3a7761736d3a3a5761736d566d2061732073726d6c5f636f6e7472616374733a3a657865633a3a566d3c543e3e3a3a657865637574653a3a6831333937356561393739303766376236bb01783c73726d6c5f636f6e7472616374733a3a6163636f756e745f64623a3a4f7665726c61794163636f756e7444623c543e2061732073726d6c5f636f6e7472616374733a3a6163636f756e745f64623a3a4163636f756e7444623c543e3e3a3a636f6d6d69743a3a6836616339326635393738306465653137bc018c013c73726d6c5f62616c616e6365733a3a4d6f64756c653c542c493e2061732073726d6c5f737570706f72743a3a7472616974733a3a43757272656e63793c3c542061732073726d6c5f73797374656d3a3a54726169743e3a3a4163636f756e7449643e3e3a3a656e737572655f63616e5f77697468647261773a3a6839626535636564373733626261363035bd0148616c6c6f633a3a636f6c6c656374696f6e733a3a62747265653a3a6d61703a3a42547265654d61703c4b2c563e3a3a696e736572743a3a6832343561663334383230376130353433be0130636f72653a3a7074723a3a7265616c5f64726f705f696e5f706c6163653a3a6835323765316362333634383130643564bf017f3c73726d6c5f636f6e7472616374733a3a6163636f756e745f64623a3a4f7665726c61794163636f756e7444623c543e2061732073726d6c5f636f6e7472616374733a3a6163636f756e745f64623a3a4163636f756e7444623c543e3e3a3a6765745f636f64655f686173683a3a6866353465663532326365346138316461c0017d3c73726d6c5f636f6e7472616374733a3a6163636f756e745f64623a3a4f7665726c61794163636f756e7444623c543e2061732073726d6c5f636f6e7472616374733a3a6163636f756e745f64623a3a4163636f756e7444623c543e3e3a3a6765745f62616c616e63653a3a6831313131303862313035626263336366c1014673726d6c5f636f6e7472616374733a3a657865633a3a457865637574696f6e436f6e746578743c542c562c4c3e3a3a63616c6c3a3a6839353866323730643039323832636563c2014273726d6c5f636f6e7472616374733a3a72656e743a3a7472795f65766963745f6f725f616e645f7061795f72656e743a3a6863336336633731646632616562646432c3013c7061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f64653a3a656e636f64653a3a6864633565333763353634646262616336c4013f7061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f64653a3a656e636f64655f746f3a3a6831613165646131353962323138616264c501c7013c73726d6c5f6f6666656e6365733a3a4d6f64756c653c543e2061732073725f7374616b696e675f7072696d6974697665733a3a6f6666656e63653a3a5265706f72744f6666656e63653c3c542061732073726d6c5f73797374656d3a3a54726169743e3a3a4163636f756e7449642c3c542061732073726d6c5f6f6666656e6365733a3a54726169743e3a3a4964656e74696669636174696f6e5475706c652c4f3e3e3a3a7265706f72745f6f6666656e63653a3a6832383939313265386363346166666539c6014b3c5b543b205f5d206173207061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f64653e3a3a656e636f64655f746f3a3a6832633136623336633063663237386639c7016f73726d6c5f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a646f75626c655f6d61703a3a53746f72616765446f75626c654d61703a3a73746f726167655f646f75626c655f6d61705f66696e616c5f6b65793a3a6838636333303466313030626264666365c801437061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f64653a3a7573696e675f656e636f6465643a3a6861623165653031323634626232353937c90141616c6c6f633a3a636f6c6c656374696f6e733a3a62747265653a3a7365617263683a3a7365617263685f747265653a3a6834353339376134376233366633383934ca01613c616c6c6f633a3a636f6c6c656374696f6e733a3a62747265653a3a6d61703a3a42547265654d61703c4b2c563e20617320636f72653a3a6f70733a3a64726f703a3a44726f703e3a3a64726f703a3a6863623836653530643234616238333461cb01437061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f64653a3a7573696e675f656e636f6465643a3a6831633062376138643436393335636534cc014073726d6c5f73797374656d3a3a4d6f64756c653c543e3a3a6465706f7369745f6576656e745f696e64657865643a3a6834313461616236326136396366376638cd0134636f72653a3a736c6963653a3a3c696d706c205b545d3e3a3a636f6e7461696e733a3a6863616665643431346630633236373166ce013673726d6c5f73797374656d3a3a4d6f64756c653c543e3a3a6465706f7369745f6c6f673a3a6865613866373434663735656363653135cf017e3c73726d6c5f62616c616e6365733a3a4d6f64756c653c542c493e2061732073726d6c5f737570706f72743a3a7472616974733a3a43757272656e63793c3c542061732073726d6c5f73797374656d3a3a54726169743e3a3a4163636f756e7449643e3e3a3a736c6173683a3a6866643562376165396361393035363832d00189013c73726d6c5f62616c616e6365733a3a4d6f64756c653c542c493e2061732073726d6c5f737570706f72743a3a7472616974733a3a43757272656e63793c3c542061732073726d6c5f73797374656d3a3a54726169743e3a3a4163636f756e7449643e3e3a3a6465706f7369745f6372656174696e673a3a6836373839333262303737623239363337d1015373725f7072696d6974697665733a3a50657262696c6c3a3a66726f6d5f726174696f6e616c5f617070726f78696d6174696f6e3a3a7b7b636c6f737572657d7d3a3a6838323439353335646130363233616166d2015373725f7072696d6974697665733a3a50657262696c6c3a3a66726f6d5f726174696f6e616c5f617070726f78696d6174696f6e3a3a7b7b636c6f737572657d7d3a3a6833333938303938366437323438633665d3014b73725f7072696d6974697665733a3a7472616974733a3a4163636f756e744964436f6e76657273696f6e3a3a696e746f5f6163636f756e743a3a6839633438346130663064333336626130d4019a0173726d6c5f7374616b696e673a3a5f494d504c5f4445434f44455f464f525f4578706f737572653a3a3c696d706c207061726974795f7363616c655f636f6465633a3a636f6465633a3a4465636f646520666f722073726d6c5f7374616b696e673a3a4578706f737572653c4163636f756e7449642c42616c616e63653e3e3a3a6465636f64653a3a6837393935333333636162333938616263d501483c73726d6c5f6f6666656e6365733a3a43616c6c3c543e20617320636f72653a3a636c6f6e653a3a436c6f6e653e3a3a636c6f6e653a3a6837303239393466376333643337643031d6015c3c73726d6c5f6f6666656e6365733a3a43616c6c3c543e2061732073725f7072696d6974697665733a3a7472616974733a3a446973706174636861626c653e3a3a64697370617463683a3a6832386366306335363565653635396665d701703c7061726974795f7363616c655f636f6465633a3a636f6d706163743a3a436f6d706163743c543e206173207061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f64653e3a3a7573696e675f656e636f6465643a3a6830373463363933373136623438643830d801303c265420617320636f72653a3a666d743a3a44656275673e3a3a666d743a3a6830313735343962623362373765363161d901406e6f64655f72756e74696d653a3a52756e74696d653a3a5f5f6d6f64756c655f6576656e74735f73797374656d3a3a6838353435663263626138613161386365da01416e6f64655f72756e74696d653a3a52756e74696d653a3a5f5f6d6f64756c655f6576656e74735f696e64696365733a3a6839656632383931386338356161373231db01426e6f64655f72756e74696d653a3a52756e74696d653a3a5f5f6d6f64756c655f6576656e74735f62616c616e6365733a3a6835613762623764323431326363363930dc01416e6f64655f72756e74696d653a3a52756e74696d653a3a5f5f6d6f64756c655f6576656e74735f7374616b696e673a3a6861386530623037316263646566366661dd01416e6f64655f72756e74696d653a3a52756e74696d653a3a5f5f6d6f64756c655f6576656e74735f73657373696f6e3a3a6837336536323763303639326138663139de01436e6f64655f72756e74696d653a3a52756e74696d653a3a5f5f6d6f64756c655f6576656e74735f64656d6f63726163793a3a6863633261336536646130336365323230df014e6e6f64655f72756e74696d653a3a52756e74696d653a3a5f5f6d6f64756c655f6576656e74735f636f6c6c6563746976655f496e7374616e6365313a3a6836656163653863306136333236353131e001436e6f64655f72756e74696d653a3a52756e74696d653a3a5f5f6d6f64756c655f6576656e74735f656c656374696f6e733a3a6832623263323461633638353163356334e1014e6e6f64655f72756e74696d653a3a52756e74696d653a3a5f5f6d6f64756c655f6576656e74735f6d656d626572736869705f496e7374616e6365313a3a6863616165316234326264323238666536e201416e6f64655f72756e74696d653a3a52756e74696d653a3a5f5f6d6f64756c655f6576656e74735f6772616e6470613a3a6834613630316463343234393033386164e301426e6f64655f72756e74696d653a3a52756e74696d653a3a5f5f6d6f64756c655f6576656e74735f74726561737572793a3a6863333761653137623166353232663861e401436e6f64655f72756e74696d653a3a52756e74696d653a3a5f5f6d6f64756c655f6576656e74735f636f6e7472616374733a3a6865343131326666386464386131633438e5013e6e6f64655f72756e74696d653a3a52756e74696d653a3a5f5f6d6f64756c655f6576656e74735f7375646f3a3a6861316434653964343230393738353039e601436e6f64655f72756e74696d653a3a52756e74696d653a3a5f5f6d6f64756c655f6576656e74735f696d5f6f6e6c696e653a3a6836356133633932336635663033326535e701426e6f64655f72756e74696d653a3a52756e74696d653a3a5f5f6d6f64756c655f6576656e74735f6f6666656e6365733a3a6862633937306433383331323331343235e8018d016e6f64655f72756e74696d653a3a5f494d504c5f4445434f44455f464f525f53657373696f6e4b6579733a3a3c696d706c207061726974795f7363616c655f636f6465633a3a636f6465633a3a4465636f646520666f72206e6f64655f72756e74696d653a3a53657373696f6e4b6579733e3a3a6465636f64653a3a6834616339333937656166633633346665e9018a0173726d6c5f636f6c6c6563746976653a3a5f494d504c5f4445434f44455f464f525f43616c6c3a3a3c696d706c207061726974795f7363616c655f636f6465633a3a636f6465633a3a4465636f646520666f722073726d6c5f636f6c6c6563746976653a3a43616c6c3c542c493e3e3a3a6465636f64653a3a6831333130353934363139353131333335ea018b0173726d6c5f636f6e7472616374733a3a5f494d504c5f4445434f44455f464f525f5363686564756c653a3a3c696d706c207061726974795f7363616c655f636f6465633a3a636f6465633a3a4465636f646520666f722073726d6c5f636f6e7472616374733a3a5363686564756c653e3a3a6465636f64653a3a6834396636343234393334303165366132eb0182016e6f64655f72756e74696d653a3a5f494d504c5f454e434f44455f464f525f43616c6c3a3a3c696d706c207061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f646520666f72206e6f64655f72756e74696d653a3a43616c6c3e3a3a656e636f64655f746f3a3a6832373361383431636330393135346263ec01723c73725f7072696d6974697665733a3a67656e657269633a3a6469676573743a3a4469676573744974656d3c486173683e206173207061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f64653e3a3a656e636f64653a3a6830376364313565343730393839633137ed018d0173726d6c5f636f6c6c6563746976653a3a5f494d504c5f454e434f44455f464f525f43616c6c3a3a3c696d706c207061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f646520666f722073726d6c5f636f6c6c6563746976653a3a43616c6c3c542c493e3e3a3a656e636f64655f746f3a3a6835626138363964316265616430313464ee018e0173726d6c5f636f6e7472616374733a3a5f494d504c5f454e434f44455f464f525f5363686564756c653a3a3c696d706c207061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f646520666f722073726d6c5f636f6e7472616374733a3a5363686564756c653e3a3a656e636f64655f746f3a3a6866346132356361353138616335333261ef01437061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f64653a3a7573696e675f656e636f6465643a3a6834306664363130326135353165306162f0012b616c6c6f633a3a736c6963653a3a6d657267655f736f72743a3a6833316161333833653836616137363032f10184016e6f64655f72756e74696d653a3a5f494d504c5f454e434f44455f464f525f4576656e743a3a3c696d706c207061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f646520666f72206e6f64655f72756e74696d653a3a4576656e743e3a3a656e636f64655f746f3a3a6836643335653535356638613331303163f201a20173726d6c5f636f6c6c6563746976653a3a5f494d504c5f454e434f44455f464f525f5261774576656e743a3a3c696d706c207061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f646520666f722073726d6c5f636f6c6c6563746976653a3a5261774576656e743c486173682c4163636f756e7449642c493e3e3a3a656e636f64655f746f3a3a6834343930633836383033333235343464f301653c6e6f64655f72756e74696d653a3a43616c6c2061732073725f7072696d6974697665733a3a776569676874733a3a4765744469737061746368496e666f3e3a3a6765745f64697370617463685f696e666f3a3a6830343764353632386132636561316131f401583c6e6f64655f72756e74696d653a3a43616c6c2061732073725f7072696d6974697665733a3a7472616974733a3a446973706174636861626c653e3a3a64697370617463683a3a6838336539363263643433313230313431f501583c73726d6c5f626162653a3a43616c6c3c543e2061732073725f7072696d6974697665733a3a7472616974733a3a446973706174636861626c653e3a3a64697370617463683a3a6830613865393037323432653436316137f601437061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f64653a3a7573696e675f656e636f6465643a3a6862373562336361323964663636363363f7017273726d6c5f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a6d61703a3a3c696d706c2073726d6c5f737570706f72743a3a73746f726167653a3a53746f726167654d61703c4b2c563e20666f7220473e3a3a6765743a3a6836313935643964653537363138303536f8013573726d6c5f617574686f72736869703a3a4d6f64756c653c543e3a3a617574686f723a3a6837616231333433646161623761326263f9013973726d6c5f7374616b696e673a3a4d6f64756c653c543e3a3a7265776172645f62795f6964733a3a6834663135326364303734323563613964fa01673c73726d6c5f617574686f726974795f646973636f766572793a3a43616c6c3c543e2061732073725f7072696d6974697665733a3a7472616974733a3a446973706174636861626c653e3a3a64697370617463683a3a6862373861323639343666653063343330fb013973726d6c5f73657373696f6e3a3a4d6f64756c653c543e3a3a63757272656e745f696e6465783a3a6862643032343430373930666636353431fc016f73726d6c5f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a646f75626c655f6d61703a3a53746f72616765446f75626c654d61703a3a73746f726167655f646f75626c655f6d61705f66696e616c5f6b65793a3a6863323531613265623837643836373037fd013773726d6c5f737570706f72743a3a73746f726167653a3a756e6861736865643a3a6765743a3a6865363039313833643065313763373335fe013473726d6c5f696e64696365733a3a4d6f64756c653c543e3a3a656e756d5f7365743a3a6834626439326135376534613539343639ff014a3c58206173207061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f64653e3a3a7573696e675f656e636f6465643a3a683331333837306130366564383137366380025d3c73726d6c5f636f6e7472616374733a3a43616c6c3c543e2061732073725f7072696d6974697665733a3a7472616974733a3a446973706174636861626c653e3a3a64697370617463683a3a683337653735393432376661653439323181029c0173726d6c5f74726561737572793a3a5f494d504c5f4445434f44455f464f525f50726f706f73616c3a3a3c696d706c207061726974795f7363616c655f636f6465633a3a636f6465633a3a4465636f646520666f722073726d6c5f74726561737572793a3a50726f706f73616c3c4163636f756e7449642c42616c616e63653e3e3a3a6465636f64653a3a6862653536383862356333373963656531820291013c73726d6c5f62616c616e6365733a3a4d6f64756c653c542c493e2061732073726d6c5f737570706f72743a3a7472616974733a3a52657365727661626c6543757272656e63793c3c542061732073726d6c5f73797374656d3a3a54726169743e3a3a4163636f756e7449643e3e3a3a736c6173685f72657365727665643a3a683935323531313561306238396239363483028a013c73726d6c5f62616c616e6365733a3a4d6f64756c653c542c493e2061732073726d6c5f737570706f72743a3a7472616974733a3a52657365727661626c6543757272656e63793c3c542061732073726d6c5f73797374656d3a3a54726169743e3a3a4163636f756e7449643e3e3a3a726573657276653a3a6835373538346635383335346464633662840295013c73726d6c5f636f6c6c6563746976653a3a4d6f64756c653c542c493e2061732073726d6c5f737570706f72743a3a7472616974733a3a4368616e67654d656d626572733c3c542061732073726d6c5f73797374656d3a3a54726169743e3a3a4163636f756e7449643e3e3a3a6368616e67655f6d656d626572735f736f727465643a3a686361376465303135316236633762653285024a73726d6c5f737570706f72743a3a7472616974733a3a4368616e67654d656d626572733a3a7365745f6d656d626572735f736f727465643a3a683538373630336262373262373332656386025d3c73726d6c5f656c656374696f6e733a3a43616c6c3c543e2061732073725f7072696d6974697665733a3a7472616974733a3a446973706174636861626c653e3a3a64697370617463683a3a68343237636433356333343061653264318702603c73726d6c5f636f6c6c6563746976653a3a43616c6c3c542c493e2061732073725f7072696d6974697665733a3a7472616974733a3a446973706174636861626c653e3a3a64697370617463683a3a68613438353966393862646662343236348802603c73726d6c5f636f6c6c6563746976653a3a43616c6c3c542c493e2061732073725f7072696d6974697665733a3a7472616974733a3a446973706174636861626c653e3a3a64697370617463683a3a683732373531613862373434313363383089025d3c73726d6c5f64656d6f63726163793a3a43616c6c3c543e2061732073725f7072696d6974697665733a3a7472616974733a3a446973706174636861626c653e3a3a64697370617463683a3a68653734393864343238613132313430328a02a40173726d6c5f7374616b696e673a3a5f494d504c5f4445434f44455f464f525f5374616b696e674c65646765723a3a3c696d706c207061726974795f7363616c655f636f6465633a3a636f6465633a3a4465636f646520666f722073726d6c5f7374616b696e673a3a5374616b696e674c65646765723c4163636f756e7449642c42616c616e63653e3e3a3a6465636f64653a3a68323763626335363133383261626464638b026f73726d6c5f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a646f75626c655f6d61703a3a53746f72616765446f75626c654d61703a3a73746f726167655f646f75626c655f6d61705f66696e616c5f6b65793a3a68316232373866353234623633623030388c026f73726d6c5f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a646f75626c655f6d61703a3a53746f72616765446f75626c654d61703a3a73746f726167655f646f75626c655f6d61705f66696e616c5f6b65793a3a68643338646665333337366133616133618d025b3c73726d6c5f7374616b696e673a3a43616c6c3c543e2061732073725f7072696d6974697665733a3a7472616974733a3a446973706174636861626c653e3a3a64697370617463683a3a68326662643138643966363865313162638e0281013c73726d6c5f62616c616e6365733a3a4d6f64756c653c542c493e2061732073726d6c5f737570706f72743a3a7472616974733a3a43757272656e63793c3c542061732073726d6c5f73797374656d3a3a54726169743e3a3a4163636f756e7449643e3e3a3a7472616e736665723a3a68393839356531356133343461393931338f023f73726d6c5f62616c616e6365733a3a4d6f64756c653c542c493e3a3a7365745f667265655f62616c616e63653a3a686338383364396561623864346264333390024373726d6c5f62616c616e6365733a3a4d6f64756c653c542c493e3a3a7365745f72657365727665645f62616c616e63653a3a686434313335333537336630653135303591025b3c73726d6c5f696e64696365733a3a43616c6c3c543e2061732073725f7072696d6974697665733a3a7472616974733a3a446973706174636861626c653e3a3a64697370617463683a3a683836643831653663633431313261616292023c7061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f64653a3a656e636f64653a3a683235616265373531383235343639656293027f3c73726d6c5f696e64696365733a3a4d6f64756c653c543e2061732073726d6c5f73797374656d3a3a4f6e4e65774163636f756e743c3c542061732073726d6c5f73797374656d3a3a54726169743e3a3a4163636f756e7449643e3e3a3a6f6e5f6e65775f6163636f756e743a3a683233616438626236666435383861326194023873726d6c5f737570706f72743a3a73746f726167653a3a756e6861736865643a3a74616b653a3a686461366639373031343963386135303795023673726d6c5f7374616b696e673a3a4d6f64756c653c543e3a3a6b696c6c5f73746173683a3a683130383536663739323263306461306596023773726d6c5f737570706f72743a3a73746f726167653a3a756e6861736865643a3a6765743a3a686634613737393939303031643038636297027573726d6c5f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a6d61703a3a3c696d706c2073726d6c5f737570706f72743a3a73746f726167653a3a53746f726167654d61703c4b2c563e20666f7220473e3a3a72656d6f76653a3a6837383737326333616663356337353965980281013c73726d6c5f62616c616e6365733a3a4d6f64756c653c542c493e2061732073726d6c5f737570706f72743a3a7472616974733a3a43757272656e63793c3c542061732073726d6c5f73797374656d3a3a54726169743e3a3a4163636f756e7449643e3e3a3a77697468647261773a3a683562396534326566383633636534646199023e73726d6c5f62616c616e6365733a3a4d6f64756c653c542c493e3a3a76657374696e675f62616c616e63653a3a68626238373339643133333535626236339a023473726d6c5f62616c616e6365733a3a4d6f64756c653c542c493e3a3a6c6f636b733a3a68333638393134633832333539393965379b02483c5b543b205f5d206173207061726974795f7363616c655f636f6465633a3a636f6465633a3a4465636f64653e3a3a6465636f64653a3a68353835323237626435376637343932309c027573726d6c5f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a6d61703a3a3c696d706c2073726d6c5f737570706f72743a3a73746f726167653a3a53746f726167654d61703c4b2c563e20666f7220473e3a3a696e736572743a3a68633038636165316435373833636636349d0286013c73726d6c5f62616c616e6365733a3a4d6f64756c653c542c493e2061732073726d6c5f737570706f72743a3a7472616974733a3a43757272656e63793c3c542061732073726d6c5f73797374656d3a3a54726169743e3a3a4163636f756e7449643e3e3a3a746f74616c5f62616c616e63653a3a68643763643637643234383134613861659e02653c73726d6c5f62616c616e6365733a3a54616b65466565733c542c493e2061732073725f7072696d6974697665733a3a7472616974733a3a5369676e6564457874656e73696f6e3e3a3a76616c69646174653a3a68376236613935643336393266623835389f023773726d6c5f737570706f72743a3a73746f726167653a3a756e6861736865643a3a6765743a3a6830653936393331313632366135383439a0023d73726d6c5f62616c616e6365733a3a4d6f64756c653c542c493e3a3a63616c6c5f66756e6374696f6e733a3a6862323666653064306530393634336432a1023d73726d6c5f62616c616e6365733a3a4d6f64756c653c542c493e3a3a746f74616c5f69737375616e63653a3a6862373662663765313663613336633032a2023f73726d6c5f62616c616e6365733a3a4d6f64756c653c542c493e3a3a73746f726167655f6d657461646174613a3a6835653663653264363439656133316565a3026f3c73726d6c5f62616c616e6365733a3a5f5f476574427974655374727563744672656542616c616e63653c542c493e2061732073726d6c5f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6861383137633863343936663239343566a4024873726d6c5f62616c616e6365733a3a4d6f64756c653c542c493e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a6834313966353063313539363139383666a5028e013c73726d6c5f62616c616e6365733a3a4d6f64756c653c542c493e2061732073726d6c5f737570706f72743a3a7472616974733a3a43757272656e63793c3c542061732073726d6c5f73797374656d3a3a54726169743e3a3a4163636f756e7449643e3e3a3a6465706f7369745f696e746f5f6578697374696e673a3a6830386464613432346263363434343536a6023c73726d6c5f696d5f6f6e6c696e653a3a4d6f64756c653c543e3a3a63616c6c5f66756e6374696f6e733a3a6862663230666535343038633831396532a7023e73726d6c5f696d5f6f6e6c696e653a3a4d6f64756c653c543e3a3a73746f726167655f6d657461646174613a3a6861643765666566376438653664313064a8028c013c73726d6c5f62616c616e6365733a3a4d6f64756c653c542c493e2061732073726d6c5f737570706f72743a3a7472616974733a3a4c6f636b61626c6543757272656e63793c3c542061732073726d6c5f73797374656d3a3a54726169743e3a3a4163636f756e7449643e3e3a3a657874656e645f6c6f636b3a3a6862363338363539643233333631623664a90289013c73726d6c5f62616c616e6365733a3a4d6f64756c653c542c493e2061732073726d6c5f737570706f72743a3a7472616974733a3a4c6f636b61626c6543757272656e63793c3c542061732073726d6c5f73797374656d3a3a54726169743e3a3a4163636f756e7449643e3e3a3a7365745f6c6f636b3a3a6836396238393930643162313061313162aa028c013c73726d6c5f62616c616e6365733a3a4d6f64756c653c542c493e2061732073726d6c5f737570706f72743a3a7472616974733a3a52657365727661626c6543757272656e63793c3c542061732073726d6c5f73797374656d3a3a54726169743e3a3a4163636f756e7449643e3e3a3a756e726573657276653a3a6832313164383839393835333764303834ab02437061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f64653a3a7573696e675f656e636f6465643a3a6830666563303961653439666334326261ac023c7061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f64653a3a656e636f64653a3a6864663432393736333738383031613830ad023c7061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f64653a3a656e636f64653a3a6862353065623633303432396164376434ae024a3c73726d6c5f62616c616e6365733a3a43616c6c3c542c493e20617320636f72653a3a636c6f6e653a3a436c6f6e653e3a3a636c6f6e653a3a6865353039326631653139383330613864af02493c73726d6c5f696d5f6f6e6c696e653a3a43616c6c3c543e20617320636f72653a3a636c6f6e653a3a436c6f6e653e3a3a636c6f6e653a3a6831666134356231303637653363663366b002613c616c6c6f633a3a636f6c6c656374696f6e733a3a62747265653a3a6d61703a3a42547265654d61703c4b2c563e20617320636f72653a3a6f70733a3a64726f703a3a44726f703e3a3a64726f703a3a6835313936613536623066393933653735b102723c616c6c6f633a3a636f6c6c656374696f6e733a3a62747265653a3a6d61703a3a496e746f497465723c4b2c563e20617320636f72653a3a697465723a3a7472616974733a3a6974657261746f723a3a4974657261746f723e3a3a6e6578743a3a6832366232363063316563313961636339b202437061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f64653a3a7573696e675f656e636f6465643a3a6833353837313637353866383936316335b3027573726d6c5f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a6d61703a3a3c696d706c2073726d6c5f737570706f72743a3a73746f726167653a3a53746f726167654d61703c4b2c563e20666f7220473e3a3a696e736572743a3a6839613865636263363866646163613530b402303c265420617320636f72653a3a666d743a3a44656275673e3a3a666d743a3a6832336661343463613531383764656463b5024d636f72653a3a666d743a3a6e756d3a3a3c696d706c20636f72653a3a666d743a3a446562756720666f72207573697a653e3a3a666d743a3a68373032373631646266343866333635362e323334b6024373726d6c5f66696e616c6974795f747261636b65723a3a4d6f64756c653c543e3a3a63616c6c5f66756e6374696f6e733a3a6837323862643265653064663338323230b7024e73726d6c5f66696e616c6974795f747261636b65723a3a4d6f64756c653c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a6863643962646630323731313235383765b8029f013c73726d6c5f66696e616c6974795f747261636b65723a3a4d6f64756c653c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a5265706f72744c6174656e637944656661756c74427974654765747465723c543e2061732073726d6c5f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6865613333313236376432326439396637b9029c013c73726d6c5f66696e616c6974795f747261636b65723a3a4d6f64756c653c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a57696e646f7753697a6544656661756c74427974654765747465723c543e2061732073726d6c5f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6865373839396264363034313435393935ba02d5017375627374726174655f636f6e73656e7375735f626162655f7072696d6974697665733a3a6469676573743a3a5f494d504c5f4445434f44455f464f525f526177426162655072654469676573743a3a3c696d706c207061726974795f7363616c655f636f6465633a3a636f6465633a3a4465636f646520666f72207375627374726174655f636f6e73656e7375735f626162655f7072696d6974697665733a3a6469676573743a3a526177426162655072654469676573743e3a3a6465636f64653a3a6831633662323537393730353733386134bb024b616c6c6f633a3a636f6c6c656374696f6e733a3a62747265653a3a6d61703a3a566163616e74456e7472793c4b2c563e3a3a696e736572743a3a6831626132303333613836643063323539bc02613c616c6c6f633a3a636f6c6c656374696f6e733a3a62747265653a3a6d61703a3a42547265654d61703c4b2c563e20617320636f72653a3a6f70733a3a64726f703a3a44726f703e3a3a64726f703a3a6830346361333431346265366331306336bd028c013c73726d6c5f656c656374696f6e733a3a4d6f64756c653c543e2061732073725f7072696d6974697665733a3a7472616974733a3a4f6e496e697469616c697a653c3c542061732073726d6c5f73797374656d3a3a54726169743e3a3a426c6f636b4e756d6265723e3e3a3a6f6e5f696e697469616c697a653a3a6830613231343334363663376138326632be023773726d6c5f737570706f72743a3a73746f726167653a3a756e6861736865643a3a6765743a3a6831396564393438326431653338623932bf024073726d6c5f656c656374696f6e733a3a4d6f64756c653c543e3a3a63616e6469646174655f7265675f696e666f3a3a6831373937623930333666633766346466c0023873726d6c5f656c656374696f6e733a3a4d6f64756c653c543e3a3a616c6c5f766f746572733a3a6861316534646265623437323035653037c1023a73726d6c5f656c656374696f6e733a3a4d6f64756c653c543e3a3a617070726f76616c735f6f663a3a6832306234303633356262643638613261c202960173726d6c5f656c656374696f6e733a3a5f494d504c5f4445434f44455f464f525f566f746572496e666f3a3a3c696d706c207061726974795f7363616c655f636f6465633a3a636f6465633a3a4465636f646520666f722073726d6c5f656c656374696f6e733a3a566f746572496e666f3c42616c616e63653e3e3a3a6465636f64653a3a6830316262336439643662306561626533c3024a3c58206173207061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f64653e3a3a7573696e675f656e636f6465643a3a6836306436643261353030666463656265c4022d636f72653a3a736c6963653a3a736f72743a3a726563757273653a3a6835643130393431636331373563363639c50295013c73726d6c5f636f6c6c6563746976653a3a4d6f64756c653c542c493e2061732073726d6c5f737570706f72743a3a7472616974733a3a4368616e67654d656d626572733c3c542061732073726d6c5f73797374656d3a3a54726169743e3a3a4163636f756e7449643e3e3a3a6368616e67655f6d656d626572735f736f727465643a3a6864653264326333356566393630353236c6023773726d6c5f737570706f72743a3a73746f726167653a3a756e6861736865643a3a6765743a3a6835393066393834646333383132663735c7023c73726d6c5f656c656374696f6e733a3a4d6f64756c653c543e3a3a63616c6c5f66756e6374696f6e733a3a6831343362643439666263383664393238c8023e73726d6c5f656c656374696f6e733a3a4d6f64756c653c543e3a3a73746f726167655f6d657461646174613a3a6866653130333861666166393439343565c902713c73726d6c5f656c656374696f6e733a3a5f5f4765744279746553747275637443616e646964617465436f756e743c543e2061732073726d6c5f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6834643433333035643361333633333334ca02713c73726d6c5f656c656374696f6e733a3a5f5f476574427974655374727563745265676973746572496e666f4f663c543e2061732073726d6c5f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6837363362656236383261363832343365cb024773726d6c5f656c656374696f6e733a3a4d6f64756c653c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a6862376137636130316332323031333132cc0299013c73726d6c5f656c656374696f6e733a3a4d6f64756c653c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a564f5445525f5345545f53495a4544656661756c74427974654765747465723c543e2061732073726d6c5f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6866366135363965663662643639346637cd0295013c73726d6c5f656c656374696f6e733a3a4d6f64756c653c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a566f74696e67426f6e6444656661756c74427974654765747465723c543e2061732073726d6c5f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6838613264656532666338373233633965ce0297013c73726d6c5f656c656374696f6e733a3a4d6f64756c653c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a566f74696e67506572696f6444656661756c74427974654765747465723c543e2061732073726d6c5f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6863653338613432616462313537383438cf029e013c73726d6c5f656c656374696f6e733a3a4d6f64756c653c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a496e6163746976654772616365506572696f6444656661756c74427974654765747465723c543e2061732073726d6c5f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6866363330386163656461376137343234d00295013c73726d6c5f656c656374696f6e733a3a4d6f64756c653c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a4361727279436f756e7444656661756c74427974654765747465723c543e2061732073726d6c5f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6833653330626135303162636236366136d10294013c73726d6c5f656c656374696f6e733a3a4d6f64756c653c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a566f74696e6746656544656661756c74427974654765747465723c543e2061732073726d6c5f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6864333434393535393035313936363639d20298013c73726d6c5f656c656374696f6e733a3a4d6f64756c653c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a43616e646964616379426f6e6444656661756c74427974654765747465723c543e2061732073726d6c5f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6839393639666163356137666662626663d302493c73726d6c5f656c656374696f6e733a3a43616c6c3c543e20617320636f72653a3a636c6f6e653a3a436c6f6e653e3a3a636c6f6e653a3a6838393533343563316230373032343266d4023e73726d6c5f656c656374696f6e733a3a4d6f64756c653c543e3a3a646f5f7365745f617070726f76616c733a3a6830356233326237643335643433376531d5023a73726d6c5f656c656374696f6e733a3a4d6f64756c653c543e3a3a72656d6f76655f766f7465723a3a6864343234646366303966313037613632d602497061726974795f7363616c655f636f6465633a3a656e636f64655f617070656e643a3a657874726163745f6c656e6774685f646174613a3a6866643865656134353734643132643761d7023a73726d6c5f6772616e6470613a3a4d6f64756c653c543e3a3a63616c6c5f66756e6374696f6e733a3a6830316131646133303365313665336564d8023c73726d6c5f6772616e6470613a3a4d6f64756c653c543e3a3a73746f726167655f6d657461646174613a3a6864313433326339303364323232303332d902663c73726d6c5f6772616e6470613a3a5f5f4765744279746553747275637453746174653c543e2061732073726d6c5f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6861633430666337353837316663386439da023c7061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f64653a3a656e636f64653a3a6866613262363366396564623731643938db023a73726d6c5f73657373696f6e3a3a4d6f64756c653c543e3a3a63616c6c5f66756e6374696f6e733a3a6839336165366236373664623230343535dc023c73726d6c5f73657373696f6e3a3a4d6f64756c653c543e3a3a73746f726167655f6d657461646174613a3a6835383233613635353036306435633137dd024573726d6c5f73657373696f6e3a3a4d6f64756c653c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a6864363061643832333262393932383237de0299013c73726d6c5f73657373696f6e3a3a4d6f64756c653c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a44454455505f4b45595f50524546495844656661756c74427974654765747465723c543e2061732073726d6c5f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6861626566343565663162336261356236df02763c73726d6c5f737570706f72743a3a73746f726167653a3a6861736865643a3a54776f783634436f6e6361742061732073726d6c5f737570706f72743a3a73746f726167653a3a6861736865643a3a53746f726167654861736865723e3a3a686173683a3a6830336164393834343263623061383436e002437061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f64653a3a7573696e675f656e636f6465643a3a6866396638336564633862303663363035e102437061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f64653a3a7573696e675f656e636f6465643a3a6839623462623063373566323965326431e2023b73726d6c5f74726561737572793a3a4d6f64756c653c543e3a3a63616c6c5f66756e6374696f6e733a3a6864623530656536616665326164663166e3023d73726d6c5f74726561737572793a3a4d6f64756c653c543e3a3a73746f726167655f6d657461646174613a3a6866303933303965666331326462656261e4024673726d6c5f74726561737572793a3a4d6f64756c653c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a6865616232643963386538373037313930e5028e013c73726d6c5f74726561737572793a3a4d6f64756c653c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a4275726e44656661756c74427974654765747465723c543e2061732073726d6c5f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6862376133356263656433663732633433e602870173725f7072696d6974697665733a3a5f494d504c5f454e434f44455f464f525f50657262696c6c3a3a3c696d706c207061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f646520666f722073725f7072696d6974697665733a3a50657262696c6c3e3a3a656e636f64653a3a6830306536383731383739316332643562e70295013c73726d6c5f74726561737572793a3a4d6f64756c653c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a5370656e64506572696f6444656661756c74427974654765747465723c543e2061732073726d6c5f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6864653636393366366136366337323939e80296013c73726d6c5f74726561737572793a3a4d6f64756c653c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a50726f706f73616c426f6e6444656661756c74427974654765747465723c543e2061732073726d6c5f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6830656261613063366636366431356332e9023673726d6c5f74726561737572793a3a4d6f64756c653c543e3a3a70726f706f73616c733a3a6863663030323230323662663936306562ea028a013c73726d6c5f73657373696f6e3a3a4d6f64756c653c543e2061732073725f7072696d6974697665733a3a7472616974733a3a4f6e496e697469616c697a653c3c542061732073726d6c5f73797374656d3a3a54726169743e3a3a426c6f636b4e756d6265723e3e3a3a6f6e5f696e697469616c697a653a3a6835333934366339396564396363636432eb023673726d6c5f626162653a3a4d6f64756c653c543e3a3a646f5f696e697469616c697a653a3a6832613837383633353631643739633635ec023373726d6c5f7374616b696e673a3a4d6f64756c653c543e3a3a7374616b6572733a3a6861393931653433343637656664343439ed0286013c73726d6c5f7374616b696e673a3a4d6f64756c653c543e2061732073726d6c5f73657373696f6e3a3a4f6e53657373696f6e456e64696e673c3c542061732073726d6c5f73797374656d3a3a54726169743e3a3a4163636f756e7449643e3e3a3a6f6e5f73657373696f6e5f656e64696e673a3a6831616537633337663639326237646539ee023b73726d6c5f6772616e6470613a3a4d6f64756c653c543e3a3a7363686564756c655f6368616e67653a3a6863663437383934313665623338366464ef023773726d6c5f737570706f72743a3a73746f726167653a3a756e6861736865643a3a6765743a3a6864313234373039313533353736666336f002437061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f64653a3a7573696e675f656e636f6465643a3a6837383364333039663738623432326336f1024b3c5b543b205f5d206173207061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f64653e3a3a656e636f64655f746f3a3a6832333063333531613138336135356361f20230636f72653a3a7074723a3a7265616c5f64726f705f696e5f706c6163653a3a6835363637303838653535663233666638f302633c636f72653a3a697465723a3a61646170746572733a3a4d61703c492c463e20617320636f72653a3a697465723a3a7472616974733a3a6974657261746f723a3a4974657261746f723e3a3a6e6578743a3a6832303361323762636366356561396333f402683c636f72653a3a697465723a3a61646170746572733a3a4d61703c492c463e20617320636f72653a3a697465723a3a7472616974733a3a6974657261746f723a3a4974657261746f723e3a3a73697a655f68696e743a3a6832346639626639393362356461613335f5023e636f72653a3a697465723a3a7472616974733a3a6974657261746f723a3a4974657261746f723a3a6e74683a3a6833383534363563373835376562323363f602633c636f72653a3a697465723a3a61646170746572733a3a4d61703c492c463e20617320636f72653a3a697465723a3a7472616974733a3a6974657261746f723a3a4974657261746f723e3a3a6e6578743a3a6835333163646162346661313032336566f7023e636f72653a3a697465723a3a7472616974733a3a6974657261746f723a3a4974657261746f723a3a6e74683a3a6830656136623430363665613539646464f8024273726d6c5f636f6e7472616374733a3a7761736d3a3a707265706172653a3a707265706172655f636f6e74726163743a3a6836323964316235366163326233306638f9024a3c58206173207061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f64653e3a3a7573696e675f656e636f6465643a3a6833663662373961343438356135623362fa02437061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f64653a3a7573696e675f656e636f6465643a3a6839303831646161613832616561363963fb026a636f72653a3a6f70733a3a66756e6374696f6e3a3a696d706c733a3a3c696d706c20636f72653a3a6f70733a3a66756e6374696f6e3a3a466e4f6e63653c413e20666f7220266d757420463e3a3a63616c6c5f6f6e63653a3a6833313938663239346337633037623537fc02663c73726d6c5f636f6e7472616374733a3a7761736d3a3a5761736d566d2061732073726d6c5f636f6e7472616374733a3a657865633a3a566d3c543e3e3a3a657865637574653a3a7b7b636c6f737572657d7d3a3a6832326566363933396635303938656631fd027d3c73726d6c5f636f6e7472616374733a3a7761736d3a3a72756e74696d653a3a456e762061732073726d6c5f636f6e7472616374733a3a7761736d3a3a656e765f6465663a3a46756e6374696f6e496d706c50726f76696465723c453e3e3a3a696d706c733a3a6761733a3a6832623037396439643933646632663439fe025273725f73616e64626f783a3a696d703a3a456e7669726f6e6d656e74446566696e6974696f6e4275696c6465723c543e3a3a6164645f686f73745f66756e633a3a6837613337346132656234333561666165ff0289013c73726d6c5f636f6e7472616374733a3a7761736d3a3a72756e74696d653a3a456e762061732073726d6c5f636f6e7472616374733a3a7761736d3a3a656e765f6465663a3a46756e6374696f6e496d706c50726f76696465723c453e3e3a3a696d706c733a3a6578745f7365745f73746f726167653a3a6833316361656264633564353264303138800389013c73726d6c5f636f6e7472616374733a3a7761736d3a3a72756e74696d653a3a456e762061732073726d6c5f636f6e7472616374733a3a7761736d3a3a656e765f6465663a3a46756e6374696f6e496d706c50726f76696465723c453e3e3a3a696d706c733a3a6578745f6765745f73746f726167653a3a6831306431663335653165616632636130810382013c73726d6c5f636f6e7472616374733a3a7761736d3a3a72756e74696d653a3a456e762061732073726d6c5f636f6e7472616374733a3a7761736d3a3a656e765f6465663a3a46756e6374696f6e496d706c50726f76696465723c453e3e3a3a696d706c733a3a6578745f63616c6c3a3a6862623530306664353561356239323037820389013c73726d6c5f636f6e7472616374733a3a7761736d3a3a72756e74696d653a3a456e762061732073726d6c5f636f6e7472616374733a3a7761736d3a3a656e765f6465663a3a46756e6374696f6e496d706c50726f76696465723c453e3e3a3a696d706c733a3a6578745f696e7374616e74696174653a3a6832616439353630656131333639626339830384013c73726d6c5f636f6e7472616374733a3a7761736d3a3a72756e74696d653a3a456e762061732073726d6c5f636f6e7472616374733a3a7761736d3a3a656e765f6465663a3a46756e6374696f6e496d706c50726f76696465723c453e3e3a3a696d706c733a3a6578745f72657475726e3a3a6861636564646338343232366335616233840384013c73726d6c5f636f6e7472616374733a3a7761736d3a3a72756e74696d653a3a456e762061732073726d6c5f636f6e7472616374733a3a7761736d3a3a656e765f6465663a3a46756e6374696f6e496d706c50726f76696465723c453e3e3a3a696d706c733a3a6578745f63616c6c65723a3a6834636231663539323330323861356630850385013c73726d6c5f636f6e7472616374733a3a7761736d3a3a72756e74696d653a3a456e762061732073726d6c5f636f6e7472616374733a3a7761736d3a3a656e765f6465663a3a46756e6374696f6e496d706c50726f76696465723c453e3e3a3a696d706c733a3a6578745f616464726573733a3a6833613661303262393533303630646139860387013c73726d6c5f636f6e7472616374733a3a7761736d3a3a72756e74696d653a3a456e762061732073726d6c5f636f6e7472616374733a3a7761736d3a3a656e765f6465663a3a46756e6374696f6e496d706c50726f76696465723c453e3e3a3a696d706c733a3a6578745f6761735f70726963653a3a6864376232663834643362623864393663870386013c73726d6c5f636f6e7472616374733a3a7761736d3a3a72756e74696d653a3a456e762061732073726d6c5f636f6e7472616374733a3a7761736d3a3a656e765f6465663a3a46756e6374696f6e496d706c50726f76696465723c453e3e3a3a696d706c733a3a6578745f6761735f6c6566743a3a6861373962343335303839303935373465880385013c73726d6c5f636f6e7472616374733a3a7761736d3a3a72756e74696d653a3a456e762061732073726d6c5f636f6e7472616374733a3a7761736d3a3a656e765f6465663a3a46756e6374696f6e496d706c50726f76696465723c453e3e3a3a696d706c733a3a6578745f62616c616e63653a3a686339306131366437336261366433336589038f013c73726d6c5f636f6e7472616374733a3a7761736d3a3a72756e74696d653a3a456e762061732073726d6c5f636f6e7472616374733a3a7761736d3a3a656e765f6465663a3a46756e6374696f6e496d706c50726f76696465723c453e3e3a3a696d706c733a3a6578745f76616c75655f7472616e736665727265643a3a68336165393265656438623133313066658a0384013c73726d6c5f636f6e7472616374733a3a7761736d3a3a72756e74696d653a3a456e762061732073726d6c5f636f6e7472616374733a3a7761736d3a3a656e765f6465663a3a46756e6374696f6e496d706c50726f76696465723c453e3e3a3a696d706c733a3a6578745f72616e646f6d3a3a68643635336131613637663332626464368b0381013c73726d6c5f636f6e7472616374733a3a7761736d3a3a72756e74696d653a3a456e762061732073726d6c5f636f6e7472616374733a3a7761736d3a3a656e765f6465663a3a46756e6374696f6e496d706c50726f76696465723c453e3e3a3a696d706c733a3a6578745f6e6f773a3a68616461313738623139303562636263618c038d013c73726d6c5f636f6e7472616374733a3a7761736d3a3a72756e74696d653a3a456e762061732073726d6c5f636f6e7472616374733a3a7761736d3a3a656e765f6465663a3a46756e6374696f6e496d706c50726f76696465723c453e3e3a3a696d706c733a3a6578745f6d696e696d756d5f62616c616e63653a3a68613038303466373261376563343666378d038b013c73726d6c5f636f6e7472616374733a3a7761736d3a3a72756e74696d653a3a456e762061732073726d6c5f636f6e7472616374733a3a7761736d3a3a656e765f6465663a3a46756e6374696f6e496d706c50726f76696465723c453e3e3a3a696d706c733a3a6578745f64697370617463685f63616c6c3a3a68383035303832366164303961386335628e0388013c73726d6c5f636f6e7472616374733a3a7761736d3a3a72756e74696d653a3a456e762061732073726d6c5f636f6e7472616374733a3a7761736d3a3a656e765f6465663a3a46756e6374696f6e496d706c50726f76696465723c453e3e3a3a696d706c733a3a6578745f726573746f72655f746f3a3a68633132333439626561366435393336308f038a013c73726d6c5f636f6e7472616374733a3a7761736d3a3a72756e74696d653a3a456e762061732073726d6c5f636f6e7472616374733a3a7761736d3a3a656e765f6465663a3a46756e6374696f6e496d706c50726f76696465723c453e3e3a3a696d706c733a3a6578745f736372617463685f73697a653a3a683538306530613263333566306331646490038a013c73726d6c5f636f6e7472616374733a3a7761736d3a3a72756e74696d653a3a456e762061732073726d6c5f636f6e7472616374733a3a7761736d3a3a656e765f6465663a3a46756e6374696f6e496d706c50726f76696465723c453e3e3a3a696d706c733a3a6578745f736372617463685f726561643a3a683663373534623336306337633265613991038b013c73726d6c5f636f6e7472616374733a3a7761736d3a3a72756e74696d653a3a456e762061732073726d6c5f636f6e7472616374733a3a7761736d3a3a656e765f6465663a3a46756e6374696f6e496d706c50726f76696465723c453e3e3a3a696d706c733a3a6578745f736372617463685f77726974653a3a683632343433353932626339633736616592038b013c73726d6c5f636f6e7472616374733a3a7761736d3a3a72756e74696d653a3a456e762061732073726d6c5f636f6e7472616374733a3a7761736d3a3a656e765f6465663a3a46756e6374696f6e496d706c50726f76696465723c453e3e3a3a696d706c733a3a6578745f6465706f7369745f6576656e743a3a6838306238323039323537373365616633930390013c73726d6c5f636f6e7472616374733a3a7761736d3a3a72756e74696d653a3a456e762061732073726d6c5f636f6e7472616374733a3a7761736d3a3a656e765f6465663a3a46756e6374696f6e496d706c50726f76696465723c453e3e3a3a696d706c733a3a6578745f7365745f72656e745f616c6c6f77616e63653a3a683466323433313333626532356363666194038c013c73726d6c5f636f6e7472616374733a3a7761736d3a3a72756e74696d653a3a456e762061732073726d6c5f636f6e7472616374733a3a7761736d3a3a656e765f6465663a3a46756e6374696f6e496d706c50726f76696465723c453e3e3a3a696d706c733a3a6578745f72656e745f616c6c6f77616e63653a3a6839363463323461623138626436633334950385013c73726d6c5f636f6e7472616374733a3a7761736d3a3a72756e74696d653a3a456e762061732073726d6c5f636f6e7472616374733a3a7761736d3a3a656e765f6465663a3a46756e6374696f6e496d706c50726f76696465723c453e3e3a3a696d706c733a3a6578745f7072696e746c6e3a3a686637366431396430353439356163373596038a013c73726d6c5f636f6e7472616374733a3a7761736d3a3a72756e74696d653a3a456e762061732073726d6c5f636f6e7472616374733a3a7761736d3a3a656e765f6465663a3a46756e6374696f6e496d706c50726f76696465723c453e3e3a3a696d706c733a3a6578745f626c6f636b5f6e756d6265723a3a686433623536316436376666623763643497033273725f73616e64626f783a3a696d703a3a64697370617463685f7468756e6b3a3a68386536656133346363343135383566389803ad017375627374726174655f7072696d6974697665733a3a73616e64626f783a3a5f494d504c5f4445434f44455f464f525f547970656456616c75653a3a3c696d706c207061726974795f7363616c655f636f6465633a3a636f6465633a3a4465636f646520666f72207375627374726174655f7072696d6974697665733a3a73616e64626f783a3a547970656456616c75653e3a3a6465636f64653a3a68363636646563623130363065303136389903b0017375627374726174655f7072696d6974697665733a3a73616e64626f783a3a5f494d504c5f454e434f44455f464f525f547970656456616c75653a3a3c696d706c207061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f646520666f72207375627374726174655f7072696d6974697665733a3a73616e64626f783a3a547970656456616c75653e3a3a656e636f64655f746f3a3a68366638396436616535373364656261659a033773726d6c5f737570706f72743a3a73746f726167653a3a756e6861736865643a3a6765743a3a68656566626338616663316366666162389b033d73726d6c5f617574686f72736869703a3a4d6f64756c653c543e3a3a63616c6c5f66756e6374696f6e733a3a68613865633662663666313730656535339c033f73726d6c5f617574686f72736869703a3a4d6f64756c653c543e3a3a73746f726167655f6d657461646174613a3a68323836393939663633396233306133669d03703c73726d6c5f617574686f72736869703a3a5f5f47657442797465537472756374446964536574556e636c65733c543e2061732073726d6c5f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a68356131666536346139393034343766639e038a033c285475706c65456c656d656e74302c205475706c65456c656d656e74312c205475706c65456c656d656e74322c205475706c65456c656d656e74332c205475706c65456c656d656e74342c205475706c65456c656d656e74352c205475706c65456c656d656e74362c205475706c65456c656d656e74372c205475706c65456c656d656e74382c205475706c65456c656d656e74392c205475706c65456c656d656e7431302c205475706c65456c656d656e7431312c205475706c65456c656d656e7431322c205475706c65456c656d656e7431332c205475706c65456c656d656e7431342c205475706c65456c656d656e7431352c205475706c65456c656d656e7431362c205475706c65456c656d656e7431372c205475706c65456c656d656e7431382c205475706c65456c656d656e743139292061732073725f7072696d6974697665733a3a7472616974733a3a4f6e46696e616c697a653c426c6f636b4e756d6265723e3e3a3a6f6e5f66696e616c697a653a3a68326334616136396565373634306235359f037573726d6c5f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a6d61703a3a3c696d706c2073726d6c5f737570706f72743a3a73746f726167653a3a53746f726167654d61703c4b2c563e20666f7220473e3a3a696e736572743a3a6835326236326535373661623038396433a0033173726d6c5f74696d657374616d703a3a4d6f64756c653c543e3a3a6e6f773a3a6834363532613662336165366264626163a103443c73726d6c5f626162653a3a43616c6c3c543e20617320636f72653a3a636c6f6e653a3a436c6f6e653e3a3a636c6f6e653a3a6835316562616163646438636565393939a2033973726d6c5f626162653a3a4d6f64756c653c543e3a3a73746f726167655f6d657461646174613a3a6838626464366437316663366336386133a303683c73726d6c5f626162653a3a5f5f4765744279746553747275637452616e646f6d6e6573733c543e2061732073726d6c5f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6831646266336432303235653433663633a4034273726d6c5f626162653a3a4d6f64756c653c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a6832653030663433376237636334623732a50397013c73726d6c5f626162653a3a4d6f64756c653c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a4578706563746564426c6f636b54696d6544656661756c74427974654765747465723c543e2061732073726d6c5f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6834383432303533646236336462623264a60393013c73726d6c5f626162653a3a4d6f64756c653c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a45706f63684475726174696f6e44656661756c74427974654765747465723c543e2061732073726d6c5f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6866373362303132363134623132356364a7033773726d6c5f737570706f72743a3a73746f726167653a3a756e6861736865643a3a6765743a3a6837346264393230333636623666316562a8033173726d6c5f73797374656d3a3a4d6f64756c653c543e3a3a72616e646f6d3a3a6836306461326464656333373364646436a9033773726d6c5f737570706f72743a3a73746f726167653a3a756e6861736865643a3a6765743a3a6861623464373335663864656363386661aa03930173726d6c5f73797374656d3a3a5f494d504c5f454e434f44455f464f525f4576656e745265636f72643a3a3c696d706c207061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f646520666f722073726d6c5f73797374656d3a3a4576656e745265636f72643c452c543e3e3a3a656e636f64655f746f3a3a6831323131373037393638613835333637ab0330636f72653a3a7074723a3a7265616c5f64726f705f696e5f706c6163653a3a6836616262343766373764373233383832ac033973726d6c5f73797374656d3a3a4d6f64756c653c543e3a3a63616c6c5f66756e6374696f6e733a3a6839396533616666666131613734653864ad033b73726d6c5f73797374656d3a3a4d6f64756c653c543e3a3a73746f726167655f6d657461646174613a3a6838613435343333313564303062363733ae03663c73726d6c5f73797374656d3a3a5f5f476574427974655374727563744576656e74733c543e2061732073726d6c5f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6837643032313739653635613738326563af03693c73726d6c5f73797374656d3a3a5f5f47657442797465537472756374426c6f636b486173683c543e2061732073726d6c5f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6831343962353364336363646564316439b0036e3c73726d6c5f73797374656d3a3a5f5f4765744279746553747275637452616e646f6d4d6174657269616c3c543e2061732073726d6c5f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6838346564373366313834376166366434b1034473726d6c5f73797374656d3a3a4d6f64756c653c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a6834613439316239383530666636343565b2033373726d6c5f73797374656d3a3a4d6f64756c653c543e3a3a66696e616c697a653a3a6861336164316265613362353165373663b303920173726d6c5f636f6c6c6563746976653a3a5f494d504c5f4445434f44455f464f525f566f7465733a3a3c696d706c207061726974795f7363616c655f636f6465633a3a636f6465633a3a4465636f646520666f722073726d6c5f636f6c6c6563746976653a3a566f7465733c4163636f756e7449643e3e3a3a6465636f64653a3a6831666334646262316561653233396639b4034a3c58206173207061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f64653e3a3a7573696e675f656e636f6465643a3a6865373436613266666630383837623565b5033f73726d6c5f636f6c6c6563746976653a3a4d6f64756c653c542c493e3a3a63616c6c5f66756e6374696f6e733a3a6866373435383836616563616334393835b6034173726d6c5f636f6c6c6563746976653a3a4d6f64756c653c542c493e3a3a73746f726167655f6d657461646174613a3a6831336536643135376135613433613432b7034173726d6c5f636f6c6c6563746976653a3a4d6f64756c653c542c493e3a3a73746f726167655f6d657461646174613a3a6834353831653732656334363130393330b8034273726d6c5f73797374656d3a3a436865636b5765696768743c543e3a3a636865636b5f626c6f636b5f6c656e6774683a3a6837666561303334346333386136616365b9033c73726d6c5f73797374656d3a3a436865636b5765696768743c543e3a3a636865636b5f7765696768743a3a6834326632643563336464616539323165ba03463c616c6c6f633a3a626f7865643a3a426f783c543e20617320636f72653a3a636c6f6e653a3a436c6f6e653e3a3a636c6f6e653a3a6831393764386331333362343930343066bb03473c73726d6c5f696e64696365733a3a43616c6c3c543e20617320636f72653a3a636c6f6e653a3a436c6f6e653e3a3a636c6f6e653a3a6831303562663766353932313861333062bc03473c73726d6c5f7374616b696e673a3a43616c6c3c543e20617320636f72653a3a636c6f6e653a3a436c6f6e653e3a3a636c6f6e653a3a6831396539646437656462396264616366bd03493c73726d6c5f64656d6f63726163793a3a43616c6c3c543e20617320636f72653a3a636c6f6e653a3a436c6f6e653e3a3a636c6f6e653a3a6836636635383139356236626464353231be034c3c73726d6c5f6d656d626572736869703a3a43616c6c3c542c493e20617320636f72653a3a636c6f6e653a3a436c6f6e653e3a3a636c6f6e653a3a6837323735633464666230386236643532bf03493c73726d6c5f636f6e7472616374733a3a43616c6c3c543e20617320636f72653a3a636c6f6e653a3a436c6f6e653e3a3a636c6f6e653a3a6862373936623731343832366162363138c003443c73726d6c5f7375646f3a3a43616c6c3c543e20617320636f72653a3a636c6f6e653a3a436c6f6e653e3a3a636c6f6e653a3a6865393938653136373161363737386139c103533c73726d6c5f617574686f726974795f646973636f766572793a3a43616c6c3c543e20617320636f72653a3a636c6f6e653a3a436c6f6e653e3a3a636c6f6e653a3a6837346565386530313939376239383937c203463c73726d6c5f73797374656d3a3a43616c6c3c543e20617320636f72653a3a636c6f6e653a3a436c6f6e653e3a3a636c6f6e653a3a6833626664323638333734663362376338c3034c3c73726d6c5f636f6c6c6563746976653a3a43616c6c3c542c493e20617320636f72653a3a636c6f6e653a3a436c6f6e653e3a3a636c6f6e653a3a6837663834326331386439383539653138c4033c73726d6c5f696e64696365733a3a4d6f64756c653c543e3a3a73746f726167655f6d657461646174613a3a6837303666626537316539373135376665c5037573726d6c5f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a6d61703a3a3c696d706c2073726d6c5f737570706f72743a3a73746f726167653a3a53746f726167654d61703c4b2c563e20666f7220473e3a3a696e736572743a3a6862383665646132366239376363326534c603d80173725f7072696d6974697665733a3a7472616e73616374696f6e5f76616c69646974793a3a5f494d504c5f454e434f44455f464f525f5472616e73616374696f6e56616c69646974794572726f723a3a3c696d706c207061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f646520666f722073725f7072696d6974697665733a3a7472616e73616374696f6e5f76616c69646974793a3a5472616e73616374696f6e56616c69646974794572726f723e3a3a656e636f64655f746f3a3a6831626165383133323764396564653362c7037173726d6c5f6578656375746976653a3a4578656375746976653c53797374656d2c426c6f636b2c436f6e746578742c556e7369676e656456616c696461746f722c416c6c4d6f64756c65733e3a3a696e697469616c697a655f626c6f636b3a3a6834626664366136356235623930656539c8033d73726d6c5f64656d6f63726163793a3a4d6f64756c653c543e3a3a6c61756e63685f65787465726e616c3a3a6862613562643931393264343264353735c9033b73726d6c5f64656d6f63726163793a3a4d6f64756c653c543e3a3a6c61756e63685f7075626c69633a3a6864623438343534306330333732386561ca033d73726d6c5f64656d6f63726163793a3a4d6f64756c653c543e3a3a7265666572656e64756d5f696e666f3a3a6833333765323135653936613163383731cb033873726d6c5f64656d6f63726163793a3a4d6f64756c653c543e3a3a766f746572735f666f723a3a6837306138346438373431306364346230cc033573726d6c5f64656d6f63726163793a3a4d6f64756c653c543e3a3a766f74655f6f663a3a6831613037316366663431353331376631cd033d73726d6c5f64656d6f63726163793a3a4d6f64756c653c543e3a3a64656c6567617465645f766f7465733a3a6832663566356266663563303233643636ce033e73726d6c5f64656d6f63726163793a3a4d6f64756c653c543e3a3a636c6561725f7265666572656e64756d3a3a6866666637373262613837616630303565cf03443c6e6f64655f72756e74696d653a3a43616c6c20617320636f72653a3a636c6f6e653a3a436c6f6e653e3a3a636c6f6e653a3a6832616531373964653035366164666439d0037973726d6c5f6578656375746976653a3a4578656375746976653c53797374656d2c426c6f636b2c436f6e746578742c556e7369676e656456616c696461746f722c416c6c4d6f64756c65733e3a3a6170706c795f65787472696e7369635f776974685f6c656e3a3a6830363363313039363438386337343964d103a5013c73725f7072696d6974697665733a3a67656e657269633a3a756e636865636b65645f65787472696e7369633a3a556e636865636b656445787472696e7369633c416464726573732c43616c6c2c5369676e61747572652c45787472613e2061732073725f7072696d6974697665733a3a7472616974733a3a436865636b61626c653c4c6f6f6b75703e3e3a3a636865636b3a3a6835353432373336616466623430333761d2036e3c73726d6c5f636f6e7472616374733a3a436865636b426c6f636b4761734c696d69743c543e2061732073725f7072696d6974697665733a3a7472616974733a3a5369676e6564457874656e73696f6e3e3a3a76616c69646174653a3a6834613539353938646632343262313836d303363c5420617320636f72653a3a636f6e766572743a3a496e746f3c553e3e3a3a696e746f3a3a6832653964376331393038323734626436d4033c73726d6c5f74696d657374616d703a3a4d6f64756c653c543e3a3a63616c6c5f66756e6374696f6e733a3a6836356634343632646235343435393338d5033e73726d6c5f74696d657374616d703a3a4d6f64756c653c543e3a3a73746f726167655f6d657461646174613a3a6865636431373939313835396165306236d6034773726d6c5f74696d657374616d703a3a4d6f64756c653c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a6864353861656165393464373762386164d70398013c73726d6c5f74696d657374616d703a3a4d6f64756c653c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a4d696e696d756d506572696f6444656661756c74427974654765747465723c543e2061732073726d6c5f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6864623734353962613435343235656461d8033f73726d6c5f6d656d626572736869703a3a4d6f64756c653c542c493e3a3a63616c6c5f66756e6374696f6e733a3a6861613637353666646431666439393661d9034173726d6c5f6d656d626572736869703a3a4d6f64756c653c542c493e3a3a73746f726167655f6d657461646174613a3a6838656137343163663931396330333264da0334636f72653a3a736c6963653a3a736f72743a3a627265616b5f7061747465726e733a3a6861613934663035386431333531633466db032e636f72653a3a736c6963653a3a736f72743a3a68656170736f72743a3a6834333461393733383437303165333236dc033c636f72653a3a736c6963653a3a736f72743a3a7061727469616c5f696e73657274696f6e5f736f72743a3a6835653664306564386338306561613034dd03593c73725f7072696d6974697665733a3a416e795369676e61747572652061732073725f7072696d6974697665733a3a7472616974733a3a5665726966793e3a3a7665726966793a3a6865653661376232666164623063306337de033773726d6c5f737570706f72743a3a73746f726167653a3a756e6861736865643a3a6765743a3a6831313330393632353863393833353939df033773726d6c5f737570706f72743a3a73746f726167653a3a756e6861736865643a3a6765743a3a6831333135303466353262396465616136e0033773726d6c5f737570706f72743a3a73746f726167653a3a756e6861736865643a3a6765743a3a6861656430393864653237386637643631e1033773726d6c5f737570706f72743a3a73746f726167653a3a756e6861736865643a3a6765743a3a6861666432643465663565656365613936e2033773726d6c5f737570706f72743a3a73746f726167653a3a756e6861736865643a3a7075743a3a6838333637626463333564323039376438e303c40173726d6c5f636f6e7472616374733a3a5f494d504c5f454e434f44455f464f525f526177416c697665436f6e7472616374496e666f3a3a3c696d706c207061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f646520666f722073726d6c5f636f6e7472616374733a3a526177416c697665436f6e7472616374496e666f3c436f6465486173682c42616c616e63652c426c6f636b4e756d6265723e3e3a3a656e636f64655f746f3a3a6837343039376637333530333664356132e4033873726d6c5f737570706f72743a3a73746f726167653a3a756e6861736865643a3a74616b653a3a6839643530626664316331393964383432e5037773726d6c5f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a76616c75653a3a3c696d706c2073726d6c5f737570706f72743a3a73746f726167653a3a53746f7261676556616c75653c543e20666f7220473e3a3a6d75746174653a3a6833393630323862623831616532396435e6033c73726d6c5f636f6e7472616374733a3a4d6f64756c653c543e3a3a63616c6c5f66756e6374696f6e733a3a6865373235383163383635373736343031e7033e73726d6c5f636f6e7472616374733a3a4d6f64756c653c543e3a3a73746f726167655f6d657461646174613a3a6838353138373039636366353134386634e8036b3c73726d6c5f636f6e7472616374733a3a5f5f4765744279746553747275637447617350726963653c543e2061732073726d6c5f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6837646161333630313731323962626161e903723c73726d6c5f636f6e7472616374733a3a5f5f4765744279746553747275637443757272656e745363686564756c653c543e2061732073726d6c5f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6830613432353664383239653035616630ea034773726d6c5f636f6e7472616374733a3a4d6f64756c653c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a6839373030323763326334383864663966eb0398013c73726d6c5f636f6e7472616374733a3a4d6f64756c653c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a426c6f636b4761734c696d697444656661756c74427974654765747465723c543e2061732073726d6c5f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6835326264363965373737633864653839ec0397013c73726d6c5f636f6e7472616374733a3a4d6f64756c653c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a4d617856616c756553697a6544656661756c74427974654765747465723c543e2061732073726d6c5f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6863653266336335666664386535346666ed0393013c73726d6c5f636f6e7472616374733a3a4d6f64756c653c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a4d6178446570746844656661756c74427974654765747465723c543e2061732073726d6c5f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6839373239663263633533653864316636ee0396013c73726d6c5f636f6e7472616374733a3a4d6f64756c653c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a43616c6c4261736546656544656661756c74427974654765747465723c543e2061732073726d6c5f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6830613062653632333537663633303232ef0396013c73726d6c5f636f6e7472616374733a3a4d6f64756c653c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a436f6e747261637446656544656661756c74427974654765747465723c543e2061732073726d6c5f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6836643062623334363530643336623765f0039d013c73726d6c5f636f6e7472616374733a3a4d6f64756c653c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a5472616e73616374696f6e4279746546656544656661756c74427974654765747465723c543e2061732073726d6c5f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6861653066326564313066333062336431f1039a013c73726d6c5f636f6e7472616374733a3a4d6f64756c653c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a53757263686172676552657761726444656661756c74427974654765747465723c543e2061732073726d6c5f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6835643765346164343430313363316363f2039c013c73726d6c5f636f6e7472616374733a3a4d6f64756c653c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a52656e744465706f7369744f666673657444656661756c74427974654765747465723c543e2061732073726d6c5f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6830653366346264376531366535323031f3039c013c73726d6c5f636f6e7472616374733a3a4d6f64756c653c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a53746f7261676553697a654f666673657444656661756c74427974654765747465723c543e2061732073726d6c5f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6836666162343733336233653630636665f4039e013c73726d6c5f636f6e7472616374733a3a4d6f64756c653c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a5369676e6564436c61696d48616e646963617044656661756c74427974654765747465723c543e2061732073726d6c5f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6832363431363262343562363133336365f5033773726d6c5f636f6e7472616374733a3a4d6f64756c653c543e3a3a626172655f63616c6c3a3a6862393261343137333037323335353038f6033773726d6c5f636f6e7472616374733a3a4d6f64756c653c543e3a3a6761735f70726963653a3a6861353534306331613131336131343632f7033e73726d6c5f636f6e7472616374733a3a4d6f64756c653c543e3a3a63757272656e745f7363686564756c653a3a6835393231353035363931356330383436f8033873726d6c5f636f6e7472616374733a3a4d6f64756c653c543e3a3a726573746f72655f746f3a3a6863613537313665383565633061613434f9034573726d6c5f636f6e7472616374733a3a7761736d3a3a707265706172653a3a436f6e74726163744d6f64756c653a3a6e65773a3a6838326533383933383863653766636635fa03467061726974795f7761736d3a3a656c656d656e74733a3a73656374696f6e3a3a436f646553656374696f6e3a3a626f646965733a3a6864393864326364313131613035613531fb0348616c6c6f633a3a636f6c6c656374696f6e733a3a62747265653a3a6d61703a3a42547265654d61703c4b2c563e3a3a696e736572743a3a6865373064323632373339343561313363fc033c7061726974795f7761736d3a3a6275696c6465723a3a6d6f64756c653a3a66726f6d5f6d6f64756c653a3a6834643832616331306433343833336233fd03537061726974795f7761736d3a3a6275696c6465723a3a6d6f64756c653a3a4d6f64756c654275696c6465723c463e3a3a7265736f6c76655f747970655f7265663a3a6861643034326537313830333035313963fe03a9017061726974795f7761736d3a3a6275696c6465723a3a6d6f64756c653a3a3c696d706c20636f72653a3a636f6e766572743a3a46726f6d3c7061726974795f7761736d3a3a6275696c6465723a3a6d6f64756c653a3a4d6f64756c6553636166666f6c643e20666f72207061726974795f7761736d3a3a656c656d656e74733a3a6d6f64756c653a3a4d6f64756c653e3a3a66726f6d3a3a6836643231633062653130613035343964ff0344707761736d5f7574696c733a3a6761733a3a436f756e7465723a3a66696e616c697a655f6d6574657265645f626c6f636b3a3a686362636565306234333463346631643080042d636f72653a3a736c6963653a3a736f72743a3a726563757273653a3a68656165383561343031313132353734348104507061726974795f7761736d3a3a6275696c6465723a3a6d6f64756c653a3a4d6f64756c654275696c6465723c463e3a3a707573685f66756e6374696f6e3a3a6865396131343838383163653163323132820430636f72653a3a7074723a3a7265616c5f64726f705f696e5f706c6163653a3a686464633764633436363333376535353783043c707761736d5f7574696c733a3a737461636b5f6865696768743a3a696e6a6563745f6c696d697465723a3a686635333865316430386135653339666384046b3c7061726974795f7761736d3a3a656c656d656e74733a3a73656374696f6e3a3a53656374696f6e206173207061726974795f7761736d3a3a656c656d656e74733a3a53657269616c697a653e3a3a73657269616c697a653a3a683633316637353930306465663336646285046b3c636f72653a3a697465723a3a61646170746572733a3a526573756c745368756e743c492c453e20617320636f72653a3a697465723a3a7472616974733a3a6974657261746f723a3a4974657261746f723e3a3a6e6578743a3a686536383437396137393936386537646686046f3c636f72653a3a697465723a3a61646170746572733a3a526573756c745368756e743c492c453e20617320636f72653a3a697465723a3a7472616974733a3a6974657261746f723a3a4974657261746f723e3a3a7472795f666f6c643a3a686631323333633761626466646630306287049f013c73725f7072696d6974697665733a3a67656e657269633a3a756e636865636b65645f65787472696e7369633a3a556e636865636b656445787472696e7369633c416464726573732c43616c6c2c5369676e61747572652c45787472613e206173207061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f64653e3a3a656e636f64653a3a686661623762663862623438396439613888043773726d6c5f7375646f3a3a4d6f64756c653c543e3a3a63616c6c5f66756e6374696f6e733a3a683535306364366435376331373164303289043973726d6c5f7375646f3a3a4d6f64756c653c543e3a3a73746f726167655f6d657461646174613a3a68303362303139613732626139303138328a04613c73726d6c5f7375646f3a3a5f5f476574427974655374727563744b65793c543e2061732073726d6c5f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a68383731363333663133333061636665378b04a5017375627374726174655f7072696d6974697665733a3a737232353531393a3a5f494d504c5f454e434f44455f464f525f5075626c69633a3a3c696d706c207061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f646520666f72207375627374726174655f7072696d6974697665733a3a737232353531393a3a5075626c69633e3a3a656e636f64653a3a68613163366230616563303734343431648c040c436f72655f76657273696f6e8d0412436f72655f657865637574655f626c6f636b8e04693c73725f7072696d6974697665733a3a7472616974733a3a426c616b6554776f3235362061732073725f7072696d6974697665733a3a7472616974733a3a486173683e3a3a6f7264657265645f747269655f726f6f743a3a68373739373939656532646161363861618f0415436f72655f696e697469616c697a655f626c6f636b9004114d657461646174615f6d657461646174619104483c5b545d206173207061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f64653e3a3a656e636f64655f746f3a3a68666533386331353361356163326164389204683c73726d6c5f6d657461646174613a3a4465636f6465446966666572656e743c422c4f3e206173207061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f64653e3a3a656e636f64655f746f3a3a68393131356662623533323965303964399304683c73726d6c5f6d657461646174613a3a4465636f6465446966666572656e743c422c4f3e206173207061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f64653e3a3a656e636f64655f746f3a3a683930613566666362353464373266346694041c426c6f636b4275696c6465725f6170706c795f65787472696e73696395041b426c6f636b4275696c6465725f66696e616c697a655f626c6f636b960420426c6f636b4275696c6465725f696e686572656e745f65787472696e7369637397043873726d6c5f74696d657374616d703a3a657874726163745f696e686572656e745f646174613a3a686362316436643834626362643035333698041c426c6f636b4275696c6465725f636865636b5f696e686572656e7473990418426c6f636b4275696c6465725f72616e646f6d5f736565649a042b5461676765645472616e73616374696f6e51756575655f76616c69646174655f7472616e73616374696f6e9b045673725f7072696d6974697665733a3a7472616e73616374696f6e5f76616c69646974793a3a56616c69645472616e73616374696f6e3a3a636f6d62696e655f776974683a3a68353736346238623566396161613662309c04214f6666636861696e576f726b65724170695f6f6666636861696e5f776f726b65729d0480013c73726d6c5f696d5f6f6e6c696e653a3a737232353531393a3a6170705f737232353531393a3a5075626c6963206173207375627374726174655f6170706c69636174696f6e5f63727970746f3a3a7472616974733a3a52756e74696d654170705075626c69633e3a3a616c6c3a3a68613834343166646339353935386136399e041e4772616e6470614170695f6772616e6470615f617574686f7269746965739f0415426162654170695f636f6e66696775726174696f6ea00421417574686f72697479446973636f766572794170695f617574686f726974696573a1041a417574686f72697479446973636f766572794170695f7369676ea2041c417574686f72697479446973636f766572794170695f766572696679a3041d4163636f756e744e6f6e63654170695f6163636f756e745f6e6f6e6365a40411436f6e7472616374734170695f63616c6ca5042153657373696f6e4b6579735f67656e65726174655f73657373696f6e5f6b657973a604820173726d6c5f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a6c696e6b65645f6d61703a3a3c696d706c2073726d6c5f737570706f72743a3a73746f726167653a3a53746f726167654c696e6b65644d61703c4b2c563e20666f7220473e3a3a72656d6f76653a3a6838663434353163653739313862313333a704820173726d6c5f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a6c696e6b65645f6d61703a3a3c696d706c2073726d6c5f737570706f72743a3a73746f726167653a3a53746f726167654c696e6b65644d61703c4b2c563e20666f7220473e3a3a72656d6f76653a3a6861663431626330376265363732653261a8043a73726d6c5f7374616b696e673a3a4d6f64756c653c543e3a3a63616c6c5f66756e6374696f6e733a3a6832383266383039373163393635623735a9043c73726d6c5f7374616b696e673a3a4d6f64756c653c543e3a3a73746f726167655f6d657461646174613a3a6830613933393034626364613731633464aa04743c73726d6c5f7374616b696e673a3a5f5f47657442797465537472756374536c6173685265776172644672616374696f6e3c543e2061732073726d6c5f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6830373539636563383531333663626462ab04773c73726d6c5f7374616b696e673a3a5f5f4765744279746553747275637443757272656e74457261506f696e74734561726e65643c543e2061732073726d6c5f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6863346466393062396266616466383466ac04703c73726d6c5f7374616b696e673a3a5f5f4765744279746553747275637443757272656e7445726153746172743c543e2061732073726d6c5f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6861346332306237316637343535343862ad04683c73726d6c5f7374616b696e673a3a5f5f476574427974655374727563745374616b6572733c543e2061732073726d6c5f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6834653030616266353365363433633733ae046b3c73726d6c5f7374616b696e673a3a5f5f4765744279746553747275637456616c696461746f72733c543e2061732073726d6c5f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6839633736316334353032636466336536af04763c73726d6c5f7374616b696e673a3a5f5f476574427974655374727563744d696e696d756d56616c696461746f72436f756e743c543e2061732073726d6c5f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6861336434623962346538633532666237b0044073726d6c5f7374616b696e673a3a4d6f64756c653c543e3a3a736c61736861626c655f62616c616e63655f6f663a3a6861636135383433363936353265613265b1043273726d6c5f7374616b696e673a3a4d6f64756c653c543e3a3a626f6e6465643a3a6830636562393635626631386363616232b2044573726d6c5f7374616b696e673a3a4d6f64756c653c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a6837306665313036376639643939383935b30498013c73726d6c5f7374616b696e673a3a4d6f64756c653c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a426f6e64696e674475726174696f6e44656661756c74427974654765747465723c543e2061732073726d6c5f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6832623535646136383130626464303061b4043773726d6c5f7374616b696e673a3a4d6f64756c653c543e3a3a6d616b655f7061796f75743a3a6832376631663237613230333735323861b5043973726d6c5f7374616b696e673a3a4d6f64756c653c543e3a3a7570646174655f6c65646765723a3a6832376563613564613530643864656139b6044a3c58206173207061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f64653e3a3a7573696e675f656e636f6465643a3a6866633236366266623663653230323433b7043f73726d6c5f64656d6f63726163793a3a4d6f64756c653c543e3a3a696e6a6563745f7265666572656e64756d3a3a6866346266323835623039613038383533b8043873726d6c5f64656d6f63726163793a3a4d6f64756c653c543e3a3a6465706f7369745f6f663a3a6833636363393431363966326232643635b9043c73726d6c5f64656d6f63726163793a3a4d6f64756c653c543e3a3a63616c6c5f66756e6374696f6e733a3a6831646437343931353664623131643533ba043e73726d6c5f64656d6f63726163793a3a4d6f64756c653c543e3a3a73746f726167655f6d657461646174613a3a6838336233383939373363343862666435bb046c3c73726d6c5f64656d6f63726163793a3a5f5f47657442797465537472756374426c61636b6c6973743c543e2061732073726d6c5f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6838623533343432616361336431616461bc046f3c73726d6c5f64656d6f63726163793a3a5f5f476574427974655374727563744e65787445787465726e616c3c543e2061732073726d6c5f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6837643466363231333432643433663038bd046e3c73726d6c5f64656d6f63726163793a3a5f5f4765744279746553747275637444656c65676174696f6e733c543e2061732073726d6c5f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6833626665323435333261616465653139be04703c73726d6c5f64656d6f63726163793a3a5f5f47657442797465537472756374446973706174636851756575653c543e2061732073726d6c5f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6835356135336235653738653362353537bf044773726d6c5f64656d6f63726163793a3a4d6f64756c653c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a6864666466353637383338323064313530c00497013c73726d6c5f64656d6f63726163793a3a4d6f64756c653c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a4c61756e6368506572696f6444656661756c74427974654765747465723c543e2061732073726d6c5f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6865623830643136316665383833373935c104a0013c73726d6c5f64656d6f63726163793a3a4d6f64756c653c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a456d657267656e6379566f74696e67506572696f6444656661756c74427974654765747465723c543e2061732073726d6c5f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6833316232323132653732363163316232c20499013c73726d6c5f64656d6f63726163793a3a4d6f64756c653c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a4d696e696d756d4465706f73697444656661756c74427974654765747465723c543e2061732073726d6c5f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6832363265623533316566353366303065c3049a013c73726d6c5f64656d6f63726163793a3a4d6f64756c653c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a456e6163746d656e74506572696f6444656661756c74427974654765747465723c543e2061732073726d6c5f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6838343565333534353965616136613466c4047573726d6c5f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a6d61703a3a3c696d706c2073726d6c5f737570706f72743a3a73746f726167653a3a53746f726167654d61703c4b2c563e20666f7220473e3a3a696e736572743a3a6832623431383266303634326531386431c5043573726d6c5f64656d6f63726163793a3a4d6f64756c653c543e3a3a646f5f766f74653a3a6834376438626636343531373064396363c604553c7061726974795f7761736d3a3a656c656d656e74733a3a6f70733a3a496e737472756374696f6e20617320636f72653a3a666d743a3a44656275673e3a3a666d743a3a6832333130333466623262396161316637c704303c265420617320636f72653a3a666d743a3a44656275673e3a3a666d743a3a6830376539663164633463383837333064c804303c265420617320636f72653a3a666d743a3a44656275673e3a3a666d743a3a6833613863363935663762313962666661c904303c265420617320636f72653a3a666d743a3a44656275673e3a3a666d743a3a6862343766326134326533363431363234ca04443c7061726974795f7761736d3a3a696f3a3a4572726f7220617320636f72653a3a666d743a3a44656275673e3a3a666d743a3a6836656663396633373739323336343738cb04303c265420617320636f72653a3a666d743a3a44656275673e3a3a666d743a3a6863373733386638313465306262636138cc04303c265420617320636f72653a3a666d743a3a44656275673e3a3a666d743a3a6865336235353835366335366563383866cd04457061726974795f7761736d3a3a656c656d656e74733a3a7365676d656e743a3a446174615365676d656e743a3a76616c75653a3a6861333366626161653136643036353336ce04303c265420617320636f72653a3a666d743a3a44656275673e3a3a666d743a3a6831613930373663633036623361623965cf04303c265420617320636f72653a3a666d743a3a44656275673e3a3a666d743a3a6835653364383861646633663531633032d004553c7061726974795f7761736d3a3a656c656d656e74733a3a74797065733a3a56616c75655479706520617320636f72653a3a666d743a3a44656275673e3a3a666d743a3a6832333362653833316563653732373563d104553c7061726974795f7761736d3a3a656c656d656e74733a3a74797065733a3a426c6f636b5479706520617320636f72653a3a666d743a3a44656275673e3a3a666d743a3a6838376433336131303565663737663430d204303c265420617320636f72653a3a666d743a3a44656275673e3a3a666d743a3a6839343630376237663435333334613836d30433636f72653a3a6f7074696f6e3a3a4f7074696f6e3c26543e3a3a636c6f6e65643a3a6833336430666462656635333766383862d404453c636f72653a3a6f7074696f6e3a3a4f7074696f6e3c543e20617320636f72653a3a666d743a3a44656275673e3a3a666d743a3a6834643038393932373338626235366665d504303c265420617320636f72653a3a666d743a3a44656275673e3a3a666d743a3a6839626562663532613237376634306665d60440707761736d5f7574696c733a3a737461636b5f6865696768743a3a636f6d707574655f737461636b5f636f73743a3a6832656332613464616131633336616664d704533c616c6c6f633a3a7665633a3a5665633c543e20617320616c6c6f633a3a7665633a3a53706563457874656e643c542c493e3e3a3a737065635f657874656e643a3a6833663135373864636638623165303366d804323c265420617320636f72653a3a666d743a3a446973706c61793e3a3a666d743a3a6833333964366132336633616239353839d904593c7061726974795f7761736d3a3a656c656d656e74733a3a6f70733a3a496e737472756374696f6e20617320636f72653a3a636c6f6e653a3a436c6f6e653e3a3a636c6f6e653a3a6832303531346563626537613764663764da04613c616c6c6f633a3a636f6c6c656374696f6e733a3a62747265653a3a6d61703a3a42547265654d61703c4b2c563e20617320636f72653a3a6f70733a3a64726f703a3a44726f703e3a3a64726f703a3a6865646336386533623863393232303938db043f707761736d5f7574696c733a3a737461636b5f6865696768743a3a7265736f6c76655f66756e635f747970653a3a6835666661376165643139363735653632dc0430636f72653a3a7074723a3a7265616c5f64726f705f696e5f706c6163653a3a6834383364613531306533653334653735dd0441707761736d5f7574696c733a3a737461636b5f6865696768743a3a6d61785f6865696768743a3a636f6d707574653a3a6830646665316537373831363437623164de0434636f72653a3a736c6963653a3a736f72743a3a627265616b5f7061747465726e733a3a6835353237373135663731363338343330df042e636f72653a3a736c6963653a3a736f72743a3a68656170736f72743a3a6833386430383365613239326630376635e0043c636f72653a3a736c6963653a3a736f72743a3a7061727469616c5f696e73657274696f6e5f736f72743a3a6833396131373737326563303238336633e104303c265420617320636f72653a3a666d743a3a44656275673e3a3a666d743a3a6830316234393736623730636366393962e2045a3c707761736d5f7574696c733a3a737461636b5f6865696768743a3a6d61785f6865696768743a3a4672616d6520617320636f72653a3a666d743a3a44656275673e3a3a666d743a3a6837373362393934386530363033303234e30446707761736d5f7574696c733a3a737461636b5f6865696768743a3a6d61785f6865696768743a3a537461636b3a3a6672616d653a3a6838653765623332646462333937343230e4044b707761736d5f7574696c733a3a737461636b5f6865696768743a3a6d61785f6865696768743a3a537461636b3a3a706f705f76616c7565733a3a6837613665336661633565303837386131e504323c265420617320636f72653a3a666d743a3a446973706c61793e3a3a666d743a3a6839353333633564346536303161336562e604323c265420617320636f72653a3a666d743a3a446973706c61793e3a3a666d743a3a6838333065633835663931653437646439e7044e73725f696f3a3a696d703a3a6578743a3a65787465726e5f66756e6374696f6e735f686f73745f696d706c3a3a6578745f7072696e745f757466383a3a6831316330336538356431303265376435e804683c7061726974795f7761736d3a3a656c656d656e74733a3a6f70733a3a496e697445787072206173207061726974795f7761736d3a3a656c656d656e74733a3a53657269616c697a653e3a3a73657269616c697a653a3a6833643262383038376431613430623032e9046b3c7061726974795f7761736d3a3a656c656d656e74733a3a6f70733a3a496e737472756374696f6e206173207061726974795f7761736d3a3a656c656d656e74733a3a53657269616c697a653e3a3a73657269616c697a653a3a6861376364656439653336396133323630ea047d3c7061726974795f7761736d3a3a656c656d656e74733a3a7072696d6974697665733a3a436f756e7465644c6973745772697465723c492c543e206173207061726974795f7761736d3a3a656c656d656e74733a3a53657269616c697a653e3a3a73657269616c697a653a3a6835653237663566326461333132313031eb046f3c7061726974795f7761736d3a3a656c656d656e74733a3a7072696d6974697665733a3a566172496e743332206173207061726974795f7761736d3a3a656c656d656e74733a3a53657269616c697a653e3a3a73657269616c697a653a3a6833356432333232326631633463663837ec046f3c7061726974795f7761736d3a3a656c656d656e74733a3a7072696d6974697665733a3a566172496e743634206173207061726974795f7761736d3a3a656c656d656e74733a3a53657269616c697a653e3a3a73657269616c697a653a3a6836666134636162356466656233633936ed046c3c7061726974795f7761736d3a3a656c656d656e74733a3a6f70733a3a496e697445787072206173207061726974795f7761736d3a3a656c656d656e74733a3a446573657269616c697a653e3a3a646573657269616c697a653a3a6861353061613066336466316663643961ee046f3c7061726974795f7761736d3a3a656c656d656e74733a3a6f70733a3a496e737472756374696f6e206173207061726974795f7761736d3a3a656c656d656e74733a3a446573657269616c697a653e3a3a646573657269616c697a653a3a6838663538373638626466643663363436ef04793c7061726974795f7761736d3a3a656c656d656e74733a3a7072696d6974697665733a3a436f756e7465644c6973743c543e206173207061726974795f7761736d3a3a656c656d656e74733a3a446573657269616c697a653e3a3a646573657269616c697a653a3a6830326534363637616133663639633832f0046b3c7061726974795f7761736d3a3a656c656d656e74733a3a6f70733a3a496e737472756374696f6e206173207061726974795f7761736d3a3a656c656d656e74733a3a53657269616c697a653e3a3a73657269616c697a653a3a6866616531383734653335636562616238f104713c7061726974795f7761736d3a3a656c656d656e74733a3a696e6465785f6d61703a3a496e6465784d61703c543e206173207061726974795f7761736d3a3a656c656d656e74733a3a53657269616c697a653e3a3a73657269616c697a653a3a6837353163336164613534326365643464f204783c7061726974795f7761736d3a3a656c656d656e74733a3a696d706f72745f656e7472793a3a526573697a61626c654c696d697473206173207061726974795f7761736d3a3a656c656d656e74733a3a53657269616c697a653e3a3a73657269616c697a653a3a6866653634336337356161613937393331f3047c3c7061726974795f7761736d3a3a656c656d656e74733a3a696d706f72745f656e7472793a3a526573697a61626c654c696d697473206173207061726974795f7761736d3a3a656c656d656e74733a3a446573657269616c697a653e3a3a646573657269616c697a653a3a6834643135366137643832646366653437f404743c7061726974795f7761736d3a3a656c656d656e74733a3a7072696d6974697665733a3a56617255696e743332206173207061726974795f7761736d3a3a656c656d656e74733a3a446573657269616c697a653e3a3a646573657269616c697a653a3a6862396165303366373735323163303237f504713c7061726974795f7761736d3a3a656c656d656e74733a3a73656374696f6e3a3a437573746f6d53656374696f6e206173207061726974795f7761736d3a3a656c656d656e74733a3a53657269616c697a653e3a3a73657269616c697a653a3a6864383435613264366361663338313736f6044b3c616c6c6f633a3a7665633a3a496e746f497465723c543e20617320636f72653a3a6f70733a3a64726f703a3a44726f703e3a3a64726f703a3a6833303831373966353539376166373962f7044b3c616c6c6f633a3a7665633a3a496e746f497465723c543e20617320636f72653a3a6f70733a3a64726f703a3a44726f703e3a3a64726f703a3a6862636562656465393336303030353930f8044b3c616c6c6f633a3a7665633a3a496e746f497465723c543e20617320636f72653a3a6f70733a3a64726f703a3a44726f703e3a3a64726f703a3a6864356438333636626133356134666363f904463c616c6c6f633a3a7665633a3a5665633c543e20617320636f72653a3a6f70733a3a64726f703a3a44726f703e3a3a64726f703a3a6830393432356365343637643235646564fa046f3c7061726974795f7761736d3a3a656c656d656e74733a3a73656374696f6e3a3a53656374696f6e206173207061726974795f7761736d3a3a656c656d656e74733a3a446573657269616c697a653e3a3a646573657269616c697a653a3a6835373532633363323332363061333635fb04457061726974795f7761736d3a3a656c656d656e74733a3a73656374696f6e3a3a53656374696f6e5265616465723a3a6e65773a3a6866656161316461386338643835366362fc0486017061726974795f7761736d3a3a656c656d656e74733a3a7072696d6974697665733a3a3c696d706c207061726974795f7761736d3a3a656c656d656e74733a3a446573657269616c697a6520666f7220616c6c6f633a3a737472696e673a3a537472696e673e3a3a646573657269616c697a653a3a6832303434366565303237346466653739fd042d636f72653a3a736c6963653a3a736f72743a3a726563757273653a3a6862353339623432353939316562373937fe0434636f72653a3a736c6963653a3a736f72743a3a627265616b5f7061747465726e733a3a6866623631656536316166636362646537ff042e636f72653a3a736c6963653a3a736f72743a3a68656170736f72743a3a683038653936383835383561383932643480053c636f72653a3a736c6963653a3a736f72743a3a7061727469616c5f696e73657274696f6e5f736f72743a3a683631623461353636613537323964363781053b636f72653a3a736c6963653a3a736f72743a3a68656170736f72743a3a7b7b636c6f737572657d7d3a3a68343831336137356561636161653734378205323c265420617320636f72653a3a666d743a3a446973706c61793e3a3a666d743a3a68663961303537303266333235643366618305397761736d695f76616c69646174696f6e3a3a76616c69646174655f6d656d6f72795f747970653a3a68386330623261323731393065373038328405347761736d695f76616c69646174696f6e3a3a657870725f636f6e73745f747970653a3a683232363566313162343233326265373685054a7761736d695f76616c69646174696f6e3a3a66756e633a3a46756e6374696f6e56616c69646174696f6e436f6e746578743a3a737465703a3a68353864303463346465383638653431658605473c7761736d695f76616c69646174696f6e3a3a4572726f7220617320636f72653a3a666d743a3a446973706c61793e3a3a666d743a3a6837353566373166363063653234393764870537616c6c6f633a3a7261775f7665633a3a5261775665633c542c413e3a3a726573657276653a3a683462396237323936623436336634353588053b636f72653a3a736c6963653a3a3c696d706c205b545d3e3a3a636f70795f66726f6d5f736c6963653a3a68383832353431646433666436326537318905347761736d695f76616c69646174696f6e3a3a66756e633a3a706f705f76616c75653a3a68656337393434626366663764623131668a05347761736d695f76616c69646174696f6e3a3a66756e633a3a706f705f6c6162656c3a3a68326336353735376131376361383336338b05407761736d695f76616c69646174696f6e3a3a7574696c3a3a4c6f63616c733a3a747970655f6f665f6c6f63616c3a3a68383162303837636564666462346434388c05543c7761736d695f76616c69646174696f6e3a3a66756e633a3a537461636b56616c75655479706520617320636f72653a3a666d743a3a44656275673e3a3a666d743a3a68633739643161663136313838663435368d05537761736d695f76616c69646174696f6e3a3a66756e633a3a46756e6374696f6e56616c69646174696f6e436f6e746578743a3a76616c69646174655f6c6f61643a3a68366138333538613164613464626566308e05547761736d695f76616c69646174696f6e3a3a66756e633a3a46756e6374696f6e56616c69646174696f6e436f6e746578743a3a76616c69646174655f73746f72653a3a68636564333562656564653636653562628f05557761736d695f76616c69646174696f6e3a3a66756e633a3a46756e6374696f6e56616c69646174696f6e436f6e746578743a3a76616c69646174655f746573746f703a3a68616533303233333361636330633266319005547761736d695f76616c69646174696f6e3a3a66756e633a3a46756e6374696f6e56616c69646174696f6e436f6e746578743a3a76616c69646174655f72656c6f703a3a68376534356165623939363562643230379105537761736d695f76616c69646174696f6e3a3a66756e633a3a46756e6374696f6e56616c69646174696f6e436f6e746578743a3a76616c69646174655f756e6f703a3a68313765386433643566626361383862399205547761736d695f76616c69646174696f6e3a3a66756e633a3a46756e6374696f6e56616c69646174696f6e436f6e746578743a3a76616c69646174655f62696e6f703a3a68333830663663353461613061383264399305547761736d695f76616c69646174696f6e3a3a66756e633a3a46756e6374696f6e56616c69646174696f6e436f6e746578743a3a76616c69646174655f6376746f703a3a6835353663323836383738376336363661940530636f72653a3a7074723a3a7265616c5f64726f705f696e5f706c6163653a3a6830363931663361393762336664333466950530636f72653a3a7074723a3a7265616c5f64726f705f696e5f706c6163653a3a68613966613837316265643663366635309605303c265420617320636f72653a3a666d743a3a44656275673e3a3a666d743a3a68393761376132643963636263616632399705453c616c6c6f633a3a737472696e673a3a537472696e6720617320636f72653a3a666d743a3a446973706c61793e3a3a666d743a3a683630376665306161343865353334636298054c3c7761736d695f76616c69646174696f6e3a3a737461636b3a3a4572726f7220617320636f72653a3a666d743a3a44656275673e3a3a666d743a3a68653966363833643036366338313166359905066d656d7365749a05066d656d6370799b05076d656d6d6f76659c05066d656d636d709d05095f5f6173686c7469339e05095f5f6c7368727469339f05085f5f6d756c746933a005095f5f75646976746933a105095f5f756d6f64746933a2050c5f5f756469766d6f6474693400550970726f64756365727302086c616e6775616765010452757374000c70726f6365737365642d62790105727573746325312e33392e302d6e696768746c79202831646431383834383920323031392d30392d323229", + "0x8f9a319405d14f3953657373696f6e204b65794f776e6572343a73657373696f6e3a6b6579730cd914acf7b89329ae59e8f7e3b8f1ee7a4f5f68d4749cca82814f2f5b1d6bbb": "0x9c7a2ee14e565db0c69f78c7b4cd839fbf52b607d867e9e9c5a79042898a0d12", + "0xc98362e2ca21b342cc749022ed9b560e4d29ec9862a960c2538c314f1d279635": "0x149ee5e5bdc0ec239eb164f865ecc345ce4c88e76ee002e0f7e3180973474718099c7a2ee14e565db0c69f78c7b4cd839fbf52b607d867e9e9c5a79042898a0d1268655684472b743e456907b398d3a44c113f189e56d1bbfd55e889e295dfde78547ff0ab649283a7ae01dbc2eb73932eba2fb09075e9485ff369082a2ff38d65f26cdb14b5aec7b2789fd5ca80f979cef3761897ae1f37ffb3e154cbcc1c2663", + "0x6e4ab2ac5a7cf9b1829eacc84a75bde0804be01fc31c9419ea72407f50a33384": "0xf26cdb14b5aec7b2789fd5ca80f979cef3761897ae1f37ffb3e154cbcc1c2663", + "0x366a192e1ce90bf109f11cf4d4bdab1ce310d835c09411b1be3ad53814e33196": "0x000001547ff0ab649283a7ae01dbc2eb73932eba2fb09075e9485ff369082a2ff38d65", + "0x125dc846383907f5846f72ce53ca0e4b": "0x00ca9a3b000000000000000000000000", + "0x46cef122497fefa60faf6c66d3ef05caf9870446796ae11f0a4f734fee993d8b": "0x00", + "0xf4adb4c4f708c4b753657373696f6e204e6578744b657973343a73657373696f6e3a6b6579737f325c981c2b001f5fe8c51cc7b89e50ebb1f60feb7ab3fa3bc79d6ab71d45cb": "0x9becad03e6dcac03cee07edebca5475314861492cdfc96a2144a67bbe96993326e7e4eb42cbd2e0ab4cae8708ce5509580b8c04d11f6758dbf686d50fe9f91066e7e4eb42cbd2e0ab4cae8708ce5509580b8c04d11f6758dbf686d50fe9f9106", + "0x71020fee971bd00e8248d1830b8cffbe5b9cf4de1ea2911a1665c44fd70ab6f3": "0xf26cdb14b5aec7b2789fd5ca80f979cef3761897ae1f37ffb3e154cbcc1c26630f0000c16ff286230f0000c16ff2862300", + "0xfff675c76ad8a5dfbd7db9a4e80f7c0ece595ad1878d2b6fca6086b2483a055b": "0x0000c16ff28623000000000000000000", + "0x2b334d6ac6698775ed17edf8cd3cbd9dae56cead0d69cb54f6af6aaecba544d8": "0x0ff6ffc06ff286230ff6ffc06ff2862300", + "0xdfaac108e0d4bc78fc9419a7fcfa84dc": "0x10f26cdb14b5aec7b2789fd5ca80f979cef3761897ae1f37ffb3e154cbcc1c2663547ff0ab649283a7ae01dbc2eb73932eba2fb09075e9485ff369082a2ff38d6568655684472b743e456907b398d3a44c113f189e56d1bbfd55e889e295dfde789c7a2ee14e565db0c69f78c7b4cd839fbf52b607d867e9e9c5a79042898a0d12", + "0x3ae31af9a378162eb2736f26855c9ad8": "0x4545454545454545454545454545454545454545454545454545454545454545", + "0x3a65787472696e7369635f696e646578": "0x00000000", + "0x8f9a319405d14f3953657373696f6e204b65794f776e6572343a73657373696f6e3a6b65797346c8960f8387b17441ee2be48a0896e48d3580e922c6e1cd8f53a621370c1e49": "0x68655684472b743e456907b398d3a44c113f189e56d1bbfd55e889e295dfde78", + "0x7e6064dc0e78ffebb59b3053826a9467": "0x109c7a2ee14e565db0c69f78c7b4cd839fbf52b607d867e9e9c5a79042898a0d1268655684472b743e456907b398d3a44c113f189e56d1bbfd55e889e295dfde78547ff0ab649283a7ae01dbc2eb73932eba2fb09075e9485ff369082a2ff38d65f26cdb14b5aec7b2789fd5ca80f979cef3761897ae1f37ffb3e154cbcc1c2663", + "0xc1fdc3d212357bc2fa98f2a77b941f0c": "0x10f26cdb14b5aec7b2789fd5ca80f979cef3761897ae1f37ffb3e154cbcc1c2663547ff0ab649283a7ae01dbc2eb73932eba2fb09075e9485ff369082a2ff38d6568655684472b743e456907b398d3a44c113f189e56d1bbfd55e889e295dfde789c7a2ee14e565db0c69f78c7b4cd839fbf52b607d867e9e9c5a79042898a0d12", + "0x8f9a319405d14f3953657373696f6e204b65794f776e6572343a73657373696f6e3a6b65797301dd273832961ca94116fd224019ea1370c0e3d27bebb1041b35651146d17832": "0x68655684472b743e456907b398d3a44c113f189e56d1bbfd55e889e295dfde78", + "0x686f6c72b7b80bad8dba022335cb7c9e4556ac7ea200008da8046e3178eb89c1": "0x0ff6ffc06ff286230ff6ffc06ff2862300", + "0x2d5205eddfc20f1a616c0391abb78a3920e823abe7ed33cfd7945dd1a1bf8651": "0x047374616b696e67200000c16ff28623000000000000000000ffffffff0f", + "0x040ff70c23416b89ce6afb75ee0d362e": "0x00000000", + "0x121725e2f949944d00a8c011c0db54ae07b84a6ca772adf3c65417345d91522d": "0x0000c16ff28623000000000000000000", + "0x9c16fd03b96712dc0751bb0d63bc05aa": "0x00e1f505", + "0x8f9a319405d14f3953657373696f6e204b65794f776e6572343a73657373696f6e3a6b657973d1ae046d940202772415992434f839d8c546542e3055143c430f7eec87f7cb69": "0xf26cdb14b5aec7b2789fd5ca80f979cef3761897ae1f37ffb3e154cbcc1c2663", + "0xccea67b51b4fa33ecbff70a8977ad91d9c60d620f3ab5ac9626dea15cde023b7": "0x0ff6ffc06ff286230ff6ffc06ff2862300", + "0x886726f904d8372fdabb7707870c2fad": "0x1000299981a2b92f878baaf5dbeba5c18d4e70f2a1fcd9c61b32ea18daf38f43780100000000000000482a3389a6cf42d8ed83888cfd920fec738ea30f97e44699ada7323f08c3380a0100000000000000482dbd7297a39fa145c570552249c2ca9dd47e281f0c500c971b59c9dcdcd82e01000000000000006e7e4eb42cbd2e0ab4cae8708ce5509580b8c04d11f6758dbf686d50fe9f91060100000000000000", + "0x68c8d2f39c4605e65218c22c5664917047e4900c797b7dd33999d94213c75049": "0x047374616b696e67200000c16ff28623000000000000000000ffffffff0f", + "0x7eb7a404bf7e3466c3f6c5914e25edfaab48b1e24fd29ea5a94deaaa1aba80e6": "0x0001547ff0ab649283a7ae01dbc2eb73932eba2fb09075e9485ff369082a2ff38d65019c7a2ee14e565db0c69f78c7b4cd839fbf52b607d867e9e9c5a79042898a0d12", + "0xdfa1667c116b77971ada377f9bd9c485a0566b8e477ae01969120423f2f124ea": "0x4545454545454545454545454545454545454545454545454545454545454545", + "0x92f53c21a80e624b3c606bc8ec0ce2a3003c4fe385bed33998bf4dc79b8970f2": "0x547ff0ab649283a7ae01dbc2eb73932eba2fb09075e9485ff369082a2ff38d650f0000c16ff286230f0000c16ff2862300", + "0xb2029f8665aac509629f2d28cea790a3": "0x10f26cdb14b5aec7b2789fd5ca80f979cef3761897ae1f37ffb3e154cbcc1c26633919132b851ef0fd2dae42a7e734fe547af5a6b809006100f48944d7fae8e8ef00299981a2b92f878baaf5dbeba5c18d4e70f2a1fcd9c61b32ea18daf38f437800299981a2b92f878baaf5dbeba5c18d4e70f2a1fcd9c61b32ea18daf38f4378547ff0ab649283a7ae01dbc2eb73932eba2fb09075e9485ff369082a2ff38d655633b70b80a6c8bb16270f82cca6d56b27ed7b76c8fd5af2986a25a4788ce440482a3389a6cf42d8ed83888cfd920fec738ea30f97e44699ada7323f08c3380a482a3389a6cf42d8ed83888cfd920fec738ea30f97e44699ada7323f08c3380a68655684472b743e456907b398d3a44c113f189e56d1bbfd55e889e295dfde787932cff431e748892fa48e10c63c17d30f80ca42e4de3921e641249cd7fa3c2f482dbd7297a39fa145c570552249c2ca9dd47e281f0c500c971b59c9dcdcd82e482dbd7297a39fa145c570552249c2ca9dd47e281f0c500c971b59c9dcdcd82e9c7a2ee14e565db0c69f78c7b4cd839fbf52b607d867e9e9c5a79042898a0d129becad03e6dcac03cee07edebca5475314861492cdfc96a2144a67bbe96993326e7e4eb42cbd2e0ab4cae8708ce5509580b8c04d11f6758dbf686d50fe9f91066e7e4eb42cbd2e0ab4cae8708ce5509580b8c04d11f6758dbf686d50fe9f9106", + "0xf4adb4c4f708c4b753657373696f6e204e6578744b657973343a73657373696f6e3a6b657973e54094c2d5af8ae10b91e1288f4f59f2946d7738f2c509b7effd909e5e9ba0ad": "0x5633b70b80a6c8bb16270f82cca6d56b27ed7b76c8fd5af2986a25a4788ce440482a3389a6cf42d8ed83888cfd920fec738ea30f97e44699ada7323f08c3380a482a3389a6cf42d8ed83888cfd920fec738ea30f97e44699ada7323f08c3380a", + "0x78f4ad73d6b7279f8d06f359e363c829": "0x0000a49d8fc957363600000000000000", + "0xfd0cbba69a04d769ddcdbb15f5123c98041978f5241f33f78f62b48e3a02b740": "0x047374616b696e67200000c16ff28623000000000000000000ffffffff0f", + "0x26ac4a74e1ba94e0e7dbfc3b2aea083cf3c0f0d80eb999c7cebb340ee8934da9": "0x68655684472b743e456907b398d3a44c113f189e56d1bbfd55e889e295dfde780f0000c16ff286230f0000c16ff2862300", + "0xf4adb4c4f708c4b753657373696f6e204e6578744b657973343a73657373696f6e3a6b65797394f72a73893fbd00b11fcce65a014cc5b9ff5066ec15aa6be068b4cabfe67fdb": "0x3919132b851ef0fd2dae42a7e734fe547af5a6b809006100f48944d7fae8e8ef00299981a2b92f878baaf5dbeba5c18d4e70f2a1fcd9c61b32ea18daf38f437800299981a2b92f878baaf5dbeba5c18d4e70f2a1fcd9c61b32ea18daf38f4378", + "0x4ac2684a5a20e7a5adf17ed7aa792a3f6334a0505f02b2a44c3934d36cc4ee0a": "0xc8dc79e36b29395413399edaec3e20fcca7205fb19776ed8ddb25d6f427ec40e", + "0xa5e869ecc1b914a6b0cf5f02b874f5eb90f1739fbd3edd01e5835d1517fd9f72": "0x781ead1e2fa9ccb74b44c19d29cb2a7a4b5be3972927ae98cd3877523976a276" + }, + {} + ] } } diff --git a/node/cli/src/chain_spec.rs b/node/cli/src/chain_spec.rs index fbc3f18f65c528eacb3cec4ce9aff36525e22312..905e867436e593e68759fbb4f35d015f3fa4f9e8 100644 --- a/node/cli/src/chain_spec.rs +++ b/node/cli/src/chain_spec.rs @@ -16,28 +16,44 @@ //! Substrate chain configurations. +use chain_spec::ChainSpecExtension; use primitives::{Pair, Public, crypto::UncheckedInto}; -pub use node_primitives::{AccountId, Balance}; +use serde::{Serialize, Deserialize}; use node_runtime::{ - BabeConfig, BalancesConfig, ContractsConfig, CouncilConfig, DemocracyConfig, - ElectionsConfig, GrandpaConfig, ImOnlineConfig, IndicesConfig, Perbill, - SessionConfig, SessionKeys, StakerStatus, StakingConfig, SudoConfig, SystemConfig, - TechnicalCommitteeConfig, WASM_BINARY, + AuthorityDiscoveryConfig, BabeConfig, BalancesConfig, ContractsConfig, CouncilConfig, DemocracyConfig, + ElectionsConfig, GrandpaConfig, ImOnlineConfig, IndicesConfig, SessionConfig, SessionKeys, StakerStatus, + StakingConfig, SudoConfig, SystemConfig, TechnicalCommitteeConfig, WASM_BINARY, }; +use node_runtime::Block; use node_runtime::constants::{time::*, currency::*}; -pub use node_runtime::GenesisConfig; use substrate_service; use hex_literal::hex; use substrate_telemetry::TelemetryEndpoints; use grandpa_primitives::{AuthorityId as GrandpaId}; use babe_primitives::{AuthorityId as BabeId}; -use im_online::AuthorityId as ImOnlineId; +use im_online::sr25519::{AuthorityId as ImOnlineId}; +use sr_primitives::Perbill; + +pub use node_primitives::{AccountId, Balance}; +pub use node_runtime::GenesisConfig; const STAGING_TELEMETRY_URL: &str = "wss://telemetry.polkadot.io/submit/"; -/// Specialized `ChainSpec`. -pub type ChainSpec = substrate_service::ChainSpec; +/// Node `ChainSpec` extensions. +/// +/// Additional parameters for some Substrate core modules, +/// customizable from the chain spec. +#[derive(Default, Clone, Serialize, Deserialize, ChainSpecExtension)] +pub struct Extensions { + /// Block numbers with known hashes. + pub fork_blocks: client::ForkBlocks, +} +/// Specialized `ChainSpec`. +pub type ChainSpec = substrate_service::ChainSpec< + GenesisConfig, + Extensions, +>; /// Flaming Fir testnet generator pub fn flaming_fir_config() -> Result { ChainSpec::from_json_bytes(&include_bytes!("../res/flaming-fir.json")[..]) @@ -59,45 +75,45 @@ fn staging_testnet_config_genesis() -> GenesisConfig { hex!["9c7a2ee14e565db0c69f78c7b4cd839fbf52b607d867e9e9c5a79042898a0d12"].unchecked_into(), // 5EnCiV7wSHeNhjW3FSUwiJNkcc2SBkPLn5Nj93FmbLtBjQUq hex!["781ead1e2fa9ccb74b44c19d29cb2a7a4b5be3972927ae98cd3877523976a276"].unchecked_into(), - // 5EZaeQ8djPcq9pheJUhgerXQZt9YaHnMJpiHMRhwQeinqUW8 - hex!["6e7e4eb42cbd2e0ab4cae8708ce5509580b8c04d11f6758dbf686d50fe9f9106"].unchecked_into(), - // 5Fb9ayurnxnaXj56CjmyQLBiadfRCqUbL2VWNbbe1nZU6wiC - hex!["9becad03e6dcac03cee07edebca5475314861492cdfc96a2144a67bbe9699332"].unchecked_into(), // 5Fb9ayurnxnaXj56CjmyQLBiadfRCqUbL2VWNbbe1nZU6wiC hex!["9becad03e6dcac03cee07edebca5475314861492cdfc96a2144a67bbe9699332"].unchecked_into(), + // 5EZaeQ8djPcq9pheJUhgerXQZt9YaHnMJpiHMRhwQeinqUW8 + hex!["6e7e4eb42cbd2e0ab4cae8708ce5509580b8c04d11f6758dbf686d50fe9f9106"].unchecked_into(), + // 5EZaeQ8djPcq9pheJUhgerXQZt9YaHnMJpiHMRhwQeinqUW8 + hex!["6e7e4eb42cbd2e0ab4cae8708ce5509580b8c04d11f6758dbf686d50fe9f9106"].unchecked_into(), ),( // 5ERawXCzCWkjVq3xz1W5KGNtVx2VdefvZ62Bw1FEuZW4Vny2 hex!["68655684472b743e456907b398d3a44c113f189e56d1bbfd55e889e295dfde78"].unchecked_into(), // 5Gc4vr42hH1uDZc93Nayk5G7i687bAQdHHc9unLuyeawHipF hex!["c8dc79e36b29395413399edaec3e20fcca7205fb19776ed8ddb25d6f427ec40e"].unchecked_into(), - // 5DhLtiaQd1L1LU9jaNeeu9HJkP6eyg3BwXA7iNMzKm7qqruQ - hex!["482dbd7297a39fa145c570552249c2ca9dd47e281f0c500c971b59c9dcdcd82e"].unchecked_into(), - // 5EockCXN6YkiNCDjpqqnbcqd4ad35nU4RmA1ikM4YeRN4WcE - hex!["7932cff431e748892fa48e10c63c17d30f80ca42e4de3921e641249cd7fa3c2f"].unchecked_into(), // 5EockCXN6YkiNCDjpqqnbcqd4ad35nU4RmA1ikM4YeRN4WcE hex!["7932cff431e748892fa48e10c63c17d30f80ca42e4de3921e641249cd7fa3c2f"].unchecked_into(), + // 5DhLtiaQd1L1LU9jaNeeu9HJkP6eyg3BwXA7iNMzKm7qqruQ + hex!["482dbd7297a39fa145c570552249c2ca9dd47e281f0c500c971b59c9dcdcd82e"].unchecked_into(), + // 5DhLtiaQd1L1LU9jaNeeu9HJkP6eyg3BwXA7iNMzKm7qqruQ + hex!["482dbd7297a39fa145c570552249c2ca9dd47e281f0c500c971b59c9dcdcd82e"].unchecked_into(), ),( // 5DyVtKWPidondEu8iHZgi6Ffv9yrJJ1NDNLom3X9cTDi98qp hex!["547ff0ab649283a7ae01dbc2eb73932eba2fb09075e9485ff369082a2ff38d65"].unchecked_into(), // 5FeD54vGVNpFX3PndHPXJ2MDakc462vBCD5mgtWRnWYCpZU9 hex!["9e42241d7cd91d001773b0b616d523dd80e13c6c2cab860b1234ef1b9ffc1526"].unchecked_into(), - // 5DhKqkHRkndJu8vq7pi2Q5S3DfftWJHGxbEUNH43b46qNspH - hex!["482a3389a6cf42d8ed83888cfd920fec738ea30f97e44699ada7323f08c3380a"].unchecked_into(), - // 5E1jLYfLdUQKrFrtqoKgFrRvxM3oQPMbf6DfcsrugZZ5Bn8d - hex!["5633b70b80a6c8bb16270f82cca6d56b27ed7b76c8fd5af2986a25a4788ce440"].unchecked_into(), // 5E1jLYfLdUQKrFrtqoKgFrRvxM3oQPMbf6DfcsrugZZ5Bn8d hex!["5633b70b80a6c8bb16270f82cca6d56b27ed7b76c8fd5af2986a25a4788ce440"].unchecked_into(), + // 5DhKqkHRkndJu8vq7pi2Q5S3DfftWJHGxbEUNH43b46qNspH + hex!["482a3389a6cf42d8ed83888cfd920fec738ea30f97e44699ada7323f08c3380a"].unchecked_into(), + // 5DhKqkHRkndJu8vq7pi2Q5S3DfftWJHGxbEUNH43b46qNspH + hex!["482a3389a6cf42d8ed83888cfd920fec738ea30f97e44699ada7323f08c3380a"].unchecked_into(), ),( // 5HYZnKWe5FVZQ33ZRJK1rG3WaLMztxWrrNDb1JRwaHHVWyP9 hex!["f26cdb14b5aec7b2789fd5ca80f979cef3761897ae1f37ffb3e154cbcc1c2663"].unchecked_into(), // 5EPQdAQ39WQNLCRjWsCk5jErsCitHiY5ZmjfWzzbXDoAoYbn hex!["66bc1e5d275da50b72b15de072a2468a5ad414919ca9054d2695767cf650012f"].unchecked_into(), - // 5C4vDQxA8LTck2xJEy4Yg1hM9qjDt4LvTQaMo4Y8ne43aU6x - hex!["00299981a2b92f878baaf5dbeba5c18d4e70f2a1fcd9c61b32ea18daf38f4378"].unchecked_into(), - // 5DMa31Hd5u1dwoRKgC4uvqyrdK45RHv3CpwvpUC1EzuwDit4 - hex!["3919132b851ef0fd2dae42a7e734fe547af5a6b809006100f48944d7fae8e8ef"].unchecked_into(), // 5DMa31Hd5u1dwoRKgC4uvqyrdK45RHv3CpwvpUC1EzuwDit4 hex!["3919132b851ef0fd2dae42a7e734fe547af5a6b809006100f48944d7fae8e8ef"].unchecked_into(), + // 5C4vDQxA8LTck2xJEy4Yg1hM9qjDt4LvTQaMo4Y8ne43aU6x + hex!["00299981a2b92f878baaf5dbeba5c18d4e70f2a1fcd9c61b32ea18daf38f4378"].unchecked_into(), + // 5C4vDQxA8LTck2xJEy4Yg1hM9qjDt4LvTQaMo4Y8ne43aU6x + hex!["00299981a2b92f878baaf5dbeba5c18d4e70f2a1fcd9c61b32ea18daf38f4378"].unchecked_into(), )]; // generated with secret: subkey inspect "$secret"/fir @@ -133,14 +149,13 @@ fn staging_testnet_config_genesis() -> GenesisConfig { }), staking: Some(StakingConfig { current_era: 0, - offline_slash: Perbill::from_parts(1_000_000), validator_count: 7, - offline_slash_grace: 4, minimum_validator_count: 4, stakers: initial_authorities.iter().map(|x| { (x.0.clone(), x.1.clone(), STASH, StakerStatus::Validator) }).collect(), invulnerables: initial_authorities.iter().map(|x| x.0.clone()).collect(), + slash_reward_fraction: Perbill::from_percent(10), .. Default::default() }), democracy: Some(DemocracyConfig::default()), @@ -166,13 +181,16 @@ fn staging_testnet_config_genesis() -> GenesisConfig { key: endowed_accounts[0].clone(), }), babe: Some(BabeConfig { - authorities: initial_authorities.iter().map(|x| (x.3.clone(), 1)).collect(), + authorities: vec![], }), im_online: Some(ImOnlineConfig { - keys: initial_authorities.iter().map(|x| x.4.clone()).collect(), + keys: vec![], + }), + authority_discovery: Some(AuthorityDiscoveryConfig{ + keys: vec![], }), grandpa: Some(GrandpaConfig { - authorities: initial_authorities.iter().map(|x| (x.2.clone(), 1)).collect(), + authorities: vec![], }), membership_Instance1: Some(Default::default()), } @@ -189,7 +207,7 @@ pub fn staging_testnet_config() -> ChainSpec { Some(TelemetryEndpoints::new(vec![(STAGING_TELEMETRY_URL.to_string(), 0)])), None, None, - None, + Default::default(), ) } @@ -262,12 +280,11 @@ pub fn testnet_genesis( current_era: 0, minimum_validator_count: 1, validator_count: 2, - offline_slash: Perbill::zero(), - offline_slash_grace: 0, stakers: initial_authorities.iter().map(|x| { (x.0.clone(), x.1.clone(), STASH, StakerStatus::Validator) }).collect(), invulnerables: initial_authorities.iter().map(|x| x.0.clone()).collect(), + slash_reward_fraction: Perbill::from_percent(10), .. Default::default() }), democracy: Some(DemocracyConfig::default()), @@ -298,13 +315,16 @@ pub fn testnet_genesis( key: root_key, }), babe: Some(BabeConfig { - authorities: initial_authorities.iter().map(|x| (x.3.clone(), 1)).collect(), + authorities: vec![], + }), + im_online: Some(ImOnlineConfig { + keys: vec![], }), - im_online: Some(ImOnlineConfig{ - keys: initial_authorities.iter().map(|x| x.4.clone()).collect(), + authority_discovery: Some(AuthorityDiscoveryConfig{ + keys: vec![], }), grandpa: Some(GrandpaConfig { - authorities: initial_authorities.iter().map(|x| (x.2.clone(), 1)).collect(), + authorities: vec![], }), membership_Instance1: Some(Default::default()), } @@ -323,7 +343,16 @@ fn development_config_genesis() -> GenesisConfig { /// Development config (single validator Alice) pub fn development_config() -> ChainSpec { - ChainSpec::from_genesis("Development", "dev", development_config_genesis, vec![], None, None, None, None) + ChainSpec::from_genesis( + "Development", + "dev", + development_config_genesis, + vec![], + None, + None, + None, + Default::default(), + ) } fn local_testnet_genesis() -> GenesisConfig { @@ -340,14 +369,24 @@ fn local_testnet_genesis() -> GenesisConfig { /// Local testnet config (multivalidator Alice + Bob) pub fn local_testnet_config() -> ChainSpec { - ChainSpec::from_genesis("Local Testnet", "local_testnet", local_testnet_genesis, vec![], None, None, None, None) + ChainSpec::from_genesis( + "Local Testnet", + "local_testnet", + local_testnet_genesis, + vec![], + None, + None, + None, + Default::default(), + ) } #[cfg(test)] pub(crate) mod tests { use super::*; + use crate::service::new_full; + use substrate_service::Roles; use service_test; - use crate::service::Factory; fn local_testnet_genesis_instant_single() -> GenesisConfig { testnet_genesis( @@ -370,7 +409,7 @@ pub(crate) mod tests { None, None, None, - None, + Default::default(), ) } @@ -384,13 +423,22 @@ pub(crate) mod tests { None, None, None, - None, + Default::default(), ) } #[test] #[ignore] fn test_connectivity() { - service_test::connectivity::(integration_test_config_with_two_authorities()); + service_test::connectivity( + integration_test_config_with_two_authorities(), + |config| new_full(config), + |mut config| { + // light nodes are unsupported + config.roles = Roles::FULL; + new_full(config) + }, + true, + ); } } diff --git a/node/cli/src/factory_impl.rs b/node/cli/src/factory_impl.rs index 6345a851f28ab115f8d3b846ef40ffd4458c1a5b..827b8e308c8f18dc5a688a7c4a1c1542e148184b 100644 --- a/node/cli/src/factory_impl.rs +++ b/node/cli/src/factory_impl.rs @@ -23,7 +23,10 @@ use rand::rngs::StdRng; use codec::{Encode, Decode}; use keyring::sr25519::Keyring; -use node_runtime::{Call, CheckedExtrinsic, UncheckedExtrinsic, SignedExtra, BalancesCall, ExistentialDeposit}; +use node_runtime::{ + Call, CheckedExtrinsic, UncheckedExtrinsic, SignedExtra, BalancesCall, ExistentialDeposit, + MinimumPeriod, +}; use primitives::{sr25519, crypto::Pair}; use sr_primitives::{generic::Era, traits::{Block as BlockT, Header as HeaderT, SignedExtension}}; use transaction_factory::RuntimeAdapter; @@ -32,9 +35,6 @@ use inherents::InherentData; use timestamp; use finality_tracker; -// TODO get via api: ::MinimumPeriod::get(). See #2587. -const MINIMUM_PERIOD: u64 = 99; - pub struct FactoryState { block_no: N, @@ -51,11 +51,13 @@ type Number = <::Header as HeaderT>::Number; impl FactoryState { fn build_extra(index: node_primitives::Index, phase: u64) -> node_runtime::SignedExtra { ( + system::CheckVersion::new(), system::CheckGenesis::new(), system::CheckEra::from(Era::mortal(256, phase)), system::CheckNonce::from(index), system::CheckWeight::new(), - balances::TakeFees::from(0) + balances::TakeFees::from(0), + Default::default(), ) } } @@ -132,12 +134,12 @@ impl RuntimeAdapter for FactoryState { key: &Self::Secret, destination: &Self::AccountId, amount: &Self::Balance, + version: u32, genesis_hash: &::Hash, prior_block_hash: &::Hash, ) -> ::Extrinsic { let index = self.extract_index(&sender, prior_block_hash); let phase = self.extract_phase(*prior_block_hash); - sign::(CheckedExtrinsic { signed: Some((sender.clone(), Self::build_extra(index, phase))), function: Call::Balances( @@ -146,11 +148,11 @@ impl RuntimeAdapter for FactoryState { (*amount).into() ) ) - }, key, (genesis_hash.clone(), prior_block_hash.clone(), (), (), ())) + }, key, (version, genesis_hash.clone(), prior_block_hash.clone(), (), (), (), ())) } fn inherent_extrinsics(&self) -> InherentData { - let timestamp = self.block_no as u64 * MINIMUM_PERIOD; + let timestamp = (self.block_no as u64 + 1) * MinimumPeriod::get(); let mut inherent = InherentData::new(); inherent.put_data(timestamp::INHERENT_IDENTIFIER, ×tamp) @@ -161,7 +163,6 @@ impl RuntimeAdapter for FactoryState { } fn minimum_balance() -> Self::Balance { - // TODO get correct amount via api. See #2587. ExistentialDeposit::get() } diff --git a/node/cli/src/lib.rs b/node/cli/src/lib.rs index 4e3cfa7f0109217f81512f29fc3905e5cb1e97a2..a4deed37c1e37931751b605c7f1a26a568e6ec91 100644 --- a/node/cli/src/lib.rs +++ b/node/cli/src/lib.rs @@ -21,14 +21,14 @@ pub use cli::error; pub mod chain_spec; +#[macro_use] mod service; mod factory_impl; use tokio::prelude::Future; use tokio::runtime::{Builder as RuntimeBuilder, Runtime}; pub use cli::{VersionInfo, IntoExit, NoCustom, SharedParams, ExecutionStrategyParam}; -use substrate_service::{ServiceFactory, Roles as ServiceRoles}; -use std::ops::Deref; +use substrate_service::{AbstractService, Roles as ServiceRoles, Configuration}; use log::info; use structopt::{StructOpt, clap::App}; use cli::{AugmentClap, GetLogFilter, parse_and_prepare, ParseAndPrepare}; @@ -158,8 +158,11 @@ pub fn run(args: I, exit: E, version: cli::VersionInfo) -> error::Resul T: Into + Clone, E: IntoExit, { + type Config = Configuration<(), A, B>; + match parse_and_prepare::(&version, "substrate-node", args) { - ParseAndPrepare::Run(cmd) => cmd.run(load_spec, exit, |exit, _cli_args, _custom_args, config| { + ParseAndPrepare::Run(cmd) => cmd.run(load_spec, exit, + |exit, _cli_args, _custom_args, config: Config<_, _>| { info!("{}", version.name); info!(" version {}", config.full_version()); info!(" by Parity Technologies, 2017-2019"); @@ -171,23 +174,26 @@ pub fn run(args: I, exit: E, version: cli::VersionInfo) -> error::Resul match config.roles { ServiceRoles::LIGHT => run_until_exit( runtime, - service::Factory::new_light(config).map_err(|e| format!("{:?}", e))?, + service::new_light(config).map_err(|e| format!("{:?}", e))?, exit ), _ => run_until_exit( runtime, - service::Factory::new_full(config).map_err(|e| format!("{:?}", e))?, + service::new_full(config).map_err(|e| format!("{:?}", e))?, exit ), }.map_err(|e| format!("{:?}", e)) }), ParseAndPrepare::BuildSpec(cmd) => cmd.run(load_spec), - ParseAndPrepare::ExportBlocks(cmd) => cmd.run::(load_spec, exit), - ParseAndPrepare::ImportBlocks(cmd) => cmd.run::(load_spec, exit), + ParseAndPrepare::ExportBlocks(cmd) => cmd.run_with_builder(|config: Config<_, _>| + Ok(new_full_start!(config).0), load_spec, exit), + ParseAndPrepare::ImportBlocks(cmd) => cmd.run_with_builder(|config: Config<_, _>| + Ok(new_full_start!(config).0), load_spec, exit), ParseAndPrepare::PurgeChain(cmd) => cmd.run(load_spec), - ParseAndPrepare::RevertChain(cmd) => cmd.run::(load_spec), + ParseAndPrepare::RevertChain(cmd) => cmd.run_with_builder(|config: Config<_, _>| + Ok(new_full_start!(config).0), load_spec), ParseAndPrepare::CustomCommand(CustomSubcommands::Factory(cli_args)) => { - let mut config = cli::create_config_with_db_path( + let mut config: Config<_, _> = cli::create_config_with_db_path( load_spec, &cli_args.shared_params, &version, @@ -209,9 +215,13 @@ pub fn run(args: I, exit: E, version: cli::VersionInfo) -> error::Resul cli_args.num, cli_args.rounds, ); - transaction_factory::factory::>( + + let service_builder = new_full_start!(config).0; + transaction_factory::factory::, _, _, _, _, _>( factory_state, - config, + service_builder.client(), + service_builder.select_chain() + .expect("The select_chain is always initialized by new_full_start!; QED") ).map_err(|e| format!("Error in transaction factory: {}", e))?; Ok(()) @@ -219,14 +229,13 @@ pub fn run(args: I, exit: E, version: cli::VersionInfo) -> error::Resul } } -fn run_until_exit( +fn run_until_exit( mut runtime: Runtime, service: T, e: E, -) -> error::Result<()> where - T: Deref>, - T: Future + Send + 'static, - C: substrate_service::Components, +) -> error::Result<()> +where + T: AbstractService, E: IntoExit, { let (exit_send, exit) = exit_future::signal(); diff --git a/node/cli/src/service.rs b/node/cli/src/service.rs index 90c76eda84cbe2f37215169aa90fe050307ff8cc..7012a3d6ce0ad3e98ae54f6d8b786a865a05ce0f 100644 --- a/node/cli/src/service.rs +++ b/node/cli/src/service.rs @@ -16,294 +16,334 @@ #![warn(unused_extern_crates)] -//! Service and ServiceFactory implementation. Specialized wrapper over substrate service. +//! Service implementation. Specialized wrapper over substrate service. use std::sync::Arc; -use std::time::Duration; -use babe::{import_queue, start_babe, BabeImportQueue, Config}; +use babe; use client::{self, LongestChain}; use grandpa::{self, FinalityProofProvider as GrandpaFinalityProofProvider}; use node_executor; -use futures::prelude::*; use node_primitives::Block; use node_runtime::{GenesisConfig, RuntimeApi}; use substrate_service::{ - FactoryFullConfiguration, LightComponents, FullComponents, FullBackend, - FullClient, LightClient, LightBackend, FullExecutor, LightExecutor, - error::{Error as ServiceError}, + AbstractService, ServiceBuilder, config::Configuration, error::{Error as ServiceError}, }; use transaction_pool::{self, txpool::{Pool as TransactionPool}}; use inherents::InherentDataProviders; use network::construct_simple_protocol; -use substrate_service::construct_service_factory; -use substrate_service::TelemetryOnConnect; + +use substrate_service::{NewService, NetworkStatus}; +use client::{Client, LocalCallExecutor}; +use client_db::Backend; +use sr_primitives::traits::Block as BlockT; +use node_executor::NativeExecutor; +use network::NetworkService; +use offchain::OffchainWorkers; +use primitives::Blake2Hasher; construct_simple_protocol! { /// Demo protocol attachment for substrate. pub struct NodeProtocol where Block = Block { } } -type BabeBlockImportForService = babe::BabeBlockImport< - FullBackend, - FullExecutor, - ::Block, - grandpa::BlockImportForService, - ::RuntimeApi, - client::Client< - FullBackend, - FullExecutor, - ::Block, - ::RuntimeApi - >, ->; - -/// Node specific configuration -pub struct NodeConfig { - /// GRANDPA and BABE connection to import block. - // FIXME #1134 rather than putting this on the config, let's have an actual intermediate setup state - pub import_setup: Option<( - BabeBlockImportForService, - grandpa::LinkHalfForService, - babe::BabeLink, - )>, - /// Tasks that were created by previous setup steps and should be spawned. - pub tasks_to_spawn: Option + Send>>>, - inherent_data_providers: InherentDataProviders, -} - -impl Default for NodeConfig where F: substrate_service::ServiceFactory { - fn default() -> NodeConfig { - NodeConfig { - import_setup: None, - inherent_data_providers: InherentDataProviders::new(), - tasks_to_spawn: None, - } - } -} - -construct_service_factory! { - struct Factory { - Block = Block, - RuntimeApi = RuntimeApi, - NetworkProtocol = NodeProtocol { |config| Ok(NodeProtocol::new()) }, - RuntimeDispatch = node_executor::Executor, - FullTransactionPoolApi = - transaction_pool::ChainApi< - client::Client, FullExecutor, Block, RuntimeApi>, - Block - > { - |config, client| - Ok(TransactionPool::new(config, transaction_pool::ChainApi::new(client))) - }, - LightTransactionPoolApi = - transaction_pool::ChainApi< - client::Client, LightExecutor, Block, RuntimeApi>, - Block - > { - |config, client| - Ok(TransactionPool::new(config, transaction_pool::ChainApi::new(client))) - }, - Genesis = GenesisConfig, - Configuration = NodeConfig, - FullService = FullComponents { - |config: FactoryFullConfiguration| FullComponents::::new(config) - }, - AuthoritySetup = { - |mut service: Self::FullService| { - let (block_import, link_half, babe_link) = - service.config_mut().custom.import_setup.take() - .expect("Link Half and Block Import are present for Full Services or setup failed before. qed"); - - // spawn any futures that were created in the previous setup steps - if let Some(tasks) = service.config_mut().custom.tasks_to_spawn.take() { - for task in tasks { - service.spawn_task( - task.select(service.on_exit()) - .map(|_| ()) - .map_err(|_| ()) - ); - } - } - - if service.config().roles.is_authority() { - let proposer = substrate_basic_authorship::ProposerFactory { - client: service.client(), - transaction_pool: service.transaction_pool(), - }; - - let client = service.client(); - let select_chain = service.select_chain() - .ok_or(ServiceError::SelectChainRequired)?; - - let babe_config = babe::BabeParams { - config: Config::get_or_compute(&*client)?, - keystore: service.keystore(), - client, - select_chain, - block_import, - env: proposer, - sync_oracle: service.network(), - inherent_data_providers: service.config() - .custom.inherent_data_providers.clone(), - force_authoring: service.config().force_authoring, - time_source: babe_link, - }; - - let babe = start_babe(babe_config)?; - let select = babe.select(service.on_exit()).then(|_| Ok(())); - - // the BABE authoring task is considered infallible, i.e. if it - // fails we take down the service with it. - service.spawn_essential_task(select); - } - - let config = grandpa::Config { - // FIXME #1578 make this available through chainspec - gossip_duration: Duration::from_millis(333), - justification_period: 4096, - name: Some(service.config().name.clone()), - keystore: Some(service.keystore()), - }; - - match (service.config().roles.is_authority(), service.config().disable_grandpa) { - (false, false) => { - // start the lightweight GRANDPA observer - service.spawn_task(Box::new(grandpa::run_grandpa_observer( - config, - link_half, - service.network(), - service.on_exit(), - )?)); - }, - (true, false) => { - // start the full GRANDPA voter - let telemetry_on_connect = TelemetryOnConnect { - telemetry_connection_sinks: service.telemetry_on_connect_stream(), - }; - let grandpa_config = grandpa::GrandpaParams { - config: config, - link: link_half, - network: service.network(), - inherent_data_providers: - service.config().custom.inherent_data_providers.clone(), - on_exit: service.on_exit(), - telemetry_on_connect: Some(telemetry_on_connect), - }; - - // the GRANDPA voter task is considered infallible, i.e. - // if it fails we take down the service with it. - service.spawn_essential_task(grandpa::run_grandpa_voter(grandpa_config)?); - }, - (_, true) => { - grandpa::setup_disabled_grandpa( - service.client(), - &service.config().custom.inherent_data_providers, - service.network(), - )?; - }, - } - - Ok(service) - } - }, - LightService = LightComponents - { |config| >::new(config) }, - FullImportQueue = BabeImportQueue - { - | - config: &mut FactoryFullConfiguration, - client: Arc>, - select_chain: Self::SelectChain, - transaction_pool: Option>>, - | - { - let (block_import, link_half) = - grandpa::block_import::<_, _, _, RuntimeApi, FullClient, _>( - client.clone(), client.clone(), select_chain +/// Starts a `ServiceBuilder` for a full service. +/// +/// Use this macro if you don't actually need the full service, but just the builder in order to +/// be able to perform chain operations. +macro_rules! new_full_start { + ($config:expr) => {{ + type RpcExtension = jsonrpc_core::IoHandler; + let mut import_setup = None; + let inherent_data_providers = inherents::InherentDataProviders::new(); + + let builder = substrate_service::ServiceBuilder::new_full::< + node_primitives::Block, node_runtime::RuntimeApi, node_executor::Executor + >($config)? + .with_select_chain(|_config, backend| { + Ok(client::LongestChain::new(backend.clone())) + })? + .with_transaction_pool(|config, client| + Ok(transaction_pool::txpool::Pool::new(config, transaction_pool::FullChainApi::new(client))) + )? + .with_import_queue(|_config, client, mut select_chain, _transaction_pool| { + let select_chain = select_chain.take() + .ok_or_else(|| substrate_service::Error::SelectChainRequired)?; + let (grandpa_block_import, grandpa_link) = + grandpa::block_import::<_, _, _, node_runtime::RuntimeApi, _, _>( + client.clone(), &*client, select_chain )?; - let justification_import = block_import.clone(); + let justification_import = grandpa_block_import.clone(); + + let (block_import, babe_link) = babe::block_import( + babe::Config::get_or_compute(&*client)?, + grandpa_block_import, + client.clone(), + client.clone(), + )?; - let (import_queue, babe_link, babe_block_import, pruning_task) = import_queue( - Config::get_or_compute(&*client)?, - block_import, + let import_queue = babe::import_queue( + babe_link.clone(), + block_import.clone(), Some(Box::new(justification_import)), None, client.clone(), client, - config.custom.inherent_data_providers.clone(), - transaction_pool, + inherent_data_providers.clone(), )?; - config.custom.import_setup = Some((babe_block_import.clone(), link_half, babe_link)); - config.custom.tasks_to_spawn = Some(vec![Box::new(pruning_task)]); - + import_setup = Some((block_import, grandpa_link, babe_link)); Ok(import_queue) - }}, - LightImportQueue = BabeImportQueue - { |config: &FactoryFullConfiguration, client: Arc>| { - #[allow(deprecated)] - let fetch_checker = client.backend().blockchain().fetcher() - .upgrade() - .map(|fetcher| fetcher.checker().clone()) - .ok_or_else(|| "Trying to start light import queue without active fetch checker")?; - let block_import = grandpa::light_block_import::<_, _, _, RuntimeApi, LightClient>( - client.clone(), Arc::new(fetch_checker), client.clone() - )?; + })? + .with_rpc_extensions(|client, pool| -> RpcExtension { + node_rpc::create(client, pool) + })?; - let finality_proof_import = block_import.clone(); - let finality_proof_request_builder = - finality_proof_import.create_finality_proof_request_builder(); + (builder, import_setup, inherent_data_providers) + }} +} - // FIXME: pruning task isn't started since light client doesn't do `AuthoritySetup`. - let (import_queue, ..) = import_queue::<_, _, _, _, _, _, TransactionPool>( - Config::get_or_compute(&*client)?, - block_import, - None, - Some(Box::new(finality_proof_import)), - client.clone(), - client, - config.custom.inherent_data_providers.clone(), - None, +/// Creates a full service from the configuration. +/// +/// We need to use a macro because the test suit doesn't work with an opaque service. It expects +/// concrete types instead. +macro_rules! new_full { + ($config:expr, $with_startup_data: expr) => {{ + use futures::sync::mpsc; + use network::DhtEvent; + + let ( + is_authority, + force_authoring, + name, + disable_grandpa + ) = ( + $config.roles.is_authority(), + $config.force_authoring, + $config.name.clone(), + $config.disable_grandpa + ); + + let (builder, mut import_setup, inherent_data_providers) = new_full_start!($config); + + // Dht event channel from the network to the authority discovery module. Use bounded channel to ensure + // back-pressure. Authority discovery is triggering one event per authority within the current authority set. + // This estimates the authority set size to be somewhere below 10 000 thereby setting the channel buffer size to + // 10 000. + let (dht_event_tx, dht_event_rx) = + mpsc::channel::(10000); + + let service = builder.with_network_protocol(|_| Ok(crate::service::NodeProtocol::new()))? + .with_finality_proof_provider(|client, backend| + Ok(Arc::new(grandpa::FinalityProofProvider::new(backend, client)) as _) + )? + .with_dht_event_tx(dht_event_tx)? + .build()?; + + let (block_import, grandpa_link, babe_link) = import_setup.take() + .expect("Link Half and Block Import are present for Full Services or setup failed before. qed"); + + ($with_startup_data)(&block_import, &babe_link); + + if is_authority { + let proposer = substrate_basic_authorship::ProposerFactory { + client: service.client(), + transaction_pool: service.transaction_pool(), + }; + + let client = service.client(); + let select_chain = service.select_chain() + .ok_or(substrate_service::Error::SelectChainRequired)?; + + let babe_config = babe::BabeParams { + keystore: service.keystore(), + client, + select_chain, + env: proposer, + block_import, + sync_oracle: service.network(), + inherent_data_providers: inherent_data_providers.clone(), + force_authoring, + babe_link, + }; + + let babe = babe::start_babe(babe_config)?; + service.spawn_essential_task(babe); + + let authority_discovery = authority_discovery::AuthorityDiscovery::new( + service.client(), + service.network(), + dht_event_rx, + ); + service.spawn_task(authority_discovery); + } + + let config = grandpa::Config { + // FIXME #1578 make this available through chainspec + gossip_duration: std::time::Duration::from_millis(333), + justification_period: 512, + name: Some(name), + keystore: Some(service.keystore()), + }; + + match (is_authority, disable_grandpa) { + (false, false) => { + // start the lightweight GRANDPA observer + service.spawn_task(Box::new(grandpa::run_grandpa_observer( + config, + grandpa_link, + service.network(), + service.on_exit(), + )?)); + }, + (true, false) => { + // start the full GRANDPA voter + let grandpa_config = grandpa::GrandpaParams { + config: config, + link: grandpa_link, + network: service.network(), + inherent_data_providers: inherent_data_providers.clone(), + on_exit: service.on_exit(), + telemetry_on_connect: Some(service.telemetry_on_connect_stream()), + }; + service.spawn_task(Box::new(grandpa::run_grandpa_voter(grandpa_config)?)); + }, + (_, true) => { + grandpa::setup_disabled_grandpa( + service.client(), + &inherent_data_providers, + service.network(), )?; + }, + } - Ok((import_queue, finality_proof_request_builder)) - }}, - SelectChain = LongestChain, Self::Block> - { |config: &FactoryFullConfiguration, client: Arc>| { - #[allow(deprecated)] - Ok(LongestChain::new(client.backend().clone())) - } - }, - FinalityProofProvider = { |client: Arc>| { - Ok(Some(Arc::new(GrandpaFinalityProofProvider::new(client.clone(), client)) as _)) - }}, - } + Ok((service, inherent_data_providers)) + }}; + ($config:expr) => {{ + new_full!($config, |_, _| {}) + }} +} + +#[allow(dead_code)] +type ConcreteBlock = node_primitives::Block; +#[allow(dead_code)] +type ConcreteClient = + Client< + Backend, + LocalCallExecutor, + NativeExecutor>, + ConcreteBlock, + node_runtime::RuntimeApi + >; +#[allow(dead_code)] +type ConcreteBackend = Backend; + +/// A specialized configuration object for setting up the node.. +pub type NodeConfiguration = Configuration; + +/// Builds a new service for a full client. +pub fn new_full(config: NodeConfiguration) +-> Result< + NewService< + ConcreteBlock, + ConcreteClient, + LongestChain, + NetworkStatus, + NetworkService::Hash>, + TransactionPool>, + OffchainWorkers< + ConcreteClient, + >::OffchainStorage, + ConcreteBlock, + > + >, + ServiceError, +> +{ + new_full!(config).map(|(service, _)| service) } +/// Builds a new service for a light client. +pub fn new_light(config: NodeConfiguration) +-> Result { + type RpcExtension = jsonrpc_core::IoHandler; + let inherent_data_providers = InherentDataProviders::new(); + + let service = ServiceBuilder::new_light::(config)? + .with_select_chain(|_config, backend| { + Ok(LongestChain::new(backend.clone())) + })? + .with_transaction_pool(|config, client| + Ok(TransactionPool::new(config, transaction_pool::FullChainApi::new(client))) + )? + .with_import_queue_and_fprb(|_config, client, backend, fetcher, _select_chain, _tx_pool| { + let fetch_checker = fetcher + .map(|fetcher| fetcher.checker().clone()) + .ok_or_else(|| "Trying to start light import queue without active fetch checker")?; + let grandpa_block_import = grandpa::light_block_import::<_, _, _, RuntimeApi, _>( + client.clone(), backend, Arc::new(fetch_checker), client.clone() + )?; + + let finality_proof_import = grandpa_block_import.clone(); + let finality_proof_request_builder = + finality_proof_import.create_finality_proof_request_builder(); + + let (babe_block_import, babe_link) = babe::block_import( + babe::Config::get_or_compute(&*client)?, + grandpa_block_import, + client.clone(), + client.clone(), + )?; + + let import_queue = babe::import_queue( + babe_link, + babe_block_import, + None, + Some(Box::new(finality_proof_import)), + client.clone(), + client, + inherent_data_providers.clone(), + )?; + + Ok((import_queue, finality_proof_request_builder)) + })? + .with_network_protocol(|_| Ok(NodeProtocol::new()))? + .with_finality_proof_provider(|client, backend| + Ok(Arc::new(GrandpaFinalityProofProvider::new(backend, client)) as _) + )? + .with_rpc_extensions(|client, pool| -> RpcExtension { + node_rpc::create(client, pool) + })? + .build()?; + + Ok(service) +} #[cfg(test)] mod tests { use std::sync::Arc; use babe::CompatibleDigestItem; use consensus_common::{ - Environment, Proposer, BlockImportParams, BlockOrigin, ForkChoiceStrategy + Environment, Proposer, BlockImportParams, BlockOrigin, ForkChoiceStrategy, BlockImport, }; - use node_primitives::DigestItem; + use node_primitives::{Block, DigestItem}; use node_runtime::{BalancesCall, Call, UncheckedExtrinsic}; use node_runtime::constants::{currency::CENTS, time::SLOT_DURATION}; use codec::{Encode, Decode}; use primitives::{ - crypto::Pair as CryptoPair, blake2_256, + crypto::Pair as CryptoPair, sr25519::Public as AddressPublic, H256, }; - use sr_primitives::{generic::{BlockId, Era, Digest}, traits::Block, OpaqueExtrinsic}; + use sr_primitives::{ + generic::{BlockId, Era, Digest, SignedPayload}, + traits::Block as BlockT, + OpaqueExtrinsic, + }; use timestamp; use finality_tracker; use keyring::AccountKeyring; - use substrate_service::ServiceFactory; - use service_test::SyncService; - use crate::service::Factory; + use substrate_service::{AbstractService, Roles}; + use crate::service::new_full; #[cfg(feature = "rhd")] fn test_sync() { @@ -358,8 +398,14 @@ mod tests { let v: Vec = Decode::decode(&mut xt.as_slice()).unwrap(); OpaqueExtrinsic(v) }; - service_test::sync::( + service_test::sync( chain_spec::integration_test_config(), + |config| new_full(config), + |mut config| { + // light nodes are unsupported + config.roles = Roles::FULL; + new_full(config) + }, block_factory, extrinsic_factory, ); @@ -376,127 +422,156 @@ mod tests { let chain_spec = crate::chain_spec::tests::integration_test_config_with_single_authority(); + // For the block factory let mut slot_num = 1u64; - let block_factory = |service: &SyncService<::FullService>| { - let service = service.get(); - let mut inherent_data = service - .config() - .custom - .inherent_data_providers - .create_inherent_data() - .expect("Creates inherent data."); - inherent_data.replace_data(finality_tracker::INHERENT_IDENTIFIER, &1u64); - - let parent_id = BlockId::number(service.client().info().chain.best_number); - let parent_header = service.client().header(&parent_id).unwrap().unwrap(); - let mut proposer_factory = substrate_basic_authorship::ProposerFactory { - client: service.client(), - transaction_pool: service.transaction_pool(), - }; - - let mut digest = Digest::::default(); - - // even though there's only one authority some slots might be empty, - // so we must keep trying the next slots until we can claim one. - let babe_pre_digest = loop { - inherent_data.replace_data(timestamp::INHERENT_IDENTIFIER, &(slot_num * SLOT_DURATION)); - if let Some(babe_pre_digest) = babe::test_helpers::claim_slot( - &*service.client(), - &parent_id, - slot_num, - (278, 1000), - &keystore, - ) { - break babe_pre_digest; - } - slot_num += 1; - }; + // For the extrinsics factory + let bob = Arc::new(AccountKeyring::Bob.pair()); + let charlie = Arc::new(AccountKeyring::Charlie.pair()); + let mut index = 0; - digest.push(::babe_pre_digest(babe_pre_digest)); - - let mut proposer = proposer_factory.init(&parent_header).unwrap(); - let new_block = futures03::executor::block_on(proposer.propose( - inherent_data, - digest, - std::time::Duration::from_secs(1), - )).expect("Error making test block"); - - let (new_header, new_body) = new_block.deconstruct(); - let pre_hash = new_header.hash(); - // sign the pre-sealed hash of the block and then - // add it to a digest item. - let to_sign = pre_hash.encode(); - let signature = alice.sign(&to_sign[..]); - let item = ::babe_seal( - signature.into(), - ); - slot_num += 1; + service_test::sync( + chain_spec, + |config| { + let mut setup_handles = None; + new_full!(config, | + block_import: &babe::BabeBlockImport<_, _, Block, _, _, _>, + babe_link: &babe::BabeLink, + | { + setup_handles = Some((block_import.clone(), babe_link.clone())); + }).map(move |(node, x)| (node, (x, setup_handles.unwrap()))) + }, + |mut config| { + // light nodes are unsupported + config.roles = Roles::FULL; + new_full(config) + }, + |service, &mut (ref inherent_data_providers, (ref mut block_import, ref babe_link))| { + let mut inherent_data = inherent_data_providers + .create_inherent_data() + .expect("Creates inherent data."); + inherent_data.replace_data(finality_tracker::INHERENT_IDENTIFIER, &1u64); + + let parent_id = BlockId::number(service.client().info().chain.best_number); + let parent_header = service.client().header(&parent_id).unwrap().unwrap(); + let mut proposer_factory = substrate_basic_authorship::ProposerFactory { + client: service.client(), + transaction_pool: service.transaction_pool(), + }; - BlockImportParams { - origin: BlockOrigin::File, - header: new_header, - justification: None, - post_digests: vec![item], - body: Some(new_body), - finalized: true, - auxiliary: Vec::new(), - fork_choice: ForkChoiceStrategy::LongestChain, - } - }; + let mut digest = Digest::::default(); + + // even though there's only one authority some slots might be empty, + // so we must keep trying the next slots until we can claim one. + let babe_pre_digest = loop { + inherent_data.replace_data(timestamp::INHERENT_IDENTIFIER, &(slot_num * SLOT_DURATION)); + if let Some(babe_pre_digest) = babe::test_helpers::claim_slot( + slot_num, + &parent_header, + &*service.client(), + &keystore, + &babe_link, + ) { + break babe_pre_digest; + } - let bob = Arc::new(AccountKeyring::Bob.pair()); - let charlie = Arc::new(AccountKeyring::Charlie.pair()); + slot_num += 1; + }; - let mut index = 0; - let extrinsic_factory = |service: &SyncService<::FullService>| { - let amount = 5 * CENTS; - let to = AddressPublic::from_raw(bob.public().0); - let from = AddressPublic::from_raw(charlie.public().0); - let genesis_hash = service.get().client().block_hash(0).unwrap().unwrap(); - let signer = charlie.clone(); - - let function = Call::Balances(BalancesCall::transfer(to.into(), amount)); - - let check_genesis = system::CheckGenesis::new(); - let check_era = system::CheckEra::from(Era::Immortal); - let check_nonce = system::CheckNonce::from(index); - let check_weight = system::CheckWeight::new(); - let take_fees = balances::TakeFees::from(0); - let extra = (check_genesis, check_era, check_nonce, check_weight, take_fees); - - let raw_payload = (function, extra.clone(), genesis_hash, genesis_hash); - let signature = raw_payload.using_encoded(|payload| if payload.len() > 256 { - signer.sign(&blake2_256(payload)[..]) - } else { - signer.sign(payload) - }); - let xt = UncheckedExtrinsic::new_signed( - raw_payload.0, - from.into(), - signature.into(), - extra, - ).encode(); - let v: Vec = Decode::decode(&mut xt.as_slice()).unwrap(); + digest.push(::babe_pre_digest(babe_pre_digest)); + + let mut proposer = proposer_factory.init(&parent_header).unwrap(); + let new_block = futures03::executor::block_on(proposer.propose( + inherent_data, + digest, + std::time::Duration::from_secs(1), + )).expect("Error making test block"); + + let (new_header, new_body) = new_block.deconstruct(); + let pre_hash = new_header.hash(); + // sign the pre-sealed hash of the block and then + // add it to a digest item. + let to_sign = pre_hash.encode(); + let signature = alice.sign(&to_sign[..]); + let item = ::babe_seal( + signature.into(), + ); + slot_num += 1; - index += 1; - OpaqueExtrinsic(v) - }; + let params = BlockImportParams { + origin: BlockOrigin::File, + header: new_header, + justification: None, + post_digests: vec![item], + body: Some(new_body), + finalized: true, + auxiliary: Vec::new(), + fork_choice: ForkChoiceStrategy::LongestChain, + }; - service_test::sync::( - chain_spec, - block_factory, - extrinsic_factory, + block_import.import_block(params, Default::default()) + .expect("error importing test block"); + }, + |service, _| { + let amount = 5 * CENTS; + let to = AddressPublic::from_raw(bob.public().0); + let from = AddressPublic::from_raw(charlie.public().0); + let genesis_hash = service.client().block_hash(0).unwrap().unwrap(); + let best_block_id = BlockId::number(service.client().info().chain.best_number); + let version = service.client().runtime_version_at(&best_block_id).unwrap().spec_version; + let signer = charlie.clone(); + + let function = Call::Balances(BalancesCall::transfer(to.into(), amount)); + + let check_version = system::CheckVersion::new(); + let check_genesis = system::CheckGenesis::new(); + let check_era = system::CheckEra::from(Era::Immortal); + let check_nonce = system::CheckNonce::from(index); + let check_weight = system::CheckWeight::new(); + let take_fees = balances::TakeFees::from(0); + let extra = ( + check_version, + check_genesis, + check_era, + check_nonce, + check_weight, + take_fees, + Default::default(), + ); + let raw_payload = SignedPayload::from_raw( + function, + extra, + (version, genesis_hash, genesis_hash, (), (), (), ()) + ); + let signature = raw_payload.using_encoded(|payload| { + signer.sign(payload) + }); + let (function, extra, _) = raw_payload.deconstruct(); + let xt = UncheckedExtrinsic::new_signed( + function, + from.into(), + signature.into(), + extra, + ).encode(); + let v: Vec = Decode::decode(&mut xt.as_slice()).unwrap(); + + index += 1; + OpaqueExtrinsic(v) + }, ); } #[test] #[ignore] fn test_consensus() { - use super::Factory; - - service_test::consensus::( + service_test::consensus( crate::chain_spec::tests::integration_test_config_with_two_authorities(), + |config| new_full(config), + |mut config| { + // light nodes are unsupported + config.roles = Roles::FULL; + new_full(config) + }, vec![ "//Alice".into(), "//Bob".into(), diff --git a/node/executor/Cargo.toml b/node/executor/Cargo.toml index d1886c2ab6ea928b153afaafe0ba2ed32a990909..63f1c8c0f4f3a9b3101558a029e17be5a19e7907 100644 --- a/node/executor/Cargo.toml +++ b/node/executor/Cargo.toml @@ -6,7 +6,7 @@ description = "Substrate node implementation in Rust." edition = "2018" [dependencies] -trie-root = "0.15.0" +trie-root = "0.15.2" codec = { package = "parity-scale-codec", version = "1.0.0" } runtime_io = { package = "sr-io", path = "../../core/sr-io" } state_machine = { package = "substrate-state-machine", path = "../../core/state-machine" } @@ -17,20 +17,19 @@ node-primitives = { path = "../primitives" } node-runtime = { path = "../runtime" } [dev-dependencies] +node-testing = { path = "../testing" } test-client = { package = "substrate-test-client", path = "../../core/test-client" } -keyring = { package = "substrate-keyring", path = "../../core/keyring" } sr-primitives = { path = "../../core/sr-primitives" } runtime_support = { package = "srml-support", path = "../../srml/support" } balances = { package = "srml-balances", path = "../../srml/balances" } session = { package = "srml-session", path = "../../srml/session" } -staking = { package = "srml-staking", path = "../../srml/staking" } system = { package = "srml-system", path = "../../srml/system" } timestamp = { package = "srml-timestamp", path = "../../srml/timestamp" } treasury = { package = "srml-treasury", path = "../../srml/treasury" } contracts = { package = "srml-contracts", path = "../../srml/contracts" } grandpa = { package = "srml-grandpa", path = "../../srml/grandpa" } indices = { package = "srml-indices", path = "../../srml/indices" } -wabt = "~0.7.4" +wabt = "0.9.2" [features] benchmarks = [] diff --git a/node/executor/src/lib.rs b/node/executor/src/lib.rs index c2e442fd580b140a785d001bc56f7809b12ef81e..864b51d6c75f0c7a6222c98e21240c651e0eea9b 100644 --- a/node/executor/src/lib.rs +++ b/node/executor/src/lib.rs @@ -30,37 +30,38 @@ use substrate_executor::native_executor_instance; native_executor_instance!( pub Executor, node_runtime::api::dispatch, - node_runtime::native_version, - node_runtime::WASM_BINARY + node_runtime::native_version ); #[cfg(test)] mod tests { use super::Executor; - use {balances, contracts, indices, staking, system, timestamp}; + use {balances, contracts, indices, system, timestamp}; use runtime_io; - use substrate_executor::WasmExecutor; use codec::{Encode, Decode, Joiner}; - use keyring::{AccountKeyring, Ed25519Keyring, Sr25519Keyring}; - use runtime_support::{Hashable, StorageValue, StorageMap, assert_eq_error_rate, traits::Currency}; - use state_machine::{CodeExecutor, Externalities, TestExternalities as CoreTestExternalities}; - use primitives::{ twox_128, blake2_256, Blake2Hasher, ChangesTrieConfiguration, NeverNativeValue, NativeOrEncoded}; - use node_primitives::{Hash, BlockNumber, AccountId, Balance, Index}; - use sr_primitives::traits::{Header as HeaderT, Hash as HashT, Convert}; - use sr_primitives::{generic::Era, ApplyOutcome, ApplyError, ApplyResult, Perbill}; - use sr_primitives::weights::{WeightMultiplier, GetDispatchInfo}; + use runtime_support::{ + Hashable, StorageValue, StorageMap, traits::Currency, + }; + use state_machine::TestExternalities as CoreTestExternalities; + use primitives::{ + Blake2Hasher, NeverNativeValue, NativeOrEncoded, map, + traits::{CodeExecutor, Externalities}, storage::well_known_keys, + }; + use sr_primitives::{ + assert_eq_error_rate, + traits::{Header as HeaderT, Hash as HashT, Convert}, ApplyResult, + transaction_validity::InvalidTransaction, weights::{WeightMultiplier, GetDispatchInfo}, + }; use contracts::ContractAddressFor; use system::{EventRecord, Phase}; use node_runtime::{ Header, Block, UncheckedExtrinsic, CheckedExtrinsic, Call, Runtime, Balances, BuildStorage, - GenesisConfig, BalancesConfig, SessionConfig, StakingConfig, System, SystemConfig, - GrandpaConfig, IndicesConfig, ContractsConfig, Event, SessionKeys, SignedExtra, - TransferFee, TransactionBaseFee, TransactionByteFee, + System, Event, TransferFee, TransactionBaseFee, TransactionByteFee, + constants::currency::*, impls::WeightToFee, }; - use node_runtime::constants::currency::*; - use node_runtime::impls::WeightToFee; + use node_primitives::{Balance, Hash, BlockNumber}; + use node_testing::keyring::*; use wabt; - use primitives::map; /// The wasm runtime code. /// @@ -79,8 +80,14 @@ mod tests { const GENESIS_HASH: [u8; 32] = [69u8; 32]; + const VERSION: u32 = node_runtime::VERSION.spec_version; + type TestExternalities = CoreTestExternalities; + fn sign(xt: CheckedExtrinsic) -> UncheckedExtrinsic { + node_testing::keyring::sign(xt, VERSION, GENESIS_HASH) + } + /// Default transfer fee fn transfer_fee(extrinsic: &E) -> Balance { let length_fee = TransactionBaseFee::get() + @@ -95,64 +102,6 @@ mod tests { length_fee + weight_fee + TransferFee::get() } - fn alice() -> AccountId { - AccountKeyring::Alice.into() - } - - fn bob() -> AccountId { - AccountKeyring::Bob.into() - } - - fn charlie() -> AccountId { - AccountKeyring::Charlie.into() - } - - fn dave() -> AccountId { - AccountKeyring::Dave.into() - } - - fn eve() -> AccountId { - AccountKeyring::Eve.into() - } - - fn ferdie() -> AccountId { - AccountKeyring::Ferdie.into() - } - - fn sign(xt: CheckedExtrinsic) -> UncheckedExtrinsic { - match xt.signed { - Some((signed, extra)) => { - let payload = (xt.function, extra.clone(), GENESIS_HASH, GENESIS_HASH); - let key = AccountKeyring::from_public(&signed).unwrap(); - let signature = payload.using_encoded(|b| { - if b.len() > 256 { - key.sign(&runtime_io::blake2_256(b)) - } else { - key.sign(b) - } - }).into(); - UncheckedExtrinsic { - signature: Some((indices::address::Address::Id(signed), signature, extra)), - function: payload.0, - } - } - None => UncheckedExtrinsic { - signature: None, - function: xt.function, - }, - } - } - - fn signed_extra(nonce: Index, extra_fee: Balance) -> SignedExtra { - ( - system::CheckGenesis::new(), - system::CheckEra::from(Era::mortal(256, 0)), - system::CheckNonce::from(nonce), - system::CheckWeight::new(), - balances::TakeFees::from(extra_fee) - ) - } - fn default_transfer_call() -> balances::Call { balances::Call::transfer::(bob().into(), 69 * DOLLARS) } @@ -172,19 +121,23 @@ mod tests { substrate_executor::NativeExecutor::new(None) } + fn set_heap_pages>(ext: &mut E, heap_pages: u64) { + ext.place_storage(well_known_keys::HEAP_PAGES.to_vec(), Some(heap_pages.encode())); + } + #[test] fn panic_execution_with_foreign_code_gives_error() { let mut t = TestExternalities::::new_with_code(BLOATY_CODE, (map![ - blake2_256(&>::key_for(alice())).to_vec() => { + >::hashed_key_for(alice()) => { 69_u128.encode() }, - twox_128(>::key()).to_vec() => { + >::hashed_key().to_vec() => { 69_u128.encode() }, - twox_128(>::key()).to_vec() => { + >::hashed_key().to_vec() => { 0_u128.encode() }, - blake2_256(&>::key_for(0)).to_vec() => { + >::hashed_key_for(0) => { vec![0u8; 32] } ], map![])); @@ -205,22 +158,22 @@ mod tests { None, ).0.unwrap(); let r = ApplyResult::decode(&mut &v.as_encoded()[..]).unwrap(); - assert_eq!(r, Err(ApplyError::CantPay)); + assert_eq!(r, Err(InvalidTransaction::Payment.into())); } #[test] fn bad_extrinsic_with_native_equivalent_code_gives_error() { let mut t = TestExternalities::::new_with_code(COMPACT_CODE, (map![ - blake2_256(&>::key_for(alice())).to_vec() => { + >::hashed_key_for(alice()) => { 69_u128.encode() }, - twox_128(>::key()).to_vec() => { + >::hashed_key().to_vec() => { 69_u128.encode() }, - twox_128(>::key()).to_vec() => { + >::hashed_key().to_vec() => { 0_u128.encode() }, - blake2_256(&>::key_for(0)).to_vec() => { + >::hashed_key_for(0) => { vec![0u8; 32] } ], map![])); @@ -241,20 +194,20 @@ mod tests { None, ).0.unwrap(); let r = ApplyResult::decode(&mut &v.as_encoded()[..]).unwrap(); - assert_eq!(r, Err(ApplyError::CantPay)); + assert_eq!(r, Err(InvalidTransaction::Payment.into())); } #[test] fn successful_execution_with_native_equivalent_code_gives_ok() { let mut t = TestExternalities::::new_with_code(COMPACT_CODE, (map![ - blake2_256(&>::key_for(alice())).to_vec() => { + >::hashed_key_for(alice()) => { (111 * DOLLARS).encode() }, - twox_128(>::key()).to_vec() => { + >::hashed_key().to_vec() => { (111 * DOLLARS).encode() }, - twox_128(>::key()).to_vec() => vec![0u8; 16], - blake2_256(&>::key_for(0)).to_vec() => vec![0u8; 32] + >::hashed_key().to_vec() => vec![0u8; 16], + >::hashed_key_for(0) => vec![0u8; 32] ], map![])); let r = executor().call::<_, NeverNativeValue, fn() -> _>( @@ -283,14 +236,14 @@ mod tests { #[test] fn successful_execution_with_foreign_code_gives_ok() { let mut t = TestExternalities::::new_with_code(BLOATY_CODE, (map![ - blake2_256(&>::key_for(alice())).to_vec() => { + >::hashed_key_for(alice()) => { (111 * DOLLARS).encode() }, - twox_128(>::key()).to_vec() => { + >::hashed_key().to_vec() => { (111 * DOLLARS).encode() }, - twox_128(>::key()).to_vec() => vec![0u8; 16], - blake2_256(&>::key_for(0)).to_vec() => vec![0u8; 32] + >::hashed_key().to_vec() => vec![0u8; 16], + >::hashed_key_for(0) => vec![0u8; 32] ], map![])); let r = executor().call::<_, NeverNativeValue, fn() -> _>( @@ -316,86 +269,11 @@ mod tests { }); } - fn to_session_keys( - ed25519_keyring: &Ed25519Keyring, - sr25519_keyring: &Sr25519Keyring, - ) -> SessionKeys { - SessionKeys { - grandpa: ed25519_keyring.to_owned().public().into(), - babe: sr25519_keyring.to_owned().public().into(), - im_online: sr25519_keyring.to_owned().public().into(), - } - } - fn new_test_ext(code: &[u8], support_changes_trie: bool) -> TestExternalities { - let mut ext = TestExternalities::new_with_code(code, GenesisConfig { - system: Some(SystemConfig { - changes_trie_config: if support_changes_trie { Some(ChangesTrieConfiguration { - digest_interval: 2, - digest_levels: 2, - }) } else { None }, - .. Default::default() - }), - indices: Some(IndicesConfig { - ids: vec![alice(), bob(), charlie(), dave(), eve(), ferdie()], - }), - balances: Some(BalancesConfig { - balances: vec![ - (alice(), 111 * DOLLARS), - (bob(), 100 * DOLLARS), - (charlie(), 100_000_000 * DOLLARS), - (dave(), 111 * DOLLARS), - (eve(), 101 * DOLLARS), - (ferdie(), 100 * DOLLARS), - ], - vesting: vec![], - }), - session: Some(SessionConfig { - keys: vec![ - (alice(), to_session_keys( - &Ed25519Keyring::Alice, - &Sr25519Keyring::Alice, - )), - (bob(), to_session_keys( - &Ed25519Keyring::Bob, - &Sr25519Keyring::Bob, - )), - (charlie(), to_session_keys( - &Ed25519Keyring::Charlie, - &Sr25519Keyring::Charlie, - )), - ] - }), - staking: Some(StakingConfig { - current_era: 0, - stakers: vec![ - (dave(), alice(), 111 * DOLLARS, staking::StakerStatus::Validator), - (eve(), bob(), 100 * DOLLARS, staking::StakerStatus::Validator), - (ferdie(), charlie(), 100 * DOLLARS, staking::StakerStatus::Validator) - ], - validator_count: 3, - minimum_validator_count: 0, - offline_slash: Perbill::zero(), - offline_slash_grace: 0, - invulnerables: vec![alice(), bob(), charlie()], - .. Default::default() - }), - contracts: Some(ContractsConfig { - current_schedule: Default::default(), - gas_price: 1 * MILLICENTS, - }), - babe: Some(Default::default()), - grandpa: Some(GrandpaConfig { - authorities: vec![], - }), - im_online: Some(Default::default()), - democracy: Some(Default::default()), - collective_Instance1: Some(Default::default()), - collective_Instance2: Some(Default::default()), - membership_Instance1: Some(Default::default()), - elections: Some(Default::default()), - sudo: Some(Default::default()), - }.build_storage().unwrap()); + let mut ext = TestExternalities::new_with_code( + code, + node_testing::genesis::config(support_changes_trie, Some(code)).build_storage().unwrap(), + ); ext.changes_trie_storage().insert(0, GENESIS_HASH.into(), Default::default()); ext } @@ -655,14 +533,26 @@ mod tests { let (block1, block2) = blocks(); - WasmExecutor::new().call(&mut t, 8, COMPACT_CODE, "Core_execute_block", &block1.0).unwrap(); + executor().call::<_, NeverNativeValue, fn() -> _>( + &mut t, + "Core_execute_block", + &block1.0, + false, + None, + ).0.unwrap(); runtime_io::with_externalities(&mut t, || { assert_eq!(Balances::total_balance(&alice()), 42 * DOLLARS - transfer_fee(&xt())); assert_eq!(Balances::total_balance(&bob()), 169 * DOLLARS); }); - WasmExecutor::new().call(&mut t, 8, COMPACT_CODE, "Core_execute_block", &block2.0).unwrap(); + executor().call::<_, NeverNativeValue, fn() -> _>( + &mut t, + "Core_execute_block", + &block2.0, + false, + None, + ).0.unwrap(); runtime_io::with_externalities(&mut t, || { assert_eq_error_rate!( @@ -799,7 +689,7 @@ mod tests { CheckedExtrinsic { signed: Some((charlie(), signed_extra(1, 0))), function: Call::Contracts( - contracts::Call::create::(1 * DOLLARS, 10_000, transfer_ch, Vec::new()) + contracts::Call::instantiate::(1 * DOLLARS, 10_000, transfer_ch, Vec::new()) ), }, CheckedExtrinsic { @@ -818,7 +708,13 @@ mod tests { let mut t = new_test_ext(COMPACT_CODE, false); - WasmExecutor::new().call(&mut t, 8, COMPACT_CODE,"Core_execute_block", &b.0).unwrap(); + executor().call::<_, NeverNativeValue, fn() -> _>( + &mut t, + "Core_execute_block", + &b.0, + false, + None, + ).0.unwrap(); runtime_io::with_externalities(&mut t, || { // Verify that the contract constructor worked well and code of TRANSFER contract is actually deployed. @@ -836,13 +732,15 @@ mod tests { fn wasm_big_block_import_fails() { let mut t = new_test_ext(COMPACT_CODE, false); - let result = WasmExecutor::new().call( + set_heap_pages(&mut t, 4); + + let result = executor().call::<_, NeverNativeValue, fn() -> _>( &mut t, - 4, - COMPACT_CODE, "Core_execute_block", - &block_with_size(42, 0, 120_000).0 - ); + &block_with_size(42, 0, 120_000).0, + false, + None, + ).0; assert!(result.is_err()); // Err(Wasmi(Trap(Trap { kind: Host(AllocatorOutOfSpace) }))) } @@ -877,45 +775,67 @@ mod tests { #[test] fn panic_execution_gives_error() { let mut t = TestExternalities::::new_with_code(BLOATY_CODE, (map![ - blake2_256(&>::key_for(alice())).to_vec() => { + >::hashed_key_for(alice()) => { 0_u128.encode() }, - twox_128(>::key()).to_vec() => { + >::hashed_key().to_vec() => { 0_u128.encode() }, - twox_128(>::key()).to_vec() => vec![0u8; 16], - blake2_256(&>::key_for(0)).to_vec() => vec![0u8; 32] + >::hashed_key().to_vec() => vec![0u8; 16], + >::hashed_key_for(0) => vec![0u8; 32] ], map![])); - let r = WasmExecutor::new() - .call(&mut t, 8, COMPACT_CODE, "Core_initialize_block", &vec![].and(&from_block_number(1u32))); + let r = executor().call::<_, NeverNativeValue, fn() -> _>( + &mut t, + "Core_initialize_block", + &vec![].and(&from_block_number(1u32)), + false, + None, + ).0; assert!(r.is_ok()); - let r = WasmExecutor::new() - .call(&mut t, 8, COMPACT_CODE, "BlockBuilder_apply_extrinsic", &vec![].and(&xt())).unwrap(); + let r = executor().call::<_, NeverNativeValue, fn() -> _>( + &mut t, + "BlockBuilder_apply_extrinsic", + &vec![].and(&xt()), + false, + None, + ).0.unwrap().into_encoded(); let r = ApplyResult::decode(&mut &r[..]).unwrap(); - assert_eq!(r, Err(ApplyError::CantPay)); + assert_eq!(r, Err(InvalidTransaction::Payment.into())); } #[test] fn successful_execution_gives_ok() { let mut t = TestExternalities::::new_with_code(COMPACT_CODE, (map![ - blake2_256(&>::key_for(alice())).to_vec() => { + >::hashed_key_for(alice()) => { (111 * DOLLARS).encode() }, - twox_128(>::key()).to_vec() => { + >::hashed_key().to_vec() => { (111 * DOLLARS).encode() }, - twox_128(>::key()).to_vec() => vec![0u8; 16], - blake2_256(&>::key_for(0)).to_vec() => vec![0u8; 32] + >::hashed_key().to_vec() => vec![0u8; 16], + >::hashed_key_for(0) => vec![0u8; 32] ], map![])); - let r = WasmExecutor::new() - .call(&mut t, 8, COMPACT_CODE, "Core_initialize_block", &vec![].and(&from_block_number(1u32))); + let r = executor().call::<_, NeverNativeValue, fn() -> _>( + &mut t, + "Core_initialize_block", + &vec![].and(&from_block_number(1u32)), + false, + None, + ).0; assert!(r.is_ok()); - let r = WasmExecutor::new() - .call(&mut t, 8, COMPACT_CODE, "BlockBuilder_apply_extrinsic", &vec![].and(&xt())).unwrap(); - let r = ApplyResult::decode(&mut &r[..]).unwrap(); - assert_eq!(r, Ok(ApplyOutcome::Success)); + let r = executor().call::<_, NeverNativeValue, fn() -> _>( + &mut t, + "BlockBuilder_apply_extrinsic", + &vec![].and(&xt()), + false, + None, + ).0.unwrap().into_encoded(); + ApplyResult::decode(&mut &r[..]) + .unwrap() + .expect("Extrinsic could be applied") + .expect("Extrinsic did not fail"); runtime_io::with_externalities(&mut t, || { assert_eq!(Balances::total_balance(&alice()), 42 * DOLLARS - 1 * transfer_fee(&xt())); @@ -946,22 +866,25 @@ mod tests { let block1 = changes_trie_block(); let mut t = new_test_ext(COMPACT_CODE, true); - WasmExecutor::new().call(&mut t, 8, COMPACT_CODE, "Core_execute_block", &block1.0).unwrap(); + executor().call::<_, NeverNativeValue, fn() -> _>( + &mut t, + "Core_execute_block", + &block1.0, + false, + None, + ).0.unwrap(); assert!(t.storage_changes_root(GENESIS_HASH.into()).unwrap().is_some()); } #[test] fn should_import_block_with_test_client() { - use test_client::{ClientExt, TestClientBuilder, consensus::BlockOrigin}; - - let client = TestClientBuilder::default() - .build_with_native_executor::(executor()) - .0; + use node_testing::client::{ClientExt, TestClientBuilderExt, TestClientBuilder, consensus::BlockOrigin}; + let client = TestClientBuilder::new().build(); let block1 = changes_trie_block(); let block_data = block1.0; - let block = Block::decode(&mut &block_data[..]).unwrap(); + let block = node_primitives::Block::decode(&mut &block_data[..]).unwrap(); client.import(BlockOrigin::Own, block).unwrap(); } @@ -1059,17 +982,17 @@ mod tests { // - 1 milldot based on current polkadot runtime. // (this baed on assigning 0.1 CENT to the cheapest tx with `weight = 100`) let mut t = TestExternalities::::new_with_code(COMPACT_CODE, (map![ - blake2_256(&>::key_for(alice())).to_vec() => { + >::hashed_key_for(alice()) => { (100 * DOLLARS).encode() }, - blake2_256(&>::key_for(bob())).to_vec() => { + >::hashed_key_for(bob()) => { (10 * DOLLARS).encode() }, - twox_128(>::key()).to_vec() => { + >::hashed_key().to_vec() => { (110 * DOLLARS).encode() }, - twox_128(>::key()).to_vec() => vec![0u8; 16], - blake2_256(&>::key_for(0)).to_vec() => vec![0u8; 32] + >::hashed_key().to_vec() => vec![0u8; 16], + >::hashed_key_for(0) => vec![0u8; 32] ], map![])); let tip = 1_000_000; diff --git a/node/primitives/Cargo.toml b/node/primitives/Cargo.toml index 654347273fb71d109bf005dcc2bb33d3bb0cedd1..266720b0246a039c0d12bb98cec187bf7375165c 100644 --- a/node/primitives/Cargo.toml +++ b/node/primitives/Cargo.toml @@ -5,10 +5,11 @@ authors = ["Parity Technologies "] edition = "2018" [dependencies] -serde = { version = "1.0", optional = true, features = ["derive"] } +client = { package = "substrate-client", path = "../../core/client", default-features = false } codec = { package = "parity-scale-codec", version = "1.0.0", default-features = false, features = ["derive"] } primitives = { package = "substrate-primitives", path = "../../core/primitives", default-features = false } rstd = { package = "sr-std", path = "../../core/sr-std", default-features = false } +serde = { version = "1.0.101", optional = true, features = ["derive"] } sr-primitives = { path = "../../core/sr-primitives", default-features = false } [dev-dependencies] @@ -18,9 +19,10 @@ pretty_assertions = "0.6.1" [features] default = ["std"] std = [ + "client/std", "codec/std", "primitives/std", "rstd/std", - "sr-primitives/std", "serde", + "sr-primitives/std", ] diff --git a/node/primitives/src/lib.rs b/node/primitives/src/lib.rs index 431ba17c00bbeca51948fa2cd47a8dc2efe97ac3..907b78a017eea491c8a942632a4cd7704a859189 100644 --- a/node/primitives/src/lib.rs +++ b/node/primitives/src/lib.rs @@ -20,10 +20,15 @@ #![cfg_attr(not(feature = "std"), no_std)] +use rstd::prelude::*; use sr_primitives::{ generic, traits::{Verify, BlakeTwo256}, OpaqueExtrinsic, AnySignature }; +#[cfg(feature = "std")] +use serde::{Serialize, Deserialize}; +use codec::{Encode, Decode}; + /// An index to a block. pub type BlockNumber = u32; @@ -66,3 +71,44 @@ pub type BlockId = generic::BlockId; /// Opaque, encoded, unchecked extrinsic. pub type UncheckedExtrinsic = OpaqueExtrinsic; + +/// A result of execution of a contract. +#[derive(Eq, PartialEq, Encode, Decode)] +#[cfg_attr(feature = "std", derive(Debug, Serialize, Deserialize))] +pub enum ContractExecResult { + /// The contract returned successfully. + /// + /// There is a status code and, optionally, some data returned by the contract. + Success { + /// Status code returned by the contract. + status: u8, + /// Output data returned by the contract. + /// + /// Can be empty. + data: Vec, + }, + /// The contract execution either trapped or returned an error. + Error, +} + +client::decl_runtime_apis! { + /// The API to query account account nonce (aka index). + pub trait AccountNonceApi { + /// Get current account nonce of given `AccountId`. + fn account_nonce(account: AccountId) -> Index; + } + + /// The API to interact with contracts without using executive. + pub trait ContractsApi { + /// Perform a call from a specified account to a given contract. + /// + /// See the contracts' `call` dispatchable function for more details. + fn call( + origin: AccountId, + dest: AccountId, + value: Balance, + gas_limit: u64, + input_data: Vec, + ) -> ContractExecResult; + } +} diff --git a/node/rpc-client/Cargo.toml b/node/rpc-client/Cargo.toml index ea255808e463e47d2f6c0d3bdf15044b0b827815..7dca1448862ee1b2ba6bb3008152ee9d8f073990 100644 --- a/node/rpc-client/Cargo.toml +++ b/node/rpc-client/Cargo.toml @@ -5,10 +5,10 @@ authors = ["Parity Technologies "] edition = "2018" [dependencies] -env_logger = "0.6" -futures = "0.1.26" -hyper = "0.12" -jsonrpc-core-client = { version = "12.0.0", features = ["http", "ws"] } -log = "0.4" +env_logger = "0.6.2" +futures = "0.1.29" +hyper = "0.12.35" +jsonrpc-core-client = { version = "13.1.0", features = ["http", "ws"] } +log = "0.4.8" node-primitives = { path = "../primitives" } substrate-rpc = { path = "../../core/rpc", version = "2.0.0" } diff --git a/node/rpc/Cargo.toml b/node/rpc/Cargo.toml new file mode 100644 index 0000000000000000000000000000000000000000..6bec6adb6f462b769dbd73357a0fe7aa4cfc2308 --- /dev/null +++ b/node/rpc/Cargo.toml @@ -0,0 +1,27 @@ +[package] +name = "node-rpc" +version = "2.0.0" +authors = ["Parity Technologies "] +edition = "2018" + +[dependencies] +client = { package = "substrate-client", path = "../../core/client" } +jsonrpc-core = "13.2.0" +jsonrpc-core-client = "13.2.0" +jsonrpc-derive = "13.2.0" +jsonrpc-pubsub = "13.2.0" +keyring = { package = "substrate-keyring", path = "../../core/keyring" } +log = "0.4.8" +node-primitives = { path = "../primitives" } +codec = { package = "parity-scale-codec", version = "1.0.0" } +serde = { version = "1.0.101", features = ["derive"] } +sr-primitives = { path = "../../core/sr-primitives" } +substrate-primitives = { path = "../../core/primitives" } +rpc-primitives = { package = "substrate-rpc-primitives", path = "../../core/rpc/primitives" } +transaction_pool = { package = "substrate-transaction-pool", path = "../../core/transaction-pool" } + +[dev-dependencies] +node-testing = { path = "../testing" } +node-runtime = { path = "../runtime" } +env_logger = "0.6.2" +futures03 = { package = "futures-preview", version = "=0.3.0-alpha.19" } diff --git a/node/rpc/src/accounts.rs b/node/rpc/src/accounts.rs new file mode 100644 index 0000000000000000000000000000000000000000..6c8e60736ac5326c5eabababf7765b7edfd3d4b7 --- /dev/null +++ b/node/rpc/src/accounts.rs @@ -0,0 +1,155 @@ +// Copyright 2019 Parity Technologies (UK) Ltd. +// This file is part of Substrate. + +// Substrate 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. + +// Substrate 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 Substrate. If not, see . + +//! Node-specific RPC methods for Accounts. + +use std::sync::Arc; + +use client::blockchain::HeaderBackend; +use jsonrpc_core::{Result, Error, ErrorCode}; +use jsonrpc_derive::rpc; +use node_primitives::{ + AccountId, Index, AccountNonceApi, Block, BlockId, +}; +use codec::Encode; +use sr_primitives::traits; +use substrate_primitives::hexdisplay::HexDisplay; +use transaction_pool::txpool::{self, Pool}; + +pub use self::gen_client::Client as AccountsClient; + +/// Accounts RPC methods. +#[rpc] +pub trait AccountsApi { + /// Returns the next valid index (aka nonce) for given account. + /// + /// This method takes into consideration all pending transactions + /// currently in the pool and if no transactions are found in the pool + /// it fallbacks to query the index from the runtime (aka. state nonce). + #[rpc(name = "account_nextIndex")] + fn nonce(&self, account: AccountId) -> Result; +} + +/// An implementation of Accounts specific RPC methods. +pub struct Accounts { + client: Arc, + pool: Arc>, +} + +impl Accounts { + /// Create new `Accounts` given client and transaction pool. + pub fn new(client: Arc, pool: Arc>) -> Self { + Accounts { + client, + pool + } + } +} + +impl AccountsApi for Accounts +where + C: traits::ProvideRuntimeApi, + C: HeaderBackend, + C: Send + Sync + 'static, + C::Api: AccountNonceApi, + P: txpool::ChainApi + Sync + Send + 'static, +{ + fn nonce(&self, account: AccountId) -> Result { + let api = self.client.runtime_api(); + let best = self.client.info().best_hash; + let at = BlockId::hash(best); + + let nonce = api.account_nonce(&at, account.clone()).map_err(|e| Error { + code: ErrorCode::ServerError(crate::constants::RUNTIME_ERROR), + message: "Unable to query nonce.".into(), + data: Some(format!("{:?}", e).into()), + })?; + + log::debug!(target: "rpc", "State nonce for {}: {}", account, nonce); + // Now we need to query the transaction pool + // and find transactions originating from the same sender. + // + // Since extrinsics are opaque to us, we look for them using + // `provides` tag. And increment the nonce if we find a transaction + // that matches the current one. + let mut current_nonce = nonce; + let mut current_tag = (account.clone(), nonce).encode(); + for tx in self.pool.ready() { + log::debug!( + target: "rpc", + "Current nonce to {:?}, checking {} vs {:?}", + current_nonce, + HexDisplay::from(¤t_tag), + tx.provides.iter().map(|x| format!("{}", HexDisplay::from(x))).collect::>(), + ); + // since transactions in `ready()` need to be ordered by nonce + // it's fine to continue with current iterator. + if tx.provides.get(0) == Some(¤t_tag) { + current_nonce += 1; + current_tag = (account.clone(), current_nonce).encode(); + } + } + + Ok(current_nonce) + } +} + +#[cfg(test)] +mod tests { + use super::*; + + use futures03::executor::block_on; + use node_runtime::{CheckedExtrinsic, Call, TimestampCall}; + use codec::Decode; + use node_testing::{ + client::{ClientExt, TestClientBuilder, TestClientBuilderExt}, + keyring::{self, alice, signed_extra}, + }; + + const VERSION: u32 = node_runtime::VERSION.spec_version; + + #[test] + fn should_return_next_nonce_for_some_account() { + // given + let _ = env_logger::try_init(); + let client = Arc::new(TestClientBuilder::new().build()); + let pool = Arc::new(Pool::new(Default::default(), transaction_pool::FullChainApi::new(client.clone()))); + + let new_transaction = |extra| { + let ex = CheckedExtrinsic { + signed: Some((alice().into(), extra)), + function: Call::Timestamp(TimestampCall::set(5)), + }; + let xt = keyring::sign(ex, VERSION, client.genesis_hash().into()); + // Convert to OpaqueExtrinsic + let encoded = xt.encode(); + node_primitives::UncheckedExtrinsic::decode(&mut &*encoded).unwrap() + }; + // Populate the pool + let ext0 = new_transaction(signed_extra(0, 0)); + block_on(pool.submit_one(&BlockId::number(0), ext0)).unwrap(); + let ext1 = new_transaction(signed_extra(1, 0)); + block_on(pool.submit_one(&BlockId::number(0), ext1)).unwrap(); + + let accounts = Accounts::new(client, pool); + + // when + let nonce = accounts.nonce(alice().into()); + + // then + assert_eq!(nonce.unwrap(), 2); + } +} diff --git a/node/rpc/src/contracts.rs b/node/rpc/src/contracts.rs new file mode 100644 index 0000000000000000000000000000000000000000..3da2478dab8bf780b0a9591352383f96f3e01187 --- /dev/null +++ b/node/rpc/src/contracts.rs @@ -0,0 +1,116 @@ +// Copyright 2019 Parity Technologies (UK) Ltd. +// This file is part of Substrate. + +// Substrate 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. + +// Substrate 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 Substrate. If not, see . + +//! Node-specific RPC methods for interaction with contracts. + +use std::sync::Arc; + +use serde::{Serialize, Deserialize}; +use client::blockchain::HeaderBackend; +use jsonrpc_core::{Error, ErrorCode, Result}; +use jsonrpc_derive::rpc; +use node_primitives::{ + AccountId, Balance, Block, BlockId, ContractExecResult, ContractsApi as ContractsRuntimeApi, +}; +use sr_primitives::traits::{ + self, + Block as BlockT, +}; +use rpc_primitives::number; + +/// A struct that encodes RPC parameters required for a call to a smart-contract. +#[derive(Serialize, Deserialize)] +#[serde(rename_all="camelCase")] +#[serde(deny_unknown_fields)] +pub struct CallRequest { + origin: AccountId, + dest: AccountId, + value: Balance, + gas_limit: number::NumberOrHex, + input_data: Vec, +} + +/// Contracts RPC methods. +#[rpc] +pub trait ContractsApi { + /// Executes a call to a contract. + /// + /// This call is performed locally without submitting any transactions. Thus executing this + /// won't change any state. Nonetheless, the calling state-changing contracts is still possible. + /// + /// This method is useful for calling getter-like methods on contracts. + #[rpc(name = "contracts_call")] + fn call( + &self, + call_request: CallRequest, + at: Option, + ) -> Result; +} + +/// An implementation of contract specific RPC methods. +pub struct Contracts { + client: Arc, +} + +impl Contracts { + /// Create new `Contracts` with the given reference to the client. + pub fn new(client: Arc) -> Self { + Contracts { client } + } +} + +impl ContractsApi<::Hash> for Contracts +where + C: Send + Sync + 'static, + C: traits::ProvideRuntimeApi, + C: HeaderBackend, + C::Api: ContractsRuntimeApi, +{ + fn call( + &self, + call_request: CallRequest, + at: Option<::Hash>, + ) -> Result { + let api = self.client.runtime_api(); + let at = BlockId::hash(at.unwrap_or_else(|| + // If the block hash is not supplied assume the best block. + self.client.info().best_hash + )); + + let CallRequest { + origin, + dest, + value, + gas_limit, + input_data + } = call_request; + let gas_limit = gas_limit.to_number().map_err(|e| Error { + code: ErrorCode::InvalidParams, + message: e, + data: None, + })?; + + let exec_result = api + .call(&at, origin, dest, value, gas_limit, input_data) + .map_err(|e| Error { + code: ErrorCode::ServerError(crate::constants::RUNTIME_ERROR), + message: "Runtime trapped while executing a contract.".into(), + data: Some(format!("{:?}", e).into()), + })?; + + Ok(exec_result) + } +} diff --git a/node/rpc/src/lib.rs b/node/rpc/src/lib.rs new file mode 100644 index 0000000000000000000000000000000000000000..43f723f7964bc87317fba57e353ccbbef0ebe088 --- /dev/null +++ b/node/rpc/src/lib.rs @@ -0,0 +1,70 @@ +// Copyright 2019 Parity Technologies (UK) Ltd. +// This file is part of Substrate. + +// Substrate 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. + +// Substrate 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 Substrate. If not, see . + +//! A collection of node-specific RPC methods. +//! +//! Since `substrate` core functionality makes no assumptions +//! about the modules used inside the runtime, so do +//! RPC methods defined in `substrate-rpc` crate. +//! It means that `core/rpc` can't have any methods that +//! need some strong assumptions about the particular runtime. +//! +//! The RPCs available in this crate however can make some assumptions +//! about how the runtime is constructed and what `SRML` modules +//! are part of it. Therefore all node-runtime-specific RPCs can +//! be placed here. + +#![warn(missing_docs)] + +use std::sync::Arc; + +use node_primitives::{Block, AccountNonceApi, ContractsApi}; +use sr_primitives::traits::ProvideRuntimeApi; +use transaction_pool::txpool::{ChainApi, Pool}; + +pub mod accounts; +pub mod contracts; + +mod constants { + /// A status code indicating an error happened while trying to call into the runtime. + /// + /// This typically means that the runtime trapped. + pub const RUNTIME_ERROR: i64 = 1; +} + +/// Instantiate all RPC extensions. +pub fn create(client: Arc, pool: Arc>) -> jsonrpc_core::IoHandler where + C: ProvideRuntimeApi, + C: client::blockchain::HeaderBackend, + C: Send + Sync + 'static, + C::Api: AccountNonceApi + ContractsApi, + P: ChainApi + Sync + Send + 'static, + M: jsonrpc_core::Metadata + Default, +{ + use self::{ + accounts::{Accounts, AccountsApi}, + contracts::{Contracts, ContractsApi}, + }; + + let mut io = jsonrpc_core::IoHandler::default(); + io.extend_with( + AccountsApi::to_delegate(Accounts::new(client.clone(), pool)) + ); + io.extend_with( + ContractsApi::to_delegate(Contracts::new(client)) + ); + io +} diff --git a/node/runtime/Cargo.toml b/node/runtime/Cargo.toml index 7ffb29e0784ce59db45f9877fd2b6a2e48bb7890..f2565750863e920c47f374e6999be4f63a624d62 100644 --- a/node/runtime/Cargo.toml +++ b/node/runtime/Cargo.toml @@ -6,85 +6,93 @@ edition = "2018" build = "build.rs" [dependencies] +codec = { package = "parity-scale-codec", version = "1.0.0", default-features = false, features = ["derive"] } integer-sqrt = { version = "0.1.2" } +rustc-hex = { version = "2.0", optional = true } safe-mix = { version = "1.0", default-features = false } -codec = { package = "parity-scale-codec", version = "1.0.0", default-features = false, features = ["derive"] } -primitives = { package = "substrate-primitives", path = "../../core/primitives", default-features = false } +serde = { version = "1.0.101", optional = true } + +authority-discovery-primitives = { package = "substrate-authority-discovery-primitives", path = "../../core/authority-discovery/primitives", default-features = false } +babe-primitives = { package = "substrate-consensus-babe-primitives", path = "../../core/consensus/babe/primitives", default-features = false } client = { package = "substrate-client", path = "../../core/client", default-features = false } +node-primitives = { path = "../primitives", default-features = false } +offchain-primitives = { package = "substrate-offchain-primitives", path = "../../core/offchain/primitives", default-features = false } +primitives = { package = "substrate-primitives", path = "../../core/primitives", default-features = false } rstd = { package = "sr-std", path = "../../core/sr-std", default-features = false } sr-primitives = { path = "../../core/sr-primitives", default-features = false } -offchain-primitives = { package = "substrate-offchain-primitives", path = "../../core/offchain/primitives", default-features = false } +sr-staking-primitives = { path = "../../core/sr-staking-primitives", default-features = false } +substrate-keyring = { path = "../../core/keyring", optional = true } +substrate-session = { path = "../../core/session", default-features = false } version = { package = "sr-version", path = "../../core/sr-version", default-features = false } -support = { package = "srml-support", path = "../../srml/support", default-features = false } + +authority-discovery = { package = "srml-authority-discovery", path = "../../srml/authority-discovery", default-features = false } authorship = { package = "srml-authorship", path = "../../srml/authorship", default-features = false } babe = { package = "srml-babe", path = "../../srml/babe", default-features = false } -babe-primitives = { package = "substrate-consensus-babe-primitives", path = "../../core/consensus/babe/primitives", default-features = false } -consensus-primitives = { package = "substrate-consensus-common-primitives", path = "../../core/consensus/common/primitives", default-features = false } balances = { package = "srml-balances", path = "../../srml/balances", default-features = false } -contracts = { package = "srml-contracts", path = "../../srml/contracts", default-features = false } collective = { package = "srml-collective", path = "../../srml/collective", default-features = false } +contracts = { package = "srml-contracts", path = "../../srml/contracts", default-features = false } democracy = { package = "srml-democracy", path = "../../srml/democracy", default-features = false } elections = { package = "srml-elections", path = "../../srml/elections", default-features = false } executive = { package = "srml-executive", path = "../../srml/executive", default-features = false } finality-tracker = { package = "srml-finality-tracker", path = "../../srml/finality-tracker", default-features = false } grandpa = { package = "srml-grandpa", path = "../../srml/grandpa", default-features = false } +im-online = { package = "srml-im-online", path = "../../srml/im-online", default-features = false } indices = { package = "srml-indices", path = "../../srml/indices", default-features = false } membership = { package = "srml-membership", path = "../../srml/membership", default-features = false } +offences = { package = "srml-offences", path = "../../srml/offences", default-features = false } session = { package = "srml-session", path = "../../srml/session", default-features = false, features = ["historical"] } staking = { package = "srml-staking", path = "../../srml/staking", default-features = false } +srml-staking-reward-curve = { path = "../../srml/staking/reward-curve"} +sudo = { package = "srml-sudo", path = "../../srml/sudo", default-features = false } +support = { package = "srml-support", path = "../../srml/support", default-features = false } system = { package = "srml-system", path = "../../srml/system", default-features = false } timestamp = { package = "srml-timestamp", path = "../../srml/timestamp", default-features = false } treasury = { package = "srml-treasury", path = "../../srml/treasury", default-features = false } -sudo = { package = "srml-sudo", path = "../../srml/sudo", default-features = false } -im-online = { package = "srml-im-online", path = "../../srml/im-online", default-features = false } -node-primitives = { path = "../primitives", default-features = false } -rustc-hex = { version = "2.0", optional = true } -serde = { version = "1.0", optional = true } -substrate-keyring = { path = "../../core/keyring", optional = true } -substrate-session = { path = "../../core/session", default-features = false } +utility = { package = "srml-utility", path = "../../srml/utility", default-features = false } [build-dependencies] wasm-builder-runner = { package = "substrate-wasm-builder-runner", version = "1.0.2", path = "../../core/utils/wasm-builder-runner" } [features] default = ["std"] -no_std = [ - "contracts/core", -] std = [ - "codec/std", - "primitives/std", - "rstd/std", - "sr-primitives/std", - "support/std", + "authority-discovery-primitives/std", + "authority-discovery/std", "authorship/std", - "babe/std", "babe-primitives/std", - "consensus-primitives/std", + "babe/std", "balances/std", - "contracts/std", + "client/std", + "codec/std", "collective/std", + "contracts/std", "democracy/std", "elections/std", "executive/std", "finality-tracker/std", "grandpa/std", + "im-online/std", "indices/std", "membership/std", + "node-primitives/std", + "offchain-primitives/std", + "offences/std", + "primitives/std", + "rstd/std", + "rustc-hex", + "safe-mix/std", + "serde", "session/std", + "sr-primitives/std", + "sr-staking-primitives/std", "staking/std", + "substrate-keyring", + "substrate-session/std", + "sudo/std", + "support/std", "system/std", "timestamp/std", "treasury/std", - "sudo/std", + "utility/std", "version/std", - "node-primitives/std", - "serde", - "safe-mix/std", - "client/std", - "rustc-hex", - "substrate-keyring", - "offchain-primitives/std", - "im-online/std", - "substrate-session/std", ] diff --git a/node/runtime/build.rs b/node/runtime/build.rs index a5f22fd0171467ee714f04a3feb583137d5a890c..7311fb90ce6a700cf9047b1ad9b0671ef1107522 100644 --- a/node/runtime/build.rs +++ b/node/runtime/build.rs @@ -21,7 +21,7 @@ fn main() { "wasm_binary.rs", WasmBuilderSource::CratesOrPath { path: "../../core/utils/wasm-builder", - version: "1.0.4", + version: "1.0.7", }, // This instructs LLD to export __heap_base as a global variable, which is used by the // external memory allocator. diff --git a/node/runtime/src/constants.rs b/node/runtime/src/constants.rs index f728efb3be89ff096341e257a5422937cfed48a0..79d3dbd8eb2bc422ead70cab6df8a38fa45aa866 100644 --- a/node/runtime/src/constants.rs +++ b/node/runtime/src/constants.rs @@ -40,11 +40,19 @@ pub mod time { /// that are expressed in blocks. The rest of the code should use /// `SLOT_DURATION` instead (like the timestamp module for calculating the /// minimum period). + /// + /// If using BABE with secondary slots (default) then all of the slots will + /// always be assigned, in which case `MILLISECS_PER_BLOCK` and + /// `SLOT_DURATION` should have the same value. + /// /// - pub const MILLISECS_PER_BLOCK: Moment = 6000; + pub const MILLISECS_PER_BLOCK: Moment = 3000; pub const SECS_PER_BLOCK: Moment = MILLISECS_PER_BLOCK / 1000; - pub const SLOT_DURATION: Moment = 1650; + pub const SLOT_DURATION: Moment = MILLISECS_PER_BLOCK; + + // 1 in 4 blocks (on average, not counting collisions) will be primary BABE blocks. + pub const PRIMARY_PROBABILITY: (u64, u64) = (1, 4); pub const EPOCH_DURATION_IN_BLOCKS: BlockNumber = 10 * MINUTES; pub const EPOCH_DURATION_IN_SLOTS: u64 = { diff --git a/node/runtime/src/lib.rs b/node/runtime/src/lib.rs index 9deaa5852ad8c83d21cfa0ed3a522415ba72ac10..7495190464693be834141fdf74ad97c86f368042 100644 --- a/node/runtime/src/lib.rs +++ b/node/runtime/src/lib.rs @@ -27,19 +27,22 @@ use support::{ use primitives::u32_trait::{_1, _2, _3, _4}; use node_primitives::{ AccountId, AccountIndex, Balance, BlockNumber, Hash, Index, - Moment, Signature, + Moment, Signature, ContractExecResult, }; -use babe::{AuthorityId as BabeId}; -use grandpa::fg_primitives::{self, ScheduledChange}; +use babe_primitives::{AuthorityId as BabeId, AuthoritySignature as BabeSignature}; +use grandpa::fg_primitives; use client::{ block_builder::api::{self as block_builder_api, InherentData, CheckInherentsResult}, runtime_api as client_api, impl_runtime_apis }; -use sr_primitives::{ApplyResult, impl_opaque_keys, generic, create_runtime_str, key_types}; +use sr_primitives::{ + Permill, Perbill, ApplyResult, impl_opaque_keys, generic, create_runtime_str, key_types +}; +use sr_primitives::curve::PiecewiseLinear; use sr_primitives::transaction_validity::TransactionValidity; use sr_primitives::weights::Weight; use sr_primitives::traits::{ - BlakeTwo256, Block as BlockT, DigestFor, NumberFor, StaticLookup, + self, BlakeTwo256, Block as BlockT, NumberFor, StaticLookup, SaturatedConversion, }; use version::RuntimeVersion; use elections::VoteIndex; @@ -47,15 +50,16 @@ use elections::VoteIndex; use version::NativeVersion; use primitives::OpaqueMetadata; use grandpa::{AuthorityId as GrandpaId, AuthorityWeight as GrandpaWeight}; -use im_online::{AuthorityId as ImOnlineId}; -use finality_tracker::{DEFAULT_REPORT_LATENCY, DEFAULT_WINDOW_SIZE}; +use im_online::sr25519::{AuthorityId as ImOnlineId}; +use authority_discovery_primitives::{AuthorityId as EncodedAuthorityId, Signature as EncodedSignature}; +use codec::{Encode, Decode}; +use system::offchain::TransactionSubmitter; #[cfg(any(feature = "std", test))] pub use sr_primitives::BuildStorage; pub use timestamp::Call as TimestampCall; pub use balances::Call as BalancesCall; pub use contracts::Gas; -pub use sr_primitives::{Permill, Perbill}; pub use support::StorageValue; pub use staking::StakerStatus; @@ -80,8 +84,8 @@ pub const VERSION: RuntimeVersion = RuntimeVersion { // and set impl_version to equal spec_version. If only runtime // implementation changes and behavior does not, then leave spec_version as // is and increment impl_version. - spec_version: 140, - impl_version: 141, + spec_version: 172, + impl_version: 172, apis: RUNTIME_API_VERSIONS, }; @@ -108,6 +112,7 @@ parameter_types! { pub const MaximumBlockWeight: Weight = 1_000_000_000; pub const AvailableBlockRatio: Perbill = Perbill::from_percent(75); pub const MaximumBlockLength: u32 = 5 * 1024 * 1024; + pub const Version: RuntimeVersion = VERSION; } impl system::Trait for Runtime { @@ -126,6 +131,12 @@ impl system::Trait for Runtime { type MaximumBlockWeight = MaximumBlockWeight; type MaximumBlockLength = MaximumBlockLength; type AvailableBlockRatio = AvailableBlockRatio; + type Version = Version; +} + +impl utility::Trait for Runtime { + type Event = Event; + type Call = Call; } parameter_types! { @@ -136,6 +147,7 @@ parameter_types! { impl babe::Trait for Runtime { type EpochDuration = EpochDuration; type ExpectedBlockTime = ExpectedBlockTime; + type EpochChangeTrigger = babe::ExternalTrigger; } impl indices::Trait for Runtime { @@ -189,7 +201,7 @@ impl authorship::Trait for Runtime { type EventHandler = Staking; } -type SessionHandlers = (Grandpa, Babe, ImOnline); +type SessionHandlers = (Grandpa, Babe, ImOnline, AuthorityDiscovery); impl_opaque_keys! { pub struct SessionKeys { @@ -207,6 +219,9 @@ impl_opaque_keys! { // `SessionKeys`. // TODO: Introduce some structure to tie these together to make it a bit less of a footgun. This // should be easy, since OneSessionHandler trait provides the `Key` as an associated type. #2858 +parameter_types! { + pub const DisabledValidatorsThreshold: Perbill = Perbill::from_percent(17); +} impl session::Trait for Runtime { type OnSessionEnding = Staking; @@ -214,9 +229,10 @@ impl session::Trait for Runtime { type ShouldEndSession = Babe; type Event = Event; type Keys = SessionKeys; - type ValidatorId = AccountId; + type ValidatorId = ::AccountId; type ValidatorIdOf = staking::StashOf; type SelectInitialValidators = Staking; + type DisabledValidatorsThreshold = DisabledValidatorsThreshold; } impl session::historical::Trait for Runtime { @@ -224,9 +240,21 @@ impl session::historical::Trait for Runtime { type FullIdentificationOf = staking::ExposureOf; } +srml_staking_reward_curve::build! { + const REWARD_CURVE: PiecewiseLinear<'static> = curve!( + min_inflation: 0_025_000, + max_inflation: 0_100_000, + ideal_stake: 0_500_000, + falloff: 0_050_000, + max_piece_count: 40, + test_precision: 0_005_000, + ); +} + parameter_types! { - pub const SessionsPerEra: session::SessionIndex = 6; + pub const SessionsPerEra: sr_staking_primitives::SessionIndex = 6; pub const BondingDuration: staking::EraIndex = 24 * 28; + pub const RewardCurve: &'static PiecewiseLinear<'static> = &REWARD_CURVE; } impl staking::Trait for Runtime { @@ -235,11 +263,12 @@ impl staking::Trait for Runtime { type CurrencyToVote = CurrencyToVoteHandler; type OnRewardMinted = Treasury; type Event = Event; - type Slash = (); - type Reward = (); + type Slash = Treasury; // send the slashed funds to the treasury. + type Reward = (); // rewards are minted from the void type SessionsPerEra = SessionsPerEra; type BondingDuration = BondingDuration; type SessionInterface = Self; + type RewardCurve = RewardCurve; } parameter_types! { @@ -289,6 +318,7 @@ parameter_types! { pub const CandidacyBond: Balance = 10 * DOLLARS; pub const VotingBond: Balance = 1 * DOLLARS; pub const VotingFee: Balance = 2 * DOLLARS; + pub const MinimumVotingLock: Balance = 1 * DOLLARS; pub const PresentSlashPerVoter: Balance = 1 * CENTS; pub const CarryCount: u32 = 6; // one additional vote should go by before an inactive voter can be reaped. @@ -308,6 +338,7 @@ impl elections::Trait for Runtime { type CandidacyBond = CandidacyBond; type VotingBond = VotingBond; type VotingFee = VotingFee; + type MinimumVotingLock = MinimumVotingLock; type PresentSlashPerVoter = PresentSlashPerVoter; type CarryCount = CarryCount; type InactiveGracePeriod = InactiveGracePeriod; @@ -358,10 +389,15 @@ parameter_types! { pub const ContractTransactionBaseFee: Balance = 1 * CENTS; pub const ContractTransactionByteFee: Balance = 10 * MILLICENTS; pub const ContractFee: Balance = 1 * CENTS; + pub const TombstoneDeposit: Balance = 1 * DOLLARS; + pub const RentByteFee: Balance = 1 * DOLLARS; + pub const RentDepositOffset: Balance = 1000 * DOLLARS; + pub const SurchargeReward: Balance = 150 * DOLLARS; } impl contracts::Trait for Runtime { type Currency = Balances; + type Time = Timestamp; type Call = Call; type Event = Event; type DetermineContractAddress = contracts::SimpleAddressDeterminator; @@ -369,18 +405,18 @@ impl contracts::Trait for Runtime { type TrieIdGenerator = contracts::TrieIdFromParentCounter; type GasPayment = (); type SignedClaimHandicap = contracts::DefaultSignedClaimHandicap; - type TombstoneDeposit = contracts::DefaultTombstoneDeposit; + type TombstoneDeposit = TombstoneDeposit; type StorageSizeOffset = contracts::DefaultStorageSizeOffset; - type RentByteFee = contracts::DefaultRentByteFee; - type RentDepositOffset = contracts::DefaultRentDepositOffset; - type SurchargeReward = contracts::DefaultSurchargeReward; + type RentByteFee = RentByteFee; + type RentDepositOffset = RentDepositOffset; + type SurchargeReward = SurchargeReward; type TransferFee = ContractTransferFee; type CreationFee = ContractCreationFee; type TransactionBaseFee = ContractTransactionBaseFee; type TransactionByteFee = ContractTransactionByteFee; type ContractFee = ContractFee; type CallBaseFee = contracts::DefaultCallBaseFee; - type CreateBaseFee = contracts::DefaultCreateBaseFee; + type InstantiateBaseFee = contracts::DefaultInstantiateBaseFee; type MaxDepth = contracts::DefaultMaxDepth; type MaxValueSize = contracts::DefaultMaxValueSize; type BlockGasLimit = contracts::DefaultBlockGasLimit; @@ -391,10 +427,24 @@ impl sudo::Trait for Runtime { type Proposal = Call; } +type SubmitTransaction = TransactionSubmitter; + impl im_online::Trait for Runtime { + type AuthorityId = ImOnlineId; type Call = Call; type Event = Event; - type UncheckedExtrinsic = UncheckedExtrinsic; + type SubmitTransaction = SubmitTransaction; + type ReportUnresponsiveness = Offences; +} + +impl offences::Trait for Runtime { + type Event = Event; + type IdentificationTuple = session::historical::IdentificationTuple; + type OnOffenceHandler = Staking; +} + +impl authority_discovery::Trait for Runtime { + type AuthorityId = BabeId; } impl grandpa::Trait for Runtime { @@ -402,8 +452,8 @@ impl grandpa::Trait for Runtime { } parameter_types! { - pub const WindowSize: BlockNumber = DEFAULT_WINDOW_SIZE.into(); - pub const ReportLatency: BlockNumber = DEFAULT_REPORT_LATENCY.into(); + pub const WindowSize: BlockNumber = 101; + pub const ReportLatency: BlockNumber = 1000; } impl finality_tracker::Trait for Runtime { @@ -412,6 +462,34 @@ impl finality_tracker::Trait for Runtime { type ReportLatency = ReportLatency; } +impl system::offchain::CreateTransaction for Runtime { + type Signature = Signature; + + fn create_transaction>( + call: Call, + account: AccountId, + index: Index, + ) -> Option<(Call, ::SignaturePayload)> { + let period = 1 << 8; + let current_block = System::block_number().saturated_into::(); + let tip = 0; + let extra: SignedExtra = ( + system::CheckVersion::::new(), + system::CheckGenesis::::new(), + system::CheckEra::::from(generic::Era::mortal(period, current_block)), + system::CheckNonce::::from(index), + system::CheckWeight::::new(), + balances::TakeFees::::from(tip), + Default::default(), + ); + let raw_payload = SignedPayload::new(call, extra).ok()?; + let signature = F::sign(account.clone(), &raw_payload)?; + let address = Indices::unlookup(account); + let (call, extra, _) = raw_payload.deconstruct(); + Some((call, (address, signature, extra))) + } +} + construct_runtime!( pub enum Runtime where Block = Block, @@ -419,11 +497,12 @@ construct_runtime!( UncheckedExtrinsic = UncheckedExtrinsic { System: system::{Module, Call, Storage, Config, Event}, + Utility: utility::{Module, Call, Event}, Babe: babe::{Module, Call, Storage, Config, Inherent(Timestamp)}, Timestamp: timestamp::{Module, Call, Storage, Inherent}, Authorship: authorship::{Module, Call, Storage, Inherent}, Indices: indices, - Balances: balances, + Balances: balances::{default, Error}, Staking: staking::{default, OfflineWorker}, Session: session::{Module, Call, Storage, Event, Config}, Democracy: democracy::{Module, Call, Storage, Config, Event}, @@ -436,7 +515,9 @@ construct_runtime!( Treasury: treasury::{Module, Call, Storage, Event}, Contracts: contracts, Sudo: sudo, - ImOnline: im_online::{Module, Call, Storage, Event, ValidateUnsigned, Config}, + ImOnline: im_online::{Module, Call, Storage, Event, ValidateUnsigned, Config}, + AuthorityDiscovery: authority_discovery::{Module, Call, Config}, + Offences: offences::{Module, Call, Storage, Event}, } ); @@ -452,14 +533,18 @@ pub type SignedBlock = generic::SignedBlock; pub type BlockId = generic::BlockId; /// The SignedExtension to the basic transaction logic. pub type SignedExtra = ( + system::CheckVersion, system::CheckGenesis, system::CheckEra, system::CheckNonce, system::CheckWeight, - balances::TakeFees + balances::TakeFees, + contracts::CheckBlockGasLimit, ); /// Unchecked extrinsic type as expected by this runtime. pub type UncheckedExtrinsic = generic::UncheckedExtrinsic; +/// The payload being signed in transactions. +pub type SignedPayload = generic::SignedPayload; /// Extrinsic type that has already been checked. pub type CheckedExtrinsic = generic::CheckedExtrinsic; /// Executive: handles dispatch to the various modules. @@ -521,51 +606,86 @@ impl_runtime_apis! { } impl fg_primitives::GrandpaApi for Runtime { - fn grandpa_pending_change(digest: &DigestFor) - -> Option>> - { - Grandpa::pending_change(digest) - } - - fn grandpa_forced_change(digest: &DigestFor) - -> Option<(NumberFor, ScheduledChange>)> - { - Grandpa::forced_change(digest) - } - fn grandpa_authorities() -> Vec<(GrandpaId, GrandpaWeight)> { Grandpa::grandpa_authorities() } } impl babe_primitives::BabeApi for Runtime { - fn startup_data() -> babe_primitives::BabeConfiguration { + fn configuration() -> babe_primitives::BabeConfiguration { // The choice of `c` parameter (where `1 - c` represents the // probability of a slot being empty), is done in accordance to the // slot duration and expected target block time, for safely // resisting network delays of maximum two seconds. // babe_primitives::BabeConfiguration { - median_required_blocks: 1000, slot_duration: Babe::slot_duration(), - c: (278, 1000), + epoch_length: EpochDuration::get(), + c: PRIMARY_PROBABILITY, + genesis_authorities: Babe::authorities(), + randomness: Babe::randomness(), + secondary_slots: true, } } + } + + impl authority_discovery_primitives::AuthorityDiscoveryApi for Runtime { + fn authorities() -> Vec { + AuthorityDiscovery::authorities().into_iter() + .map(|id| id.encode()) + .map(EncodedAuthorityId) + .collect() + } - fn epoch() -> babe_primitives::Epoch { - babe_primitives::Epoch { - start_slot: Babe::epoch_start_slot(), - authorities: Babe::authorities(), - epoch_index: Babe::epoch_index(), - randomness: Babe::randomness(), - duration: EpochDuration::get(), - } + fn sign(payload: &Vec) -> Option<(EncodedSignature, EncodedAuthorityId)> { + AuthorityDiscovery::sign(payload).map(|(sig, id)| { + (EncodedSignature(sig.encode()), EncodedAuthorityId(id.encode())) + }) + } + + fn verify(payload: &Vec, signature: &EncodedSignature, authority_id: &EncodedAuthorityId) -> bool { + let signature = match BabeSignature::decode(&mut &signature.0[..]) { + Ok(s) => s, + _ => return false, + }; + + let authority_id = match BabeId::decode(&mut &authority_id.0[..]) { + Ok(id) => id, + _ => return false, + }; + + AuthorityDiscovery::verify(payload, signature, authority_id) + } + } + + impl node_primitives::AccountNonceApi for Runtime { + fn account_nonce(account: AccountId) -> Index { + System::account_nonce(account) } } - impl consensus_primitives::ConsensusApi for Runtime { - fn authorities() -> Vec { - Babe::authorities().into_iter().map(|(a, _)| a).collect() + impl node_primitives::ContractsApi for Runtime { + fn call( + origin: AccountId, + dest: AccountId, + value: Balance, + gas_limit: u64, + input_data: Vec, + ) -> ContractExecResult { + let exec_result = Contracts::bare_call( + origin, + dest.into(), + value, + gas_limit, + input_data, + ); + match exec_result { + Ok(v) => ContractExecResult::Success { + status: v.status, + data: v.data, + }, + Err(_) => ContractExecResult::Error, + } } } @@ -576,3 +696,28 @@ impl_runtime_apis! { } } } + +#[cfg(test)] +mod tests { + use super::*; + use sr_primitives::app_crypto::RuntimeAppPublic; + use system::offchain::SubmitSignedTransaction; + + fn is_submit_signed_transaction(_arg: T) where + T: SubmitSignedTransaction< + Runtime, + Call, + Extrinsic=UncheckedExtrinsic, + CreateTransaction=Runtime, + Signer=Signer, + >, + Signer: RuntimeAppPublic + From, + Signer::Signature: Into, + {} + + #[test] + fn validate_bounds() { + let x = SubmitTransaction::default(); + is_submit_signed_transaction(x); + } +} diff --git a/node/testing/Cargo.toml b/node/testing/Cargo.toml new file mode 100644 index 0000000000000000000000000000000000000000..e622e35d4aad0c37da7aa7db108e51546476609f --- /dev/null +++ b/node/testing/Cargo.toml @@ -0,0 +1,30 @@ +[package] +name = "node-testing" +version = "2.0.0" +authors = ["Parity Technologies "] +description = "Test utilities for Substrate node." +edition = "2018" + +[dependencies] +balances = { package = "srml-balances", path = "../../srml/balances" } +client = { package = "substrate-client", path = "../../core/client" } +contracts = { package = "srml-contracts", path = "../../srml/contracts" } +grandpa = { package = "srml-grandpa", path = "../../srml/grandpa" } +indices = { package = "srml-indices", path = "../../srml/indices" } +keyring = { package = "substrate-keyring", path = "../../core/keyring" } +node-executor = { path = "../executor" } +node-primitives = { path = "../primitives" } +node-runtime = { path = "../runtime" } +codec = { package = "parity-scale-codec", version = "1.0.0" } +primitives = { package = "substrate-primitives", path = "../../core/primitives" } +sr-io = { path = "../../core/sr-io" } +sr-primitives = { path = "../../core/sr-primitives" } +runtime_support = { package = "srml-support", path = "../../srml/support" } +session = { package = "srml-session", path = "../../srml/session" } +staking = { package = "srml-staking", path = "../../srml/staking" } +substrate-executor = { path = "../../core/executor" } +system = { package = "srml-system", path = "../../srml/system" } +test-client = { package = "substrate-test-client", path = "../../core/test-client" } +timestamp = { package = "srml-timestamp", path = "../../srml/timestamp" } +treasury = { package = "srml-treasury", path = "../../srml/treasury" } +wabt = "0.9.2" diff --git a/node/testing/src/client.rs b/node/testing/src/client.rs new file mode 100644 index 0000000000000000000000000000000000000000..3b16f2cbcb97d801500e1bb8ffbef3f2e0c9bb9c --- /dev/null +++ b/node/testing/src/client.rs @@ -0,0 +1,73 @@ +// Copyright 2019 Parity Technologies (UK) Ltd. +// This file is part of Substrate. + +// Substrate 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. + +// Substrate 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 Substrate. If not, see . + +//! Utilites to build a `TestClient` for `node-runtime`. + +use sr_primitives::BuildStorage; + +/// Re-export test-client utilities. +pub use test_client::*; + +/// Call executor for `node-runtime` `TestClient`. +pub type Executor = substrate_executor::NativeExecutor; + +/// Default backend type. +pub type Backend = client_db::Backend; + +/// Test client type. +pub type Client = client::Client< + Backend, + client::LocalCallExecutor, + node_primitives::Block, + node_runtime::RuntimeApi, +>; + +/// Genesis configuration parameters for `TestClient`. +#[derive(Default)] +pub struct GenesisParameters { + support_changes_trie: bool, +} + +impl test_client::GenesisInit for GenesisParameters { + fn genesis_storage(&self) -> (StorageOverlay, ChildrenStorageOverlay) { + crate::genesis::config(self.support_changes_trie, None).build_storage().unwrap() + } +} + +/// A `test-runtime` extensions to `TestClientBuilder`. +pub trait TestClientBuilderExt: Sized { + /// Create test client builder. + fn new() -> Self; + + /// Build the test client. + fn build(self) -> Client; +} + +impl TestClientBuilderExt for test_client::TestClientBuilder< + client::LocalCallExecutor, + Backend, + GenesisParameters, +> { + fn new() -> Self{ + Self::default() + } + + fn build(self) -> Client { + self.build_with_native_executor(None).0 + } +} + + diff --git a/node/testing/src/genesis.rs b/node/testing/src/genesis.rs new file mode 100644 index 0000000000000000000000000000000000000000..35ff93d1a69ae65797a2bca6d592bc65e0e474bd --- /dev/null +++ b/node/testing/src/genesis.rs @@ -0,0 +1,100 @@ +// Copyright 2019 Parity Technologies (UK) Ltd. +// This file is part of Substrate. + +// Substrate 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. + +// Substrate 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 Substrate. If not, see . + +//! Genesis Configuration. + +use crate::keyring::*; +use keyring::{Ed25519Keyring, Sr25519Keyring}; +use node_runtime::{ + GenesisConfig, BalancesConfig, SessionConfig, StakingConfig, SystemConfig, + GrandpaConfig, IndicesConfig, ContractsConfig, WASM_BINARY, +}; +use node_runtime::constants::currency::*; +use primitives::ChangesTrieConfiguration; +use sr_primitives::Perbill; + + +/// Create genesis runtime configuration for tests. +pub fn config(support_changes_trie: bool, code: Option<&[u8]>) -> GenesisConfig { + GenesisConfig { + system: Some(SystemConfig { + changes_trie_config: if support_changes_trie { Some(ChangesTrieConfiguration { + digest_interval: 2, + digest_levels: 2, + }) } else { None }, + code: code.map(|x| x.to_vec()).unwrap_or_else(|| WASM_BINARY.to_vec()), + }), + indices: Some(IndicesConfig { + ids: vec![alice(), bob(), charlie(), dave(), eve(), ferdie()], + }), + balances: Some(BalancesConfig { + balances: vec![ + (alice(), 111 * DOLLARS), + (bob(), 100 * DOLLARS), + (charlie(), 100_000_000 * DOLLARS), + (dave(), 111 * DOLLARS), + (eve(), 101 * DOLLARS), + (ferdie(), 100 * DOLLARS), + ], + vesting: vec![], + }), + session: Some(SessionConfig { + keys: vec![ + (alice(), to_session_keys( + &Ed25519Keyring::Alice, + &Sr25519Keyring::Alice, + )), + (bob(), to_session_keys( + &Ed25519Keyring::Bob, + &Sr25519Keyring::Bob, + )), + (charlie(), to_session_keys( + &Ed25519Keyring::Charlie, + &Sr25519Keyring::Charlie, + )), + ] + }), + staking: Some(StakingConfig { + current_era: 0, + stakers: vec![ + (dave(), alice(), 111 * DOLLARS, staking::StakerStatus::Validator), + (eve(), bob(), 100 * DOLLARS, staking::StakerStatus::Validator), + (ferdie(), charlie(), 100 * DOLLARS, staking::StakerStatus::Validator) + ], + validator_count: 3, + minimum_validator_count: 0, + slash_reward_fraction: Perbill::from_percent(10), + invulnerables: vec![alice(), bob(), charlie()], + .. Default::default() + }), + contracts: Some(ContractsConfig { + current_schedule: Default::default(), + gas_price: 1 * MILLICENTS, + }), + babe: Some(Default::default()), + grandpa: Some(GrandpaConfig { + authorities: vec![], + }), + im_online: Some(Default::default()), + authority_discovery: Some(Default::default()), + democracy: Some(Default::default()), + collective_Instance1: Some(Default::default()), + collective_Instance2: Some(Default::default()), + membership_Instance1: Some(Default::default()), + elections: Some(Default::default()), + sudo: Some(Default::default()), + } +} diff --git a/node/testing/src/keyring.rs b/node/testing/src/keyring.rs new file mode 100644 index 0000000000000000000000000000000000000000..0c6eb478cc5a08055cd3c6c0bbb1caf7cf50447d --- /dev/null +++ b/node/testing/src/keyring.rs @@ -0,0 +1,104 @@ +// Copyright 2019 Parity Technologies (UK) Ltd. +// This file is part of Substrate. + +// Substrate 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. + +// Substrate 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 Substrate. If not, see . + +//! Test accounts. + +use keyring::{AccountKeyring, Sr25519Keyring, Ed25519Keyring}; +use node_primitives::{AccountId, Balance, Index}; +use node_runtime::{CheckedExtrinsic, UncheckedExtrinsic, SessionKeys, SignedExtra}; +use sr_primitives::generic::Era; +use codec::Encode; + +/// Alice's account id. +pub fn alice() -> AccountId { + AccountKeyring::Alice.into() +} + +/// Bob's account id. +pub fn bob() -> AccountId { + AccountKeyring::Bob.into() +} + +/// Charlie's account id. +pub fn charlie() -> AccountId { + AccountKeyring::Charlie.into() +} + +/// Dave's account id. +pub fn dave() -> AccountId { + AccountKeyring::Dave.into() +} + +/// Eve's account id. +pub fn eve() -> AccountId { + AccountKeyring::Eve.into() +} + +/// Ferdie's account id. +pub fn ferdie() -> AccountId { + AccountKeyring::Ferdie.into() +} + +/// Convert keyrings into `SessionKeys`. +pub fn to_session_keys( + ed25519_keyring: &Ed25519Keyring, + sr25519_keyring: &Sr25519Keyring, +) -> SessionKeys { + SessionKeys { + grandpa: ed25519_keyring.to_owned().public().into(), + babe: sr25519_keyring.to_owned().public().into(), + im_online: sr25519_keyring.to_owned().public().into(), + } +} + +/// Returns transaction extra. +pub fn signed_extra(nonce: Index, extra_fee: Balance) -> SignedExtra { + ( + system::CheckVersion::new(), + system::CheckGenesis::new(), + system::CheckEra::from(Era::mortal(256, 0)), + system::CheckNonce::from(nonce), + system::CheckWeight::new(), + balances::TakeFees::from(extra_fee), + Default::default(), + ) +} + +/// Sign given `CheckedExtrinsic`. +pub fn sign(xt: CheckedExtrinsic, version: u32, genesis_hash: [u8; 32]) -> UncheckedExtrinsic { + match xt.signed { + Some((signed, extra)) => { + let payload = (xt.function, extra.clone(), version, genesis_hash, genesis_hash); + let key = AccountKeyring::from_public(&signed).unwrap(); + let signature = payload.using_encoded(|b| { + if b.len() > 256 { + key.sign(&sr_io::blake2_256(b)) + } else { + key.sign(b) + } + }).into(); + UncheckedExtrinsic { + signature: Some((indices::address::Address::Id(signed), signature, extra)), + function: payload.0, + } + } + None => UncheckedExtrinsic { + signature: None, + function: xt.function, + }, + } +} + diff --git a/node/testing/src/lib.rs b/node/testing/src/lib.rs new file mode 100644 index 0000000000000000000000000000000000000000..71a22d9b57f2555095b5b5ab67701945a2dd6897 --- /dev/null +++ b/node/testing/src/lib.rs @@ -0,0 +1,24 @@ +// Copyright 2019 Parity Technologies (UK) Ltd. +// This file is part of Substrate. + +// Substrate 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. + +// Substrate 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 Substrate. If not, see . + +//! A set of testing utilities for Substrate Node. + +#![warn(missing_docs)] + +pub mod client; +pub mod genesis; +pub mod keyring; + diff --git a/rustdoc-header.html b/rustdoc-header.html new file mode 100644 index 0000000000000000000000000000000000000000..a679d5e299da7a79e6fd52aa3594a78053b7d641 --- /dev/null +++ b/rustdoc-header.html @@ -0,0 +1,10 @@ + + + + diff --git a/scripts/build-only-wasm.sh b/scripts/build-only-wasm.sh new file mode 100755 index 0000000000000000000000000000000000000000..b6da3319c8214aeca3ca54b76fda87d83077eec5 --- /dev/null +++ b/scripts/build-only-wasm.sh @@ -0,0 +1,29 @@ +#!/usr/bin/env sh + +# Script for building only the WASM binary of the given project. + +set -e + +PROJECT_ROOT=`git rev-parse --show-toplevel` + +if [ "$#" -lt 1 ]; then + echo "You need to pass the name of the crate you want to compile!" + exit 1 +fi + +WASM_BUILDER_RUNNER="$PROJECT_ROOT/target/release/wbuild-runner/$1" + +if [ -z "$2" ]; then + export WASM_TARGET_DIRECTORY=$(pwd) +else + export WASM_TARGET_DIRECTORY=$2 +fi + +if [ -d $WASM_BUILDER_RUNNER ]; then + export DEBUG=false + export OUT_DIR="$PROJECT_ROOT/target/release/build" + cargo run --release --manifest-path="$WASM_BUILDER_RUNNER/Cargo.toml" \ + | grep -vE "cargo:rerun-if-|Executing build command" +else + cargo build --release -p $1 +fi diff --git a/scripts/node-template-release/src/main.rs b/scripts/node-template-release/src/main.rs index 4036104f6030a243f44deaf25664597ad13ed69b..e1db5af64974842f7e8efef39faa11d244faed02 100644 --- a/scripts/node-template-release/src/main.rs +++ b/scripts/node-template-release/src/main.rs @@ -117,8 +117,15 @@ fn replace_path_dependencies_with_git(cargo_toml_path: &Path, commit_id: &str, c cargo_toml.insert("dependencies".into(), dependencies.into()); } -/// Add `profile.release` = `panic = unwind` to the given `Cargo.toml` -fn cargo_toml_add_profile_release(cargo_toml: &mut CargoToml) { +/// Update the top level (workspace) `Cargo.toml` file. +/// +/// - Adds `profile.release` = `panic = unwind` +/// - Adds `workspace` definition +fn update_top_level_cargo_toml( + cargo_toml: &mut CargoToml, + workspace_members: Vec<&PathBuf>, + node_template_path: &Path, +) { let mut panic_unwind = toml::value::Table::new(); panic_unwind.insert("panic".into(), "unwind".into()); @@ -126,6 +133,24 @@ fn cargo_toml_add_profile_release(cargo_toml: &mut CargoToml) { profile.insert("release".into(), panic_unwind.into()); cargo_toml.insert("profile".into(), profile.into()); + + let members = workspace_members.iter() + .map(|p| + p.strip_prefix(node_template_path) + .expect("Workspace member is a child of the node template path!") + .parent() + // We get the `Cargo.toml` paths as workspace members, but for the `members` field + // we just need the path. + .expect("The given path ends with `Cargo.toml` as file name!") + .display() + .to_string() + ) + .collect::>(); + + let mut members_section = toml::value::Table::new(); + members_section.insert("members".into(), members.into()); + + cargo_toml.insert("workspace".into(), members_section.into()); } fn write_cargo_toml(path: &Path, cargo_toml: CargoToml) { @@ -137,10 +162,24 @@ fn write_cargo_toml(path: &Path, cargo_toml: CargoToml) { /// Build and test the generated node-template fn build_and_test(path: &Path, cargo_tomls: &[PathBuf]) { // Build node - assert!(Command::new("cargo").args(&["build", "--all"]).current_dir(path).status().expect("Compiles node").success()); + assert!( + Command::new("cargo") + .args(&["build", "--all"]) + .current_dir(path) + .status() + .expect("Compiles node") + .success() + ); // Test node - assert!(Command::new("cargo").args(&["test", "--all"]).current_dir(path).status().expect("Tests node").success()); + assert!( + Command::new("cargo") + .args(&["test", "--all"]) + .current_dir(path) + .status() + .expect("Tests node") + .success() + ); // Remove all `target` directories for toml in cargo_tomls { @@ -174,14 +213,20 @@ fn main() { let cargo_tomls = find_cargo_tomls(build_dir.path().to_owned()); let commit_id = get_git_commit_id(&options.node_template); + let top_level_cargo_toml_path = node_template_path.join("Cargo.toml"); cargo_tomls.iter().for_each(|t| { let mut cargo_toml = parse_cargo_toml(&t); replace_path_dependencies_with_git(&t, &commit_id, &mut cargo_toml); - // If this is the top-level `Cargo.toml`, add `profile.release` - if &node_template_path.join("Cargo.toml") == t { - cargo_toml_add_profile_release(&mut cargo_toml); + // Check if this is the top level `Cargo.toml`, as this requires some special treatments. + if top_level_cargo_toml_path == *t { + // All workspace member `Cargo.toml` file paths. + let workspace_members = cargo_tomls.iter() + .filter(|p| **p != top_level_cargo_toml_path) + .collect(); + + update_top_level_cargo_toml(&mut cargo_toml, workspace_members, &node_template_path); } write_cargo_toml(&t, cargo_toml); diff --git a/srml/assets/Cargo.toml b/srml/assets/Cargo.toml index 2badb461303cd4aa390a00840d4d25e0423ce9fc..5f22ab3ba33e5ca51aae10a4d62a2f073f2c2b4e 100644 --- a/srml/assets/Cargo.toml +++ b/srml/assets/Cargo.toml @@ -5,19 +5,19 @@ authors = ["Parity Technologies "] edition = "2018" [dependencies] -serde = { version = "1.0", optional = true } +serde = { version = "1.0.101", optional = true } codec = { package = "parity-scale-codec", version = "1.0.0", default-features = false } # Needed for various traits. In our case, `OnFinalize`. sr-primitives = { path = "../../core/sr-primitives", default-features = false } # Needed for type-safe access to storage DB. -srml-support = { path = "../support", default-features = false } +support = { package = "srml-support", path = "../support", default-features = false } # `system` module provides us with all sorts of useful stuff and macros depend on it being around. system = { package = "srml-system", path = "../system", default-features = false } [dev-dependencies] primitives = { package = "substrate-primitives", path = "../../core/primitives" } -sr-std = { path = "../../core/sr-std" } -runtime_io = { package = "sr-io", path = "../../core/sr-io" } +rstd = { package = "sr-std", path = "../../core/sr-std" } +runtime-io = { package = "sr-io", path = "../../core/sr-io" } [features] default = ["std"] @@ -25,6 +25,7 @@ std = [ "serde", "codec/std", "sr-primitives/std", - "srml-support/std", + "support/std", "system/std", + "runtime-io/std", ] diff --git a/srml/assets/src/lib.rs b/srml/assets/src/lib.rs index d5ae95c559539d82466cd8c010b0616a78a21645..2a4245176a4fa046af6c34c4e13648b20e49b00e 100644 --- a/srml/assets/src/lib.rs +++ b/srml/assets/src/lib.rs @@ -130,7 +130,7 @@ // Ensure we're `no_std` when compiling for Wasm. #![cfg_attr(not(feature = "std"), no_std)] -use srml_support::{StorageValue, StorageMap, Parameter, decl_module, decl_event, decl_storage, ensure}; +use support::{Parameter, decl_module, decl_event, decl_storage, ensure}; use sr_primitives::traits::{Member, SimpleArithmetic, Zero, StaticLookup}; use system::ensure_signed; use sr_primitives::traits::One; @@ -149,7 +149,7 @@ pub trait Trait: system::Trait { decl_module! { pub struct Module for enum Call where origin: T::Origin { - fn deposit_event() = default; + fn deposit_event() = default; /// Issue a new class of fungible assets. There are, and will only ever be, `total` /// such assets and they'll all belong to the `origin` initially. It will have an /// identifier `AssetId` instance: this will be specified in the `Issued` event. @@ -159,7 +159,7 @@ decl_module! { let id = Self::next_asset_id(); >::mutate(|id| *id += One::one()); - >::insert((id, origin.clone()), total); + >::insert((id, &origin), total); >::insert(id, total); Self::deposit_event(RawEvent::Issued(id, origin, total)); @@ -186,7 +186,7 @@ decl_module! { /// Destroy any assets of `id` owned by `origin`. fn destroy(origin, #[compact] id: T::AssetId) { let origin = ensure_signed(origin)?; - let balance = >::take((id, origin.clone())); + let balance = >::take((id, &origin)); ensure!(!balance.is_zero(), "origin balance should be non-zero"); >::mutate(id, |total_supply| *total_supply -= balance); @@ -196,10 +196,11 @@ decl_module! { } decl_event!( - pub enum Event - where ::AccountId, - ::Balance, - ::AssetId { + pub enum Event where + ::AccountId, + ::Balance, + ::AssetId, + { /// Some assets were issued. Issued(AssetId, AccountId, Balance), /// Some assets were transferred. @@ -240,7 +241,7 @@ mod tests { use super::*; use runtime_io::with_externalities; - use srml_support::{impl_outer_origin, assert_ok, assert_noop, parameter_types}; + use support::{impl_outer_origin, assert_ok, assert_noop, parameter_types}; use primitives::{H256, Blake2Hasher}; // The testing primitives are very useful for avoiding having to work with signatures // or public keys. `u64` is used as the `AccountId` and no `Signature`s are required. @@ -277,6 +278,7 @@ mod tests { type MaximumBlockWeight = MaximumBlockWeight; type AvailableBlockRatio = AvailableBlockRatio; type MaximumBlockLength = MaximumBlockLength; + type Version = (); } impl Trait for Test { type Event = (); diff --git a/srml/aura/Cargo.toml b/srml/aura/Cargo.toml index 955831ba299104ddd35f360bb2a99f43333aaef1..f1c37b7c08d45fe7ec2cadcf608d1c407e7dbc15 100644 --- a/srml/aura/Cargo.toml +++ b/srml/aura/Cargo.toml @@ -5,38 +5,37 @@ authors = ["Parity Technologies "] edition = "2018" [dependencies] +app-crypto = { package = "substrate-application-crypto", path = "../../core/application-crypto", default-features = false } codec = { package = "parity-scale-codec", version = "1.0.0", default-features = false, features = ["derive"] } -serde = { version = "1.0", optional = true } inherents = { package = "substrate-inherents", path = "../../core/inherents", default-features = false } +primitives = { package = "substrate-primitives", path = "../../core/primitives", default-features = false } rstd = { package = "sr-std", path = "../../core/sr-std", default-features = false } +serde = { version = "1.0.101", optional = true } +session = { package = "srml-session", path = "../session", default-features = false } sr-primitives = { path = "../../core/sr-primitives", default-features = false } -primitives = { package = "substrate-primitives", path = "../../core/primitives", default-features = false } -app-crypto = { package = "substrate-application-crypto", path = "../../core/application-crypto", default-features = false } -srml-support = { path = "../support", default-features = false } +runtime-io ={ package = "sr-io", path = "../../core/sr-io", default-features = false } +support = { package = "srml-support", path = "../support", default-features = false } +substrate-consensus-aura-primitives = { path = "../../core/consensus/aura/primitives", default-features = false} system = { package = "srml-system", path = "../system", default-features = false } timestamp = { package = "srml-timestamp", path = "../timestamp", default-features = false } -staking = { package = "srml-staking", path = "../staking", default-features = false } -session = { package = "srml-session", path = "../session", default-features = false } -substrate-consensus-aura-primitives = { path = "../../core/consensus/aura/primitives", default-features = false} [dev-dependencies] -lazy_static = "1.0" +lazy_static = "1.4.0" parking_lot = "0.9.0" -runtime_io = { package = "sr-io", path = "../../core/sr-io" } [features] default = ["std"] std = [ - "serde", + "app-crypto/std", "codec/std", + "inherents/std", + "runtime-io/std", + "primitives/std", "rstd/std", - "srml-support/std", + "serde", "sr-primitives/std", - "primitives/std", + "support/std", + "substrate-consensus-aura-primitives/std", "system/std", "timestamp/std", - "staking/std", - "inherents/std", - "substrate-consensus-aura-primitives/std", - "app-crypto/std", ] diff --git a/srml/aura/src/lib.rs b/srml/aura/src/lib.rs index 6d707fc8e195f79416a4f421042c0e9d8df7e125..834d6b0a14dfe941d9809e0c638a5f44b8f1a470 100644 --- a/srml/aura/src/lib.rs +++ b/srml/aura/src/lib.rs @@ -31,9 +31,6 @@ //! //! ## Related Modules //! -//! - [Staking](../srml_staking/index.html): The Staking module is called in Aura to enforce slashing -//! if validators miss a certain number of slots (see the [`StakingSlasher`](./struct.StakingSlasher.html) -//! struct and associated method). //! - [Timestamp](../srml_timestamp/index.html): The Timestamp module is used in Aura to track //! consensus rounds (via `slots`). //! - [Consensus](../srml_consensus/index.html): The Consensus module does not relate directly to Aura, @@ -51,11 +48,14 @@ pub use timestamp; use rstd::{result, prelude::*}; -use codec::Encode; -use srml_support::{decl_storage, decl_module, Parameter, storage::StorageValue, traits::Get}; -use app_crypto::AppPublic; +use codec::{Encode, Decode}; +use support::{ + decl_storage, decl_module, Parameter, traits::{Get, FindAuthor}, + ConsensusEngineId, +}; use sr_primitives::{ - traits::{SaturatedConversion, Saturating, Zero, One, Member, IsMember}, generic::DigestItem, + RuntimeAppPublic, + traits::{SaturatedConversion, Saturating, Zero, Member, IsMember}, generic::DigestItem, }; use timestamp::OnTimestampSet; #[cfg(feature = "std")] @@ -63,9 +63,7 @@ use timestamp::TimestampInherentData; use inherents::{RuntimeString, InherentIdentifier, InherentData, ProvideInherent, MakeFatalError}; #[cfg(feature = "std")] use inherents::{InherentDataProviders, ProvideInherentData}; -use substrate_consensus_aura_primitives::{AURA_ENGINE_ID, ConsensusLog}; -#[cfg(feature = "std")] -use codec::Decode; +use substrate_consensus_aura_primitives::{AURA_ENGINE_ID, ConsensusLog, AuthorityIndex}; mod mock; mod tests; @@ -142,21 +140,9 @@ impl ProvideInherentData for InherentDataProvider { } } -/// Something that can handle Aura consensus reports. -pub trait HandleReport { - fn handle_report(report: AuraReport); -} - -impl HandleReport for () { - fn handle_report(_report: AuraReport) { } -} - pub trait Trait: timestamp::Trait { - /// The logic for handling reports. - type HandleReport: HandleReport; - /// The identifier type for an authority. - type AuthorityId: Member + Parameter + AppPublic + Default; + type AuthorityId: Member + Parameter + RuntimeAppPublic + Default; } decl_storage! { @@ -165,7 +151,11 @@ decl_storage! { LastTimestamp get(last) build(|_| 0.into()): T::Moment; /// The current authorities - pub Authorities get(authorities) config(): Vec; + pub Authorities get(authorities): Vec; + } + add_extra_genesis { + config(authorities): Vec; + build(|config| Module::::initialize_authorities(&config.authorities)) } } @@ -183,11 +173,25 @@ impl Module { ); >::deposit_log(log.into()); } + + fn initialize_authorities(authorities: &[T::AuthorityId]) { + if !authorities.is_empty() { + assert!(>::get().is_empty(), "Authorities are already initialized!"); + >::put(authorities); + } + } } impl session::OneSessionHandler for Module { type Key = T::AuthorityId; + fn on_genesis_session<'a, I: 'a>(validators: I) + where I: Iterator + { + let authorities = validators.map(|(_, k)| k).collect::>(); + Self::initialize_authorities(&authorities); + } + fn on_new_session<'a, I: 'a>(changed: bool, validators: I, _queued_validators: I) where I: Iterator { @@ -200,16 +204,34 @@ impl session::OneSessionHandler for Module { } } } + fn on_disabled(i: usize) { let log: DigestItem = DigestItem::Consensus( AURA_ENGINE_ID, - ConsensusLog::::OnDisabled(i as u64).encode(), + ConsensusLog::::OnDisabled(i as AuthorityIndex).encode(), ); >::deposit_log(log.into()); } } +impl FindAuthor for Module { + fn find_author<'a, I>(digests: I) -> Option where + I: 'a + IntoIterator + { + for (id, mut data) in digests.into_iter() { + if id == AURA_ENGINE_ID { + if let Ok(slot_num) = u64::decode(&mut data) { + let author_index = slot_num % Self::authorities().len() as u64; + return Some(author_index as u32) + } + } + } + + None + } +} + impl IsMember for Module { fn is_member(authority_id: &T::AuthorityId) -> bool { Self::authorities() @@ -218,34 +240,6 @@ impl IsMember for Module { } } -/// A report of skipped authorities in Aura. -#[derive(Clone, PartialEq, Eq)] -#[cfg_attr(feature = "std", derive(Debug))] -pub struct AuraReport { - // The first skipped slot. - start_slot: usize, - // The number of times authorities were skipped. - skipped: usize, -} - -impl AuraReport { - /// Call the closure with (`validator_indices`, `punishment_count`) for each - /// validator to punish. - pub fn punish(&self, validator_count: usize, mut punish_with: F) - where F: FnMut(usize, usize) - { - // If all validators have been skipped, then it implies some sort of - // systematic problem common to all rather than a minority of validators - // not fulfilling their specific duties. In this case, it doesn't make - // sense to punish anyone, so we guard against it. - if self.skipped < validator_count { - for index in 0..self.skipped { - punish_with((self.start_slot + index) % validator_count, 1); - } - } - } -} - impl Module { /// Determine the Aura slot-duration based on the Timestamp module configuration. pub fn slot_duration() -> T::Moment { @@ -254,9 +248,9 @@ impl Module { ::MinimumPeriod::get().saturating_mul(2.into()) } - fn on_timestamp_set(now: T::Moment, slot_duration: T::Moment) { + fn on_timestamp_set(now: T::Moment, slot_duration: T::Moment) { let last = Self::last(); - ::LastTimestamp::put(now.clone()); + ::LastTimestamp::put(now); if last.is_zero() { return; @@ -264,43 +258,18 @@ impl Module { assert!(!slot_duration.is_zero(), "Aura slot duration cannot be zero."); - let last_slot = last / slot_duration.clone(); - let first_skipped = last_slot.clone() + One::one(); + let last_slot = last / slot_duration; let cur_slot = now / slot_duration; assert!(last_slot < cur_slot, "Only one block may be authored per slot."); - if cur_slot == first_skipped { return } - - let skipped_slots = cur_slot - last_slot - One::one(); - H::handle_report(AuraReport { - start_slot: first_skipped.saturated_into::(), - skipped: skipped_slots.saturated_into::(), - }) + // TODO [#3398] Generate offence report for all authorities that skipped their slots. } } impl OnTimestampSet for Module { fn on_timestamp_set(moment: T::Moment) { - Self::on_timestamp_set::(moment, Self::slot_duration()) - } -} - -/// A type for performing slashing based on Aura reports. -pub struct StakingSlasher(::rstd::marker::PhantomData); - -impl HandleReport for StakingSlasher { - fn handle_report(report: AuraReport) { - use staking::SessionInterface; - let validators = T::SessionInterface::validators(); - - report.punish( - validators.len(), - |idx, slash_count| { - let v = validators[idx].clone(); - staking::Module::::on_offline_validator(v, slash_count); - } - ); + Self::on_timestamp_set(moment, Self::slot_duration()) } } diff --git a/srml/aura/src/mock.rs b/srml/aura/src/mock.rs index aac3f63f974ae7031d6aadaaa632ea2092cfe852..6dc8953e8832d1b69e4a68e7e8a5887c1c743c23 100644 --- a/srml/aura/src/mock.rs +++ b/srml/aura/src/mock.rs @@ -24,7 +24,7 @@ use sr_primitives::{ traits::IdentityLookup, Perbill, testing::{Header, UintAuthorityId}, }; -use srml_support::{impl_outer_origin, parameter_types}; +use support::{impl_outer_origin, parameter_types}; use runtime_io; use primitives::{H256, Blake2Hasher}; @@ -60,6 +60,7 @@ impl system::Trait for Test { type MaximumBlockWeight = MaximumBlockWeight; type AvailableBlockRatio = AvailableBlockRatio; type MaximumBlockLength = MaximumBlockLength; + type Version = (); } impl timestamp::Trait for Test { @@ -69,7 +70,6 @@ impl timestamp::Trait for Test { } impl Trait for Test { - type HandleReport = (); type AuthorityId = AuthorityId; } @@ -81,5 +81,4 @@ pub fn new_test_ext(authorities: Vec) -> runtime_io::TestExternalities; pub type Aura = Module; diff --git a/srml/aura/src/tests.rs b/srml/aura/src/tests.rs index 12deeb99a8d3e52e056c679e09eb79ac15d6714a..a90eddf18f73095fd2072c715962a907f90a8050 100644 --- a/srml/aura/src/tests.rs +++ b/srml/aura/src/tests.rs @@ -18,75 +18,13 @@ #![cfg(test)] -use lazy_static::lazy_static; -use crate::mock::{System, Aura, new_test_ext}; -use sr_primitives::traits::Header; use runtime_io::with_externalities; -use parking_lot::Mutex; -use crate::{AuraReport, HandleReport}; +use crate::mock::{Aura, new_test_ext}; #[test] -fn aura_report_gets_skipped_correctly() { - let mut report = AuraReport { - start_slot: 3, - skipped: 15, - }; - - let mut validators = vec![0; 10]; - report.punish(10, |idx, count| validators[idx] += count); - assert_eq!(validators, vec![0, 0, 0, 0, 0, 0, 0, 0, 0, 0]); - - let mut validators = vec![0; 10]; - report.skipped = 5; - report.punish(10, |idx, count| validators[idx] += count); - assert_eq!(validators, vec![0, 0, 0, 1, 1, 1, 1, 1, 0, 0]); - - let mut validators = vec![0; 10]; - report.start_slot = 8; - report.punish(10, |idx, count| validators[idx] += count); - assert_eq!(validators, vec![1, 1, 1, 0, 0, 0, 0, 0, 1, 1]); - - let mut validators = vec![0; 4]; - report.start_slot = 1; - report.skipped = 3; - report.punish(4, |idx, count| validators[idx] += count); - assert_eq!(validators, vec![0, 1, 1, 1]); - - let mut validators = vec![0; 4]; - report.start_slot = 2; - report.punish(4, |idx, count| validators[idx] += count); - assert_eq!(validators, vec![1, 0, 1, 1]); -} - -#[test] -fn aura_reports_offline() { - lazy_static! { - static ref SLASH_COUNTS: Mutex> = Mutex::new(vec![0; 4]); - } - - struct HandleTestReport; - impl HandleReport for HandleTestReport { - fn handle_report(report: AuraReport) { - let mut counts = SLASH_COUNTS.lock(); - report.punish(counts.len(), |idx, count| counts[idx] += count); - } - } - +fn initial_values() { with_externalities(&mut new_test_ext(vec![0, 1, 2, 3]), || { - System::initialize(&1, &Default::default(), &Default::default(), &Default::default()); - let slot_duration = Aura::slot_duration(); - - Aura::on_timestamp_set::(5 * slot_duration, slot_duration); - let header = System::finalize(); - - // no slashing when last step was 0. - assert_eq!(SLASH_COUNTS.lock().as_slice(), &[0, 0, 0, 0]); - - System::initialize(&2, &header.hash(), &Default::default(), &Default::default()); - Aura::on_timestamp_set::(8 * slot_duration, slot_duration); - let _header = System::finalize(); - - // Steps 6 and 7 were skipped. - assert_eq!(SLASH_COUNTS.lock().as_slice(), &[0, 0, 1, 1]); + assert_eq!(Aura::last(), 0u64); + assert_eq!(Aura::authorities().len(), 4); }); } diff --git a/srml/authority-discovery/Cargo.toml b/srml/authority-discovery/Cargo.toml new file mode 100644 index 0000000000000000000000000000000000000000..3968ab52aec6638aa6b03ce7edb756e2c042c900 --- /dev/null +++ b/srml/authority-discovery/Cargo.toml @@ -0,0 +1,36 @@ +[package] +name = "srml-authority-discovery" +version = "0.1.0" +authors = ["Parity Technologies "] +edition = "2018" + +[dependencies] +app-crypto = { package = "substrate-application-crypto", path = "../../core/application-crypto", default-features = false } +codec = { package = "parity-scale-codec", version = "1.0.0", default-features = false, features = ["derive"] } +primitives = { package = "substrate-primitives", path = "../../core/primitives", default-features = false } +rstd = { package = "sr-std", path = "../../core/sr-std", default-features = false } +serde = { version = "1.0.101", optional = true } +runtime-io = { package = "sr-io", path = "../../core/sr-io", default-features = false } +session = { package = "srml-session", path = "../session", default-features = false } +sr-primitives = { path = "../../core/sr-primitives", default-features = false } +support = { package = "srml-support", path = "../support", default-features = false } +system = { package = "srml-system", path = "../system", default-features = false } + +[dev-dependencies] +babe-primitives = { package = "substrate-consensus-babe-primitives", path = "../../core/consensus/babe/primitives", default-features = false } +sr-staking-primitives = { path = "../../core/sr-staking-primitives", default-features = false } + +[features] +default = ["std"] +std = [ + "app-crypto/std", + "codec/std", + "primitives/std", + "rstd/std", + "runtime-io/std", + "serde", + "session/std", + "sr-primitives/std", + "support/std", + "system/std", +] diff --git a/srml/authority-discovery/src/lib.rs b/srml/authority-discovery/src/lib.rs new file mode 100644 index 0000000000000000000000000000000000000000..2ec9e988358cc93c6fb91fceac43e3aaa43ef95b --- /dev/null +++ b/srml/authority-discovery/src/lib.rs @@ -0,0 +1,357 @@ +// Copyright 2019 Parity Technologies (UK) Ltd. +// This file is part of Substrate. + +// Substrate 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. + +// Substrate 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 Substrate. If not, see . + +//! # Authority discovery module. +//! +//! This module is used by the `core/authority-discovery` to retrieve the +//! current set of authorities, learn its own authority id as well as sign and +//! verify messages to and from other authorities. +//! +//! ## Dependencies +//! +//! This module depends on an externally defined session key type, specified via +//! `Trait::AuthorityId` in the respective node runtime implementation. + +// Ensure we're `no_std` when compiling for Wasm. +#![cfg_attr(not(feature = "std"), no_std)] + +use app_crypto::RuntimeAppPublic; +use codec::FullCodec; +use rstd::prelude::*; +use support::{decl_module, decl_storage}; + +/// The module's config trait. +pub trait Trait: system::Trait + session::Trait { + type AuthorityId: RuntimeAppPublic + Default + FullCodec + PartialEq; +} + +decl_storage! { + trait Store for Module as AuthorityDiscovery { + /// The current set of keys that may issue a heartbeat. + Keys get(keys): Vec; + } + add_extra_genesis { + config(keys): Vec; + build(|config| Module::::initialize_keys(&config.keys)) + } +} + +decl_module! { + pub struct Module for enum Call where origin: T::Origin { + } +} + +impl Module { + /// Returns own authority identifier iff it is part of the current authority + /// set, otherwise this function returns None. The restriction might be + /// softened in the future in case a consumer needs to learn own authority + /// identifier. + fn authority_id() -> Option { + let authorities = Keys::::get(); + + let local_keys = T::AuthorityId::all(); + + authorities.into_iter().find_map(|authority| { + if local_keys.contains(&authority) { + Some(authority) + } else { + None + } + }) + } + + /// Retrieve authority identifiers of the current authority set. + pub fn authorities() -> Vec { + Keys::::get() + } + + /// Sign the given payload with the private key corresponding to the given authority id. + pub fn sign( + payload: &Vec, + ) -> Option<( + <::AuthorityId as RuntimeAppPublic>::Signature, + T::AuthorityId, + )> { + let authority_id = Module::::authority_id()?; + authority_id.sign(payload).map(|s| (s, authority_id)) + } + + /// Verify the given signature for the given payload with the given + /// authority identifier. + pub fn verify( + payload: &Vec, + signature: <::AuthorityId as RuntimeAppPublic>::Signature, + authority_id: T::AuthorityId, + ) -> bool { + authority_id.verify(payload, &signature) + } + + fn initialize_keys(keys: &[T::AuthorityId]) { + if !keys.is_empty() { + assert!(Keys::::get().is_empty(), "Keys are already initialized!"); + Keys::::put(keys); + } + } +} + +impl session::OneSessionHandler for Module { + type Key = T::AuthorityId; + + fn on_genesis_session<'a, I: 'a>(validators: I) + where + I: Iterator, + { + let keys = validators.map(|x| x.1).collect::>(); + Self::initialize_keys(&keys); + } + + fn on_new_session<'a, I: 'a>(_changed: bool, _validators: I, next_validators: I) + where + I: Iterator, + { + // Remember who the authorities are for the new session. + Keys::::put(next_validators.map(|x| x.1).collect::>()); + } + + fn on_disabled(_i: usize) { + // ignore + } +} + +#[cfg(test)] +mod tests { + use super::*; + use app_crypto::Pair; + use primitives::testing::KeyStore; + use primitives::{crypto::key_types, sr25519, traits::BareCryptoStore, H256}; + use runtime_io::{with_externalities, TestExternalities}; + use sr_primitives::testing::{Header, UintAuthorityId}; + use sr_primitives::traits::{ConvertInto, IdentityLookup, OpaqueKeys}; + use sr_primitives::Perbill; + use support::{impl_outer_origin, parameter_types}; + + type AuthorityDiscovery = Module; + type SessionIndex = u32; + + #[derive(Clone, Eq, PartialEq)] + pub struct Test; + impl Trait for Test { + type AuthorityId = babe_primitives::AuthorityId; + } + + type AuthorityId = babe_primitives::AuthorityId; + + pub struct TestOnSessionEnding; + impl session::OnSessionEnding for TestOnSessionEnding { + fn on_session_ending(_: SessionIndex, _: SessionIndex) -> Option> { + None + } + } + + parameter_types! { + pub const DisabledValidatorsThreshold: Perbill = Perbill::from_percent(33); + } + + impl session::Trait for Test { + type OnSessionEnding = TestOnSessionEnding; + type Keys = UintAuthorityId; + type ShouldEndSession = session::PeriodicSessions; + type SessionHandler = TestSessionHandler; + type Event = (); + type ValidatorId = AuthorityId; + type ValidatorIdOf = ConvertInto; + type SelectInitialValidators = (); + type DisabledValidatorsThreshold = DisabledValidatorsThreshold; + } + + impl session::historical::Trait for Test { + type FullIdentification = (); + type FullIdentificationOf = (); + } + + pub type BlockNumber = u64; + + parameter_types! { + pub const Period: BlockNumber = 1; + pub const Offset: BlockNumber = 0; + pub const UncleGenerations: u64 = 0; + pub const BlockHashCount: u64 = 250; + pub const MaximumBlockWeight: u32 = 1024; + pub const MaximumBlockLength: u32 = 2 * 1024; + pub const AvailableBlockRatio: Perbill = Perbill::one(); + } + + impl system::Trait for Test { + type Origin = Origin; + type Index = u64; + type BlockNumber = BlockNumber; + type Call = (); + type Hash = H256; + type Hashing = ::sr_primitives::traits::BlakeTwo256; + type AccountId = AuthorityId; + type Lookup = IdentityLookup; + type Header = Header; + type WeightMultiplierUpdate = (); + type Event = (); + type BlockHashCount = BlockHashCount; + type MaximumBlockWeight = MaximumBlockWeight; + type AvailableBlockRatio = AvailableBlockRatio; + type MaximumBlockLength = MaximumBlockLength; + type Version = (); + } + + impl_outer_origin! { + pub enum Origin for Test {} + } + + pub struct TestSessionHandler; + impl session::SessionHandler for TestSessionHandler { + fn on_new_session( + _changed: bool, + _validators: &[(AuthorityId, Ks)], + _queued_validators: &[(AuthorityId, Ks)], + ) { + } + + fn on_disabled(_validator_index: usize) {} + + fn on_genesis_session(_validators: &[(AuthorityId, Ks)]) {} + } + + #[test] + fn authority_id_fn_returns_intersection_of_current_authorities_and_keys_in_key_store() { + // Create keystore and generate key. + let key_store = KeyStore::new(); + key_store + .write() + .sr25519_generate_new(key_types::BABE, None) + .expect("Generates key."); + + // Retrieve key to later check if we got the right one. + let public_key = key_store + .read() + .sr25519_public_keys(key_types::BABE) + .pop() + .unwrap(); + let authority_id = AuthorityId::from(public_key); + + // Build genesis. + let mut t = system::GenesisConfig::default() + .build_storage::() + .unwrap(); + + GenesisConfig:: { + keys: vec![authority_id.clone()], + } + .assimilate_storage(&mut t) + .unwrap(); + + // Create externalities. + let mut externalities = TestExternalities::new(t); + externalities.set_keystore(key_store); + + with_externalities(&mut externalities, || { + assert_eq!( + authority_id, + AuthorityDiscovery::authority_id().expect("Retrieving public key.") + ); + }); + } + + #[test] + fn authority_id_fn_does_not_return_key_outside_current_authority_set() { + // Create keystore and generate key. + let key_store = KeyStore::new(); + key_store + .write() + .sr25519_generate_new(key_types::BABE, None) + .expect("Generates key."); + + // Build genesis. + let mut t = system::GenesisConfig::default() + .build_storage::() + .unwrap(); + + // Generate random authority set. + let keys = vec![(); 5] + .iter() + .map(|_x| sr25519::Pair::generate_with_phrase(None).0.public()) + .map(AuthorityId::from) + .collect(); + + GenesisConfig:: { keys: keys } + .assimilate_storage(&mut t) + .unwrap(); + + // Create externalities. + let mut externalities = TestExternalities::new(t); + externalities.set_keystore(key_store); + + with_externalities(&mut externalities, || { + assert_eq!(None, AuthorityDiscovery::authority_id()); + }); + } + + #[test] + fn sign_and_verify_workflow() { + // Create keystore and generate key. + let key_store = KeyStore::new(); + key_store + .write() + .sr25519_generate_new(key_types::BABE, None) + .expect("Generates key."); + + // Retrieve key to later check if we got the right one. + let public_key = key_store + .read() + .sr25519_public_keys(key_types::BABE) + .pop() + .unwrap(); + let authority_id = AuthorityId::from(public_key); + + // Build genesis. + let mut t = system::GenesisConfig::default() + .build_storage::() + .unwrap(); + + GenesisConfig:: { + keys: vec![authority_id.clone()], + } + .assimilate_storage(&mut t) + .unwrap(); + + // Create externalities. + let mut externalities = TestExternalities::new(t); + externalities.set_keystore(key_store); + + with_externalities(&mut externalities, || { + let payload = String::from("test payload").into_bytes(); + let (sig, authority_id) = AuthorityDiscovery::sign(&payload).expect("signature"); + + assert!(AuthorityDiscovery::verify( + &payload, + sig.clone(), + authority_id.clone(), + )); + + assert!(!AuthorityDiscovery::verify( + &String::from("other payload").into_bytes(), + sig, + authority_id + )) + }); + } +} diff --git a/srml/authorship/Cargo.toml b/srml/authorship/Cargo.toml index e7f7b0941b6a293693dff357de98722778c5cead..e860be2f644849ec6e01dda816011c9423ef5279 100644 --- a/srml/authorship/Cargo.toml +++ b/srml/authorship/Cargo.toml @@ -11,9 +11,10 @@ codec = { package = "parity-scale-codec", version = "1.0.0", default-features = inherents = { package = "substrate-inherents", path = "../../core/inherents", default-features = false } rstd = { package = "sr-std", path = "../../core/sr-std", default-features = false } sr-primitives = { path = "../../core/sr-primitives", default-features = false } -srml-support = { path = "../support", default-features = false } +support = { package = "srml-support", path = "../support", default-features = false } system = { package = "srml-system", path = "../system", default-features = false } -runtime_io = { package = "sr-io", path = "../../core/sr-io", default-features = false } +runtime-io ={ package = "sr-io", path = "../../core/sr-io", default-features = false } +impl-trait-for-tuples = "0.1.2" [features] default = ["std"] @@ -23,7 +24,7 @@ std = [ "inherents/std", "sr-primitives/std", "rstd/std", - "srml-support/std", + "support/std", "system/std", - "runtime_io/std", + "runtime-io/std", ] diff --git a/srml/authorship/src/lib.rs b/srml/authorship/src/lib.rs index 32dd140e82ff57fe5d63c10f583066ba78d5b9f2..490774c734e589a3945db8de65d8efcf07f2b530 100644 --- a/srml/authorship/src/lib.rs +++ b/srml/authorship/src/lib.rs @@ -22,12 +22,12 @@ use rstd::{result, prelude::*}; use rstd::collections::btree_set::BTreeSet; -use srml_support::{decl_module, decl_storage, for_each_tuple, StorageValue}; -use srml_support::traits::{FindAuthor, VerifySeal, Get}; -use srml_support::dispatch::Result as DispatchResult; +use support::{decl_module, decl_storage}; +use support::traits::{FindAuthor, VerifySeal, Get}; +use support::dispatch::Result as DispatchResult; use codec::{Encode, Decode}; use system::ensure_none; -use sr_primitives::traits::{SimpleArithmetic, Header as HeaderT, One, Zero}; +use sr_primitives::traits::{Header as HeaderT, One, Zero}; use sr_primitives::weights::SimpleDispatchInfo; use inherents::{ RuntimeString, InherentIdentifier, ProvideInherent, @@ -112,6 +112,7 @@ pub trait Trait: system::Trait { /// An event handler for the authorship module. There is a dummy implementation /// for `()`, which does nothing. +#[impl_trait_for_tuples::impl_for_tuples(30)] pub trait EventHandler { /// Note that the given account ID is the author of the current block. fn note_author(author: Author); @@ -121,30 +122,6 @@ pub trait EventHandler { fn note_uncle(author: Author, age: BlockNumber); } -macro_rules! impl_event_handler { - () => ( - impl EventHandler for () { - fn note_author(_author: A) { } - fn note_uncle(_author: A, _age: B) { } - } - ); - - ( $($t:ident)* ) => { - impl),*> - EventHandler for ($($t,)*) - { - fn note_author(author: Author) { - $($t::note_author(author.clone());)* - } - fn note_uncle(author: Author, age: BlockNumber) { - $($t::note_uncle(author.clone(), age.clone());)* - } - } - } -} - -for_each_tuple!(impl_event_handler); - /// Additional filtering on uncles that pass preliminary ancestry checks. /// /// This should do work such as checking seals @@ -236,29 +213,14 @@ decl_storage! { } } -fn prune_old_uncles( - minimum_height: BlockNumber, - uncles: &mut Vec> -) where BlockNumber: SimpleArithmetic { - let prune_entries = uncles.iter().take_while(|item| match item { - UncleEntryItem::Uncle(_, _) => true, - UncleEntryItem::InclusionHeight(height) => height < &minimum_height, - }); - let prune_index = prune_entries.count(); - - let _ = uncles.drain(..prune_index); -} - decl_module! { pub struct Module for enum Call where origin: T::Origin { fn on_initialize(now: T::BlockNumber) { let uncle_generations = T::UncleGenerations::get(); - let mut uncles = ::Uncles::get(); - // prune uncles that are older than the allowed number of generations. if uncle_generations <= now { let minimum_height = now - uncle_generations; - prune_old_uncles(minimum_height, &mut uncles) + Self::prune_old_uncles(minimum_height) } ::DidSetUncles::put(false); @@ -387,6 +349,18 @@ impl Module { // check uncle validity. T::FilterUncle::filter_uncle(&uncle, accumulator) } + + fn prune_old_uncles(minimum_height: T::BlockNumber) { + let mut uncles = ::Uncles::get(); + let prune_entries = uncles.iter().take_while(|item| match item { + UncleEntryItem::Uncle(_, _) => true, + UncleEntryItem::InclusionHeight(height) => height < &minimum_height, + }); + let prune_index = prune_entries.count(); + + let _ = uncles.drain(..prune_index); + ::Uncles::put(uncles); + } } impl ProvideInherent for Module { @@ -444,7 +418,7 @@ mod tests { use sr_primitives::testing::Header; use sr_primitives::generic::DigestItem; use sr_primitives::Perbill; - use srml_support::{parameter_types, impl_outer_origin, ConsensusEngineId}; + use support::{parameter_types, impl_outer_origin, ConsensusEngineId}; impl_outer_origin!{ pub enum Origin for Test {} @@ -476,6 +450,7 @@ mod tests { type MaximumBlockWeight = MaximumBlockWeight; type AvailableBlockRatio = AvailableBlockRatio; type MaximumBlockLength = MaximumBlockLength; + type Version = (); } parameter_types! { @@ -568,15 +543,21 @@ mod tests { #[test] fn prune_old_uncles_works() { use UncleEntryItem::*; - let mut uncles = vec![ - InclusionHeight(1u32), Uncle((), Some(())), Uncle((), None), Uncle((), None), - InclusionHeight(2u32), Uncle((), None), - InclusionHeight(3u32), Uncle((), None), - ]; - - prune_old_uncles(3, &mut uncles); - - assert_eq!(uncles, vec![InclusionHeight(3), Uncle((), None)]); + with_externalities(&mut new_test_ext(), || { + let hash = Default::default(); + let author = Default::default(); + let uncles = vec![ + InclusionHeight(1u64), Uncle(hash, Some(author)), Uncle(hash, None), Uncle(hash, None), + InclusionHeight(2u64), Uncle(hash, None), + InclusionHeight(3u64), Uncle(hash, None), + ]; + + ::Uncles::put(uncles); + Authorship::prune_old_uncles(3); + + let uncles = ::Uncles::get(); + assert_eq!(uncles, vec![InclusionHeight(3u64), Uncle(hash, None)]); + }) } #[test] diff --git a/srml/babe/Cargo.toml b/srml/babe/Cargo.toml index 76bd849a95594d79b3e9920a3caf8aae40421bc5..dc82906650bef2db9a405e0fd753ad16620b8bb6 100644 --- a/srml/babe/Cargo.toml +++ b/srml/babe/Cargo.toml @@ -5,24 +5,26 @@ authors = ["Parity Technologies "] edition = "2018" [dependencies] -hex-literal = "0.2" +hex-literal = "0.2.1" codec = { package = "parity-scale-codec", version = "1.0.0", default-features = false, features = ["derive"] } -serde = { version = "1.0.93", optional = true } +serde = { version = "1.0.101", optional = true } inherents = { package = "substrate-inherents", path = "../../core/inherents", default-features = false } rstd = { package = "sr-std", path = "../../core/sr-std", default-features = false } sr-primitives = { path = "../../core/sr-primitives", default-features = false } -staking = { package = "srml-staking", path = "../staking", default-features = false } -srml-support = { path = "../support", default-features = false } +sr-staking-primitives = { path = "../../core/sr-staking-primitives", default-features = false } +support = { package = "srml-support", path = "../support", default-features = false } system = { package = "srml-system", path = "../system", default-features = false } timestamp = { package = "srml-timestamp", path = "../timestamp", default-features = false } session = { package = "srml-session", path = "../session", default-features = false } babe-primitives = { package = "substrate-consensus-babe-primitives", path = "../../core/consensus/babe/primitives", default-features = false } -runtime_io = { package = "sr-io", path = "../../core/sr-io", default-features = false, features = [ "wasm-nice-panic-message" ] } +runtime-io ={ package = "sr-io", path = "../../core/sr-io", default-features = false } [dev-dependencies] -lazy_static = "1.3.0" +lazy_static = "1.4.0" parking_lot = "0.9.0" +sr-version = { path = "../../core/sr-version", default-features = false } primitives = { package = "substrate-primitives", path = "../../core/primitives" } +test-runtime = { package = "substrate-test-runtime", path = "../../core/test-runtime" } [features] default = ["std"] @@ -30,13 +32,13 @@ std = [ "serde", "codec/std", "rstd/std", - "srml-support/std", + "support/std", "sr-primitives/std", + "sr-staking-primitives/std", "system/std", "timestamp/std", "inherents/std", "babe-primitives/std", "session/std", - "runtime_io/std", - "staking/std", + "runtime-io/std", ] diff --git a/srml/babe/src/lib.rs b/srml/babe/src/lib.rs index 02099aace84e4c16047631d466019734e9326cd1..e69877d783b3d1a67b7e68e55d7187ba50aa3e45 100644 --- a/srml/babe/src/lib.rs +++ b/srml/babe/src/lib.rs @@ -14,27 +14,41 @@ // You should have received a copy of the GNU General Public License // along with Substrate. If not, see . -//! Consensus extension module for BABE consensus. +//! Consensus extension module for BABE consensus. Collects on-chain randomness +//! from VRF outputs and manages epoch transitions. #![cfg_attr(not(feature = "std"), no_std)] -#![forbid(unused_must_use, unsafe_code, unused_variables, dead_code)] - +#![forbid(unused_must_use, unsafe_code, unused_variables, unused_must_use)] +#![deny(unused_imports)] pub use timestamp; use rstd::{result, prelude::*}; -use srml_support::{decl_storage, decl_module, StorageValue, StorageMap, traits::FindAuthor, traits::Get}; -use timestamp::{OnTimestampSet}; -use sr_primitives::{generic::DigestItem, ConsensusEngineId}; -use sr_primitives::traits::{IsMember, SaturatedConversion, Saturating, RandomnessBeacon, Convert}; +use support::{decl_storage, decl_module, traits::FindAuthor, traits::Get}; +use timestamp::OnTimestampSet; +use sr_primitives::{generic::DigestItem, ConsensusEngineId, Perbill}; +use sr_primitives::traits::{IsMember, SaturatedConversion, Saturating, RandomnessBeacon}; +use sr_staking_primitives::{ + SessionIndex, + offence::{Offence, Kind}, +}; #[cfg(feature = "std")] use timestamp::TimestampInherentData; use codec::{Encode, Decode}; use inherents::{RuntimeString, InherentIdentifier, InherentData, ProvideInherent, MakeFatalError}; #[cfg(feature = "std")] use inherents::{InherentDataProviders, ProvideInherentData}; -use babe_primitives::{BABE_ENGINE_ID, ConsensusLog, BabeWeight, Epoch, RawBabePreDigest}; +use babe_primitives::{ + BABE_ENGINE_ID, ConsensusLog, BabeAuthorityWeight, NextEpochDescriptor, RawBabePreDigest, + SlotNumber, +}; pub use babe_primitives::{AuthorityId, VRF_OUTPUT_LENGTH, PUBLIC_KEY_LENGTH}; +#[cfg(all(feature = "std", test))] +mod tests; + +#[cfg(all(feature = "std", test))] +mod mock; + /// The BABE inherent identifier. pub const INHERENT_IDENTIFIER: InherentIdentifier = *b"babeslot"; @@ -108,8 +122,52 @@ impl ProvideInherentData for InherentDataProvider { } pub trait Trait: timestamp::Trait { - type EpochDuration: Get; + /// The amount of time, in slots, that each epoch should last. + type EpochDuration: Get; + + /// The expected average block time at which BABE should be creating + /// blocks. Since BABE is probabilistic it is not trivial to figure out + /// what the expected average block time should be based on the slot + /// duration and the security parameter `c` (where `1 - c` represents + /// the probability of a slot being empty). type ExpectedBlockTime: Get; + + /// BABE requires some logic to be triggered on every block to query for whether an epoch + /// has ended and to perform the transition to the next epoch. + /// + /// Typically, the `ExternalTrigger` type should be used. An internal trigger should only be used + /// when no other module is responsible for changing authority set. + type EpochChangeTrigger: EpochChangeTrigger; +} + +/// Trigger an epoch change, if any should take place. +pub trait EpochChangeTrigger { + /// Trigger an epoch change, if any should take place. This should be called + /// during every block, after initialization is done. + fn trigger(now: T::BlockNumber); +} + +/// A type signifying to BABE that an external trigger +/// for epoch changes (e.g. srml-session) is used. +pub struct ExternalTrigger; + +impl EpochChangeTrigger for ExternalTrigger { + fn trigger(_: T::BlockNumber) { } // nothing - trigger is external. +} + +/// A type signifying to BABE that it should perform epoch changes +/// with an internal trigger, recycling the same authorities forever. +pub struct SameAuthoritiesForever; + +impl EpochChangeTrigger for SameAuthoritiesForever { + fn trigger(now: T::BlockNumber) { + if >::should_epoch_change(now) { + let authorities = >::authorities(); + let next_authorities = authorities.clone(); + + >::enact_epoch_change(authorities, next_authorities); + } + } } /// The length of the BABE randomness @@ -117,18 +175,19 @@ pub const RANDOMNESS_LENGTH: usize = 32; const UNDER_CONSTRUCTION_SEGMENT_LENGTH: usize = 256; +type MaybeVrf = Option<[u8; 32 /* VRF_OUTPUT_LENGTH */]>; + decl_storage! { trait Store for Module as Babe { /// Current epoch index. pub EpochIndex get(epoch_index): u64; /// Current epoch authorities. - pub Authorities get(authorities) config(): Vec<(AuthorityId, BabeWeight)>; + pub Authorities get(authorities): Vec<(AuthorityId, BabeAuthorityWeight)>; - /// Slot at which the current epoch started. It is possible that no - /// block was authored at the given slot and the epoch change was - /// signalled later than this. - pub EpochStartSlot get(epoch_start_slot): u64; + /// The slot at which the first epoch actually started. This is 0 + /// until the first block of the chain. + pub GenesisSlot get(genesis_slot): u64; /// Current slot number. pub CurrentSlot get(current_slot): u64; @@ -162,6 +221,14 @@ decl_storage! { /// epoch. SegmentIndex build(|_| 0): u32; UnderConstruction: map u32 => Vec<[u8; 32 /* VRF_OUTPUT_LENGTH */]>; + + /// Temporary value (cleared at block finalization) which is `Some` + /// if per-block initialization has already been called for current block. + Initialized get(initialized): Option; + } + add_extra_genesis { + config(authorities): Vec<(AuthorityId, BabeAuthorityWeight)>; + build(|config| Module::::initialize_authorities(&config.authorities)) } } @@ -180,25 +247,19 @@ decl_module! { const ExpectedBlockTime: T::Moment = T::ExpectedBlockTime::get(); /// Initialization - fn on_initialize() { - for digest in Self::get_inherent_digests() - .logs - .iter() - .filter_map(|s| s.as_pre_runtime()) - .filter_map(|(id, mut data)| if id == BABE_ENGINE_ID { - RawBabePreDigest::decode(&mut data).ok() - } else { - None - }) - { - if EpochStartSlot::get() == 0 { - EpochStartSlot::put(digest.slot_number); - } - - CurrentSlot::put(digest.slot_number); - Self::deposit_vrf_output(&digest.vrf_output); - - return; + fn on_initialize(now: T::BlockNumber) { + Self::do_initialize(now); + } + + /// Block finalization + fn on_finalize() { + // at the end of the block, we can safely include the new VRF output + // from this block into the under-construction randomness. If we've determined + // that this block was the first in a new epoch, the changeover logic has + // already occurred at this point, so the under-construction randomness + // will only contain outputs from the right epoch. + if let Some(Some(vrf_output)) = Initialized::take() { + Self::deposit_vrf_output(&vrf_output); } } } @@ -219,9 +280,16 @@ impl FindAuthor for Module { { for (id, mut data) in digests.into_iter() { if id == BABE_ENGINE_ID { - return Some(RawBabePreDigest::decode(&mut data).ok()?.authority_index); + let pre_digest = RawBabePreDigest::decode(&mut data).ok()?; + return Some(match pre_digest { + RawBabePreDigest::Primary { authority_index, .. } => + authority_index, + RawBabePreDigest::Secondary { authority_index, .. } => + authority_index, + }); } } + return None; } } @@ -235,9 +303,61 @@ impl IsMember for Module { } impl session::ShouldEndSession for Module { - fn should_end_session(_: T::BlockNumber) -> bool { - let diff = CurrentSlot::get().saturating_sub(EpochStartSlot::get()); - diff >= T::EpochDuration::get() + fn should_end_session(now: T::BlockNumber) -> bool { + // it might be (and it is in current implementation) that session module is calling + // should_end_session() from it's own on_initialize() handler + // => because session on_initialize() is called earlier than ours, let's ensure + // that we have synced with digest before checking if session should be ended. + Self::do_initialize(now); + + Self::should_epoch_change(now) + } +} + +// TODO [slashing]: @marcio use this, remove the dead_code annotation. +/// A BABE equivocation offence report. +/// +/// When a validator released two or more blocks at the same slot. +#[allow(dead_code)] +struct BabeEquivocationOffence { + /// A babe slot number in which this incident happened. + slot: u64, + /// The session index in which the incident happened. + session_index: SessionIndex, + /// The size of the validator set at the time of the offence. + validator_set_count: u32, + /// The authority that produced the equivocation. + offender: FullIdentification, +} + +impl Offence for BabeEquivocationOffence { + const ID: Kind = *b"babe:equivocatio"; + type TimeSlot = u64; + + fn offenders(&self) -> Vec { + vec![self.offender.clone()] + } + + fn session_index(&self) -> SessionIndex { + self.session_index + } + + fn validator_set_count(&self) -> u32 { + self.validator_set_count + } + + fn time_slot(&self) -> Self::TimeSlot { + self.slot + } + + fn slash_fraction( + offenders_count: u32, + validator_set_count: u32, + ) -> Perbill { + // the formula is min((3k / n)^2, 1) + let x = Perbill::from_rational_approximation(3 * offenders_count, validator_set_count); + // _ ^ 2 + x.square() } } @@ -249,15 +369,81 @@ impl Module { ::MinimumPeriod::get().saturating_mul(2.into()) } + /// Determine whether an epoch change should take place at this block. + /// Assumes that initialization has already taken place. + pub fn should_epoch_change(now: T::BlockNumber) -> bool { + // The epoch has technically ended during the passage of time + // between this block and the last, but we have to "end" the epoch now, + // since there is no earlier possible block we could have done it. + // + // The exception is for block 1: the genesis has slot 0, so we treat + // epoch 0 as having started at the slot of block 1. We want to use + // the same randomness and validator set as signalled in the genesis, + // so we don't rotate the epoch. + now != sr_primitives::traits::One::one() && { + let diff = CurrentSlot::get().saturating_sub(Self::current_epoch_start()); + diff >= T::EpochDuration::get() + } + } + + /// DANGEROUS: Enact an epoch change. Should be done on every block where `should_epoch_change` has returned `true`, + /// and the caller is the only caller of this function. + /// + /// Typically, this is not handled directly by the user, but by higher-level validator-set manager logic like + /// `srml-session`. + pub fn enact_epoch_change( + authorities: Vec<(AuthorityId, BabeAuthorityWeight)>, + next_authorities: Vec<(AuthorityId, BabeAuthorityWeight)>, + ) { + // PRECONDITION: caller has done initialization and is guaranteed + // by the session module to be called before this. + #[cfg(debug_assertions)] + { + assert!(Self::initialized().is_some()) + } + + // Update epoch index + let epoch_index = EpochIndex::get() + .checked_add(1) + .expect("epoch indices will never reach 2^64 before the death of the universe; qed"); + + EpochIndex::put(epoch_index); + Authorities::put(authorities); + + // Update epoch randomness. + let next_epoch_index = epoch_index + .checked_add(1) + .expect("epoch indices will never reach 2^64 before the death of the universe; qed"); + + // Returns randomness for the current epoch and computes the *next* + // epoch randomness. + let randomness = Self::randomness_change_epoch(next_epoch_index); + Randomness::put(randomness); + + // After we update the current epoch, we signal the *next* epoch change + // so that nodes can track changes. + let next_randomness = NextRandomness::get(); + + let next = NextEpochDescriptor { + authorities: next_authorities, + randomness: next_randomness, + }; + + Self::deposit_consensus(ConsensusLog::NextEpochData(next)) + } + + // finds the start slot of the current epoch. only guaranteed to + // give correct results after `do_initialize` of the first block + // in the chain (as its result is based off of `GenesisSlot`). + fn current_epoch_start() -> SlotNumber { + (EpochIndex::get() * T::EpochDuration::get()) + GenesisSlot::get() + } + fn deposit_consensus(new: U) { let log: DigestItem = DigestItem::Consensus(BABE_ENGINE_ID, new.encode()); >::deposit_log(log.into()) } - fn get_inherent_digests() -> system::DigestOf { - >::digest() - } - fn deposit_vrf_output(vrf_output: &[u8; VRF_OUTPUT_LENGTH]) { let segment_idx = ::get(); let mut segment = ::get(&segment_idx); @@ -268,11 +454,67 @@ impl Module { } else { // move onto the next segment and update the index. let segment_idx = segment_idx + 1; - ::insert(&segment_idx, vec![*vrf_output].as_ref()); + ::insert(&segment_idx, &vec![*vrf_output]); ::put(&segment_idx); } } + fn do_initialize(now: T::BlockNumber) { + // since do_initialize can be called twice (if session module is present) + // => let's ensure that we only modify the storage once per block + let initialized = Self::initialized().is_some(); + if initialized { + return; + } + + let maybe_pre_digest = >::digest() + .logs + .iter() + .filter_map(|s| s.as_pre_runtime()) + .filter_map(|(id, mut data)| if id == BABE_ENGINE_ID { + RawBabePreDigest::decode(&mut data).ok() + } else { + None + }) + .next(); + + let maybe_vrf = maybe_pre_digest.and_then(|digest| { + // on the first non-zero block (i.e. block #1) + // this is where the first epoch (epoch #0) actually starts. + // we need to adjust internal storage accordingly. + if GenesisSlot::get() == 0 { + GenesisSlot::put(digest.slot_number()); + debug_assert_ne!(GenesisSlot::get(), 0); + + // deposit a log because this is the first block in epoch #0 + // we use the same values as genesis because we haven't collected any + // randomness yet. + let next = NextEpochDescriptor { + authorities: Self::authorities(), + randomness: Self::randomness(), + }; + + Self::deposit_consensus(ConsensusLog::NextEpochData(next)) + } + + CurrentSlot::put(digest.slot_number()); + + if let RawBabePreDigest::Primary { vrf_output, .. } = digest { + // place the VRF output into the `Initialized` storage item + // and it'll be put onto the under-construction randomness + // later, once we've decided which epoch this block is in. + Some(vrf_output) + } else { + None + } + }); + + Initialized::put(maybe_vrf); + + // enact epoch change, if necessary. + T::EpochChangeTrigger::trigger::(now) + } + /// Call this function exactly once when an epoch changes, to update the /// randomness. Returns the new randomness. fn randomness_change_epoch(next_epoch_index: u64) -> [u8; RANDOMNESS_LENGTH] { @@ -292,79 +534,40 @@ impl Module { this_randomness } + fn initialize_authorities(authorities: &[(AuthorityId, BabeAuthorityWeight)]) { + if !authorities.is_empty() { + assert!(Authorities::get().is_empty(), "Authorities are already initialized!"); + Authorities::put(authorities); + } + } } impl OnTimestampSet for Module { fn on_timestamp_set(_moment: T::Moment) { } } -impl session::OneSessionHandler for Module { +impl session::OneSessionHandler for Module { type Key = AuthorityId; - fn on_new_session<'a, I: 'a>(_changed: bool, validators: I, queued_validators: I) + + fn on_genesis_session<'a, I: 'a>(validators: I) where I: Iterator { - use staking::BalanceOf; - let to_votes = |b: BalanceOf| { - , u64>>::convert(b) - }; - - // Update epoch index - let epoch_index = EpochIndex::get() - .checked_add(1) - .expect("epoch indices will never reach 2^64 before the death of the universe; qed"); - - EpochIndex::put(epoch_index); + let authorities = validators.map(|(_, k)| (k, 1)).collect::>(); + Self::initialize_authorities(&authorities); + } - // Update authorities. - let authorities = validators.map(|(account, k)| { - (k, to_votes(staking::Module::::stakers(account).total)) + fn on_new_session<'a, I: 'a>(_changed: bool, validators: I, queued_validators: I) + where I: Iterator + { + let authorities = validators.map(|(_account, k)| { + (k, 1) }).collect::>(); - Authorities::put(authorities); - - // Update epoch start slot. - let now = CurrentSlot::get(); - EpochStartSlot::mutate(|previous| { - loop { - // on the first epoch we must account for skipping at least one - // whole epoch, in case the first block is authored with a slot - // number far in the past. - if now.saturating_sub(*previous) < T::EpochDuration::get() { - break; - } - - *previous = previous.saturating_add(T::EpochDuration::get()); - } - }); - - // Update epoch randomness. - let next_epoch_index = epoch_index - .checked_add(1) - .expect("epoch indices will never reach 2^64 before the death of the universe; qed"); - - // Returns randomness for the current epoch and computes the *next* - // epoch randomness. - let randomness = Self::randomness_change_epoch(next_epoch_index); - Randomness::put(randomness); - - // After we update the current epoch, we signal the *next* epoch change - // so that nodes can track changes. - let next_authorities = queued_validators.map(|(account, k)| { - (k, to_votes(staking::Module::::stakers(account).total)) + let next_authorities = queued_validators.map(|(_account, k)| { + (k, 1) }).collect::>(); - let next_epoch_start_slot = EpochStartSlot::get().saturating_add(T::EpochDuration::get()); - let next_randomness = NextRandomness::get(); - - let next = Epoch { - epoch_index: next_epoch_index, - start_slot: next_epoch_start_slot, - duration: T::EpochDuration::get(), - authorities: next_authorities, - randomness: next_randomness, - }; - - Self::deposit_consensus(ConsensusLog::NextEpochData(next)) + Self::enact_epoch_change(authorities, next_authorities) } fn on_disabled(i: usize) { diff --git a/srml/babe/src/mock.rs b/srml/babe/src/mock.rs new file mode 100644 index 0000000000000000000000000000000000000000..acc08c7a3bef28775885f456d4b6f0cf1d8f1b0f --- /dev/null +++ b/srml/babe/src/mock.rs @@ -0,0 +1,113 @@ +// Copyright 2019 Parity Technologies (UK) Ltd. +// This file is part of Substrate. + +// Substrate 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. + +// Substrate 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 Substrate. If not, see . + +//! Test utilities +#![allow(dead_code, unused_imports)] + +use super::{Trait, Module, GenesisConfig}; +use babe_primitives::AuthorityId; +use sr_primitives::{ + traits::IdentityLookup, Perbill, + testing::{Header, UintAuthorityId}, + impl_opaque_keys, key_types::DUMMY, +}; +use sr_version::RuntimeVersion; +use support::{impl_outer_origin, parameter_types}; +use runtime_io; +use primitives::{H256, Blake2Hasher}; + +impl_outer_origin!{ + pub enum Origin for Test {} +} + +type DummyValidatorId = u64; + +// Workaround for https://github.com/rust-lang/rust/issues/26925 . Remove when sorted. +#[derive(Clone, PartialEq, Eq, Debug)] +pub struct Test; + +parameter_types! { + pub const BlockHashCount: u64 = 250; + pub const MaximumBlockWeight: u32 = 1024; + pub const MaximumBlockLength: u32 = 2 * 1024; + pub const AvailableBlockRatio: Perbill = Perbill::one(); + pub const MinimumPeriod: u64 = 1; + pub const EpochDuration: u64 = 3; + pub const ExpectedBlockTime: u64 = 1; + pub const Version: RuntimeVersion = test_runtime::VERSION; + pub const DisabledValidatorsThreshold: Perbill = Perbill::from_percent(16); +} + +impl system::Trait for Test { + type Origin = Origin; + type Index = u64; + type BlockNumber = u64; + type Call = (); + type Hash = H256; + type Version = Version; + type Hashing = sr_primitives::traits::BlakeTwo256; + type AccountId = DummyValidatorId; + type Lookup = IdentityLookup; + type Header = Header; + type WeightMultiplierUpdate = (); + type Event = (); + type BlockHashCount = BlockHashCount; + type MaximumBlockWeight = MaximumBlockWeight; + type AvailableBlockRatio = AvailableBlockRatio; + type MaximumBlockLength = MaximumBlockLength; +} + +impl_opaque_keys! { + pub struct MockSessionKeys { + #[id(DUMMY)] + pub dummy: UintAuthorityId, + } +} + +impl session::Trait for Test { + type Event = (); + type ValidatorId = ::AccountId; + type ShouldEndSession = Babe; + type SessionHandler = (Babe,Babe,); + type OnSessionEnding = (); + type ValidatorIdOf = (); + type SelectInitialValidators = (); + type Keys = MockSessionKeys; + type DisabledValidatorsThreshold = DisabledValidatorsThreshold; +} + +impl timestamp::Trait for Test { + type Moment = u64; + type OnTimestampSet = Babe; + type MinimumPeriod = MinimumPeriod; +} + +impl Trait for Test { + type EpochDuration = EpochDuration; + type ExpectedBlockTime = ExpectedBlockTime; + type EpochChangeTrigger = crate::ExternalTrigger; +} + +pub fn new_test_ext(authorities: Vec) -> runtime_io::TestExternalities { + let mut t = system::GenesisConfig::default().build_storage::().unwrap(); + GenesisConfig { + authorities: authorities.into_iter().map(|a| (UintAuthorityId(a).to_public_key(), 1)).collect(), + }.assimilate_storage::(&mut t).unwrap(); + t.into() +} + +pub type System = system::Module; +pub type Babe = Module; diff --git a/srml/babe/src/tests.rs b/srml/babe/src/tests.rs new file mode 100644 index 0000000000000000000000000000000000000000..ef449485b77ed530abad06ac519beef4c0a90f78 --- /dev/null +++ b/srml/babe/src/tests.rs @@ -0,0 +1,127 @@ +// Copyright 2019 Parity Technologies (UK) Ltd. +// This file is part of Substrate. + +// Substrate 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. + +// Substrate 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 Substrate. If not, see . + +//! Consensus extension module tests for BABE consensus. + +use super::*; +use runtime_io::with_externalities; +use mock::{new_test_ext, Babe, Test}; +use sr_primitives::{traits::OnFinalize, testing::{Digest, DigestItem}}; +use session::ShouldEndSession; + +const EMPTY_RANDOMNESS: [u8; 32] = [ + 74, 25, 49, 128, 53, 97, 244, 49, + 222, 202, 176, 2, 231, 66, 95, 10, + 133, 49, 213, 228, 86, 161, 164, 127, + 217, 153, 138, 37, 48, 192, 248, 0, +]; + +fn make_pre_digest( + authority_index: babe_primitives::AuthorityIndex, + slot_number: babe_primitives::SlotNumber, + vrf_output: [u8; babe_primitives::VRF_OUTPUT_LENGTH], + vrf_proof: [u8; babe_primitives::VRF_PROOF_LENGTH], +) -> Digest { + let digest_data = babe_primitives::RawBabePreDigest::Primary { + authority_index, + slot_number, + vrf_output, + vrf_proof, + }; + let log = DigestItem::PreRuntime(babe_primitives::BABE_ENGINE_ID, digest_data.encode()); + Digest { logs: vec![log] } +} + +#[test] +fn empty_randomness_is_correct() { + let s = compute_randomness([0; RANDOMNESS_LENGTH], 0, std::iter::empty(), None); + assert_eq!(s, EMPTY_RANDOMNESS); +} + +#[test] +fn initial_values() { + with_externalities(&mut new_test_ext(vec![0, 1, 2, 3]), || { + assert_eq!(Babe::authorities().len(), 4) + }) +} + +#[test] +fn check_module() { + with_externalities(&mut new_test_ext(vec![0, 1, 2, 3]), || { + assert!(!Babe::should_end_session(0), "Genesis does not change sessions"); + assert!(!Babe::should_end_session(200000), + "BABE does not include the block number in epoch calculations"); + }) +} + +type System = system::Module; + +#[test] +fn first_block_epoch_zero_start() { + with_externalities(&mut new_test_ext(vec![0, 1, 2, 3]), || { + let genesis_slot = 100; + let first_vrf = [1; 32]; + let pre_digest = make_pre_digest( + 0, + genesis_slot, + first_vrf, + [0xff; 64], + ); + + assert_eq!(Babe::genesis_slot(), 0); + System::initialize(&1, &Default::default(), &Default::default(), &pre_digest); + + // see implementation of the function for details why: we issue an + // epoch-change digest but don't do it via the normal session mechanism. + assert!(!Babe::should_end_session(1)); + assert_eq!(Babe::genesis_slot(), genesis_slot); + assert_eq!(Babe::current_slot(), genesis_slot); + assert_eq!(Babe::epoch_index(), 0); + + Babe::on_finalize(1); + let header = System::finalize(); + + assert_eq!(SegmentIndex::get(), 0); + assert_eq!(UnderConstruction::get(0), vec![first_vrf]); + assert_eq!(Babe::randomness(), [0; 32]); + assert_eq!(NextRandomness::get(), [0; 32]); + + assert_eq!(header.digest.logs.len(), 2); + assert_eq!(pre_digest.logs.len(), 1); + assert_eq!(header.digest.logs[0], pre_digest.logs[0]); + + let authorities = Babe::authorities(); + let consensus_log = babe_primitives::ConsensusLog::NextEpochData( + babe_primitives::NextEpochDescriptor { + authorities, + randomness: Babe::randomness(), + } + ); + let consensus_digest = DigestItem::Consensus(BABE_ENGINE_ID, consensus_log.encode()); + + // first epoch descriptor has same info as last. + assert_eq!(header.digest.logs[1], consensus_digest.clone()) + }) +} + +#[test] +fn authority_index() { + with_externalities(&mut new_test_ext(vec![0, 1, 2, 3]), || { + assert_eq!( + Babe::find_author((&[(BABE_ENGINE_ID, &[][..])]).into_iter().cloned()), None, + "Trivially invalid authorities are ignored") + }) +} diff --git a/srml/balances/Cargo.toml b/srml/balances/Cargo.toml index d3ac0c96b37efce873e3f13c1500f49d8ef853ce..d2b6e00d98e8b5e01c9701bb9229744001e8e2fa 100644 --- a/srml/balances/Cargo.toml +++ b/srml/balances/Cargo.toml @@ -5,17 +5,17 @@ authors = ["Parity Technologies "] edition = "2018" [dependencies] -serde = { version = "1.0", optional = true } -safe-mix = { version = "1.0", default-features = false} +serde = { version = "1.0.101", optional = true } +safe-mix = { version = "1.0.0", default-features = false } codec = { package = "parity-scale-codec", version = "1.0.0", default-features = false, features = ["derive"] } substrate-keyring = { path = "../../core/keyring", optional = true } rstd = { package = "sr-std", path = "../../core/sr-std", default-features = false } sr-primitives = { path = "../../core/sr-primitives", default-features = false } -srml-support = { path = "../support", default-features = false } +support = { package = "srml-support", path = "../support", default-features = false } system = { package = "srml-system", path = "../system", default-features = false } [dev-dependencies] -runtime_io = { package = "sr-io", path = "../../core/sr-io", default-features = false } +runtime-io = { package = "sr-io", path = "../../core/sr-io" } primitives = { package = "substrate-primitives", path = "../../core/primitives" } [features] @@ -26,7 +26,7 @@ std = [ "substrate-keyring", "codec/std", "rstd/std", - "srml-support/std", + "support/std", "sr-primitives/std", "system/std", ] diff --git a/srml/balances/src/lib.rs b/srml/balances/src/lib.rs index 66d0ee028495f411c7dee374012ec0b3455a0489..03e32e1ddf295d11e01a2c79dce854045439809a 100644 --- a/srml/balances/src/lib.rs +++ b/srml/balances/src/lib.rs @@ -72,8 +72,6 @@ //! - [`Imbalance`](../srml_support/traits/trait.Imbalance.html): Functions for handling //! imbalances between total issuance in the system and account balances. Must be used when a function //! creates new funds (e.g. a reward) or destroys some funds (e.g. a system fee). -//! - [`MakePayment`](../srml_support/traits/trait.MakePayment.html): Simple trait designed -//! for hooking into a transaction payment. //! - [`IsDeadAccount`](../srml_system/trait.IsDeadAccount.html): Determiner to say whether a //! given account is unused. //! @@ -88,6 +86,17 @@ //! //! - `vesting_balance` - Get the amount that is currently being vested and cannot be transferred out of this account. //! +//! ### Signed Extensions +//! +//! The balances module defines the following extensions: +//! +//! - [`TakeFees`]: Consumes fees proportional to the length and weight of the transaction. +//! Additionally, it can contain a single encoded payload as a `tip`. The inclusion priority +//! is increased proportional to the tip. +//! +//! Lookup the runtime aggregator file (e.g. `node/runtime`) to see the full list of signed +//! extensions included in a chain. +//! //! ## Usage //! //! The following examples show how to use the Balances module in your custom module. @@ -97,7 +106,7 @@ //! The Contract module uses the `Currency` trait to handle gas payment, and its types inherit from `Currency`: //! //! ``` -//! use srml_support::traits::Currency; +//! use support::traits::Currency; //! # pub trait Trait: system::Trait { //! # type Currency: Currency; //! # } @@ -111,14 +120,14 @@ //! The Staking module uses the `LockableCurrency` trait to lock a stash account's funds: //! //! ``` -//! use srml_support::traits::{WithdrawReasons, LockableCurrency}; +//! use support::traits::{WithdrawReasons, LockableCurrency}; //! use sr_primitives::traits::Bounded; //! pub trait Trait: system::Trait { //! type Currency: LockableCurrency; //! } //! # struct StakingLedger { //! # stash: ::AccountId, -//! # total: <::Currency as srml_support::traits::Currency<::AccountId>>::Balance, +//! # total: <::Currency as support::traits::Currency<::AccountId>>::Balance, //! # phantom: std::marker::PhantomData, //! # } //! # const STAKING_ID: [u8; 8] = *b"staking "; @@ -152,19 +161,26 @@ use rstd::prelude::*; use rstd::{cmp, result, mem}; use codec::{Codec, Encode, Decode}; -use srml_support::{StorageValue, StorageMap, Parameter, decl_event, decl_storage, decl_module}; -use srml_support::traits::{ - UpdateBalanceOutcome, Currency, OnFreeBalanceZero, OnUnbalanced, - WithdrawReason, WithdrawReasons, LockIdentifier, LockableCurrency, ExistenceRequirement, - Imbalance, SignedImbalance, ReservableCurrency, Get, +use support::{ + StorageValue, Parameter, decl_event, decl_storage, decl_module, + traits::{ + UpdateBalanceOutcome, Currency, OnFreeBalanceZero, OnUnbalanced, + WithdrawReason, WithdrawReasons, LockIdentifier, LockableCurrency, ExistenceRequirement, + Imbalance, SignedImbalance, ReservableCurrency, Get, + }, + dispatch::Result, }; -use srml_support::dispatch::Result; -use sr_primitives::traits::{ - Zero, SimpleArithmetic, StaticLookup, Member, CheckedAdd, CheckedSub, MaybeSerializeDebug, - Saturating, Bounded, SignedExtension, SaturatedConversion, DispatchError, Convert, +use sr_primitives::{ + transaction_validity::{ + TransactionPriority, ValidTransaction, InvalidTransaction, TransactionValidityError, + TransactionValidity, + }, + traits::{ + Zero, SimpleArithmetic, StaticLookup, Member, CheckedAdd, CheckedSub, MaybeSerializeDebug, + Saturating, Bounded, SignedExtension, SaturatedConversion, Convert, + }, + weights::{DispatchInfo, SimpleDispatchInfo, Weight}, }; -use sr_primitives::transaction_validity::{TransactionPriority, ValidTransaction}; -use sr_primitives::weights::{DispatchInfo, SimpleDispatchInfo, Weight}; use system::{IsDeadAccount, OnNewAccount, ensure_signed, ensure_root}; mod mock; @@ -172,12 +188,6 @@ mod tests; pub use self::imbalances::{PositiveImbalance, NegativeImbalance}; -pub const DEFAULT_EXISTENTIAL_DEPOSIT: u32 = 0; -pub const DEFAULT_TRANSFER_FEE: u32 = 0; -pub const DEFAULT_CREATION_FEE: u32 = 0; -pub const DEFAULT_TRANSACTION_BASE_FEE: u32 = 0; -pub const DEFAULT_TRANSACTION_BYTE_FEE: u32 = 0; - pub trait Subtrait: system::Trait { /// The balance of an account. type Balance: Parameter + Member + SimpleArithmetic + Codec + Default + Copy + @@ -410,7 +420,7 @@ decl_module! { /// The fee to be paid for making a transaction; the per-byte portion. const TransactionByteFee: T::Balance = T::TransactionByteFee::get(); - fn deposit_event() = default; + fn deposit_event() = default; /// Transfer some liquid free balance to another account. /// @@ -459,7 +469,7 @@ decl_module! { /// - Independent of the arguments. /// - Contains a limited number of reads and writes. /// # - #[weight = SimpleDispatchInfo::FixedOperational(500_000)] + #[weight = SimpleDispatchInfo::FixedOperational(50_000)] fn set_balance( origin, who: ::Source, @@ -485,6 +495,21 @@ decl_module! { } Self::set_reserved_balance(&who, new_reserved); } + + /// Exactly as `transfer`, except the origin must be root and the source account may be + /// specified. + #[weight = SimpleDispatchInfo::FixedNormal(1_000_000)] + pub fn force_transfer( + origin, + source: ::Source, + dest: ::Source, + #[compact] value: T::Balance + ) { + ensure_root(origin)?; + let source = T::Lookup::lookup(source)?; + let dest = T::Lookup::lookup(dest)?; + >::transfer(&source, &dest, value)?; + } } } @@ -777,6 +802,7 @@ impl, I: Instance> system::Trait for ElevatedTrait { type MaximumBlockWeight = T::MaximumBlockWeight; type MaximumBlockLength = T::MaximumBlockLength; type AvailableBlockRatio = T::AvailableBlockRatio; + type Version = T::Version; } impl, I: Instance> Trait for ElevatedTrait { type Balance = T::Balance; @@ -823,12 +849,12 @@ where } fn burn(mut amount: Self::Balance) -> Self::PositiveImbalance { - >::mutate(|issued| - issued.checked_sub(&amount).unwrap_or_else(|| { + >::mutate(|issued| { + *issued = issued.checked_sub(&amount).unwrap_or_else(|| { amount = *issued; Zero::zero() - }) - ); + }); + }); PositiveImbalance::new(amount) } @@ -1168,7 +1194,6 @@ pub struct TakeFees, I: Instance = DefaultInstance>(#[codec(compact) impl, I: Instance> TakeFees { /// utility constructor. Used only in client/factory code. - #[cfg(feature = "std")] pub fn from(fee: T::Balance) -> Self { Self(fee) } @@ -1217,7 +1242,7 @@ impl, I: Instance + Clone + Eq> SignedExtension for TakeFees { type Call = T::Call; type AdditionalSigned = (); type Pre = (); - fn additional_signed(&self) -> rstd::result::Result<(), &'static str> { Ok(()) } + fn additional_signed(&self) -> rstd::result::Result<(), TransactionValidityError> { Ok(()) } fn validate( &self, @@ -1225,15 +1250,18 @@ impl, I: Instance + Clone + Eq> SignedExtension for TakeFees { _call: &Self::Call, info: DispatchInfo, len: usize, - ) -> rstd::result::Result { + ) -> TransactionValidity { // pay any fees. let fee = Self::compute_fee(len, info, self.0); - let imbalance = >::withdraw( + let imbalance = match >::withdraw( who, fee, WithdrawReason::TransactionPayment, ExistenceRequirement::KeepAlive, - ).map_err(|_| DispatchError::Payment)?; + ) { + Ok(imbalance) => imbalance, + Err(_) => return InvalidTransaction::Payment.into(), + }; T::TransactionPayment::on_unbalanced(imbalance); let mut r = ValidTransaction::default(); diff --git a/srml/balances/src/mock.rs b/srml/balances/src/mock.rs index 954d500a1076be24ff02d607c7d40b0dd567f5a6..12a49fc90d2cfa987197553252200ece1ae68a3b 100644 --- a/srml/balances/src/mock.rs +++ b/srml/balances/src/mock.rs @@ -22,8 +22,8 @@ use sr_primitives::{Perbill, traits::{Convert, IdentityLookup}, testing::Header, weights::{DispatchInfo, Weight}}; use primitives::{H256, Blake2Hasher}; use runtime_io; -use srml_support::{impl_outer_origin, parameter_types}; -use srml_support::traits::Get; +use support::{impl_outer_origin, parameter_types}; +use support::traits::Get; use std::cell::RefCell; use crate::{GenesisConfig, Module, Trait}; @@ -98,6 +98,7 @@ impl system::Trait for Runtime { type MaximumBlockWeight = MaximumBlockWeight; type MaximumBlockLength = MaximumBlockLength; type AvailableBlockRatio = AvailableBlockRatio; + type Version = (); } impl Trait for Runtime { type Balance = u64; diff --git a/srml/balances/src/tests.rs b/srml/balances/src/tests.rs index edbb198f341ee5e3b859f3aa858bb919b60d6abc..8e9f6acdd850b6cc055f31615e5ddc4ceb88047b 100644 --- a/srml/balances/src/tests.rs +++ b/srml/balances/src/tests.rs @@ -21,11 +21,12 @@ use super::*; use mock::{Balances, ExtBuilder, Runtime, System, info_from_weight, CALL}; use runtime_io::with_externalities; -use srml_support::{ +use support::{ assert_noop, assert_ok, assert_err, traits::{LockableCurrency, LockIdentifier, WithdrawReason, WithdrawReasons, Currency, ReservableCurrency} }; +use system::RawOrigin; const ID_1: LockIdentifier = *b"1 "; const ID_2: LockIdentifier = *b"2 "; @@ -231,7 +232,7 @@ fn default_indexing_on_new_accounts_should_not_work2() { // ext_deposit is 10, value is 9, not satisfies for ext_deposit assert_noop!( Balances::transfer(Some(1).into(), 5, 9), - "value too low to create account" + "value too low to create account", ); assert_eq!(Balances::is_dead_account(&5), true); // account 5 should not exist assert_eq!(Balances::free_balance(&1), 100); @@ -352,6 +353,20 @@ fn balance_transfer_works() { }); } +#[test] +fn force_transfer_works() { + with_externalities(&mut ExtBuilder::default().build(), || { + let _ = Balances::deposit_creating(&1, 111); + assert_noop!( + Balances::force_transfer(Some(2).into(), 1, 2, 69), + "RequireRootOrigin", + ); + assert_ok!(Balances::force_transfer(RawOrigin::Root.into(), 1, 2, 69)); + assert_eq!(Balances::total_balance(&1), 42); + assert_eq!(Balances::total_balance(&2), 69); + }); +} + #[test] fn reserving_balance_should_work() { with_externalities(&mut ExtBuilder::default().build(), || { @@ -374,7 +389,10 @@ fn balance_transfer_when_reserved_should_not_work() { with_externalities(&mut ExtBuilder::default().build(), || { let _ = Balances::deposit_creating(&1, 111); assert_ok!(Balances::reserve(&1, 69)); - assert_noop!(Balances::transfer(Some(1).into(), 2, 69), "balance too low to send value"); + assert_noop!( + Balances::transfer(Some(1).into(), 2, 69), + "balance too low to send value", + ); }); } @@ -502,7 +520,7 @@ fn transferring_too_high_value_should_not_panic() { assert_err!( Balances::transfer(Some(1).into(), 2, u64::max_value()), - "destination balance too high to receive value" + "destination balance too high to receive value", ); assert_eq!(Balances::free_balance(&1), u64::max_value()); @@ -580,7 +598,7 @@ fn transfer_overflow_isnt_exploitable() { assert_err!( Balances::transfer(Some(1).into(), 5, evil_value), - "got overflow after adding a fee to value" + "got overflow after adding a fee to value", ); } ); @@ -665,7 +683,7 @@ fn unvested_balance_should_not_transfer() { assert_eq!(Balances::vesting_balance(&1), 45); assert_noop!( Balances::transfer(Some(1).into(), 2, 56), - "vesting balance too high to send value" + "vesting balance too high to send value", ); // Account 1 cannot send more than vested amount } ); @@ -789,3 +807,19 @@ fn signed_extension_take_fees_is_bounded() { } ); } + +#[test] +fn burn_must_work() { + with_externalities( + &mut ExtBuilder::default() + .monied(true) + .build(), + || { + let init_total_issuance = Balances::total_issuance(); + let imbalance = Balances::burn(10); + assert_eq!(Balances::total_issuance(), init_total_issuance - 10); + drop(imbalance); + assert_eq!(Balances::total_issuance(), init_total_issuance); + } + ); +} diff --git a/srml/collective/Cargo.toml b/srml/collective/Cargo.toml index 7aaba7c29f7b8d2bb554d1de637e02de5b15ecca..347a289b57b89b457e0894a4dd54ab815dbd6aa3 100644 --- a/srml/collective/Cargo.toml +++ b/srml/collective/Cargo.toml @@ -5,18 +5,18 @@ authors = ["Parity Technologies "] edition = "2018" [dependencies] -serde = { version = "1.0", optional = true } -safe-mix = { version = "1.0", default-features = false} +serde = { version = "1.0.101", optional = true } +safe-mix = { version = "1.0.0", default-features = false } codec = { package = "parity-scale-codec", version = "1.0.0", default-features = false, features = ["derive"] } primitives = { package = "substrate-primitives", path = "../../core/primitives", default-features = false } rstd = { package = "sr-std", path = "../../core/sr-std", default-features = false } -runtime_io = { package = "sr-io", path = "../../core/sr-io", default-features = false } +runtime-io = { package = "sr-io", path = "../../core/sr-io", default-features = false } sr-primitives = { path = "../../core/sr-primitives", default-features = false } -srml-support = { path = "../support", default-features = false } +support = { package = "srml-support", path = "../support", default-features = false } system = { package = "srml-system", path = "../system", default-features = false } [dev-dependencies] -hex-literal = "0.2.0" +hex-literal = "0.2.1" balances = { package = "srml-balances", path = "../balances" } [features] @@ -27,8 +27,8 @@ std = [ "primitives/std", "rstd/std", "serde", - "runtime_io/std", - "srml-support/std", + "runtime-io/std", + "support/std", "sr-primitives/std", "system/std", ] diff --git a/srml/collective/src/lib.rs b/srml/collective/src/lib.rs index 76320d1117cb6fcd60ff98c62c7cca1bdf251002..4a157569c0ffec890a9f4985a69dfa5bd01adfe6 100644 --- a/srml/collective/src/lib.rs +++ b/srml/collective/src/lib.rs @@ -27,9 +27,9 @@ use rstd::{prelude::*, result}; use primitives::u32_trait::Value as U32; use sr_primitives::traits::{Hash, EnsureOrigin}; use sr_primitives::weights::SimpleDispatchInfo; -use srml_support::{ +use support::{ dispatch::{Dispatchable, Parameter}, codec::{Encode, Decode}, - traits::{ChangeMembers, InitializeMembers}, StorageValue, StorageMap, decl_module, decl_event, + traits::{ChangeMembers, InitializeMembers}, decl_module, decl_event, decl_storage, ensure, }; use system::{self, ensure_signed, ensure_root}; @@ -99,15 +99,7 @@ decl_storage! { add_extra_genesis { config(phantom): rstd::marker::PhantomData; config(members): Vec; - build(| - storage: &mut (sr_primitives::StorageOverlay, sr_primitives::ChildrenStorageOverlay), - config: &Self, - | { - runtime_io::with_storage( - storage, - || Module::::initialize_members(&config.members), - ); - }) + build(|config| Module::::initialize_members(&config.members)) } } @@ -138,7 +130,7 @@ decl_event!( // operational class. decl_module! { pub struct Module, I: Instance=DefaultInstance> for enum Call where origin: ::Origin { - fn deposit_event() = default; + fn deposit_event() = default; /// Set the collective's membership manually to `new_members`. Be nice to the chain and /// provide it pre-sorted. @@ -289,7 +281,7 @@ impl, I: Instance> ChangeMembers for Module { } ); } - >::put_ref(new); + >::put(new); } } @@ -297,7 +289,7 @@ impl, I: Instance> InitializeMembers for Module fn initialize_members(members: &[T::AccountId]) { if !members.is_empty() { assert!(>::get().is_empty(), "Members are already initialized!"); - >::put_ref(members); + >::put(members); } } } @@ -387,7 +379,7 @@ impl< #[cfg(test)] mod tests { use super::*; - use srml_support::{Hashable, assert_ok, assert_noop, parameter_types}; + use support::{Hashable, assert_ok, assert_noop, parameter_types}; use system::{EventRecord, Phase}; use hex_literal::hex; use runtime_io::with_externalities; @@ -419,6 +411,7 @@ mod tests { type MaximumBlockWeight = MaximumBlockWeight; type MaximumBlockLength = MaximumBlockLength; type AvailableBlockRatio = AvailableBlockRatio; + type Version = (); } impl Trait for Test { type Origin = Origin; @@ -434,7 +427,7 @@ mod tests { pub type Block = sr_primitives::generic::Block; pub type UncheckedExtrinsic = sr_primitives::generic::UncheckedExtrinsic; - srml_support::construct_runtime!( + support::construct_runtime!( pub enum Test where Block = Block, NodeBlock = Block, diff --git a/srml/contracts/COMPLEXITY.md b/srml/contracts/COMPLEXITY.md index c582de4264f841f2b5d4024081b5ddb641bd6907..a29127f778f7ebc37f048a2bcb302e081385564f 100644 --- a/srml/contracts/COMPLEXITY.md +++ b/srml/contracts/COMPLEXITY.md @@ -123,7 +123,7 @@ While these functions only modify the local `Map`, if changes made by them are c **complexity**: Each lookup has a logarithmical computing time to the number of already inserted entries. No additional memory is required. -## create_contract +## instantiate_contract Calls `contract_exists` and if it doesn't exist, do not modify the local `Map` similarly to `set_rent_allowance`. @@ -174,7 +174,7 @@ Assuming marshaled size of a balance value is of the constant size we can neglec ## Initialization -Before a call or create can be performed the execution context must be initialized. +Before a call or instantiate can be performed the execution context must be initialized. For the first call or instantiation in the handling of an extrinsic, this involves two calls: @@ -213,7 +213,7 @@ and on top of that at most once per block: - `kill_child_storage` - mutation of `ContractInfoOf` -Loading code most likely will trigger a DB read, since the code is immutable and therefore will not get into the cache (unless a suicide removes it, or it has been created in the same call chain). +Loading code most likely will trigger a DB read, since the code is immutable and therefore will not get into the cache (unless a suicide removes it, or it has been instantiated in the same call chain). Also, `transfer` can make up to 2 DB reads and up to 2 DB writes (if flushed to the storage) in the standard case. If removal of the source account takes place then it will additionally perform a DB write per one storage entry that the account has. @@ -223,15 +223,15 @@ Finally, all changes are `commit`-ted into the underlying overlay. The complexit - Only for the first invocation of the contract: up to 5 DB reads and one DB write as well as logic executed by `ensure_can_withdraw`, `withdraw`, `make_free_balance_be`. - On top of that for every invocation: Up to 5 DB reads. DB read of the code is of dynamic size. There can also be up to 2 DB writes (if flushed to the storage). Additionally, if the source account removal takes place a DB write will be performed per one storage entry that the account has. -## Create +## Instantiate -This function takes the code of the constructor and input data. Creation of a contract consists of the following steps: +This function takes the code of the constructor and input data. Instantiation of a contract consists of the following steps: 1. Initialization of the execution context. 2. Calling `DetermineContractAddress` hook to determine an address for the contract, -3. `transfer`-ing funds between self and the newly created contract. +3. `transfer`-ing funds between self and the newly instantiated contract. 4. Executing the constructor code. This will yield the final code of the code. -5. Storing the code for the newly created contract in the overlay. +5. Storing the code for the newly instantiated contract in the overlay. 6. Committing overlayed changed to the underlying `AccountDb`. **Note** that the complexity of executing the constructor code should be considered separately. @@ -303,7 +303,7 @@ Loading `input_data` should be charged in any case. **complexity**: All complexity comes from loading buffers and executing `call` executive function. The former component is proportional to the sizes of `callee`, `value` and `input_data` buffers. The latter component completely depends on the complexity of `call` executive function, and also dominated by it. -## ext_create +## ext_instantiate This function receives the following arguments: @@ -317,13 +317,13 @@ It consists of the following steps: 1. Loading `init_code` buffer from the sandbox memory (see sandboxing memory get) and then decoding it. 2. Loading `value` buffer from the sandbox memory and then decoding it. 3. Loading `input_data` buffer from the sandbox memory. -4. Invoking `create` executive function. +4. Invoking `instantiate` executive function. Loading of `value` buffer should be charged. This is because the size of the buffer is specified by the calling code, even though marshaled representation is, essentially, of constant size. This can be fixed by assigning an upper bound for size for `Balance`. Loading `init_code` and `input_data` should be charged in any case. -**complexity**: All complexity comes from loading buffers and executing `create` executive function. The former component is proportional to the sizes of `init_code`, `value` and `input_data` buffers. The latter component completely depends on the complexity of `create` executive function and also dominated by it. +**complexity**: All complexity comes from loading buffers and executing `instantiate` executive function. The former component is proportional to the sizes of `init_code`, `value` and `input_data` buffers. The latter component completely depends on the complexity of `instantiate` executive function and also dominated by it. ## ext_return diff --git a/srml/contracts/Cargo.toml b/srml/contracts/Cargo.toml index a013571edf3577faee1db3336611ece7a77e468f..f076f5fedae1ded702d9eeb593d053b751c5de3d 100644 --- a/srml/contracts/Cargo.toml +++ b/srml/contracts/Cargo.toml @@ -5,32 +5,29 @@ authors = ["Parity Technologies "] edition = "2018" [dependencies] -serde = { version = "1.0", optional = true, features = ["derive"] } -pwasm-utils = { version = "0.6.1", default-features = false } +serde = { version = "1.0.101", optional = true, features = ["derive"] } +pwasm-utils = { version = "0.11.0", default-features = false } codec = { package = "parity-scale-codec", version = "1.0.0", default-features = false, features = ["derive"] } -parity-wasm = { version = "0.31", default-features = false } -wasmi-validation = { version = "0.1", default-features = false } +parity-wasm = { version = "0.40.3", default-features = false } +wasmi-validation = { version = "0.2.0", default-features = false } primitives = { package = "substrate-primitives", path = "../../core/primitives", default-features = false } sr-primitives = { path = "../../core/sr-primitives", default-features = false } runtime-io = { package = "sr-io", path = "../../core/sr-io", default-features = false } rstd = { package = "sr-std", path = "../../core/sr-std", default-features = false } sandbox = { package = "sr-sandbox", path = "../../core/sr-sandbox", default-features = false } -srml-support = { path = "../support", default-features = false } +support = { package = "srml-support", path = "../support", default-features = false } system = { package = "srml-system", path = "../system", default-features = false } -timestamp = { package = "srml-timestamp", path = "../timestamp", default-features = false } [dev-dependencies] -wabt = "~0.7.4" -assert_matches = "1.1" -hex-literal = "0.2.0" +wabt = "0.9.2" +assert_matches = "1.3.0" +hex-literal = "0.2.1" balances = { package = "srml-balances", path = "../balances" } -hex = "0.3" +hex = "0.3.2" +timestamp = { package = "srml-timestamp", path = "../timestamp" } [features] default = ["std"] -core = [ - "wasmi-validation/core", -] std = [ "serde", "codec/std", @@ -39,9 +36,8 @@ std = [ "runtime-io/std", "rstd/std", "sandbox/std", - "srml-support/std", + "support/std", "system/std", - "timestamp/std", "parity-wasm/std", "pwasm-utils/std", "wasmi-validation/std", diff --git a/srml/contracts/src/account_db.rs b/srml/contracts/src/account_db.rs index 5cfd0d3a65fa8dc77c5584cefdcbd730cc401092..50bd1fd40e97d34a319dc9b590c2f5ffd977d7c4 100644 --- a/srml/contracts/src/account_db.rs +++ b/srml/contracts/src/account_db.rs @@ -26,19 +26,65 @@ use rstd::collections::btree_map::{BTreeMap, Entry}; use rstd::prelude::*; use runtime_io::blake2_256; use sr_primitives::traits::{Bounded, Zero}; -use srml_support::traits::{Currency, Get, Imbalance, SignedImbalance, UpdateBalanceOutcome}; -use srml_support::{storage::child, StorageMap}; +use support::traits::{Currency, Get, Imbalance, SignedImbalance, UpdateBalanceOutcome}; +use support::{storage::child, StorageMap}; use system; // Note: we don't provide Option because we can't create // the trie_id in the overlay, thus we provide an overlay on the fields // specifically. pub struct ChangeEntry { + /// If Some(_), then the account balance is modified to the value. If None and `reset` is false, + /// the balance unmodified. If None and `reset` is true, the balance is reset to 0. balance: Option>, - /// If None, the code_hash remains untouched. + /// If Some(_), then a contract is instantiated with the code hash. If None and `reset` is false, + /// then the contract code is unmodified. If None and `reset` is true, the contract is deleted. code_hash: Option>, + /// If Some(_), then the rent allowance is set to the value. If None and `reset` is false, then + /// the rent allowance is unmodified. If None and `reset` is true, the contract is deleted. rent_allowance: Option>, storage: BTreeMap>>, + /// If true, indicates that the existing contract and all its storage entries should be removed + /// and replaced with the fields on this change entry. Otherwise, the fields on this change + /// entry are updates merged into the existing contract info and storage. + reset: bool, +} + +impl ChangeEntry { + fn balance(&self) -> Option> { + self.balance.or_else(|| { + if self.reset { + Some(>::zero()) + } else { + None + } + }) + } + + fn code_hash(&self) -> Option>> { + if self.reset { + Some(self.code_hash) + } else { + self.code_hash.map(Some) + } + } + + fn rent_allowance(&self) -> Option>> { + if self.reset { + Some(self.rent_allowance) + } else { + self.rent_allowance.map(Some) + } + } + + fn storage(&self, location: &StorageKey) -> Option>> { + let value = self.storage.get(location).cloned(); + if self.reset { + Some(value.unwrap_or(None)) + } else { + value + } + } } // Cannot derive(Default) since it erroneously bounds T by Default. @@ -49,6 +95,7 @@ impl Default for ChangeEntry { balance: Default::default(), code_hash: Default::default(), storage: Default::default(), + reset: false, } } } @@ -98,7 +145,7 @@ impl AccountDb for DirectAccountDb { fn commit(&mut self, s: ChangeSet) { let mut total_imbalance = SignedImbalance::zero(); for (address, changed) in s.into_iter() { - if let Some(balance) = changed.balance { + if let Some(balance) = changed.balance() { let (imbalance, outcome) = T::Currency::make_free_balance_be(&address, balance); total_imbalance = total_imbalance.merge(imbalance); if let UpdateBalanceOutcome::AccountKilled = outcome { @@ -109,9 +156,10 @@ impl AccountDb for DirectAccountDb { } } - if changed.code_hash.is_some() - || changed.rent_allowance.is_some() + if changed.code_hash().is_some() + || changed.rent_allowance().is_some() || !changed.storage.is_empty() + || changed.reset { let old_info = match >::get(&address) { Some(ContractInfo::Alive(alive)) => Some(alive), @@ -120,20 +168,40 @@ impl AccountDb for DirectAccountDb { Some(ContractInfo::Tombstone(_)) => continue, }; - let mut new_info = if let Some(info) = old_info.clone() { - info - } else if let Some(code_hash) = changed.code_hash { - AliveContractInfo:: { - code_hash, - storage_size: T::StorageSizeOffset::get(), - trie_id: ::TrieIdGenerator::trie_id(&address), - deduct_block: >::block_number(), - rent_allowance: >::max_value(), - last_write: None, + let mut new_info = match (changed.reset, old_info.clone(), changed.code_hash) { + // Existing contract is being modified. + (false, Some(info), _) => info, + // Existing contract is being removed. + (true, Some(info), None) => { + child::kill_storage(&info.trie_id); + >::remove(&address); + continue; } - } else { - // No contract exist and no code_hash provided - continue; + // Existing contract is being replaced by a new one. + (true, Some(info), Some(code_hash)) => { + child::kill_storage(&info.trie_id); + AliveContractInfo:: { + code_hash, + storage_size: T::StorageSizeOffset::get(), + trie_id: ::TrieIdGenerator::trie_id(&address), + deduct_block: >::block_number(), + rent_allowance: >::max_value(), + last_write: None, + } + } + // New contract is being instantiated. + (_, None, Some(code_hash)) => { + AliveContractInfo:: { + code_hash, + storage_size: T::StorageSizeOffset::get(), + trie_id: ::TrieIdGenerator::trie_id(&address), + deduct_block: >::block_number(), + rent_allowance: >::max_value(), + last_write: None, + } + } + // There is no existing at the address nor a new one to be instantiated. + (_, None, None) => continue, }; if let Some(rent_allowance) = changed.rent_allowance { @@ -210,7 +278,7 @@ impl<'a, T: Trait> OverlayAccountDb<'a, T> { } /// Return an error if contract already exists (either if it is alive or tombstone) - pub fn create_contract( + pub fn instantiate_contract( &mut self, account: &T::AccountId, code_hash: CodeHash, @@ -227,6 +295,19 @@ impl<'a, T: Trait> OverlayAccountDb<'a, T> { Ok(()) } + + /// Mark a contract as deleted. + pub fn destroy_contract(&mut self, account: &T::AccountId) { + let mut local = self.local.borrow_mut(); + local.insert( + account.clone(), + ChangeEntry { + reset: true, + ..Default::default() + } + ); + } + /// Assume contract exists pub fn set_rent_allowance(&mut self, account: &T::AccountId, rent_allowance: BalanceOf) { self.local @@ -254,36 +335,35 @@ impl<'a, T: Trait> AccountDb for OverlayAccountDb<'a, T> { self.local .borrow() .get(account) - .and_then(|a| a.storage.get(location)) - .cloned() + .and_then(|changes| changes.storage(location)) .unwrap_or_else(|| self.underlying.get_storage(account, trie_id, location)) } fn get_code_hash(&self, account: &T::AccountId) -> Option> { self.local .borrow() .get(account) - .and_then(|changes| changes.code_hash) - .or_else(|| self.underlying.get_code_hash(account)) + .and_then(|changes| changes.code_hash()) + .unwrap_or_else(|| self.underlying.get_code_hash(account)) } fn get_rent_allowance(&self, account: &T::AccountId) -> Option> { self.local .borrow() .get(account) - .and_then(|changes| changes.rent_allowance) - .or_else(|| self.underlying.get_rent_allowance(account)) + .and_then(|changes| changes.rent_allowance()) + .unwrap_or_else(|| self.underlying.get_rent_allowance(account)) } fn contract_exists(&self, account: &T::AccountId) -> bool { self.local .borrow() .get(account) - .map(|a| a.code_hash.is_some()) + .and_then(|changes| changes.code_hash().map(|code_hash| code_hash.is_some())) .unwrap_or_else(|| self.underlying.contract_exists(account)) } fn get_balance(&self, account: &T::AccountId) -> BalanceOf { self.local .borrow() .get(account) - .and_then(|a| a.balance) + .and_then(|changes| changes.balance()) .unwrap_or_else(|| self.underlying.get_balance(account)) } fn commit(&mut self, s: ChangeSet) { @@ -293,10 +373,14 @@ impl<'a, T: Trait> AccountDb for OverlayAccountDb<'a, T> { match local.entry(address) { Entry::Occupied(e) => { let mut value = e.into_mut(); - value.balance = changed.balance.or(value.balance); - value.code_hash = changed.code_hash.or(value.code_hash); - value.rent_allowance = changed.rent_allowance.or(value.rent_allowance); - value.storage.extend(changed.storage.into_iter()); + if changed.reset { + *value = changed; + } else { + value.balance = changed.balance.or(value.balance); + value.code_hash = changed.code_hash.or(value.code_hash); + value.rent_allowance = changed.rent_allowance.or(value.rent_allowance); + value.storage.extend(changed.storage.into_iter()); + } } Entry::Vacant(e) => { e.insert(changed); diff --git a/srml/contracts/src/exec.rs b/srml/contracts/src/exec.rs index 5ba02d43a0ffe68d1d99bdf4e260a4b35a043b47..94343c5fb93c2b25c8b68084abd7575195a583c9 100644 --- a/srml/contracts/src/exec.rs +++ b/srml/contracts/src/exec.rs @@ -22,12 +22,11 @@ use crate::rent; use rstd::prelude::*; use sr_primitives::traits::{Bounded, CheckedAdd, CheckedSub, Zero}; -use srml_support::traits::{WithdrawReason, Currency}; -use timestamp; +use support::traits::{WithdrawReason, Currency, Time}; pub type AccountIdOf = ::AccountId; pub type CallOf = ::Call; -pub type MomentOf = ::Moment; +pub type MomentOf = <::Time as Time>::Moment; pub type SeedOf = ::Hash; pub type BlockNumberOf = ::BlockNumber; @@ -75,11 +74,12 @@ pub type ExecResult = Result; /// wrap the error string into an ExecutionError with the provided buffer and return from the /// enclosing function. This macro is used instead of .map_err(..)? in order to avoid taking /// ownership of buffer unless there is an error. +#[macro_export] macro_rules! try_or_exec_error { ($e:expr, $buffer:expr) => { match $e { Ok(val) => val, - Err(reason) => return Err(ExecError { reason, buffer: $buffer }), + Err(reason) => return Err($crate::exec::ExecError { reason, buffer: $buffer }), } } } @@ -154,6 +154,9 @@ pub trait Ext { /// Returns a reference to the timestamp of the current block fn now(&self) -> &MomentOf; + /// Returns the minimum balance that is required for creating an account. + fn minimum_balance(&self) -> BalanceOf; + /// Returns a random number for the current block with the given subject. fn random(&self, subject: &[u8]) -> SeedOf; @@ -188,15 +191,6 @@ pub trait Loader { fn load_main(&self, code_hash: &CodeHash) -> Result; } -/// Struct that records a request to deposit an event with a list of topics. -#[cfg_attr(any(feature = "std", test), derive(Debug, PartialEq, Eq))] -pub struct IndexedEvent { - /// A list of topics this event will be deposited with. - pub topics: Vec, - /// The event to deposit. - pub event: Event, -} - /// A trait that represent a virtual machine. /// /// You can view a virtual machine as something that takes code, an input data buffer, @@ -267,6 +261,7 @@ pub enum DeferredAction { } pub struct ExecutionContext<'a, T: Trait + 'a, V, L> { + pub parent: Option<&'a ExecutionContext<'a, T, V, L>>, pub self_account: T::AccountId, pub self_trie_id: Option, pub overlay: OverlayAccountDb<'a, T>, @@ -275,7 +270,7 @@ pub struct ExecutionContext<'a, T: Trait + 'a, V, L> { pub config: &'a Config, pub vm: &'a V, pub loader: &'a L, - pub timestamp: T::Moment, + pub timestamp: MomentOf, pub block_number: T::BlockNumber, } @@ -291,6 +286,7 @@ where /// account (not a contract). pub fn top_level(origin: T::AccountId, cfg: &'a Config, vm: &'a V, loader: &'a L) -> Self { ExecutionContext { + parent: None, self_trie_id: None, self_account: origin, overlay: OverlayAccountDb::::new(&DirectAccountDb), @@ -299,7 +295,7 @@ where config: &cfg, vm: &vm, loader: &loader, - timestamp: >::now(), + timestamp: T::Time::now(), block_number: >::block_number(), } } @@ -308,6 +304,7 @@ where -> ExecutionContext<'b, T, V, L> { ExecutionContext { + parent: Some(self), self_trie_id: trie_id, self_account: dest, overlay: OverlayAccountDb::new(&self.overlay), @@ -385,13 +382,29 @@ where nested.loader.load_main(&dest_code_hash), input_data ); - nested.vm + let output = nested.vm .execute( &executable, nested.new_call_context(caller, value), input_data, gas_meter, - ) + )?; + + // Destroy contract if insufficient remaining balance. + if nested.overlay.get_balance(&dest) < nested.config.existential_deposit { + let parent = nested.parent + .expect("a nested execution context must have a parent; qed"); + if parent.is_live(&dest) { + return Err(ExecError { + reason: "contract cannot be destroyed during recursive execution", + buffer: output.data, + }); + } + + nested.overlay.destroy_contract(&dest); + } + + Ok(output) } None => Ok(ExecReturnValue { status: STATUS_SUCCESS, data: Vec::new() }), } @@ -407,7 +420,7 @@ where ) -> Result<(T::AccountId, ExecReturnValue), ExecError> { if self.depth == self.config.max_depth as usize { return Err(ExecError { - reason: "reached maximum depth, cannot create", + reason: "reached maximum depth, cannot instantiate", buffer: input_data, }); } @@ -434,7 +447,7 @@ where let output = self.with_nested_context(dest.clone(), dest_trie_id, |nested| { try_or_exec_error!( - nested.overlay.create_contract(&dest, code_hash.clone()), + nested.overlay.instantiate_contract(&dest, code_hash.clone()), input_data ); @@ -464,6 +477,14 @@ where gas_meter, )?; + // Error out if insufficient remaining balance. + if nested.overlay.get_balance(&dest) < nested.config.existential_deposit { + return Err(ExecError { + reason: "insufficient remaining balance", + buffer: output.data, + }); + } + // Deposit an instantiation event. nested.deferred.push(DeferredAction::DepositEvent { event: RawEvent::Instantiated(caller.clone(), dest.clone()), @@ -507,6 +528,13 @@ where Ok(output) } + + /// Returns whether a contract, identified by address, is currently live in the execution + /// stack, meaning it is in the middle of an execution. + fn is_live(&self, account: &T::AccountId) -> bool { + &self.self_account == account || + self.parent.map_or(false, |parent| parent.is_live(account)) + } } #[cfg_attr(test, derive(Debug, PartialEq, Eq))] @@ -636,7 +664,7 @@ struct CallContext<'a, 'b: 'a, T: Trait + 'b, V: Vm + 'b, L: Loader> { ctx: &'a mut ExecutionContext<'b, T, V, L>, caller: T::AccountId, value_transferred: BalanceOf, - timestamp: T::Moment, + timestamp: MomentOf, block_number: T::BlockNumber, } @@ -728,10 +756,14 @@ where system::Module::::random(subject) } - fn now(&self) -> &T::Moment { + fn now(&self) -> &MomentOf { &self.timestamp } + fn minimum_balance(&self) -> BalanceOf { + self.ctx.config.existential_deposit + } + fn deposit_event(&mut self, topics: Vec, data: Vec) { self.ctx.deferred.push(DeferredAction::DepositEvent { topics, @@ -908,7 +940,7 @@ mod tests { with_externalities(&mut ExtBuilder::default().build(), || { let cfg = Config::preload(); let mut ctx = ExecutionContext::top_level(ALICE, &cfg, &vm, &loader); - ctx.overlay.create_contract(&BOB, exec_ch).unwrap(); + ctx.overlay.instantiate_contract(&BOB, exec_ch).unwrap(); assert_matches!( ctx.call(BOB, value, &mut gas_meter, data), @@ -1008,7 +1040,7 @@ mod tests { with_externalities(&mut ExtBuilder::default().build(), || { let cfg = Config::preload(); let mut ctx = ExecutionContext::top_level(origin, &cfg, &vm, &loader); - ctx.overlay.create_contract(&BOB, return_ch).unwrap(); + ctx.overlay.instantiate_contract(&BOB, return_ch).unwrap(); ctx.overlay.set_balance(&origin, 100); ctx.overlay.set_balance(&dest, 0); @@ -1031,7 +1063,7 @@ mod tests { let dest = BOB; // This test sends 50 units of currency to a non-existent account. - // This should create lead to creation of a new account thus + // This should lead to creation of a new account thus // a fee should be charged. with_externalities( &mut ExtBuilder::default().existential_deposit(15).build(), @@ -1090,7 +1122,7 @@ mod tests { ); // This test sends 50 units of currency as an endownment to a newly - // created contract. + // instantiated contract. with_externalities( &mut ExtBuilder::default().existential_deposit(15).build(), || { @@ -1169,7 +1201,7 @@ mod tests { with_externalities(&mut ExtBuilder::default().build(), || { let cfg = Config::preload(); let mut ctx = ExecutionContext::top_level(origin, &cfg, &vm, &loader); - ctx.overlay.create_contract(&BOB, return_ch).unwrap(); + ctx.overlay.instantiate_contract(&BOB, return_ch).unwrap(); let result = ctx.call( dest, @@ -1200,7 +1232,7 @@ mod tests { with_externalities(&mut ExtBuilder::default().build(), || { let cfg = Config::preload(); let mut ctx = ExecutionContext::top_level(origin, &cfg, &vm, &loader); - ctx.overlay.create_contract(&BOB, return_ch).unwrap(); + ctx.overlay.instantiate_contract(&BOB, return_ch).unwrap(); let result = ctx.call( dest, @@ -1228,7 +1260,7 @@ mod tests { with_externalities(&mut ExtBuilder::default().build(), || { let cfg = Config::preload(); let mut ctx = ExecutionContext::top_level(ALICE, &cfg, &vm, &loader); - ctx.overlay.create_contract(&BOB, input_data_ch).unwrap(); + ctx.overlay.instantiate_contract(&BOB, input_data_ch).unwrap(); let result = ctx.call( BOB, @@ -1297,7 +1329,7 @@ mod tests { with_externalities(&mut ExtBuilder::default().build(), || { let cfg = Config::preload(); let mut ctx = ExecutionContext::top_level(ALICE, &cfg, &vm, &loader); - ctx.overlay.create_contract(&BOB, recurse_ch).unwrap(); + ctx.overlay.instantiate_contract(&BOB, recurse_ch).unwrap(); let result = ctx.call( BOB, @@ -1342,8 +1374,8 @@ mod tests { let cfg = Config::preload(); let mut ctx = ExecutionContext::top_level(origin, &cfg, &vm, &loader); - ctx.overlay.create_contract(&dest, bob_ch).unwrap(); - ctx.overlay.create_contract(&CHARLIE, charlie_ch).unwrap(); + ctx.overlay.instantiate_contract(&dest, bob_ch).unwrap(); + ctx.overlay.instantiate_contract(&CHARLIE, charlie_ch).unwrap(); let result = ctx.call( dest, @@ -1383,8 +1415,8 @@ mod tests { with_externalities(&mut ExtBuilder::default().build(), || { let cfg = Config::preload(); let mut ctx = ExecutionContext::top_level(ALICE, &cfg, &vm, &loader); - ctx.overlay.create_contract(&BOB, bob_ch).unwrap(); - ctx.overlay.create_contract(&CHARLIE, charlie_ch).unwrap(); + ctx.overlay.instantiate_contract(&BOB, bob_ch).unwrap(); + ctx.overlay.instantiate_contract(&CHARLIE, charlie_ch).unwrap(); let result = ctx.call( BOB, @@ -1439,7 +1471,7 @@ mod tests { let mut ctx = ExecutionContext::top_level(ALICE, &cfg, &vm, &loader); ctx.overlay.set_balance(&ALICE, 1000); - let created_contract_address = assert_matches!( + let instantiated_contract_address = assert_matches!( ctx.instantiate( 100, &mut GasMeter::::with_limit(10000, 1), @@ -1451,14 +1483,14 @@ mod tests { // Check that the newly created account has the expected code hash and // there are instantiation event. - assert_eq!(ctx.overlay.get_code_hash(&created_contract_address).unwrap(), dummy_ch); + assert_eq!(ctx.overlay.get_code_hash(&instantiated_contract_address).unwrap(), dummy_ch); assert_eq!(&ctx.events(), &[ DeferredAction::DepositEvent { - event: RawEvent::Transfer(ALICE, created_contract_address, 100), + event: RawEvent::Transfer(ALICE, instantiated_contract_address, 100), topics: Vec::new(), }, DeferredAction::DepositEvent { - event: RawEvent::Instantiated(ALICE, created_contract_address), + event: RawEvent::Instantiated(ALICE, instantiated_contract_address), topics: Vec::new(), } ]); @@ -1482,7 +1514,7 @@ mod tests { let mut ctx = ExecutionContext::top_level(ALICE, &cfg, &vm, &loader); ctx.overlay.set_balance(&ALICE, 1000); - let created_contract_address = assert_matches!( + let instantiated_contract_address = assert_matches!( ctx.instantiate( 100, &mut GasMeter::::with_limit(10000, 1), @@ -1493,7 +1525,7 @@ mod tests { ); // Check that the account has not been created. - assert!(ctx.overlay.get_code_hash(&created_contract_address).is_none()); + assert!(ctx.overlay.get_code_hash(&instantiated_contract_address).is_none()); assert!(ctx.events().is_empty()); } ); @@ -1505,12 +1537,12 @@ mod tests { let mut loader = MockLoader::empty(); let dummy_ch = loader.insert(|_| exec_success()); - let created_contract_address = Rc::new(RefCell::new(None::)); - let creator_ch = loader.insert({ + let instantiated_contract_address = Rc::new(RefCell::new(None::)); + let instantiator_ch = loader.insert({ let dummy_ch = dummy_ch.clone(); - let created_contract_address = Rc::clone(&created_contract_address); + let instantiated_contract_address = Rc::clone(&instantiated_contract_address); move |ctx| { - // Instantiate a contract and save it's address in `created_contract_address`. + // Instantiate a contract and save it's address in `instantiated_contract_address`. let (address, output) = ctx.ext.instantiate( &dummy_ch, 15u64, @@ -1518,7 +1550,7 @@ mod tests { vec![] ).unwrap(); - *created_contract_address.borrow_mut() = address.into(); + *instantiated_contract_address.borrow_mut() = address.into(); Ok(output) } }); @@ -1529,29 +1561,29 @@ mod tests { let cfg = Config::preload(); let mut ctx = ExecutionContext::top_level(ALICE, &cfg, &vm, &loader); ctx.overlay.set_balance(&ALICE, 1000); - ctx.overlay.create_contract(&BOB, creator_ch).unwrap(); + ctx.overlay.instantiate_contract(&BOB, instantiator_ch).unwrap(); assert_matches!( ctx.call(BOB, 20, &mut GasMeter::::with_limit(1000, 1), vec![]), Ok(_) ); - let created_contract_address = created_contract_address.borrow().as_ref().unwrap().clone(); + let instantiated_contract_address = instantiated_contract_address.borrow().as_ref().unwrap().clone(); // Check that the newly created account has the expected code hash and // there are instantiation event. - assert_eq!(ctx.overlay.get_code_hash(&created_contract_address).unwrap(), dummy_ch); + assert_eq!(ctx.overlay.get_code_hash(&instantiated_contract_address).unwrap(), dummy_ch); assert_eq!(&ctx.events(), &[ DeferredAction::DepositEvent { event: RawEvent::Transfer(ALICE, BOB, 20), topics: Vec::new(), }, DeferredAction::DepositEvent { - event: RawEvent::Transfer(BOB, created_contract_address, 15), + event: RawEvent::Transfer(BOB, instantiated_contract_address, 15), topics: Vec::new(), }, DeferredAction::DepositEvent { - event: RawEvent::Instantiated(BOB, created_contract_address), + event: RawEvent::Instantiated(BOB, instantiated_contract_address), topics: Vec::new(), }, ]); @@ -1567,10 +1599,10 @@ mod tests { let dummy_ch = loader.insert( |_| Err(ExecError { reason: "It's a trap!", buffer: Vec::new() }) ); - let creator_ch = loader.insert({ + let instantiator_ch = loader.insert({ let dummy_ch = dummy_ch.clone(); move |ctx| { - // Instantiate a contract and save it's address in `created_contract_address`. + // Instantiate a contract and save it's address in `instantiated_contract_address`. assert_matches!( ctx.ext.instantiate( &dummy_ch, @@ -1591,14 +1623,14 @@ mod tests { let cfg = Config::preload(); let mut ctx = ExecutionContext::top_level(ALICE, &cfg, &vm, &loader); ctx.overlay.set_balance(&ALICE, 1000); - ctx.overlay.create_contract(&BOB, creator_ch).unwrap(); + ctx.overlay.instantiate_contract(&BOB, instantiator_ch).unwrap(); assert_matches!( ctx.call(BOB, 20, &mut GasMeter::::with_limit(1000, 1), vec![]), Ok(_) ); - // The contract wasn't created so we don't expect to see an instantiation + // The contract wasn't instantiated so we don't expect to see an instantiation // event here. assert_eq!(&ctx.events(), &[ DeferredAction::DepositEvent { diff --git a/srml/contracts/src/gas.rs b/srml/contracts/src/gas.rs index a5811e81a0c3bd3fe54df01b72ccd8d188aabf3d..08070916fbf293d439783fae9e5f30287d1e0ddb 100644 --- a/srml/contracts/src/gas.rs +++ b/srml/contracts/src/gas.rs @@ -16,10 +16,12 @@ use crate::{GasSpent, Module, Trait, BalanceOf, NegativeImbalanceOf}; use rstd::convert::TryFrom; -use sr_primitives::BLOCK_FULL; -use sr_primitives::traits::{CheckedMul, Zero, SaturatedConversion, SimpleArithmetic, UniqueSaturatedInto}; -use srml_support::StorageValue; -use srml_support::traits::{Currency, ExistenceRequirement, Get, Imbalance, OnUnbalanced, WithdrawReason}; +use sr_primitives::traits::{ + CheckedMul, Zero, SaturatedConversion, SimpleArithmetic, UniqueSaturatedInto, +}; +use support::{ + traits::{Currency, ExistenceRequirement, Imbalance, OnUnbalanced, WithdrawReason}, StorageValue, +}; #[cfg(test)] use std::{any::Any, fmt::Debug}; @@ -200,14 +202,6 @@ pub fn buy_gas( transactor: &T::AccountId, gas_limit: Gas, ) -> Result<(GasMeter, NegativeImbalanceOf), &'static str> { - // Check if the specified amount of gas is available in the current block. - // This cannot underflow since `gas_spent` is never greater than `T::BlockGasLimit`. - let gas_available = T::BlockGasLimit::get() - >::gas_spent(); - if gas_limit > gas_available { - // gas limit reached, revert the transaction and retry again in the future - return Err(BLOCK_FULL); - } - // Buy the specified amount of gas. let gas_price = >::gas_price(); let cost = if gas_price.is_zero() { diff --git a/srml/contracts/src/lib.rs b/srml/contracts/src/lib.rs index 9f9fae52922bfe87ab66097f43a3a66e6f55917d..918d0838c47154678a1c689affff5937ab46c389 100644 --- a/srml/contracts/src/lib.rs +++ b/srml/contracts/src/lib.rs @@ -25,14 +25,14 @@ //! //! This module extends accounts based on the `Currency` trait to have smart-contract functionality. It can //! be used with other modules that implement accounts based on `Currency`. These "smart-contract accounts" -//! have the ability to create smart-contracts and make calls to other contract and non-contract accounts. +//! have the ability to instantiate smart-contracts and make calls to other contract and non-contract accounts. //! //! The smart-contract code is stored once in a `code_cache`, and later retrievable via its `code_hash`. //! This means that multiple smart-contracts can be instantiated from the same `code_cache`, without replicating //! the code each time. //! //! When a smart-contract is called, its associated code is retrieved via the code hash and gets executed. -//! This call can alter the storage entries of the smart-contract account, create new smart-contracts, +//! This call can alter the storage entries of the smart-contract account, instantiate new smart-contracts, //! or call other smart-contracts. //! //! Finally, when an account is reaped, its associated code and storage of the smart-contract account @@ -59,14 +59,24 @@ //! ### Dispatchable functions //! //! * `put_code` - Stores the given binary Wasm code into the chain's storage and returns its `code_hash`. -//! * `create` - Deploys a new contract from the given `code_hash`, optionally transferring some balance. -//! This creates a new smart contract account and calls its contract deploy handler to initialize the contract. +//! * `instantiate` - Deploys a new contract from the given `code_hash`, optionally transferring some balance. +//! This instantiates a new smart contract account and calls its contract deploy handler to +//! initialize the contract. //! * `call` - Makes a call to an account, optionally transferring some balance. //! +//! ### Signed Extensions +//! +//! The contracts module defines the following extension: +//! +//! - [`CheckBlockGasLimit`]: Ensures that the transaction does not exceeds the block gas limit. +//! +//! The signed extension needs to be added as signed extra to the transaction type to be used in the +//! runtime. +//! //! ## Usage //! -//! The Contract module is a work in progress. The following examples show how this Contract module can be -//! used to create and call contracts. +//! The Contract module is a work in progress. The following examples show how this Contract module +//! can be used to instantiate and call contracts. //! //! * [`ink`](https://github.com/paritytech/ink) is //! an [`eDSL`](https://wiki.haskell.org/Embedded_domain_specific_language) that enables writing @@ -89,29 +99,34 @@ mod rent; #[cfg(test)] mod tests; -use crate::exec::{ExecutionContext, ExecResult}; +use crate::exec::ExecutionContext; use crate::account_db::{AccountDb, DirectAccountDb}; -pub use crate::gas::{Gas, GasMeter}; use crate::wasm::{WasmLoader, WasmVm}; +pub use crate::gas::{Gas, GasMeter}; +pub use crate::exec::{ExecResult, ExecReturnValue, ExecError, StatusCode}; + #[cfg(feature = "std")] use serde::{Serialize, Deserialize}; use primitives::crypto::UncheckedFrom; use rstd::{prelude::*, marker::PhantomData}; use codec::{Codec, Encode, Decode}; use runtime_io::blake2_256; -use sr_primitives::traits::{ - Hash, StaticLookup, Zero, MaybeSerializeDebug, Member +use sr_primitives::{ + traits::{Hash, StaticLookup, Zero, MaybeSerializeDebug, Member, SignedExtension}, + weights::DispatchInfo, + transaction_validity::{ + ValidTransaction, InvalidTransaction, TransactionValidity, TransactionValidityError, + }, }; -use srml_support::dispatch::{Result, Dispatchable}; -use srml_support::{ - Parameter, StorageMap, StorageValue, decl_module, decl_event, decl_storage, storage::child, +use support::dispatch::{Result, Dispatchable}; +use support::{ + Parameter, decl_module, decl_event, decl_storage, storage::child, parameter_types, }; -use srml_support::traits::{OnFreeBalanceZero, OnUnbalanced, Currency, Get}; +use support::{traits::{OnFreeBalanceZero, OnUnbalanced, Currency, Get, Time}, IsSubType}; use system::{ensure_signed, RawOrigin, ensure_root}; use primitives::storage::well_known_keys::CHILD_STORAGE_KEY_PREFIX; -use timestamp; pub type CodeHash = ::Hash; pub type TrieId = Vec; @@ -283,56 +298,57 @@ pub type NegativeImbalanceOf = <::Currency as Currency<::AccountId>>::NegativeImbalance; parameter_types! { - /// A resonable default value for [`Trait::SignedClaimedHandicap`]. + /// A reasonable default value for [`Trait::SignedClaimedHandicap`]. pub const DefaultSignedClaimHandicap: u32 = 2; - /// A resonable default value for [`Trait::TombstoneDeposit`]. + /// A reasonable default value for [`Trait::TombstoneDeposit`]. pub const DefaultTombstoneDeposit: u32 = 16; - /// A resonable default value for [`Trait::StorageSizeOffset`]. + /// A reasonable default value for [`Trait::StorageSizeOffset`]. pub const DefaultStorageSizeOffset: u32 = 8; - /// A resonable default value for [`Trait::RentByteFee`]. + /// A reasonable default value for [`Trait::RentByteFee`]. pub const DefaultRentByteFee: u32 = 4; - /// A resonable default value for [`Trait::RentDepositOffset`]. + /// A reasonable default value for [`Trait::RentDepositOffset`]. pub const DefaultRentDepositOffset: u32 = 1000; - /// A resonable default value for [`Trait::SurchargeReward`]. + /// A reasonable default value for [`Trait::SurchargeReward`]. pub const DefaultSurchargeReward: u32 = 150; - /// A resonable default value for [`Trait::TransferFee`]. + /// A reasonable default value for [`Trait::TransferFee`]. pub const DefaultTransferFee: u32 = 0; - /// A resonable default value for [`Trait::CreationFee`]. - pub const DefaultCreationFee: u32 = 0; - /// A resonable default value for [`Trait::TransactionBaseFee`]. + /// A reasonable default value for [`Trait::InstantiationFee`]. + pub const DefaultInstantiationFee: u32 = 0; + /// A reasonable default value for [`Trait::TransactionBaseFee`]. pub const DefaultTransactionBaseFee: u32 = 0; - /// A resonable default value for [`Trait::TransactionByteFee`]. + /// A reasonable default value for [`Trait::TransactionByteFee`]. pub const DefaultTransactionByteFee: u32 = 0; - /// A resonable default value for [`Trait::ContractFee`]. + /// A reasonable default value for [`Trait::ContractFee`]. pub const DefaultContractFee: u32 = 21; - /// A resonable default value for [`Trait::CallBaseFee`]. + /// A reasonable default value for [`Trait::CallBaseFee`]. pub const DefaultCallBaseFee: u32 = 1000; - /// A resonable default value for [`Trait::CreateBaseFee`]. - pub const DefaultCreateBaseFee: u32 = 1000; - /// A resonable default value for [`Trait::MaxDepth`]. + /// A reasonable default value for [`Trait::InstantiateBaseFee`]. + pub const DefaultInstantiateBaseFee: u32 = 1000; + /// A reasonable default value for [`Trait::MaxDepth`]. pub const DefaultMaxDepth: u32 = 1024; - /// A resonable default value for [`Trait::MaxValueSize`]. + /// A reasonable default value for [`Trait::MaxValueSize`]. pub const DefaultMaxValueSize: u32 = 16_384; - /// A resonable default value for [`Trait::BlockGasLimit`]. + /// A reasonable default value for [`Trait::BlockGasLimit`]. pub const DefaultBlockGasLimit: u32 = 10_000_000; } -pub trait Trait: timestamp::Trait { +pub trait Trait: system::Trait { type Currency: Currency; + type Time: Time; /// The outer call dispatch type. - type Call: Parameter + Dispatchable::Origin>; + type Call: Parameter + Dispatchable::Origin> + IsSubType, Self>; /// The overarching event type. type Event: From> + Into<::Event>; - /// A function type to get the contract address given the creator. + /// A function type to get the contract address given the instantiator. type DetermineContractAddress: ContractAddressFor, Self::AccountId>; /// A function type that computes the fee for dispatching the given `Call`. /// - /// It is recommended (though not required) for this function to return a fee that would be taken - /// by the Executive module for regular dispatch. + /// It is recommended (though not required) for this function to return a fee that would be + /// taken by the Executive module for regular dispatch. type ComputeDispatchFee: ComputeDispatchFee<::Call, BalanceOf>; /// trie id generator @@ -350,7 +366,7 @@ pub trait Trait: timestamp::Trait { /// The minimum amount required to generate a tombstone. type TombstoneDeposit: Get>; - /// Size of a contract at the time of creation. This is a simple way to ensure + /// Size of a contract at the time of instantiation. This is a simple way to ensure /// that empty contracts eventually gets deleted. type StorageSizeOffset: Get; @@ -382,16 +398,16 @@ pub trait Trait: timestamp::Trait { /// The fee to be paid for making a transaction; the per-byte portion. type TransactionByteFee: Get>; - /// The fee required to create a contract instance. + /// The fee required to instantiate a contract instance. type ContractFee: Get>; /// The base fee charged for calling into a contract. type CallBaseFee: Get; - /// The base fee charged for creating a contract. - type CreateBaseFee: Get; + /// The base fee charged for instantiating a contract. + type InstantiateBaseFee: Get; - /// The maximum nesting level of a call/create stack. + /// The maximum nesting level of a call/instantiate stack. type MaxDepth: Get; /// The maximum size of a storage value in bytes. @@ -425,7 +441,8 @@ where } /// The default dispatch fee computor computes the fee in the same way that -/// the implementation of `MakePayment` for the Balances module does. +/// the implementation of `TakeFees` for the Balances module does. Note that this only takes a fixed +/// fee based on size. Unlike the balances module, weight-fee is applied. pub struct DefaultDispatchFeeComputor(PhantomData); impl ComputeDispatchFee<::Call, BalanceOf> for DefaultDispatchFeeComputor { fn compute_dispatch_fee(call: &::Call) -> BalanceOf { @@ -448,8 +465,8 @@ decl_module! { /// The minimum amount required to generate a tombstone. const TombstoneDeposit: BalanceOf = T::TombstoneDeposit::get(); - /// Size of a contract at the time of creation. This is a simple way to ensure - /// that empty contracts eventually gets deleted. + /// Size of a contract at the time of instantiaion. This is a simple way to ensure that + /// empty contracts eventually gets deleted. const StorageSizeOffset: u32 = T::StorageSizeOffset::get(); /// Price of a byte of storage per one block interval. Should be greater than 0. @@ -480,7 +497,7 @@ decl_module! { /// The fee to be paid for making a transaction; the per-byte portion. const TransactionByteFee: BalanceOf = T::TransactionByteFee::get(); - /// The fee required to create a contract instance. A reasonable default value + /// The fee required to instantiate a contract instance. A reasonable default value /// is 21. const ContractFee: BalanceOf = T::ContractFee::get(); @@ -488,11 +505,11 @@ decl_module! { /// value is 135. const CallBaseFee: Gas = T::CallBaseFee::get(); - /// The base fee charged for creating a contract. A reasonable default value + /// The base fee charged for instantiating a contract. A reasonable default value /// is 175. - const CreateBaseFee: Gas = T::CreateBaseFee::get(); + const InstantiateBaseFee: Gas = T::InstantiateBaseFee::get(); - /// The maximum nesting level of a call/create stack. A reasonable default + /// The maximum nesting level of a call/instantiate stack. A reasonable default /// value is 100. const MaxDepth: u32 = T::MaxDepth::get(); @@ -503,7 +520,7 @@ decl_module! { /// default value is 10_000_000. const BlockGasLimit: Gas = T::BlockGasLimit::get(); - fn deposit_event() = default; + fn deposit_event() = default; /// Updates the schedule for metering contracts. /// @@ -559,14 +576,14 @@ decl_module! { let origin = ensure_signed(origin)?; let dest = T::Lookup::lookup(dest)?; - Self::execute_wasm(origin, gas_limit, |ctx, gas_meter| { - ctx.call(dest, value, gas_meter, data) - }) + Self::bare_call(origin, dest, value, gas_limit, data) + .map(|_| ()) + .map_err(|e| e.reason) } - /// Creates a new contract from the `codehash` generated by `put_code`, optionally transferring some balance. + /// Instantiates a new contract from the `codehash` generated by `put_code`, optionally transferring some balance. /// - /// Creation is executed as follows: + /// Instantiation is executed as follows: /// /// - The destination address is computed based on the sender and hash of the code. /// - The smart-contract account is created at the computed address. @@ -574,7 +591,7 @@ decl_module! { /// after the execution is saved as the `code` of the account. That code will be invoked /// upon any call received by this account. /// - The contract is initialized. - pub fn create( + pub fn instantiate( origin, #[compact] endowment: BalanceOf, #[compact] gas_limit: Gas, @@ -587,6 +604,8 @@ decl_module! { ctx.instantiate(endowment, gas_meter, &code_hash, data) .map(|(_address, output)| output) }) + .map(|_| ()) + .map_err(|e| e.reason) } /// Allows block producers to claim a small reward for evicting a contract. If a block producer @@ -596,15 +615,17 @@ decl_module! { /// the sender is not eligible for the reward. fn claim_surcharge(origin, dest: T::AccountId, aux_sender: Option) { let origin = origin.into(); - let (signed, rewarded) = match origin { - Ok(system::RawOrigin::Signed(ref account)) if aux_sender.is_none() => { + let (signed, rewarded) = match (origin, aux_sender) { + (Ok(system::RawOrigin::Signed(account)), None) => { (true, account) }, - Ok(system::RawOrigin::None) if aux_sender.is_some() => { - (false, aux_sender.as_ref().expect("checked above")) + (Ok(system::RawOrigin::None), Some(aux_sender)) => { + (false, aux_sender) }, - _ => return Err("Invalid surcharge claim: origin must be signed or \ - inherent and auxiliary sender only provided on inherent") + _ => return Err( + "Invalid surcharge claim: origin must be signed or \ + inherent and auxiliary sender only provided on inherent" + ), }; // Add some advantage for block producers (who send unsigned extrinsics) by @@ -618,7 +639,7 @@ decl_module! { // If poking the contract has lead to eviction of the contract, give out the rewards. if rent::try_evict::(&dest, handicap) == rent::RentOutcome::Evicted { - T::Currency::deposit_into_existing(rewarded, T::SurchargeReward::get())?; + T::Currency::deposit_into_existing(&rewarded, T::SurchargeReward::get())?; } } @@ -629,16 +650,37 @@ decl_module! { } impl Module { + /// Perform a call to a specified contract. + /// + /// This function is similar to `Self::call`, but doesn't perform any lookups and better + /// suitable for calling directly from Rust. + pub fn bare_call( + origin: T::AccountId, + dest: T::AccountId, + value: BalanceOf, + gas_limit: Gas, + input_data: Vec, + ) -> ExecResult { + Self::execute_wasm(origin, gas_limit, |ctx, gas_meter| { + ctx.call(dest, value, gas_meter, input_data) + }) + } + fn execute_wasm( origin: T::AccountId, gas_limit: Gas, func: impl FnOnce(&mut ExecutionContext, &mut GasMeter) -> ExecResult - ) -> Result { + ) -> ExecResult { // Pay for the gas upfront. // // NOTE: it is very important to avoid any state changes before // paying for the gas. - let (mut gas_meter, imbalance) = gas::buy_gas::(&origin, gas_limit)?; + let (mut gas_meter, imbalance) = + try_or_exec_error!( + gas::buy_gas::(&origin, gas_limit), + // We don't have a spare buffer here in the first place, so create a new empty one. + Vec::new() + ); let cfg = Config::preload(); let vm = WasmVm::new(&cfg.schedule); @@ -689,8 +731,6 @@ impl Module { }); result - .map(|_| ()) - .map_err(|e| e.reason) } fn restore_to( @@ -773,7 +813,7 @@ decl_event! { ::AccountId, ::Hash { - /// Transfer happened `from` to `to` with given `value` as part of a `call` or `create`. + /// Transfer happened `from` to `to` with given `value` as part of a `call` or `instantiate`. Transfer(AccountId, AccountId, Balance), /// Contract deployed by address at the specified address. @@ -936,3 +976,62 @@ impl Default for Schedule { } } } + +/// `SignedExtension` that checks if a transaction would exhausts the block gas limit. +#[derive(Encode, Decode, Clone, Eq, PartialEq)] +pub struct CheckBlockGasLimit(PhantomData); + +impl Default for CheckBlockGasLimit { + fn default() -> Self { + Self(PhantomData) + } +} + +#[cfg(feature = "std")] +impl std::fmt::Debug for CheckBlockGasLimit { + fn fmt(&self, _: &mut std::fmt::Formatter) -> std::fmt::Result { + Ok(()) + } +} + +impl SignedExtension for CheckBlockGasLimit { + type AccountId = T::AccountId; + type Call = ::Call; + type AdditionalSigned = (); + type Pre = (); + + fn additional_signed(&self) -> rstd::result::Result<(), TransactionValidityError> { Ok(()) } + + fn validate( + &self, + _: &Self::AccountId, + call: &Self::Call, + _: DispatchInfo, + _: usize, + ) -> TransactionValidity { + let call = match call.is_sub_type() { + Some(call) => call, + None => return Ok(ValidTransaction::default()), + }; + + match call { + Call::claim_surcharge(_, _) | Call::update_schedule(_) => + Ok(ValidTransaction::default()), + Call::put_code(gas_limit, _) + | Call::call(_, _, gas_limit, _) + | Call::instantiate(_, gas_limit, _, _) + => { + // Check if the specified amount of gas is available in the current block. + // This cannot underflow since `gas_spent` is never greater than `T::BlockGasLimit`. + let gas_available = T::BlockGasLimit::get() - >::gas_spent(); + if *gas_limit > gas_available { + // gas limit reached, revert the transaction and retry again in the future + InvalidTransaction::ExhaustsResources.into() + } else { + Ok(ValidTransaction::default()) + } + }, + Call::__PhantomItem(_, _) => unreachable!("Variant is never constructed"), + } + } +} diff --git a/srml/contracts/src/rent.rs b/srml/contracts/src/rent.rs index fea6cdc7f3969577c3e77fc342f6fe3806868eca..776f804ee7cac094634c96636dceee01a6bc47c1 100644 --- a/srml/contracts/src/rent.rs +++ b/srml/contracts/src/rent.rs @@ -17,8 +17,8 @@ use crate::{BalanceOf, ContractInfo, ContractInfoOf, TombstoneContractInfo, Trait, AliveContractInfo}; use sr_primitives::traits::{Bounded, CheckedDiv, CheckedMul, Saturating, Zero, SaturatedConversion}; -use srml_support::traits::{Currency, ExistenceRequirement, Get, WithdrawReason}; -use srml_support::StorageMap; +use support::traits::{Currency, ExistenceRequirement, Get, WithdrawReason}; +use support::StorageMap; #[derive(PartialEq, Eq, Copy, Clone)] #[must_use] diff --git a/srml/contracts/src/tests.rs b/srml/contracts/src/tests.rs index 224d01d48aa2fbb283cc44eff72ed058f4422a42..f2ef8a275d66bc4263ab7102958a85bdb263a63a 100644 --- a/srml/contracts/src/tests.rs +++ b/srml/contracts/src/tests.rs @@ -22,34 +22,34 @@ use crate::account_db::{AccountDb, DirectAccountDb, OverlayAccountDb}; use crate::{ BalanceOf, ComputeDispatchFee, ContractAddressFor, ContractInfo, ContractInfoOf, GenesisConfig, - Module, RawAliveContractInfo, RawEvent, Trait, TrieId, TrieIdFromParentCounter, - TrieIdGenerator, Schedule, + Module, RawAliveContractInfo, RawEvent, Trait, TrieId, TrieIdFromParentCounter, Schedule, + TrieIdGenerator, CheckBlockGasLimit, }; use assert_matches::assert_matches; use hex_literal::*; use codec::{Decode, Encode, KeyedVec}; use runtime_io; use runtime_io::with_externalities; -use sr_primitives::testing::{Digest, DigestItem, Header, UintAuthorityId, H256}; -use sr_primitives::traits::{BlakeTwo256, Hash, IdentityLookup}; -use sr_primitives::{Perbill, BuildStorage}; -use srml_support::{ +use sr_primitives::{ + Perbill, BuildStorage, transaction_validity::{InvalidTransaction, ValidTransaction}, + traits::{BlakeTwo256, Hash, IdentityLookup, SignedExtension}, + weights::{DispatchInfo, DispatchClass}, + testing::{Digest, DigestItem, Header, UintAuthorityId, H256}, +}; +use support::{ assert_ok, assert_err, impl_outer_dispatch, impl_outer_event, impl_outer_origin, parameter_types, storage::child, StorageMap, StorageValue, traits::{Currency, Get}, }; -use std::cell::RefCell; -use std::sync::atomic::{AtomicUsize, Ordering}; -use primitives::storage::well_known_keys; -use primitives::Blake2Hasher; +use std::{cell::RefCell, sync::atomic::{AtomicUsize, Ordering}}; +use primitives::{storage::well_known_keys, Blake2Hasher}; use system::{self, EventRecord, Phase}; -use {balances, wabt}; mod contract { // Re-export contents of the root. This basically // needs to give a name for the current crate. // This hack is required for `impl_outer_event!`. pub use super::super::*; - use srml_support::impl_outer_event; + use support::impl_outer_event; } impl_outer_event! { pub enum MetaEvent for Test { @@ -69,7 +69,7 @@ impl_outer_dispatch! { thread_local! { static EXISTENTIAL_DEPOSIT: RefCell = RefCell::new(0); static TRANSFER_FEE: RefCell = RefCell::new(0); - static CREATION_FEE: RefCell = RefCell::new(0); + static INSTANTIATION_FEE: RefCell = RefCell::new(0); static BLOCK_GAS_LIMIT: RefCell = RefCell::new(0); } @@ -85,7 +85,7 @@ impl Get for TransferFee { pub struct CreationFee; impl Get for CreationFee { - fn get() -> u64 { CREATION_FEE.with(|v| *v.borrow()) } + fn get() -> u64 { INSTANTIATION_FEE.with(|v| *v.borrow()) } } pub struct BlockGasLimit; @@ -119,6 +119,7 @@ impl system::Trait for Test { type MaximumBlockWeight = MaximumBlockWeight; type AvailableBlockRatio = AvailableBlockRatio; type MaximumBlockLength = MaximumBlockLength; + type Version = (); } impl balances::Trait for Test { type Balance = u64; @@ -154,12 +155,13 @@ parameter_types! { pub const TransactionByteFee: u64 = 6; pub const ContractFee: u64 = 21; pub const CallBaseFee: u64 = 135; - pub const CreateBaseFee: u64 = 175; + pub const InstantiateBaseFee: u64 = 175; pub const MaxDepth: u32 = 100; pub const MaxValueSize: u32 = 16_384; } impl Trait for Test { type Currency = Balances; + type Time = Timestamp; type Call = Call; type DetermineContractAddress = DummyContractAddressFor; type Event = MetaEvent; @@ -178,13 +180,14 @@ impl Trait for Test { type TransactionByteFee = TransactionByteFee; type ContractFee = ContractFee; type CallBaseFee = CallBaseFee; - type CreateBaseFee = CreateBaseFee; + type InstantiateBaseFee = InstantiateBaseFee; type MaxDepth = MaxDepth; type MaxValueSize = MaxValueSize; type BlockGasLimit = BlockGasLimit; } type Balances = balances::Module; +type Timestamp = timestamp::Module; type Contract = Module; type System = system::Module; @@ -232,7 +235,7 @@ pub struct ExtBuilder { gas_price: u64, block_gas_limit: u64, transfer_fee: u64, - creation_fee: u64, + instantiation_fee: u64, } impl Default for ExtBuilder { fn default() -> Self { @@ -241,7 +244,7 @@ impl Default for ExtBuilder { gas_price: 2, block_gas_limit: 100_000_000, transfer_fee: 0, - creation_fee: 0, + instantiation_fee: 0, } } } @@ -262,14 +265,14 @@ impl ExtBuilder { self.transfer_fee = transfer_fee; self } - pub fn creation_fee(mut self, creation_fee: u64) -> Self { - self.creation_fee = creation_fee; + pub fn instantiation_fee(mut self, instantiation_fee: u64) -> Self { + self.instantiation_fee = instantiation_fee; self } pub fn set_associated_consts(&self) { EXISTENTIAL_DEPOSIT.with(|v| *v.borrow_mut() = self.existential_deposit); TRANSFER_FEE.with(|v| *v.borrow_mut() = self.transfer_fee); - CREATION_FEE.with(|v| *v.borrow_mut() = self.creation_fee); + INSTANTIATION_FEE.with(|v| *v.borrow_mut() = self.instantiation_fee); BLOCK_GAS_LIMIT.with(|v| *v.borrow_mut() = self.block_gas_limit); } pub fn build(self) -> runtime_io::TestExternalities { @@ -424,7 +427,7 @@ fn instantiate_and_call_and_deposit_event() { assert_ok!(Contract::put_code(Origin::signed(ALICE), 100_000, wasm)); // Check at the end to get hash on error easily - let creation = Contract::create( + let creation = Contract::instantiate( Origin::signed(ALICE), 100, 100_000, @@ -521,7 +524,7 @@ fn dispatch_call() { }, ]); - assert_ok!(Contract::create( + assert_ok!(Contract::instantiate( Origin::signed(ALICE), 100, 100_000, @@ -642,7 +645,7 @@ fn dispatch_call_not_dispatched_after_top_level_transaction_failure() { }, ]); - assert_ok!(Contract::create( + assert_ok!(Contract::instantiate( Origin::signed(ALICE), 100, 100_000, @@ -650,7 +653,7 @@ fn dispatch_call_not_dispatched_after_top_level_transaction_failure() { vec![], )); - // Call the newly created contract. The contract is expected to dispatch a call + // Call the newly instantiated contract. The contract is expected to dispatch a call // and then trap. assert_err!( Contract::call( @@ -858,7 +861,7 @@ fn storage_size() { // Create Balances::deposit_creating(&ALICE, 1_000_000); assert_ok!(Contract::put_code(Origin::signed(ALICE), 100_000, wasm)); - assert_ok!(Contract::create( + assert_ok!(Contract::instantiate( Origin::signed(ALICE), 30_000, 100_000, code_hash.into(), @@ -888,7 +891,7 @@ fn deduct_blocks() { // Create Balances::deposit_creating(&ALICE, 1_000_000); assert_ok!(Contract::put_code(Origin::signed(ALICE), 100_000, wasm)); - assert_ok!(Contract::create( + assert_ok!(Contract::instantiate( Origin::signed(ALICE), 30_000, 100_000, code_hash.into(), @@ -985,7 +988,7 @@ fn claim_surcharge(blocks: u64, trigger_call: impl Fn() -> bool, removes: bool) // Create Balances::deposit_creating(&ALICE, 1_000_000); assert_ok!(Contract::put_code(Origin::signed(ALICE), 100_000, wasm)); - assert_ok!(Contract::create( + assert_ok!(Contract::instantiate( Origin::signed(ALICE), 100, 100_000, code_hash.into(), @@ -1021,7 +1024,7 @@ fn removals(trigger_call: impl Fn() -> bool) { // Create Balances::deposit_creating(&ALICE, 1_000_000); assert_ok!(Contract::put_code(Origin::signed(ALICE), 100_000, wasm.clone())); - assert_ok!(Contract::create( + assert_ok!(Contract::instantiate( Origin::signed(ALICE), 100, 100_000, code_hash.into(), @@ -1060,7 +1063,7 @@ fn removals(trigger_call: impl Fn() -> bool) { // Create Balances::deposit_creating(&ALICE, 1_000_000); assert_ok!(Contract::put_code(Origin::signed(ALICE), 100_000, wasm.clone())); - assert_ok!(Contract::create( + assert_ok!(Contract::instantiate( Origin::signed(ALICE), 1_000, 100_000, code_hash.into(), @@ -1098,7 +1101,7 @@ fn removals(trigger_call: impl Fn() -> bool) { // Create Balances::deposit_creating(&ALICE, 1_000_000); assert_ok!(Contract::put_code(Origin::signed(ALICE), 100_000, wasm.clone())); - assert_ok!(Contract::create( + assert_ok!(Contract::instantiate( Origin::signed(ALICE), 50+Balances::minimum_balance(), 100_000, code_hash.into(), @@ -1145,7 +1148,7 @@ fn call_removed_contract() { // Create Balances::deposit_creating(&ALICE, 1_000_000); assert_ok!(Contract::put_code(Origin::signed(ALICE), 100_000, wasm.clone())); - assert_ok!(Contract::create( + assert_ok!(Contract::instantiate( Origin::signed(ALICE), 100, 100_000, code_hash.into(), @@ -1224,7 +1227,7 @@ const CODE_CHECK_DEFAULT_RENT_ALLOWANCE: &str = r#" "#; #[test] -fn default_rent_allowance_on_create() { +fn default_rent_allowance_on_instantiate() { let (wasm, code_hash) = compile_module::(CODE_CHECK_DEFAULT_RENT_ALLOWANCE).unwrap(); with_externalities( @@ -1233,7 +1236,7 @@ fn default_rent_allowance_on_create() { // Create Balances::deposit_creating(&ALICE, 1_000_000); assert_ok!(Contract::put_code(Origin::signed(ALICE), 100_000, wasm)); - assert_ok!(Contract::create( + assert_ok!(Contract::instantiate( Origin::signed(ALICE), 30_000, 100_000, @@ -1373,7 +1376,7 @@ fn restoration(test_different_storage: bool, test_restore_to_with_dirty_storage: // Create an account with address `BOB` with code `CODE_SET_RENT`. // The input parameter sets the rent allowance to 0. - assert_ok!(Contract::create( + assert_ok!(Contract::instantiate( Origin::signed(ALICE), 30_000, 100_000, @@ -1410,7 +1413,7 @@ fn restoration(test_different_storage: bool, test_restore_to_with_dirty_storage: /// Note that we can't use `ALICE` for creating `DJANGO` so we create yet another /// account `CHARLIE` and create `DJANGO` with it. Balances::deposit_creating(&CHARLIE, 1_000_000); - assert_ok!(Contract::create( + assert_ok!(Contract::instantiate( Origin::signed(CHARLIE), 30_000, 100_000, @@ -1536,7 +1539,7 @@ fn storage_max_value_limit() { // Create Balances::deposit_creating(&ALICE, 1_000_000); assert_ok!(Contract::put_code(Origin::signed(ALICE), 100_000, wasm)); - assert_ok!(Contract::create( + assert_ok!(Contract::instantiate( Origin::signed(ALICE), 30_000, 100_000, @@ -1601,7 +1604,7 @@ const CODE_RETURN_WITH_DATA: &str = r#" ;; Copy all but the first 4 bytes of the input data as the output data. (call $ext_scratch_write - (i32.const 4) ;; Offset from the start of the scratch buffer. + (i32.const 4) ;; Pointer to the data to return. (i32.sub ;; Count of bytes to copy. (get_local $buf_size) (i32.const 4) @@ -1620,7 +1623,7 @@ const CODE_CALLER_CONTRACT: &str = r#" (import "env" "ext_scratch_read" (func $ext_scratch_read (param i32 i32 i32))) (import "env" "ext_balance" (func $ext_balance)) (import "env" "ext_call" (func $ext_call (param i32 i32 i64 i32 i32 i32 i32) (result i32))) - (import "env" "ext_create" (func $ext_create (param i32 i32 i64 i32 i32 i32 i32) (result i32))) + (import "env" "ext_instantiate" (func $ext_instantiate (param i32 i32 i64 i32 i32 i32 i32) (result i32))) (import "env" "ext_println" (func $ext_println (param i32 i32))) (import "env" "memory" (memory 1 1)) @@ -1676,7 +1679,7 @@ const CODE_CALLER_CONTRACT: &str = r#" ;; Fail to deploy the contract since it returns a non-zero exit status. (set_local $exit_code - (call $ext_create + (call $ext_instantiate (i32.const 24) ;; Pointer to the code hash. (i32.const 32) ;; Length of the code hash. (i64.const 0) ;; How much gas to devote for the execution. 0 = all. @@ -1704,7 +1707,7 @@ const CODE_CALLER_CONTRACT: &str = r#" ;; Fail to deploy the contract due to insufficient gas. (set_local $exit_code - (call $ext_create + (call $ext_instantiate (i32.const 24) ;; Pointer to the code hash. (i32.const 32) ;; Length of the code hash. (i64.const 200) ;; How much gas to devote for the execution. @@ -1732,7 +1735,7 @@ const CODE_CALLER_CONTRACT: &str = r#" ;; Deploy the contract successfully. (set_local $exit_code - (call $ext_create + (call $ext_instantiate (i32.const 24) ;; Pointer to the code hash. (i32.const 32) ;; Length of the code hash. (i64.const 0) ;; How much gas to devote for the execution. 0 = all. @@ -1905,7 +1908,7 @@ fn deploy_and_call_other_contract() { assert_ok!(Contract::put_code(Origin::signed(ALICE), 100_000, callee_wasm)); assert_ok!(Contract::put_code(Origin::signed(ALICE), 100_000, caller_wasm)); - assert_ok!(Contract::create( + assert_ok!(Contract::instantiate( Origin::signed(ALICE), 100_000, 100_000, @@ -1925,3 +1928,486 @@ fn deploy_and_call_other_contract() { } ); } + +const CODE_SELF_DESTRUCT: &str = r#" +(module + (import "env" "ext_scratch_size" (func $ext_scratch_size (result i32))) + (import "env" "ext_scratch_read" (func $ext_scratch_read (param i32 i32 i32))) + (import "env" "ext_address" (func $ext_address)) + (import "env" "ext_balance" (func $ext_balance)) + (import "env" "ext_call" (func $ext_call (param i32 i32 i64 i32 i32 i32 i32) (result i32))) + (import "env" "memory" (memory 1 1)) + + (func $assert (param i32) + (block $ok + (br_if $ok + (get_local 0) + ) + (unreachable) + ) + ) + + (func (export "deploy")) + + (func (export "call") + ;; If the input data is not empty, then recursively call self with empty input data. + ;; This should trap instead of self-destructing since a contract cannot be removed live in + ;; the execution stack cannot be removed. If the recursive call traps, then trap here as + ;; well. + (if (call $ext_scratch_size) + (then + (call $ext_address) + + ;; Expect address to be 8 bytes. + (call $assert + (i32.eq + (call $ext_scratch_size) + (i32.const 8) + ) + ) + + ;; Read own address into memory. + (call $ext_scratch_read + (i32.const 16) ;; Pointer to write address to + (i32.const 0) ;; Offset into scrach buffer + (i32.const 8) ;; Length of encoded address + ) + + ;; Recursively call self with empty imput data. + (call $assert + (i32.eq + (call $ext_call + (i32.const 16) ;; Pointer to own address + (i32.const 8) ;; Length of own address + (i64.const 0) ;; How much gas to devote for the execution. 0 = all. + (i32.const 8) ;; Pointer to the buffer with value to transfer + (i32.const 8) ;; Length of the buffer with value to transfer + (i32.const 0) ;; Pointer to input data buffer address + (i32.const 0) ;; Length of input data buffer + ) + (i32.const 0) + ) + ) + ) + ) + + ;; Send entire remaining balance to the 0 address. + (call $ext_balance) + + ;; Balance should be encoded as a u64. + (call $assert + (i32.eq + (call $ext_scratch_size) + (i32.const 8) + ) + ) + + ;; Read balance into memory. + (call $ext_scratch_read + (i32.const 8) ;; Pointer to write balance to + (i32.const 0) ;; Offset into scrach buffer + (i32.const 8) ;; Length of encoded balance + ) + + ;; Self-destruct by sending full balance to the 0 address. + (call $assert + (i32.eq + (call $ext_call + (i32.const 0) ;; Pointer to destination address + (i32.const 8) ;; Length of destination address + (i64.const 0) ;; How much gas to devote for the execution. 0 = all. + (i32.const 8) ;; Pointer to the buffer with value to transfer + (i32.const 8) ;; Length of the buffer with value to transfer + (i32.const 0) ;; Pointer to input data buffer address + (i32.const 0) ;; Length of input data buffer + ) + (i32.const 0) + ) + ) + ) +) +"#; + +#[test] +fn self_destruct_by_draining_balance() { + let (wasm, code_hash) = compile_module::(CODE_SELF_DESTRUCT).unwrap(); + with_externalities( + &mut ExtBuilder::default().existential_deposit(50).build(), + || { + Balances::deposit_creating(&ALICE, 1_000_000); + assert_ok!(Contract::put_code(Origin::signed(ALICE), 100_000, wasm)); + + // Instantiate the BOB contract. + assert_ok!(Contract::instantiate( + Origin::signed(ALICE), + 100_000, + 100_000, + code_hash.into(), + vec![], + )); + + // Check that the BOB contract has been instantiated. + assert_matches!( + ContractInfoOf::::get(BOB), + Some(ContractInfo::Alive(_)) + ); + + // Call BOB with no input data, forcing it to self-destruct. + assert_ok!(Contract::call( + Origin::signed(ALICE), + BOB, + 0, + 100_000, + vec![], + )); + + // Check that BOB is now dead. + assert!(ContractInfoOf::::get(BOB).is_none()); + } + ); +} + +#[test] +fn cannot_self_destruct_while_live() { + let (wasm, code_hash) = compile_module::(CODE_SELF_DESTRUCT).unwrap(); + with_externalities( + &mut ExtBuilder::default().existential_deposit(50).build(), + || { + Balances::deposit_creating(&ALICE, 1_000_000); + assert_ok!(Contract::put_code(Origin::signed(ALICE), 100_000, wasm)); + + // Instantiate the BOB contract. + assert_ok!(Contract::instantiate( + Origin::signed(ALICE), + 100_000, + 100_000, + code_hash.into(), + vec![], + )); + + // Check that the BOB contract has been instantiated. + assert_matches!( + ContractInfoOf::::get(BOB), + Some(ContractInfo::Alive(_)) + ); + + // Call BOB with input data, forcing it make a recursive call to itself to + // self-destruct, resulting in a trap. + assert_err!( + Contract::call( + Origin::signed(ALICE), + BOB, + 0, + 100_000, + vec![0], + ), + "during execution" + ); + + // Check that BOB is still alive. + assert_matches!( + ContractInfoOf::::get(BOB), + Some(ContractInfo::Alive(_)) + ); + } + ); +} + +const CODE_DESTROY_AND_TRANSFER: &str = r#" +(module + (import "env" "ext_scratch_size" (func $ext_scratch_size (result i32))) + (import "env" "ext_scratch_read" (func $ext_scratch_read (param i32 i32 i32))) + (import "env" "ext_get_storage" (func $ext_get_storage (param i32) (result i32))) + (import "env" "ext_set_storage" (func $ext_set_storage (param i32 i32 i32 i32))) + (import "env" "ext_call" (func $ext_call (param i32 i32 i64 i32 i32 i32 i32) (result i32))) + (import "env" "ext_instantiate" (func $ext_instantiate (param i32 i32 i64 i32 i32 i32 i32) (result i32))) + (import "env" "memory" (memory 1 1)) + + (func $assert (param i32) + (block $ok + (br_if $ok + (get_local 0) + ) + (unreachable) + ) + ) + + (func (export "deploy") + ;; Input data is the code hash of the contract to be deployed. + (call $assert + (i32.eq + (call $ext_scratch_size) + (i32.const 32) + ) + ) + + ;; Copy code hash from scratch buffer into this contract's memory. + (call $ext_scratch_read + (i32.const 48) ;; The pointer where to store the scratch buffer contents, + (i32.const 0) ;; Offset from the start of the scratch buffer. + (i32.const 32) ;; Count of bytes to copy. + ) + + ;; Deploy the contract with the provided code hash. + (call $assert + (i32.eq + (call $ext_instantiate + (i32.const 48) ;; Pointer to the code hash. + (i32.const 32) ;; Length of the code hash. + (i64.const 0) ;; How much gas to devote for the execution. 0 = all. + (i32.const 0) ;; Pointer to the buffer with value to transfer + (i32.const 8) ;; Length of the buffer with value to transfer. + (i32.const 0) ;; Pointer to input data buffer address + (i32.const 0) ;; Length of input data buffer + ) + (i32.const 0) + ) + ) + + ;; Read the address of the instantiated contract into memory. + (call $assert + (i32.eq + (call $ext_scratch_size) + (i32.const 8) + ) + ) + (call $ext_scratch_read + (i32.const 80) ;; The pointer where to store the scratch buffer contents, + (i32.const 0) ;; Offset from the start of the scratch buffer. + (i32.const 8) ;; Count of bytes to copy. + ) + + ;; Store the return address. + (call $ext_set_storage + (i32.const 16) ;; Pointer to the key + (i32.const 1) ;; Value is not null + (i32.const 80) ;; Pointer to the value + (i32.const 8) ;; Length of the value + ) + ) + + (func (export "call") + ;; Read address of destination contract from storage. + (call $assert + (i32.eq + (call $ext_get_storage + (i32.const 16) ;; Pointer to the key + ) + (i32.const 0) + ) + ) + (call $assert + (i32.eq + (call $ext_scratch_size) + (i32.const 8) + ) + ) + (call $ext_scratch_read + (i32.const 80) ;; The pointer where to store the contract address. + (i32.const 0) ;; Offset from the start of the scratch buffer. + (i32.const 8) ;; Count of bytes to copy. + ) + + ;; Calling the destination contract with non-empty input data should fail. + (call $assert + (i32.eq + (call $ext_call + (i32.const 80) ;; Pointer to destination address + (i32.const 8) ;; Length of destination address + (i64.const 0) ;; How much gas to devote for the execution. 0 = all. + (i32.const 0) ;; Pointer to the buffer with value to transfer + (i32.const 8) ;; Length of the buffer with value to transfer + (i32.const 0) ;; Pointer to input data buffer address + (i32.const 1) ;; Length of input data buffer + ) + (i32.const 0x0100) + ) + ) + + ;; Call the destination contract regularly, forcing it to self-destruct. + (call $assert + (i32.eq + (call $ext_call + (i32.const 80) ;; Pointer to destination address + (i32.const 8) ;; Length of destination address + (i64.const 0) ;; How much gas to devote for the execution. 0 = all. + (i32.const 8) ;; Pointer to the buffer with value to transfer + (i32.const 8) ;; Length of the buffer with value to transfer + (i32.const 0) ;; Pointer to input data buffer address + (i32.const 0) ;; Length of input data buffer + ) + (i32.const 0) + ) + ) + + ;; Calling the destination address with non-empty input data should now work since the + ;; contract has been removed. Also transfer a balance to the address so we can ensure this + ;; does not keep the contract alive. + (call $assert + (i32.eq + (call $ext_call + (i32.const 80) ;; Pointer to destination address + (i32.const 8) ;; Length of destination address + (i64.const 0) ;; How much gas to devote for the execution. 0 = all. + (i32.const 0) ;; Pointer to the buffer with value to transfer + (i32.const 8) ;; Length of the buffer with value to transfer + (i32.const 0) ;; Pointer to input data buffer address + (i32.const 1) ;; Length of input data buffer + ) + (i32.const 0) + ) + ) + ) + + (data (i32.const 0) "\00\00\01") ;; Endowment to send when creating contract. + (data (i32.const 8) "") ;; Value to send when calling contract. + (data (i32.const 16) "") ;; The key to store the contract address under. +) +"#; + +// This tests that one contract cannot prevent another from self-destructing by sending it +// additional funds after it has been drained. +#[test] +fn destroy_contract_and_transfer_funds() { + let (callee_wasm, callee_code_hash) = compile_module::(CODE_SELF_DESTRUCT).unwrap(); + let (caller_wasm, caller_code_hash) = compile_module::(CODE_DESTROY_AND_TRANSFER).unwrap(); + + with_externalities( + &mut ExtBuilder::default().existential_deposit(50).build(), + || { + // Create + Balances::deposit_creating(&ALICE, 1_000_000); + assert_ok!(Contract::put_code(Origin::signed(ALICE), 100_000, callee_wasm)); + assert_ok!(Contract::put_code(Origin::signed(ALICE), 100_000, caller_wasm)); + + // This deploys the BOB contract, which in turn deploys the CHARLIE contract during + // construction. + assert_ok!(Contract::instantiate( + Origin::signed(ALICE), + 200_000, + 100_000, + caller_code_hash.into(), + callee_code_hash.as_ref().to_vec(), + )); + + // Check that the CHARLIE contract has been instantiated. + assert_matches!( + ContractInfoOf::::get(CHARLIE), + Some(ContractInfo::Alive(_)) + ); + + // Call BOB, which calls CHARLIE, forcing CHARLIE to self-destruct. + assert_ok!(Contract::call( + Origin::signed(ALICE), + BOB, + 0, + 100_000, + CHARLIE.encode(), + )); + + // Check that CHARLIE has moved on to the great beyond (ie. died). + assert!(ContractInfoOf::::get(CHARLIE).is_none()); + } + ); +} + +const CODE_SELF_DESTRUCTING_CONSTRUCTOR: &str = r#" +(module + (import "env" "ext_scratch_size" (func $ext_scratch_size (result i32))) + (import "env" "ext_scratch_read" (func $ext_scratch_read (param i32 i32 i32))) + (import "env" "ext_balance" (func $ext_balance)) + (import "env" "ext_call" (func $ext_call (param i32 i32 i64 i32 i32 i32 i32) (result i32))) + (import "env" "memory" (memory 1 1)) + + (func $assert (param i32) + (block $ok + (br_if $ok + (get_local 0) + ) + (unreachable) + ) + ) + + (func (export "deploy") + ;; Send entire remaining balance to the 0 address. + (call $ext_balance) + + ;; Balance should be encoded as a u64. + (call $assert + (i32.eq + (call $ext_scratch_size) + (i32.const 8) + ) + ) + + ;; Read balance into memory. + (call $ext_scratch_read + (i32.const 8) ;; Pointer to write balance to + (i32.const 0) ;; Offset into scrach buffer + (i32.const 8) ;; Length of encoded balance + ) + + ;; Self-destruct by sending full balance to the 0 address. + (call $assert + (i32.eq + (call $ext_call + (i32.const 0) ;; Pointer to destination address + (i32.const 8) ;; Length of destination address + (i64.const 0) ;; How much gas to devote for the execution. 0 = all. + (i32.const 8) ;; Pointer to the buffer with value to transfer + (i32.const 8) ;; Length of the buffer with value to transfer + (i32.const 0) ;; Pointer to input data buffer address + (i32.const 0) ;; Length of input data buffer + ) + (i32.const 0) + ) + ) + ) + + (func (export "call")) +) +"#; + +#[test] +fn cannot_self_destruct_in_constructor() { + let (wasm, code_hash) = compile_module::(CODE_SELF_DESTRUCTING_CONSTRUCTOR).unwrap(); + with_externalities( + &mut ExtBuilder::default().existential_deposit(50).build(), + || { + Balances::deposit_creating(&ALICE, 1_000_000); + assert_ok!(Contract::put_code(Origin::signed(ALICE), 100_000, wasm)); + + // Fail to instantiate the BOB contract since its final balance is below existential + // deposit. + assert_err!( + Contract::instantiate( + Origin::signed(ALICE), + 100_000, + 100_000, + code_hash.into(), + vec![], + ), + "insufficient remaining balance" + ); + } + ); +} + +#[test] +fn check_block_gas_limit_works() { + with_externalities( + &mut ExtBuilder::default().block_gas_limit(50).build(), + || { + let info = DispatchInfo { weight: 100, class: DispatchClass::Normal }; + let check = CheckBlockGasLimit::(Default::default()); + let call: Call = crate::Call::put_code(1000, vec![]).into(); + + assert_eq!( + check.validate(&0, &call, info, 0), InvalidTransaction::ExhaustsResources.into(), + ); + + let call: Call = crate::Call::update_schedule(Default::default()).into(); + assert_eq!(check.validate(&0, &call, info, 0), Ok(Default::default())); + } + ); +} diff --git a/srml/contracts/src/wasm/code_cache.rs b/srml/contracts/src/wasm/code_cache.rs index 9e8fcab8c257315f1f64abd815be92987279cc5b..e6702d29cf5c71b1fbfa8d1a0026cefc6c48a86e 100644 --- a/srml/contracts/src/wasm/code_cache.rs +++ b/srml/contracts/src/wasm/code_cache.rs @@ -31,7 +31,7 @@ use crate::wasm::{prepare, runtime::Env, PrefabWasmModule}; use crate::{CodeHash, CodeStorage, PristineCode, Schedule, Trait}; use rstd::prelude::*; use sr_primitives::traits::{Hash, Bounded}; -use srml_support::StorageMap; +use support::StorageMap; /// Gas metering token that used for charging storing code into the code storage. /// @@ -98,7 +98,7 @@ pub fn load( let original_code = >::get(code_hash).ok_or_else(|| "pristine code is not found")?; prefab_module = prepare::prepare_contract::(&original_code, schedule)?; - >::insert(code_hash, prefab_module.clone()); + >::insert(&code_hash, &prefab_module); } Ok(prefab_module) } diff --git a/srml/contracts/src/wasm/mod.rs b/srml/contracts/src/wasm/mod.rs index 99578fee2747f5623cb24e0f515c8d7a6ca4f25b..4fa9412bc1769121c4d5fa06dcf30b384d5acb79 100644 --- a/srml/contracts/src/wasm/mod.rs +++ b/srml/contracts/src/wasm/mod.rs @@ -173,7 +173,7 @@ mod tests { } #[derive(Debug, PartialEq, Eq)] - struct CreateEntry { + struct InstantiateEntry { code_hash: H256, endowment: u64, data: Vec, @@ -192,7 +192,7 @@ mod tests { pub struct MockExt { storage: HashMap>, rent_allowance: u64, - creates: Vec, + instantiates: Vec, transfers: Vec, dispatches: Vec, restores: Vec, @@ -220,7 +220,7 @@ mod tests { gas_meter: &mut GasMeter, data: Vec, ) -> Result<(u64, ExecReturnValue), ExecError> { - self.creates.push(CreateEntry { + self.instantiates.push(InstantiateEntry { code_hash: code_hash.clone(), endowment, data: data.to_vec(), @@ -282,6 +282,10 @@ mod tests { &1111 } + fn minimum_balance(&self) -> u64 { + 666 + } + fn random(&self, subject: &[u8]) -> H256 { H256::from_slice(subject) } @@ -364,6 +368,9 @@ mod tests { fn now(&self) -> &u64 { (**self).now() } + fn minimum_balance(&self) -> u64 { + (**self).minimum_balance() + } fn random(&self, subject: &[u8]) -> H256 { (**self).random(subject) } @@ -464,14 +471,14 @@ mod tests { to: 9, value: 6, data: vec![1, 2, 3, 4], - gas_left: 49970, + gas_left: 49971, }] ); } - const CODE_CREATE: &str = r#" + const CODE_INSTANTIATE: &str = r#" (module - ;; ext_create( + ;; ext_instantiate( ;; code_ptr: u32, ;; code_len: u32, ;; gas: u64, @@ -480,11 +487,11 @@ mod tests { ;; input_data_ptr: u32, ;; input_data_len: u32, ;; ) -> u32 - (import "env" "ext_create" (func $ext_create (param i32 i32 i64 i32 i32 i32 i32) (result i32))) + (import "env" "ext_instantiate" (func $ext_instantiate (param i32 i32 i64 i32 i32 i32 i32) (result i32))) (import "env" "memory" (memory 1 1)) (func (export "call") (drop - (call $ext_create + (call $ext_instantiate (i32.const 16) ;; Pointer to `code_hash` (i32.const 32) ;; Length of `code_hash` (i64.const 0) ;; How much gas to devote for the execution. 0 = all. @@ -500,7 +507,7 @@ mod tests { ;; Amount of value to transfer. ;; Represented by u64 (8 bytes long) in little endian. (data (i32.const 4) "\03\00\00\00\00\00\00\00") - ;; Input data to pass to the contract being created. + ;; Input data to pass to the contract being instantiated. (data (i32.const 12) "\01\02\03\04") ;; Hash of code. (data (i32.const 16) @@ -511,22 +518,22 @@ mod tests { "#; #[test] - fn contract_create() { + fn contract_instantiate() { let mut mock_ext = MockExt::default(); let _ = execute( - CODE_CREATE, + CODE_INSTANTIATE, vec![], &mut mock_ext, &mut GasMeter::with_limit(50_000, 1), ).unwrap(); assert_eq!( - &mock_ext.creates, - &[CreateEntry { + &mock_ext.instantiates, + &[InstantiateEntry { code_hash: [0x11; 32].into(), endowment: 3, data: vec![1, 2, 3, 4], - gas_left: 49946, + gas_left: 49947, }] ); } @@ -1176,6 +1183,65 @@ mod tests { ).unwrap(); } + const CODE_MINIMUM_BALANCE: &str = r#" +(module + (import "env" "ext_minimum_balance" (func $ext_minimum_balance)) + (import "env" "ext_scratch_size" (func $ext_scratch_size (result i32))) + (import "env" "ext_scratch_read" (func $ext_scratch_read (param i32 i32 i32))) + (import "env" "memory" (memory 1 1)) + + (func $assert (param i32) + (block $ok + (br_if $ok + (get_local 0) + ) + (unreachable) + ) + ) + + (func (export "call") + (call $ext_minimum_balance) + + ;; assert $ext_scratch_size == 8 + (call $assert + (i32.eq + (call $ext_scratch_size) + (i32.const 8) + ) + ) + + ;; copy contents of the scratch buffer into the contract's memory. + (call $ext_scratch_read + (i32.const 8) ;; Pointer in memory to the place where to copy. + (i32.const 0) ;; Offset from the start of the scratch buffer. + (i32.const 8) ;; Count of bytes to copy. + ) + + ;; assert that contents of the buffer is equal to the i64 value of 666. + (call $assert + (i64.eq + (i64.load + (i32.const 8) + ) + (i64.const 666) + ) + ) + ) + (func (export "deploy")) +) +"#; + + #[test] + fn minimum_balance() { + let mut gas_meter = GasMeter::with_limit(50_000, 1); + let _ = execute( + CODE_MINIMUM_BALANCE, + vec![], + MockExt::default(), + &mut gas_meter, + ).unwrap(); + } + const CODE_RANDOM: &str = r#" (module (import "env" "ext_random" (func $ext_random (param i32 i32))) @@ -1293,11 +1359,7 @@ mod tests { vec![0x00, 0x01, 0x2a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe5, 0x14, 0x00]) ]); - assert_eq!(gas_meter.gas_left(), 50_000 - - 6 // Explicit - - 13 - 1 - 1 // Deposit event - - (13 + 33) // read memory - ); + assert_eq!(gas_meter.gas_left(), 49934); } const CODE_DEPOSIT_EVENT_MAX_TOPICS: &str = r#" diff --git a/srml/contracts/src/wasm/runtime.rs b/srml/contracts/src/wasm/runtime.rs index ecc4dfc7fb592f40ae5504d654405af65cc9865e..28117eaa7c690d7b25f5d06c99f6a9fee2ea6cb9 100644 --- a/srml/contracts/src/wasm/runtime.rs +++ b/srml/contracts/src/wasm/runtime.rs @@ -29,7 +29,7 @@ use rstd::mem; use codec::{Decode, Encode}; use sr_primitives::traits::{Bounded, SaturatedConversion}; -/// The value returned from ext_call and ext_create contract external functions if the call or +/// The value returned from ext_call and ext_instantiate contract external functions if the call or /// instantiation traps. This value is chosen as if the execution does not trap, the return value /// will always be an 8-bit integer, so 0x0100 is the smallest value that could not be returned. const TRAP_RETURN_CODE: u32 = 0x0100; @@ -70,10 +70,6 @@ impl<'a, E: Ext + 'a> Runtime<'a, E> { special_trap: None, } } - - fn memory(&self) -> &sandbox::Memory { - &self.memory - } } pub(crate) fn to_execution_result( @@ -436,11 +432,12 @@ define_env!(Env, , // by the code hash. // // If the constructor runs to completion, then this returns the status code that the newly - // created contract returns on exit in the bottom 8 bits of the return value. The top 24 bits - // are 0s. A status code of 0 indicates success, and any other code indicates a failure. On - // failure, any state changes made by the called contract are reverted and the contract is not - // instantiated. On a success status, the scratch buffer is filled with the encoded address of - // the newly created contract. In the case of a failure status, the scratch buffer is cleared. + // instantiated contract returns on exit in the bottom 8 bits of the return value. The top 24 + // bits are 0s. A status code of 0 indicates success, and any other code indicates a failure. + // On failure, any state changes made by the called contract are reverted and the contract is + // not instantiated. On a success status, the scratch buffer is filled with the encoded address + // of the newly instantiated contract. In the case of a failure status, the scratch buffer is + // cleared. // // If the contract traps during execution or otherwise fails to complete successfully, then // this function clears the scratch buffer and returns 0x0100. As with a failure status, any @@ -449,8 +446,9 @@ define_env!(Env, , // This function creates an account and executes initializer code. After the execution, // the returned buffer is saved as the code of the created account. // - // Returns 0 on the successful contract creation and puts the address of the created contract - // into the scratch buffer. Otherwise, returns non-zero value and clears the scratch buffer. + // Returns 0 on the successful contract instantiation and puts the address of the instantiated + // contract into the scratch buffer. Otherwise, returns non-zero value and clears the scratch + // buffer. // // - code_hash_ptr: a pointer to the buffer that contains the initializer code. // - code_hash_len: length of the initializer code buffer. @@ -460,7 +458,7 @@ define_env!(Env, , // - value_len: length of the value buffer. // - input_data_ptr: a pointer to a buffer to be used as input data to the initializer code. // - input_data_len: length of the input data buffer. - ext_create( + ext_instantiate( ctx, code_hash_ptr: u32, code_hash_len: u32, @@ -539,9 +537,9 @@ define_env!(Env, , // Stores the address of the caller into the scratch buffer. // - // If this is a top-level call (i.e. initiated by an extrinsic) the origin address of the extrinsic - // will be returned. Otherwise, if this call is initiated by another contract then the address - // of the contract will be returned. + // If this is a top-level call (i.e. initiated by an extrinsic) the origin address of the + // extrinsic will be returned. Otherwise, if this call is initiated by another contract then the + // address of the contract will be returned. ext_caller(ctx) => { ctx.scratch_buf.clear(); ctx.ext.caller().encode_to(&mut ctx.scratch_buf); @@ -615,6 +613,16 @@ define_env!(Env, , Ok(()) }, + // Stores the minimum balance (a.k.a. existential deposit) into the scratch buffer. + // + // The data is encoded as T::Balance. The current contents of the scratch buffer are + // overwritten. + ext_minimum_balance(ctx) => { + ctx.scratch_buf.clear(); + ctx.ext.minimum_balance().encode_to(&mut ctx.scratch_buf); + Ok(()) + }, + // Decodes the given buffer as a `T::Call` and adds it to the list // of to-be-dispatched calls. // @@ -711,8 +719,8 @@ define_env!(Env, , Ok(ctx.scratch_buf.len() as u32) }, - // Copy data from the scratch buffer starting from `offset` with length `len` into the contract memory. - // The region at which the data should be put is specified by `dest_ptr`. + // Copy data from the scratch buffer starting from `offset` with length `len` into the contract + // memory. The region at which the data should be put is specified by `dest_ptr`. // // In order to get size of the scratch buffer use `ext_scratch_size`. At the start of contract // execution, the scratch buffer is filled with the input data. Whenever a contract calls @@ -816,7 +824,7 @@ define_env!(Env, , ext_println(ctx, str_ptr: u32, str_len: u32) => { let data = read_sandbox_memory(ctx, str_ptr, str_len)?; if let Ok(utf8) = core::str::from_utf8(&data) { - runtime_io::print(utf8); + sr_primitives::print(utf8); } Ok(()) }, diff --git a/srml/council/src/lib.rs b/srml/council/src/lib.rs index 787abdb0787dd99956ed86cd8f5b38f80fb27639..aa27bcde21f6aafd990b9660142bd7b249339ff1 100644 --- a/srml/council/src/lib.rs +++ b/srml/council/src/lib.rs @@ -39,8 +39,8 @@ mod tests { // These re-exports are here for a reason, edit with care pub use super::*; pub use runtime_io::with_externalities; - use srml_support::{impl_outer_origin, impl_outer_event, impl_outer_dispatch, parameter_types}; - use srml_support::traits::Get; + use support::{impl_outer_origin, impl_outer_event, impl_outer_dispatch, parameter_types}; + use support::traits::Get; pub use primitives::{H256, Blake2Hasher, u32_trait::{_1, _2, _3, _4}}; pub use sr_primitives::traits::{BlakeTwo256, IdentityLookup}; pub use sr_primitives::testing::{Digest, DigestItem, Header}; @@ -62,6 +62,8 @@ mod tests { impl_outer_dispatch! { pub enum Call for Test where origin: Origin { + type Error = Error; + balances::Balances, democracy::Democracy, } @@ -115,10 +117,12 @@ mod tests { type Header = Header; type WeightMultiplierUpdate = (); type Event = Event; + type Error = Error; type BlockHashCount = BlockHashCount; type MaximumBlockWeight = MaximumBlockWeight; type MaximumBlockLength = MaximumBlockLength; type AvailableBlockRatio = AvailableBlockRatio; + type Version = (); } parameter_types! { pub const ExistentialDeposit: u64 = 0; @@ -135,6 +139,7 @@ mod tests { type TransactionPayment = (); type TransferPayment = (); type DustRemoval = (); + type Error = Error; type ExistentialDeposit = ExistentialDeposit; type TransferFee = TransferFee; type CreationFee = CreationFee; diff --git a/srml/democracy/Cargo.toml b/srml/democracy/Cargo.toml index b6341a8225638a04342fad4f9d65ab83510fd778..761e56ceda6cb978d1c208126dd076c59eca5d3a 100644 --- a/srml/democracy/Cargo.toml +++ b/srml/democracy/Cargo.toml @@ -5,13 +5,13 @@ authors = ["Parity Technologies "] edition = "2018" [dependencies] -serde = { version = "1.0", optional = true, features = ["derive"] } -safe-mix = { version = "1.0", default-features = false} +serde = { version = "1.0.101", optional = true, features = ["derive"] } +safe-mix = { version = "1.0.0", default-features = false } codec = { package = "parity-scale-codec", version = "1.0.0", default-features = false, features = ["derive"] } rstd = { package = "sr-std", path = "../../core/sr-std", default-features = false } -runtime_io = { package = "sr-io", path = "../../core/sr-io", default-features = false } +runtime-io = { package = "sr-io", path = "../../core/sr-io", default-features = false } sr-primitives = { path = "../../core/sr-primitives", default-features = false } -srml-support = { path = "../support", default-features = false } +support = { package = "srml-support", path = "../support", default-features = false } system = { package = "srml-system", path = "../system", default-features = false } [dev-dependencies] @@ -25,8 +25,8 @@ std = [ "safe-mix/std", "codec/std", "rstd/std", - "runtime_io/std", - "srml-support/std", + "runtime-io/std", + "support/std", "sr-primitives/std", "system/std", ] diff --git a/srml/democracy/src/lib.rs b/srml/democracy/src/lib.rs index 5a1c61b8ae24ce47410a350ed7018c2cb8bf86c1..b93f6f893aef9d0f44e2316b23d127556420f1c7 100644 --- a/srml/democracy/src/lib.rs +++ b/srml/democracy/src/lib.rs @@ -20,18 +20,20 @@ use rstd::prelude::*; use rstd::{result, convert::TryFrom}; -use sr_primitives::traits::{Zero, Bounded, CheckedMul, CheckedDiv, EnsureOrigin, Hash}; -use sr_primitives::weights::SimpleDispatchInfo; -use codec::{Encode, Decode, Input, Output, Error}; -use srml_support::{ +use sr_primitives::{ + traits::{Zero, Bounded, CheckedMul, CheckedDiv, EnsureOrigin, Hash, Dispatchable}, + weights::SimpleDispatchInfo, +}; +use codec::{Ref, Encode, Decode, Input, Output, Error}; +use support::{ decl_module, decl_storage, decl_event, ensure, - StorageValue, StorageMap, Parameter, Dispatchable, EnumerableStorageMap, + Parameter, traits::{ - Currency, ReservableCurrency, LockableCurrency, WithdrawReason, LockIdentifier, - OnFreeBalanceZero, Get + Currency, ReservableCurrency, LockableCurrency, WithdrawReason, LockIdentifier, Get, + OnFreeBalanceZero } }; -use srml_support::dispatch::Result; +use support::dispatch::Result; use system::{ensure_signed, ensure_root}; mod vote_threshold; @@ -174,13 +176,6 @@ impl Decode for Vote { type BalanceOf = <::Currency as Currency<::AccountId>>::Balance; -pub const DEFAULT_ENACTMENT_PERIOD: u32 = 0; -pub const DEFAULT_LAUNCH_PERIOD: u32 = 0; -pub const DEFAULT_VOTING_PERIOD: u32 = 0; -pub const DEFAULT_MINIMUM_DEPOSIT: u32 = 0; -pub const DEFAULT_EMERGENCY_VOTING_PERIOD: u32 = 0; -pub const DEFAULT_COOLOFF_PERIOD: u32 = 0; - pub trait Trait: system::Trait + Sized { type Proposal: Parameter + Dispatchable; type Event: From> + Into<::Event>; @@ -361,7 +356,7 @@ decl_module! { /// Period in blocks where an external proposal may not be re-submitted after being vetoed. const CooloffPeriod: T::BlockNumber = T::CooloffPeriod::get(); - fn deposit_event() = default; + fn deposit_event() = default; /// Propose a sensitive action to be taken. /// @@ -382,11 +377,10 @@ decl_module! { let index = Self::public_prop_count(); PublicPropCount::put(index + 1); - >::insert(index, (value, vec![who.clone()])); + >::insert(index, (value, &[&who][..])); - let mut props = Self::public_props(); - props.push((index, (*proposal).clone(), who)); - >::put(props); + let new_prop = (index, proposal, who); + >::append_or_put(&[Ref::from(&new_prop)][..]); Self::deposit_event(RawEvent::Proposed(index, value)); } @@ -568,7 +562,7 @@ decl_module! { fn on_initialize(n: T::BlockNumber) { if let Err(e) = Self::end_block(n) { - runtime_io::print(e); + sr_primitives::print(e); } } @@ -615,7 +609,7 @@ decl_module! { #[weight = SimpleDispatchInfo::FixedNormal(500_000)] pub fn delegate(origin, to: T::AccountId, conviction: Conviction) { let who = ensure_signed(origin)?; - >::insert(who.clone(), (to.clone(), conviction)); + >::insert(&who, (&to, conviction)); // Currency is locked indefinitely as long as it's delegated. T::Currency::extend_lock( DEMOCRACY_ID, @@ -794,10 +788,10 @@ impl Module { /// Actually enact a vote, if legit. fn do_vote(who: T::AccountId, ref_index: ReferendumIndex, vote: Vote) -> Result { ensure!(Self::is_active_referendum(ref_index), "vote given for invalid referendum."); - if !>::exists(&(ref_index, who.clone())) { - >::mutate(ref_index, |voters| voters.push(who.clone())); + if !>::exists((ref_index, &who)) { + >::append_or_insert(ref_index, &[&who][..]); } - >::insert(&(ref_index, who), vote); + >::insert((ref_index, &who), vote); Ok(()) } @@ -933,9 +927,9 @@ impl Module { if info.delay.is_zero() { Self::enact_proposal(info.proposal, index); } else { - >::mutate( + >::append_or_insert( now + info.delay, - |q| q.push(Some((info.proposal, index))) + &[Some((info.proposal, index))][..] ); } } else { @@ -953,12 +947,12 @@ impl Module { if (now % T::LaunchPeriod::get()).is_zero() { // Errors come from the queue being empty. we don't really care about that, and even if // we did, there is nothing we can do here. - let _ = Self::launch_next(now.clone()); + let _ = Self::launch_next(now); } // tally up votes for any expiring referenda. for (index, info) in Self::maturing_referenda_at(now).into_iter() { - Self::bake_referendum(now.clone(), index, info)?; + Self::bake_referendum(now, index, info)?; } for (proposal, index) in >::take(now).into_iter().filter_map(|x| x) { @@ -978,7 +972,7 @@ impl OnFreeBalanceZero for Module { mod tests { use super::*; use runtime_io::with_externalities; - use srml_support::{ + use support::{ impl_outer_origin, impl_outer_dispatch, assert_noop, assert_ok, parameter_types, traits::Contains }; @@ -1029,6 +1023,7 @@ mod tests { type MaximumBlockWeight = MaximumBlockWeight; type MaximumBlockLength = MaximumBlockLength; type AvailableBlockRatio = AvailableBlockRatio; + type Version = (); } parameter_types! { pub const ExistentialDeposit: u64 = 0; diff --git a/srml/elections-phragmen/Cargo.toml b/srml/elections-phragmen/Cargo.toml new file mode 100644 index 0000000000000000000000000000000000000000..02898fc754f2ede30f3c6b13ac9624f769e1678e --- /dev/null +++ b/srml/elections-phragmen/Cargo.toml @@ -0,0 +1,34 @@ +[package] +name = "srml-elections-phragmen" +version = "2.0.0" +authors = ["Parity Technologies "] +edition = "2018" + +[dependencies] +serde = { version = "1.0.101", optional = true } +codec = { package = "parity-scale-codec", version = "1.0.0", default-features = false, features = ["derive"] } +primitives = { package = "substrate-primitives", path = "../../core/primitives", default-features = false } +runtime_io = { package = "sr-io", path = "../../core/sr-io", default-features = false } +sr-primitives = { path = "../../core/sr-primitives", default-features = false } +phragmen = { package = "substrate-phragmen", path = "../../core/phragmen", default-features = false } +srml-support = { path = "../support", default-features = false } +system = { package = "srml-system", path = "../system", default-features = false } +rstd = { package = "sr-std", path = "../../core/sr-std", default-features = false } + +[dev-dependencies] +hex-literal = "0.2.1" +balances = { package = "srml-balances", path = "../balances" } + +[features] +default = ["std"] +std = [ + "codec/std", + "primitives/std", + "serde", + "runtime_io/std", + "srml-support/std", + "sr-primitives/std", + "phragmen/std", + "system/std", + "rstd/std", +] diff --git a/srml/elections-phragmen/src/lib.rs b/srml/elections-phragmen/src/lib.rs new file mode 100644 index 0000000000000000000000000000000000000000..58c0f11340608673300d68308e1d6a41a690d702 --- /dev/null +++ b/srml/elections-phragmen/src/lib.rs @@ -0,0 +1,1605 @@ +// Copyright 2019 Parity Technologies (UK) Ltd. +// This file is part of Substrate. + +// Substrate 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. + +// Substrate 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 Substrate. If not, see . + +//! # Phragmen Election Module. +//! +//! An election module based on sequential phragmen. +//! +//! ### Term and Round +//! +//! The election happens in _rounds_: every `N` blocks, all previous members are retired and a new +//! set is elected (which may or may not have an intersection with the previous set). Each round +//! lasts for some number of blocks defined by `TermDuration` storage item. The words _term_ and +//! _round_ can be used interchangeably in this context. +//! +//! `TermDuration` might change during a round. This can shorten or extend the length of the round. +//! The next election round's block number is never stored but rather always checked on the fly. +//! Based on the current block number and `TermDuration`, the condition `BlockNumber % TermDuration +//! == 0` being satisfied will always trigger a new election round. +//! +//! ### Voting +//! +//! Voters can vote for any set of the candidates by providing a list of account ids. Invalid votes +//! (voting for non-candidates) are ignored during election. Yet, a voter _might_ vote for a future +//! candidate. Voters reserve a bond as they vote. Each vote defines a `value`. This amount is +//! locked from the account of the voter and indicates the weight of the vote. Voters can update +//! their votes at any time by calling `vote()` again. This keeps the bond untouched but can +//! optionally change the locked `value`. After a round, votes are kept and might still be valid for +//! further rounds. A voter is responsible for calling `remove_voter` once they are done to have +//! their bond back and remove the lock. +//! +//! Voters also report other voters as being defunct to earn their bond. A voter is defunct once all +//! of the candidates that they have voted for are neither a valid candidate anymore nor a member. +//! Upon reporting, if the target voter is actually defunct, the reporter will be rewarded by the +//! voting bond of the target. The target will lose their bond and get removed. If the target is not +//! defunct, the reporter is slashed and removed. To prevent being reported, voters should manually +//! submit a `remove_voter()` as soon as they are in the defunct state. +//! +//! ### Candidacy and Members +//! +//! Candidates also reserve a bond as they submit candidacy. A candidate cannot take their candidacy +//! back. A candidate can end up in one of the below situations: +//! - **Winner**: A winner is kept as a _member_. They must still have a bond in reserve and they +//! are automatically counted as a candidate for the next election. +//! - **Loser**: Any of the candidate who are not a winner are left as losers. A loser might be an +//! _outgoing member_, meaning that they are an active member who failed to keep their spot. In +//! this case, the outgoing member will get their bond back. Otherwise, the bond is slashed from +//! the loser candidate. +//! - **Runner-up**: Runners-up are the best candidates immediately after the winners. The number +//! of runners_up to keep is configurable. Runners-up are used, in order that they are elected, +//! as replacements when a candidate is kicked by `remove_member()`. +//! +//! Note that with the members being the default candidates for the next round and votes persisting +//! in storage, the election system is entirely stable given no further input. This means that if +//! the system has a particular set of candidates `C` and voters `V` that lead to a set of members +//! `M` being elected, as long as `V` and `C` don't remove their candidacy and votes, `M` will keep +//! being re-elected at the end of each round. +//! +//! ### Module Information +//! +//! - [`election_phragmen::Trait`](./trait.Trait.html) +//! - [`Call`](./enum.Call.html) +//! - [`Module`](./struct.Module.html) + +#![cfg_attr(not(feature = "std"), no_std)] + +use sr_primitives::{print, traits::{Zero, StaticLookup, Bounded, Convert}}; +use sr_primitives::weights::SimpleDispatchInfo; +use srml_support::{ + decl_storage, decl_event, ensure, decl_module, dispatch, + traits::{ + Currency, Get, LockableCurrency, LockIdentifier, ReservableCurrency, WithdrawReasons, + ChangeMembers, OnUnbalanced, + } +}; +use system::{self, ensure_signed, ensure_root}; + +const MODULE_ID: LockIdentifier = *b"phrelect"; + +/// The maximum votes allowed per voter. +pub const MAXIMUM_VOTE: usize = 16; + +type BalanceOf = <::Currency as Currency<::AccountId>>::Balance; +type NegativeImbalanceOf = + <::Currency as Currency<::AccountId>>::NegativeImbalance; + +pub trait Trait: system::Trait { + /// The overarching event type.c + type Event: From> + Into<::Event>; + + /// The currency that people are electing with. + type Currency: + LockableCurrency + + ReservableCurrency; + + /// What to do when the members change. + type ChangeMembers: ChangeMembers; + + /// Convert a balance into a number used for election calculation. + /// This must fit into a `u64` but is allowed to be sensibly lossy. + type CurrencyToVote: Convert, u64> + Convert>; + + /// How much should be locked up in order to submit one's candidacy. + type CandidacyBond: Get>; + + /// How much should be locked up in order to be able to submit votes. + type VotingBond: Get>; + + /// Handler for the unbalanced reduction when a candidate has lost (and is not a runner-up) + type LoserCandidate: OnUnbalanced>; + + /// Handler for the unbalanced reduction when a reporter has submitted a bad defunct report. + type BadReport: OnUnbalanced>; + + /// Handler for the unbalanced reduction when a member has been kicked. + type KickedMember: OnUnbalanced>; +} + +decl_storage! { + trait Store for Module as PhragmenElection { + // ---- parameters + /// Number of members to elect. + pub DesiredMembers get(desired_members) config(): u32; + /// Number of runners_up to keep. + pub DesiredRunnersUp get(desired_runners_up) config(): u32; + /// How long each seat is kept. This defines the next block number at which an election + /// round will happen. + pub TermDuration get(term_duration) config(): T::BlockNumber; + + // ---- State + /// The current elected membership. Sorted based on account id. + pub Members get(members) config(): Vec; + /// The current runners_up. Sorted based on low to high merit (worse to best runner). + pub RunnersUp get(runners_up): Vec; + /// The total number of vote rounds that have happened, excluding the upcoming one. + pub ElectionRounds get(election_rounds): u32 = Zero::zero(); + + /// Votes of a particular voter, with the round index of the votes. + pub VotesOf get(votes_of): linked_map T::AccountId => Vec; + /// Locked stake of a voter. + pub StakeOf get(stake_of): map T::AccountId => BalanceOf; + + /// The present candidate list. Sorted based on account id. A current member can never enter + /// this vector and is always implicitly assumed to be a candidate. + pub Candidates get(candidates): Vec; + } +} + +decl_module! { + pub struct Module for enum Call where origin: T::Origin { + fn deposit_event() = default; + + const CandidacyBond: BalanceOf = T::CandidacyBond::get(); + const VotingBond: BalanceOf = T::VotingBond::get(); + + /// Vote for a set of candidates for the upcoming round of election. + /// + /// The `votes` should: + /// - not be empty. + /// - be less than the number of candidates. + /// + /// Upon voting, `value` units of `who`'s balance is locked and a bond amount is reserved. + /// It is the responsibility of the caller to not place all of their balance into the lock + /// and keep some for further transactions. + /// + /// # + /// #### State + /// Reads: O(1) + /// Writes: O(V) given `V` votes. V is bounded by 16. + /// # + #[weight = SimpleDispatchInfo::FixedNormal(100_000)] + fn vote(origin, votes: Vec, #[compact] value: BalanceOf) { + let who = ensure_signed(origin)?; + + let candidates_count = >::decode_len().unwrap_or(0) as usize; + let members_count = >::decode_len().unwrap_or(0) as usize; + // addition is valid: candidates and members never overlap. + let allowed_votes = candidates_count + members_count; + + ensure!(!allowed_votes.is_zero(), "cannot vote when no candidates or members exist"); + ensure!(votes.len() <= allowed_votes, "cannot vote more than candidates"); + ensure!(votes.len() <= MAXIMUM_VOTE, "cannot vote more than maximum allowed"); + + ensure!(!votes.is_empty(), "must vote for at least one candidate."); + ensure!( + value > T::Currency::minimum_balance(), + "cannot vote with stake less than minimum balance" + ); + + if !Self::is_voter(&who) { + // first time voter. Reserve bond. + T::Currency::reserve(&who, T::VotingBond::get()) + .map_err(|_| "voter can not pay voting bond")?; + } + // Amount to be locked up. + let locked_balance = value.min(T::Currency::total_balance(&who)); + + // lock + T::Currency::set_lock( + MODULE_ID, + &who, + locked_balance, + T::BlockNumber::max_value(), + WithdrawReasons::all(), + ); + >::insert(&who, locked_balance); + >::insert(&who, votes); + } + + /// Remove `origin` as a voter. This removes the lock and returns the bond. + /// + /// # + /// #### State + /// Reads: O(1) + /// Writes: O(1) + /// # + #[weight = SimpleDispatchInfo::FixedNormal(10_000)] + fn remove_voter(origin) { + let who = ensure_signed(origin)?; + + ensure!(Self::is_voter(&who), "must be a voter"); + + Self::do_remove_voter(&who, true); + } + + /// Report `target` for being an defunct voter. In case of a valid report, the reporter is + /// rewarded by the bond amount of `target`. Otherwise, the reporter itself is removed and + /// their bond is slashed. + /// + /// A defunct voter is defined to be: + /// - a voter whose current submitted votes are all invalid. i.e. all of them are no + /// longer a candidate nor an active member. + /// + /// # + /// #### State + /// Reads: O(NLogM) given M current candidates and N votes for `target`. + /// Writes: O(1) + /// # + #[weight = SimpleDispatchInfo::FixedNormal(1_000_000)] + fn report_defunct_voter(origin, target: ::Source) { + let reporter = ensure_signed(origin)?; + let target = T::Lookup::lookup(target)?; + + ensure!(reporter != target, "cannot report self"); + ensure!(Self::is_voter(&reporter), "reporter must be a voter"); + + // Checking if someone is a candidate and a member here is O(LogN), making the whole + // function O(MLonN) with N candidates in total and M of them being voted by `target`. + // We could easily add another mapping to be able to check if someone is a candidate in + // `O(1)` but that would make the process of removing candidates at the end of each + // round slightly harder. Note that for now we have a bound of number of votes (`N`). + let valid = Self::is_defunct_voter(&target); + if valid { + // reporter will get the voting bond of the target + T::Currency::repatriate_reserved(&target, &reporter, T::VotingBond::get())?; + // remove the target. They are defunct. + Self::do_remove_voter(&target, false); + } else { + // slash the bond of the reporter. + let imbalance = T::Currency::slash_reserved(&reporter, T::VotingBond::get()).0; + T::BadReport::on_unbalanced(imbalance); + // remove the reporter. + Self::do_remove_voter(&reporter, false); + } + Self::deposit_event(RawEvent::VoterReported(target, reporter, valid)); + } + + + /// Submit oneself for candidacy. + /// + /// A candidate will either: + /// - Lose at the end of the term and forfeit their deposit. + /// - Win and become a member. Members will eventually get their stash back. + /// - Become a runner-up. Runners-ups are reserved members in case one gets forcefully + /// removed. + /// + /// # + /// #### State + /// Reads: O(LogN) Given N candidates. + /// Writes: O(1) + /// # + #[weight = SimpleDispatchInfo::FixedNormal(500_000)] + fn submit_candidacy(origin) { + let who = ensure_signed(origin)?; + + let is_candidate = Self::is_candidate(&who); + ensure!(is_candidate.is_err(), "duplicate candidate submission"); + // assured to be an error, error always contains the index. + let index = is_candidate.unwrap_err(); + + ensure!(!Self::is_member(&who), "member cannot re-submit candidacy"); + + T::Currency::reserve(&who, T::CandidacyBond::get()) + .map_err(|_| "candidate does not have enough funds")?; + + >::mutate(|c| c.insert(index, who)); + } + + /// Set the desired member count. Changes will be effective at the beginning of next round. + /// + /// # + /// #### State + /// Reads: O(1) + /// Writes: O(1) + /// # + #[weight = SimpleDispatchInfo::FixedOperational(10_000)] + fn set_desired_member_count(origin, #[compact] count: u32) { + ensure_root(origin)?; + DesiredMembers::put(count); + } + + /// Remove a particular member from the set. This is effective immediately. + /// + /// If a runner-up is available, then the best runner-up will be removed and replaces the + /// outgoing member. Otherwise, a new phragmen round is started. + /// + /// Note that this does not affect the designated block number of the next election. + /// + /// # + /// #### State + /// Reads: O(do_phragmen) + /// Writes: O(do_phragmen) + /// # + #[weight = SimpleDispatchInfo::FixedOperational(2_000_000)] + fn remove_member(origin, who: ::Source) { + ensure_root(origin)?; + let who = T::Lookup::lookup(who)?; + + let mut members = Self::members(); + if let Ok(index) = members.binary_search(&who) { + // remove, slash, emit event. + members.remove(index); + let (imbalance, _) = T::Currency::slash_reserved(&who, T::CandidacyBond::get()); + T::KickedMember::on_unbalanced(imbalance); + Self::deposit_event(RawEvent::MemberKicked(who.clone())); + + let mut runners_up = Self::runners_up(); + if let Some(replacement) = runners_up.pop() { + // replace the outgoing with the best runner up. + if let Err(index) = members.binary_search(&replacement) { + members.insert(index, replacement.clone()); + ElectionRounds::mutate(|v| *v += 1); + T::ChangeMembers::change_members_sorted(&[replacement], &[who], &members); + } + // else it would mean that the runner up was already a member. This cannot + // happen. If it does, not much that we can do about it. + + >::put(members); + >::put(runners_up); + } else { + // update `Members` storage -- `do_phragmen` adds this to the candidate list. + >::put(members); + // trigger a new phragmen. grab a cup of coffee. This might take a while. + Self::do_phragmen(); + } + } + } + + /// Set the duration of each term. This will affect the next election's block number. + /// + /// # + /// #### State + /// Reads: O(1) + /// Writes: O(1) + /// # + #[weight = SimpleDispatchInfo::FixedOperational(10_000)] + fn set_term_duration(origin, #[compact] count: T::BlockNumber) { + ensure_root(origin)?; + >::put(count); + } + + /// What to do at the end of each block. Checks if an election needs to happen or not. + fn on_initialize(n: T::BlockNumber) { + if let Err(e) = Self::end_block(n) { + print("Guru meditation"); + print(e); + } + } + } +} + +decl_event!( + pub enum Event where ::AccountId { + /// A new term with new members. This indicates that enough candidates existed, not that + /// enough have has been elected. The inner value must be examined for this purpose. + NewTerm(Vec), + /// No (or not enough) candidates existed for this round. + EmptyTerm, + /// A member has been removed. This should always be followed by either `NewTerm` ot + /// `EmptyTerm`. + MemberKicked(AccountId), + /// A voter (first element) was reported (byt the second element) with the the report being + /// successful or not (third element). + VoterReported(AccountId, AccountId, bool), + } +); + +impl Module { + /// Check if `who` is a candidate. It returns the insert index if the element does not exists as + /// an error. + /// + /// State: O(LogN) given N candidates. + fn is_candidate(who: &T::AccountId) -> Result<(), usize> { + Self::candidates().binary_search(who).map(|_| ()) + } + + /// Check if `who` is a voter. It may or may not be a _current_ one. + /// + /// State: O(1). + fn is_voter(who: &T::AccountId) -> bool { + >::exists(who) + } + + /// Check if `who` is currently an active member. + /// + /// Limited number of members. Binary search. Constant time factor. O(1) + fn is_member(who: &T::AccountId) -> bool { + Self::members().binary_search(who).is_ok() + } + + /// Check if `who` is a defunct voter. + /// + /// Note that false is returned if `who` is not a voter at all. + /// + /// O(NLogM) with M candidates and `who` having voted for `N` of them. + fn is_defunct_voter(who: &T::AccountId) -> bool { + if Self::is_voter(who) { + Self::votes_of(who) + .iter() + .all(|v| !Self::is_member(v) && !Self::is_candidate(v).is_ok()) + } else { + false + } + } + + /// Remove a certain someone as a voter. + /// + /// This will clean always clean the storage associated with the voter, and remove the balance + /// lock. Optionally, it would also return the reserved voting bond if indicated by `unreserve`. + fn do_remove_voter(who: &T::AccountId, unreserve: bool) { + // remove storage and lock. + >::remove(who); + >::remove(who); + T::Currency::remove_lock(MODULE_ID, who); + + if unreserve { + T::Currency::unreserve(who, T::VotingBond::get()); + } + } + + /// The locked stake of a voter. + fn locked_stake_of(who: &T::AccountId) -> BalanceOf { + Self::stake_of(who) + } + + /// Check there's nothing to do this block. + /// + /// Runs phragmen election and cleans all the previous candidate state. The voter state is NOT + /// cleaned and voters must themselves submit a transaction to retract. + fn end_block(block_number: T::BlockNumber) -> dispatch::Result { + if (block_number % Self::term_duration()).is_zero() { + Self::do_phragmen(); + } + Ok(()) + } + + /// Run the phragmen election with all required side processes and state updates. + /// + /// Calls the appropriate `ChangeMembers` function variant internally. + /// + /// # + /// #### State + /// Reads: O(C + V*E) where C = candidates, V voters and E votes per voter exits. + /// Writes: O(M + R) with M desired members and R runners_up. + /// # + fn do_phragmen() { + let desired_seats = Self::desired_members() as usize; + let desired_runners_up = Self::desired_runners_up() as usize; + let num_to_elect = desired_runners_up + desired_seats; + + let mut candidates = Self::candidates(); + // candidates who explicitly called `submit_candidacy`. Only these folks are at the risk of + // losing their bond. + let mut exposed_candidates = candidates.clone(); + // current members are always a candidate for the next round as well. + // this is guaranteed to not create any duplicates. + candidates.append(&mut Self::members()); + // previous runners_up are also always candidates for the next round. + candidates.append(&mut Self::runners_up()); + // and exposed to being an outgoing in case they are no longer elected. + exposed_candidates.append(&mut Self::runners_up()); + + let voters_and_votes = >::enumerate() + .map(|(v, i)| (v, i)) + .collect::)>>(); + let maybe_phragmen_result = phragmen::elect::<_, _, _, T::CurrencyToVote>( + num_to_elect, + 0, + candidates, + voters_and_votes, + Self::locked_stake_of, + false, + ); + + let mut to_release_bond: Vec = Vec::with_capacity(desired_seats); + let old_members = >::take(); + if let Some(phragmen_result) = maybe_phragmen_result { + // filter out those who had literally no votes at all. + // AUDIT/NOTE: the need to do this is because all candidates, even those who have no + // vote are still considered by phragmen and when good candidates are scarce, then these + // cheap ones might get elected. We might actually want to remove the filter and allow + // zero-voted candidates to also make it to the membership set. + let new_set_with_approval = phragmen_result.winners; + let new_set = new_set_with_approval + .into_iter() + .filter_map(|(m, a)| if a.is_zero() { None } else { Some(m) } ) + .collect::>(); + + // split new set into winners and runner ups. + let split_point = desired_seats.min(new_set.len()); + let mut new_members = (&new_set[..split_point]).to_vec(); + let runners_up = &new_set[split_point..] + .into_iter() + .cloned() + .rev() + .collect::>(); + + // sort and save the members. + new_members.sort(); + >::put(&new_members); + + // save the runners as-is + >::put(runners_up); + + // report member changes. We compute diff because we need the outgoing list. + let (incoming, outgoing) = T::ChangeMembers::compute_members_diff( + &new_members, + &old_members + ); + T::ChangeMembers::change_members_sorted( + &incoming, + &outgoing.clone(), + &new_members + ); + + // unlike exposed_candidates, these are members who were in the list and no longer + // exist. They must get their bond back. + to_release_bond = outgoing.to_vec(); + + // Burn loser bond. members list is sorted. O(NLogM) (N candidates, M members) + // runner up list is not sorted. O(K*N) given K runner ups. Overall: O(NLogM + N*K) + exposed_candidates.into_iter().for_each(|c| { + // any candidate who is not a member and not a runner up. + if new_members.binary_search(&c).is_err() && !runners_up.contains(&c) + { + let (imbalance, _) = T::Currency::slash_reserved(&c, T::CandidacyBond::get()); + T::LoserCandidate::on_unbalanced(imbalance); + } + }); + Self::deposit_event(RawEvent::NewTerm(new_members.to_vec())); + } else { + Self::deposit_event(RawEvent::EmptyTerm); + } + + // unreserve the bond of all the outgoings. + to_release_bond.iter().for_each(|m| { + T::Currency::unreserve(&m, T::CandidacyBond::get()); + }); + + // clean candidates. + >::kill(); + + ElectionRounds::mutate(|v| *v += 1); + } +} + +#[cfg(test)] +mod tests { + use super::*; + use std::cell::RefCell; + use srml_support::{assert_ok, assert_noop, parameter_types, assert_eq_uvec}; + use runtime_io::with_externalities; + use primitives::{H256, Blake2Hasher}; + use sr_primitives::{Perbill, testing::Header, BuildStorage, + traits::{BlakeTwo256, IdentityLookup, Block as BlockT} + }; + use crate as elections; + + parameter_types! { + pub const BlockHashCount: u64 = 250; + pub const MaximumBlockWeight: u32 = 1024; + pub const MaximumBlockLength: u32 = 2 * 1024; + pub const AvailableBlockRatio: Perbill = Perbill::one(); + } + + impl system::Trait for Test { + type Origin = Origin; + type Index = u64; + type BlockNumber = u64; + type Call = (); + type Hash = H256; + type Hashing = BlakeTwo256; + type AccountId = u64; + type Lookup = IdentityLookup; + type Header = Header; + type Event = Event; + type WeightMultiplierUpdate = (); + type BlockHashCount = BlockHashCount; + type MaximumBlockWeight = MaximumBlockWeight; + type MaximumBlockLength = MaximumBlockLength; + type AvailableBlockRatio = AvailableBlockRatio; + type Version = (); + } + + parameter_types! { + pub const ExistentialDeposit: u64 = 1; + pub const TransferFee: u64 = 0; + pub const CreationFee: u64 = 0; + pub const TransactionBaseFee: u64 = 0; + pub const TransactionByteFee: u64 = 0; + } + + impl balances::Trait for Test { + type Balance = u64; + type OnNewAccount = (); + type OnFreeBalanceZero = (); + type Event = Event; + type TransactionPayment = (); + type TransferPayment = (); + type DustRemoval = (); + type ExistentialDeposit = ExistentialDeposit; + type TransferFee = TransferFee; + type CreationFee = CreationFee; + type TransactionBaseFee = TransactionBaseFee; + type TransactionByteFee = TransactionByteFee; + type WeightToFee = (); + } + + parameter_types! { + pub const CandidacyBond: u64 = 3; + } + + thread_local! { + static VOTING_BOND: RefCell = RefCell::new(2); + static MEMBERS: RefCell> = RefCell::new(vec![]); + } + + pub struct VotingBond; + impl Get for VotingBond { + fn get() -> u64 { VOTING_BOND.with(|v| *v.borrow()) } + } + + pub struct TestChangeMembers; + impl ChangeMembers for TestChangeMembers { + fn change_members_sorted(_: &[u64], _: &[u64], _: &[u64]) {} + } + + /// Simple structure that exposes how u64 currency can be represented as... u64. + pub struct CurrencyToVoteHandler; + impl Convert for CurrencyToVoteHandler { + fn convert(x: u64) -> u64 { x } + } + impl Convert for CurrencyToVoteHandler { + fn convert(x: u128) -> u64 { + x as u64 + } + } + + impl Trait for Test { + type Event = Event; + type Currency = Balances; + type CurrencyToVote = CurrencyToVoteHandler; + type ChangeMembers = TestChangeMembers; + type CandidacyBond = CandidacyBond; + type VotingBond = VotingBond; + type LoserCandidate = (); + type KickedMember = (); + type BadReport = (); + } + + pub type Block = sr_primitives::generic::Block; + pub type UncheckedExtrinsic = sr_primitives::generic::UncheckedExtrinsic; + + srml_support::construct_runtime!( + pub enum Test where + Block = Block, + NodeBlock = Block, + UncheckedExtrinsic = UncheckedExtrinsic + { + System: system::{Module, Call, Event}, + Balances: balances::{Module, Call, Event, Config}, + Elections: elections::{Module, Call, Event, Config}, + } + ); + + pub struct ExtBuilder { + balance_factor: u64, + voter_bond: u64, + desired_runners_up: u32, + } + + impl Default for ExtBuilder { + fn default() -> Self { + Self { + balance_factor: 1, + voter_bond: 2, + desired_runners_up: 0, + } + } + } + + impl ExtBuilder { + pub fn voter_bond(mut self, fee: u64) -> Self { + self.voter_bond = fee; + self + } + pub fn desired_runners_up(mut self, count: u32) -> Self { + self.desired_runners_up = count; + self + } + pub fn build(self) -> runtime_io::TestExternalities { + VOTING_BOND.with(|v| *v.borrow_mut() = self.voter_bond); + GenesisConfig { + balances: Some(balances::GenesisConfig::{ + balances: vec![ + (1, 10 * self.balance_factor), + (2, 20 * self.balance_factor), + (3, 30 * self.balance_factor), + (4, 40 * self.balance_factor), + (5, 50 * self.balance_factor), + (6, 60 * self.balance_factor) + ], + vesting: vec![], + }), + elections: Some(elections::GenesisConfig::{ + members: vec![], + desired_members: 2, + desired_runners_up: self.desired_runners_up, + term_duration: 5, + }), + }.build_storage().unwrap().into() + } + } + + fn all_voters() -> Vec { + >::enumerate().map(|(v, _)| v).collect::>() + } + + fn balances(who: &u64) -> (u64, u64) { + (Balances::free_balance(who), Balances::reserved_balance(who)) + } + + fn has_lock(who: &u64) -> u64 { + let lock = Balances::locks(who)[0].clone(); + assert_eq!(lock.id, MODULE_ID); + lock.amount + } + + #[test] + fn params_should_work() { + with_externalities(&mut ExtBuilder::default().build(), || { + System::set_block_number(1); + assert_eq!(Elections::desired_members(), 2); + assert_eq!(Elections::term_duration(), 5); + assert_eq!(Elections::election_rounds(), 0); + + assert_eq!(Elections::members(), vec![]); + assert_eq!(Elections::runners_up(), vec![]); + + assert_eq!(Elections::candidates(), vec![]); + assert_eq!(>::decode_len().unwrap(), 0); + assert!(Elections::is_candidate(&1).is_err()); + + assert_eq!(all_voters(), vec![]); + assert_eq!(Elections::votes_of(&1), vec![]); + }); + } + + #[test] + fn simple_candidate_submission_should_work() { + with_externalities(&mut ExtBuilder::default().build(), || { + assert_eq!(Elections::candidates(), Vec::::new()); + assert!(Elections::is_candidate(&1).is_err()); + assert!(Elections::is_candidate(&2).is_err()); + + assert_eq!(balances(&1), (10, 0)); + assert_ok!(Elections::submit_candidacy(Origin::signed(1))); + assert_eq!(balances(&1), (7, 3)); + + assert_eq!(Elections::candidates(), vec![1]); + + assert!(Elections::is_candidate(&1).is_ok()); + assert!(Elections::is_candidate(&2).is_err()); + + assert_eq!(balances(&2), (20, 0)); + assert_ok!(Elections::submit_candidacy(Origin::signed(2))); + assert_eq!(balances(&2), (17, 3)); + + assert_eq!(Elections::candidates(), vec![1, 2]); + + assert!(Elections::is_candidate(&1).is_ok()); + assert!(Elections::is_candidate(&2).is_ok()); + }); + } + + #[test] + fn simple_candidate_submission_with_no_votes_should_work() { + with_externalities(&mut ExtBuilder::default().build(), || { + assert_eq!(Elections::candidates(), Vec::::new()); + + assert_ok!(Elections::submit_candidacy(Origin::signed(1))); + assert_ok!(Elections::submit_candidacy(Origin::signed(2))); + + assert!(Elections::is_candidate(&1).is_ok()); + assert!(Elections::is_candidate(&2).is_ok()); + assert_eq!(Elections::candidates(), vec![1, 2]); + + assert_eq!(Elections::members(), vec![]); + assert_eq!(Elections::runners_up(), vec![]); + + System::set_block_number(5); + assert_ok!(Elections::end_block(System::block_number())); + + assert!(Elections::is_candidate(&1).is_err()); + assert!(Elections::is_candidate(&2).is_err()); + assert_eq!(Elections::candidates(), vec![]); + + assert_eq!(Elections::members(), vec![]); + assert_eq!(Elections::runners_up(), vec![]); + }); + } + + #[test] + fn dupe_candidate_submission_should_not_work() { + with_externalities(&mut ExtBuilder::default().build(), || { + assert_eq!(Elections::candidates(), Vec::::new()); + assert_ok!(Elections::submit_candidacy(Origin::signed(1))); + assert_eq!(Elections::candidates(), vec![1]); + assert_noop!( + Elections::submit_candidacy(Origin::signed(1)), + "duplicate candidate submission" + ); + }); + } + + #[test] + fn member_candidacy_submission_should_not_work() { + // critically important to make sure that outgoing candidates and losers are not mixed up. + with_externalities(&mut ExtBuilder::default().build(), || { + assert_ok!(Elections::submit_candidacy(Origin::signed(5))); + assert_ok!(Elections::vote(Origin::signed(2), vec![5], 20)); + + System::set_block_number(5); + assert_ok!(Elections::end_block(System::block_number())); + + assert_eq!(Elections::members(), vec![5]); + assert_eq!(Elections::runners_up(), vec![]); + assert_eq!(Elections::candidates(), vec![]); + + assert_noop!( + Elections::submit_candidacy(Origin::signed(5)), + "member cannot re-submit candidacy" + ); + }); + } + + #[test] + fn poor_candidate_submission_should_not_work() { + with_externalities(&mut ExtBuilder::default().build(), || { + assert_eq!(Elections::candidates(), Vec::::new()); + assert_noop!( + Elections::submit_candidacy(Origin::signed(7)), + "candidate does not have enough funds" + ); + }); + } + + #[test] + fn simple_voting_should_work() { + with_externalities(&mut ExtBuilder::default().build(), || { + assert_eq!(Elections::candidates(), Vec::::new()); + assert_eq!(balances(&2), (20, 0)); + + assert_ok!(Elections::submit_candidacy(Origin::signed(5))); + assert_ok!(Elections::vote(Origin::signed(2), vec![5], 20)); + + assert_eq!(balances(&2), (18, 2)); + assert_eq!(has_lock(&2), 20); + }); + } + + #[test] + fn can_vote_with_custom_stake() { + with_externalities(&mut ExtBuilder::default().build(), || { + assert_eq!(Elections::candidates(), Vec::::new()); + assert_eq!(balances(&2), (20, 0)); + + assert_ok!(Elections::submit_candidacy(Origin::signed(5))); + assert_ok!(Elections::vote(Origin::signed(2), vec![5], 12)); + + assert_eq!(balances(&2), (18, 2)); + assert_eq!(has_lock(&2), 12); + }); + } + + #[test] + fn can_update_votes_and_stake() { + with_externalities(&mut ExtBuilder::default().build(), || { + assert_eq!(balances(&2), (20, 0)); + + assert_ok!(Elections::submit_candidacy(Origin::signed(5))); + assert_ok!(Elections::submit_candidacy(Origin::signed(4))); + assert_ok!(Elections::vote(Origin::signed(2), vec![5], 20)); + + assert_eq!(balances(&2), (18, 2)); + assert_eq!(has_lock(&2), 20); + assert_eq!(Elections::stake_of(2), 20); + + // can update; different stake; different lock and reserve. + assert_ok!(Elections::vote(Origin::signed(2), vec![5, 4], 15)); + assert_eq!(balances(&2), (18, 2)); + assert_eq!(has_lock(&2), 15); + assert_eq!(Elections::stake_of(2), 15); + }); + } + + #[test] + fn cannot_vote_for_no_candidate() { + with_externalities(&mut ExtBuilder::default().build(), || { + assert_noop!( + Elections::vote(Origin::signed(2), vec![], 20), + "cannot vote when no candidates or members exist" + ); + }); + } + + #[test] + fn can_vote_for_old_members_even_when_no_new_candidates() { + // let allowed_votes = candidates_count as usize + Self::members().len() + with_externalities(&mut ExtBuilder::default().build(), || { + assert_ok!(Elections::submit_candidacy(Origin::signed(5))); + assert_ok!(Elections::submit_candidacy(Origin::signed(4))); + + assert_ok!(Elections::vote(Origin::signed(2), vec![4, 5], 20)); + + System::set_block_number(5); + assert_ok!(Elections::end_block(System::block_number())); + + assert_eq!(Elections::members(), vec![4, 5]); + assert_eq!(Elections::candidates(), vec![]); + + assert_ok!(Elections::vote(Origin::signed(3), vec![4, 5], 10)); + }); + } + + #[test] + fn cannot_vote_for_more_than_candidates() { + with_externalities(&mut ExtBuilder::default().build(), || { + assert_ok!(Elections::submit_candidacy(Origin::signed(5))); + assert_ok!(Elections::submit_candidacy(Origin::signed(4))); + + assert_noop!( + Elections::vote(Origin::signed(2), vec![10, 20, 30], 20), + "cannot vote more than candidates" + ); + }); + } + + #[test] + fn cannot_vote_for_less_than_ed() { + with_externalities(&mut ExtBuilder::default().voter_bond(8).build(), || { + assert_ok!(Elections::submit_candidacy(Origin::signed(5))); + assert_ok!(Elections::submit_candidacy(Origin::signed(4))); + + assert_noop!( + Elections::vote(Origin::signed(2), vec![4], 1), + "cannot vote with stake less than minimum balance" + ); + }) + } + + #[test] + fn can_vote_for_more_than_total_balance_but_moot() { + with_externalities(&mut ExtBuilder::default().build(), || { + assert_ok!(Elections::submit_candidacy(Origin::signed(5))); + assert_ok!(Elections::submit_candidacy(Origin::signed(4))); + + assert_ok!(Elections::vote(Origin::signed(2), vec![4, 5], 30)); + // you can lie but won't get away with it. + assert_eq!(Elections::stake_of(2), 20); + assert_eq!(has_lock(&2), 20); + }); + } + + #[test] + fn remove_voter_should_work() { + with_externalities(&mut ExtBuilder::default().voter_bond(8).build(), || { + assert_ok!(Elections::submit_candidacy(Origin::signed(5))); + + assert_ok!(Elections::vote(Origin::signed(2), vec![5], 20)); + assert_ok!(Elections::vote(Origin::signed(3), vec![5], 30)); + + assert_eq_uvec!(all_voters(), vec![2, 3]); + assert_eq!(Elections::stake_of(2), 20); + assert_eq!(Elections::stake_of(3), 30); + assert_eq!(Elections::votes_of(2), vec![5]); + assert_eq!(Elections::votes_of(3), vec![5]); + + assert_ok!(Elections::remove_voter(Origin::signed(2))); + + assert_eq_uvec!(all_voters(), vec![3]); + assert_eq!(Elections::votes_of(2), vec![]); + assert_eq!(Elections::stake_of(2), 0); + + assert_eq!(balances(&2), (20, 0)); + assert_eq!(Balances::locks(&2).len(), 0); + }); + } + + #[test] + fn non_voter_remove_should_not_work() { + with_externalities(&mut ExtBuilder::default().build(), || { + assert_noop!(Elections::remove_voter(Origin::signed(3)), "must be a voter"); + }); + } + + #[test] + fn dupe_remove_should_fail() { + with_externalities(&mut ExtBuilder::default().build(), || { + assert_ok!(Elections::submit_candidacy(Origin::signed(5))); + assert_ok!(Elections::vote(Origin::signed(2), vec![5], 20)); + + assert_ok!(Elections::remove_voter(Origin::signed(2))); + assert_eq!(all_voters(), vec![]); + + assert_noop!(Elections::remove_voter(Origin::signed(2)), "must be a voter"); + }); + } + + #[test] + fn removed_voter_should_not_be_counted() { + with_externalities(&mut ExtBuilder::default().build(), || { + assert_ok!(Elections::submit_candidacy(Origin::signed(5))); + assert_ok!(Elections::submit_candidacy(Origin::signed(4))); + assert_ok!(Elections::submit_candidacy(Origin::signed(3))); + + assert_ok!(Elections::vote(Origin::signed(5), vec![5], 50)); + assert_ok!(Elections::vote(Origin::signed(4), vec![4], 40)); + assert_ok!(Elections::vote(Origin::signed(3), vec![3], 30)); + + assert_ok!(Elections::remove_voter(Origin::signed(4))); + + System::set_block_number(5); + assert_ok!(Elections::end_block(System::block_number())); + + assert_eq!(Elections::members(), vec![3, 5]); + }); + } + + #[test] + fn reporter_must_be_voter() { + with_externalities(&mut ExtBuilder::default().build(), || { + assert_noop!( + Elections::report_defunct_voter(Origin::signed(1), 2), + "reporter must be a voter", + ); + }); + } + + #[test] + fn can_detect_defunct_voter() { + with_externalities(&mut ExtBuilder::default().build(), || { + assert_ok!(Elections::submit_candidacy(Origin::signed(5))); + assert_ok!(Elections::submit_candidacy(Origin::signed(4))); + + assert_ok!(Elections::vote(Origin::signed(5), vec![5], 50)); + assert_ok!(Elections::vote(Origin::signed(4), vec![4], 40)); + assert_ok!(Elections::vote(Origin::signed(2), vec![4, 5], 20)); + // will be soon a defunct voter. + assert_ok!(Elections::vote(Origin::signed(3), vec![3], 30)); + + System::set_block_number(5); + assert_ok!(Elections::end_block(System::block_number())); + + assert_eq!(Elections::members(), vec![4, 5]); + assert_eq!(Elections::candidates(), vec![]); + + // all of them have a member that they voted for. + assert_eq!(Elections::is_defunct_voter(&5), false); + assert_eq!(Elections::is_defunct_voter(&4), false); + assert_eq!(Elections::is_defunct_voter(&2), false); + + // defunct + assert_eq!(Elections::is_defunct_voter(&3), true); + + assert_ok!(Elections::submit_candidacy(Origin::signed(1))); + assert_ok!(Elections::vote(Origin::signed(1), vec![1], 10)); + + // has a candidate voted for. + assert_eq!(Elections::is_defunct_voter(&1), false); + + }); + } + + #[test] + fn report_voter_should_work_and_earn_reward() { + with_externalities(&mut ExtBuilder::default().build(), || { + assert_ok!(Elections::submit_candidacy(Origin::signed(5))); + assert_ok!(Elections::submit_candidacy(Origin::signed(4))); + + assert_ok!(Elections::vote(Origin::signed(5), vec![5], 50)); + assert_ok!(Elections::vote(Origin::signed(4), vec![4], 40)); + assert_ok!(Elections::vote(Origin::signed(2), vec![4, 5], 20)); + // will be soon a defunct voter. + assert_ok!(Elections::vote(Origin::signed(3), vec![3], 30)); + + System::set_block_number(5); + assert_ok!(Elections::end_block(System::block_number())); + + assert_eq!(Elections::members(), vec![4, 5]); + assert_eq!(Elections::candidates(), vec![]); + + assert_eq!(balances(&3), (28, 2)); + assert_eq!(balances(&5), (45, 5)); + + assert_ok!(Elections::report_defunct_voter(Origin::signed(5), 3)); + assert_eq!( + System::events()[1].event, + Event::elections(RawEvent::VoterReported(3, 5, true)) + ); + + assert_eq!(balances(&3), (28, 0)); + assert_eq!(balances(&5), (47, 5)); + }); + } + + #[test] + fn report_voter_should_slash_when_bad_report() { + with_externalities(&mut ExtBuilder::default().build(), || { + with_externalities(&mut ExtBuilder::default().build(), || { + assert_ok!(Elections::submit_candidacy(Origin::signed(5))); + assert_ok!(Elections::submit_candidacy(Origin::signed(4))); + + assert_ok!(Elections::vote(Origin::signed(5), vec![5], 50)); + assert_ok!(Elections::vote(Origin::signed(4), vec![4], 40)); + + System::set_block_number(5); + assert_ok!(Elections::end_block(System::block_number())); + + assert_eq!(Elections::members(), vec![4, 5]); + assert_eq!(Elections::candidates(), vec![]); + + assert_eq!(balances(&4), (35, 5)); + assert_eq!(balances(&5), (45, 5)); + + assert_ok!(Elections::report_defunct_voter(Origin::signed(5), 4)); + assert_eq!( + System::events()[1].event, + Event::elections(RawEvent::VoterReported(4, 5, false)) + ); + + assert_eq!(balances(&4), (35, 5)); + assert_eq!(balances(&5), (45, 3)); + }); + }); + } + + + #[test] + fn simple_voting_rounds_should_work() { + with_externalities(&mut ExtBuilder::default().build(), || { + assert_ok!(Elections::submit_candidacy(Origin::signed(5))); + assert_ok!(Elections::submit_candidacy(Origin::signed(4))); + assert_ok!(Elections::submit_candidacy(Origin::signed(3))); + + assert_ok!(Elections::vote(Origin::signed(2), vec![5], 20)); + assert_ok!(Elections::vote(Origin::signed(4), vec![4], 15)); + assert_ok!(Elections::vote(Origin::signed(3), vec![3], 30)); + + assert_eq_uvec!(all_voters(), vec![2, 3, 4]); + + assert_eq!(Elections::votes_of(2), vec![5]); + assert_eq!(Elections::votes_of(3), vec![3]); + assert_eq!(Elections::votes_of(4), vec![4]); + + assert_eq!(Elections::candidates(), vec![3, 4, 5]); + assert_eq!(>::decode_len().unwrap(), 3); + + assert_eq!(Elections::election_rounds(), 0); + + System::set_block_number(5); + assert_ok!(Elections::end_block(System::block_number())); + + assert_eq!(Elections::members(), vec![3, 5]); + assert_eq!(Elections::runners_up(), vec![]); + assert_eq_uvec!(all_voters(), vec![2, 3, 4]); + assert_eq!(Elections::candidates(), vec![]); + assert_eq!(>::decode_len().unwrap(), 0); + + assert_eq!(Elections::election_rounds(), 1); + }); + } + + #[test] + fn defunct_voter_will_be_counted() { + with_externalities(&mut ExtBuilder::default().build(), || { + assert_ok!(Elections::submit_candidacy(Origin::signed(5))); + + // This guy's vote is pointless for this round. + assert_ok!(Elections::vote(Origin::signed(3), vec![4], 30)); + assert_ok!(Elections::vote(Origin::signed(5), vec![5], 50)); + + System::set_block_number(5); + assert_ok!(Elections::end_block(System::block_number())); + + assert_eq!(Elections::members(), vec![5]); + assert_eq!(Elections::election_rounds(), 1); + + // but now it has a valid target. + assert_ok!(Elections::submit_candidacy(Origin::signed(4))); + + System::set_block_number(10); + assert_ok!(Elections::end_block(System::block_number())); + + // candidate 4 is affected by an old vote. + assert_eq!(Elections::members(), vec![4, 5]); + assert_eq!(Elections::election_rounds(), 2); + assert_eq_uvec!(all_voters(), vec![3, 5]); + }); + } + + #[test] + fn only_desired_seats_are_chosen() { + with_externalities(&mut ExtBuilder::default().build(), || { + assert_ok!(Elections::submit_candidacy(Origin::signed(5))); + assert_ok!(Elections::submit_candidacy(Origin::signed(4))); + assert_ok!(Elections::submit_candidacy(Origin::signed(3))); + assert_ok!(Elections::submit_candidacy(Origin::signed(2))); + + assert_ok!(Elections::vote(Origin::signed(2), vec![2], 20)); + assert_ok!(Elections::vote(Origin::signed(3), vec![3], 30)); + assert_ok!(Elections::vote(Origin::signed(4), vec![4], 40)); + assert_ok!(Elections::vote(Origin::signed(5), vec![5], 50)); + + System::set_block_number(5); + assert_ok!(Elections::end_block(System::block_number())); + + assert_eq!(Elections::election_rounds(), 1); + assert_eq!(Elections::members(), vec![4, 5]); + }); + } + + #[test] + fn phragmen_should_not_self_vote() { + with_externalities(&mut ExtBuilder::default().build(), || { + assert_ok!(Elections::submit_candidacy(Origin::signed(5))); + assert_ok!(Elections::submit_candidacy(Origin::signed(4))); + + System::set_block_number(5); + assert_ok!(Elections::end_block(System::block_number())); + + assert_eq!(Elections::candidates(), vec![]); + assert_eq!(Elections::election_rounds(), 1); + assert_eq!(Elections::members(), vec![]); + }); + } + + #[test] + fn runners_up_should_be_kept() { + with_externalities(&mut ExtBuilder::default().desired_runners_up(2).build(), || { + assert_ok!(Elections::submit_candidacy(Origin::signed(5))); + assert_ok!(Elections::submit_candidacy(Origin::signed(4))); + assert_ok!(Elections::submit_candidacy(Origin::signed(3))); + assert_ok!(Elections::submit_candidacy(Origin::signed(2))); + + assert_ok!(Elections::vote(Origin::signed(2), vec![3], 20)); + assert_ok!(Elections::vote(Origin::signed(3), vec![2], 30)); + assert_ok!(Elections::vote(Origin::signed(4), vec![5], 40)); + assert_ok!(Elections::vote(Origin::signed(5), vec![4], 50)); + + System::set_block_number(5); + assert_ok!(Elections::end_block(System::block_number())); + // sorted based on account id. + assert_eq!(Elections::members(), vec![4, 5]); + // sorted based on merit (least -> most) + assert_eq!(Elections::runners_up(), vec![3, 2]); + + // runner ups are still locked. + assert_eq!(balances(&4), (35, 5)); + assert_eq!(balances(&5), (45, 5)); + assert_eq!(balances(&3), (25, 5)); + }); + } + + #[test] + fn runners_up_should_be_next_candidates() { + with_externalities(&mut ExtBuilder::default().desired_runners_up(2).build(), || { + assert_ok!(Elections::submit_candidacy(Origin::signed(5))); + assert_ok!(Elections::submit_candidacy(Origin::signed(4))); + assert_ok!(Elections::submit_candidacy(Origin::signed(3))); + assert_ok!(Elections::submit_candidacy(Origin::signed(2))); + + assert_ok!(Elections::vote(Origin::signed(2), vec![2], 20)); + assert_ok!(Elections::vote(Origin::signed(3), vec![3], 30)); + assert_ok!(Elections::vote(Origin::signed(4), vec![4], 40)); + assert_ok!(Elections::vote(Origin::signed(5), vec![5], 50)); + + System::set_block_number(5); + assert_ok!(Elections::end_block(System::block_number())); + assert_eq!(Elections::members(), vec![4, 5]); + assert_eq!(Elections::runners_up(), vec![2, 3]); + + assert_ok!(Elections::vote(Origin::signed(5), vec![5], 15)); + + System::set_block_number(10); + assert_ok!(Elections::end_block(System::block_number())); + assert_eq!(Elections::members(), vec![3, 4]); + assert_eq!(Elections::runners_up(), vec![5, 2]); + }); + } + + #[test] + fn runners_up_lose_bond_once_outgoing() { + with_externalities(&mut ExtBuilder::default().desired_runners_up(1).build(), || { + assert_ok!(Elections::submit_candidacy(Origin::signed(5))); + assert_ok!(Elections::submit_candidacy(Origin::signed(4))); + assert_ok!(Elections::submit_candidacy(Origin::signed(2))); + + assert_ok!(Elections::vote(Origin::signed(2), vec![2], 20)); + assert_ok!(Elections::vote(Origin::signed(4), vec![4], 40)); + assert_ok!(Elections::vote(Origin::signed(5), vec![5], 50)); + + System::set_block_number(5); + assert_ok!(Elections::end_block(System::block_number())); + assert_eq!(Elections::members(), vec![4, 5]); + + assert_eq!(Elections::runners_up(), vec![2]); + assert_eq!(balances(&2), (15, 5)); + + assert_ok!(Elections::submit_candidacy(Origin::signed(3))); + assert_ok!(Elections::vote(Origin::signed(3), vec![3], 30)); + + System::set_block_number(10); + assert_ok!(Elections::end_block(System::block_number())); + assert_eq!(Elections::members(), vec![4, 5]); + + assert_eq!(Elections::runners_up(), vec![3]); + assert_eq!(balances(&3), (25, 5)); + assert_eq!(balances(&2), (15, 2)); + }); + } + + #[test] + fn current_members_are_always_implicitly_next_candidate() { + with_externalities(&mut ExtBuilder::default().build(), || { + assert_ok!(Elections::submit_candidacy(Origin::signed(5))); + assert_ok!(Elections::submit_candidacy(Origin::signed(4))); + + assert_ok!(Elections::vote(Origin::signed(4), vec![4], 40)); + assert_ok!(Elections::vote(Origin::signed(5), vec![5], 50)); + + System::set_block_number(5); + assert_ok!(Elections::end_block(System::block_number())); + + assert_eq!(Elections::members(), vec![4, 5]); + assert_eq!(Elections::election_rounds(), 1); + + assert_ok!(Elections::submit_candidacy(Origin::signed(2))); + assert_ok!(Elections::vote(Origin::signed(2), vec![2], 20)); + + assert_ok!(Elections::submit_candidacy(Origin::signed(3))); + assert_ok!(Elections::vote(Origin::signed(3), vec![3], 30)); + + assert_ok!(Elections::remove_voter(Origin::signed(4))); + + // 5 will persist as candidates despite not being in the list. + assert_eq!(Elections::candidates(), vec![2, 3]); + + System::set_block_number(10); + assert_ok!(Elections::end_block(System::block_number())); + + // 4 removed; 5 and 3 are the new best. + assert_eq!(Elections::members(), vec![3, 5]); + }); + } + + #[test] + fn election_state_is_uninterrupted() { + // what I mean by uninterrupted: + // given no input or stimulants the same members are re-elected. + with_externalities(&mut ExtBuilder::default().desired_runners_up(2).build(), || { + assert_ok!(Elections::submit_candidacy(Origin::signed(5))); + assert_ok!(Elections::submit_candidacy(Origin::signed(4))); + assert_ok!(Elections::submit_candidacy(Origin::signed(3))); + assert_ok!(Elections::submit_candidacy(Origin::signed(2))); + + assert_ok!(Elections::vote(Origin::signed(5), vec![5], 50)); + assert_ok!(Elections::vote(Origin::signed(4), vec![4], 40)); + assert_ok!(Elections::vote(Origin::signed(3), vec![3], 30)); + assert_ok!(Elections::vote(Origin::signed(2), vec![2], 20)); + + let check_at_block = |b: u32| { + System::set_block_number(b.into()); + assert_ok!(Elections::end_block(System::block_number())); + // we keep re-electing the same folks. + assert_eq!(Elections::members(), vec![4, 5]); + assert_eq!(Elections::runners_up(), vec![2, 3]); + // no new candidates but old members and runners-up are always added. + assert_eq!(Elections::candidates(), vec![]); + assert_eq!(Elections::election_rounds(), b / 5); + assert_eq_uvec!(all_voters(), vec![2, 3, 4, 5]); + }; + + // this state will always persist when no further input is given. + check_at_block(5); + check_at_block(10); + check_at_block(15); + check_at_block(20); + }); + } + + #[test] + fn remove_members_triggers_election() { + with_externalities(&mut ExtBuilder::default().build(), || { + assert_ok!(Elections::submit_candidacy(Origin::signed(5))); + assert_ok!(Elections::submit_candidacy(Origin::signed(4))); + + assert_ok!(Elections::vote(Origin::signed(4), vec![4], 40)); + assert_ok!(Elections::vote(Origin::signed(5), vec![5], 50)); + + System::set_block_number(5); + assert_ok!(Elections::end_block(System::block_number())); + assert_eq!(Elections::members(), vec![4, 5]); + assert_eq!(Elections::election_rounds(), 1); + + // a new candidate + assert_ok!(Elections::submit_candidacy(Origin::signed(3))); + assert_ok!(Elections::vote(Origin::signed(3), vec![3], 30)); + + assert_ok!(Elections::remove_member(Origin::ROOT, 4)); + + assert_eq!(balances(&4), (35, 2)); // slashed + assert_eq!(Elections::election_rounds(), 2); // new election round + assert_eq!(Elections::members(), vec![3, 5]); // new members + }); + } + + #[test] + fn seats_should_be_released_when_no_vote() { + with_externalities(&mut ExtBuilder::default().build(), || { + assert_ok!(Elections::submit_candidacy(Origin::signed(5))); + assert_ok!(Elections::submit_candidacy(Origin::signed(4))); + assert_ok!(Elections::submit_candidacy(Origin::signed(3))); + + assert_ok!(Elections::vote(Origin::signed(2), vec![3], 20)); + assert_ok!(Elections::vote(Origin::signed(3), vec![3], 30)); + assert_ok!(Elections::vote(Origin::signed(4), vec![4], 40)); + assert_ok!(Elections::vote(Origin::signed(5), vec![5], 50)); + + assert_eq!(>::decode_len().unwrap(), 3); + + assert_eq!(Elections::election_rounds(), 0); + + System::set_block_number(5); + assert_ok!(Elections::end_block(System::block_number())); + assert_eq!(Elections::members(), vec![3, 5]); + assert_eq!(Elections::election_rounds(), 1); + + assert_ok!(Elections::remove_voter(Origin::signed(2))); + assert_ok!(Elections::remove_voter(Origin::signed(3))); + assert_ok!(Elections::remove_voter(Origin::signed(4))); + assert_ok!(Elections::remove_voter(Origin::signed(5))); + + // meanwhile, no one cares to become a candidate again. + System::set_block_number(10); + assert_ok!(Elections::end_block(System::block_number())); + assert_eq!(Elections::members(), vec![]); + assert_eq!(Elections::election_rounds(), 2); + }); + } + + #[test] + fn outgoing_will_get_the_bond_back() { + with_externalities(&mut ExtBuilder::default().build(), || { + assert_eq!(balances(&5), (50, 0)); + + assert_ok!(Elections::submit_candidacy(Origin::signed(5))); + assert_eq!(balances(&5), (47, 3)); + + assert_ok!(Elections::vote(Origin::signed(5), vec![5], 50)); + assert_eq!(balances(&5), (45, 5)); + + System::set_block_number(5); + assert_ok!(Elections::end_block(System::block_number())); + assert_eq!(Elections::members(), vec![5]); + + assert_ok!(Elections::remove_voter(Origin::signed(5))); + assert_eq!(balances(&5), (47, 3)); + + System::set_block_number(10); + assert_ok!(Elections::end_block(System::block_number())); + assert_eq!(Elections::members(), vec![]); + + assert_eq!(balances(&5), (50, 0)); + }); + } + + #[test] + fn losers_will_lose_the_bond() { + with_externalities(&mut ExtBuilder::default().build(), || { + assert_ok!(Elections::submit_candidacy(Origin::signed(5))); + assert_ok!(Elections::submit_candidacy(Origin::signed(3))); + + assert_ok!(Elections::vote(Origin::signed(4), vec![5], 40)); + + assert_eq!(balances(&5), (47, 3)); + assert_eq!(balances(&3), (27, 3)); + + System::set_block_number(5); + assert_ok!(Elections::end_block(System::block_number())); + + assert_eq!(Elections::members(), vec![5]); + + // winner + assert_eq!(balances(&5), (47, 3)); + // loser + assert_eq!(balances(&3), (27, 0)); + }); + } + + #[test] + fn incoming_outgoing_are_reported() { + with_externalities(&mut ExtBuilder::default().build(), || { + assert_ok!(Elections::submit_candidacy(Origin::signed(4))); + assert_ok!(Elections::submit_candidacy(Origin::signed(5))); + + assert_ok!(Elections::vote(Origin::signed(4), vec![4], 40)); + assert_ok!(Elections::vote(Origin::signed(5), vec![5], 50)); + + System::set_block_number(5); + assert_ok!(Elections::end_block(System::block_number())); + assert_eq!(Elections::members(), vec![4, 5]); + + assert_ok!(Elections::submit_candidacy(Origin::signed(1))); + assert_ok!(Elections::submit_candidacy(Origin::signed(2))); + assert_ok!(Elections::submit_candidacy(Origin::signed(3))); + + // 5 will change their vote and becomes an `outgoing` + assert_ok!(Elections::vote(Origin::signed(5), vec![4], 8)); + // 4 will stay in the set + assert_ok!(Elections::vote(Origin::signed(4), vec![4], 40)); + // 3 will become a winner + assert_ok!(Elections::vote(Origin::signed(3), vec![3], 30)); + // these two are losers. + assert_ok!(Elections::vote(Origin::signed(2), vec![2], 20)); + assert_ok!(Elections::vote(Origin::signed(1), vec![1], 10)); + + System::set_block_number(10); + assert_ok!(Elections::end_block(System::block_number())); + + // 3, 4 are new members, must still be bonded, nothing slashed. + assert_eq!(Elections::members(), vec![3, 4]); + assert_eq!(balances(&3), (25, 5)); + assert_eq!(balances(&4), (35, 5)); + + // 1 is a loser, slashed by 3. + assert_eq!(balances(&1), (5, 2)); + + // 5 is an outgoing loser, it will get their bond back. + assert_eq!(balances(&5), (48, 2)); + + assert_eq!(System::events()[0].event, Event::elections(RawEvent::NewTerm(vec![4, 5]))); + }) + } + + #[test] + fn invalid_votes_are_moot() { + with_externalities(&mut ExtBuilder::default().build(), || { + assert_ok!(Elections::submit_candidacy(Origin::signed(4))); + assert_ok!(Elections::submit_candidacy(Origin::signed(3))); + + assert_ok!(Elections::vote(Origin::signed(3), vec![3], 30)); + assert_ok!(Elections::vote(Origin::signed(4), vec![4], 40)); + assert_ok!(Elections::vote(Origin::signed(5), vec![10], 50)); + + System::set_block_number(5); + assert_ok!(Elections::end_block(System::block_number())); + + assert_eq_uvec!(Elections::members(), vec![3, 4]); + assert_eq!(Elections::election_rounds(), 1); + }); + } +} diff --git a/srml/elections/Cargo.toml b/srml/elections/Cargo.toml index d6043bb2d02337d2363c91b74348ccdef3ded0ec..88d147ac087aa69cf22e10f545fd333b5f2e63de 100644 --- a/srml/elections/Cargo.toml +++ b/srml/elections/Cargo.toml @@ -5,18 +5,18 @@ authors = ["Parity Technologies "] edition = "2018" [dependencies] -serde = { version = "1.0", optional = true } -safe-mix = { version = "1.0", default-features = false} +serde = { version = "1.0.101", optional = true } +safe-mix = { version = "1.0.0", default-features = false } codec = { package = "parity-scale-codec", version = "1.0.0", default-features = false, features = ["derive"] } primitives = { package = "substrate-primitives", path = "../../core/primitives", default-features = false } rstd = { package = "sr-std", path = "../../core/sr-std", default-features = false } -runtime_io = { package = "sr-io", path = "../../core/sr-io", default-features = false } +runtime-io = { package = "sr-io", path = "../../core/sr-io", default-features = false } sr-primitives = { path = "../../core/sr-primitives", default-features = false } -srml-support = { path = "../support", default-features = false } +support = { package = "srml-support", path = "../support", default-features = false } system = { package = "srml-system", path = "../system", default-features = false } [dev-dependencies] -hex-literal = "0.2.0" +hex-literal = "0.2.1" balances = { package = "srml-balances", path = "../balances" } [features] @@ -27,8 +27,8 @@ std = [ "primitives/std", "rstd/std", "serde", - "runtime_io/std", - "srml-support/std", + "runtime-io/std", + "support/std", "sr-primitives/std", "system/std", ] diff --git a/srml/elections/src/lib.rs b/srml/elections/src/lib.rs index a96588e84a3c6b1d44283fd30172a36ce24ff860..8c90090349727b3611e1a5b9683499fc3eb3c41a 100644 --- a/srml/elections/src/lib.rs +++ b/srml/elections/src/lib.rs @@ -24,11 +24,10 @@ #![recursion_limit="128"] use rstd::prelude::*; -use sr_primitives::traits::{Zero, One, StaticLookup, Bounded, Saturating}; -use sr_primitives::weights::SimpleDispatchInfo; -use runtime_io::print; -use srml_support::{ - StorageValue, StorageMap, +use sr_primitives::{ + print, traits::{Zero, One, StaticLookup, Bounded, Saturating}, weights::SimpleDispatchInfo, +}; +use support::{ dispatch::Result, decl_storage, decl_event, ensure, decl_module, traits::{ Currency, ExistenceRequirement, Get, LockableCurrency, LockIdentifier, @@ -38,6 +37,9 @@ use srml_support::{ use codec::{Encode, Decode}; use system::{self, ensure_signed, ensure_root}; +mod mock; +mod tests; + // no polynomial attacks: // // all unbonded public operations should be constant time. @@ -126,29 +128,23 @@ pub enum CellStatus { const MODULE_ID: LockIdentifier = *b"py/elect"; +/// Number of voters grouped in one chunk. pub const VOTER_SET_SIZE: usize = 64; +/// NUmber of approvals grouped in one chunk. pub const APPROVAL_SET_SIZE: usize = 8; type BalanceOf = <::Currency as Currency<::AccountId>>::Balance; type NegativeImbalanceOf = <::Currency as Currency<::AccountId>>::NegativeImbalance; +/// Index used to access chunks. type SetIndex = u32; +/// Index used to count voting rounds. pub type VoteIndex = u32; - -// all three must be in sync. +/// Underlying data type of the approvals. type ApprovalFlag = u32; -pub const APPROVAL_FLAG_MASK: ApprovalFlag = 0x8000_0000; -pub const APPROVAL_FLAG_LEN: usize = 32; - -pub const DEFAULT_CANDIDACY_BOND: u32 = 9; -pub const DEFAULT_VOTING_BOND: u32 = 0; -pub const DEFAULT_VOTING_FEE: u32 = 0; -pub const DEFAULT_PRESENT_SLASH_PER_VOTER: u32 = 1; -pub const DEFAULT_CARRY_COUNT: u32 = 2; -pub const DEFAULT_INACTIVE_GRACE_PERIOD: u32 = 1; -pub const DEFAULT_VOTING_PERIOD: u32 = 1000; -pub const DEFAULT_DECAY_RATIO: u32 = 24; +/// Number of approval flags that can fit into [`ApprovalFlag`] type. +const APPROVAL_FLAG_LEN: usize = 32; pub trait Trait: system::Trait { type Event: From> + Into<::Event>; @@ -184,6 +180,9 @@ pub trait Trait: system::Trait { /// _hole_ index and replace it. type VotingFee: Get>; + /// Minimum about that can be used as the locked value for voting. + type MinimumVotingLock: Get>; + /// The punishment, per voter, if you provide an invalid presentation. A /// reasonable default value is 1. type PresentSlashPerVoter: Get>; @@ -212,6 +211,7 @@ pub trait Trait: system::Trait { decl_storage! { trait Store for Module as Council { // ---- parameters + /// How long to give each top candidate to present themselves after the vote ends. pub PresentationDuration get(presentation_duration) config(): T::BlockNumber; /// How long each position is active for. @@ -220,23 +220,24 @@ decl_storage! { pub DesiredSeats get(desired_seats) config(): u32; // ---- permanent state (always relevant, changes only at the finalization of voting) - /// The current membership. When there's a vote going on, this should still be used for executive - /// matters. The block number (second element in the tuple) is the block that their position is - /// active until (calculated by the sum of the block number when the member was elected - /// and their term duration). + + /// The current membership. When there's a vote going on, this should still be used for + /// executive matters. The block number (second element in the tuple) is the block that + /// their position is active until (calculated by the sum of the block number when the + /// member was elected and their term duration). pub Members get(members) config(): Vec<(T::AccountId, T::BlockNumber)>; /// The total number of vote rounds that have happened or are in progress. pub VoteCount get(vote_index): VoteIndex; // ---- persistent state (always relevant, changes constantly) - /// A list of votes for each voter. The votes are stored as numeric values and parsed in a bit-wise manner. - /// - /// In order to get a human-readable representation (`Vec`), use [`all_approvals_of`]. - /// - /// Furthermore, each vector of scalars is chunked with the cap of `APPROVAL_SET_SIZE`. + + // A list of votes for each voter. The votes are stored as numeric values and parsed in a + // bit-wise manner. In order to get a human-readable representation (`Vec`), use + // [`all_approvals_of`]. Furthermore, each vector of scalars is chunked with the cap of + // `APPROVAL_SET_SIZE`. pub ApprovalsOf get(approvals_of): map (T::AccountId, SetIndex) => Vec; - /// The vote index and list slot that the candidate `who` was registered or `None` if they are not - /// currently registered. + /// The vote index and list slot that the candidate `who` was registered or `None` if they + /// are not currently registered. pub RegisterInfoOf get(candidate_reg_info): map T::AccountId => Option<(VoteIndex, u32)>; /// Basic information about a voter. pub VoterInfoOf get(voter_info): map T::AccountId => Option>>; @@ -252,11 +253,13 @@ decl_storage! { pub CandidateCount get(candidate_count): u32; // ---- temporary state (only relevant during finalization/presentation) + /// The accounts holding the seats that will become free on the next tally. pub NextFinalize get(next_finalize): Option<(T::BlockNumber, u32, Vec)>; - /// Get the leaderboard if we're in the presentation phase. The first element is the weight of each entry; - /// It may be the direct summed approval stakes, or a weighted version of it. - pub Leaderboard get(leaderboard): Option, T::AccountId)> >; // ORDERED low -> high + /// Get the leaderboard if we're in the presentation phase. The first element is the weight + /// of each entry; It may be the direct summed approval stakes, or a weighted version of it. + /// Sorted from low to high. + pub Leaderboard get(leaderboard): Option, T::AccountId)> >; /// Who is able to vote for whom. Value is the fund-holding account, key is the /// vote-transaction-sending account. @@ -294,6 +297,9 @@ decl_module! { /// is 1000. const VotingPeriod: T::BlockNumber = T::VotingPeriod::get(); + /// Minimum about that can be used as the locked value for voting. + const MinimumVotingLock: BalanceOf = T::MinimumVotingLock::get(); + /// Decay factor of weight when being accumulated. It should typically be set to /// __at least__ `membership_size -1` to keep the collective secure. /// When set to `N`, it indicates `(1/N)^t` of staked is decayed at weight @@ -306,26 +312,26 @@ decl_module! { /// The chunk size of the approval vector. const APPROVAL_SET_SIZE: u32 = APPROVAL_SET_SIZE as u32; - fn deposit_event() = default; + fn deposit_event() = default; /// Set candidate approvals. Approval slots stay valid as long as candidates in those slots /// are registered. /// - /// Locks the total balance of caller indefinitely. - /// Only [`retract_voter`] or [`reap_inactive_voter`] can unlock the balance. + /// Locks `value` from the balance of `origin` indefinitely. Only [`retract_voter`] or + /// [`reap_inactive_voter`] can unlock the balance. /// /// `hint` argument is interpreted differently based on: - /// - if `origin` is setting approvals for the first time: The index will be checked - /// for being a valid _hole_ in the voter list. + /// - if `origin` is setting approvals for the first time: The index will be checked for + /// being a valid _hole_ in the voter list. /// - if the hint is correctly pointing to a hole, no fee is deducted from `origin`. - /// - Otherwise, the call will succeed but the index is ignored and simply a push to the last chunk - /// with free space happens. If the new push causes a new chunk to be created, a fee indicated by - /// [`VotingFee`] is deducted. + /// - Otherwise, the call will succeed but the index is ignored and simply a push to the + /// last chunk with free space happens. If the new push causes a new chunk to be + /// created, a fee indicated by [`VotingFee`] is deducted. /// - if `origin` is already a voter: the index __must__ be valid and point to the correct - /// position of the `origin` in the current voters list. + /// position of the `origin` in the current voters list. /// - /// Note that any trailing `false` votes in `votes` is ignored; In approval voting, not voting for a candidate - /// and voting false, are equal. + /// Note that any trailing `false` votes in `votes` is ignored; In approval voting, not + /// voting for a candidate and voting false, are equal. /// /// # /// - O(1). @@ -333,13 +339,19 @@ decl_module! { /// - Argument `votes` is limited in length to number of candidates. /// # #[weight = SimpleDispatchInfo::FixedNormal(2_500_000)] - fn set_approvals(origin, votes: Vec, #[compact] index: VoteIndex, hint: SetIndex) -> Result { + fn set_approvals( + origin, + votes: Vec, + #[compact] index: VoteIndex, + hint: SetIndex, + #[compact] value: BalanceOf + ) -> Result { let who = ensure_signed(origin)?; - Self::do_set_approvals(who, votes, index, hint) + Self::do_set_approvals(who, votes, index, hint, value) } - /// Set candidate approvals from a proxy. Approval slots stay valid as long as candidates in those slots - /// are registered. + /// Set candidate approvals from a proxy. Approval slots stay valid as long as candidates in + /// those slots are registered. /// /// # /// - Same as `set_approvals` with one additional storage read. @@ -348,15 +360,16 @@ decl_module! { fn proxy_set_approvals(origin, votes: Vec, #[compact] index: VoteIndex, - hint: SetIndex + hint: SetIndex, + #[compact] value: BalanceOf ) -> Result { let who = Self::proxy(ensure_signed(origin)?).ok_or("not a proxy")?; - Self::do_set_approvals(who, votes, index, hint) + Self::do_set_approvals(who, votes, index, hint, value) } /// Remove a voter. For it not to be a bond-consuming no-op, all approved candidate indices - /// must now be either unregistered or registered to a candidate that registered the slot after - /// the voter gave their last approval set. + /// must now be either unregistered or registered to a candidate that registered the slot + /// after the voter gave their last approval set. /// /// Both indices must be provided as explained in [`voter_at`] function. /// @@ -380,7 +393,8 @@ decl_module! { ensure!(!Self::presentation_active(), "cannot reap during presentation period"); ensure!(Self::voter_info(&reporter).is_some(), "reporter must be a voter"); - let info = Self::voter_info(&who).ok_or("target for inactivity cleanup must be active")?; + let info = Self::voter_info(&who) + .ok_or("target for inactivity cleanup must be active")?; let last_active = info.last_active; ensure!(assumed_vote_index == Self::vote_index(), "vote index not current"); @@ -419,8 +433,8 @@ decl_module! { ); if valid { - // This only fails if `reporter` doesn't exist, which it clearly must do since its the origin. - // Still, it's no more harmful to propagate any error at this point. + // This only fails if `reporter` doesn't exist, which it clearly must do since its + // the origin. Still, it's no more harmful to propagate any error at this point. T::Currency::repatriate_reserved(&who, &reporter, T::VotingBond::get())?; Self::deposit_event(RawEvent::VoterReaped(who, reporter)); } else { @@ -496,9 +510,10 @@ decl_module! { CandidateCount::put(count as u32 + 1); } - /// Claim that `signed` is one of the top Self::carry_count() + current_vote().1 candidates. - /// Only works if the `block_number >= current_vote().0` and `< current_vote().0 + presentation_duration()` - /// `signed` should have at least + /// Claim that `candidate` is one of the top `carry_count + desired_seats` candidates. Only + /// works iff the presentation period is active. `candidate` should have at least collected + /// some non-zero `total` votes and `origin` must have enough funds to pay for a potential + /// slash. /// /// # /// - O(voters) compute. @@ -514,12 +529,13 @@ decl_module! { let who = ensure_signed(origin)?; ensure!( !total.is_zero(), - "stake deposited to present winner and be added to leaderboard should be non-zero" + "stake deposited to present winner and be added to leaderboard should be non-zero", ); let candidate = T::Lookup::lookup(candidate)?; ensure!(index == Self::vote_index(), "index not current"); - let (_, _, expiring) = Self::next_finalize().ok_or("cannot present outside of presentation period")?; + let (_, _, expiring) = Self::next_finalize() + .ok_or("cannot present outside of presentation period")?; let bad_presentation_punishment = T::PresentSlashPerVoter::get() * BalanceOf::::from(Self::voter_count() as u32); @@ -528,11 +544,15 @@ decl_module! { "presenter must have sufficient slashable funds" ); - let mut leaderboard = Self::leaderboard().ok_or("leaderboard must exist while present phase active")?; + let mut leaderboard = Self::leaderboard() + .ok_or("leaderboard must exist while present phase active")?; ensure!(total > leaderboard[0].0, "candidate not worthy of leaderboard"); if let Some(p) = Self::members().iter().position(|&(ref c, _)| c == &candidate) { - ensure!(p < expiring.len(), "candidate must not form a duplicated member if elected"); + ensure!( + p < expiring.len(), + "candidate must not form a duplicated member if elected" + ); } let voters = Self::all_voters(); @@ -681,8 +701,8 @@ impl Module { } else { // next tally begins once enough members expire to bring members below desired. if desired_seats <= coming { - // the entire amount of desired seats is less than those new members - we'll have - // to wait until they expire. + // the entire amount of desired seats is less than those new members - we'll + // have to wait until they expire. Some(next_possible + Self::term_duration()) } else { Some(c[c.len() - (desired_seats - coming) as usize].1) @@ -723,19 +743,33 @@ impl Module { /// Actually do the voting. /// /// The voter index must be provided as explained in [`voter_at`] function. - fn do_set_approvals(who: T::AccountId, votes: Vec, index: VoteIndex, hint: SetIndex) -> Result { - let candidates = Self::candidates(); + fn do_set_approvals( + who: T::AccountId, + votes: Vec, + index: VoteIndex, + hint: SetIndex, + value: BalanceOf, + ) -> Result { + let candidates_len = ::Candidates::decode_len().unwrap_or(0_usize); ensure!(!Self::presentation_active(), "no approval changes during presentation period"); ensure!(index == Self::vote_index(), "incorrect vote index"); - ensure!(!candidates.is_empty(), "amount of candidates to receive approval votes should be non-zero"); - // Prevent a vote from voters that provide a list of votes that exceeds the candidates length - // since otherwise an attacker may be able to submit a very long list of `votes` that far exceeds - // the amount of candidates and waste more computation than a reasonable voting bond would cover. - ensure!(candidates.len() >= votes.len(), "amount of candidate votes cannot exceed amount of candidates"); + ensure!( + !candidates_len.is_zero(), + "amount of candidates to receive approval votes should be non-zero" + ); + // Prevent a vote from voters that provide a list of votes that exceeds the candidates + // length since otherwise an attacker may be able to submit a very long list of `votes` that + // far exceeds the amount of candidates and waste more computation than a reasonable voting + // bond would cover. + ensure!( + candidates_len >= votes.len(), + "amount of candidate votes cannot exceed amount of candidates" + ); + ensure!(value >= T::MinimumVotingLock::get(), "locked value must be more than limit"); // Amount to be locked up. - let mut locked_balance = T::Currency::total_balance(&who); + let mut locked_balance = value.min(T::Currency::total_balance(&who)); let mut pot_to_set = Zero::zero(); let hint = hint as usize; @@ -765,10 +799,10 @@ impl Module { CellStatus::Head | CellStatus::Occupied => { // Either occupied or out-of-range. let next = Self::next_nonfull_voter_set(); - let mut set = Self::voters(next); + let set_len = >::decode_len(next).unwrap_or(0_usize); // Caused a new set to be created. Pay for it. // This is the last potential error. Writes will begin afterwards. - if set.is_empty() { + if set_len == 0 { let imbalance = T::Currency::withdraw( &who, T::VotingFee::get(), @@ -779,8 +813,10 @@ impl Module { // NOTE: this is safe since the `withdraw()` will check this. locked_balance -= T::VotingFee::get(); } - Self::checked_push_voter(&mut set, who.clone(), next); - >::insert(next, set); + if set_len + 1 == VOTER_SET_SIZE { + NextVoterSet::put(next + 1); + } + >::append_or_insert(next, &[Some(who.clone())][..]) } } @@ -793,7 +829,7 @@ impl Module { &who, locked_balance, T::BlockNumber::max_value(), - WithdrawReasons::except(WithdrawReason::TransactionPayment), + WithdrawReasons::all(), ); >::insert( @@ -815,28 +851,33 @@ impl Module { let members = Self::members(); let desired_seats = Self::desired_seats() as usize; let number = >::block_number(); - let expiring = members.iter().take_while(|i| i.1 <= number).map(|i| i.0.clone()).collect::>(); + let expiring = + members.iter().take_while(|i| i.1 <= number).map(|i| i.0.clone()).collect::>(); let retaining_seats = members.len() - expiring.len(); if retaining_seats < desired_seats { let empty_seats = desired_seats - retaining_seats; - >::put((number + Self::presentation_duration(), empty_seats as u32, expiring)); + >::put( + (number + Self::presentation_duration(), empty_seats as u32, expiring) + ); // initialize leaderboard. let leaderboard_size = empty_seats + T::CarryCount::get() as usize; - >::put(vec![(Zero::zero(), T::AccountId::default()); leaderboard_size]); + >::put(vec![(BalanceOf::::zero(), T::AccountId::default()); leaderboard_size]); Self::deposit_event(RawEvent::TallyStarted(empty_seats as u32)); } } - /// Finalize the vote, removing each of the `removals` and inserting `seats` of the most approved - /// candidates in their place. If the total number of members is less than the desired membership - /// a new vote is started. - /// Clears all presented candidates, returning the bond of the elected ones. + /// Finalize the vote, removing each of the `removals` and inserting `seats` of the most + /// approved candidates in their place. If the total number of members is less than the desired + /// membership a new vote is started. Clears all presented candidates, returning the bond of the + /// elected ones. fn finalize_tally() -> Result { let (_, coming, expiring): (T::BlockNumber, u32, Vec) = - >::take().ok_or("finalize can only be called after a tally is started.")?; - let leaderboard: Vec<(BalanceOf, T::AccountId)> = >::take().unwrap_or_default(); + >::take() + .ok_or("finalize can only be called after a tally is started.")?; + let leaderboard: Vec<(BalanceOf, T::AccountId)> = >::take() + .unwrap_or_default(); let new_expiry = >::block_number() + Self::term_duration(); // return bond to winners. @@ -892,15 +933,25 @@ impl Module { count += 1; } for (old, new) in candidates.iter().zip(new_candidates.iter()) { + // candidate is not a runner up. if old != new { // removed - kill it >::remove(old); + + // and candidate is not a winner. + if incoming.iter().find(|e| *e == old).is_none() { + // slash the bond. + let (imbalance, _) = T::Currency::slash_reserved(&old, T::CandidacyBond::get()); + T::LoserCandidate::on_unbalanced(imbalance); + } } } // discard any superfluous slots. - if let Some(last_index) = new_candidates.iter().rposition(|c| *c != T::AccountId::default()) { - new_candidates.truncate(last_index + 1); - } + if let Some(last_index) = new_candidates + .iter() + .rposition(|c| *c != T::AccountId::default()) { + new_candidates.truncate(last_index + 1); + } Self::deposit_event(RawEvent::TallyFinalized(incoming, outgoing)); @@ -910,18 +961,6 @@ impl Module { Ok(()) } - fn checked_push_voter(set: &mut Vec>, who: T::AccountId, index: u32) { - let len = set.len(); - - // Defensive only: this should never happen. Don't push since it will break more things. - if len == VOTER_SET_SIZE { return; } - - set.push(Some(who)); - if len + 1 == VOTER_SET_SIZE { - NextVoterSet::put(index + 1); - } - } - /// Get the set and vector index of a global voter index. /// /// Note that this function does not take holes into account. @@ -966,8 +1005,8 @@ impl Module { } } - /// A more sophisticated version of `voter_at`. Will be kept separate as most often it is an overdue - /// compared to `voter_at`. Only used when setting approvals. + /// A more sophisticated version of `voter_at`. Will be kept separate as most often it is an + /// overdue compared to `voter_at`. Only used when setting approvals. fn cell_status(set_index: SetIndex, vec_index: usize) -> CellStatus { let set = Self::voters(set_index); if vec_index < set.len() { @@ -987,13 +1026,15 @@ impl Module { approvals_flag_vec .chunks(APPROVAL_SET_SIZE) .enumerate() - .for_each(|(index, slice)| >::insert((who.clone(), index as SetIndex), slice.to_vec())); + .for_each(|(index, slice)| >::insert( + (&who, index as SetIndex), slice) + ); } /// shorthand for fetching a specific approval of a voter at a specific (global) index. /// - /// Using this function to read a vote is preferred as it reads `APPROVAL_SET_SIZE` items of type - /// `ApprovalFlag` from storage at most; not all of them. + /// Using this function to read a vote is preferred as it reads `APPROVAL_SET_SIZE` items of + /// type `ApprovalFlag` from storage at most; not all of them. /// /// Note that false is returned in case of no-vote or an explicit `false`. fn approvals_of_at(who: &T::AccountId, index: usize) -> bool { @@ -1012,7 +1053,6 @@ impl Module { /// Return true of the bit `n` of scalar `x` is set to `1` and false otherwise. fn bit_at(x: ApprovalFlag, n: usize) -> bool { if n < APPROVAL_FLAG_LEN { - // x & ( APPROVAL_FLAG_MASK >> n ) != 0 x & ( 1 << n ) != 0 } else { false @@ -1047,7 +1087,9 @@ impl Module { let mut result = Vec::with_capacity(chunk.len()); if chunk.is_empty() { return vec![] } chunk.into_iter() - .map(|num| (0..APPROVAL_FLAG_LEN).map(|bit| Self::bit_at(num, bit)).collect::>()) + .map(|num| + (0..APPROVAL_FLAG_LEN).map(|bit| Self::bit_at(num, bit)).collect::>() + ) .for_each(|c| { let last_approve = match c.iter().rposition(|n| *n) { Some(index) => index + 1, @@ -1109,1768 +1151,3 @@ impl Module { r } } - -#[cfg(test)] -mod tests { - use super::*; - use std::cell::RefCell; - use srml_support::{assert_ok, assert_err, assert_noop, parameter_types}; - use runtime_io::with_externalities; - use primitives::{H256, Blake2Hasher}; - use sr_primitives::{ - Perbill, traits::{BlakeTwo256, IdentityLookup, Block as BlockT}, testing::Header, BuildStorage - }; - use crate as elections; - - parameter_types! { - pub const BlockHashCount: u64 = 250; - pub const MaximumBlockWeight: u32 = 1024; - pub const MaximumBlockLength: u32 = 2 * 1024; - pub const AvailableBlockRatio: Perbill = Perbill::one(); - } - impl system::Trait for Test { - type Origin = Origin; - type Index = u64; - type BlockNumber = u64; - type Call = (); - type Hash = H256; - type Hashing = BlakeTwo256; - type AccountId = u64; - type Lookup = IdentityLookup; - type Header = Header; - type Event = Event; - type WeightMultiplierUpdate = (); - type BlockHashCount = BlockHashCount; - type MaximumBlockWeight = MaximumBlockWeight; - type MaximumBlockLength = MaximumBlockLength; - type AvailableBlockRatio = AvailableBlockRatio; - } - parameter_types! { - pub const ExistentialDeposit: u64 = 0; - pub const TransferFee: u64 = 0; - pub const CreationFee: u64 = 0; - pub const TransactionBaseFee: u64 = 0; - pub const TransactionByteFee: u64 = 0; - } - impl balances::Trait for Test { - type Balance = u64; - type OnNewAccount = (); - type OnFreeBalanceZero = (); - type Event = Event; - type TransactionPayment = (); - type TransferPayment = (); - type DustRemoval = (); - type ExistentialDeposit = ExistentialDeposit; - type TransferFee = TransferFee; - type CreationFee = CreationFee; - type TransactionBaseFee = TransactionBaseFee; - type TransactionByteFee = TransactionByteFee; - type WeightToFee = (); - } - parameter_types! { - pub const CandidacyBond: u64 = 3; - pub const CarryCount: u32 = 2; - pub const InactiveGracePeriod: u32 = 1; - pub const VotingPeriod: u64 = 4; - } - - thread_local! { - static VOTER_BOND: RefCell = RefCell::new(0); - static VOTING_FEE: RefCell = RefCell::new(0); - static PRESENT_SLASH_PER_VOTER: RefCell = RefCell::new(0); - static DECAY_RATIO: RefCell = RefCell::new(0); - static MEMBERS: RefCell> = RefCell::new(vec![]); - } - - pub struct VotingBond; - impl Get for VotingBond { - fn get() -> u64 { VOTER_BOND.with(|v| *v.borrow()) } - } - - pub struct VotingFee; - impl Get for VotingFee { - fn get() -> u64 { VOTING_FEE.with(|v| *v.borrow()) } - } - - pub struct PresentSlashPerVoter; - impl Get for PresentSlashPerVoter { - fn get() -> u64 { PRESENT_SLASH_PER_VOTER.with(|v| *v.borrow()) } - } - - pub struct DecayRatio; - impl Get for DecayRatio { - fn get() -> u32 { DECAY_RATIO.with(|v| *v.borrow()) } - } - - pub struct TestChangeMembers; - impl ChangeMembers for TestChangeMembers { - fn change_members_sorted(incoming: &[u64], outgoing: &[u64], new: &[u64]) { - let mut old_plus_incoming = MEMBERS.with(|m| m.borrow().to_vec()); - old_plus_incoming.extend_from_slice(incoming); - old_plus_incoming.sort(); - let mut new_plus_outgoing = new.to_vec(); - new_plus_outgoing.extend_from_slice(outgoing); - new_plus_outgoing.sort(); - assert_eq!(old_plus_incoming, new_plus_outgoing); - - MEMBERS.with(|m| *m.borrow_mut() = new.to_vec()); - } - } - - impl Trait for Test { - type Event = Event; - type Currency = Balances; - type BadPresentation = (); - type BadReaper = (); - type BadVoterIndex = (); - type LoserCandidate = (); - type ChangeMembers = TestChangeMembers; - type CandidacyBond = CandidacyBond; - type VotingBond = VotingBond; - type VotingFee = VotingFee; - type PresentSlashPerVoter = PresentSlashPerVoter; - type CarryCount = CarryCount; - type InactiveGracePeriod = InactiveGracePeriod; - type VotingPeriod = VotingPeriod; - type DecayRatio = DecayRatio; - } - - pub type Block = sr_primitives::generic::Block; - pub type UncheckedExtrinsic = sr_primitives::generic::UncheckedExtrinsic; - - srml_support::construct_runtime!( - pub enum Test where - Block = Block, - NodeBlock = Block, - UncheckedExtrinsic = UncheckedExtrinsic - { - System: system::{Module, Call, Event}, - Balances: balances::{Module, Call, Event, Config}, - Elections: elections::{Module, Call, Event, Config}, - } - ); - - pub struct ExtBuilder { - balance_factor: u64, - decay_ratio: u32, - voting_fee: u64, - voter_bond: u64, - bad_presentation_punishment: u64, - } - - impl Default for ExtBuilder { - fn default() -> Self { - Self { - balance_factor: 1, - decay_ratio: 24, - voting_fee: 0, - voter_bond: 0, - bad_presentation_punishment: 1, - } - } - } - - impl ExtBuilder { - pub fn balance_factor(mut self, factor: u64) -> Self { - self.balance_factor = factor; - self - } - pub fn decay_ratio(mut self, ratio: u32) -> Self { - self.decay_ratio = ratio; - self - } - pub fn voting_fee(mut self, fee: u64) -> Self { - self.voting_fee = fee; - self - } - pub fn bad_presentation_punishment(mut self, fee: u64) -> Self { - self.bad_presentation_punishment = fee; - self - } - pub fn voter_bond(mut self, fee: u64) -> Self { - self.voter_bond = fee; - self - } - pub fn build(self) -> runtime_io::TestExternalities { - VOTER_BOND.with(|v| *v.borrow_mut() = self.voter_bond); - VOTING_FEE.with(|v| *v.borrow_mut() = self.voting_fee); - PRESENT_SLASH_PER_VOTER.with(|v| *v.borrow_mut() = self.bad_presentation_punishment); - DECAY_RATIO.with(|v| *v.borrow_mut() = self.decay_ratio); - GenesisConfig { - balances: Some(balances::GenesisConfig::{ - balances: vec![ - (1, 10 * self.balance_factor), - (2, 20 * self.balance_factor), - (3, 30 * self.balance_factor), - (4, 40 * self.balance_factor), - (5, 50 * self.balance_factor), - (6, 60 * self.balance_factor) - ], - vesting: vec![], - }), - elections: Some(elections::GenesisConfig::{ - members: vec![], - desired_seats: 2, - presentation_duration: 2, - term_duration: 5, - }), - }.build_storage().unwrap().into() - } - } - - fn voter_ids() -> Vec { - Elections::all_voters().iter().map(|v| v.unwrap_or(0) ).collect::>() - } - - fn vote(i: u64, l: usize) { - let _ = Balances::make_free_balance_be(&i, 20); - assert_ok!(Elections::set_approvals(Origin::signed(i), (0..l).map(|_| true).collect::>(), 0, 0)); - } - - fn vote_at(i: u64, l: usize, index: VoteIndex) { - let _ = Balances::make_free_balance_be(&i, 20); - assert_ok!(Elections::set_approvals(Origin::signed(i), (0..l).map(|_| true).collect::>(), 0, index)); - } - - fn create_candidate(i: u64, index: u32) { - let _ = Balances::make_free_balance_be(&i, 20); - assert_ok!(Elections::submit_candidacy(Origin::signed(i), index)); - } - - fn bond() -> u64 { - ::VotingBond::get() - } - - #[test] - fn bool_to_flag_should_work() { - with_externalities(&mut ExtBuilder::default().build(), || { - assert_eq!(Elections::bool_to_flag(vec![]), vec![]); - assert_eq!(Elections::bool_to_flag(vec![false]), vec![0]); - assert_eq!(Elections::bool_to_flag(vec![true]), vec![1]); - assert_eq!(Elections::bool_to_flag(vec![true, true, true, true]), vec![15]); - assert_eq!(Elections::bool_to_flag(vec![true, true, true, true, true]), vec![15 + 16]); - - let set_1 = vec![ - true, false, false, false, // 0x1 - false, true, true, true, // 0xE - ]; - assert_eq!( - Elections::bool_to_flag(set_1.clone()), - vec![0x00_00_00_E1_u32] - ); - assert_eq!( - Elections::flag_to_bool(vec![0x00_00_00_E1_u32]), - set_1 - ); - - let set_2 = vec![ - false, false, false, true, // 0x8 - false, true, false, true, // 0xA - ]; - assert_eq!( - Elections::bool_to_flag(set_2.clone()), - vec![0x00_00_00_A8_u32] - ); - assert_eq!( - Elections::flag_to_bool(vec![0x00_00_00_A8_u32]), - set_2 - ); - - let mut rhs = (0..100/APPROVAL_FLAG_LEN).map(|_| 0xFFFFFFFF_u32).collect::>(); - // NOTE: this might be need change based on `APPROVAL_FLAG_LEN`. - rhs.extend(vec![0x00_00_00_0F]); - assert_eq!( - Elections::bool_to_flag((0..100).map(|_| true).collect()), - rhs - ) - }) - } - - #[test] - fn params_should_work() { - with_externalities(&mut ExtBuilder::default().build(), || { - System::set_block_number(1); - assert_eq!(Elections::next_vote_from(1), 4); - assert_eq!(Elections::next_vote_from(4), 4); - assert_eq!(Elections::next_vote_from(5), 8); - assert_eq!(Elections::vote_index(), 0); - assert_eq!(Elections::presentation_duration(), 2); - assert_eq!(Elections::term_duration(), 5); - assert_eq!(Elections::desired_seats(), 2); - - assert_eq!(Elections::members(), vec![]); - assert_eq!(Elections::next_tally(), Some(4)); - assert_eq!(Elections::presentation_active(), false); - assert_eq!(Elections::next_finalize(), None); - - assert_eq!(Elections::candidates(), Vec::::new()); - assert_eq!(Elections::is_a_candidate(&1), false); - assert_eq!(Elections::candidate_reg_info(1), None); - - assert_eq!(Elections::voters(0), Vec::>::new()); - assert_eq!(Elections::voter_info(1), None); - assert_eq!(Elections::all_approvals_of(&1), vec![]); - }); - } - - #[test] - fn voter_set_growth_should_work() { - with_externalities(&mut ExtBuilder::default().build(), || { - assert_ok!(Elections::submit_candidacy(Origin::signed(2), 0)); - assert_ok!(Elections::submit_candidacy(Origin::signed(3), 1)); - - // create 65. 64 (set0) + 1 (set1) - (1..=63).for_each(|i| vote(i, 2)); - assert_eq!(Elections::next_nonfull_voter_set(), 0); - vote(64, 2); - assert_eq!(Elections::next_nonfull_voter_set(), 1); - vote(65, 2); - - let set1 = Elections::voters(0); - let set2 = Elections::voters(1); - - assert_eq!(set1.len(), 64); - assert_eq!(set2.len(), 1); - - assert_eq!(set1[0], Some(1)); - assert_eq!(set1[10], Some(11)); - assert_eq!(set2[0], Some(65)); - }) - } - - #[test] - fn voter_set_reclaim_should_work() { - with_externalities(&mut ExtBuilder::default().build(), || { - assert_ok!(Elections::submit_candidacy(Origin::signed(2), 0)); - assert_ok!(Elections::submit_candidacy(Origin::signed(3), 1)); - - (1..=129).for_each(|i| vote(i, 2)); - assert_eq!(Elections::next_nonfull_voter_set(), 2); - - assert_ok!(Elections::retract_voter(Origin::signed(11), 10)); - - assert_ok!(Elections::retract_voter(Origin::signed(66), 65)); - assert_ok!(Elections::retract_voter(Origin::signed(67), 66)); - - // length does not show it but holes do exist. - assert_eq!(Elections::voters(0).len(), 64); - assert_eq!(Elections::voters(1).len(), 64); - assert_eq!(Elections::voters(2).len(), 1); - - assert_eq!(Elections::voters(0)[10], None); - assert_eq!(Elections::voters(1)[1], None); - assert_eq!(Elections::voters(1)[2], None); - // Next set with capacity is 2. - assert_eq!(Elections::next_nonfull_voter_set(), 2); - - // But we can fill a hole. - vote_at(130, 2, 10); - - // Nothing added to set 2. A hole was filled. - assert_eq!(Elections::voters(0).len(), 64); - assert_eq!(Elections::voters(1).len(), 64); - assert_eq!(Elections::voters(2).len(), 1); - - // and the next two (scheduled) to the second set. - assert_eq!(Elections::next_nonfull_voter_set(), 2); - }) - } - - #[test] - fn approvals_set_growth_should_work() { - with_externalities(&mut ExtBuilder::default().build(), || { - // create candidates and voters. - (1..=250).for_each(|i| create_candidate(i, (i-1) as u32)); - (1..=250).for_each(|i| vote(i, i as usize)); - - // all approvals of should return the exact expected vector. - assert_eq!(Elections::all_approvals_of(&180), (0..180).map(|_| true).collect::>()); - - assert_eq!(Elections::all_approvals_of(&32), (0..32).map(|_| true).collect::>()); - assert_eq!(Elections::all_approvals_of(&8), (0..8).map(|_| true).collect::>()); - assert_eq!(Elections::all_approvals_of(&64), (0..64).map(|_| true).collect::>()); - assert_eq!(Elections::all_approvals_of(&65), (0..65).map(|_| true).collect::>()); - assert_eq!(Elections::all_approvals_of(&63), (0..63).map(|_| true).collect::>()); - - // NOTE: assuming that APPROVAL_SET_SIZE is more or less small-ish. Might fail otherwise. - let full_sets = (180 / APPROVAL_FLAG_LEN) / APPROVAL_SET_SIZE; - let left_over = (180 / APPROVAL_FLAG_LEN) / APPROVAL_SET_SIZE; - let rem = 180 % APPROVAL_FLAG_LEN; - - // grab and check the last full set, if it exists. - if full_sets > 0 { - assert_eq!( - Elections::approvals_of((180, (full_sets-1) as SetIndex )), - Elections::bool_to_flag((0..APPROVAL_SET_SIZE * APPROVAL_FLAG_LEN).map(|_| true).collect::>()) - ); - } - - // grab and check the last, half-empty, set. - if left_over > 0 { - assert_eq!( - Elections::approvals_of((180, full_sets as SetIndex)), - Elections::bool_to_flag((0..left_over * APPROVAL_FLAG_LEN + rem).map(|_| true).collect::>()) - ); - } - }) - } - - - #[test] - fn cell_status_works() { - with_externalities(&mut ExtBuilder::default().build(), || { - assert_ok!(Elections::submit_candidacy(Origin::signed(2), 0)); - assert_ok!(Elections::submit_candidacy(Origin::signed(3), 1)); - - (1..=63).for_each(|i| vote(i, 2)); - - assert_ok!(Elections::retract_voter(Origin::signed(11), 10)); - assert_ok!(Elections::retract_voter(Origin::signed(21), 20)); - - assert_eq!(Elections::cell_status(0, 10), CellStatus::Hole); - assert_eq!(Elections::cell_status(0, 0), CellStatus::Occupied); - assert_eq!(Elections::cell_status(0, 20), CellStatus::Hole); - assert_eq!(Elections::cell_status(0, 63), CellStatus::Head); - assert_eq!(Elections::cell_status(1, 0), CellStatus::Head); - assert_eq!(Elections::cell_status(1, 10), CellStatus::Head); - }) - } - - #[test] - fn initial_set_approvals_ignores_voter_index() { - with_externalities(&mut ExtBuilder::default().build(), || { - assert_ok!(Elections::submit_candidacy(Origin::signed(2), 0)); - - // Last argument is essentially irrelevant. You might get or miss a tip. - assert_ok!(Elections::set_approvals(Origin::signed(3), vec![true], 0, 0)); - assert_ok!(Elections::set_approvals(Origin::signed(4), vec![true], 0, 5)); - assert_ok!(Elections::set_approvals(Origin::signed(5), vec![true], 0, 100)); - - // indices are more or less ignored. all is pushed. - assert_eq!(voter_ids(), vec![3, 4, 5]); - }) - } - - #[test] - fn bad_approval_index_slashes_voters_and_bond_reduces_stake() { - with_externalities(&mut ExtBuilder::default().voting_fee(5).voter_bond(2).build(), || { - assert_ok!(Elections::submit_candidacy(Origin::signed(2), 0)); - assert_ok!(Elections::submit_candidacy(Origin::signed(3), 1)); - - (1..=63).for_each(|i| vote(i, 2)); - assert_eq!(Balances::free_balance(&1), 20 - 5 - 2); // -5 fee -2 bond - assert_eq!(Balances::free_balance(&10), 20 - 2); - assert_eq!(Balances::free_balance(&60), 20 - 2); - - // still no fee - vote(64, 2); - assert_eq!(Balances::free_balance(&64), 20 - 2); // -2 bond - assert_eq!( - Elections::voter_info(&64).unwrap(), - VoterInfo { last_win: 0, last_active: 0, stake: 20, pot:0 } - ); - - assert_eq!(Elections::next_nonfull_voter_set(), 1); - - // now we charge the next voter. - vote(65, 2); - assert_eq!(Balances::free_balance(&65), 20 - 5 - 2); - assert_eq!( - Elections::voter_info(&65).unwrap(), - VoterInfo { last_win: 0, last_active: 0, stake: 15, pot:0 } - ); - }); - } - - #[test] - fn subsequent_set_approvals_checks_voter_index() { - with_externalities(&mut ExtBuilder::default().build(), || { - assert_ok!(Elections::submit_candidacy(Origin::signed(2), 0)); - - assert_ok!(Elections::set_approvals(Origin::signed(3), vec![true], 0, 0)); - assert_ok!(Elections::set_approvals(Origin::signed(4), vec![true], 0, 5)); - assert_ok!(Elections::set_approvals(Origin::signed(5), vec![true], 0, 100)); - - // invalid index - assert_noop!(Elections::set_approvals(Origin::signed(4), vec![true], 0, 5), "invalid voter index"); - // wrong index - assert_noop!(Elections::set_approvals(Origin::signed(4), vec![true], 0, 0), "wrong voter index"); - // correct - assert_ok!(Elections::set_approvals(Origin::signed(4), vec![true], 0, 1)); - }) - } - - #[test] - fn voter_index_does_not_take_holes_into_account() { - with_externalities(&mut ExtBuilder::default().build(), || { - assert_ok!(Elections::submit_candidacy(Origin::signed(2), 0)); - assert_ok!(Elections::submit_candidacy(Origin::signed(3), 1)); - - // create 65. 64 (set0) + 1 (set1) - (1..=65).for_each(|i| vote(i, 2)); - - // account 65 has global index 65. - assert_eq!(Elections::voter_at(64).unwrap(), 65); - - assert_ok!(Elections::retract_voter(Origin::signed(1), 0)); - assert_ok!(Elections::retract_voter(Origin::signed(2), 1)); - - // still the same. These holes are in some other set. - assert_eq!(Elections::voter_at(64).unwrap(), 65); - // proof: can submit a new approval with the old index. - assert_noop!(Elections::set_approvals(Origin::signed(65), vec![false, true], 0, 64 - 2), "wrong voter index"); - assert_ok!(Elections::set_approvals(Origin::signed(65), vec![false, true], 0, 64)); - }) - } - - #[test] - fn simple_candidate_submission_should_work() { - with_externalities(&mut ExtBuilder::default().build(), || { - System::set_block_number(1); - assert_eq!(Elections::candidates(), Vec::::new()); - assert_eq!(Elections::candidate_reg_info(1), None); - assert_eq!(Elections::candidate_reg_info(2), None); - assert_eq!(Elections::is_a_candidate(&1), false); - assert_eq!(Elections::is_a_candidate(&2), false); - - assert_ok!(Elections::submit_candidacy(Origin::signed(1), 0)); - assert_eq!(Elections::candidates(), vec![1]); - assert_eq!(Elections::candidate_reg_info(1), Some((0, 0))); - assert_eq!(Elections::candidate_reg_info(2), None); - assert_eq!(Elections::is_a_candidate(&1), true); - assert_eq!(Elections::is_a_candidate(&2), false); - - assert_ok!(Elections::submit_candidacy(Origin::signed(2), 1)); - assert_eq!(Elections::candidates(), vec![1, 2]); - assert_eq!(Elections::candidate_reg_info(1), Some((0, 0))); - assert_eq!(Elections::candidate_reg_info(2), Some((0, 1))); - assert_eq!(Elections::is_a_candidate(&1), true); - assert_eq!(Elections::is_a_candidate(&2), true); - }); - } - - fn new_test_ext_with_candidate_holes() -> runtime_io::TestExternalities { - let mut t = ExtBuilder::default().build(); - with_externalities(&mut t, || { - >::put(vec![0, 0, 1]); - CandidateCount::put(1); - >::insert(1, (0, 2)); - }); - t - } - - #[test] - fn candidate_submission_using_free_slot_should_work() { - let mut t = new_test_ext_with_candidate_holes(); - - with_externalities(&mut t, || { - System::set_block_number(1); - assert_eq!(Elections::candidates(), vec![0, 0, 1]); - - assert_ok!(Elections::submit_candidacy(Origin::signed(2), 1)); - assert_eq!(Elections::candidates(), vec![0, 2, 1]); - - assert_ok!(Elections::submit_candidacy(Origin::signed(3), 0)); - assert_eq!(Elections::candidates(), vec![3, 2, 1]); - }); - } - - #[test] - fn candidate_submission_using_alternative_free_slot_should_work() { - let mut t = new_test_ext_with_candidate_holes(); - - with_externalities(&mut t, || { - System::set_block_number(1); - assert_eq!(Elections::candidates(), vec![0, 0, 1]); - - assert_ok!(Elections::submit_candidacy(Origin::signed(2), 0)); - assert_eq!(Elections::candidates(), vec![2, 0, 1]); - - assert_ok!(Elections::submit_candidacy(Origin::signed(3), 1)); - assert_eq!(Elections::candidates(), vec![2, 3, 1]); - }); - } - - #[test] - fn candidate_submission_not_using_free_slot_should_not_work() { - let mut t = new_test_ext_with_candidate_holes(); - - with_externalities(&mut t, || { - System::set_block_number(1); - assert_noop!(Elections::submit_candidacy(Origin::signed(4), 3), "invalid candidate slot"); - }); - } - - #[test] - fn bad_candidate_slot_submission_should_not_work() { - with_externalities(&mut ExtBuilder::default().build(), || { - System::set_block_number(1); - assert_eq!(Elections::candidates(), Vec::::new()); - assert_noop!(Elections::submit_candidacy(Origin::signed(1), 1), "invalid candidate slot"); - }); - } - - #[test] - fn non_free_candidate_slot_submission_should_not_work() { - with_externalities(&mut ExtBuilder::default().build(), || { - System::set_block_number(1); - assert_eq!(Elections::candidates(), Vec::::new()); - assert_ok!(Elections::submit_candidacy(Origin::signed(1), 0)); - assert_eq!(Elections::candidates(), vec![1]); - assert_noop!(Elections::submit_candidacy(Origin::signed(2), 0), "invalid candidate slot"); - }); - } - - #[test] - fn dupe_candidate_submission_should_not_work() { - with_externalities(&mut ExtBuilder::default().build(), || { - System::set_block_number(1); - assert_eq!(Elections::candidates(), Vec::::new()); - assert_ok!(Elections::submit_candidacy(Origin::signed(1), 0)); - assert_eq!(Elections::candidates(), vec![1]); - assert_noop!(Elections::submit_candidacy(Origin::signed(1), 1), "duplicate candidate submission"); - }); - } - - #[test] - fn poor_candidate_submission_should_not_work() { - with_externalities(&mut ExtBuilder::default().build(), || { - System::set_block_number(1); - assert_eq!(Elections::candidates(), Vec::::new()); - assert_noop!(Elections::submit_candidacy(Origin::signed(7), 0), "candidate has not enough funds"); - }); - } - - #[test] - fn balance_should_lock_to_the_maximum() { - with_externalities(&mut ExtBuilder::default().build(), || { - System::set_block_number(1); - assert_eq!(Elections::candidates(), Vec::::new()); - assert_eq!(Balances::free_balance(&2), 20); - - assert_ok!(Elections::submit_candidacy(Origin::signed(5), 0)); - assert_ok!(Elections::set_approvals(Origin::signed(2), vec![true], 0, 0)); - - assert_eq!(Balances::free_balance(&2), 20 - bond() ); - assert_noop!(Balances::reserve(&2, 1), "account liquidity restrictions prevent withdrawal"); // locked. - - // deposit a bit more. - let _ = Balances::deposit_creating(&2, 100); - assert_ok!(Balances::reserve(&2, 1)); // locked but now has enough. - - assert_ok!(Elections::set_approvals(Origin::signed(2), vec![true], 0, 0)); - assert_noop!(Balances::reserve(&2, 1), "account liquidity restrictions prevent withdrawal"); // locked. - assert_eq!(Balances::locks(&2).len(), 1); - assert_eq!(Balances::locks(&2)[0].amount, 100 + 20); - - assert_ok!(Elections::retract_voter(Origin::signed(2), 0)); - - assert_eq!(Balances::locks(&2).len(), 0); - assert_eq!(Balances::free_balance(&2), 120 - 1); // 1 ok call to .reserve() happened. - assert_ok!(Balances::reserve(&2, 1)); // unlocked. - }); - } - - #[test] - fn balance_should_lock_on_submit_approvals_unlock_on_retract() { - with_externalities(&mut ExtBuilder::default().voter_bond(8).voting_fee(0).build(), || { - System::set_block_number(1); - assert_eq!(Elections::candidates(), Vec::::new()); - assert_eq!(Balances::free_balance(&2), 20); - - assert_ok!(Elections::submit_candidacy(Origin::signed(5), 0)); - assert_ok!(Elections::set_approvals(Origin::signed(2), vec![true], 0, 0)); - - assert_eq!(Balances::free_balance(&2), 12); // 20 - 8 (bond) - assert_noop!(Balances::reserve(&2, 10), "account liquidity restrictions prevent withdrawal"); // locked. - - assert_ok!(Elections::retract_voter(Origin::signed(2), 0)); - - assert_eq!(Balances::free_balance(&2), 20); - assert_ok!(Balances::reserve(&2, 10)); // unlocked. - }); - } - - #[test] - fn accumulating_weight_and_decaying_should_work() { - with_externalities(&mut ExtBuilder::default().balance_factor(10).build(), || { - System::set_block_number(4); - assert!(!Elections::presentation_active()); - - assert_ok!(Elections::submit_candidacy(Origin::signed(6), 0)); - assert_ok!(Elections::submit_candidacy(Origin::signed(5), 1)); - assert_ok!(Elections::submit_candidacy(Origin::signed(1), 2)); - - assert_ok!(Elections::set_approvals(Origin::signed(6), vec![true, false, false], 0, 0)); - assert_ok!(Elections::set_approvals(Origin::signed(5), vec![false, true, false], 0, 0)); - assert_ok!(Elections::set_approvals(Origin::signed(1), vec![false, false, true], 0, 0)); - - assert_ok!(Elections::end_block(System::block_number())); - - System::set_block_number(6); - assert!(Elections::presentation_active()); - - assert_eq!(Elections::present_winner(Origin::signed(6), 6, 600, 0), Ok(())); - assert_eq!(Elections::present_winner(Origin::signed(5), 5, 500, 0), Ok(())); - assert_eq!(Elections::present_winner(Origin::signed(1), 1, 100, 0), Ok(())); - assert_eq!(Elections::leaderboard(), Some(vec![(0, 0), (100, 1), (500, 5), (600, 6)])); - assert_ok!(Elections::end_block(System::block_number())); - - assert_eq!(Elections::members(), vec![(6, 11), (5, 11)]); - assert_eq!(Elections::voter_info(6).unwrap(), VoterInfo { last_win: 1, last_active: 0, stake: 600, pot: 0}); - assert_eq!(Elections::voter_info(5).unwrap(), VoterInfo { last_win: 1, last_active: 0, stake: 500, pot: 0}); - assert_eq!(Elections::voter_info(1).unwrap(), VoterInfo { last_win: 0, last_active: 0, stake: 100, pot: 0}); - - System::set_block_number(12); - // retract needed to unlock approval funds => submit candidacy again. - assert_ok!(Elections::retract_voter(Origin::signed(6), 0)); - assert_ok!(Elections::retract_voter(Origin::signed(5), 1)); - assert_ok!(Elections::submit_candidacy(Origin::signed(6), 0)); - assert_ok!(Elections::submit_candidacy(Origin::signed(5), 1)); - assert_ok!(Elections::set_approvals(Origin::signed(6), vec![true, false, false], 1, 0)); - assert_ok!(Elections::set_approvals(Origin::signed(5), vec![false, true, false], 1, 1)); - assert_ok!(Elections::end_block(System::block_number())); - - System::set_block_number(14); - assert!(Elections::presentation_active()); - assert_eq!(Elections::present_winner(Origin::signed(6), 6, 600, 1), Ok(())); - assert_eq!(Elections::present_winner(Origin::signed(5), 5, 500, 1), Ok(())); - assert_eq!(Elections::present_winner(Origin::signed(1), 1, 100 + Elections::get_offset(100, 1), 1), Ok(())); - assert_eq!(Elections::leaderboard(), Some(vec![(0, 0), (100 + 96, 1), (500, 5), (600, 6)])); - assert_ok!(Elections::end_block(System::block_number())); - - assert_eq!(Elections::members(), vec![(6, 19), (5, 19)]); - assert_eq!( - Elections::voter_info(6).unwrap(), - VoterInfo { last_win: 2, last_active: 1, stake: 600, pot:0 } - ); - assert_eq!(Elections::voter_info(5).unwrap(), VoterInfo { last_win: 2, last_active: 1, stake: 500, pot:0 }); - assert_eq!(Elections::voter_info(1).unwrap(), VoterInfo { last_win: 0, last_active: 0, stake: 100, pot:0 }); - - System::set_block_number(20); - assert_ok!(Elections::retract_voter(Origin::signed(6), 0)); - assert_ok!(Elections::retract_voter(Origin::signed(5), 1)); - assert_ok!(Elections::submit_candidacy(Origin::signed(6), 0)); - assert_ok!(Elections::submit_candidacy(Origin::signed(5), 1)); - assert_ok!(Elections::set_approvals(Origin::signed(6), vec![true, false, false], 2, 0)); - assert_ok!(Elections::set_approvals(Origin::signed(5), vec![false, true, false], 2, 1)); - assert_ok!(Elections::end_block(System::block_number())); - - System::set_block_number(22); - assert!(Elections::presentation_active()); - assert_eq!(Elections::present_winner(Origin::signed(6), 6, 600, 2), Ok(())); - assert_eq!(Elections::present_winner(Origin::signed(5), 5, 500, 2), Ok(())); - assert_eq!(Elections::present_winner(Origin::signed(1), 1, 100 + Elections::get_offset(100, 2), 2), Ok(())); - assert_eq!(Elections::leaderboard(), Some(vec![(0, 0), (100 + 96 + 93, 1), (500, 5), (600, 6)])); - assert_ok!(Elections::end_block(System::block_number())); - - assert_eq!(Elections::members(), vec![(6, 27), (5, 27)]); - assert_eq!( - Elections::voter_info(6).unwrap(), - VoterInfo { last_win: 3, last_active: 2, stake: 600, pot: 0} - ); - assert_eq!(Elections::voter_info(5).unwrap(), VoterInfo { last_win: 3, last_active: 2, stake: 500, pot: 0}); - assert_eq!(Elections::voter_info(1).unwrap(), VoterInfo { last_win: 0, last_active: 0, stake: 100, pot: 0}); - - - System::set_block_number(28); - assert_ok!(Elections::retract_voter(Origin::signed(6), 0)); - assert_ok!(Elections::retract_voter(Origin::signed(5), 1)); - assert_ok!(Elections::submit_candidacy(Origin::signed(6), 0)); - assert_ok!(Elections::submit_candidacy(Origin::signed(5), 1)); - assert_ok!(Elections::set_approvals(Origin::signed(6), vec![true, false, false], 3, 0)); - assert_ok!(Elections::set_approvals(Origin::signed(5), vec![false, true, false], 3, 1)); - assert_ok!(Elections::end_block(System::block_number())); - - System::set_block_number(30); - assert!(Elections::presentation_active()); - assert_eq!(Elections::present_winner(Origin::signed(6), 6, 600, 3), Ok(())); - assert_eq!(Elections::present_winner(Origin::signed(5), 5, 500, 3), Ok(())); - assert_eq!(Elections::present_winner(Origin::signed(1), 1, 100 + Elections::get_offset(100, 3), 3), Ok(())); - assert_eq!(Elections::leaderboard(), Some(vec![(0, 0), (100 + 96 + 93 + 90, 1), (500, 5), (600, 6)])); - assert_ok!(Elections::end_block(System::block_number())); - - assert_eq!(Elections::members(), vec![(6, 35), (5, 35)]); - assert_eq!( - Elections::voter_info(6).unwrap(), - VoterInfo { last_win: 4, last_active: 3, stake: 600, pot: 0} - ); - assert_eq!(Elections::voter_info(5).unwrap(), VoterInfo { last_win: 4, last_active: 3, stake: 500, pot: 0}); - assert_eq!(Elections::voter_info(1).unwrap(), VoterInfo { last_win: 0, last_active: 0, stake: 100, pot: 0}); - }) - } - - #[test] - fn winning_resets_accumulated_pot() { - with_externalities(&mut ExtBuilder::default().balance_factor(10).build(), || { - System::set_block_number(4); - assert!(!Elections::presentation_active()); - - assert_ok!(Elections::submit_candidacy(Origin::signed(6), 0)); - assert_ok!(Elections::submit_candidacy(Origin::signed(4), 1)); - assert_ok!(Elections::submit_candidacy(Origin::signed(3), 2)); - assert_ok!(Elections::submit_candidacy(Origin::signed(2), 3)); - - assert_ok!(Elections::set_approvals(Origin::signed(6), vec![true, false, false, false], 0, 0)); - assert_ok!(Elections::set_approvals(Origin::signed(4), vec![false, true, false, false], 0, 1)); - assert_ok!(Elections::set_approvals(Origin::signed(3), vec![false, false, true, true], 0, 2)); - assert_ok!(Elections::end_block(System::block_number())); - - System::set_block_number(6); - assert!(Elections::presentation_active()); - assert_eq!(Elections::present_winner(Origin::signed(6), 6, 600, 0), Ok(())); - assert_eq!(Elections::present_winner(Origin::signed(4), 4, 400, 0), Ok(())); - assert_eq!(Elections::present_winner(Origin::signed(3), 3, 300, 0), Ok(())); - assert_eq!(Elections::present_winner(Origin::signed(2), 2, 300, 0), Ok(())); - assert_eq!(Elections::leaderboard(), Some(vec![(300, 2), (300, 3), (400, 4), (600, 6)])); - assert_ok!(Elections::end_block(System::block_number())); - - assert_eq!(Elections::members(), vec![(6, 11), (4, 11)]); - - System::set_block_number(12); - assert_ok!(Elections::retract_voter(Origin::signed(6), 0)); - assert_ok!(Elections::retract_voter(Origin::signed(4), 1)); - assert_ok!(Elections::submit_candidacy(Origin::signed(6), 0)); - assert_ok!(Elections::submit_candidacy(Origin::signed(4), 1)); - assert_ok!(Elections::set_approvals(Origin::signed(6), vec![true, false, false, false], 1, 0)); - assert_ok!(Elections::set_approvals(Origin::signed(4), vec![false, true, false, false], 1, 1)); - assert_ok!(Elections::end_block(System::block_number())); - - System::set_block_number(14); - assert!(Elections::presentation_active()); - assert_eq!(Elections::present_winner(Origin::signed(6), 6, 600, 1), Ok(())); - assert_eq!(Elections::present_winner(Origin::signed(4), 4, 400, 1), Ok(())); - assert_eq!(Elections::present_winner(Origin::signed(3), 3, 300 + Elections::get_offset(300, 1), 1), Ok(())); - assert_eq!(Elections::present_winner(Origin::signed(2), 2, 300 + Elections::get_offset(300, 1), 1), Ok(())); - assert_eq!(Elections::leaderboard(), Some(vec![(400, 4), (588, 2), (588, 3), (600, 6)])); - assert_ok!(Elections::end_block(System::block_number())); - - assert_eq!(Elections::members(), vec![(6, 19), (3, 19)]); - - System::set_block_number(20); - assert_ok!(Elections::end_block(System::block_number())); - - System::set_block_number(22); - // 2 will not get re-elected with 300 + 288, instead just 300. - // because one of 3's candidates (3) won in previous round - // 4 on the other hand will get extra weight since it was unlucky. - assert_eq!(Elections::present_winner(Origin::signed(3), 2, 300, 2), Ok(())); - assert_eq!(Elections::present_winner(Origin::signed(4), 4, 400 + Elections::get_offset(400, 1), 2), Ok(())); - assert_ok!(Elections::end_block(System::block_number())); - - assert_eq!(Elections::members(), vec![(4, 27), (2, 27)]); - }) - } - - #[test] - fn resubmitting_approvals_stores_pot() { - with_externalities(&mut ExtBuilder::default() - .voter_bond(0) - .voting_fee(0) - .balance_factor(10) - .build(), - || { System::set_block_number(4); - assert!(!Elections::presentation_active()); - - assert_ok!(Elections::submit_candidacy(Origin::signed(6), 0)); - assert_ok!(Elections::submit_candidacy(Origin::signed(5), 1)); - assert_ok!(Elections::submit_candidacy(Origin::signed(1), 2)); - - assert_ok!(Elections::set_approvals(Origin::signed(6), vec![true, false, false], 0, 0)); - assert_ok!(Elections::set_approvals(Origin::signed(5), vec![false, true, false], 0, 1)); - assert_ok!(Elections::set_approvals(Origin::signed(1), vec![false, false, true], 0, 2)); - - assert_ok!(Elections::end_block(System::block_number())); - - System::set_block_number(6); - assert!(Elections::presentation_active()); - - assert_eq!(Elections::present_winner(Origin::signed(6), 6, 600, 0), Ok(())); - assert_eq!(Elections::present_winner(Origin::signed(5), 5, 500, 0), Ok(())); - assert_eq!(Elections::present_winner(Origin::signed(1), 1, 100, 0), Ok(())); - assert_eq!(Elections::leaderboard(), Some(vec![(0, 0), (100, 1), (500, 5), (600, 6)])); - assert_ok!(Elections::end_block(System::block_number())); - - assert_eq!(Elections::members(), vec![(6, 11), (5, 11)]); - - System::set_block_number(12); - assert_ok!(Elections::retract_voter(Origin::signed(6), 0)); - assert_ok!(Elections::retract_voter(Origin::signed(5), 1)); - assert_ok!(Elections::submit_candidacy(Origin::signed(6), 0)); - assert_ok!(Elections::submit_candidacy(Origin::signed(5), 1)); - assert_ok!(Elections::set_approvals(Origin::signed(6), vec![true, false, false], 1, 0)); - assert_ok!(Elections::set_approvals(Origin::signed(5), vec![false, true, false], 1, 1)); - // give 1 some new high balance - let _ = Balances::make_free_balance_be(&1, 997); - assert_ok!(Elections::set_approvals(Origin::signed(1), vec![false, false, true], 1, 2)); - assert_eq!(Elections::voter_info(1).unwrap(), - VoterInfo { - stake: 1000, // 997 + 3 which is candidacy bond. - pot: Elections::get_offset(100, 1), - last_active: 1, - last_win: 1, - } - ); - assert_ok!(Elections::end_block(System::block_number())); - - assert_eq!(Elections::members(), vec![(6, 11), (5, 11)]); - - System::set_block_number(14); - assert!(Elections::presentation_active()); - assert_eq!(Elections::present_winner(Origin::signed(6), 6, 600, 1), Ok(())); - assert_eq!(Elections::present_winner(Origin::signed(5), 5, 500, 1), Ok(())); - assert_eq!(Elections::present_winner(Origin::signed(1), 1, 1000 + 96 /* pot */, 1), Ok(())); - assert_eq!(Elections::leaderboard(), Some(vec![(0, 0), (500, 5), (600, 6), (1096, 1)])); - assert_ok!(Elections::end_block(System::block_number())); - - assert_eq!(Elections::members(), vec![(1, 19), (6, 19)]); - }) - } - - #[test] - fn get_offset_should_work() { - with_externalities(&mut ExtBuilder::default().build(), || { - assert_eq!(Elections::get_offset(100, 0), 0); - assert_eq!(Elections::get_offset(100, 1), 96); - assert_eq!(Elections::get_offset(100, 2), 96 + 93); - assert_eq!(Elections::get_offset(100, 3), 96 + 93 + 90); - assert_eq!(Elections::get_offset(100, 4), 96 + 93 + 90 + 87); - // limit - assert_eq!(Elections::get_offset(100, 1000), 100 * 24); - - assert_eq!(Elections::get_offset(50_000_000_000, 0), 0); - assert_eq!(Elections::get_offset(50_000_000_000, 1), 48_000_000_000); - assert_eq!(Elections::get_offset(50_000_000_000, 2), 48_000_000_000 + 46_080_000_000); - assert_eq!(Elections::get_offset(50_000_000_000, 3), 48_000_000_000 + 46_080_000_000 + 44_236_800_000); - assert_eq!( - Elections::get_offset(50_000_000_000, 4), - 48_000_000_000 + 46_080_000_000 + 44_236_800_000 + 42_467_328_000 - ); - // limit - assert_eq!(Elections::get_offset(50_000_000_000, 1000), 50_000_000_000 * 24); - }) - } - - #[test] - fn get_offset_with_zero_decay() { - with_externalities(&mut ExtBuilder::default().decay_ratio(0).build(), || { - assert_eq!(Elections::get_offset(100, 0), 0); - assert_eq!(Elections::get_offset(100, 1), 0); - assert_eq!(Elections::get_offset(100, 2), 0); - assert_eq!(Elections::get_offset(100, 3), 0); - // limit - assert_eq!(Elections::get_offset(100, 1000), 0); - }) - } - - #[test] - fn voting_should_work() { - with_externalities(&mut ExtBuilder::default().build(), || { - System::set_block_number(1); - - assert_ok!(Elections::submit_candidacy(Origin::signed(5), 0)); - - assert_ok!(Elections::set_approvals(Origin::signed(1), vec![true], 0, 0)); - assert_ok!(Elections::set_approvals(Origin::signed(4), vec![true], 0, 1)); - - assert_eq!(Elections::all_approvals_of(&1), vec![true]); - assert_eq!(Elections::all_approvals_of(&4), vec![true]); - assert_eq!(voter_ids(), vec![1, 4]); - - assert_ok!(Elections::submit_candidacy(Origin::signed(2), 1)); - assert_ok!(Elections::submit_candidacy(Origin::signed(3), 2)); - - assert_ok!(Elections::set_approvals(Origin::signed(2), vec![false, true, true], 0, 2)); - assert_ok!(Elections::set_approvals(Origin::signed(3), vec![false, true, true], 0, 3)); - - assert_eq!(Elections::all_approvals_of(&1), vec![true]); - assert_eq!(Elections::all_approvals_of(&4), vec![true]); - assert_eq!(Elections::all_approvals_of(&2), vec![false, true, true]); - assert_eq!(Elections::all_approvals_of(&3), vec![false, true, true]); - - assert_eq!(voter_ids(), vec![1, 4, 2, 3]); - }); - } - - #[test] - fn proxy_voting_should_work() { - with_externalities(&mut ExtBuilder::default().build(), || { - System::set_block_number(1); - - assert_ok!(Elections::submit_candidacy(Origin::signed(5), 0)); - - >::insert(11, 1); - >::insert(12, 2); - >::insert(13, 3); - >::insert(14, 4); - assert_ok!(Elections::proxy_set_approvals(Origin::signed(11), vec![true], 0, 0)); - assert_ok!(Elections::proxy_set_approvals(Origin::signed(14), vec![true], 0, 1)); - - assert_eq!(Elections::all_approvals_of(&1), vec![true]); - assert_eq!(Elections::all_approvals_of(&4), vec![true]); - assert_eq!(voter_ids(), vec![1, 4]); - - assert_ok!(Elections::submit_candidacy(Origin::signed(2), 1)); - assert_ok!(Elections::submit_candidacy(Origin::signed(3), 2)); - - assert_ok!(Elections::proxy_set_approvals(Origin::signed(12), vec![false, true, true], 0, 2)); - assert_ok!(Elections::proxy_set_approvals(Origin::signed(13), vec![false, true, true], 0, 3)); - - assert_eq!(Elections::all_approvals_of(&1), vec![true]); - assert_eq!(Elections::all_approvals_of(&4), vec![true]); - assert_eq!(Elections::all_approvals_of(&2), vec![false, true, true]); - assert_eq!(Elections::all_approvals_of(&3), vec![false, true, true]); - - assert_eq!(voter_ids(), vec![1, 4, 2, 3]); - }); - } - - #[test] - fn setting_any_approval_vote_count_without_any_candidate_count_should_not_work() { - with_externalities(&mut ExtBuilder::default().build(), || { - System::set_block_number(1); - - assert_eq!(Elections::candidates().len(), 0); - - assert_noop!( - Elections::set_approvals(Origin::signed(4), vec![], 0, 0), - "amount of candidates to receive approval votes should be non-zero" - ); - }); - } - - #[test] - fn setting_an_approval_vote_count_more_than_candidate_count_should_not_work() { - with_externalities(&mut ExtBuilder::default().build(), || { - System::set_block_number(1); - - assert_ok!(Elections::submit_candidacy(Origin::signed(5), 0)); - assert_eq!(Elections::candidates().len(), 1); - - assert_noop!( - Elections::set_approvals(Origin::signed(4),vec![true, true], 0, 0), - "amount of candidate votes cannot exceed amount of candidates" - ); - }); - } - - #[test] - fn resubmitting_voting_should_work() { - with_externalities(&mut ExtBuilder::default().build(), || { - System::set_block_number(1); - - assert_ok!(Elections::submit_candidacy(Origin::signed(5), 0)); - assert_ok!(Elections::set_approvals(Origin::signed(4), vec![true], 0, 0)); - - assert_eq!(Elections::all_approvals_of(&4), vec![true]); - - assert_ok!(Elections::submit_candidacy(Origin::signed(2), 1)); - assert_ok!(Elections::submit_candidacy(Origin::signed(3), 2)); - assert_eq!(Elections::candidates().len(), 3); - assert_ok!(Elections::set_approvals(Origin::signed(4), vec![true, false, true], 0, 0)); - - assert_eq!(Elections::all_approvals_of(&4), vec![true, false, true]); - }); - } - - #[test] - fn retracting_voter_should_work() { - with_externalities(&mut ExtBuilder::default().build(), || { - System::set_block_number(1); - - assert_ok!(Elections::submit_candidacy(Origin::signed(5), 0)); - assert_ok!(Elections::submit_candidacy(Origin::signed(2), 1)); - assert_ok!(Elections::submit_candidacy(Origin::signed(3), 2)); - assert_eq!(Elections::candidates().len(), 3); - - assert_ok!(Elections::set_approvals(Origin::signed(1), vec![true], 0, 0)); - assert_ok!(Elections::set_approvals(Origin::signed(2), vec![false, true, true], 0, 1)); - assert_ok!(Elections::set_approvals(Origin::signed(3), vec![false, true, true], 0, 2)); - assert_ok!(Elections::set_approvals(Origin::signed(4), vec![true, false, true], 0, 3)); - - assert_eq!(voter_ids(), vec![1, 2, 3, 4]); - assert_eq!(Elections::all_approvals_of(&1), vec![true]); - assert_eq!(Elections::all_approvals_of(&2), vec![false, true, true]); - assert_eq!(Elections::all_approvals_of(&3), vec![false, true, true]); - assert_eq!(Elections::all_approvals_of(&4), vec![true, false, true]); - - assert_ok!(Elections::retract_voter(Origin::signed(1), 0)); - - assert_eq!(voter_ids(), vec![0, 2, 3, 4]); - assert_eq!(Elections::all_approvals_of(&1), Vec::::new()); - assert_eq!(Elections::all_approvals_of(&2), vec![false, true, true]); - assert_eq!(Elections::all_approvals_of(&3), vec![false, true, true]); - assert_eq!(Elections::all_approvals_of(&4), vec![true, false, true]); - - assert_ok!(Elections::retract_voter(Origin::signed(2), 1)); - - assert_eq!(voter_ids(), vec![0, 0, 3, 4]); - assert_eq!(Elections::all_approvals_of(&1), Vec::::new()); - assert_eq!(Elections::all_approvals_of(&2), Vec::::new()); - assert_eq!(Elections::all_approvals_of(&3), vec![false, true, true]); - assert_eq!(Elections::all_approvals_of(&4), vec![true, false, true]); - - assert_ok!(Elections::retract_voter(Origin::signed(3), 2)); - - assert_eq!(voter_ids(), vec![0, 0, 0, 4]); - assert_eq!(Elections::all_approvals_of(&1), Vec::::new()); - assert_eq!(Elections::all_approvals_of(&2), Vec::::new()); - assert_eq!(Elections::all_approvals_of(&3), Vec::::new()); - assert_eq!(Elections::all_approvals_of(&4), vec![true, false, true]); - }); - } - - #[test] - fn invalid_retraction_index_should_not_work() { - with_externalities(&mut ExtBuilder::default().build(), || { - System::set_block_number(1); - assert_ok!(Elections::submit_candidacy(Origin::signed(3), 0)); - assert_ok!(Elections::set_approvals(Origin::signed(1), vec![true], 0, 0)); - assert_ok!(Elections::set_approvals(Origin::signed(2), vec![true], 0, 0)); - assert_eq!(voter_ids(), vec![1, 2]); - assert_noop!(Elections::retract_voter(Origin::signed(1), 1), "retraction index mismatch"); - }); - } - - #[test] - fn overflow_retraction_index_should_not_work() { - with_externalities(&mut ExtBuilder::default().build(), || { - System::set_block_number(1); - assert_ok!(Elections::submit_candidacy(Origin::signed(3), 0)); - assert_ok!(Elections::set_approvals(Origin::signed(1), vec![true], 0, 0)); - assert_noop!(Elections::retract_voter(Origin::signed(1), 1), "retraction index invalid"); - }); - } - - #[test] - fn non_voter_retraction_should_not_work() { - with_externalities(&mut ExtBuilder::default().build(), || { - System::set_block_number(1); - assert_ok!(Elections::submit_candidacy(Origin::signed(3), 0)); - assert_ok!(Elections::set_approvals(Origin::signed(1), vec![true], 0, 0)); - assert_noop!(Elections::retract_voter(Origin::signed(2), 0), "cannot retract non-voter"); - }); - } - - #[test] - fn approval_storage_should_work() { - with_externalities(&mut ExtBuilder::default().build(), || { - assert_ok!(Elections::submit_candidacy(Origin::signed(2), 0)); - assert_ok!(Elections::submit_candidacy(Origin::signed(3), 1)); - - assert_ok!(Elections::set_approvals(Origin::signed(2), vec![true, false], 0, 0)); - assert_ok!(Elections::set_approvals(Origin::signed(3), vec![false, false], 0, 0)); - assert_ok!(Elections::set_approvals(Origin::signed(4), vec![], 0, 0)); - - assert_eq!(Elections::all_approvals_of(&2), vec![true]); - // NOTE: these two are stored in mem differently though. - assert_eq!(Elections::all_approvals_of(&3), vec![]); - assert_eq!(Elections::all_approvals_of(&4), vec![]); - - assert_eq!(Elections::approvals_of((3, 0)), vec![0]); - assert_eq!(Elections::approvals_of((4, 0)), vec![]); - }); - } - - #[test] - fn simple_tally_should_work() { - with_externalities(&mut ExtBuilder::default().build(), || { - System::set_block_number(4); - assert!(!Elections::presentation_active()); - - assert_ok!(Elections::submit_candidacy(Origin::signed(2), 0)); - assert_ok!(Elections::submit_candidacy(Origin::signed(5), 1)); - assert_ok!(Elections::set_approvals(Origin::signed(2), vec![true], 0, 0)); - assert_ok!(Elections::set_approvals(Origin::signed(5), vec![false, true], 0, 0)); - assert_eq!(voter_ids(), vec![2, 5]); - assert_eq!(Elections::all_approvals_of(&2), vec![true]); - assert_eq!(Elections::all_approvals_of(&5), vec![false, true]); - assert_ok!(Elections::end_block(System::block_number())); - - System::set_block_number(6); - assert!(Elections::presentation_active()); - assert_eq!(Elections::present_winner(Origin::signed(4), 2, 20, 0), Ok(())); - assert_eq!(Elections::present_winner(Origin::signed(4), 5, 50, 0), Ok(())); - assert_eq!(Elections::leaderboard(), Some(vec![(0, 0), (0, 0), (20, 2), (50, 5)])); - assert_ok!(Elections::end_block(System::block_number())); - - assert!(!Elections::presentation_active()); - assert_eq!(Elections::members(), vec![(5, 11), (2, 11)]); - - assert!(!Elections::is_a_candidate(&2)); - assert!(!Elections::is_a_candidate(&5)); - assert_eq!(Elections::vote_index(), 1); - assert_eq!(Elections::voter_info(2), Some(VoterInfo { last_win: 1, last_active: 0, stake: 20, pot: 0 })); - assert_eq!(Elections::voter_info(5), Some(VoterInfo { last_win: 1, last_active: 0, stake: 50, pot: 0 })); - }); - } - - #[test] - fn seats_should_be_released() { - with_externalities(&mut ExtBuilder::default().build(), || { - System::set_block_number(4); - assert_ok!(Elections::submit_candidacy(Origin::signed(2), 0)); - assert_ok!(Elections::submit_candidacy(Origin::signed(5), 1)); - assert_ok!(Elections::set_approvals(Origin::signed(2), vec![true, false], 0, 0)); - assert_ok!(Elections::set_approvals(Origin::signed(5), vec![false, true], 0, 0)); - assert_ok!(Elections::end_block(System::block_number())); - - System::set_block_number(6); - assert!(Elections::presentation_active()); - assert_eq!(Elections::present_winner(Origin::signed(4), 2, 20, 0), Ok(())); - assert_eq!(Elections::present_winner(Origin::signed(4), 5, 50, 0), Ok(())); - assert_eq!(Elections::leaderboard(), Some(vec![(0, 0), (0, 0), (20, 2), (50, 5)])); - assert_ok!(Elections::end_block(System::block_number())); - - assert_eq!(Elections::members(), vec![(5, 11), (2, 11)]); - let mut current = System::block_number(); - let free_block; - loop { - current += 1; - System::set_block_number(current); - assert_ok!(Elections::end_block(System::block_number())); - if Elections::members().len() == 0 { - free_block = current; - break; - } - } - // 11 + 2 which is the next voting period. - assert_eq!(free_block, 14); - }); - } - - #[test] - fn presentations_with_zero_staked_deposit_should_not_work() { - with_externalities(&mut ExtBuilder::default().build(), || { - System::set_block_number(4); - assert_ok!(Elections::submit_candidacy(Origin::signed(2), 0)); - assert_ok!(Elections::set_approvals(Origin::signed(2), vec![true], 0, 0)); - assert_ok!(Elections::end_block(System::block_number())); - - System::set_block_number(6); - assert_noop!( - Elections::present_winner(Origin::signed(4), 2, 0, 0), - "stake deposited to present winner and be added to leaderboard should be non-zero" - ); - }); - } - - #[test] - fn double_presentations_should_be_punished() { - with_externalities(&mut ExtBuilder::default().build(), || { - assert!(Balances::can_slash(&4, 10)); - - System::set_block_number(4); - assert_ok!(Elections::submit_candidacy(Origin::signed(2), 0)); - assert_ok!(Elections::submit_candidacy(Origin::signed(5), 1)); - assert_ok!(Elections::set_approvals(Origin::signed(2), vec![true, false], 0, 0)); - assert_ok!(Elections::set_approvals(Origin::signed(5), vec![false, true], 0, 0)); - assert_ok!(Elections::end_block(System::block_number())); - - System::set_block_number(6); - assert_ok!(Elections::present_winner(Origin::signed(4), 2, 20, 0)); - assert_ok!(Elections::present_winner(Origin::signed(4), 5, 50, 0)); - assert_eq!(Elections::present_winner(Origin::signed(4), 5, 50, 0), Err("duplicate presentation")); - assert_ok!(Elections::end_block(System::block_number())); - - assert_eq!(Elections::members(), vec![(5, 11), (2, 11)]); - assert_eq!(Balances::total_balance(&4), 38); - }); - } - - #[test] - fn retracting_inactive_voter_should_work() { - with_externalities(&mut ExtBuilder::default().build(), || { - System::set_block_number(4); - assert_ok!(Elections::submit_candidacy(Origin::signed(2), 0)); - assert_ok!(Elections::set_approvals(Origin::signed(2), vec![true], 0, 0)); - assert_ok!(Elections::end_block(System::block_number())); - - System::set_block_number(6); - assert_ok!(Elections::present_winner(Origin::signed(4), 2, 20, 0)); - assert_ok!(Elections::end_block(System::block_number())); - - System::set_block_number(8); - assert_ok!(Elections::submit_candidacy(Origin::signed(5), 0)); - assert_ok!(Elections::set_approvals(Origin::signed(5), vec![true], 1, 0)); - assert_ok!(Elections::end_block(System::block_number())); - - System::set_block_number(10); - assert_ok!(Elections::present_winner(Origin::signed(4), 5, 50, 1)); - assert_ok!(Elections::end_block(System::block_number())); - - assert_ok!(Elections::reap_inactive_voter(Origin::signed(5), - (voter_ids().iter().position(|&i| i == 5).unwrap() as u32).into(), - 2, (voter_ids().iter().position(|&i| i == 2).unwrap() as u32).into(), - 2 - )); - - assert_eq!(voter_ids(), vec![0, 5]); - assert_eq!(Elections::all_approvals_of(&2).len(), 0); - assert_eq!(Balances::total_balance(&2), 20); - assert_eq!(Balances::total_balance(&5), 50); - }); - } - - #[test] - fn presenting_for_double_election_should_not_work() { - with_externalities(&mut ExtBuilder::default().build(), || { - System::set_block_number(4); - assert_eq!(Elections::submit_candidacy(Origin::signed(2), 0), Ok(())); - assert_ok!(Elections::set_approvals(Origin::signed(2), vec![true], 0, 0)); - assert_ok!(Elections::end_block(System::block_number())); - - System::set_block_number(6); - assert_ok!(Elections::present_winner(Origin::signed(4), 2, 20, 0)); - assert_ok!(Elections::end_block(System::block_number())); - - System::set_block_number(8); - // NOTE: This is now mandatory to disable the lock - assert_ok!(Elections::retract_voter(Origin::signed(2), 0)); - assert_eq!(Elections::submit_candidacy(Origin::signed(2), 0), Ok(())); - assert_ok!(Elections::set_approvals(Origin::signed(2), vec![true], 1, 0)); - assert_ok!(Elections::end_block(System::block_number())); - - System::set_block_number(10); - assert_noop!( - Elections::present_winner(Origin::signed(4), 2, 20, 1), - "candidate must not form a duplicated member if elected" - ); - }); - } - - #[test] - fn retracting_inactive_voter_with_other_candidates_in_slots_should_work() { - with_externalities(&mut ExtBuilder::default().voter_bond(2).build(), || { - System::set_block_number(4); - assert_ok!(Elections::submit_candidacy(Origin::signed(2), 0)); - assert_ok!(Elections::set_approvals(Origin::signed(2), vec![true], 0, 0)); - assert_ok!(Elections::end_block(System::block_number())); - - System::set_block_number(6); - assert_ok!(Elections::present_winner(Origin::signed(4), 2, 20, 0)); - assert_ok!(Elections::end_block(System::block_number())); - - System::set_block_number(8); - assert_ok!(Elections::submit_candidacy(Origin::signed(5), 0)); - assert_ok!(Elections::set_approvals(Origin::signed(5), vec![true], 1, 0)); - assert_ok!(Elections::end_block(System::block_number())); - - System::set_block_number(10); - assert_ok!(Elections::present_winner(Origin::signed(4), 5, 50, 1)); - assert_ok!(Elections::end_block(System::block_number())); - - System::set_block_number(11); - assert_ok!(Elections::submit_candidacy(Origin::signed(1), 0)); - - assert_ok!(Elections::reap_inactive_voter(Origin::signed(5), - (voter_ids().iter().position(|&i| i == 5).unwrap() as u32).into(), - 2, (voter_ids().iter().position(|&i| i == 2).unwrap() as u32).into(), - 2 - )); - - assert_eq!(voter_ids(), vec![0, 5]); - assert_eq!(Elections::all_approvals_of(&2).len(), 0); - assert_eq!(Balances::total_balance(&2), 18); - assert_eq!(Balances::total_balance(&5), 52); - }); - } - - #[test] - fn retracting_inactive_voter_with_bad_reporter_index_should_not_work() { - with_externalities(&mut ExtBuilder::default().build(), || { - System::set_block_number(4); - assert_ok!(Elections::submit_candidacy(Origin::signed(2), 0)); - assert_ok!(Elections::set_approvals(Origin::signed(2), vec![true], 0, 0)); - assert_ok!(Elections::end_block(System::block_number())); - - System::set_block_number(6); - assert_ok!(Elections::present_winner(Origin::signed(4), 2, 20, 0)); - assert_ok!(Elections::end_block(System::block_number())); - - System::set_block_number(8); - assert_ok!(Elections::submit_candidacy(Origin::signed(5), 0)); - assert_ok!(Elections::set_approvals(Origin::signed(5), vec![true], 1, 0)); - assert_ok!(Elections::end_block(System::block_number())); - - System::set_block_number(10); - assert_ok!(Elections::present_winner(Origin::signed(4), 5, 50, 1)); - assert_ok!(Elections::end_block(System::block_number())); - - assert_noop!(Elections::reap_inactive_voter(Origin::signed(2), - 42, - 2, (voter_ids().iter().position(|&i| i == 2).unwrap() as u32).into(), - 2 - ), "invalid reporter index"); - }); - } - - #[test] - fn retracting_inactive_voter_with_bad_target_index_should_not_work() { - with_externalities(&mut ExtBuilder::default().build(), || { - System::set_block_number(4); - assert_ok!(Elections::submit_candidacy(Origin::signed(2), 0)); - assert_ok!(Elections::set_approvals(Origin::signed(2), vec![true], 0, 0)); - assert_ok!(Elections::end_block(System::block_number())); - - System::set_block_number(6); - assert_ok!(Elections::present_winner(Origin::signed(4), 2, 20, 0)); - assert_ok!(Elections::end_block(System::block_number())); - - System::set_block_number(8); - assert_ok!(Elections::submit_candidacy(Origin::signed(5), 0)); - assert_ok!(Elections::set_approvals(Origin::signed(5), vec![true], 1, 0)); - assert_ok!(Elections::end_block(System::block_number())); - - System::set_block_number(10); - assert_ok!(Elections::present_winner(Origin::signed(4), 5, 50, 1)); - assert_ok!(Elections::end_block(System::block_number())); - - assert_noop!(Elections::reap_inactive_voter(Origin::signed(2), - (voter_ids().iter().position(|&i| i == 2).unwrap() as u32).into(), - 2, 42, - 2 - ), "invalid target index"); - }); - } - - #[test] - fn attempting_to_retract_active_voter_should_slash_reporter() { - with_externalities(&mut ExtBuilder::default().build(), || { - System::set_block_number(4); - assert_ok!(Elections::submit_candidacy(Origin::signed(2), 0)); - assert_ok!(Elections::submit_candidacy(Origin::signed(3), 1)); - assert_ok!(Elections::submit_candidacy(Origin::signed(4), 2)); - assert_ok!(Elections::submit_candidacy(Origin::signed(5), 3)); - assert_ok!(Elections::set_approvals(Origin::signed(2), vec![true, false, false, false], 0, 0)); - assert_ok!(Elections::set_approvals(Origin::signed(3), vec![false, true, false, false], 0, 0)); - assert_ok!(Elections::set_approvals(Origin::signed(4), vec![false, false, true, false], 0, 0)); - assert_ok!(Elections::set_approvals(Origin::signed(5), vec![false, false, false, true], 0, 0)); - assert_ok!(Elections::end_block(System::block_number())); - - System::set_block_number(6); - assert_ok!(Elections::present_winner(Origin::signed(4), 2, 20, 0)); - assert_ok!(Elections::present_winner(Origin::signed(4), 3, 30, 0)); - assert_ok!(Elections::present_winner(Origin::signed(4), 4, 40, 0)); - assert_ok!(Elections::present_winner(Origin::signed(4), 5, 50, 0)); - assert_ok!(Elections::end_block(System::block_number())); - - System::set_block_number(8); - assert_ok!(Elections::set_desired_seats(Origin::ROOT, 3)); - assert_ok!(Elections::end_block(System::block_number())); - - System::set_block_number(10); - assert_ok!(Elections::present_winner(Origin::signed(4), 2, 20 + Elections::get_offset(20, 1), 1)); - assert_ok!(Elections::present_winner(Origin::signed(4), 3, 30 + Elections::get_offset(30, 1), 1)); - assert_ok!(Elections::end_block(System::block_number())); - - assert_eq!(Elections::vote_index(), 2); - assert_eq!(::InactiveGracePeriod::get(), 1); - assert_eq!(::VotingPeriod::get(), 4); - assert_eq!(Elections::voter_info(4), Some(VoterInfo { last_win: 1, last_active: 0, stake: 40, pot: 0 })); - - assert_ok!(Elections::reap_inactive_voter(Origin::signed(4), - (voter_ids().iter().position(|&i| i == 4).unwrap() as u32).into(), - 2, - (voter_ids().iter().position(|&i| i == 2).unwrap() as u32).into(), - 2 - )); - - assert_eq!(voter_ids(), vec![2, 3, 0, 5]); - assert_eq!(Elections::all_approvals_of(&4).len(), 0); - assert_eq!(Balances::total_balance(&4), 40); - }); - } - - #[test] - fn attempting_to_retract_inactive_voter_by_nonvoter_should_not_work() { - with_externalities(&mut ExtBuilder::default().build(), || { - System::set_block_number(4); - assert_ok!(Elections::submit_candidacy(Origin::signed(2), 0)); - assert_ok!(Elections::set_approvals(Origin::signed(2), vec![true], 0, 0)); - assert_ok!(Elections::end_block(System::block_number())); - - System::set_block_number(6); - assert_ok!(Elections::present_winner(Origin::signed(4), 2, 20, 0)); - assert_ok!(Elections::end_block(System::block_number())); - - System::set_block_number(8); - assert_ok!(Elections::submit_candidacy(Origin::signed(5), 0)); - assert_ok!(Elections::set_approvals(Origin::signed(5), vec![true], 1, 0)); - assert_ok!(Elections::end_block(System::block_number())); - - System::set_block_number(10); - assert_ok!(Elections::present_winner(Origin::signed(4), 5, 50, 1)); - assert_ok!(Elections::end_block(System::block_number())); - - assert_noop!(Elections::reap_inactive_voter(Origin::signed(4), - 0, - 2, (voter_ids().iter().position(|&i| i == 2).unwrap() as u32).into(), - 2 - ), "reporter must be a voter"); - }); - } - - #[test] - fn presenting_loser_should_not_work() { - with_externalities(&mut ExtBuilder::default().build(), || { - System::set_block_number(4); - assert_ok!(Elections::submit_candidacy(Origin::signed(1), 0)); - assert_ok!(Elections::set_approvals(Origin::signed(6), vec![true], 0, 0)); - assert_ok!(Elections::submit_candidacy(Origin::signed(2), 1)); - assert_ok!(Elections::set_approvals(Origin::signed(2), vec![false, true], 0, 0)); - assert_ok!(Elections::submit_candidacy(Origin::signed(3), 2)); - assert_ok!(Elections::set_approvals(Origin::signed(3), vec![false, false, true], 0, 0)); - assert_ok!(Elections::submit_candidacy(Origin::signed(4), 3)); - assert_ok!(Elections::set_approvals(Origin::signed(4), vec![false, false, false, true], 0, 0)); - assert_ok!(Elections::submit_candidacy(Origin::signed(5), 4)); - assert_ok!(Elections::set_approvals(Origin::signed(5), vec![false, false, false, false, true], 0, 0)); - assert_ok!(Elections::end_block(System::block_number())); - - System::set_block_number(6); - assert_ok!(Elections::present_winner(Origin::signed(4), 1, 60, 0)); - assert_ok!(Elections::present_winner(Origin::signed(4), 3, 30, 0)); - assert_ok!(Elections::present_winner(Origin::signed(4), 4, 40, 0)); - assert_ok!(Elections::present_winner(Origin::signed(4), 5, 50, 0)); - - assert_eq!(Elections::leaderboard(), Some(vec![ - (30, 3), - (40, 4), - (50, 5), - (60, 1) - ])); - - assert_noop!(Elections::present_winner(Origin::signed(4), 2, 20, 0), "candidate not worthy of leaderboard"); - }); - } - - #[test] - fn presenting_loser_first_should_not_matter() { - with_externalities(&mut ExtBuilder::default().build(), || { - System::set_block_number(4); - assert_ok!(Elections::submit_candidacy(Origin::signed(1), 0)); - assert_ok!(Elections::set_approvals(Origin::signed(6), vec![true], 0, 0)); - assert_ok!(Elections::submit_candidacy(Origin::signed(2), 1)); - assert_ok!(Elections::set_approvals(Origin::signed(2), vec![false, true], 0, 0)); - assert_ok!(Elections::submit_candidacy(Origin::signed(3), 2)); - assert_ok!(Elections::set_approvals(Origin::signed(3), vec![false, false, true], 0, 0)); - assert_ok!(Elections::submit_candidacy(Origin::signed(4), 3)); - assert_ok!(Elections::set_approvals(Origin::signed(4), vec![false, false, false, true], 0, 0)); - assert_ok!(Elections::submit_candidacy(Origin::signed(5), 4)); - assert_ok!(Elections::set_approvals(Origin::signed(5), vec![false, false, false, false, true], 0, 0)); - assert_ok!(Elections::end_block(System::block_number())); - - System::set_block_number(6); - assert_ok!(Elections::present_winner(Origin::signed(4), 2, 20, 0)); - assert_ok!(Elections::present_winner(Origin::signed(4), 1, 60, 0)); - assert_ok!(Elections::present_winner(Origin::signed(4), 3, 30, 0)); - assert_ok!(Elections::present_winner(Origin::signed(4), 4, 40, 0)); - assert_ok!(Elections::present_winner(Origin::signed(4), 5, 50, 0)); - - assert_eq!(Elections::leaderboard(), Some(vec![ - (30, 3), - (40, 4), - (50, 5), - (60, 1) - ])); - }); - } - - #[test] - fn present_outside_of_presentation_period_should_not_work() { - with_externalities(&mut ExtBuilder::default().build(), || { - System::set_block_number(4); - assert!(!Elections::presentation_active()); - assert_noop!( - Elections::present_winner(Origin::signed(5), 5, 1, 0), - "cannot present outside of presentation period" - ); - }); - } - - #[test] - fn present_with_invalid_vote_index_should_not_work() { - with_externalities(&mut ExtBuilder::default().build(), || { - System::set_block_number(4); - assert_ok!(Elections::submit_candidacy(Origin::signed(2), 0)); - assert_ok!(Elections::submit_candidacy(Origin::signed(5), 1)); - assert_ok!(Elections::set_approvals(Origin::signed(2), vec![true, false], 0, 0)); - assert_ok!(Elections::set_approvals(Origin::signed(5), vec![false, true], 0, 0)); - assert_ok!(Elections::end_block(System::block_number())); - - System::set_block_number(6); - assert_noop!(Elections::present_winner(Origin::signed(4), 2, 20, 1), "index not current"); - }); - } - - #[test] - fn present_when_presenter_is_poor_should_not_work() { - let test_present = |p| { - with_externalities(&mut ExtBuilder::default() - .voting_fee(5) - .voter_bond(2) - .bad_presentation_punishment(p) - .build(), - || { - System::set_block_number(4); - let _ = Balances::make_free_balance_be(&1, 15); - assert!(!Elections::presentation_active()); - - assert_ok!(Elections::submit_candidacy(Origin::signed(1), 0)); // -3 - assert_eq!(Balances::free_balance(&1), 12); - assert_ok!(Elections::set_approvals(Origin::signed(1), vec![true], 0, 0)); // -2 -5 - assert_ok!(Elections::end_block(System::block_number())); - - System::set_block_number(6); - assert_eq!(Balances::free_balance(&1), 5); - assert_eq!(Balances::reserved_balance(&1), 5); - if p > 5 { - assert_noop!(Elections::present_winner( - Origin::signed(1), 1, 10, 0), - "presenter must have sufficient slashable funds" - ); - } else { - assert_ok!(Elections::present_winner(Origin::signed(1), 1, 10, 0)); - } - }); - }; - test_present(4); - test_present(6); - } - - #[test] - fn invalid_present_tally_should_slash() { - with_externalities(&mut ExtBuilder::default().build(), || { - System::set_block_number(4); - assert!(!Elections::presentation_active()); - assert_eq!(Balances::total_balance(&4), 40); - - assert_ok!(Elections::submit_candidacy(Origin::signed(2), 0)); - assert_ok!(Elections::submit_candidacy(Origin::signed(5), 1)); - assert_ok!(Elections::set_approvals(Origin::signed(2), vec![true, false], 0, 0)); - assert_ok!(Elections::set_approvals(Origin::signed(5), vec![false, true], 0, 0)); - assert_ok!(Elections::end_block(System::block_number())); - - System::set_block_number(6); - assert_err!(Elections::present_winner(Origin::signed(4), 2, 80, 0), "incorrect total"); - - assert_eq!(Balances::total_balance(&4), 38); - }); - } - - #[test] - fn runners_up_should_be_kept() { - with_externalities(&mut ExtBuilder::default().build(), || { - System::set_block_number(4); - assert!(!Elections::presentation_active()); - - assert_ok!(Elections::submit_candidacy(Origin::signed(1), 0)); - assert_ok!(Elections::set_approvals(Origin::signed(6), vec![true], 0, 0)); - assert_ok!(Elections::submit_candidacy(Origin::signed(2), 1)); - assert_ok!(Elections::set_approvals(Origin::signed(2), vec![false, true], 0, 0)); - assert_ok!(Elections::submit_candidacy(Origin::signed(3), 2)); - assert_ok!(Elections::set_approvals(Origin::signed(3), vec![false, false, true], 0, 0)); - assert_ok!(Elections::submit_candidacy(Origin::signed(4), 3)); - assert_ok!(Elections::set_approvals(Origin::signed(4), vec![false, false, false, true], 0, 0)); - assert_ok!(Elections::submit_candidacy(Origin::signed(5), 4)); - assert_ok!(Elections::set_approvals(Origin::signed(5), vec![false, false, false, false, true], 0, 0)); - - assert_ok!(Elections::end_block(System::block_number())); - - System::set_block_number(6); - assert!(Elections::presentation_active()); - assert_ok!(Elections::present_winner(Origin::signed(4), 1, 60, 0)); - // leaderboard length is the empty seats plus the carry count (i.e. 5 + 2), where those - // to be carried are the lowest and stored in lowest indices - assert_eq!(Elections::leaderboard(), Some(vec![ - (0, 0), - (0, 0), - (0, 0), - (60, 1) - ])); - assert_ok!(Elections::present_winner(Origin::signed(4), 3, 30, 0)); - assert_ok!(Elections::present_winner(Origin::signed(4), 4, 40, 0)); - assert_ok!(Elections::present_winner(Origin::signed(4), 5, 50, 0)); - assert_eq!(Elections::leaderboard(), Some(vec![ - (30, 3), - (40, 4), - (50, 5), - (60, 1) - ])); - - assert_ok!(Elections::end_block(System::block_number())); - - assert!(!Elections::presentation_active()); - assert_eq!(Elections::members(), vec![(1, 11), (5, 11)]); - - assert!(!Elections::is_a_candidate(&1)); - assert!(!Elections::is_a_candidate(&5)); - assert!(!Elections::is_a_candidate(&2)); - assert!(Elections::is_a_candidate(&3)); - assert!(Elections::is_a_candidate(&4)); - assert_eq!(Elections::vote_index(), 1); - assert_eq!(Elections::voter_info(2), Some(VoterInfo { last_win: 0, last_active: 0, stake: 20, pot: 0 })); - assert_eq!(Elections::voter_info(3), Some(VoterInfo { last_win: 0, last_active: 0, stake: 30, pot: 0 })); - assert_eq!(Elections::voter_info(4), Some(VoterInfo { last_win: 0, last_active: 0, stake: 40, pot: 0 })); - assert_eq!(Elections::voter_info(5), Some(VoterInfo { last_win: 1, last_active: 0, stake: 50, pot: 0 })); - assert_eq!(Elections::voter_info(6), Some(VoterInfo { last_win: 1, last_active: 0, stake: 60, pot: 0 })); - assert_eq!(Elections::candidate_reg_info(3), Some((0, 2))); - assert_eq!(Elections::candidate_reg_info(4), Some((0, 3))); - }); - } - - #[test] - fn second_tally_should_use_runners_up() { - with_externalities(&mut ExtBuilder::default().build(), || { - System::set_block_number(4); - assert_ok!(Elections::submit_candidacy(Origin::signed(1), 0)); - assert_ok!(Elections::set_approvals(Origin::signed(6), vec![true], 0, 0)); - assert_ok!(Elections::submit_candidacy(Origin::signed(2), 1)); - assert_ok!(Elections::set_approvals(Origin::signed(2), vec![false, true], 0, 0)); - assert_ok!(Elections::submit_candidacy(Origin::signed(3), 2)); - assert_ok!(Elections::set_approvals(Origin::signed(3), vec![false, false, true], 0, 0)); - assert_ok!(Elections::submit_candidacy(Origin::signed(4), 3)); - assert_ok!(Elections::set_approvals(Origin::signed(4), vec![false, false, false, true], 0, 0)); - assert_ok!(Elections::submit_candidacy(Origin::signed(5), 4)); - assert_ok!(Elections::set_approvals(Origin::signed(5), vec![false, false, false, false, true], 0, 0)); - assert_ok!(Elections::end_block(System::block_number())); - - System::set_block_number(6); - assert_ok!(Elections::present_winner(Origin::signed(4), 1, 60, 0)); - assert_ok!(Elections::present_winner(Origin::signed(4), 3, 30, 0)); - assert_ok!(Elections::present_winner(Origin::signed(4), 4, 40, 0)); - assert_ok!(Elections::present_winner(Origin::signed(4), 5, 50, 0)); - assert_ok!(Elections::end_block(System::block_number())); - - System::set_block_number(8); - assert_ok!(Elections::set_approvals(Origin::signed(6), vec![false, false, true, false], 1, 0)); - assert_ok!(Elections::set_desired_seats(Origin::ROOT, 3)); - assert_ok!(Elections::end_block(System::block_number())); - - System::set_block_number(10); - assert_ok!(Elections::present_winner(Origin::signed(4), 3, 30 + Elections::get_offset(30, 1) + 60, 1)); - assert_ok!(Elections::present_winner(Origin::signed(4), 4, 40 + Elections::get_offset(40, 1), 1)); - assert_ok!(Elections::end_block(System::block_number())); - - assert!(!Elections::presentation_active()); - assert_eq!(Elections::members(), vec![(1, 11), (5, 11), (3, 15)]); - - assert!(!Elections::is_a_candidate(&1)); - assert!(!Elections::is_a_candidate(&2)); - assert!(!Elections::is_a_candidate(&3)); - assert!(!Elections::is_a_candidate(&5)); - assert!(Elections::is_a_candidate(&4)); - assert_eq!(Elections::vote_index(), 2); - assert_eq!(Elections::voter_info(2), Some( VoterInfo { last_win: 0, last_active: 0, stake: 20, pot: 0})); - assert_eq!(Elections::voter_info(3), Some( VoterInfo { last_win: 2, last_active: 0, stake: 30, pot: 0})); - assert_eq!(Elections::voter_info(4), Some( VoterInfo { last_win: 0, last_active: 0, stake: 40, pot: 0})); - assert_eq!(Elections::voter_info(5), Some( VoterInfo { last_win: 1, last_active: 0, stake: 50, pot: 0})); - assert_eq!( - Elections::voter_info(6), - Some(VoterInfo { last_win: 2, last_active: 1, stake: 60, pot: 0}) - ); - - assert_eq!(Elections::candidate_reg_info(4), Some((0, 3))); - }); - } -} diff --git a/srml/elections/src/mock.rs b/srml/elections/src/mock.rs new file mode 100644 index 0000000000000000000000000000000000000000..161da35e6a6b1df81bdf7a79f3acd56c00bd4f39 --- /dev/null +++ b/srml/elections/src/mock.rs @@ -0,0 +1,294 @@ +// Copyright 2019 Parity Technologies (UK) Ltd. +// This file is part of Substrate. + +// Substrate 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. + +// Substrate 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 Substrate. If not, see . + +//! Mock file for election module. + +#![cfg(test)] + +use std::cell::RefCell; +use support::{ + StorageValue, StorageMap, parameter_types, assert_ok, + traits::{Get, ChangeMembers, Currency} +}; +use runtime_io::with_externalities; +use primitives::{H256, Blake2Hasher}; +use sr_primitives::{ + Perbill, BuildStorage, + testing::Header, + traits::{BlakeTwo256, IdentityLookup, Block as BlockT}, +}; +use crate as elections; + + +parameter_types! { + pub const BlockHashCount: u64 = 250; + pub const MaximumBlockWeight: u32 = 1024; + pub const MaximumBlockLength: u32 = 2 * 1024; + pub const AvailableBlockRatio: Perbill = Perbill::one(); +} +impl system::Trait for Test { + type Origin = Origin; + type Index = u64; + type BlockNumber = u64; + type Call = (); + type Hash = H256; + type Hashing = BlakeTwo256; + type AccountId = u64; + type Lookup = IdentityLookup; + type Header = Header; + type Event = Event; + type WeightMultiplierUpdate = (); + type BlockHashCount = BlockHashCount; + type MaximumBlockWeight = MaximumBlockWeight; + type MaximumBlockLength = MaximumBlockLength; + type AvailableBlockRatio = AvailableBlockRatio; + type Version = (); +} + +parameter_types! { + pub const ExistentialDeposit: u64 = 0; + pub const TransferFee: u64 = 0; + pub const CreationFee: u64 = 0; + pub const TransactionBaseFee: u64 = 0; + pub const TransactionByteFee: u64 = 0; +} +impl balances::Trait for Test { + type Balance = u64; + type OnNewAccount = (); + type OnFreeBalanceZero = (); + type Event = Event; + type TransactionPayment = (); + type TransferPayment = (); + type DustRemoval = (); + type ExistentialDeposit = ExistentialDeposit; + type TransferFee = TransferFee; + type CreationFee = CreationFee; + type TransactionBaseFee = TransactionBaseFee; + type TransactionByteFee = TransactionByteFee; + type WeightToFee = (); +} + +parameter_types! { + pub const CandidacyBond: u64 = 3; + pub const CarryCount: u32 = 2; + pub const InactiveGracePeriod: u32 = 1; + pub const VotingPeriod: u64 = 4; + pub const MinimumVotingLock: u64 = 5; +} + +thread_local! { + static VOTER_BOND: RefCell = RefCell::new(0); + static VOTING_FEE: RefCell = RefCell::new(0); + static PRESENT_SLASH_PER_VOTER: RefCell = RefCell::new(0); + static DECAY_RATIO: RefCell = RefCell::new(0); + static MEMBERS: RefCell> = RefCell::new(vec![]); +} + +pub struct VotingBond; +impl Get for VotingBond { + fn get() -> u64 { VOTER_BOND.with(|v| *v.borrow()) } +} + +pub struct VotingFee; +impl Get for VotingFee { + fn get() -> u64 { VOTING_FEE.with(|v| *v.borrow()) } +} + +pub struct PresentSlashPerVoter; +impl Get for PresentSlashPerVoter { + fn get() -> u64 { PRESENT_SLASH_PER_VOTER.with(|v| *v.borrow()) } +} + +pub struct DecayRatio; +impl Get for DecayRatio { + fn get() -> u32 { DECAY_RATIO.with(|v| *v.borrow()) } +} + +pub struct TestChangeMembers; +impl ChangeMembers for TestChangeMembers { + fn change_members_sorted(incoming: &[u64], outgoing: &[u64], new: &[u64]) { + let mut old_plus_incoming = MEMBERS.with(|m| m.borrow().to_vec()); + old_plus_incoming.extend_from_slice(incoming); + old_plus_incoming.sort(); + let mut new_plus_outgoing = new.to_vec(); + new_plus_outgoing.extend_from_slice(outgoing); + new_plus_outgoing.sort(); + assert_eq!(old_plus_incoming, new_plus_outgoing); + + MEMBERS.with(|m| *m.borrow_mut() = new.to_vec()); + } +} + +impl elections::Trait for Test { + type Event = Event; + type Currency = Balances; + type BadPresentation = (); + type BadReaper = (); + type BadVoterIndex = (); + type LoserCandidate = (); + type ChangeMembers = TestChangeMembers; + type CandidacyBond = CandidacyBond; + type VotingBond = VotingBond; + type VotingFee = VotingFee; + type MinimumVotingLock = MinimumVotingLock; + type PresentSlashPerVoter = PresentSlashPerVoter; + type CarryCount = CarryCount; + type InactiveGracePeriod = InactiveGracePeriod; + type VotingPeriod = VotingPeriod; + type DecayRatio = DecayRatio; +} + +pub type Block = sr_primitives::generic::Block; +pub type UncheckedExtrinsic = sr_primitives::generic::UncheckedExtrinsic; + +support::construct_runtime!( + pub enum Test where + Block = Block, + NodeBlock = Block, + UncheckedExtrinsic = UncheckedExtrinsic + { + System: system::{Module, Call, Event}, + Balances: balances::{Module, Call, Event, Config, Error}, + Elections: elections::{Module, Call, Event, Config}, + } +); + +pub struct ExtBuilder { + balance_factor: u64, + decay_ratio: u32, + desired_seats: u32, + voting_fee: u64, + voter_bond: u64, + bad_presentation_punishment: u64, +} + +impl Default for ExtBuilder { + fn default() -> Self { + Self { + balance_factor: 1, + decay_ratio: 24, + desired_seats: 2, + voting_fee: 0, + voter_bond: 0, + bad_presentation_punishment: 1, + } + } +} + +impl ExtBuilder { + pub fn balance_factor(mut self, factor: u64) -> Self { + self.balance_factor = factor; + self + } + pub fn decay_ratio(mut self, ratio: u32) -> Self { + self.decay_ratio = ratio; + self + } + pub fn voting_fee(mut self, fee: u64) -> Self { + self.voting_fee = fee; + self + } + pub fn bad_presentation_punishment(mut self, fee: u64) -> Self { + self.bad_presentation_punishment = fee; + self + } + pub fn voter_bond(mut self, fee: u64) -> Self { + self.voter_bond = fee; + self + } + pub fn desired_seats(mut self, seats: u32) -> Self { + self.desired_seats = seats; + self + } + pub fn build(self) -> runtime_io::TestExternalities { + VOTER_BOND.with(|v| *v.borrow_mut() = self.voter_bond); + VOTING_FEE.with(|v| *v.borrow_mut() = self.voting_fee); + PRESENT_SLASH_PER_VOTER.with(|v| *v.borrow_mut() = self.bad_presentation_punishment); + DECAY_RATIO.with(|v| *v.borrow_mut() = self.decay_ratio); + GenesisConfig { + balances: Some(balances::GenesisConfig::{ + balances: vec![ + (1, 10 * self.balance_factor), + (2, 20 * self.balance_factor), + (3, 30 * self.balance_factor), + (4, 40 * self.balance_factor), + (5, 50 * self.balance_factor), + (6, 60 * self.balance_factor) + ], + vesting: vec![], + }), + elections: Some(elections::GenesisConfig::{ + members: vec![], + desired_seats: self.desired_seats, + presentation_duration: 2, + term_duration: 5, + }), + }.build_storage().unwrap().into() + } +} + +pub(crate) fn voter_ids() -> Vec { + Elections::all_voters().iter().map(|v| v.unwrap_or(0) ).collect::>() +} + +pub(crate) fn vote(i: u64, l: usize) { + let _ = Balances::make_free_balance_be(&i, 20); + assert_ok!( + Elections::set_approvals( + Origin::signed(i), + (0..l).map(|_| true).collect::>(), + 0, + 0, + 20, + ) + ); +} + +pub(crate) fn vote_at(i: u64, l: usize, index: elections::VoteIndex) { + let _ = Balances::make_free_balance_be(&i, 20); + assert_ok!( + Elections::set_approvals( + Origin::signed(i), + (0..l).map(|_| true).collect::>(), + 0, + index, + 20, + ) + ); +} + +pub(crate) fn create_candidate(i: u64, index: u32) { + let _ = Balances::make_free_balance_be(&i, 20); + assert_ok!(Elections::submit_candidacy(Origin::signed(i), index)); +} + +pub(crate) fn balances(who: &u64) -> (u64, u64) { + (Balances::free_balance(who), Balances::reserved_balance(who)) +} + +pub(crate) fn locks(who: &u64) -> Vec { + Balances::locks(who).iter().map(|l| l.amount).collect::>() +} + +pub(crate) fn new_test_ext_with_candidate_holes() -> runtime_io::TestExternalities { + let mut t = ExtBuilder::default().build(); + with_externalities(&mut t, || { + >::put(vec![0, 0, 1]); + elections::CandidateCount::put(1); + >::insert(1, (0, 2)); + }); + t +} diff --git a/srml/elections/src/tests.rs b/srml/elections/src/tests.rs new file mode 100644 index 0000000000000000000000000000000000000000..c6f4f9a0b375f813e4ce0b03756aad566b679aff --- /dev/null +++ b/srml/elections/src/tests.rs @@ -0,0 +1,1664 @@ +// Copyright 2019 Parity Technologies (UK) Ltd. +// This file is part of Substrate. + +// Substrate 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. + +// Substrate 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 Substrate. If not, see . + +//! Tests for election module. + +#![cfg(test)] + +use crate::mock::*; +use crate::*; + +use support::{assert_ok, assert_err, assert_noop}; +use runtime_io::with_externalities; + +#[test] +fn params_should_work() { + with_externalities(&mut ExtBuilder::default().build(), || { + System::set_block_number(1); + assert_eq!(Elections::next_vote_from(1), 4); + assert_eq!(Elections::next_vote_from(4), 4); + assert_eq!(Elections::next_vote_from(5), 8); + assert_eq!(Elections::vote_index(), 0); + assert_eq!(Elections::presentation_duration(), 2); + assert_eq!(Elections::term_duration(), 5); + assert_eq!(Elections::desired_seats(), 2); + + assert_eq!(Elections::members(), vec![]); + assert_eq!(Elections::next_tally(), Some(4)); + assert_eq!(Elections::presentation_active(), false); + assert_eq!(Elections::next_finalize(), None); + + assert_eq!(Elections::candidates(), Vec::::new()); + assert_eq!(Elections::is_a_candidate(&1), false); + assert_eq!(Elections::candidate_reg_info(1), None); + + assert_eq!(Elections::voters(0), Vec::>::new()); + assert_eq!(Elections::voter_info(1), None); + assert_eq!(Elections::all_approvals_of(&1), vec![]); + }); +} + +#[test] +fn chunking_bool_to_flag_should_work() { + with_externalities(&mut ExtBuilder::default().build(), || { + assert_eq!(Elections::bool_to_flag(vec![]), vec![]); + assert_eq!(Elections::bool_to_flag(vec![false]), vec![0]); + assert_eq!(Elections::bool_to_flag(vec![true]), vec![1]); + assert_eq!(Elections::bool_to_flag(vec![true, true, true, true]), vec![15]); + assert_eq!(Elections::bool_to_flag(vec![true, true, true, true, true]), vec![15 + 16]); + + let set_1 = vec![ + true, false, false, false, // 0x1 + false, true, true, true, // 0xE + ]; + assert_eq!( + Elections::bool_to_flag(set_1.clone()), + vec![0x00_00_00_E1_u32] + ); + assert_eq!( + Elections::flag_to_bool(vec![0x00_00_00_E1_u32]), + set_1 + ); + + let set_2 = vec![ + false, false, false, true, // 0x8 + false, true, false, true, // 0xA + ]; + assert_eq!( + Elections::bool_to_flag(set_2.clone()), + vec![0x00_00_00_A8_u32] + ); + assert_eq!( + Elections::flag_to_bool(vec![0x00_00_00_A8_u32]), + set_2 + ); + + let mut rhs = (0..100/APPROVAL_FLAG_LEN).map(|_| 0xFFFFFFFF_u32).collect::>(); + // NOTE: this might be need change based on `APPROVAL_FLAG_LEN`. + rhs.extend(vec![0x00_00_00_0F]); + assert_eq!( + Elections::bool_to_flag((0..100).map(|_| true).collect()), + rhs + ) + }) +} + +#[test] +fn chunking_voter_set_growth_should_work() { + with_externalities(&mut ExtBuilder::default().build(), || { + assert_ok!(Elections::submit_candidacy(Origin::signed(2), 0)); + + // create 65. 64 (set0) + 1 (set1) + (1..=63).for_each(|i| vote(i, 0)); + assert_eq!(Elections::next_nonfull_voter_set(), 0); + vote(64, 0); + assert_eq!(Elections::next_nonfull_voter_set(), 1); + vote(65, 0); + + let set1 = Elections::voters(0); + let set2 = Elections::voters(1); + + assert_eq!(set1.len(), 64); + assert_eq!(set2.len(), 1); + + assert_eq!(set1[0], Some(1)); + assert_eq!(set1[10], Some(11)); + assert_eq!(set2[0], Some(65)); + }) +} + +#[test] +fn chunking_voter_set_reclaim_should_work() { + with_externalities(&mut ExtBuilder::default().build(), || { + assert_ok!(Elections::submit_candidacy(Origin::signed(2), 0)); + + (1..=129).for_each(|i| vote(i, 0)); + assert_eq!(Elections::next_nonfull_voter_set(), 2); + + assert_ok!(Elections::retract_voter(Origin::signed(11), 10)); + + assert_ok!(Elections::retract_voter(Origin::signed(66), 65)); + assert_ok!(Elections::retract_voter(Origin::signed(67), 66)); + + // length does not show it but holes do exist. + assert_eq!(Elections::voters(0).len(), 64); + assert_eq!(Elections::voters(1).len(), 64); + assert_eq!(Elections::voters(2).len(), 1); + + assert_eq!(Elections::voters(0)[10], None); + assert_eq!(Elections::voters(1)[1], None); + assert_eq!(Elections::voters(1)[2], None); + // Next set with capacity is 2. + assert_eq!(Elections::next_nonfull_voter_set(), 2); + + // But we can fill a hole. + vote_at(130, 0, 10); + + // Nothing added to set 2. A hole was filled. + assert_eq!(Elections::voters(0).len(), 64); + assert_eq!(Elections::voters(1).len(), 64); + assert_eq!(Elections::voters(2).len(), 1); + + // and the next two (scheduled) to the second set. + assert_eq!(Elections::next_nonfull_voter_set(), 2); + }) +} + +#[test] +fn chunking_approvals_set_growth_should_work() { + with_externalities(&mut ExtBuilder::default().build(), || { + // create candidates and voters. + (1..=250).for_each(|i| create_candidate(i, (i-1) as u32)); + (1..=250).for_each(|i| vote(i, i as usize)); + + // all approvals of should return the exact expected vector. + assert_eq!( + Elections::all_approvals_of(&180), + (0..180).map(|_| true).collect::>() + ); + assert_eq!( + Elections::all_approvals_of(&32), + (0..32).map(|_| true).collect::>() + ); + assert_eq!( + Elections::all_approvals_of(&8), + (0..8).map(|_| true).collect::>() + ); + assert_eq!( + Elections::all_approvals_of(&64), + (0..64).map(|_| true).collect::>() + ); + assert_eq!( + Elections::all_approvals_of(&65), + (0..65).map(|_| true).collect::>() + ); + assert_eq!( + Elections::all_approvals_of(&63), + (0..63).map(|_| true).collect::>() + ); + + // NOTE: assuming that APPROVAL_SET_SIZE is more or less small-ish. Might fail otherwise. + let full_sets = (180 / APPROVAL_FLAG_LEN) / APPROVAL_SET_SIZE; + let left_over = (180 / APPROVAL_FLAG_LEN) / APPROVAL_SET_SIZE; + let rem = 180 % APPROVAL_FLAG_LEN; + + // grab and check the last full set, if it exists. + if full_sets > 0 { + assert_eq!( + Elections::approvals_of((180, (full_sets-1) as SetIndex )), + Elections::bool_to_flag( + (0..APPROVAL_SET_SIZE * APPROVAL_FLAG_LEN) + .map(|_| true).collect::>() + ) + ); + } + + // grab and check the last, half-empty, set. + if left_over > 0 { + assert_eq!( + Elections::approvals_of((180, full_sets as SetIndex)), + Elections::bool_to_flag( + (0..left_over * APPROVAL_FLAG_LEN + rem) + .map(|_| true).collect::>() + ) + ); + } + }) +} + +#[test] +fn chunking_cell_status_works() { + with_externalities(&mut ExtBuilder::default().build(), || { + assert_ok!(Elections::submit_candidacy(Origin::signed(2), 0)); + + (1..=63).for_each(|i| vote(i, 0)); + + assert_ok!(Elections::retract_voter(Origin::signed(11), 10)); + assert_ok!(Elections::retract_voter(Origin::signed(21), 20)); + + assert_eq!(Elections::cell_status(0, 10), CellStatus::Hole); + assert_eq!(Elections::cell_status(0, 0), CellStatus::Occupied); + assert_eq!(Elections::cell_status(0, 20), CellStatus::Hole); + assert_eq!(Elections::cell_status(0, 63), CellStatus::Head); + assert_eq!(Elections::cell_status(1, 0), CellStatus::Head); + assert_eq!(Elections::cell_status(1, 10), CellStatus::Head); + }) +} + +#[test] +fn chunking_voter_index_does_not_take_holes_into_account() { + with_externalities(&mut ExtBuilder::default().build(), || { + assert_ok!(Elections::submit_candidacy(Origin::signed(2), 0)); + + // create 65. 64 (set0) + 1 (set1) + (1..=65).for_each(|i| vote(i, 0)); + + // account 65 has global index 65. + assert_eq!(Elections::voter_at(64).unwrap(), 65); + + assert_ok!(Elections::retract_voter(Origin::signed(1), 0)); + assert_ok!(Elections::retract_voter(Origin::signed(2), 1)); + + // still the same. These holes are in some other set. + assert_eq!(Elections::voter_at(64).unwrap(), 65); + // proof: can submit a new approval with the old index. + assert_noop!( + Elections::set_approvals(Origin::signed(65), vec![], 0, 64 - 2, 10), + "wrong voter index" + ); + assert_ok!(Elections::set_approvals(Origin::signed(65), vec![], 0, 64, 10)); + }) +} + +#[test] +fn chunking_approval_storage_should_work() { + with_externalities(&mut ExtBuilder::default().build(), || { + assert_ok!(Elections::submit_candidacy(Origin::signed(2), 0)); + assert_ok!(Elections::submit_candidacy(Origin::signed(3), 1)); + + assert_ok!(Elections::set_approvals(Origin::signed(2), vec![true, false], 0, 0, 20)); + assert_ok!(Elections::set_approvals(Origin::signed(3), vec![false, false], 0, 0, 30)); + assert_ok!(Elections::set_approvals(Origin::signed(4), vec![], 0, 0, 40)); + + assert_eq!(Elections::all_approvals_of(&2), vec![true]); + // NOTE: these two are stored in mem differently though. + assert_eq!(Elections::all_approvals_of(&3), vec![]); + assert_eq!(Elections::all_approvals_of(&4), vec![]); + + assert_eq!(Elections::approvals_of((3, 0)), vec![0]); + assert_eq!(Elections::approvals_of((4, 0)), vec![]); + }); +} + +#[test] +fn voting_initial_set_approvals_ignores_voter_index() { + with_externalities(&mut ExtBuilder::default().build(), || { + assert_ok!(Elections::submit_candidacy(Origin::signed(2), 0)); + + // Last argument is essentially irrelevant. You might get or miss a tip. + assert_ok!(Elections::set_approvals(Origin::signed(3), vec![], 0, 0, 30)); + assert_ok!(Elections::set_approvals(Origin::signed(4), vec![], 0, 5, 40)); + assert_ok!(Elections::set_approvals(Origin::signed(5), vec![], 0, 100, 50)); + + // indices are more or less ignored. all is pushed. + assert_eq!(voter_ids(), vec![3, 4, 5]); + }) +} +#[test] +fn voting_bad_approval_index_slashes_voters_and_bond_reduces_stake() { + with_externalities(&mut ExtBuilder::default().voting_fee(5).voter_bond(2).build(), || { + assert_ok!(Elections::submit_candidacy(Origin::signed(2), 0)); + + (1..=63).for_each(|i| vote(i, 0)); + assert_eq!(balances(&1), (13, 2)); + assert_eq!(balances(&10), (18, 2)); + assert_eq!(balances(&60), (18, 2)); + + // still no fee + vote(64, 0); + assert_eq!(balances(&64), (18, 2)); + assert_eq!( + Elections::voter_info(&64).unwrap(), + VoterInfo { last_win: 0, last_active: 0, stake: 20, pot:0 } + ); + + assert_eq!(Elections::next_nonfull_voter_set(), 1); + + // now we charge the next voter. + vote(65, 0); + assert_eq!(balances(&65), (13, 2)); + assert_eq!( + Elections::voter_info(&65).unwrap(), + VoterInfo { last_win: 0, last_active: 0, stake: 15, pot:0 } + ); + }); +} + +#[test] +fn voting_subsequent_set_approvals_checks_voter_index() { + with_externalities(&mut ExtBuilder::default().build(), || { + assert_ok!(Elections::submit_candidacy(Origin::signed(2), 0)); + + assert_ok!(Elections::set_approvals(Origin::signed(3), vec![], 0, 0, 30)); + assert_ok!(Elections::set_approvals(Origin::signed(4), vec![], 0, 5, 40)); + assert_ok!(Elections::set_approvals(Origin::signed(5), vec![], 0, 100, 50)); + + // invalid index + assert_noop!( + Elections::set_approvals(Origin::signed(4), vec![true], 0, 5, 40), + "invalid voter index" + ); + // wrong index + assert_noop!( + Elections::set_approvals(Origin::signed(4), vec![true], 0, 0, 40), + "wrong voter index" + ); + // correct + assert_ok!(Elections::set_approvals(Origin::signed(4), vec![true], 0, 1, 40)); + }) +} + +#[test] +fn voting_cannot_lock_less_than_limit() { + with_externalities(&mut ExtBuilder::default().build(), || { + assert_ok!(Elections::submit_candidacy(Origin::signed(2), 0)); + + assert_noop!( + Elections::set_approvals(Origin::signed(3), vec![], 0, 0, 4), + "locked value must be more than limit", + ); + assert_ok!(Elections::set_approvals(Origin::signed(3), vec![], 0, 0, 5)); + }); +} + +#[test] +fn voting_locking_more_than_total_balance_is_moot() { + with_externalities(&mut ExtBuilder::default().voter_bond(2).build(), || { + assert_ok!(Elections::submit_candidacy(Origin::signed(2), 0)); + + assert_eq!(balances(&3), (30, 0)); + assert_ok!(Elections::set_approvals(Origin::signed(3), vec![], 0, 0, 35)); + + assert_eq!(balances(&3), (28, 2)); + assert_eq!( + Elections::voter_info(&3).unwrap(), + VoterInfo { last_win: 0, last_active: 0, stake: 30, pot:0 } + ); + }); +} + +#[test] +fn voting_locking_stake_and_reserving_bond_works() { + with_externalities(&mut ExtBuilder::default().voter_bond(2).build(), || { + assert_ok!(Elections::submit_candidacy(Origin::signed(5), 0)); + + assert_eq!(balances(&2), (20, 0)); + assert_eq!(locks(&2), vec![]); + assert_ok!(Elections::set_approvals(Origin::signed(2), vec![], 0, 0, 15)); + assert_eq!(balances(&2), (18, 2)); + assert_eq!(locks(&2), vec![15]); + + // deposit a bit more. + let _ = Balances::make_free_balance_be(&2, 100); + + // change vote + assert_ok!(Elections::set_approvals(Origin::signed(2), vec![true], 0, 0, 70)); + assert_eq!(balances(&2), (100, 2)); + assert_eq!(locks(&2), vec![70]); + + assert_ok!(Elections::retract_voter(Origin::signed(2), 0)); + + assert_eq!(balances(&2), (102, 0)); + assert_eq!(locks(&2), vec![]); + }); +} + +#[test] +fn voting_without_any_candidate_count_should_not_work() { + with_externalities(&mut ExtBuilder::default().build(), || { + System::set_block_number(1); + + assert_eq!(Elections::candidates().len(), 0); + + assert_noop!( + Elections::set_approvals(Origin::signed(4), vec![], 0, 0, 40), + "amount of candidates to receive approval votes should be non-zero" + ); + }); +} + +#[test] +fn voting_setting_an_approval_vote_count_more_than_candidate_count_should_not_work() { + with_externalities(&mut ExtBuilder::default().build(), || { + System::set_block_number(1); + + assert_ok!(Elections::submit_candidacy(Origin::signed(5), 0)); + assert_eq!(Elections::candidates().len(), 1); + + assert_noop!( + Elections::set_approvals(Origin::signed(4),vec![true, true], 0, 0, 40), + "amount of candidate votes cannot exceed amount of candidates" + ); + }); +} + +#[test] +fn voting_resubmitting_approvals_should_work() { + with_externalities(&mut ExtBuilder::default().build(), || { + System::set_block_number(1); + + assert_ok!(Elections::submit_candidacy(Origin::signed(5), 0)); + assert_ok!(Elections::set_approvals(Origin::signed(4), vec![true], 0, 0, 40)); + + assert_eq!(Elections::all_approvals_of(&4), vec![true]); + + assert_ok!(Elections::submit_candidacy(Origin::signed(2), 1)); + assert_ok!(Elections::submit_candidacy(Origin::signed(3), 2)); + assert_eq!(Elections::candidates().len(), 3); + assert_ok!(Elections::set_approvals(Origin::signed(4), vec![true, false, true], 0, 0, 40)); + + assert_eq!(Elections::all_approvals_of(&4), vec![true, false, true]); + }); +} + +#[test] +fn voting_retracting_voter_should_work() { + with_externalities(&mut ExtBuilder::default().build(), || { + System::set_block_number(1); + + assert_ok!(Elections::submit_candidacy(Origin::signed(5), 0)); + assert_eq!(Elections::candidates().len(), 1); + + assert_ok!(Elections::set_approvals(Origin::signed(1), vec![true], 0, 0, 10)); + assert_ok!(Elections::set_approvals(Origin::signed(2), vec![true], 0, 1, 20)); + assert_ok!(Elections::set_approvals(Origin::signed(3), vec![true], 0, 2, 30)); + assert_ok!(Elections::set_approvals(Origin::signed(4), vec![true], 0, 3, 40)); + + assert_eq!(voter_ids(), vec![1, 2, 3, 4]); + assert_eq!(Elections::all_approvals_of(&1), vec![true]); + assert_eq!(Elections::all_approvals_of(&2), vec![true]); + assert_eq!(Elections::all_approvals_of(&3), vec![true]); + assert_eq!(Elections::all_approvals_of(&4), vec![true]); + + assert_ok!(Elections::retract_voter(Origin::signed(1), 0)); + + assert_eq!(voter_ids(), vec![0, 2, 3, 4]); + assert_eq!(Elections::all_approvals_of(&1), Vec::::new()); + assert_eq!(Elections::all_approvals_of(&2), vec![true]); + assert_eq!(Elections::all_approvals_of(&3), vec![true]); + assert_eq!(Elections::all_approvals_of(&4), vec![true]); + + assert_ok!(Elections::retract_voter(Origin::signed(2), 1)); + + assert_eq!(voter_ids(), vec![0, 0, 3, 4]); + assert_eq!(Elections::all_approvals_of(&1), Vec::::new()); + assert_eq!(Elections::all_approvals_of(&2), Vec::::new()); + assert_eq!(Elections::all_approvals_of(&3), vec![true]); + assert_eq!(Elections::all_approvals_of(&4), vec![true]); + + assert_ok!(Elections::retract_voter(Origin::signed(3), 2)); + + assert_eq!(voter_ids(), vec![0, 0, 0, 4]); + assert_eq!(Elections::all_approvals_of(&1), Vec::::new()); + assert_eq!(Elections::all_approvals_of(&2), Vec::::new()); + assert_eq!(Elections::all_approvals_of(&3), Vec::::new()); + assert_eq!(Elections::all_approvals_of(&4), vec![true]); + }); +} + +#[test] +fn voting_invalid_retraction_index_should_not_work() { + with_externalities(&mut ExtBuilder::default().build(), || { + System::set_block_number(1); + assert_ok!(Elections::submit_candidacy(Origin::signed(3), 0)); + + assert_ok!(Elections::set_approvals(Origin::signed(1), vec![true], 0, 0, 10)); + assert_ok!(Elections::set_approvals(Origin::signed(2), vec![true], 0, 0, 20)); + assert_eq!(voter_ids(), vec![1, 2]); + assert_noop!(Elections::retract_voter(Origin::signed(1), 1), "retraction index mismatch"); + }); +} + +#[test] +fn voting_overflow_retraction_index_should_not_work() { + with_externalities(&mut ExtBuilder::default().build(), || { + System::set_block_number(1); + assert_ok!(Elections::submit_candidacy(Origin::signed(3), 0)); + + assert_ok!(Elections::set_approvals(Origin::signed(1), vec![true], 0, 0, 10)); + assert_noop!(Elections::retract_voter(Origin::signed(1), 1), "retraction index invalid"); + }); +} + +#[test] +fn voting_non_voter_retraction_should_not_work() { + with_externalities(&mut ExtBuilder::default().build(), || { + System::set_block_number(1); + assert_ok!(Elections::submit_candidacy(Origin::signed(3), 0)); + + assert_ok!(Elections::set_approvals(Origin::signed(1), vec![true], 0, 0, 10)); + assert_noop!(Elections::retract_voter(Origin::signed(2), 0), "cannot retract non-voter"); + }); +} + +#[test] +fn retracting_inactive_voter_should_work() { + with_externalities(&mut ExtBuilder::default().build(), || { + System::set_block_number(4); + assert_ok!(Elections::submit_candidacy(Origin::signed(2), 0)); + assert_ok!(Elections::set_approvals(Origin::signed(2), vec![true], 0, 0, 20)); + assert_ok!(Elections::end_block(System::block_number())); + + System::set_block_number(6); + assert_ok!(Elections::present_winner(Origin::signed(4), 2, 20, 0)); + assert_ok!(Elections::end_block(System::block_number())); + + System::set_block_number(8); + assert_ok!(Elections::submit_candidacy(Origin::signed(5), 0)); + assert_ok!(Elections::set_approvals(Origin::signed(5), vec![true], 1, 0, 50)); + assert_ok!(Elections::end_block(System::block_number())); + + System::set_block_number(10); + assert_ok!(Elections::present_winner(Origin::signed(4), 5, 50, 1)); + assert_ok!(Elections::end_block(System::block_number())); + + assert_ok!(Elections::reap_inactive_voter(Origin::signed(5), + (voter_ids().iter().position(|&i| i == 5).unwrap() as u32).into(), + 2, (voter_ids().iter().position(|&i| i == 2).unwrap() as u32).into(), + 2 + )); + + assert_eq!(voter_ids(), vec![0, 5]); + assert_eq!(Elections::all_approvals_of(&2).len(), 0); + assert_eq!(Balances::total_balance(&2), 20); + assert_eq!(Balances::total_balance(&5), 50); + }); +} + +#[test] +fn retracting_inactive_voter_with_other_candidates_in_slots_should_work() { + with_externalities(&mut ExtBuilder::default().voter_bond(2).build(), || { + System::set_block_number(4); + assert_ok!(Elections::submit_candidacy(Origin::signed(2), 0)); + assert_ok!(Elections::set_approvals(Origin::signed(2), vec![true], 0, 0, 20)); + assert_ok!(Elections::end_block(System::block_number())); + + System::set_block_number(6); + assert_ok!(Elections::present_winner(Origin::signed(4), 2, 20, 0)); + assert_ok!(Elections::end_block(System::block_number())); + + System::set_block_number(8); + assert_ok!(Elections::submit_candidacy(Origin::signed(5), 0)); + assert_ok!(Elections::set_approvals(Origin::signed(5), vec![true], 1, 0, 50)); + assert_ok!(Elections::end_block(System::block_number())); + + System::set_block_number(10); + assert_ok!(Elections::present_winner(Origin::signed(4), 5, 50, 1)); + assert_ok!(Elections::end_block(System::block_number())); + + System::set_block_number(11); + assert_ok!(Elections::submit_candidacy(Origin::signed(1), 0)); + + assert_ok!(Elections::reap_inactive_voter(Origin::signed(5), + (voter_ids().iter().position(|&i| i == 5).unwrap() as u32).into(), + 2, (voter_ids().iter().position(|&i| i == 2).unwrap() as u32).into(), + 2 + )); + + assert_eq!(voter_ids(), vec![0, 5]); + assert_eq!(Elections::all_approvals_of(&2).len(), 0); + }); +} + +#[test] +fn retracting_inactive_voter_with_bad_reporter_index_should_not_work() { + with_externalities(&mut ExtBuilder::default().build(), || { + System::set_block_number(4); + assert_ok!(Elections::submit_candidacy(Origin::signed(2), 0)); + assert_ok!(Elections::set_approvals(Origin::signed(2), vec![true], 0, 0, 20)); + assert_ok!(Elections::end_block(System::block_number())); + + System::set_block_number(6); + assert_ok!(Elections::present_winner(Origin::signed(4), 2, 20, 0)); + assert_ok!(Elections::end_block(System::block_number())); + + System::set_block_number(8); + assert_ok!(Elections::submit_candidacy(Origin::signed(5), 0)); + assert_ok!(Elections::set_approvals(Origin::signed(5), vec![true], 1, 0, 50)); + assert_ok!(Elections::end_block(System::block_number())); + + System::set_block_number(10); + assert_ok!(Elections::present_winner(Origin::signed(4), 5, 50, 1)); + assert_ok!(Elections::end_block(System::block_number())); + + assert_noop!(Elections::reap_inactive_voter(Origin::signed(2), + 42, + 2, (voter_ids().iter().position(|&i| i == 2).unwrap() as u32).into(), + 2 + ), "invalid reporter index"); + }); +} + +#[test] +fn retracting_inactive_voter_with_bad_target_index_should_not_work() { + with_externalities(&mut ExtBuilder::default().build(), || { + System::set_block_number(4); + assert_ok!(Elections::submit_candidacy(Origin::signed(2), 0)); + assert_ok!(Elections::set_approvals(Origin::signed(2), vec![true], 0, 0, 20)); + assert_ok!(Elections::end_block(System::block_number())); + + System::set_block_number(6); + assert_ok!(Elections::present_winner(Origin::signed(4), 2, 20, 0)); + assert_ok!(Elections::end_block(System::block_number())); + + System::set_block_number(8); + assert_ok!(Elections::submit_candidacy(Origin::signed(5), 0)); + assert_ok!(Elections::set_approvals(Origin::signed(5), vec![true], 1, 0, 50)); + assert_ok!(Elections::end_block(System::block_number())); + + System::set_block_number(10); + assert_ok!(Elections::present_winner(Origin::signed(4), 5, 50, 1)); + assert_ok!(Elections::end_block(System::block_number())); + + assert_noop!(Elections::reap_inactive_voter(Origin::signed(2), + (voter_ids().iter().position(|&i| i == 2).unwrap() as u32).into(), + 2, 42, + 2 + ), "invalid target index"); + }); +} + +#[test] +fn retracting_active_voter_should_slash_reporter() { + with_externalities(&mut ExtBuilder::default().build(), || { + System::set_block_number(4); + assert_ok!(Elections::submit_candidacy(Origin::signed(2), 0)); + assert_ok!(Elections::submit_candidacy(Origin::signed(3), 1)); + assert_ok!(Elections::submit_candidacy(Origin::signed(4), 2)); + assert_ok!(Elections::submit_candidacy(Origin::signed(5), 3)); + assert_ok!(Elections::set_approvals(Origin::signed(2), vec![true, false, false, false], 0, 0, 20)); + assert_ok!(Elections::set_approvals(Origin::signed(3), vec![false, true, false, false], 0, 0, 30)); + assert_ok!(Elections::set_approvals(Origin::signed(4), vec![false, false, true, false], 0, 0, 40)); + assert_ok!(Elections::set_approvals(Origin::signed(5), vec![false, false, false, true], 0, 0, 50)); + assert_ok!(Elections::end_block(System::block_number())); + + System::set_block_number(6); + assert_ok!(Elections::present_winner(Origin::signed(4), 2, 20, 0)); + assert_ok!(Elections::present_winner(Origin::signed(4), 3, 30, 0)); + assert_ok!(Elections::present_winner(Origin::signed(4), 4, 40, 0)); + assert_ok!(Elections::present_winner(Origin::signed(4), 5, 50, 0)); + assert_ok!(Elections::end_block(System::block_number())); + + System::set_block_number(8); + assert_ok!(Elections::set_desired_seats(Origin::ROOT, 3)); + assert_ok!(Elections::end_block(System::block_number())); + + System::set_block_number(10); + assert_ok!(Elections::present_winner(Origin::signed(4), 2, 20 + Elections::get_offset(20, 1), 1)); + assert_ok!(Elections::present_winner(Origin::signed(4), 3, 30 + Elections::get_offset(30, 1), 1)); + assert_ok!(Elections::end_block(System::block_number())); + + assert_eq!(Elections::vote_index(), 2); + assert_eq!(::InactiveGracePeriod::get(), 1); + assert_eq!(::VotingPeriod::get(), 4); + assert_eq!(Elections::voter_info(4), Some(VoterInfo { last_win: 1, last_active: 0, stake: 40, pot: 0 })); + + assert_ok!(Elections::reap_inactive_voter(Origin::signed(4), + (voter_ids().iter().position(|&i| i == 4).unwrap() as u32).into(), + 2, + (voter_ids().iter().position(|&i| i == 2).unwrap() as u32).into(), + 2 + )); + + assert_eq!(voter_ids(), vec![2, 3, 0, 5]); + assert_eq!(Elections::all_approvals_of(&4).len(), 0); + assert_eq!(Balances::total_balance(&4), 40); + }); +} + +#[test] +fn retracting_inactive_voter_by_nonvoter_should_not_work() { + with_externalities(&mut ExtBuilder::default().build(), || { + System::set_block_number(4); + assert_ok!(Elections::submit_candidacy(Origin::signed(2), 0)); + assert_ok!(Elections::set_approvals(Origin::signed(2), vec![true], 0, 0, 20)); + assert_ok!(Elections::end_block(System::block_number())); + + System::set_block_number(6); + assert_ok!(Elections::present_winner(Origin::signed(4), 2, 20, 0)); + assert_ok!(Elections::end_block(System::block_number())); + + System::set_block_number(8); + assert_ok!(Elections::submit_candidacy(Origin::signed(5), 0)); + assert_ok!(Elections::set_approvals(Origin::signed(5), vec![true], 1, 0, 50)); + assert_ok!(Elections::end_block(System::block_number())); + + System::set_block_number(10); + assert_ok!(Elections::present_winner(Origin::signed(4), 5, 50, 1)); + assert_ok!(Elections::end_block(System::block_number())); + + assert_noop!(Elections::reap_inactive_voter(Origin::signed(4), + 0, + 2, (voter_ids().iter().position(|&i| i == 2).unwrap() as u32).into(), + 2 + ), "reporter must be a voter"); + }); +} + +#[test] +fn candidacy_simple_candidate_submission_should_work() { + with_externalities(&mut ExtBuilder::default().build(), || { + System::set_block_number(1); + assert_eq!(Elections::candidates(), Vec::::new()); + assert_eq!(Elections::candidate_reg_info(1), None); + assert_eq!(Elections::candidate_reg_info(2), None); + assert_eq!(Elections::is_a_candidate(&1), false); + assert_eq!(Elections::is_a_candidate(&2), false); + + assert_ok!(Elections::submit_candidacy(Origin::signed(1), 0)); + assert_eq!(Elections::candidates(), vec![1]); + assert_eq!(Elections::candidate_reg_info(1), Some((0, 0))); + assert_eq!(Elections::candidate_reg_info(2), None); + assert_eq!(Elections::is_a_candidate(&1), true); + assert_eq!(Elections::is_a_candidate(&2), false); + + assert_ok!(Elections::submit_candidacy(Origin::signed(2), 1)); + assert_eq!(Elections::candidates(), vec![1, 2]); + assert_eq!(Elections::candidate_reg_info(1), Some((0, 0))); + assert_eq!(Elections::candidate_reg_info(2), Some((0, 1))); + assert_eq!(Elections::is_a_candidate(&1), true); + assert_eq!(Elections::is_a_candidate(&2), true); + }); +} + +#[test] +fn candidacy_submission_using_free_slot_should_work() { + let mut t = new_test_ext_with_candidate_holes(); + + with_externalities(&mut t, || { + System::set_block_number(1); + assert_eq!(Elections::candidates(), vec![0, 0, 1]); + + assert_ok!(Elections::submit_candidacy(Origin::signed(2), 1)); + assert_eq!(Elections::candidates(), vec![0, 2, 1]); + + assert_ok!(Elections::submit_candidacy(Origin::signed(3), 0)); + assert_eq!(Elections::candidates(), vec![3, 2, 1]); + }); +} + +#[test] +fn candidacy_submission_using_alternative_free_slot_should_work() { + let mut t = new_test_ext_with_candidate_holes(); + + with_externalities(&mut t, || { + System::set_block_number(1); + assert_eq!(Elections::candidates(), vec![0, 0, 1]); + + assert_ok!(Elections::submit_candidacy(Origin::signed(2), 0)); + assert_eq!(Elections::candidates(), vec![2, 0, 1]); + + assert_ok!(Elections::submit_candidacy(Origin::signed(3), 1)); + assert_eq!(Elections::candidates(), vec![2, 3, 1]); + }); +} + +#[test] +fn candidacy_submission_not_using_free_slot_should_not_work() { + let mut t = new_test_ext_with_candidate_holes(); + + with_externalities(&mut t, || { + System::set_block_number(1); + assert_noop!( + Elections::submit_candidacy(Origin::signed(4), 3), + "invalid candidate slot" + ); + }); +} + +#[test] +fn candidacy_bad_candidate_slot_submission_should_not_work() { + with_externalities(&mut ExtBuilder::default().build(), || { + System::set_block_number(1); + assert_eq!(Elections::candidates(), Vec::::new()); + assert_noop!( + Elections::submit_candidacy(Origin::signed(1), 1), + "invalid candidate slot" + ); + }); +} + +#[test] +fn candidacy_non_free_candidate_slot_submission_should_not_work() { + with_externalities(&mut ExtBuilder::default().build(), || { + System::set_block_number(1); + assert_eq!(Elections::candidates(), Vec::::new()); + assert_ok!(Elections::submit_candidacy(Origin::signed(1), 0)); + assert_eq!(Elections::candidates(), vec![1]); + assert_noop!( + Elections::submit_candidacy(Origin::signed(2), 0), + "invalid candidate slot" + ); + }); +} + +#[test] +fn candidacy_dupe_candidate_submission_should_not_work() { + with_externalities(&mut ExtBuilder::default().build(), || { + System::set_block_number(1); + assert_eq!(Elections::candidates(), Vec::::new()); + assert_ok!(Elections::submit_candidacy(Origin::signed(1), 0)); + assert_eq!(Elections::candidates(), vec![1]); + assert_noop!( + Elections::submit_candidacy(Origin::signed(1), 1), + "duplicate candidate submission" + ); + }); +} + +#[test] +fn candidacy_poor_candidate_submission_should_not_work() { + with_externalities(&mut ExtBuilder::default().build(), || { + System::set_block_number(1); + assert_eq!(Elections::candidates(), Vec::::new()); + assert_noop!( + Elections::submit_candidacy(Origin::signed(7), 0), + "candidate has not enough funds" + ); + }); +} + +#[test] +fn election_voting_should_work() { + with_externalities(&mut ExtBuilder::default().build(), || { + System::set_block_number(1); + + assert_ok!(Elections::submit_candidacy(Origin::signed(5), 0)); + + assert_ok!(Elections::set_approvals(Origin::signed(1), vec![true], 0, 0, 10)); + assert_ok!(Elections::set_approvals(Origin::signed(4), vec![true], 0, 1, 40)); + + assert_eq!(Elections::all_approvals_of(&1), vec![true]); + assert_eq!(Elections::all_approvals_of(&4), vec![true]); + assert_eq!(voter_ids(), vec![1, 4]); + + assert_ok!(Elections::submit_candidacy(Origin::signed(2), 1)); + assert_ok!(Elections::submit_candidacy(Origin::signed(3), 2)); + + assert_ok!(Elections::set_approvals(Origin::signed(2), vec![false, true, true], 0, 2, 20)); + assert_ok!(Elections::set_approvals(Origin::signed(3), vec![false, true, true], 0, 3, 30)); + + assert_eq!(Elections::all_approvals_of(&1), vec![true]); + assert_eq!(Elections::all_approvals_of(&4), vec![true]); + assert_eq!(Elections::all_approvals_of(&2), vec![false, true, true]); + assert_eq!(Elections::all_approvals_of(&3), vec![false, true, true]); + + assert_eq!(voter_ids(), vec![1, 4, 2, 3]); + }); +} + +#[test] +fn election_proxy_voting_should_work() { + with_externalities(&mut ExtBuilder::default().build(), || { + System::set_block_number(1); + + assert_ok!(Elections::submit_candidacy(Origin::signed(5), 0)); + + >::insert(11, 1); + >::insert(12, 2); + >::insert(13, 3); + >::insert(14, 4); + assert_ok!( + Elections::proxy_set_approvals(Origin::signed(11), vec![true], 0, 0, 10) + ); + assert_ok!( + Elections::proxy_set_approvals(Origin::signed(14), vec![true], 0, 1, 40) + ); + + assert_eq!(Elections::all_approvals_of(&1), vec![true]); + assert_eq!(Elections::all_approvals_of(&4), vec![true]); + assert_eq!(voter_ids(), vec![1, 4]); + + assert_ok!(Elections::submit_candidacy(Origin::signed(2), 1)); + assert_ok!(Elections::submit_candidacy(Origin::signed(3), 2)); + + assert_ok!( + Elections::proxy_set_approvals(Origin::signed(12), vec![false, true], 0, 2, 20) + ); + assert_ok!( + Elections::proxy_set_approvals(Origin::signed(13), vec![false, true], 0, 3, 30) + ); + + assert_eq!(Elections::all_approvals_of(&1), vec![true]); + assert_eq!(Elections::all_approvals_of(&4), vec![true]); + assert_eq!(Elections::all_approvals_of(&2), vec![false, true]); + assert_eq!(Elections::all_approvals_of(&3), vec![false, true]); + + assert_eq!(voter_ids(), vec![1, 4, 2, 3]); + }); +} + +#[test] +fn election_simple_tally_should_work() { + with_externalities(&mut ExtBuilder::default().build(), || { + System::set_block_number(4); + assert!(!Elections::presentation_active()); + + assert_ok!(Elections::submit_candidacy(Origin::signed(2), 0)); + assert_ok!(Elections::submit_candidacy(Origin::signed(5), 1)); + assert_ok!(Elections::set_approvals(Origin::signed(2), vec![true], 0, 0, 20)); + assert_ok!(Elections::set_approvals(Origin::signed(5), vec![false, true], 0, 0, 50)); + assert_eq!(voter_ids(), vec![2, 5]); + assert_eq!(Elections::all_approvals_of(&2), vec![true]); + assert_eq!(Elections::all_approvals_of(&5), vec![false, true]); + assert_ok!(Elections::end_block(System::block_number())); + + System::set_block_number(6); + assert!(Elections::presentation_active()); + assert_eq!(Elections::present_winner(Origin::signed(4), 2, 20, 0), Ok(())); + assert_eq!(Elections::present_winner(Origin::signed(4), 5, 50, 0), Ok(())); + assert_eq!(Elections::leaderboard(), Some(vec![(0, 0), (0, 0), (20, 2), (50, 5)])); + assert_ok!(Elections::end_block(System::block_number())); + + assert!(!Elections::presentation_active()); + assert_eq!(Elections::members(), vec![(5, 11), (2, 11)]); + + assert!(!Elections::is_a_candidate(&2)); + assert!(!Elections::is_a_candidate(&5)); + assert_eq!(Elections::vote_index(), 1); + assert_eq!( + Elections::voter_info(2), + Some(VoterInfo { last_win: 1, last_active: 0, stake: 20, pot: 0 }) + ); + assert_eq!( + Elections::voter_info(5), + Some(VoterInfo { last_win: 1, last_active: 0, stake: 50, pot: 0 }) + ); + }); +} + +#[test] +fn election_seats_should_be_released() { + with_externalities(&mut ExtBuilder::default().build(), || { + System::set_block_number(4); + assert_ok!(Elections::submit_candidacy(Origin::signed(2), 0)); + assert_ok!(Elections::submit_candidacy(Origin::signed(5), 1)); + assert_ok!(Elections::set_approvals(Origin::signed(2), vec![true, false], 0, 0, 20)); + assert_ok!(Elections::set_approvals(Origin::signed(5), vec![false, true], 0, 0, 50)); + assert_ok!(Elections::end_block(System::block_number())); + + System::set_block_number(6); + assert!(Elections::presentation_active()); + assert_eq!(Elections::present_winner(Origin::signed(4), 2, 20, 0), Ok(())); + assert_eq!(Elections::present_winner(Origin::signed(4), 5, 50, 0), Ok(())); + assert_eq!(Elections::leaderboard(), Some(vec![(0, 0), (0, 0), (20, 2), (50, 5)])); + assert_ok!(Elections::end_block(System::block_number())); + + assert_eq!(Elections::members(), vec![(5, 11), (2, 11)]); + let mut current = System::block_number(); + let free_block; + loop { + current += 1; + System::set_block_number(current); + assert_ok!(Elections::end_block(System::block_number())); + if Elections::members().len() == 0 { + free_block = current; + break; + } + } + // 11 + 2 which is the next voting period. + assert_eq!(free_block, 14); + }); +} + +#[test] +fn election_presentations_with_zero_staked_deposit_should_not_work() { + with_externalities(&mut ExtBuilder::default().build(), || { + System::set_block_number(4); + assert_ok!(Elections::submit_candidacy(Origin::signed(2), 0)); + assert_ok!(Elections::set_approvals(Origin::signed(2), vec![true], 0, 0, 20)); + assert_ok!(Elections::end_block(System::block_number())); + + System::set_block_number(6); + assert_noop!( + Elections::present_winner(Origin::signed(4), 2, 0, 0), + "stake deposited to present winner and be added to leaderboard should be non-zero" + ); + }); +} + +#[test] +fn election_double_presentations_should_be_punished() { + with_externalities(&mut ExtBuilder::default().build(), || { + assert!(Balances::can_slash(&4, 10)); + + System::set_block_number(4); + assert_ok!(Elections::submit_candidacy(Origin::signed(2), 0)); + assert_ok!(Elections::submit_candidacy(Origin::signed(5), 1)); + assert_ok!(Elections::set_approvals(Origin::signed(2), vec![true, false], 0, 0, 20)); + assert_ok!(Elections::set_approvals(Origin::signed(5), vec![false, true], 0, 0, 50)); + assert_ok!(Elections::end_block(System::block_number())); + + System::set_block_number(6); + assert_ok!(Elections::present_winner(Origin::signed(4), 2, 20, 0)); + assert_ok!(Elections::present_winner(Origin::signed(4), 5, 50, 0)); + assert_eq!(Elections::present_winner(Origin::signed(4), 5, 50, 0), Err("duplicate presentation")); + assert_ok!(Elections::end_block(System::block_number())); + + assert_eq!(Elections::members(), vec![(5, 11), (2, 11)]); + assert_eq!(Balances::total_balance(&4), 38); + }); +} + +#[test] +fn election_presenting_for_double_election_should_not_work() { + with_externalities(&mut ExtBuilder::default().build(), || { + System::set_block_number(4); + assert_eq!(Elections::submit_candidacy(Origin::signed(2), 0), Ok(())); + assert_ok!(Elections::set_approvals(Origin::signed(2), vec![true], 0, 0, 20)); + assert_ok!(Elections::end_block(System::block_number())); + + System::set_block_number(6); + assert_ok!(Elections::present_winner(Origin::signed(4), 2, 20, 0)); + assert_ok!(Elections::end_block(System::block_number())); + + System::set_block_number(8); + // NOTE: This is now mandatory to disable the lock + assert_ok!(Elections::retract_voter(Origin::signed(2), 0)); + assert_eq!(Elections::submit_candidacy(Origin::signed(2), 0), Ok(())); + assert_ok!(Elections::set_approvals(Origin::signed(2), vec![true], 1, 0, 20)); + assert_ok!(Elections::end_block(System::block_number())); + + System::set_block_number(10); + assert_noop!( + Elections::present_winner(Origin::signed(4), 2, 20, 1), + "candidate must not form a duplicated member if elected" + ); + }); +} + +#[test] +fn election_presenting_loser_should_not_work() { + with_externalities(&mut ExtBuilder::default().build(), || { + System::set_block_number(4); + assert_ok!(Elections::submit_candidacy(Origin::signed(1), 0)); + assert_ok!(Elections::set_approvals(Origin::signed(6), vec![true], 0, 0, 60)); + assert_ok!(Elections::submit_candidacy(Origin::signed(2), 1)); + assert_ok!(Elections::set_approvals(Origin::signed(2), vec![false, true], 0, 0, 20)); + assert_ok!(Elections::submit_candidacy(Origin::signed(3), 2)); + assert_ok!(Elections::set_approvals(Origin::signed(3), vec![false, false, true], 0, 0, 30)); + assert_ok!(Elections::submit_candidacy(Origin::signed(4), 3)); + assert_ok!(Elections::set_approvals(Origin::signed(4), vec![false, false, false, true], 0, 0, 40)); + assert_ok!(Elections::submit_candidacy(Origin::signed(5), 4)); + assert_ok!(Elections::set_approvals(Origin::signed(5), vec![false, false, false, false, true], 0, 0, 50)); + assert_ok!(Elections::end_block(System::block_number())); + + System::set_block_number(6); + assert_ok!(Elections::present_winner(Origin::signed(4), 1, 60, 0)); + assert_ok!(Elections::present_winner(Origin::signed(4), 3, 30, 0)); + assert_ok!(Elections::present_winner(Origin::signed(4), 4, 40, 0)); + assert_ok!(Elections::present_winner(Origin::signed(4), 5, 50, 0)); + + assert_eq!(Elections::leaderboard(), Some(vec![ + (30, 3), + (40, 4), + (50, 5), + (60, 1) + ])); + + assert_noop!(Elections::present_winner(Origin::signed(4), 2, 20, 0), "candidate not worthy of leaderboard"); + }); +} + +#[test] +fn election_presenting_loser_first_should_not_matter() { + with_externalities(&mut ExtBuilder::default().build(), || { + System::set_block_number(4); + assert_ok!(Elections::submit_candidacy(Origin::signed(1), 0)); + assert_ok!(Elections::set_approvals(Origin::signed(6), vec![true], 0, 0, 60)); + assert_ok!(Elections::submit_candidacy(Origin::signed(2), 1)); + assert_ok!(Elections::set_approvals(Origin::signed(2), vec![false, true], 0, 0, 20)); + assert_ok!(Elections::submit_candidacy(Origin::signed(3), 2)); + assert_ok!(Elections::set_approvals(Origin::signed(3), vec![false, false, true], 0, 0, 30)); + assert_ok!(Elections::submit_candidacy(Origin::signed(4), 3)); + assert_ok!(Elections::set_approvals(Origin::signed(4), vec![false, false, false, true], 0, 0, 40)); + assert_ok!(Elections::submit_candidacy(Origin::signed(5), 4)); + assert_ok!(Elections::set_approvals(Origin::signed(5), vec![false, false, false, false, true], 0, 0, 50)); + assert_ok!(Elections::end_block(System::block_number())); + + System::set_block_number(6); + assert_ok!(Elections::present_winner(Origin::signed(4), 2, 20, 0)); + assert_ok!(Elections::present_winner(Origin::signed(4), 1, 60, 0)); + assert_ok!(Elections::present_winner(Origin::signed(4), 3, 30, 0)); + assert_ok!(Elections::present_winner(Origin::signed(4), 4, 40, 0)); + assert_ok!(Elections::present_winner(Origin::signed(4), 5, 50, 0)); + + assert_eq!(Elections::leaderboard(), Some(vec![ + (30, 3), + (40, 4), + (50, 5), + (60, 1) + ])); + }); +} + +#[test] +fn election_present_outside_of_presentation_period_should_not_work() { + with_externalities(&mut ExtBuilder::default().build(), || { + System::set_block_number(4); + assert!(!Elections::presentation_active()); + assert_noop!( + Elections::present_winner(Origin::signed(5), 5, 1, 0), + "cannot present outside of presentation period" + ); + }); +} + +#[test] +fn election_present_with_invalid_vote_index_should_not_work() { + with_externalities(&mut ExtBuilder::default().build(), || { + System::set_block_number(4); + assert_ok!(Elections::submit_candidacy(Origin::signed(2), 0)); + assert_ok!(Elections::submit_candidacy(Origin::signed(5), 1)); + assert_ok!(Elections::set_approvals(Origin::signed(2), vec![true, false], 0, 0, 20)); + assert_ok!(Elections::set_approvals(Origin::signed(5), vec![false, true], 0, 0, 50)); + assert_ok!(Elections::end_block(System::block_number())); + + System::set_block_number(6); + assert_noop!(Elections::present_winner(Origin::signed(4), 2, 20, 1), "index not current"); + }); +} + +#[test] +fn election_present_when_presenter_is_poor_should_not_work() { + let test_present = |p| { + with_externalities(&mut ExtBuilder::default() + .voting_fee(5) + .voter_bond(2) + .bad_presentation_punishment(p) + .build(), + || { + System::set_block_number(4); + let _ = Balances::make_free_balance_be(&1, 15); + assert!(!Elections::presentation_active()); + + assert_ok!(Elections::submit_candidacy(Origin::signed(1), 0)); // -3 + assert_eq!(Balances::free_balance(&1), 12); + assert_ok!(Elections::set_approvals(Origin::signed(1), vec![true], 0, 0, 15)); // -2 -5 + assert_ok!(Elections::end_block(System::block_number())); + + System::set_block_number(6); + assert_eq!(Balances::free_balance(&1), 5); + assert_eq!(Balances::reserved_balance(&1), 5); + if p > 5 { + assert_noop!(Elections::present_winner( + Origin::signed(1), 1, 10, 0), + "presenter must have sufficient slashable funds" + ); + } else { + assert_ok!(Elections::present_winner(Origin::signed(1), 1, 10, 0)); + } + }); + }; + test_present(4); + test_present(6); +} + +#[test] +fn election_invalid_present_tally_should_slash() { + with_externalities(&mut ExtBuilder::default().build(), || { + System::set_block_number(4); + assert!(!Elections::presentation_active()); + assert_eq!(Balances::total_balance(&4), 40); + + assert_ok!(Elections::submit_candidacy(Origin::signed(2), 0)); + assert_ok!(Elections::submit_candidacy(Origin::signed(5), 1)); + assert_ok!(Elections::set_approvals(Origin::signed(2), vec![true, false], 0, 0, 20)); + assert_ok!(Elections::set_approvals(Origin::signed(5), vec![false, true], 0, 0, 50)); + assert_ok!(Elections::end_block(System::block_number())); + + System::set_block_number(6); + assert_err!(Elections::present_winner(Origin::signed(4), 2, 80, 0), "incorrect total"); + + assert_eq!(Balances::total_balance(&4), 38); + }); +} + +#[test] +fn election_runners_up_should_be_kept() { + with_externalities(&mut ExtBuilder::default().build(), || { + System::set_block_number(4); + assert!(!Elections::presentation_active()); + + assert_ok!(Elections::submit_candidacy(Origin::signed(1), 0)); + assert_ok!(Elections::set_approvals(Origin::signed(6), vec![true], 0, 0, 60)); + assert_ok!(Elections::submit_candidacy(Origin::signed(2), 1)); + assert_ok!(Elections::set_approvals(Origin::signed(2), vec![false, true], 0, 0, 20)); + assert_ok!(Elections::submit_candidacy(Origin::signed(3), 2)); + assert_ok!(Elections::set_approvals(Origin::signed(3), vec![false, false, true], 0, 0, 30)); + assert_ok!(Elections::submit_candidacy(Origin::signed(4), 3)); + assert_ok!(Elections::set_approvals(Origin::signed(4), vec![false, false, false, true], 0, 0, 40)); + assert_ok!(Elections::submit_candidacy(Origin::signed(5), 4)); + assert_ok!(Elections::set_approvals(Origin::signed(5), vec![false, false, false, false, true], 0, 0, 50)); + + assert_ok!(Elections::end_block(System::block_number())); + + System::set_block_number(6); + assert!(Elections::presentation_active()); + assert_ok!(Elections::present_winner(Origin::signed(4), 1, 60, 0)); + // leaderboard length is the empty seats plus the carry count (i.e. 5 + 2), where those + // to be carried are the lowest and stored in lowest indices + assert_eq!(Elections::leaderboard(), Some(vec![ + (0, 0), + (0, 0), + (0, 0), + (60, 1) + ])); + assert_ok!(Elections::present_winner(Origin::signed(4), 3, 30, 0)); + assert_ok!(Elections::present_winner(Origin::signed(4), 4, 40, 0)); + assert_ok!(Elections::present_winner(Origin::signed(4), 5, 50, 0)); + assert_eq!(Elections::leaderboard(), Some(vec![ + (30, 3), + (40, 4), + (50, 5), + (60, 1) + ])); + + assert_ok!(Elections::end_block(System::block_number())); + + assert!(!Elections::presentation_active()); + assert_eq!(Elections::members(), vec![(1, 11), (5, 11)]); + + assert!(!Elections::is_a_candidate(&1)); + assert!(!Elections::is_a_candidate(&5)); + assert!(!Elections::is_a_candidate(&2)); + assert!(Elections::is_a_candidate(&3)); + assert!(Elections::is_a_candidate(&4)); + assert_eq!(Elections::vote_index(), 1); + assert_eq!(Elections::voter_info(2), Some(VoterInfo { last_win: 0, last_active: 0, stake: 20, pot: 0 })); + assert_eq!(Elections::voter_info(3), Some(VoterInfo { last_win: 0, last_active: 0, stake: 30, pot: 0 })); + assert_eq!(Elections::voter_info(4), Some(VoterInfo { last_win: 0, last_active: 0, stake: 40, pot: 0 })); + assert_eq!(Elections::voter_info(5), Some(VoterInfo { last_win: 1, last_active: 0, stake: 50, pot: 0 })); + assert_eq!(Elections::voter_info(6), Some(VoterInfo { last_win: 1, last_active: 0, stake: 60, pot: 0 })); + assert_eq!(Elections::candidate_reg_info(3), Some((0, 2))); + assert_eq!(Elections::candidate_reg_info(4), Some((0, 3))); + }); +} + +#[test] +fn election_second_tally_should_use_runners_up() { + with_externalities(&mut ExtBuilder::default().build(), || { + System::set_block_number(4); + assert_ok!(Elections::submit_candidacy(Origin::signed(1), 0)); + assert_ok!(Elections::set_approvals(Origin::signed(6), vec![true], 0, 0, 60)); + assert_ok!(Elections::submit_candidacy(Origin::signed(2), 1)); + assert_ok!(Elections::set_approvals(Origin::signed(2), vec![false, true], 0, 0, 20)); + assert_ok!(Elections::submit_candidacy(Origin::signed(3), 2)); + assert_ok!(Elections::set_approvals(Origin::signed(3), vec![false, false, true], 0, 0, 30)); + assert_ok!(Elections::submit_candidacy(Origin::signed(4), 3)); + assert_ok!(Elections::set_approvals(Origin::signed(4), vec![false, false, false, true], 0, 0, 40)); + assert_ok!(Elections::submit_candidacy(Origin::signed(5), 4)); + assert_ok!(Elections::set_approvals(Origin::signed(5), vec![false, false, false, false, true], 0, 0, 50)); + assert_ok!(Elections::end_block(System::block_number())); + + System::set_block_number(6); + assert_ok!(Elections::present_winner(Origin::signed(4), 1, 60, 0)); + assert_ok!(Elections::present_winner(Origin::signed(4), 3, 30, 0)); + assert_ok!(Elections::present_winner(Origin::signed(4), 4, 40, 0)); + assert_ok!(Elections::present_winner(Origin::signed(4), 5, 50, 0)); + assert_ok!(Elections::end_block(System::block_number())); + + System::set_block_number(8); + assert_ok!(Elections::set_approvals(Origin::signed(6), vec![false, false, true, false], 1, 0, 60)); + assert_ok!(Elections::set_desired_seats(Origin::ROOT, 3)); + assert_ok!(Elections::end_block(System::block_number())); + + System::set_block_number(10); + assert_ok!(Elections::present_winner(Origin::signed(4), 3, 30 + Elections::get_offset(30, 1) + 60, 1)); + assert_ok!(Elections::present_winner(Origin::signed(4), 4, 40 + Elections::get_offset(40, 1), 1)); + assert_ok!(Elections::end_block(System::block_number())); + + assert!(!Elections::presentation_active()); + assert_eq!(Elections::members(), vec![(1, 11), (5, 11), (3, 15)]); + + assert!(!Elections::is_a_candidate(&1)); + assert!(!Elections::is_a_candidate(&2)); + assert!(!Elections::is_a_candidate(&3)); + assert!(!Elections::is_a_candidate(&5)); + assert!(Elections::is_a_candidate(&4)); + assert_eq!(Elections::vote_index(), 2); + assert_eq!(Elections::voter_info(2), Some( VoterInfo { last_win: 0, last_active: 0, stake: 20, pot: 0})); + assert_eq!(Elections::voter_info(3), Some( VoterInfo { last_win: 2, last_active: 0, stake: 30, pot: 0})); + assert_eq!(Elections::voter_info(4), Some( VoterInfo { last_win: 0, last_active: 0, stake: 40, pot: 0})); + assert_eq!(Elections::voter_info(5), Some( VoterInfo { last_win: 1, last_active: 0, stake: 50, pot: 0})); + assert_eq!( + Elections::voter_info(6), + Some(VoterInfo { last_win: 2, last_active: 1, stake: 60, pot: 0}) + ); + + assert_eq!(Elections::candidate_reg_info(4), Some((0, 3))); + }); +} + +#[test] +fn election_loser_candidates_bond_gets_slashed() { + with_externalities(&mut ExtBuilder::default().desired_seats(1).build(), || { + System::set_block_number(4); + assert!(!Elections::presentation_active()); + + assert_ok!(Elections::submit_candidacy(Origin::signed(1), 0)); + assert_ok!(Elections::submit_candidacy(Origin::signed(2), 1)); + assert_ok!(Elections::submit_candidacy(Origin::signed(3), 2)); + assert_ok!(Elections::submit_candidacy(Origin::signed(4), 3)); + + assert_eq!(balances(&2), (17, 3)); + + assert_ok!(Elections::set_approvals(Origin::signed(5), vec![true], 0, 0, 50)); + assert_ok!( + Elections::set_approvals(Origin::signed(1), vec![false, true, true, true], 0, 0, 10) + ); + + assert_ok!(Elections::end_block(System::block_number())); + + System::set_block_number(6); + assert!(Elections::presentation_active()); + assert_eq!(Elections::present_winner(Origin::signed(4), 4, 10, 0), Ok(())); + assert_eq!(Elections::present_winner(Origin::signed(3), 3, 10, 0), Ok(())); + assert_eq!(Elections::present_winner(Origin::signed(2), 2, 10, 0), Ok(())); + assert_eq!(Elections::present_winner(Origin::signed(1), 1, 50, 0), Ok(())); + + + // winner + carry + assert_eq!(Elections::leaderboard(), Some(vec![(10, 3), (10, 4), (50, 1)])); + assert_ok!(Elections::end_block(System::block_number())); + assert!(!Elections::presentation_active()); + assert_eq!(Elections::members(), vec![(1, 11)]); + + // account 2 is not a runner up or in leaderboard. + assert_eq!(balances(&2), (17, 0)); + }); +} + +#[test] +fn pot_accumulating_weight_and_decaying_should_work() { + with_externalities(&mut ExtBuilder::default().balance_factor(10).build(), || { + System::set_block_number(4); + assert!(!Elections::presentation_active()); + + assert_ok!(Elections::submit_candidacy(Origin::signed(6), 0)); + assert_ok!(Elections::submit_candidacy(Origin::signed(5), 1)); + assert_ok!(Elections::submit_candidacy(Origin::signed(1), 2)); + + assert_ok!( + Elections::set_approvals(Origin::signed(6), vec![true, false, false], 0, 0, 600) + ); + assert_ok!( + Elections::set_approvals(Origin::signed(5), vec![false, true, false], 0, 0, 500) + ); + assert_ok!( + Elections::set_approvals(Origin::signed(1), vec![false, false, true], 0, 0, 100) + ); + + assert_ok!(Elections::end_block(System::block_number())); + + System::set_block_number(6); + assert!(Elections::presentation_active()); + + assert_eq!(Elections::present_winner(Origin::signed(6), 6, 600, 0), Ok(())); + assert_eq!(Elections::present_winner(Origin::signed(5), 5, 500, 0), Ok(())); + assert_eq!(Elections::present_winner(Origin::signed(1), 1, 100, 0), Ok(())); + assert_eq!(Elections::leaderboard(), Some(vec![(0, 0), (100, 1), (500, 5), (600, 6)])); + assert_ok!(Elections::end_block(System::block_number())); + + assert_eq!(Elections::members(), vec![(6, 11), (5, 11)]); + assert_eq!( + Elections::voter_info(6).unwrap(), + VoterInfo { last_win: 1, last_active: 0, stake: 600, pot: 0}, + ); + assert_eq!( + Elections::voter_info(5).unwrap(), + VoterInfo { last_win: 1, last_active: 0, stake: 500, pot: 0}, + ); + assert_eq!( + Elections::voter_info(1).unwrap(), + VoterInfo { last_win: 0, last_active: 0, stake: 100, pot: 0}, + ); + + System::set_block_number(12); + // retract needed to unlock approval funds => submit candidacy again. + assert_ok!(Elections::retract_voter(Origin::signed(6), 0)); + assert_ok!(Elections::retract_voter(Origin::signed(5), 1)); + assert_ok!(Elections::submit_candidacy(Origin::signed(6), 0)); + assert_ok!(Elections::submit_candidacy(Origin::signed(5), 1)); + assert_ok!( + Elections::set_approvals(Origin::signed(6), vec![true, false, false], 1, 0, 600) + ); + assert_ok!( + Elections::set_approvals(Origin::signed(5), vec![false, true, false], 1, 1, 500) + ); + assert_ok!(Elections::end_block(System::block_number())); + + System::set_block_number(14); + assert!(Elections::presentation_active()); + assert_eq!(Elections::present_winner(Origin::signed(6), 6, 600, 1), Ok(())); + assert_eq!(Elections::present_winner(Origin::signed(5), 5, 500, 1), Ok(())); + assert_eq!(Elections::present_winner(Origin::signed(1), 1, 100 + Elections::get_offset(100, 1), 1), Ok(())); + assert_eq!(Elections::leaderboard(), Some(vec![(0, 0), (100 + 96, 1), (500, 5), (600, 6)])); + assert_ok!(Elections::end_block(System::block_number())); + + assert_eq!(Elections::members(), vec![(6, 19), (5, 19)]); + assert_eq!( + Elections::voter_info(6).unwrap(), + VoterInfo { last_win: 2, last_active: 1, stake: 600, pot:0 } + ); + assert_eq!(Elections::voter_info(5).unwrap(), VoterInfo { last_win: 2, last_active: 1, stake: 500, pot:0 }); + assert_eq!(Elections::voter_info(1).unwrap(), VoterInfo { last_win: 0, last_active: 0, stake: 100, pot:0 }); + + System::set_block_number(20); + assert_ok!(Elections::retract_voter(Origin::signed(6), 0)); + assert_ok!(Elections::retract_voter(Origin::signed(5), 1)); + assert_ok!(Elections::submit_candidacy(Origin::signed(6), 0)); + assert_ok!(Elections::submit_candidacy(Origin::signed(5), 1)); + assert_ok!(Elections::set_approvals(Origin::signed(6), vec![true, false, false], 2, 0, 600)); + assert_ok!(Elections::set_approvals(Origin::signed(5), vec![false, true, false], 2, 1, 500)); + assert_ok!(Elections::end_block(System::block_number())); + + System::set_block_number(22); + assert!(Elections::presentation_active()); + assert_eq!(Elections::present_winner(Origin::signed(6), 6, 600, 2), Ok(())); + assert_eq!(Elections::present_winner(Origin::signed(5), 5, 500, 2), Ok(())); + assert_eq!(Elections::present_winner(Origin::signed(1), 1, 100 + Elections::get_offset(100, 2), 2), Ok(())); + assert_eq!(Elections::leaderboard(), Some(vec![(0, 0), (100 + 96 + 93, 1), (500, 5), (600, 6)])); + assert_ok!(Elections::end_block(System::block_number())); + + assert_eq!(Elections::members(), vec![(6, 27), (5, 27)]); + assert_eq!( + Elections::voter_info(6).unwrap(), + VoterInfo { last_win: 3, last_active: 2, stake: 600, pot: 0} + ); + assert_eq!(Elections::voter_info(5).unwrap(), VoterInfo { last_win: 3, last_active: 2, stake: 500, pot: 0}); + assert_eq!(Elections::voter_info(1).unwrap(), VoterInfo { last_win: 0, last_active: 0, stake: 100, pot: 0}); + + + System::set_block_number(28); + assert_ok!(Elections::retract_voter(Origin::signed(6), 0)); + assert_ok!(Elections::retract_voter(Origin::signed(5), 1)); + assert_ok!(Elections::submit_candidacy(Origin::signed(6), 0)); + assert_ok!(Elections::submit_candidacy(Origin::signed(5), 1)); + assert_ok!(Elections::set_approvals(Origin::signed(6), vec![true, false, false], 3, 0, 600)); + assert_ok!(Elections::set_approvals(Origin::signed(5), vec![false, true, false], 3, 1, 500)); + assert_ok!(Elections::end_block(System::block_number())); + + System::set_block_number(30); + assert!(Elections::presentation_active()); + assert_eq!(Elections::present_winner(Origin::signed(6), 6, 600, 3), Ok(())); + assert_eq!(Elections::present_winner(Origin::signed(5), 5, 500, 3), Ok(())); + assert_eq!(Elections::present_winner(Origin::signed(1), 1, 100 + Elections::get_offset(100, 3), 3), Ok(())); + assert_eq!(Elections::leaderboard(), Some(vec![(0, 0), (100 + 96 + 93 + 90, 1), (500, 5), (600, 6)])); + assert_ok!(Elections::end_block(System::block_number())); + + assert_eq!(Elections::members(), vec![(6, 35), (5, 35)]); + assert_eq!( + Elections::voter_info(6).unwrap(), + VoterInfo { last_win: 4, last_active: 3, stake: 600, pot: 0} + ); + assert_eq!(Elections::voter_info(5).unwrap(), VoterInfo { last_win: 4, last_active: 3, stake: 500, pot: 0}); + assert_eq!(Elections::voter_info(1).unwrap(), VoterInfo { last_win: 0, last_active: 0, stake: 100, pot: 0}); + }) +} + +#[test] +fn pot_winning_resets_accumulated_pot() { + with_externalities(&mut ExtBuilder::default().balance_factor(10).build(), || { + System::set_block_number(4); + assert!(!Elections::presentation_active()); + + assert_ok!(Elections::submit_candidacy(Origin::signed(6), 0)); + assert_ok!(Elections::submit_candidacy(Origin::signed(4), 1)); + assert_ok!(Elections::submit_candidacy(Origin::signed(3), 2)); + assert_ok!(Elections::submit_candidacy(Origin::signed(2), 3)); + + assert_ok!(Elections::set_approvals(Origin::signed(6), vec![true, false, false, false], 0, 0, 600)); + assert_ok!(Elections::set_approvals(Origin::signed(4), vec![false, true, false, false], 0, 1, 400)); + assert_ok!(Elections::set_approvals(Origin::signed(3), vec![false, false, true, true], 0, 2, 300)); + assert_ok!(Elections::end_block(System::block_number())); + + System::set_block_number(6); + assert!(Elections::presentation_active()); + assert_eq!(Elections::present_winner(Origin::signed(6), 6, 600, 0), Ok(())); + assert_eq!(Elections::present_winner(Origin::signed(4), 4, 400, 0), Ok(())); + assert_eq!(Elections::present_winner(Origin::signed(3), 3, 300, 0), Ok(())); + assert_eq!(Elections::present_winner(Origin::signed(2), 2, 300, 0), Ok(())); + assert_eq!(Elections::leaderboard(), Some(vec![(300, 2), (300, 3), (400, 4), (600, 6)])); + assert_ok!(Elections::end_block(System::block_number())); + + assert_eq!(Elections::members(), vec![(6, 11), (4, 11)]); + + System::set_block_number(12); + assert_ok!(Elections::retract_voter(Origin::signed(6), 0)); + assert_ok!(Elections::retract_voter(Origin::signed(4), 1)); + assert_ok!(Elections::submit_candidacy(Origin::signed(6), 0)); + assert_ok!(Elections::submit_candidacy(Origin::signed(4), 1)); + assert_ok!(Elections::set_approvals(Origin::signed(6), vec![true, false, false, false], 1, 0, 600)); + assert_ok!(Elections::set_approvals(Origin::signed(4), vec![false, true, false, false], 1, 1, 400)); + assert_ok!(Elections::end_block(System::block_number())); + + System::set_block_number(14); + assert!(Elections::presentation_active()); + assert_eq!(Elections::present_winner(Origin::signed(6), 6, 600, 1), Ok(())); + assert_eq!(Elections::present_winner(Origin::signed(4), 4, 400, 1), Ok(())); + assert_eq!(Elections::present_winner(Origin::signed(3), 3, 300 + Elections::get_offset(300, 1), 1), Ok(())); + assert_eq!(Elections::present_winner(Origin::signed(2), 2, 300 + Elections::get_offset(300, 1), 1), Ok(())); + assert_eq!(Elections::leaderboard(), Some(vec![(400, 4), (588, 2), (588, 3), (600, 6)])); + assert_ok!(Elections::end_block(System::block_number())); + + assert_eq!(Elections::members(), vec![(6, 19), (3, 19)]); + + System::set_block_number(20); + assert_ok!(Elections::end_block(System::block_number())); + + System::set_block_number(22); + // 2 will not get re-elected with 300 + 288, instead just 300. + // because one of 3's candidates (3) won in previous round + // 4 on the other hand will get extra weight since it was unlucky. + assert_eq!(Elections::present_winner(Origin::signed(3), 2, 300, 2), Ok(())); + assert_eq!(Elections::present_winner(Origin::signed(4), 4, 400 + Elections::get_offset(400, 1), 2), Ok(())); + assert_ok!(Elections::end_block(System::block_number())); + + assert_eq!(Elections::members(), vec![(4, 27), (2, 27)]); + }) +} + +#[test] +fn pot_resubmitting_approvals_stores_pot() { + with_externalities(&mut ExtBuilder::default() + .voter_bond(0) + .voting_fee(0) + .balance_factor(10) + .build(), + || { System::set_block_number(4); + assert!(!Elections::presentation_active()); + + assert_ok!(Elections::submit_candidacy(Origin::signed(6), 0)); + assert_ok!(Elections::submit_candidacy(Origin::signed(5), 1)); + assert_ok!(Elections::submit_candidacy(Origin::signed(1), 2)); + + assert_ok!(Elections::set_approvals(Origin::signed(6), vec![true, false, false], 0, 0, 600)); + assert_ok!(Elections::set_approvals(Origin::signed(5), vec![false, true, false], 0, 1, 500)); + assert_ok!(Elections::set_approvals(Origin::signed(1), vec![false, false, true], 0, 2, 100)); + + assert_ok!(Elections::end_block(System::block_number())); + + System::set_block_number(6); + assert!(Elections::presentation_active()); + + assert_eq!(Elections::present_winner(Origin::signed(6), 6, 600, 0), Ok(())); + assert_eq!(Elections::present_winner(Origin::signed(5), 5, 500, 0), Ok(())); + assert_eq!(Elections::present_winner(Origin::signed(1), 1, 100, 0), Ok(())); + assert_eq!(Elections::leaderboard(), Some(vec![(0, 0), (100, 1), (500, 5), (600, 6)])); + assert_ok!(Elections::end_block(System::block_number())); + + assert_eq!(Elections::members(), vec![(6, 11), (5, 11)]); + + System::set_block_number(12); + assert_ok!(Elections::retract_voter(Origin::signed(6), 0)); + assert_ok!(Elections::retract_voter(Origin::signed(5), 1)); + assert_ok!(Elections::submit_candidacy(Origin::signed(6), 0)); + assert_ok!(Elections::submit_candidacy(Origin::signed(5), 1)); + assert_ok!(Elections::set_approvals(Origin::signed(6), vec![true, false, false], 1, 0, 600)); + assert_ok!(Elections::set_approvals(Origin::signed(5), vec![false, true, false], 1, 1, 500)); + // give 1 some new high balance + let _ = Balances::make_free_balance_be(&1, 997); + assert_ok!(Elections::set_approvals(Origin::signed(1), vec![false, false, true], 1, 2, 1000)); + assert_eq!(Elections::voter_info(1).unwrap(), + VoterInfo { + stake: 1000, // 997 + 3 which is candidacy bond. + pot: Elections::get_offset(100, 1), + last_active: 1, + last_win: 1, + } + ); + assert_ok!(Elections::end_block(System::block_number())); + + assert_eq!(Elections::members(), vec![(6, 11), (5, 11)]); + + System::set_block_number(14); + assert!(Elections::presentation_active()); + assert_eq!(Elections::present_winner(Origin::signed(6), 6, 600, 1), Ok(())); + assert_eq!(Elections::present_winner(Origin::signed(5), 5, 500, 1), Ok(())); + assert_eq!(Elections::present_winner(Origin::signed(1), 1, 1000 + 96 /* pot */, 1), Ok(())); + assert_eq!(Elections::leaderboard(), Some(vec![(0, 0), (500, 5), (600, 6), (1096, 1)])); + assert_ok!(Elections::end_block(System::block_number())); + + assert_eq!(Elections::members(), vec![(1, 19), (6, 19)]); + }) +} + +#[test] +fn pot_get_offset_should_work() { + with_externalities(&mut ExtBuilder::default().build(), || { + assert_eq!(Elections::get_offset(100, 0), 0); + assert_eq!(Elections::get_offset(100, 1), 96); + assert_eq!(Elections::get_offset(100, 2), 96 + 93); + assert_eq!(Elections::get_offset(100, 3), 96 + 93 + 90); + assert_eq!(Elections::get_offset(100, 4), 96 + 93 + 90 + 87); + // limit + assert_eq!(Elections::get_offset(100, 1000), 100 * 24); + + assert_eq!(Elections::get_offset(50_000_000_000, 0), 0); + assert_eq!(Elections::get_offset(50_000_000_000, 1), 48_000_000_000); + assert_eq!(Elections::get_offset(50_000_000_000, 2), 48_000_000_000 + 46_080_000_000); + assert_eq!(Elections::get_offset(50_000_000_000, 3), 48_000_000_000 + 46_080_000_000 + 44_236_800_000); + assert_eq!( + Elections::get_offset(50_000_000_000, 4), + 48_000_000_000 + 46_080_000_000 + 44_236_800_000 + 42_467_328_000 + ); + // limit + assert_eq!(Elections::get_offset(50_000_000_000, 1000), 50_000_000_000 * 24); + }) +} + +#[test] +fn pot_get_offset_with_zero_decay() { + with_externalities(&mut ExtBuilder::default().decay_ratio(0).build(), || { + assert_eq!(Elections::get_offset(100, 0), 0); + assert_eq!(Elections::get_offset(100, 1), 0); + assert_eq!(Elections::get_offset(100, 2), 0); + assert_eq!(Elections::get_offset(100, 3), 0); + // limit + assert_eq!(Elections::get_offset(100, 1000), 0); + }) +} diff --git a/srml/example/Cargo.toml b/srml/example/Cargo.toml index 87069a487a19a617f31fd08b9e3fcf05c2951516..695e0602fb32757b203213c7ad7a18d89c5dcdfd 100644 --- a/srml/example/Cargo.toml +++ b/srml/example/Cargo.toml @@ -5,15 +5,16 @@ authors = ["Parity Technologies "] edition = "2018" [dependencies] -serde = { version = "1.0", optional = true } +serde = { version = "1.0.101", optional = true } codec = { package = "parity-scale-codec", version = "1.0.0", default-features = false } -srml-support = { path = "../support", default-features = false } +support = { package = "srml-support", path = "../support", default-features = false } system = { package = "srml-system", path = "../system", default-features = false } balances = { package = "srml-balances", path = "../balances", default-features = false } sr-primitives = { path = "../../core/sr-primitives", default-features = false } +rstd = { package = "sr-std", path = "../../core/sr-std", default-features = false } +runtime-io = { package = "sr-io", path = "../../core/sr-io", default-features = false } [dev-dependencies] -sr-io = { path = "../../core/sr-io" } primitives = { package = "substrate-primitives", path = "../../core/primitives" } [features] @@ -22,7 +23,9 @@ std = [ "serde", "codec/std", "sr-primitives/std", - "srml-support/std", + "support/std", "system/std", "balances/std", + "runtime-io/std", + "rstd/std" ] diff --git a/srml/example/src/lib.rs b/srml/example/src/lib.rs index 0cfad989b156c7920c55c5aa9efdc9d38911de75..fe16fb7d6eada831c5d973f3cdea1d6a093342bd 100644 --- a/srml/example/src/lib.rs +++ b/srml/example/src/lib.rs @@ -253,9 +253,16 @@ // Ensure we're `no_std` when compiling for Wasm. #![cfg_attr(not(feature = "std"), no_std)] -use srml_support::{StorageValue, dispatch::Result, decl_module, decl_storage, decl_event}; +use rstd::marker::PhantomData; +use support::{dispatch::Result, decl_module, decl_storage, decl_event}; use system::{ensure_signed, ensure_root}; -use sr_primitives::weights::SimpleDispatchInfo; +use codec::{Encode, Decode}; +use sr_primitives::{ + traits::{SignedExtension, Bounded}, weights::{SimpleDispatchInfo, DispatchInfo}, + transaction_validity::{ + ValidTransaction, TransactionValidityError, InvalidTransaction, TransactionValidity, + }, +}; /// Our module's configuration trait. All our types and consts go in here. If the /// module is dependent on specific other modules, then their configuration traits @@ -357,7 +364,7 @@ decl_module! { /// It is also possible to provide a custom implementation. /// For non-generic events, the generic parameter just needs to be dropped, so that it /// looks like: `fn deposit_event() = default;`. - fn deposit_event() = default; + fn deposit_event() = default; /// This is your public interface. Be extremely careful. /// This is just a simple example of how to interact with the module from the external /// world. @@ -500,15 +507,98 @@ impl Module { } } +// Similar to other SRML modules, your module can also define a signed extension and perform some +// checks and [pre/post]processing [before/after] the transaction. A signed extension can be any +// decodable type that implements `SignedExtension`. See the trait definition for the full list of +// bounds. As a convention, you can follow this approach to create an extension for your module: +// - If the extension does not carry any data, then use a tuple struct with just a `marker` +// (needed for the compiler to accept `T: Trait`) will suffice. +// - Otherwise, create a tuple struct which contains the external data. Of course, for the entire +// struct to be decodable, each individual item also needs to be decodable. +// +// Note that a signed extension can also indicate that a particular data must be present in the +// _signing payload_ of a transaction by providing an implementation for the `additional_signed` +// method. This example will not cover this type of extension. See `CheckRuntime` in system module +// for an example. +// +// Using the extension, you can add some hooks to the lifecycle of each transaction. Note that by +// default, an extension is applied to all `Call` functions (i.e. all transactions). the `Call` enum +// variant is given to each function of `SignedExtension`. Hence, you can filter based on module or +// a particular call if needed. +// +// Some extra information, such as encoded length, some static dispatch info like weight and the +// sender of the transaction (if signed) are also provided. +// +// The full list of hooks that can be added to a signed extension can be found +// [here](https://crates.parity.io/sr_primitives/traits/trait.SignedExtension.html). +// +// The signed extensions are aggregated in the runtime file of a substrate chain. All extensions +// should be aggregated in a tuple and passed to the `CheckedExtrinsic` and `UncheckedExtrinsic` +// types defined in the runtime. Lookup `pub type SignedExtra = (...)` in `node/runtime` and +// `node-template` for an example of this. + +/// A simple signed extension that checks for the `set_dummy` call. In that case, it increases the +/// priority and prints some log. +/// +/// Additionally, it drops any transaction with an encoded length higher than 200 bytes. No +/// particular reason why, just to demonstrate the power of signed extensions. +#[derive(Encode, Decode, Clone, Eq, PartialEq)] +pub struct WatchDummy(PhantomData); + +#[cfg(feature = "std")] +impl rstd::fmt::Debug for WatchDummy { + fn fmt(&self, f: &mut rstd::fmt::Formatter) -> rstd::fmt::Result { + write!(f, "WatchDummy") + } +} + +impl SignedExtension for WatchDummy { + type AccountId = T::AccountId; + // Note that this could also be assigned to the top-level call enum. It is passed into the + // balances module directly and since `Trait: balances::Trait`, you could also use `T::Call`. + // In that case, you would have had access to all call variants and could match on variants from + // other modules. + type Call = Call; + type AdditionalSigned = (); + type Pre = (); + + fn additional_signed(&self) -> rstd::result::Result<(), TransactionValidityError> { Ok(()) } + + fn validate( + &self, + _who: &Self::AccountId, + call: &Self::Call, + _info: DispatchInfo, + len: usize, + ) -> TransactionValidity { + // if the transaction is too big, just drop it. + if len > 200 { + return InvalidTransaction::ExhaustsResources.into() + } + + // check for `set_dummy` + match call { + Call::set_dummy(..) => { + sr_primitives::print("set_dummy was received."); + + let mut valid_tx = ValidTransaction::default(); + valid_tx.priority = Bounded::max_value(); + Ok(valid_tx) + } + _ => Ok(Default::default()), + } + } +} + #[cfg(test)] mod tests { use super::*; - use srml_support::{assert_ok, impl_outer_origin, parameter_types}; - use sr_io::with_externalities; + use support::{assert_ok, impl_outer_origin, parameter_types}; + use runtime_io::with_externalities; use primitives::{H256, Blake2Hasher}; // The testing primitives are very useful for avoiding having to work with signatures - // or public keys. `u64` is used as the `AccountId` and no `Signature`s are requried. + // or public keys. `u64` is used as the `AccountId` and no `Signature`s are required. use sr_primitives::{ Perbill, traits::{BlakeTwo256, OnInitialize, OnFinalize, IdentityLookup}, testing::Header }; @@ -544,6 +634,7 @@ mod tests { type MaximumBlockWeight = MaximumBlockWeight; type MaximumBlockLength = MaximumBlockLength; type AvailableBlockRatio = AvailableBlockRatio; + type Version = (); } parameter_types! { pub const ExistentialDeposit: u64 = 0; @@ -574,7 +665,7 @@ mod tests { // This function basically just builds a genesis storage key/value store according to // our desired mockup. - fn new_test_ext() -> sr_io::TestExternalities { + fn new_test_ext() -> runtime_io::TestExternalities { let mut t = system::GenesisConfig::default().build_storage::().unwrap(); // We use default for brevity, but you can configure as desired if needed. balances::GenesisConfig::::default().assimilate_storage(&mut t).unwrap(); @@ -616,4 +707,23 @@ mod tests { assert_eq!(Example::foo(), 25); }); } + + #[test] + fn signed_ext_watch_dummy_works() { + with_externalities(&mut new_test_ext(), || { + let call = >::set_dummy(10); + let info = DispatchInfo::default(); + + assert_eq!( + WatchDummy::(PhantomData).validate(&1, &call, info, 150) + .unwrap() + .priority, + Bounded::max_value(), + ); + assert_eq!( + WatchDummy::(PhantomData).validate(&1, &call, info, 250), + InvalidTransaction::ExhaustsResources.into(), + ); + }) + } } diff --git a/srml/executive/Cargo.toml b/srml/executive/Cargo.toml index e398a951896ea6e59767981a72d2316040ae1c65..a87eed40b75dfea6881fcd24b0444b74887ee66c 100644 --- a/srml/executive/Cargo.toml +++ b/srml/executive/Cargo.toml @@ -5,16 +5,16 @@ authors = ["Parity Technologies "] edition = "2018" [dependencies] -serde = { version = "1.0", optional = true } +serde = { version = "1.0.101", optional = true } codec = { package = "parity-scale-codec", version = "1.0.0", default-features = false, features = ["derive"] } rstd = { package = "sr-std", path = "../../core/sr-std", default-features = false } -runtime_io = { package = "sr-io", path = "../../core/sr-io", default-features = false } +runtime-io ={ package = "sr-io", path = "../../core/sr-io", default-features = false } sr-primitives = { path = "../../core/sr-primitives", default-features = false } -srml-support = { path = "../support", default-features = false } +support = { package = "srml-support", path = "../support", default-features = false } system = { package = "srml-system", path = "../system", default-features = false } [dev-dependencies] -hex-literal = "0.2.0" +hex-literal = "0.2.1" primitives = { package = "substrate-primitives", path = "../../core/primitives" } srml-indices = { path = "../indices" } balances = { package = "srml-balances", path = "../balances" } @@ -23,10 +23,10 @@ balances = { package = "srml-balances", path = "../balances" } default = ["std"] std = [ "rstd/std", - "srml-support/std", + "support/std", "serde", "codec/std", "sr-primitives/std", - "runtime_io/std", + "runtime-io/std", "system/std", ] diff --git a/srml/executive/src/lib.rs b/srml/executive/src/lib.rs index 9c29c95f1082de13e07d254cd5aef3665e1542fa..ad9cb7bf80742fa00f07384dfd3ca5c3670264b7 100644 --- a/srml/executive/src/lib.rs +++ b/srml/executive/src/lib.rs @@ -59,13 +59,13 @@ //! # pub type Balances = u64; //! # pub type AllModules = u64; //! # pub enum Runtime {}; -//! # use sr_primitives::transaction_validity::TransactionValidity; +//! # use sr_primitives::transaction_validity::{TransactionValidity, UnknownTransaction}; //! # use sr_primitives::traits::ValidateUnsigned; //! # impl ValidateUnsigned for Runtime { //! # type Call = (); //! # //! # fn validate_unsigned(_call: &Self::Call) -> TransactionValidity { -//! # TransactionValidity::Invalid(0) +//! # UnknownTransaction::NoUnsignedValidator.into() //! # } //! # } //! /// Executive: handles dispatch to the various modules. @@ -74,50 +74,17 @@ #![cfg_attr(not(feature = "std"), no_std)] -use rstd::prelude::*; -use rstd::marker::PhantomData; -use rstd::result; -use sr_primitives::{generic::Digest, traits::{ - self, Header, Zero, One, Checkable, Applyable, CheckEqual, OnFinalize, - OnInitialize, NumberFor, Block as BlockT, OffchainWorker, ValidateUnsigned -}}; -use srml_support::Dispatchable; +use rstd::{prelude::*, marker::PhantomData}; +use sr_primitives::{ + generic::Digest, ApplyResult, weights::GetDispatchInfo, + traits::{ + self, Header, Zero, One, Checkable, Applyable, CheckEqual, OnFinalize, OnInitialize, + NumberFor, Block as BlockT, OffchainWorker, ValidateUnsigned, Dispatchable + }, + transaction_validity::TransactionValidity, +}; use codec::{Codec, Encode}; use system::{extrinsics_root, DigestOf}; -use sr_primitives::{ApplyOutcome, ApplyError}; -use sr_primitives::transaction_validity::TransactionValidity; -use sr_primitives::weights::GetDispatchInfo; - -mod internal { - use sr_primitives::traits::DispatchError; - - pub enum ApplyError { - BadSignature(&'static str), - Stale, - Future, - CantPay, - FullBlock, - } - - pub enum ApplyOutcome { - Success, - Fail(&'static str), - } - - impl From for ApplyError { - fn from(d: DispatchError) -> Self { - match d { - DispatchError::Payment => ApplyError::CantPay, - DispatchError::Exhausted => ApplyError::FullBlock, - DispatchError::NoPermission => ApplyError::CantPay, - DispatchError::BadState => ApplyError::CantPay, - DispatchError::Stale => ApplyError::Stale, - DispatchError::Future => ApplyError::Future, - DispatchError::BadProof => ApplyError::BadSignature(""), - } - } - } -} /// Trait that can be used to execute a block. pub trait ExecuteBlock { @@ -239,30 +206,19 @@ where /// Apply extrinsic outside of the block execution function. /// This doesn't attempt to validate anything regarding the block, but it builds a list of uxt /// hashes. - pub fn apply_extrinsic(uxt: Block::Extrinsic) -> result::Result { + pub fn apply_extrinsic(uxt: Block::Extrinsic) -> ApplyResult { let encoded = uxt.encode(); let encoded_len = encoded.len(); - match Self::apply_extrinsic_with_len(uxt, encoded_len, Some(encoded)) { - Ok(internal::ApplyOutcome::Success) => Ok(ApplyOutcome::Success), - Ok(internal::ApplyOutcome::Fail(_)) => Ok(ApplyOutcome::Fail), - Err(internal::ApplyError::CantPay) => Err(ApplyError::CantPay), - Err(internal::ApplyError::BadSignature(_)) => Err(ApplyError::BadSignature), - Err(internal::ApplyError::Stale) => Err(ApplyError::Stale), - Err(internal::ApplyError::Future) => Err(ApplyError::Future), - Err(internal::ApplyError::FullBlock) => Err(ApplyError::FullBlock), - } + Self::apply_extrinsic_with_len(uxt, encoded_len, Some(encoded)) } /// Apply an extrinsic inside the block execution function. fn apply_extrinsic_no_note(uxt: Block::Extrinsic) { let l = uxt.encode().len(); match Self::apply_extrinsic_with_len(uxt, l, None) { - Ok(internal::ApplyOutcome::Success) => (), - Ok(internal::ApplyOutcome::Fail(e)) => runtime_io::print(e), - Err(internal::ApplyError::CantPay) => panic!("All extrinsics should have sender able to pay their fees"), - Err(internal::ApplyError::BadSignature(_)) => panic!("All extrinsics should be properly signed"), - Err(internal::ApplyError::Stale) | Err(internal::ApplyError::Future) => panic!("All extrinsics should have the correct nonce"), - Err(internal::ApplyError::FullBlock) => panic!("Extrinsics should not exceed block limit"), + Ok(Ok(())) => (), + Ok(Err(e)) => sr_primitives::print(e), + Err(e) => { let err: &'static str = e.into(); panic!(err) }, } } @@ -271,9 +227,9 @@ where uxt: Block::Extrinsic, encoded_len: usize, to_note: Option>, - ) -> result::Result { + ) -> ApplyResult { // Verify that the signature is good. - let xt = uxt.check(&Default::default()).map_err(internal::ApplyError::BadSignature)?; + let xt = uxt.check(&Default::default())?; // We don't need to make sure to `note_extrinsic` only after we know it's going to be // executed to prevent it from leaking in storage since at this point, it will either @@ -286,15 +242,11 @@ where // Decode parameters and dispatch let dispatch_info = xt.get_dispatch_info(); - let r = Applyable::dispatch(xt, dispatch_info, encoded_len) - .map_err(internal::ApplyError::from)?; + let r = Applyable::apply(xt, dispatch_info, encoded_len)?; >::note_applied_extrinsic(&r, encoded_len as u32); - r.map(|_| internal::ApplyOutcome::Success).or_else(|e| match e { - sr_primitives::BLOCK_FULL => Err(internal::ApplyError::FullBlock), - e => Ok(internal::ApplyOutcome::Fail(e)) - }) + Ok(r) } fn final_checks(header: &System::Header) { @@ -324,21 +276,8 @@ where /// /// Changes made to storage should be discarded. pub fn validate_transaction(uxt: Block::Extrinsic) -> TransactionValidity { - // Note errors > 0 are from ApplyError - const UNKNOWN_ERROR: i8 = -127; - const INVALID_INDEX: i8 = -10; - let encoded_len = uxt.using_encoded(|d| d.len()); - let xt = match uxt.check(&Default::default()) { - // Checks out. Carry on. - Ok(xt) => xt, - // An unknown account index implies that the transaction may yet become valid. - Err("invalid account index") => return TransactionValidity::Unknown(INVALID_INDEX), - // Technically a bad signature could also imply an out-of-date account index, but - // that's more of an edge case. - Err(sr_primitives::BAD_SIGNATURE) => return TransactionValidity::Invalid(ApplyError::BadSignature as i8), - Err(_) => return TransactionValidity::Invalid(UNKNOWN_ERROR), - }; + let xt = uxt.check(&Default::default())?; let dispatch_info = xt.get_dispatch_info(); xt.validate::(dispatch_info, encoded_len) @@ -354,19 +293,24 @@ where #[cfg(test)] mod tests { use super::*; - use balances::Call; use runtime_io::with_externalities; use primitives::{H256, Blake2Hasher}; - use sr_primitives::generic::Era; - use sr_primitives::Perbill; - use sr_primitives::weights::Weight; - use sr_primitives::traits::{Header as HeaderT, BlakeTwo256, IdentityLookup, ConvertInto}; - use sr_primitives::testing::{Digest, Header, Block}; - use srml_support::{impl_outer_event, impl_outer_origin, parameter_types}; - use srml_support::traits::{Currency, LockIdentifier, LockableCurrency, WithdrawReasons, WithdrawReason}; - use system; + use sr_primitives::{ + generic::Era, Perbill, DispatchError, weights::Weight, testing::{Digest, Header, Block}, + traits::{Bounded, Header as HeaderT, BlakeTwo256, IdentityLookup, ConvertInto}, + transaction_validity::{InvalidTransaction, UnknownTransaction}, ApplyError, + }; + use support::{ + impl_outer_event, impl_outer_origin, parameter_types, impl_outer_dispatch, + traits::{Currency, LockIdentifier, LockableCurrency, WithdrawReasons, WithdrawReason}, + }; + use system::Call as SystemCall; + use balances::Call as BalancesCall; use hex_literal::hex; + type System = system::Module; + type Balances = balances::Module; + impl_outer_origin! { pub enum Origin for Runtime { } } @@ -376,6 +320,12 @@ mod tests { balances, } } + impl_outer_dispatch! { + pub enum Call for Runtime where origin: Origin { + system::System, + balances::Balances, + } + } // Workaround for https://github.com/rust-lang/rust/issues/26925 . Remove when sorted. #[derive(Clone, Eq, PartialEq)] @@ -389,7 +339,7 @@ mod tests { impl system::Trait for Runtime { type Origin = Origin; type Index = u64; - type Call = Call; + type Call = Call; type BlockNumber = u64; type Hash = primitives::H256; type Hashing = BlakeTwo256; @@ -402,6 +352,7 @@ mod tests { type MaximumBlockWeight = MaximumBlockWeight; type AvailableBlockRatio = AvailableBlockRatio; type MaximumBlockLength = MaximumBlockLength; + type Version = (); } parameter_types! { pub const ExistentialDeposit: u64 = 0; @@ -427,12 +378,12 @@ mod tests { } impl ValidateUnsigned for Runtime { - type Call = Call; + type Call = Call; fn validate_unsigned(call: &Self::Call) -> TransactionValidity { match call { - Call::set_balance(_, _, _) => TransactionValidity::Valid(Default::default()), - _ => TransactionValidity::Invalid(0), + Call::Balances(BalancesCall::set_balance(_, _, _)) => Ok(Default::default()), + _ => UnknownTransaction::NoUnsignedValidator.into(), } } } @@ -443,7 +394,7 @@ mod tests { system::CheckWeight, balances::TakeFees ); - type TestXt = sr_primitives::testing::TestXt, SignedExtra>; + type TestXt = sr_primitives::testing::TestXt; type Executive = super::Executive, system::ChainContext, Runtime, ()>; fn extra(nonce: u64, fee: u64) -> SignedExtra { @@ -466,7 +417,7 @@ mod tests { balances: vec![(1, 211)], vesting: vec![], }.assimilate_storage(&mut t).unwrap(); - let xt = sr_primitives::testing::TestXt(sign_extra(1, 0, 0), Call::transfer(2, 69)); + let xt = sr_primitives::testing::TestXt(sign_extra(1, 0, 0), Call::Balances(BalancesCall::transfer(2, 69))); let weight = xt.get_dispatch_info().weight as u64; let mut t = runtime_io::TestExternalities::::new(t); with_externalities(&mut t, || { @@ -478,7 +429,7 @@ mod tests { Digest::default(), )); let r = Executive::apply_extrinsic(xt); - assert_eq!(r, Ok(ApplyOutcome::Success)); + assert!(r.is_ok()); assert_eq!(>::total_balance(&1), 142 - 10 - weight); assert_eq!(>::total_balance(&2), 69); }); @@ -547,7 +498,7 @@ mod tests { fn bad_extrinsic_not_inserted() { let mut t = new_test_ext(1); // bad nonce check! - let xt = sr_primitives::testing::TestXt(sign_extra(1, 30, 0), Call::transfer(33, 69)); + let xt = sr_primitives::testing::TestXt(sign_extra(1, 30, 0), Call::Balances(BalancesCall::transfer(33, 69))); with_externalities(&mut t, || { Executive::initialize_block(&Header::new( 1, @@ -565,7 +516,7 @@ mod tests { fn block_weight_limit_enforced() { let mut t = new_test_ext(10000); // given: TestXt uses the encoded len as fixed Len: - let xt = sr_primitives::testing::TestXt(sign_extra(1, 0, 0), Call::transfer::(33, 0)); + let xt = sr_primitives::testing::TestXt(sign_extra(1, 0, 0), Call::Balances(BalancesCall::transfer(33, 0))); let encoded = xt.encode(); let encoded_len = encoded.len() as Weight; let limit = AvailableBlockRatio::get() * MaximumBlockWeight::get(); @@ -581,14 +532,19 @@ mod tests { assert_eq!(>::all_extrinsics_weight(), 0); for nonce in 0..=num_to_exhaust_block { - let xt = sr_primitives::testing::TestXt(sign_extra(1, nonce.into(), 0), Call::transfer::(33, 0)); + let xt = sr_primitives::testing::TestXt( + sign_extra(1, nonce.into(), 0), Call::Balances(BalancesCall::transfer(33, 0)), + ); let res = Executive::apply_extrinsic(xt); if nonce != num_to_exhaust_block { - assert_eq!(res.unwrap(), ApplyOutcome::Success); - assert_eq!(>::all_extrinsics_weight(), encoded_len * (nonce + 1)); + assert!(res.is_ok()); + assert_eq!( + >::all_extrinsics_weight(), + encoded_len * (nonce + 1), + ); assert_eq!(>::extrinsic_index(), Some(nonce as u32 + 1)); } else { - assert_eq!(res, Err(ApplyError::FullBlock)); + assert_eq!(res, Err(InvalidTransaction::ExhaustsResources.into())); } } }); @@ -596,18 +552,18 @@ mod tests { #[test] fn block_weight_and_size_is_stored_per_tx() { - let xt = sr_primitives::testing::TestXt(sign_extra(1, 0, 0), Call::transfer(33, 0)); - let x1 = sr_primitives::testing::TestXt(sign_extra(1, 1, 0), Call::transfer(33, 0)); - let x2 = sr_primitives::testing::TestXt(sign_extra(1, 2, 0), Call::transfer(33, 0)); + let xt = sr_primitives::testing::TestXt(sign_extra(1, 0, 0), Call::Balances(BalancesCall::transfer(33, 0))); + let x1 = sr_primitives::testing::TestXt(sign_extra(1, 1, 0), Call::Balances(BalancesCall::transfer(33, 0))); + let x2 = sr_primitives::testing::TestXt(sign_extra(1, 2, 0), Call::Balances(BalancesCall::transfer(33, 0))); let len = xt.clone().encode().len() as u32; let mut t = new_test_ext(1); with_externalities(&mut t, || { assert_eq!(>::all_extrinsics_weight(), 0); assert_eq!(>::all_extrinsics_weight(), 0); - assert_eq!(Executive::apply_extrinsic(xt.clone()).unwrap(), ApplyOutcome::Success); - assert_eq!(Executive::apply_extrinsic(x1.clone()).unwrap(), ApplyOutcome::Success); - assert_eq!(Executive::apply_extrinsic(x2.clone()).unwrap(), ApplyOutcome::Success); + assert!(Executive::apply_extrinsic(xt.clone()).unwrap().is_ok()); + assert!(Executive::apply_extrinsic(x1.clone()).unwrap().is_ok()); + assert!(Executive::apply_extrinsic(x2.clone()).unwrap().is_ok()); // default weight for `TestXt` == encoded length. assert_eq!(>::all_extrinsics_weight(), (3 * len).into()); @@ -622,13 +578,19 @@ mod tests { #[test] fn validate_unsigned() { - let xt = sr_primitives::testing::TestXt(None, Call::set_balance(33, 69, 69)); - let valid = TransactionValidity::Valid(Default::default()); + let xt = sr_primitives::testing::TestXt(None, Call::Balances(BalancesCall::set_balance(33, 69, 69))); let mut t = new_test_ext(1); with_externalities(&mut t, || { - assert_eq!(Executive::validate_transaction(xt.clone()), valid); - assert_eq!(Executive::apply_extrinsic(xt), Ok(ApplyOutcome::Fail)); + assert_eq!(Executive::validate_transaction(xt.clone()), Ok(Default::default())); + assert_eq!( + Executive::apply_extrinsic(xt), + Ok( + Err( + DispatchError { module: Some(1), error: 0, message: Some("RequireRootOrigin") } + ) + ) + ); }); } @@ -642,10 +604,13 @@ mod tests { id, &1, 110, - 10, + Bounded::max_value(), lock, ); - let xt = sr_primitives::testing::TestXt(sign_extra(1, 0, 0), Call::transfer(2, 10)); + let xt = sr_primitives::testing::TestXt( + sign_extra(1, 0, 0), + Call::System(SystemCall::remark(vec![1u8])), + ); let weight = xt.get_dispatch_info().weight as u64; Executive::initialize_block(&Header::new( 1, @@ -656,11 +621,14 @@ mod tests { )); if lock == WithdrawReasons::except(WithdrawReason::TransactionPayment) { - assert_eq!(Executive::apply_extrinsic(xt).unwrap(), ApplyOutcome::Fail); - // but tx fee has been deducted. the transaction failed on transfer, not on fee. + assert!(Executive::apply_extrinsic(xt).unwrap().is_ok()); + // tx fee has been deducted. assert_eq!(>::total_balance(&1), 111 - 10 - weight); } else { - assert_eq!(Executive::apply_extrinsic(xt), Err(ApplyError::CantPay)); + assert_eq!( + Executive::apply_extrinsic(xt), + Err(ApplyError::Validity(InvalidTransaction::Payment.into())), + ); assert_eq!(>::total_balance(&1), 111); } }); diff --git a/srml/finality-tracker/Cargo.toml b/srml/finality-tracker/Cargo.toml index 65ac540b6bcaee5e586bca231c47ab12c23c6644..7e3439e0fecea9045761cf9bc1101e889d2cd9ff 100644 --- a/srml/finality-tracker/Cargo.toml +++ b/srml/finality-tracker/Cargo.toml @@ -5,17 +5,18 @@ authors = ["Parity Technologies "] edition = "2018" [dependencies] -serde = { version = "1.0", default-features = false, features = ["derive"] } +serde = { version = "1.0.101", default-features = false, features = ["derive"] } codec = { package = "parity-scale-codec", version = "1.0.0", default-features = false } inherents = { package = "substrate-inherents", path = "../../core/inherents", default-features = false } rstd = { package = "sr-std", path = "../../core/sr-std", default-features = false } sr-primitives = { path = "../../core/sr-primitives", default-features = false } -srml-support = { path = "../support", default-features = false } +support = { package = "srml-support", path = "../support", default-features = false } srml-system = { path = "../system", default-features = false } +impl-trait-for-tuples = "0.1.2" [dev-dependencies] primitives = { package = "substrate-primitives", path = "../../core/primitives", default-features = false } -sr-io = { path = "../../core/sr-io", default-features = false } +runtime-io = { package = "sr-io", path = "../../core/sr-io", default-features = false } [features] default = ["std"] @@ -23,7 +24,7 @@ std = [ "serde/std", "codec/std", "rstd/std", - "srml-support/std", + "support/std", "sr-primitives/std", "srml-system/std", "inherents/std", diff --git a/srml/finality-tracker/src/lib.rs b/srml/finality-tracker/src/lib.rs index 26a0e0d4151214bae51eeb88f705508a00859c95..1bf9754b0a583bb428bdea6361645aa5fb45f609 100644 --- a/srml/finality-tracker/src/lib.rs +++ b/srml/finality-tracker/src/lib.rs @@ -22,12 +22,11 @@ use inherents::{ RuntimeString, InherentIdentifier, ProvideInherent, InherentData, MakeFatalError, }; -use srml_support::StorageValue; use sr_primitives::traits::{One, Zero, SaturatedConversion}; use rstd::{prelude::*, result, cmp, vec}; use codec::Decode; -use srml_support::{decl_module, decl_storage, for_each_tuple}; -use srml_support::traits::Get; +use support::{decl_module, decl_storage}; +use support::traits::Get; use srml_system::{ensure_none, Trait as SystemTrait}; #[cfg(feature = "std")] @@ -214,30 +213,13 @@ impl Module { } /// Called when finalization stalled at a given number. +#[impl_trait_for_tuples::impl_for_tuples(30)] pub trait OnFinalizationStalled { /// The parameter here is how many more blocks to wait before applying /// changes triggered by finality stalling. fn on_stalled(further_wait: N, median: N); } -macro_rules! impl_on_stalled { - () => ( - impl OnFinalizationStalled for () { - fn on_stalled(_: N, _: N) {} - } - ); - - ( $($t:ident)* ) => { - impl),*> OnFinalizationStalled for ($($t,)*) { - fn on_stalled(further_wait: NUM, median: NUM) { - $($t::on_stalled(further_wait.clone(), median.clone());)* - } - } - } -} - -for_each_tuple!(impl_on_stalled); - impl ProvideInherent for Module { type Call = Call; type Error = MakeFatalError<()>; @@ -265,12 +247,12 @@ impl ProvideInherent for Module { mod tests { use super::*; - use sr_io::{with_externalities, TestExternalities}; + use runtime_io::{with_externalities, TestExternalities}; use primitives::H256; use sr_primitives::traits::{BlakeTwo256, IdentityLookup, OnFinalize, Header as HeaderT}; use sr_primitives::testing::Header; use sr_primitives::Perbill; - use srml_support::{assert_ok, impl_outer_origin, parameter_types}; + use support::{assert_ok, impl_outer_origin, parameter_types}; use srml_system as system; use std::cell::RefCell; @@ -321,6 +303,7 @@ mod tests { type MaximumBlockWeight = MaximumBlockWeight; type AvailableBlockRatio = AvailableBlockRatio; type MaximumBlockLength = MaximumBlockLength; + type Version = (); } parameter_types! { pub const WindowSize: u64 = 11; diff --git a/srml/generic-asset/Cargo.toml b/srml/generic-asset/Cargo.toml index 65e21c3b11fbe8eb4b947a8521423fe2b5c3aa28..49a9db4c0ecd8962f81bdf0a1df1ebed83dfedeb 100644 --- a/srml/generic-asset/Cargo.toml +++ b/srml/generic-asset/Cargo.toml @@ -5,7 +5,7 @@ authors = ["Centrality Developers "] edition = "2018" [dependencies] -serde = { version = "1.0", optional = true } +serde = { version = "1.0.101", optional = true } codec = { package = "parity-scale-codec", version = "1.0.0", default-features = false, features = ["derive"] } rstd = { package = "sr-std", path = "../../core/sr-std", default-features = false } sr-primitives = { path = "../../core/sr-primitives", default-features = false } @@ -13,7 +13,7 @@ support = { package = "srml-support", path = "../support", default-features = fa system = { package = "srml-system", path = "../system", default-features = false } [dev-dependencies] -runtime_io = { package = "sr-io", path = "../../core/sr-io" } +runtime-io ={ package = "sr-io", path = "../../core/sr-io" } primitives = { package = "substrate-primitives", path = "../../core/primitives" } [features] diff --git a/srml/generic-asset/src/lib.rs b/srml/generic-asset/src/lib.rs index 45dd53449225a3942a8b88fd9cbc6a6dbffb15b5..6791ee578526380b4444b1a4c05a7c76a37d60c3 100644 --- a/srml/generic-asset/src/lib.rs +++ b/srml/generic-asset/src/lib.rs @@ -166,7 +166,7 @@ use support::{ Currency, ExistenceRequirement, Imbalance, LockIdentifier, LockableCurrency, ReservableCurrency, SignedImbalance, UpdateBalanceOutcome, WithdrawReason, WithdrawReasons, }, - Parameter, StorageDoubleMap, StorageMap, StorageValue, + Parameter, StorageMap, }; use system::{ensure_signed, ensure_root}; @@ -324,7 +324,7 @@ impl Into> for PermissionLatest for enum Call where origin: T::Origin { - fn deposit_event() = default; + fn deposit_event() = default; /// Create a new kind of asset. fn create(origin, options: AssetOptions) -> Result { @@ -478,15 +478,10 @@ decl_storage! { config(initial_balance): T::Balance; config(endowed_accounts): Vec; - build(| - storage: &mut (sr_primitives::StorageOverlay, sr_primitives::ChildrenStorageOverlay), - config: &GenesisConfig| { + build(|config: &GenesisConfig| { config.assets.iter().for_each(|asset_id| { config.endowed_accounts.iter().for_each(|account_id| { - storage.0.insert( - >::key_for(asset_id, account_id), - ::encode(&config.initial_balance) - ); + >::insert(asset_id, account_id, &config.initial_balance); }); }); }); @@ -1063,6 +1058,7 @@ impl system::Trait for ElevatedTrait { type AvailableBlockRatio = T::AvailableBlockRatio; type WeightMultiplierUpdate = (); type BlockHashCount = T::BlockHashCount; + type Version = T::Version; } impl Trait for ElevatedTrait { type Balance = T::Balance; diff --git a/srml/generic-asset/src/mock.rs b/srml/generic-asset/src/mock.rs index 2c348a0175c4f3c46ab8d9691a67d9d3ff0cc9cb..7e47de0b36537d18076d86461432afe5db8e52a6 100644 --- a/srml/generic-asset/src/mock.rs +++ b/srml/generic-asset/src/mock.rs @@ -61,6 +61,7 @@ impl system::Trait for Test { type MaximumBlockLength = MaximumBlockLength; type AvailableBlockRatio = AvailableBlockRatio; type BlockHashCount = BlockHashCount; + type Version = (); } impl Trait for Test { diff --git a/srml/grandpa/Cargo.toml b/srml/grandpa/Cargo.toml index 2466b8e012ec538238fa38bc241cf7668dc58acc..4b494cfeff8d11979116deb598d03dc5920f690e 100644 --- a/srml/grandpa/Cargo.toml +++ b/srml/grandpa/Cargo.toml @@ -5,19 +5,20 @@ authors = ["Parity Technologies "] edition = "2018" [dependencies] -serde = { version = "1.0", optional = true, features = ["derive"] } +serde = { version = "1.0.101", optional = true, features = ["derive"] } codec = { package = "parity-scale-codec", version = "1.0.0", default-features = false, features = ["derive"] } primitives = { package = "substrate-primitives", path = "../../core/primitives", default-features = false } substrate-finality-grandpa-primitives = { path = "../../core/finality-grandpa/primitives", default-features = false } rstd = { package = "sr-std", path = "../../core/sr-std", default-features = false } sr-primitives = { path = "../../core/sr-primitives", default-features = false } -srml-support = { path = "../support", default-features = false } +sr-staking-primitives = { path = "../../core/sr-staking-primitives", default-features = false } +support = { package = "srml-support", path = "../support", default-features = false } system = { package = "srml-system", path = "../system", default-features = false } session = { package = "srml-session", path = "../session", default-features = false } finality-tracker = { package = "srml-finality-tracker", path = "../finality-tracker", default-features = false } [dev-dependencies] -runtime_io = { package = "sr-io", path = "../../core/sr-io" } +runtime-io ={ package = "sr-io", path = "../../core/sr-io" } [features] default = ["std"] @@ -27,8 +28,9 @@ std = [ "primitives/std", "substrate-finality-grandpa-primitives/std", "rstd/std", - "srml-support/std", + "support/std", "sr-primitives/std", + "sr-staking-primitives/std", "system/std", "session/std", "finality-tracker/std", diff --git a/srml/grandpa/src/lib.rs b/srml/grandpa/src/lib.rs index 3f4b26c17d74cf6debd807072b04018f4fe0d352..610bd18fb3f8a3b5fb7219f55a701b13e1f5542b 100644 --- a/srml/grandpa/src/lib.rs +++ b/srml/grandpa/src/lib.rs @@ -32,13 +32,18 @@ pub use substrate_finality_grandpa_primitives as fg_primitives; use rstd::prelude::*; use codec::{self as codec, Encode, Decode, Error}; -use srml_support::{ - decl_event, decl_storage, decl_module, dispatch::Result, storage::StorageValue +use support::{ + decl_event, decl_storage, decl_module, dispatch::Result, }; use sr_primitives::{ generic::{DigestItem, OpaqueDigestItemId}, traits::Zero, + Perbill, }; -use fg_primitives::{ScheduledChange, ConsensusLog, GRANDPA_ENGINE_ID}; +use sr_staking_primitives::{ + SessionIndex, + offence::{Offence, Kind}, +}; +use fg_primitives::{GRANDPA_ENGINE_ID, ScheduledChange, ConsensusLog, SetId, RoundNumber}; pub use fg_primitives::{AuthorityId, AuthorityWeight}; use system::{ensure_signed, DigestOf}; @@ -60,7 +65,7 @@ pub struct OldStoredPendingChange { /// The delay in blocks until it will be applied. pub delay: N, /// The next authority set. - pub next_authorities: Vec<(AuthorityId, u64)>, + pub next_authorities: Vec<(AuthorityId, AuthorityWeight)>, } /// A stored pending change. @@ -71,7 +76,7 @@ pub struct StoredPendingChange { /// The delay in blocks until it will be applied. pub delay: N, /// The next authority set. - pub next_authorities: Vec<(AuthorityId, u64)>, + pub next_authorities: Vec<(AuthorityId, AuthorityWeight)>, /// If defined it means the change was forced and the given block number /// indicates the median last finalized block when the change was signaled. pub forced: Option, @@ -122,7 +127,7 @@ pub enum StoredState { decl_event!( pub enum Event { /// New authority set has been applied. - NewAuthorities(Vec<(AuthorityId, u64)>), + NewAuthorities(Vec<(AuthorityId, AuthorityWeight)>), /// Current authority set has been paused. Paused, /// Current authority set has been resumed. @@ -133,7 +138,7 @@ decl_event!( decl_storage! { trait Store for Module as GrandpaFinality { /// The current authority set. - Authorities get(authorities) config(): Vec<(AuthorityId, AuthorityWeight)>; + Authorities get(authorities): Vec<(AuthorityId, AuthorityWeight)>; /// State of the current authority set. State get(state): StoredState = StoredState::Live; @@ -146,6 +151,17 @@ decl_storage! { /// `true` if we are currently stalled. Stalled get(stalled): Option<(T::BlockNumber, T::BlockNumber)>; + + /// The number of changes (both in terms of keys and underlying economic responsibilities) + /// in the "set" of Grandpa validators from genesis. + CurrentSetId get(current_set_id) build(|_| fg_primitives::SetId::default()): SetId; + + /// A mapping from grandpa set ID to the index of the *most recent* session for which its members were responsible. + SetIdSession get(session_for_set): map SetId => Option; + } + add_extra_genesis { + config(authorities): Vec<(AuthorityId, AuthorityWeight)>; + build(|config| Module::::initialize_authorities(&config.authorities)) } } @@ -226,10 +242,12 @@ decl_module! { impl Module { /// Get the current set of authorities, along with their respective weights. - pub fn grandpa_authorities() -> Vec<(AuthorityId, u64)> { + pub fn grandpa_authorities() -> Vec<(AuthorityId, AuthorityWeight)> { Authorities::get() } + /// Schedule GRANDPA to pause starting in the given number of blocks. + /// Cannot be done when already paused. pub fn schedule_pause(in_blocks: T::BlockNumber) -> Result { if let StoredState::Live = >::get() { let scheduled_at = >::block_number(); @@ -245,6 +263,7 @@ impl Module { } } + /// Schedule a resume of GRANDPA after pausing. pub fn schedule_resume(in_blocks: T::BlockNumber) -> Result { if let StoredState::Paused = >::get() { let scheduled_at = >::block_number(); @@ -275,7 +294,7 @@ impl Module { /// No change should be signaled while any change is pending. Returns /// an error if a change is already pending. pub fn schedule_change( - next_authorities: Vec<(AuthorityId, u64)>, + next_authorities: Vec<(AuthorityId, AuthorityWeight)>, in_blocks: T::BlockNumber, forced: Option, ) -> Result { @@ -310,32 +329,44 @@ impl Module { let log: DigestItem = DigestItem::Consensus(GRANDPA_ENGINE_ID, log.encode()); >::deposit_log(log.into()); } + + fn initialize_authorities(authorities: &[(AuthorityId, AuthorityWeight)]) { + if !authorities.is_empty() { + assert!(Authorities::get().is_empty(), "Authorities are already initialized!"); + Authorities::put(authorities); + } + } } impl Module { + /// Attempt to extract a GRANDPA log from a generic digest. pub fn grandpa_log(digest: &DigestOf) -> Option> { let id = OpaqueDigestItemId::Consensus(&GRANDPA_ENGINE_ID); digest.convert_first(|l| l.try_to::>(id)) } + /// Attempt to extract a pending set-change signal from a digest. pub fn pending_change(digest: &DigestOf) -> Option> { Self::grandpa_log(digest).and_then(|signal| signal.try_into_change()) } + /// Attempt to extract a forced set-change signal from a digest. pub fn forced_change(digest: &DigestOf) -> Option<(T::BlockNumber, ScheduledChange)> { Self::grandpa_log(digest).and_then(|signal| signal.try_into_forced_change()) } + /// Attempt to extract a pause signal from a digest. pub fn pending_pause(digest: &DigestOf) -> Option { Self::grandpa_log(digest).and_then(|signal| signal.try_into_pause()) } + /// Attempt to extract a resume signal from a digest. pub fn pending_resume(digest: &DigestOf) -> Option { @@ -343,24 +374,42 @@ impl Module { } } -impl session::OneSessionHandler for Module { +impl session::OneSessionHandler for Module + where T: session::Trait +{ type Key = AuthorityId; + fn on_genesis_session<'a, I: 'a>(validators: I) + where I: Iterator + { + let authorities = validators.map(|(_, k)| (k, 1)).collect::>(); + Self::initialize_authorities(&authorities); + } + fn on_new_session<'a, I: 'a>(changed: bool, validators: I, _queued_validators: I) where I: Iterator { - // instant changes - if changed { - let next_authorities = validators.map(|(_, k)| (k, 1u64)).collect::>(); - let last_authorities = >::grandpa_authorities(); - if next_authorities != last_authorities { - if let Some((further_wait, median)) = >::take() { - let _ = Self::schedule_change(next_authorities, further_wait, Some(median)); - } else { - let _ = Self::schedule_change(next_authorities, Zero::zero(), None); - } + // Always issue a change if `session` says that the validators have changed. + // Even if their session keys are the same as before, the underyling economic + // identities have changed. + let current_set_id = if changed { + let next_authorities = validators.map(|(_, k)| (k, 1)).collect::>(); + if let Some((further_wait, median)) = >::take() { + let _ = Self::schedule_change(next_authorities, further_wait, Some(median)); + } else { + let _ = Self::schedule_change(next_authorities, Zero::zero(), None); } - } + CurrentSetId::mutate(|s| { *s += 1; *s }) + } else { + // nothing's changed, neither economic conditions nor session keys. update the pointer + // of the current set. + Self::current_set_id() + }; + + // if we didn't issue a change, we update the mapping to note that the current + // set corresponds to the latest equivalent session (i.e. now). + let session_index = >::current_index(); + SetIdSession::insert(current_set_id, &session_index); } fn on_disabled(i: usize) { @@ -376,3 +425,56 @@ impl finality_tracker::OnFinalizationStalled for Modul >::put((further_wait, median)); } } + +/// A round number and set id which point on the time of an offence. +#[derive(Copy, Clone, PartialOrd, Ord, Eq, PartialEq, Encode, Decode)] +struct GrandpaTimeSlot { + // The order of these matters for `derive(Ord)`. + set_id: SetId, + round: RoundNumber, +} + +// TODO [slashing]: Integrate this. +/// A grandpa equivocation offence report. +#[allow(dead_code)] +struct GrandpaEquivocationOffence { + /// Time slot at which this incident happened. + time_slot: GrandpaTimeSlot, + /// The session index in which the incident happened. + session_index: SessionIndex, + /// The size of the validator set at the time of the offence. + validator_set_count: u32, + /// The authority which produced this equivocation. + offender: FullIdentification, +} + +impl Offence for GrandpaEquivocationOffence { + const ID: Kind = *b"grandpa:equivoca"; + type TimeSlot = GrandpaTimeSlot; + + fn offenders(&self) -> Vec { + vec![self.offender.clone()] + } + + fn session_index(&self) -> SessionIndex { + self.session_index + } + + fn validator_set_count(&self) -> u32 { + self.validator_set_count + } + + fn time_slot(&self) -> Self::TimeSlot { + self.time_slot + } + + fn slash_fraction( + offenders_count: u32, + validator_set_count: u32, + ) -> Perbill { + // the formula is min((3k / n)^2, 1) + let x = Perbill::from_rational_approximation(3 * offenders_count, validator_set_count); + // _ ^ 2 + x.square() + } +} diff --git a/srml/grandpa/src/mock.rs b/srml/grandpa/src/mock.rs index e3c53510deae48f900c078208732ae76ee36a3bc..af2fedf42f8f953c9526267eee317f1f230660f5 100644 --- a/srml/grandpa/src/mock.rs +++ b/srml/grandpa/src/mock.rs @@ -20,7 +20,7 @@ use sr_primitives::{Perbill, DigestItem, traits::IdentityLookup, testing::{Header, UintAuthorityId}}; use runtime_io; -use srml_support::{impl_outer_origin, impl_outer_event, parameter_types}; +use support::{impl_outer_origin, impl_outer_event, parameter_types}; use primitives::{H256, Blake2Hasher}; use codec::{Encode, Decode}; use crate::{AuthorityId, GenesisConfig, Trait, Module, ConsensusLog}; @@ -37,9 +37,9 @@ pub fn grandpa_log(log: ConsensusLog) -> DigestItem { // Workaround for https://github.com/rust-lang/rust/issues/26925 . Remove when sorted. #[derive(Clone, PartialEq, Eq, Debug, Decode, Encode)] pub struct Test; + impl Trait for Test { type Event = TestEvent; - } parameter_types! { pub const BlockHashCount: u64 = 250; @@ -53,7 +53,7 @@ impl system::Trait for Test { type BlockNumber = u64; type Call = (); type Hash = H256; - type Hashing = ::sr_primitives::traits::BlakeTwo256; + type Hashing = sr_primitives::traits::BlakeTwo256; type AccountId = u64; type Lookup = IdentityLookup; type Header = Header; @@ -63,6 +63,7 @@ impl system::Trait for Test { type MaximumBlockWeight = MaximumBlockWeight; type MaximumBlockLength = MaximumBlockLength; type AvailableBlockRatio = AvailableBlockRatio; + type Version = (); } mod grandpa { @@ -85,7 +86,7 @@ pub fn new_test_ext(authorities: Vec<(u64, u64)>) -> runtime_io::TestExternaliti let mut t = system::GenesisConfig::default().build_storage::().unwrap(); GenesisConfig { authorities: to_authorities(authorities), - }.assimilate_storage(&mut t).unwrap(); + }.assimilate_storage::(&mut t).unwrap(); t.into() } diff --git a/srml/grandpa/src/tests.rs b/srml/grandpa/src/tests.rs index adef602ce6f185ff4e0cdaef3ef929a9c57cd0e6..41229a5136165d5f4970ce603153ae7c881cd831 100644 --- a/srml/grandpa/src/tests.rs +++ b/srml/grandpa/src/tests.rs @@ -282,3 +282,31 @@ fn schedule_resume_only_when_paused() { ); }); } + +#[test] +fn time_slot_have_sane_ord() { + // Ensure that `Ord` implementation is sane. + const FIXTURE: &[GrandpaTimeSlot] = &[ + GrandpaTimeSlot { + set_id: 0, + round: 0, + }, + GrandpaTimeSlot { + set_id: 0, + round: 1, + }, + GrandpaTimeSlot { + set_id: 1, + round: 0, + }, + GrandpaTimeSlot { + set_id: 1, + round: 1, + }, + GrandpaTimeSlot { + set_id: 1, + round: 2, + } + ]; + assert!(FIXTURE.windows(2).all(|f| f[0] < f[1])); +} diff --git a/srml/im-online/Cargo.toml b/srml/im-online/Cargo.toml index 8f0e4cc39fa825a6dd85bbcb9b17e76cff612059..b62cc2a8f96158219c9bd2e092e7625e54203a63 100644 --- a/srml/im-online/Cargo.toml +++ b/srml/im-online/Cargo.toml @@ -5,27 +5,33 @@ authors = ["Parity Technologies "] edition = "2018" [dependencies] -codec = { package = "parity-scale-codec", version = "1.0.0", default-features = false, features = ["derive"] } -sr-primitives = { path = "../../core/sr-primitives", default-features = false } -primitives = { package = "substrate-primitives", path = "../../core/primitives", default-features = false } app-crypto = { package = "substrate-application-crypto", path = "../../core/application-crypto", default-features = false } +codec = { package = "parity-scale-codec", version = "1.0.0", default-features = false, features = ["derive"] } +primitives = { package="substrate-primitives", path = "../../core/primitives", default-features = false } rstd = { package = "sr-std", path = "../../core/sr-std", default-features = false } -serde = { version = "1.0", optional = true } +serde = { version = "1.0.101", optional = true } session = { package = "srml-session", path = "../session", default-features = false } -srml-support = { path = "../support", default-features = false } -sr-io = { package = "sr-io", path = "../../core/sr-io", default-features = false } +runtime-io = { package = "sr-io", path = "../../core/sr-io", default-features = false } +sr-primitives = { path = "../../core/sr-primitives", default-features = false } +sr-staking-primitives = { path = "../../core/sr-staking-primitives", default-features = false } +support = { package = "srml-support", path = "../support", default-features = false } system = { package = "srml-system", path = "../system", default-features = false } +[dev-dependencies] +offchain = { package = "substrate-offchain", path = "../../core/offchain" } + [features] -default = ["std"] +default = ["std", "session/historical"] std = [ + "app-crypto/std", "codec/std", - "sr-primitives/std", + "primitives/std", "rstd/std", "serde", "session/std", - "srml-support/std", - "sr-io/std", + "runtime-io/std", + "sr-primitives/std", + "sr-staking-primitives/std", + "support/std", "system/std", - "app-crypto/std", ] diff --git a/srml/im-online/src/lib.rs b/srml/im-online/src/lib.rs index 512fca0c0c52675cbe603fd63ac84fcbc4c7270a..84c95fee47fb75a4343ffa51762009bb8aa3c6b4 100644 --- a/srml/im-online/src/lib.rs +++ b/srml/im-online/src/lib.rs @@ -42,7 +42,7 @@ //! ## Usage //! //! ``` -//! use srml_support::{decl_module, dispatch::Result}; +//! use support::{decl_module, dispatch::Result}; //! use system::ensure_signed; //! use srml_im_online::{self as im_online}; //! @@ -67,49 +67,85 @@ // Ensure we're `no_std` when compiling for Wasm. #![cfg_attr(not(feature = "std"), no_std)] -use primitives::offchain::{OpaqueNetworkState, StorageKind}; +mod mock; +mod tests; + +use app_crypto::RuntimeAppPublic; use codec::{Encode, Decode}; +use primitives::offchain::{OpaqueNetworkState, StorageKind}; +use rstd::prelude::*; +use session::historical::IdentificationTuple; use sr_primitives::{ - ApplyError, traits::Extrinsic as ExtrinsicT, - transaction_validity::{TransactionValidity, TransactionLongevity, ValidTransaction}, + traits::{Convert, Member, Printable, Saturating}, Perbill, + transaction_validity::{ + TransactionValidity, TransactionLongevity, ValidTransaction, InvalidTransaction, + }, }; -use rstd::prelude::*; -use session::SessionIndex; -use sr_io::Printable; -use srml_support::{ - StorageValue, decl_module, decl_event, decl_storage, StorageDoubleMap, print, +use sr_staking_primitives::{ + SessionIndex, + offence::{ReportOffence, Offence, Kind}, +}; +use support::{ + decl_module, decl_event, decl_storage, print, ensure, Parameter }; use system::ensure_none; -use app_crypto::RuntimeAppPublic; +use system::offchain::SubmitUnsignedTransaction; -mod app { - pub use app_crypto::sr25519 as crypto; - use app_crypto::{app_crypto, key_types::IM_ONLINE, sr25519}; +pub mod sr25519 { + mod app_sr25519 { + use app_crypto::{app_crypto, key_types::IM_ONLINE, sr25519}; + app_crypto!(sr25519, IM_ONLINE); - app_crypto!(sr25519, IM_ONLINE); + impl From for sr_primitives::AnySignature { + fn from(sig: Signature) -> Self { + sr25519::Signature::from(sig).into() + } + } + } + + /// An i'm online keypair using sr25519 as its crypto. + #[cfg(feature = "std")] + pub type AuthorityPair = app_sr25519::Pair; + + /// An i'm online signature using sr25519 as its crypto. + pub type AuthoritySignature = app_sr25519::Signature; + + /// An i'm online identifier using sr25519 as its crypto. + pub type AuthorityId = app_sr25519::Public; } -/// A Babe authority keypair. Necessarily equivalent to the schnorrkel public key used in -/// the main Babe module. If that ever changes, then this must, too. -#[cfg(feature = "std")] -pub type AuthorityPair = app::Pair; +pub mod ed25519 { + mod app_ed25519 { + use app_crypto::{app_crypto, key_types::IM_ONLINE, ed25519}; + app_crypto!(ed25519, IM_ONLINE); + + impl From for sr_primitives::AnySignature { + fn from(sig: Signature) -> Self { + ed25519::Signature::from(sig).into() + } + } + } + + /// An i'm online keypair using ed25519 as its crypto. + #[cfg(feature = "std")] + pub type AuthorityPair = app_ed25519::Pair; -/// A Babe authority signature. -pub type AuthoritySignature = app::Signature; + /// An i'm online signature using ed25519 as its crypto. + pub type AuthoritySignature = app_ed25519::Signature; -/// A Babe authority identifier. Necessarily equivalent to the schnorrkel public key used in -/// the main Babe module. If that ever changes, then this must, too. -pub type AuthorityId = app::Public; + /// An i'm online identifier using ed25519 as its crypto. + pub type AuthorityId = app_ed25519::Public; +} -// The local storage database key under which the worker progress status -// is tracked. +/// The local storage database key under which the worker progress status +/// is tracked. const DB_KEY: &[u8] = b"srml/im-online-worker-status"; -// It's important to persist the worker state, since e.g. the -// server could be restarted while starting the gossip process, but before -// finishing it. With every execution of the off-chain worker we check -// if we need to recover and resume gossipping or if there is already -// another off-chain worker in the process of gossipping. +/// It's important to persist the worker state, since e.g. the +/// server could be restarted while starting the gossip process, but before +/// finishing it. With every execution of the off-chain worker we check +/// if we need to recover and resume gossipping or if there is already +/// another off-chain worker in the process of gossipping. #[derive(Encode, Decode, Clone, PartialEq, Eq)] #[cfg_attr(feature = "std", derive(Debug))] struct WorkerStatus { @@ -117,20 +153,19 @@ struct WorkerStatus { gossipping_at: BlockNumber, } -// Error which may occur while executing the off-chain code. +/// Error which may occur while executing the off-chain code. +#[cfg_attr(feature = "std", derive(Debug))] enum OffchainErr { DecodeWorkerStatus, - ExtrinsicCreation, FailedSigning, NetworkState, SubmitTransaction, } impl Printable for OffchainErr { - fn print(self) { + fn print(&self) { match self { OffchainErr::DecodeWorkerStatus => print("Offchain error: decoding WorkerStatus failed!"), - OffchainErr::ExtrinsicCreation => print("Offchain error: extrinsic creation failed!"), OffchainErr::FailedSigning => print("Offchain error: signing failed!"), OffchainErr::NetworkState => print("Offchain error: fetching network state failed!"), OffchainErr::SubmitTransaction => print("Offchain error: submitting transaction failed!"), @@ -152,20 +187,32 @@ pub struct Heartbeat authority_index: AuthIndex, } -pub trait Trait: system::Trait + session::Trait { +pub trait Trait: system::Trait + session::historical::Trait { + /// The identifier type for an authority. + type AuthorityId: Member + Parameter + RuntimeAppPublic + Default + Ord; + /// The overarching event type. - type Event: From + Into<::Event>; + type Event: From> + Into<::Event>; - /// The function call. + /// A dispatchable call type. type Call: From>; - /// A extrinsic right from the external world. This is unchecked and so - /// can contain a signature. - type UncheckedExtrinsic: ExtrinsicT::Call> + Encode + Decode; + /// A transaction submitter. + type SubmitTransaction: SubmitUnsignedTransaction::Call>; + + /// A type that gives us the ability to submit unresponsiveness offence reports. + type ReportUnresponsiveness: + ReportOffence< + Self::AccountId, + IdentificationTuple, + UnresponsivenessOffence>, + >; } decl_event!( - pub enum Event { + pub enum Event where + ::AuthorityId, + { /// A new heartbeat was received from `AuthorityId` HeartbeatReceived(AuthorityId), } @@ -177,13 +224,17 @@ decl_storage! { GossipAt get(gossip_at): T::BlockNumber; /// The current set of keys that may issue a heartbeat. - Keys get(keys) config(): Vec; + Keys get(keys): Vec; /// For each session index we keep a mapping of `AuthorityId` /// to `offchain::OpaqueNetworkState`. ReceivedHeartbeats get(received_heartbeats): double_map SessionIndex, blake2_256(AuthIndex) => Vec; } + add_extra_genesis { + config(keys): Vec; + build(|config| Module::::initialize_keys(&config.keys)) + } } @@ -194,19 +245,25 @@ decl_module! { fn heartbeat( origin, heartbeat: Heartbeat, - _signature: AuthoritySignature + signature: ::Signature ) { ensure_none(origin)?; let current_session = >::current_index(); + ensure!(current_session == heartbeat.session_index, "Outdated heartbeat received."); let exists = ::exists( ¤t_session, &heartbeat.authority_index ); - let keys = Keys::get(); + let keys = Keys::::get(); let public = keys.get(heartbeat.authority_index as usize); if let (true, Some(public)) = (!exists, public) { - Self::deposit_event(Event::HeartbeatReceived(public.clone())); + let signature_valid = heartbeat.using_encoded(|encoded_heartbeat| { + public.verify(&encoded_heartbeat, &signature) + }); + ensure!(signature_valid, "Invalid heartbeat signature."); + + Self::deposit_event(Event::::HeartbeatReceived(public.clone())); let network_state = heartbeat.network_state.encode(); ::insert( @@ -214,13 +271,17 @@ decl_module! { &heartbeat.authority_index, &network_state ); + } else if exists { + Err("Duplicated heartbeat.")? + } else { + Err("Non existent public key.")? } } // Runs after every block. fn offchain_worker(now: T::BlockNumber) { // Only send messages if we are a potential validator. - if sr_io::is_validator() { + if runtime_io::is_validator() { Self::offchain(now); } } @@ -235,7 +296,7 @@ impl Module { ::exists(¤t_session, &authority_index) } - fn offchain(now: T::BlockNumber) { + pub(crate) fn offchain(now: T::BlockNumber) { let next_gossip = >::get(); let check = Self::check_not_yet_gossipped(now, next_gossip); let (curr_worker_status, not_yet_gossipped) = match check { @@ -263,8 +324,8 @@ impl Module { fn do_gossip_at(block_number: T::BlockNumber) -> Result<(), OffchainErr> { // we run only when a local authority key is configured - let authorities = Keys::get(); - let mut local_keys = app::Public::all(); + let authorities = Keys::::get(); + let mut local_keys = T::AuthorityId::all(); local_keys.sort(); for (authority_index, key) in authorities.into_iter() @@ -275,7 +336,7 @@ impl Module { .map(|location| (index as u32, &local_keys[location])) }) { - let network_state = sr_io::network_state().map_err(|_| OffchainErr::NetworkState)?; + let network_state = runtime_io::network_state().map_err(|_| OffchainErr::NetworkState)?; let heartbeat_data = Heartbeat { block_number, network_state, @@ -285,9 +346,8 @@ impl Module { let signature = key.sign(&heartbeat_data.encode()).ok_or(OffchainErr::FailedSigning)?; let call = Call::heartbeat(heartbeat_data, signature); - let ex = T::UncheckedExtrinsic::new_unsigned(call.into()) - .ok_or(OffchainErr::ExtrinsicCreation)?; - sr_io::submit_transaction(&ex).map_err(|_| OffchainErr::SubmitTransaction)?; + T::SubmitTransaction::submit_unsigned(call) + .map_err(|_| OffchainErr::SubmitTransaction)?; // once finished we set the worker status without comparing // if the existing value changed in the meantime. this is @@ -306,7 +366,7 @@ impl Module { done, gossipping_at, }; - sr_io::local_storage_compare_and_set( + runtime_io::local_storage_compare_and_set( StorageKind::PERSISTENT, DB_KEY, curr_worker_status.as_ref().map(Vec::as_slice), @@ -322,7 +382,7 @@ impl Module { done, gossipping_at, }; - sr_io::local_storage_set( + runtime_io::local_storage_set( StorageKind::PERSISTENT, DB_KEY, &enc.encode()); } @@ -333,7 +393,7 @@ impl Module { now: T::BlockNumber, next_gossip: T::BlockNumber, ) -> Result<(Option>, bool), OffchainErr> { - let last_gossip = sr_io::local_storage_get(StorageKind::PERSISTENT, DB_KEY); + let last_gossip = runtime_io::local_storage_get(StorageKind::PERSISTENT, DB_KEY); match last_gossip { Some(last) => { let worker_status: WorkerStatus = Decode::decode(&mut &last[..]) @@ -355,22 +415,76 @@ impl Module { } } + fn initialize_keys(keys: &[T::AuthorityId]) { + if !keys.is_empty() { + assert!(Keys::::get().is_empty(), "Keys are already initialized!"); + Keys::::put(keys); + } + } } impl session::OneSessionHandler for Module { - type Key = AuthorityId; - fn on_new_session<'a, I: 'a>(_changed: bool, _validators: I, next_validators: I) - where I: Iterator + type Key = T::AuthorityId; + + fn on_genesis_session<'a, I: 'a>(validators: I) + where I: Iterator { - // Reset heartbeats - ::remove_prefix(&>::current_index()); + let keys = validators.map(|x| x.1).collect::>(); + Self::initialize_keys(&keys); + } + fn on_new_session<'a, I: 'a>(_changed: bool, validators: I, _queued_validators: I) + where I: Iterator + { // Tell the offchain worker to start making the next session's heartbeats. >::put(>::block_number()); // Remember who the authorities are for the new session. - Keys::put(next_validators.map(|x| x.1).collect::>()); + Keys::::put(validators.map(|x| x.1).collect::>()); + } + + fn on_before_session_ending() { + let mut unresponsive = vec![]; + + let current_session = >::current_index(); + + let keys = Keys::::get(); + let current_validators = >::validators(); + + for (auth_idx, validator_id) in current_validators.into_iter().enumerate() { + let auth_idx = auth_idx as u32; + let exists = ::exists(¤t_session, &auth_idx); + if !exists { + let full_identification = T::FullIdentificationOf::convert(validator_id.clone()) + .expect( + "we got the validator_id from current_validators; + current_validators is set of currently acting validators; + the mapping between the validator id and its full identification should be valid; + thus `FullIdentificationOf::convert` can't return `None`; + qed", + ); + + unresponsive.push((validator_id, full_identification)); + } + } + + if unresponsive.is_empty() { + return; + } + + let validator_set_count = keys.len() as u32; + let offence = UnresponsivenessOffence { + session_index: current_session, + validator_set_count, + offenders: unresponsive, + }; + + T::ReportUnresponsiveness::report_offence(vec![], offence); + + // Remove all received heartbeats from the current session, they have + // already been processed and won't be needed anymore. + ::remove_prefix(&>::current_index()); } fn on_disabled(_i: usize) { @@ -378,27 +492,27 @@ impl session::OneSessionHandler for Module { } } -impl srml_support::unsigned::ValidateUnsigned for Module { +impl support::unsigned::ValidateUnsigned for Module { type Call = Call; - fn validate_unsigned(call: &Self::Call) -> srml_support::unsigned::TransactionValidity { + fn validate_unsigned(call: &Self::Call) -> TransactionValidity { if let Call::heartbeat(heartbeat, signature) = call { if >::is_online_in_current_session(heartbeat.authority_index) { // we already received a heartbeat for this authority - return TransactionValidity::Invalid(ApplyError::Stale as i8); + return InvalidTransaction::Stale.into(); } // check if session index from heartbeat is recent let current_session = >::current_index(); if heartbeat.session_index != current_session { - return TransactionValidity::Invalid(ApplyError::Stale as i8); + return InvalidTransaction::Stale.into(); } // verify that the incoming (unverified) pubkey is actually an authority id - let keys = Keys::get(); + let keys = Keys::::get(); let authority_id = match keys.get(heartbeat.authority_index as usize) { Some(id) => id, - None => return TransactionValidity::Invalid(ApplyError::BadSignature as i8), + None => return InvalidTransaction::BadProof.into(), }; // check signature (this is expensive so we do it last). @@ -407,18 +521,59 @@ impl srml_support::unsigned::ValidateUnsigned for Module { }); if !signature_valid { - return TransactionValidity::Invalid(ApplyError::BadSignature as i8); + return InvalidTransaction::BadProof.into(); } - return TransactionValidity::Valid(ValidTransaction { + Ok(ValidTransaction { priority: 0, requires: vec![], provides: vec![(current_session, authority_id).encode()], longevity: TransactionLongevity::max_value(), propagate: true, }) + } else { + InvalidTransaction::Call.into() } + } +} + +/// An offence that is filed if a validator didn't send a heartbeat message. +#[cfg_attr(feature = "std", derive(Clone, Debug, PartialEq, Eq))] +pub struct UnresponsivenessOffence { + /// The current session index in which we report the unresponsive validators. + /// + /// It acts as a time measure for unresponsiveness reports and effectively will always point + /// at the end of the session. + session_index: SessionIndex, + /// The size of the validator set in current session/era. + validator_set_count: u32, + /// Authorities that were unresponsive during the current era. + offenders: Vec, +} + +impl Offence for UnresponsivenessOffence { + const ID: Kind = *b"im-online:offlin"; + type TimeSlot = SessionIndex; + + fn offenders(&self) -> Vec { + self.offenders.clone() + } + + fn session_index(&self) -> SessionIndex { + self.session_index + } + + fn validator_set_count(&self) -> u32 { + self.validator_set_count + } + + fn time_slot(&self) -> Self::TimeSlot { + self.session_index + } - TransactionValidity::Invalid(0) + fn slash_fraction(offenders: u32, validator_set_count: u32) -> Perbill { + // the formula is min((3 * (k - 1)) / n, 1) * 0.05 + let x = Perbill::from_rational_approximation(3 * (offenders - 1), validator_set_count); + x.saturating_mul(Perbill::from_percent(5)) } } diff --git a/srml/im-online/src/mock.rs b/srml/im-online/src/mock.rs new file mode 100644 index 0000000000000000000000000000000000000000..a7b669ddb8b91290ca466338a1e10c995ccac938 --- /dev/null +++ b/srml/im-online/src/mock.rs @@ -0,0 +1,167 @@ +// Copyright 2019 Parity Technologies (UK) Ltd. +// This file is part of Substrate. + +// Substrate 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. + +// Substrate 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 Substrate. If not, see . + +//! Test utilities + +#![cfg(test)] + +use std::cell::RefCell; + +use crate::{Module, Trait}; +use sr_primitives::Perbill; +use sr_staking_primitives::{SessionIndex, offence::ReportOffence}; +use sr_primitives::testing::{Header, UintAuthorityId, TestXt}; +use sr_primitives::traits::{IdentityLookup, BlakeTwo256, ConvertInto}; +use primitives::{H256, Blake2Hasher}; +use support::{impl_outer_origin, impl_outer_dispatch, parameter_types}; +use {runtime_io, system}; + +impl_outer_origin!{ + pub enum Origin for Runtime {} +} + +impl_outer_dispatch! { + pub enum Call for Runtime where origin: Origin { + imonline::ImOnline, + } +} + +thread_local! { + pub static VALIDATORS: RefCell>> = RefCell::new(Some(vec![1, 2, 3])); +} + +pub struct TestOnSessionEnding; +impl session::OnSessionEnding for TestOnSessionEnding { + fn on_session_ending(_ending_index: SessionIndex, _will_apply_at: SessionIndex) + -> Option> + { + VALIDATORS.with(|l| l.borrow_mut().take()) + } +} + +impl session::historical::OnSessionEnding for TestOnSessionEnding { + fn on_session_ending(_ending_index: SessionIndex, _will_apply_at: SessionIndex) + -> Option<(Vec, Vec<(u64, u64)>)> + { + VALIDATORS.with(|l| l + .borrow_mut() + .take() + .map(|validators| { + let full_identification = validators.iter().map(|v| (*v, *v)).collect(); + (validators, full_identification) + }) + ) + } +} + +/// An extrinsic type used for tests. +pub type Extrinsic = TestXt; +type SubmitTransaction = system::offchain::TransactionSubmitter<(), Call, Extrinsic>; +type IdentificationTuple = (u64, u64); +type Offence = crate::UnresponsivenessOffence; + +thread_local! { + pub static OFFENCES: RefCell, Offence)>> = RefCell::new(vec![]); +} + +/// A mock offence report handler. +pub struct OffenceHandler; +impl ReportOffence for OffenceHandler { + fn report_offence(reporters: Vec, offence: Offence) { + OFFENCES.with(|l| l.borrow_mut().push((reporters, offence))); + } +} + +pub fn new_test_ext() -> runtime_io::TestExternalities { + let t = system::GenesisConfig::default().build_storage::().unwrap(); + t.into() +} + + +#[derive(Clone, PartialEq, Eq, Debug)] +pub struct Runtime; + +parameter_types! { + pub const BlockHashCount: u64 = 250; + pub const MaximumBlockWeight: u32 = 1024; + pub const MaximumBlockLength: u32 = 2 * 1024; + pub const AvailableBlockRatio: Perbill = Perbill::one(); +} + +impl system::Trait for Runtime { + type Origin = Origin; + type Index = u64; + type BlockNumber = u64; + type Call = Call; + type Hash = H256; + type Hashing = BlakeTwo256; + type AccountId = u64; + type Lookup = IdentityLookup; + type Header = Header; + type WeightMultiplierUpdate = (); + type Event = (); + type BlockHashCount = BlockHashCount; + type MaximumBlockWeight = MaximumBlockWeight; + type MaximumBlockLength = MaximumBlockLength; + type AvailableBlockRatio = AvailableBlockRatio; + type Version = (); +} + +parameter_types! { + pub const Period: u64 = 1; + pub const Offset: u64 = 0; +} + +parameter_types! { + pub const DisabledValidatorsThreshold: Perbill = Perbill::from_percent(33); +} + +impl session::Trait for Runtime { + type ShouldEndSession = session::PeriodicSessions; + type OnSessionEnding = session::historical::NoteHistoricalRoot; + type SessionHandler = (ImOnline, ); + type ValidatorId = u64; + type ValidatorIdOf = ConvertInto; + type Keys = UintAuthorityId; + type Event = (); + type SelectInitialValidators = (); + type DisabledValidatorsThreshold = DisabledValidatorsThreshold; +} + +impl session::historical::Trait for Runtime { + type FullIdentification = u64; + type FullIdentificationOf = ConvertInto; +} + +impl Trait for Runtime { + type AuthorityId = UintAuthorityId; + type Event = (); + type Call = Call; + type SubmitTransaction = SubmitTransaction; + type ReportUnresponsiveness = OffenceHandler; +} + +/// Im Online module. +pub type ImOnline = Module; +pub type System = system::Module; +pub type Session = session::Module; + +pub fn advance_session() { + let now = System::block_number(); + System::set_block_number(now + 1); + Session::rotate_session(); + assert_eq!(Session::current_index(), (now / Period::get()) as u32); +} diff --git a/srml/im-online/src/tests.rs b/srml/im-online/src/tests.rs new file mode 100644 index 0000000000000000000000000000000000000000..c6405c34fa645b71f9d84797206734b83d6372c5 --- /dev/null +++ b/srml/im-online/src/tests.rs @@ -0,0 +1,247 @@ +// Copyright 2019 Parity Technologies (UK) Ltd. +// This file is part of Substrate. + +// Substrate 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. + +// Substrate 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 Substrate. If not, see . + +//! Tests for the im-online module. + +#![cfg(test)] + +use super::*; +use crate::mock::*; +use offchain::testing::TestOffchainExt; +use primitives::offchain::OpaquePeerId; +use runtime_io::with_externalities; +use support::{dispatch, assert_noop}; +use sr_primitives::testing::UintAuthorityId; + + +#[test] +fn test_unresponsiveness_slash_fraction() { + // A single case of unresponsiveness is not slashed. + assert_eq!( + UnresponsivenessOffence::<()>::slash_fraction(1, 50), + Perbill::zero(), + ); + + assert_eq!( + UnresponsivenessOffence::<()>::slash_fraction(3, 50), + Perbill::from_parts(6000000), // 0.6% + ); + + // One third offline should be punished around 5%. + assert_eq!( + UnresponsivenessOffence::<()>::slash_fraction(17, 50), + Perbill::from_parts(48000000), // 4.8% + ); +} + +#[test] +fn should_report_offline_validators() { + with_externalities(&mut new_test_ext(), || { + // given + let block = 1; + System::set_block_number(block); + // buffer new validators + Session::rotate_session(); + // enact the change and buffer another one + let validators = vec![1, 2, 3, 4, 5, 6]; + VALIDATORS.with(|l| *l.borrow_mut() = Some(validators.clone())); + Session::rotate_session(); + + // when + // we end current session and start the next one + Session::rotate_session(); + + // then + let offences = OFFENCES.with(|l| l.replace(vec![])); + assert_eq!(offences, vec![ + (vec![], UnresponsivenessOffence { + session_index: 2, + validator_set_count: 3, + offenders: vec![ + (1, 1), + (2, 2), + (3, 3), + ], + }) + ]); + + // should not report when heartbeat is sent + for (idx, v) in validators.into_iter().take(4).enumerate() { + let _ = heartbeat(block, 3, idx as u32, v.into()).unwrap(); + } + Session::rotate_session(); + + // then + let offences = OFFENCES.with(|l| l.replace(vec![])); + assert_eq!(offences, vec![ + (vec![], UnresponsivenessOffence { + session_index: 3, + validator_set_count: 6, + offenders: vec![ + (5, 5), + (6, 6), + ], + }) + ]); + }); +} + +fn heartbeat( + block_number: u64, + session_index: u32, + authority_index: u32, + id: UintAuthorityId, +) -> dispatch::Result { + let heartbeat = Heartbeat { + block_number, + network_state: OpaqueNetworkState { + peer_id: OpaquePeerId(vec![1]), + external_addresses: vec![], + }, + session_index, + authority_index, + }; + let signature = id.sign(&heartbeat.encode()).unwrap(); + + ImOnline::heartbeat( + Origin::system(system::RawOrigin::None), + heartbeat, + signature + ) +} + +#[test] +fn should_mark_online_validator_when_heartbeat_is_received() { + with_externalities(&mut new_test_ext(), || { + advance_session(); + // given + VALIDATORS.with(|l| *l.borrow_mut() = Some(vec![1, 2, 3, 4, 5, 6])); + assert_eq!(Session::validators(), Vec::::new()); + // enact the change and buffer another one + advance_session(); + + assert_eq!(Session::current_index(), 2); + assert_eq!(Session::validators(), vec![1, 2, 3]); + + assert!(!ImOnline::is_online_in_current_session(0)); + assert!(!ImOnline::is_online_in_current_session(1)); + assert!(!ImOnline::is_online_in_current_session(2)); + + // when + let _ = heartbeat(1, 2, 0, 1.into()).unwrap(); + + // then + assert!(ImOnline::is_online_in_current_session(0)); + assert!(!ImOnline::is_online_in_current_session(1)); + assert!(!ImOnline::is_online_in_current_session(2)); + + // and when + let _ = heartbeat(1, 2, 2, 3.into()).unwrap(); + + // then + assert!(ImOnline::is_online_in_current_session(0)); + assert!(!ImOnline::is_online_in_current_session(1)); + assert!(ImOnline::is_online_in_current_session(2)); + }); +} + +#[test] +fn late_heartbeat_should_fail() { + with_externalities(&mut new_test_ext(), || { + advance_session(); + // given + VALIDATORS.with(|l| *l.borrow_mut() = Some(vec![1, 2, 4, 4, 5, 6])); + assert_eq!(Session::validators(), Vec::::new()); + // enact the change and buffer another one + advance_session(); + + assert_eq!(Session::current_index(), 2); + assert_eq!(Session::validators(), vec![1, 2, 3]); + + // when + assert_noop!(heartbeat(1, 3, 0, 1.into()), "Outdated heartbeat received."); + assert_noop!(heartbeat(1, 1, 0, 1.into()), "Outdated heartbeat received."); + }); +} + +#[test] +fn should_generate_heartbeats() { + let mut ext = new_test_ext(); + let (offchain, state) = TestOffchainExt::new(); + ext.set_offchain_externalities(offchain); + + with_externalities(&mut ext, || { + // given + let block = 1; + System::set_block_number(block); + // buffer new validators + Session::rotate_session(); + // enact the change and buffer another one + VALIDATORS.with(|l| *l.borrow_mut() = Some(vec![1, 2, 3, 4, 5, 6])); + Session::rotate_session(); + + // when + UintAuthorityId::set_all_keys(vec![0, 1, 2]); + ImOnline::offchain(2); + + // then + let transaction = state.write().transactions.pop().unwrap(); + // All validators have `0` as their session key, so we generate 3 transactions. + assert_eq!(state.read().transactions.len(), 2); + // check stuff about the transaction. + let ex: Extrinsic = Decode::decode(&mut &*transaction).unwrap(); + let heartbeat = match ex.1 { + crate::mock::Call::ImOnline(crate::Call::heartbeat(h, _)) => h, + e => panic!("Unexpected call: {:?}", e), + }; + + assert_eq!(heartbeat, Heartbeat { + block_number: 2, + network_state: runtime_io::network_state().unwrap(), + session_index: 2, + authority_index: 2, + }); + }); +} + +#[test] +fn should_cleanup_received_heartbeats_on_session_end() { + with_externalities(&mut new_test_ext(), || { + advance_session(); + + VALIDATORS.with(|l| *l.borrow_mut() = Some(vec![1, 2, 3])); + assert_eq!(Session::validators(), Vec::::new()); + + // enact the change and buffer another one + advance_session(); + + assert_eq!(Session::current_index(), 2); + assert_eq!(Session::validators(), vec![1, 2, 3]); + + // send an heartbeat from authority id 0 at session 2 + let _ = heartbeat(1, 2, 0, 1.into()).unwrap(); + + // the heartbeat is stored + assert!(!ImOnline::received_heartbeats(&2, &0).is_empty()); + + advance_session(); + + // after the session has ended we have already processed the heartbeat + // message, so any messages received on the previous session should have + // been pruned. + assert!(ImOnline::received_heartbeats(&2, &0).is_empty()); + }); +} diff --git a/srml/indices/Cargo.toml b/srml/indices/Cargo.toml index 3cbf1d88dec9f1e8c88c43b2249519f4336e5fee..b8b560c3f9b4d4b34a178582e4dcc7f695f540ef 100644 --- a/srml/indices/Cargo.toml +++ b/srml/indices/Cargo.toml @@ -5,19 +5,19 @@ authors = ["Parity Technologies "] edition = "2018" [dependencies] -serde = { version = "1.0", optional = true } -safe-mix = { version = "1.0", default-features = false} +serde = { version = "1.0.101", optional = true } +safe-mix = { version = "1.0.0", default-features = false } codec = { package = "parity-scale-codec", version = "1.0.0", default-features = false, features = ["derive"] } substrate-keyring = { path = "../../core/keyring", optional = true } rstd = { package = "sr-std", path = "../../core/sr-std", default-features = false } runtime-io = { package = "sr-io", path = "../../core/sr-io", default-features = false } sr-primitives = { path = "../../core/sr-primitives", default-features = false } primitives = { package = "substrate-primitives", path = "../../core/primitives", default-features = false } -srml-support = { path = "../support", default-features = false } +support = { package = "srml-support", path = "../support", default-features = false } system = { package = "srml-system", path = "../system", default-features = false } [dev-dependencies] -ref_thread_local = "0.0" +ref_thread_local = "0.0.0" [features] default = ["std"] @@ -29,7 +29,7 @@ std = [ "primitives/std", "rstd/std", "runtime-io/std", - "srml-support/std", + "support/std", "sr-primitives/std", "system/std", ] diff --git a/srml/indices/src/lib.rs b/srml/indices/src/lib.rs index 5bf838f32112dfc56c63fce28ff272218cb23a90..be5016c40ef08baeb5ec68bcf16e9eb184966182 100644 --- a/srml/indices/src/lib.rs +++ b/srml/indices/src/lib.rs @@ -19,10 +19,10 @@ #![cfg_attr(not(feature = "std"), no_std)] -use rstd::{prelude::*, result, marker::PhantomData, convert::TryInto}; +use rstd::{prelude::*, marker::PhantomData, convert::TryInto}; use codec::{Encode, Codec}; -use srml_support::{StorageValue, StorageMap, Parameter, decl_module, decl_event, decl_storage}; -use sr_primitives::traits::{One, SimpleArithmetic, StaticLookup, Member}; +use support::{Parameter, decl_module, decl_event, decl_storage}; +use sr_primitives::traits::{One, SimpleArithmetic, StaticLookup, Member, LookupError}; use system::{IsDeadAccount, OnNewAccount}; use self::address::Address as RawAddress; @@ -73,7 +73,7 @@ pub trait Trait: system::Trait { decl_module! { pub struct Module for enum Call where origin: T::Origin { - fn deposit_event() = default; + fn deposit_event() = default; } } @@ -224,9 +224,11 @@ impl OnNewAccount for Module { impl StaticLookup for Module { type Source = address::Address; type Target = T::AccountId; - fn lookup(a: Self::Source) -> result::Result { - Self::lookup_address(a).ok_or("invalid account index") + + fn lookup(a: Self::Source) -> Result { + Self::lookup_address(a).ok_or(LookupError) } + fn unlookup(a: Self::Target) -> Self::Source { address::Address::Id(a) } diff --git a/srml/indices/src/mock.rs b/srml/indices/src/mock.rs index 50b38eae28f91b5992c67a4159509fb211f9363c..65a0193b5af4902ee40794d642cbbf1c63257d7b 100644 --- a/srml/indices/src/mock.rs +++ b/srml/indices/src/mock.rs @@ -23,7 +23,7 @@ use ref_thread_local::{ref_thread_local, RefThreadLocal}; use sr_primitives::testing::Header; use sr_primitives::Perbill; use primitives::{H256, Blake2Hasher}; -use srml_support::{impl_outer_origin, parameter_types}; +use support::{impl_outer_origin, parameter_types}; use {runtime_io, system}; use crate::{GenesisConfig, Module, Trait, IsDeadAccount, OnNewAccount, ResolveHint}; @@ -87,6 +87,7 @@ impl system::Trait for Runtime { type MaximumBlockWeight = MaximumBlockWeight; type MaximumBlockLength = MaximumBlockLength; type AvailableBlockRatio = AvailableBlockRatio; + type Version = (); } impl Trait for Runtime { type AccountIndex = u64; diff --git a/srml/membership/Cargo.toml b/srml/membership/Cargo.toml index 5126f41f8929aa52fbda89f8b8ce78ee056fd729..a8cb73055563ec5fa82ec40e9d2d0f20031f6c7c 100644 --- a/srml/membership/Cargo.toml +++ b/srml/membership/Cargo.toml @@ -5,11 +5,11 @@ authors = ["Parity Technologies "] edition = "2018" [dependencies] -serde = { version = "1.0", optional = true } +serde = { version = "1.0.101", optional = true } codec = { package = "parity-scale-codec", version = "1.0.0", default-features = false } -sr-std = { path = "../../core/sr-std", default-features = false } -sr-io = { path = "../../core/sr-io", default-features = false } -srml-support = { path = "../support", default-features = false } +rstd = { package = "sr-std", path = "../../core/sr-std", default-features = false } +runtime-io = { package = "sr-io", path = "../../core/sr-io", default-features = false } +support = { package = "srml-support", path = "../support", default-features = false } system = { package = "srml-system", path = "../system", default-features = false } sr-primitives = { path = "../../core/sr-primitives", default-features = false } @@ -22,8 +22,8 @@ std = [ "serde", "codec/std", "sr-primitives/std", - "sr-std/std", - "sr-io/std", - "srml-support/std", + "rstd/std", + "runtime-io/std", + "support/std", "system/std", ] diff --git a/srml/membership/src/lib.rs b/srml/membership/src/lib.rs index 8e8feec4ee59053db1f1cea4b7d7fe3215bbeeb3..87e9268bd910e54afb723b9b899cb06ed629186a 100644 --- a/srml/membership/src/lib.rs +++ b/srml/membership/src/lib.rs @@ -22,9 +22,9 @@ // Ensure we're `no_std` when compiling for Wasm. #![cfg_attr(not(feature = "std"), no_std)] -use sr_std::prelude::*; -use srml_support::{ - StorageValue, decl_module, decl_storage, decl_event, traits::{ChangeMembers, InitializeMembers}, +use rstd::prelude::*; +use support::{ + decl_module, decl_storage, decl_event, traits::{ChangeMembers, InitializeMembers}, }; use system::ensure_root; use sr_primitives::{traits::EnsureOrigin, weights::SimpleDispatchInfo}; @@ -61,17 +61,12 @@ decl_storage! { } add_extra_genesis { config(members): Vec; - config(phantom): sr_std::marker::PhantomData; - build(| - storage: &mut (sr_primitives::StorageOverlay, sr_primitives::ChildrenStorageOverlay), - config: &Self, - | { - sr_io::with_storage(storage, || { - let mut members = config.members.clone(); - members.sort(); - T::MembershipInitialized::initialize_members(&members); - >::put(members); - }); + config(phantom): rstd::marker::PhantomData; + build(|config: &Self| { + let mut members = config.members.clone(); + members.sort(); + T::MembershipInitialized::initialize_members(&members); + >::put(members); }) } } @@ -90,7 +85,7 @@ decl_event!( /// The membership was reset; see the transaction for who the new set is. MembersReset, /// Phantom member, never used. - Dummy(sr_std::marker::PhantomData<(AccountId, Event)>), + Dummy(rstd::marker::PhantomData<(AccountId, Event)>), } ); @@ -99,7 +94,7 @@ decl_module! { for enum Call where origin: T::Origin { - fn deposit_event() = default; + fn deposit_event() = default; /// Add a member `who` to the set. /// @@ -197,8 +192,8 @@ mod tests { use super::*; use std::cell::RefCell; - use srml_support::{assert_ok, assert_noop, impl_outer_origin, parameter_types}; - use sr_io::with_externalities; + use support::{assert_ok, assert_noop, impl_outer_origin, parameter_types}; + use runtime_io::with_externalities; use primitives::{H256, Blake2Hasher}; // The testing primitives are very useful for avoiding having to work with signatures // or public keys. `u64` is used as the `AccountId` and no `Signature`s are requried. @@ -238,6 +233,7 @@ mod tests { type MaximumBlockWeight = MaximumBlockWeight; type MaximumBlockLength = MaximumBlockLength; type AvailableBlockRatio = AvailableBlockRatio; + type Version = (); } parameter_types! { pub const One: u64 = 1; @@ -285,7 +281,7 @@ mod tests { // This function basically just builds a genesis storage key/value store according to // our desired mockup. - fn new_test_ext() -> sr_io::TestExternalities { + fn new_test_ext() -> runtime_io::TestExternalities { let mut t = system::GenesisConfig::default().build_storage::().unwrap(); // We use default for brevity, but you can configure as desired if needed. GenesisConfig::{ diff --git a/srml/metadata/Cargo.toml b/srml/metadata/Cargo.toml index 9fc9c6e46d5dbfaa1dbbf4a1a350a2d3d0ef9825..e9381f68bbbf967f24c3a168cca47d1f4116e626 100644 --- a/srml/metadata/Cargo.toml +++ b/srml/metadata/Cargo.toml @@ -6,7 +6,7 @@ edition = "2018" [dependencies] codec = { package = "parity-scale-codec", version = "1.0.0", default-features = false, features = ["derive"] } -serde = { version = "1.0", optional = true, features = ["derive"] } +serde = { version = "1.0.101", optional = true, features = ["derive"] } rstd = { package = "sr-std", path = "../../core/sr-std", default-features = false } primitives = { package = "substrate-primitives", path = "../../core/primitives", default-features = false } diff --git a/srml/offences/Cargo.toml b/srml/offences/Cargo.toml new file mode 100644 index 0000000000000000000000000000000000000000..90a3396d112280285dfa1b55fcdcf1071e613cc9 --- /dev/null +++ b/srml/offences/Cargo.toml @@ -0,0 +1,32 @@ +[package] +name = "srml-offences" +version = "1.0.0" +authors = ["Parity Technologies "] +edition = "2018" + +[dependencies] +balances = { package = "srml-balances", path = "../balances", default-features = false } +codec = { package = "parity-scale-codec", version = "1.0.0", default-features = false, features = ["derive"] } +rstd = { package = "sr-std", path = "../../core/sr-std", default-features = false } +serde = { version = "1.0.101", optional = true } +sr-primitives = { path = "../../core/sr-primitives", default-features = false } +sr-staking-primitives = { path = "../../core/sr-staking-primitives", default-features = false } +support = { package = "srml-support", path = "../support", default-features = false } +system = { package = "srml-system", path = "../system", default-features = false } + +[dev-dependencies] +runtime-io = { package = "sr-io", path = "../../core/sr-io" } +substrate-primitives = { path = "../../core/primitives" } + +[features] +default = ["std"] +std = [ + "balances/std", + "codec/std", + "rstd/std", + "serde", + "sr-primitives/std", + "sr-staking-primitives/std", + "support/std", + "system/std", +] diff --git a/srml/offences/src/lib.rs b/srml/offences/src/lib.rs new file mode 100644 index 0000000000000000000000000000000000000000..801b8b5fca90b0d7d8dcf0771ea825291ea08899 --- /dev/null +++ b/srml/offences/src/lib.rs @@ -0,0 +1,279 @@ +// Copyright 2019 Parity Technologies (UK) Ltd. +// This file is part of Substrate. + +// Substrate 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. + +// Substrate 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 Substrate. If not, see . + +//! # Offences Module +//! +//! Tracks reported offences + +// Ensure we're `no_std` when compiling for Wasm. +#![cfg_attr(not(feature = "std"), no_std)] + +mod mock; +mod tests; + +use rstd::{ + vec::Vec, + collections::btree_set::BTreeSet, +}; +use support::{ + decl_module, decl_event, decl_storage, Parameter, +}; +use sr_primitives::{ + Perbill, + traits::{Hash, Saturating}, +}; +use sr_staking_primitives::{ + offence::{Offence, ReportOffence, Kind, OnOffenceHandler, OffenceDetails}, +}; +use codec::{Encode, Decode}; + +/// A binary blob which represents a SCALE codec-encoded `O::TimeSlot`. +type OpaqueTimeSlot = Vec; + +/// A type alias for a report identifier. +type ReportIdOf = ::Hash; + +/// Offences trait +pub trait Trait: system::Trait { + /// The overarching event type. + type Event: From + Into<::Event>; + /// Full identification of the validator. + type IdentificationTuple: Parameter + Ord; + /// A handler called for every offence report. + type OnOffenceHandler: OnOffenceHandler; +} + +decl_storage! { + trait Store for Module as Offences { + /// The primary structure that holds all offence records keyed by report identifiers. + Reports get(reports): map ReportIdOf => Option>; + + /// A vector of reports of the same kind that happened at the same time slot. + ConcurrentReportsIndex: double_map Kind, blake2_256(OpaqueTimeSlot) => Vec>; + + /// Enumerates all reports of a kind along with the time they happened. + /// + /// All reports are sorted by the time of offence. + /// + /// Note that the actual type of this mapping is `Vec`, this is because values of + /// different types are not supported at the moment so we are doing the manual serialization. + ReportsByKindIndex: map Kind => Vec; // (O::TimeSlot, ReportIdOf) + } +} + +decl_event!( + pub enum Event { + /// There is an offence reported of the given `kind` happened at the `session_index` and + /// (kind-specific) time slot. This event is not deposited for duplicate slashes. + Offence(Kind, OpaqueTimeSlot), + } +); + +decl_module! { + /// Offences module, currently just responsible for taking offence reports. + pub struct Module for enum Call where origin: T::Origin { + fn deposit_event() = default; + } +} +impl> + ReportOffence for Module +where + T::IdentificationTuple: Clone, +{ + fn report_offence(reporters: Vec, offence: O) { + let offenders = offence.offenders(); + let time_slot = offence.time_slot(); + let validator_set_count = offence.validator_set_count(); + + // Go through all offenders in the offence report and find all offenders that was spotted + // in unique reports. + let TriageOutcome { + new_offenders, + concurrent_offenders, + } = match Self::triage_offence_report::(reporters, &time_slot, offenders) { + Some(triage) => triage, + // The report contained only duplicates, so there is no need to slash again. + None => return, + }; + + // Deposit the event. + Self::deposit_event(Event::Offence(O::ID, time_slot.encode())); + + let offenders_count = concurrent_offenders.len() as u32; + let previous_offenders_count = offenders_count - new_offenders.len() as u32; + + // The amount new offenders are slashed + let new_fraction = O::slash_fraction(offenders_count, validator_set_count); + + // The amount previous offenders are slashed additionally. + // + // Since they were slashed in the past, we slash by: + // x = (new - prev) / (1 - prev) + // because: + // Y = X * (1 - prev) + // Z = Y * (1 - x) + // Z = X * (1 - new) + let old_fraction = if previous_offenders_count > 0 { + let previous_fraction = O::slash_fraction( + offenders_count.saturating_sub(previous_offenders_count), + validator_set_count, + ); + let numerator = new_fraction.saturating_sub(previous_fraction); + let denominator = Perbill::one().saturating_sub(previous_fraction); + denominator.saturating_mul(numerator) + } else { + new_fraction.clone() + }; + + // calculate how much to slash + let slash_perbill = concurrent_offenders + .iter() + .map(|details| { + if previous_offenders_count > 0 && new_offenders.contains(&details.offender) { + new_fraction.clone() + } else { + old_fraction.clone() + } + }) + .collect::>(); + + T::OnOffenceHandler::on_offence(&concurrent_offenders, &slash_perbill); + } +} + +impl Module { + /// Compute the ID for the given report properties. + /// + /// The report id depends on the offence kind, time slot and the id of offender. + fn report_id>( + time_slot: &O::TimeSlot, + offender: &T::IdentificationTuple, + ) -> ReportIdOf { + (O::ID, time_slot.encode(), offender).using_encoded(T::Hashing::hash) + } + + /// Triages the offence report and returns the set of offenders that was involved in unique + /// reports along with the list of the concurrent offences. + fn triage_offence_report>( + reporters: Vec, + time_slot: &O::TimeSlot, + offenders: Vec, + ) -> Option> { + let mut storage = ReportIndexStorage::::load(time_slot); + let mut new_offenders = BTreeSet::new(); + + for offender in offenders { + let report_id = Self::report_id::(time_slot, &offender); + + if !>::exists(&report_id) { + new_offenders.insert(offender.clone()); + >::insert( + &report_id, + OffenceDetails { + offender, + reporters: reporters.clone(), + }, + ); + + storage.insert(time_slot, report_id); + } + } + + if !new_offenders.is_empty() { + // Load report details for the all reports happened at the same time. + let concurrent_offenders = storage.concurrent_reports + .iter() + .filter_map(|report_id| >::get(report_id)) + .collect::>(); + + storage.save(); + + Some(TriageOutcome { + new_offenders, + concurrent_offenders, + }) + } else { + None + } + } +} + +struct TriageOutcome { + /// Offenders that was spotted in the unique reports. + new_offenders: BTreeSet, + /// Other reports for the same report kinds. + concurrent_offenders: Vec>, +} + +/// An auxilary struct for working with storage of indexes localized for a specific offence +/// kind (specified by the `O` type parameter). +/// +/// This struct is responsible for aggregating storage writes and the underlying storage should not +/// accessed directly meanwhile. +#[must_use = "The changes are not saved without called `save`"] +struct ReportIndexStorage> { + opaque_time_slot: OpaqueTimeSlot, + concurrent_reports: Vec>, + same_kind_reports: Vec<(O::TimeSlot, ReportIdOf)>, +} + +impl> ReportIndexStorage { + /// Preload indexes from the storage for the specific `time_slot` and the kind of the offence. + fn load(time_slot: &O::TimeSlot) -> Self { + let opaque_time_slot = time_slot.encode(); + + let same_kind_reports = ::get(&O::ID); + let same_kind_reports = + Vec::<(O::TimeSlot, ReportIdOf)>::decode(&mut &same_kind_reports[..]) + .unwrap_or_default(); + + let concurrent_reports = >::get(&O::ID, &opaque_time_slot); + + Self { + opaque_time_slot, + concurrent_reports, + same_kind_reports, + } + } + + /// Insert a new report to the index. + fn insert(&mut self, time_slot: &O::TimeSlot, report_id: ReportIdOf) { + // Insert the report id into the list while maintaining the ordering by the time + // slot. + let pos = match self + .same_kind_reports + .binary_search_by_key(&time_slot, |&(ref when, _)| when) + { + Ok(pos) => pos, + Err(pos) => pos, + }; + self.same_kind_reports + .insert(pos, (time_slot.clone(), report_id)); + + // Update the list of concurrent reports. + self.concurrent_reports.push(report_id); + } + + /// Dump the indexes to the storage. + fn save(self) { + ::insert(&O::ID, self.same_kind_reports.encode()); + >::insert( + &O::ID, + &self.opaque_time_slot, + &self.concurrent_reports, + ); + } +} diff --git a/srml/offences/src/mock.rs b/srml/offences/src/mock.rs new file mode 100644 index 0000000000000000000000000000000000000000..e7280c34e92431265b60bedda712de52e254679e --- /dev/null +++ b/srml/offences/src/mock.rs @@ -0,0 +1,163 @@ +// Copyright 2018-2019 Parity Technologies (UK) Ltd. +// This file is part of Substrate. + +// Substrate 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. + +// Substrate 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 Substrate. If not, see . + +//! Test utilities + +#![cfg(test)] + +use std::cell::RefCell; +use crate::{Module, Trait}; +use codec::Encode; +use sr_primitives::Perbill; +use sr_staking_primitives::{ + SessionIndex, + offence::{self, Kind, OffenceDetails}, +}; +use sr_primitives::testing::Header; +use sr_primitives::traits::{IdentityLookup, BlakeTwo256}; +use substrate_primitives::{H256, Blake2Hasher}; +use support::{impl_outer_origin, impl_outer_event, parameter_types, StorageMap, StorageDoubleMap}; +use {runtime_io, system}; + +impl_outer_origin!{ + pub enum Origin for Runtime {} +} + +pub struct OnOffenceHandler; + +thread_local! { + pub static ON_OFFENCE_PERBILL: RefCell> = RefCell::new(Default::default()); +} + +impl offence::OnOffenceHandler for OnOffenceHandler { + fn on_offence( + _offenders: &[OffenceDetails], + slash_fraction: &[Perbill], + ) { + ON_OFFENCE_PERBILL.with(|f| { + *f.borrow_mut() = slash_fraction.to_vec(); + }); + } +} + +pub fn with_on_offence_fractions) -> R>(f: F) -> R { + ON_OFFENCE_PERBILL.with(|fractions| { + f(&mut *fractions.borrow_mut()) + }) +} + +// Workaround for https://github.com/rust-lang/rust/issues/26925 . Remove when sorted. +#[derive(Clone, PartialEq, Eq, Debug)] +pub struct Runtime; +parameter_types! { + pub const BlockHashCount: u64 = 250; + pub const MaximumBlockWeight: u32 = 1024; + pub const MaximumBlockLength: u32 = 2 * 1024; + pub const AvailableBlockRatio: Perbill = Perbill::one(); +} +impl system::Trait for Runtime { + type Origin = Origin; + type Index = u64; + type BlockNumber = u64; + type Call = (); + type Hash = H256; + type Hashing = BlakeTwo256; + type AccountId = u64; + type Lookup = IdentityLookup; + type Header = Header; + type WeightMultiplierUpdate = (); + type Event = TestEvent; + type BlockHashCount = BlockHashCount; + type MaximumBlockWeight = MaximumBlockWeight; + type MaximumBlockLength = MaximumBlockLength; + type AvailableBlockRatio = AvailableBlockRatio; + type Version = (); +} + +impl Trait for Runtime { + type Event = TestEvent; + type IdentificationTuple = u64; + type OnOffenceHandler = OnOffenceHandler; +} + +mod offences { + pub use crate::Event; +} + +impl_outer_event! { + pub enum TestEvent for Runtime { + offences, + } +} + +pub fn new_test_ext() -> runtime_io::TestExternalities { + let t = system::GenesisConfig::default().build_storage::().unwrap(); + t.into() +} + +/// Offences module. +pub type Offences = Module; +pub type System = system::Module; + +pub const KIND: [u8; 16] = *b"test_report_1234"; + +/// Returns all offence details for the specific `kind` happened at the specific time slot. +pub fn offence_reports(kind: Kind, time_slot: u128) -> Vec> { + >::get(&kind, &time_slot.encode()) + .into_iter() + .map(|report_id| { + >::get(&report_id) + .expect("dangling report id is found in ConcurrentReportsIndex") + }) + .collect() +} + +#[derive(Clone)] +pub struct Offence { + pub validator_set_count: u32, + pub offenders: Vec, + pub time_slot: u128, +} + +impl offence::Offence for Offence { + const ID: offence::Kind = KIND; + type TimeSlot = u128; + + fn offenders(&self) -> Vec { + self.offenders.clone() + } + + fn validator_set_count(&self) -> u32 { + self.validator_set_count + } + + fn time_slot(&self) -> u128 { + self.time_slot + } + + fn session_index(&self) -> SessionIndex { + // session index is not used by the srml-offences directly, but rather it exists only for + // filtering historical reports. + unimplemented!() + } + + fn slash_fraction( + offenders_count: u32, + validator_set_count: u32, + ) -> Perbill { + Perbill::from_percent(5 + offenders_count * 100 / validator_set_count) + } +} diff --git a/srml/offences/src/tests.rs b/srml/offences/src/tests.rs new file mode 100644 index 0000000000000000000000000000000000000000..17f933b8e8d12bcd6dc9d8f26613e0cca753fccf --- /dev/null +++ b/srml/offences/src/tests.rs @@ -0,0 +1,246 @@ +// Copyright 2017-2019 Parity Technologies (UK) Ltd. +// This file is part of Substrate. + +// Substrate 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. + +// Substrate 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 Substrate. If not, see . + +//! Tests for the offences module. + +#![cfg(test)] + +use super::*; +use crate::mock::{ + Offences, System, Offence, TestEvent, KIND, new_test_ext, with_on_offence_fractions, + offence_reports, +}; +use system::{EventRecord, Phase}; +use runtime_io::with_externalities; + +#[test] +fn should_report_an_authority_and_trigger_on_offence() { + with_externalities(&mut new_test_ext(), || { + // given + let time_slot = 42; + assert_eq!(offence_reports(KIND, time_slot), vec![]); + + let offence = Offence { + validator_set_count: 5, + time_slot, + offenders: vec![5], + }; + + // when + Offences::report_offence(vec![], offence); + + // then + with_on_offence_fractions(|f| { + assert_eq!(f.clone(), vec![Perbill::from_percent(25)]); + }); + }); +} + +#[test] +fn should_calculate_the_fraction_correctly() { + with_externalities(&mut new_test_ext(), || { + // given + let time_slot = 42; + assert_eq!(offence_reports(KIND, time_slot), vec![]); + let offence1 = Offence { + validator_set_count: 5, + time_slot, + offenders: vec![5], + }; + let offence2 = Offence { + validator_set_count: 5, + time_slot, + offenders: vec![4], + }; + + // when + Offences::report_offence(vec![], offence1); + with_on_offence_fractions(|f| { + assert_eq!(f.clone(), vec![Perbill::from_percent(25)]); + }); + + Offences::report_offence(vec![], offence2); + + // then + with_on_offence_fractions(|f| { + assert_eq!(f.clone(), vec![Perbill::from_percent(15), Perbill::from_percent(45)]); + }); + }); +} + +#[test] +fn should_not_report_the_same_authority_twice_in_the_same_slot() { + with_externalities(&mut new_test_ext(), || { + // given + let time_slot = 42; + assert_eq!(offence_reports(KIND, time_slot), vec![]); + + let offence = Offence { + validator_set_count: 5, + time_slot, + offenders: vec![5], + }; + Offences::report_offence(vec![], offence.clone()); + with_on_offence_fractions(|f| { + assert_eq!(f.clone(), vec![Perbill::from_percent(25)]); + f.clear(); + }); + + // when + // report for the second time + Offences::report_offence(vec![], offence); + + // then + with_on_offence_fractions(|f| { + assert_eq!(f.clone(), vec![]); + }); + }); +} + + +#[test] +fn should_report_in_different_time_slot() { + with_externalities(&mut new_test_ext(), || { + // given + let time_slot = 42; + assert_eq!(offence_reports(KIND, time_slot), vec![]); + + let mut offence = Offence { + validator_set_count: 5, + time_slot, + offenders: vec![5], + }; + Offences::report_offence(vec![], offence.clone()); + with_on_offence_fractions(|f| { + assert_eq!(f.clone(), vec![Perbill::from_percent(25)]); + f.clear(); + }); + + // when + // reportfor the second time + offence.time_slot += 1; + Offences::report_offence(vec![], offence); + + // then + with_on_offence_fractions(|f| { + assert_eq!(f.clone(), vec![Perbill::from_percent(25)]); + }); + }); +} + +#[test] +fn should_deposit_event() { + with_externalities(&mut new_test_ext(), || { + // given + let time_slot = 42; + assert_eq!(offence_reports(KIND, time_slot), vec![]); + + let offence = Offence { + validator_set_count: 5, + time_slot, + offenders: vec![5], + }; + + // when + Offences::report_offence(vec![], offence); + + // then + assert_eq!( + System::events(), + vec![EventRecord { + phase: Phase::ApplyExtrinsic(0), + event: TestEvent::offences(crate::Event::Offence(KIND, time_slot.encode())), + topics: vec![], + }] + ); + }); +} + +#[test] +fn doesnt_deposit_event_for_dups() { + with_externalities(&mut new_test_ext(), || { + // given + let time_slot = 42; + assert_eq!(offence_reports(KIND, time_slot), vec![]); + + let offence = Offence { + validator_set_count: 5, + time_slot, + offenders: vec![5], + }; + Offences::report_offence(vec![], offence.clone()); + with_on_offence_fractions(|f| { + assert_eq!(f.clone(), vec![Perbill::from_percent(25)]); + f.clear(); + }); + + // when + // report for the second time + Offences::report_offence(vec![], offence); + + // then + // there is only one event. + assert_eq!( + System::events(), + vec![EventRecord { + phase: Phase::ApplyExtrinsic(0), + event: TestEvent::offences(crate::Event::Offence(KIND, time_slot.encode())), + topics: vec![], + }] + ); + }); +} + +#[test] +fn should_properly_count_offences() { + // We report two different authorities for the same issue. Ultimately, the 1st authority + // should have `count` equal 2 and the count of the 2nd one should be equal to 1. + with_externalities(&mut new_test_ext(), || { + // given + let time_slot = 42; + assert_eq!(offence_reports(KIND, time_slot), vec![]); + + let offence1 = Offence { + validator_set_count: 5, + time_slot, + offenders: vec![5], + }; + let offence2 = Offence { + validator_set_count: 5, + time_slot, + offenders: vec![4], + }; + Offences::report_offence(vec![], offence1); + with_on_offence_fractions(|f| { + assert_eq!(f.clone(), vec![Perbill::from_percent(25)]); + f.clear(); + }); + + // when + // report for the second time + Offences::report_offence(vec![], offence2); + + // then + // the 1st authority should have count 2 and the 2nd one should be reported only once. + assert_eq!( + offence_reports(KIND, time_slot), + vec![ + OffenceDetails { offender: 5, reporters: vec![] }, + OffenceDetails { offender: 4, reporters: vec![] }, + ] + ); + }); +} diff --git a/srml/scored-pool/Cargo.toml b/srml/scored-pool/Cargo.toml new file mode 100644 index 0000000000000000000000000000000000000000..e65f71a10d13ed24cadfe957ca7732df661d5291 --- /dev/null +++ b/srml/scored-pool/Cargo.toml @@ -0,0 +1,30 @@ +[package] +name = "srml-scored-pool" +version = "1.0.0" +authors = ["Parity Technologies "] +edition = "2018" + +[dependencies] +codec = { package = "parity-scale-codec", version = "1.0.0", default-features = false, features = ["derive"] } +serde = { version = "1.0.101", optional = true } +runtime-io = { package = "sr-io", path = "../../core/sr-io", default-features = false } +sr-primitives = { path = "../../core/sr-primitives", default-features = false } +rstd = { package = "sr-std", path = "../../core/sr-std", default-features = false } +support = { package = "srml-support", path = "../support", default-features = false } +system = { package = "srml-system", path = "../system", default-features = false } + +[dev-dependencies] +balances = { package = "srml-balances", path = "../balances" } +primitives = { package = "substrate-primitives", path = "../../core/primitives" } + +[features] +default = ["std"] +std = [ + "codec/std", + "serde", + "runtime-io/std", + "sr-primitives/std", + "rstd/std", + "support/std", + "system/std", +] diff --git a/srml/scored-pool/src/lib.rs b/srml/scored-pool/src/lib.rs new file mode 100644 index 0000000000000000000000000000000000000000..609f17b4572e688aef4dc36ae139d712579418af --- /dev/null +++ b/srml/scored-pool/src/lib.rs @@ -0,0 +1,452 @@ +// Copyright 2019 Parity Technologies (UK) Ltd. +// This file is part of Substrate. + +// Substrate 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. + +// Substrate 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 Substrate. If not, see . + +//! # Scored Pool Module +//! +//! The module maintains a scored membership pool. Each entity in the +//! pool can be attributed a `Score`. From this pool a set `Members` +//! is constructed. This set contains the `MemberCount` highest +//! scoring entities. Unscored entities are never part of `Members`. +//! +//! If an entity wants to be part of the pool a deposit is required. +//! The deposit is returned when the entity withdraws or when it +//! is removed by an entity with the appropriate authority. +//! +//! Every `Period` blocks the set of `Members` is refreshed from the +//! highest scoring members in the pool and, no matter if changes +//! occurred, `T::MembershipChanged::set_members_sorted` is invoked. +//! On first load `T::MembershipInitialized::initialize_members` is +//! invoked with the initial `Members` set. +//! +//! It is possible to withdraw candidacy/resign your membership at any +//! time. If an entity is currently a member, this results in removal +//! from the `Pool` and `Members`; the entity is immediately replaced +//! by the next highest scoring candidate in the pool, if available. +//! +//! - [`scored_pool::Trait`](./trait.Trait.html) +//! - [`Call`](./enum.Call.html) +//! - [`Module`](./struct.Module.html) +//! +//! ## Interface +//! +//! ### Public Functions +//! +//! - `submit_candidacy` - Submit candidacy to become a member. Requires a deposit. +//! - `withdraw_candidacy` - Withdraw candidacy. Deposit is returned. +//! - `score` - Attribute a quantitative score to an entity. +//! - `kick` - Remove an entity from the pool and members. Deposit is returned. +//! - `change_member_count` - Changes the amount of candidates taken into `Members`. +//! +//! ## Usage +//! +//! ``` +//! use support::{decl_module, dispatch::Result}; +//! use system::ensure_signed; +//! use srml_scored_pool::{self as scored_pool}; +//! +//! pub trait Trait: scored_pool::Trait {} +//! +//! decl_module! { +//! pub struct Module for enum Call where origin: T::Origin { +//! pub fn candidate(origin) -> Result { +//! let who = ensure_signed(origin)?; +//! +//! let _ = >::submit_candidacy( +//! T::Origin::from(Some(who.clone()).into()) +//! ); +//! Ok(()) +//! } +//! } +//! } +//! +//! # fn main() { } +//! ``` +//! +//! ## Dependencies +//! +//! This module depends on the [System module](../srml_system/index.html). + +// Ensure we're `no_std` when compiling for Wasm. +#![cfg_attr(not(feature = "std"), no_std)] + +#[cfg(test)] +mod mock; + +#[cfg(test)] +mod tests; + +use codec::FullCodec; +use rstd::prelude::*; +use support::{ + decl_module, decl_storage, decl_event, ensure, + traits::{ChangeMembers, InitializeMembers, Currency, Get, ReservableCurrency}, +}; +use system::{self, ensure_root, ensure_signed}; +use sr_primitives::{ + traits::{EnsureOrigin, SimpleArithmetic, MaybeSerializeDebug, Zero, StaticLookup}, +}; + +type BalanceOf = <>::Currency as Currency<::AccountId>>::Balance; +type PoolT = Vec<(::AccountId, Option<>::Score>)>; + +/// The enum is supplied when refreshing the members set. +/// Depending on the enum variant the corresponding associated +/// type function will be invoked. +enum ChangeReceiver { + /// Should call `T::MembershipInitialized`. + MembershipInitialized, + /// Should call `T::MembershipChanged`. + MembershipChanged, +} + +pub trait Trait: system::Trait { + /// The currency used for deposits. + type Currency: Currency + ReservableCurrency; + + /// The score attributed to a member or candidate. + type Score: SimpleArithmetic + Clone + Copy + Default + FullCodec + MaybeSerializeDebug; + + /// The overarching event type. + type Event: From> + Into<::Event>; + + // The deposit which is reserved from candidates if they want to + // start a candidacy. The deposit gets returned when the candidacy is + // withdrawn or when the candidate is kicked. + type CandidateDeposit: Get>; + + /// Every `Period` blocks the `Members` are filled with the highest scoring + /// members in the `Pool`. + type Period: Get; + + /// The receiver of the signal for when the membership has been initialized. + /// This happens pre-genesis and will usually be the same as `MembershipChanged`. + /// If you need to do something different on initialization, then you can change + /// this accordingly. + type MembershipInitialized: InitializeMembers; + + /// The receiver of the signal for when the members have changed. + type MembershipChanged: ChangeMembers; + + /// Allows a configurable origin type to set a score to a candidate in the pool. + type ScoreOrigin: EnsureOrigin; + + /// Required origin for removing a member (though can always be Root). + /// Configurable origin which enables removing an entity. If the entity + /// is part of the `Members` it is immediately replaced by the next + /// highest scoring candidate, if available. + type KickOrigin: EnsureOrigin; +} + +decl_storage! { + trait Store for Module, I: Instance=DefaultInstance> as ScoredPool { + /// The current pool of candidates, stored as an ordered Vec + /// (ordered descending by score, `None` last, highest first). + Pool get(pool) config(): PoolT; + + /// A Map of the candidates. The information in this Map is redundant + /// to the information in the `Pool`. But the Map enables us to easily + /// check if a candidate is already in the pool, without having to + /// iterate over the entire pool (the `Pool` is not sorted by + /// `T::AccountId`, but by `T::Score` instead). + CandidateExists get(candidate_exists): map T::AccountId => bool; + + /// The current membership, stored as an ordered Vec. + Members get(members): Vec; + + /// Size of the `Members` set. + MemberCount get(member_count) config(): u32; + } + add_extra_genesis { + config(members): Vec; + config(phantom): rstd::marker::PhantomData; + build(|config| { + let mut pool = config.pool.clone(); + + // reserve balance for each candidate in the pool. + // panicking here is ok, since this just happens one time, pre-genesis. + pool + .iter() + .for_each(|(who, _)| { + T::Currency::reserve(&who, T::CandidateDeposit::get()) + .expect("balance too low to create candidacy"); + >::insert(who, true); + }); + + /// Sorts the `Pool` by score in a descending order. Entities which + /// have a score of `None` are sorted to the beginning of the vec. + pool.sort_by_key(|(_, maybe_score)| + Reverse(maybe_score.unwrap_or_default()) + ); + + >::put(&pool); + >::refresh_members(pool, ChangeReceiver::MembershipInitialized); + }) + } +} + +decl_event!( + pub enum Event where + ::AccountId, + { + /// The given member was removed. See the transaction for who. + MemberRemoved, + /// An entity has issued a candidacy. See the transaction for who. + CandidateAdded, + /// An entity withdrew candidacy. See the transaction for who. + CandidateWithdrew, + /// The candidacy was forcefully removed for an entity. + /// See the transaction for who. + CandidateKicked, + /// A score was attributed to the candidate. + /// See the transaction for who. + CandidateScored, + /// Phantom member, never used. + Dummy(rstd::marker::PhantomData<(AccountId, I)>), + } +); + +decl_module! { + pub struct Module, I: Instance=DefaultInstance> + for enum Call + where origin: T::Origin + { + fn deposit_event() = default; + + /// Every `Period` blocks the `Members` set is refreshed from the + /// highest scoring members in the pool. + fn on_initialize(n: T::BlockNumber) { + if n % T::Period::get() == Zero::zero() { + let pool = >::get(); + >::refresh_members(pool, ChangeReceiver::MembershipChanged); + } + } + + /// Add `origin` to the pool of candidates. + /// + /// This results in `CandidateDeposit` being reserved from + /// the `origin` account. The deposit is returned once + /// candidacy is withdrawn by the candidate or the entity + /// is kicked by `KickOrigin`. + /// + /// The dispatch origin of this function must be signed. + /// + /// The `index` parameter of this function must be set to + /// the index of the transactor in the `Pool`. + pub fn submit_candidacy(origin) { + let who = ensure_signed(origin)?; + ensure!(!>::exists(&who), "already a member"); + + let deposit = T::CandidateDeposit::get(); + T::Currency::reserve(&who, deposit) + .map_err(|_| "balance too low to submit candidacy")?; + + // can be inserted as last element in pool, since entities with + // `None` are always sorted to the end. + if let Err(e) = >::append(&[(who.clone(), None)]) { + T::Currency::unreserve(&who, deposit); + return Err(e); + } + + >::insert(&who, true); + + Self::deposit_event(RawEvent::CandidateAdded); + } + + /// An entity withdraws candidacy and gets its deposit back. + /// + /// If the entity is part of the `Members`, then the highest member + /// of the `Pool` that is not currently in `Members` is immediately + /// placed in the set instead. + /// + /// The dispatch origin of this function must be signed. + /// + /// The `index` parameter of this function must be set to + /// the index of the transactor in the `Pool`. + pub fn withdraw_candidacy( + origin, + index: u32 + ) { + let who = ensure_signed(origin)?; + + let pool = >::get(); + Self::ensure_index(&pool, &who, index)?; + + Self::remove_member(pool, who, index)?; + Self::deposit_event(RawEvent::CandidateWithdrew); + } + + /// Kick a member `who` from the set. + /// + /// May only be called from `KickOrigin` or root. + /// + /// The `index` parameter of this function must be set to + /// the index of `dest` in the `Pool`. + pub fn kick( + origin, + dest: ::Source, + index: u32 + ) { + T::KickOrigin::try_origin(origin) + .map(|_| ()) + .or_else(ensure_root) + .map_err(|_| "bad origin")?; + + let who = T::Lookup::lookup(dest)?; + + let pool = >::get(); + Self::ensure_index(&pool, &who, index)?; + + Self::remove_member(pool, who, index)?; + Self::deposit_event(RawEvent::CandidateKicked); + } + + /// Score a member `who` with `score`. + /// + /// May only be called from `ScoreOrigin` or root. + /// + /// The `index` parameter of this function must be set to + /// the index of the `dest` in the `Pool`. + pub fn score( + origin, + dest: ::Source, + index: u32, + score: T::Score + ) { + T::ScoreOrigin::try_origin(origin) + .map(|_| ()) + .or_else(ensure_root) + .map_err(|_| "bad origin")?; + + let who = T::Lookup::lookup(dest)?; + + let mut pool = >::get(); + Self::ensure_index(&pool, &who, index)?; + + pool.remove(index as usize); + + // we binary search the pool (which is sorted descending by score). + // if there is already an element with `score`, we insert + // right before that. if not, the search returns a location + // where we can insert while maintaining order. + let item = (who.clone(), Some(score.clone())); + let location = pool + .binary_search_by_key( + &Reverse(score), + |(_, maybe_score)| Reverse(maybe_score.unwrap_or_default()) + ) + .unwrap_or_else(|l| l); + pool.insert(location, item); + + >::put(&pool); + Self::deposit_event(RawEvent::CandidateScored); + } + + /// Dispatchable call to change `MemberCount`. + /// + /// This will only have an effect the next time a refresh happens + /// (this happens each `Period`). + /// + /// May only be called from root. + pub fn change_member_count(origin, count: u32) { + ensure_root(origin)?; + >::put(&count); + } + } +} + +impl, I: Instance> Module { + + /// Fetches the `MemberCount` highest scoring members from + /// `Pool` and puts them into `Members`. + /// + /// The `notify` parameter is used to deduct which associated + /// type function to invoke at the end of the method. + fn refresh_members( + pool: PoolT, + notify: ChangeReceiver + ) { + let count = >::get(); + + let mut new_members: Vec = pool + .into_iter() + .filter(|(_, score)| score.is_some()) + .take(count as usize) + .map(|(account_id, _)| account_id) + .collect(); + new_members.sort(); + + let old_members = >::get(); + >::put(&new_members); + + match notify { + ChangeReceiver::MembershipInitialized => + T::MembershipInitialized::initialize_members(&new_members), + ChangeReceiver::MembershipChanged => + T::MembershipChanged::set_members_sorted( + &new_members[..], + &old_members[..], + ), + } + } + + /// Removes an entity `remove` at `index` from the `Pool`. + /// + /// If the entity is a member it is also removed from `Members` and + /// the deposit is returned. + fn remove_member( + mut pool: PoolT, + remove: T::AccountId, + index: u32 + ) -> Result<(), &'static str> { + // all callers of this function in this module also check + // the index for validity before calling this function. + // nevertheless we check again here, to assert that there was + // no mistake when invoking this sensible function. + Self::ensure_index(&pool, &remove, index)?; + + pool.remove(index as usize); + >::put(&pool); + + // remove from set, if it was in there + let members = >::get(); + if members.binary_search(&remove).is_ok() { + Self::refresh_members(pool, ChangeReceiver::MembershipChanged); + } + + >::remove(&remove); + + T::Currency::unreserve(&remove, T::CandidateDeposit::get()); + + Self::deposit_event(RawEvent::MemberRemoved); + Ok(()) + } + + /// Checks if `index` is a valid number and if the element found + /// at `index` in `Pool` is equal to `who`. + fn ensure_index( + pool: &PoolT, + who: &T::AccountId, + index: u32 + ) -> Result<(), &'static str> { + ensure!(index < pool.len() as u32, "index out of bounds"); + + let (index_who, _index_score) = &pool[index as usize]; + ensure!(index_who == who, "index does not match requested account"); + + Ok(()) + } +} + diff --git a/srml/scored-pool/src/mock.rs b/srml/scored-pool/src/mock.rs new file mode 100644 index 0000000000000000000000000000000000000000..fd14abd6175a3d5e8f8bd97586c8dcae16081c20 --- /dev/null +++ b/srml/scored-pool/src/mock.rs @@ -0,0 +1,177 @@ +// Copyright 2019 Parity Technologies (UK) Ltd. +// This file is part of Substrate. + +// Substrate 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. + +// Substrate 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 Substrate. If not, see . + +//! Test utilities + +use super::*; + +use std::cell::RefCell; +use support::{impl_outer_origin, parameter_types}; +use primitives::{H256, Blake2Hasher}; +// The testing primitives are very useful for avoiding having to work with signatures +// or public keys. `u64` is used as the `AccountId` and no `Signature`s are requried. +use sr_primitives::{ + Perbill, traits::{BlakeTwo256, IdentityLookup}, testing::Header, +}; +use system::EnsureSignedBy; + +impl_outer_origin! { + pub enum Origin for Test {} +} + +// For testing the module, we construct most of a mock runtime. This means +// first constructing a configuration type (`Test`) which `impl`s each of the +// configuration traits of modules we want to use. +#[derive(Clone, Eq, PartialEq)] +pub struct Test; +parameter_types! { + pub const CandidateDeposit: u64 = 25; + pub const Period: u64 = 4; + + pub const KickOrigin: u64 = 2; + pub const ScoreOrigin: u64 = 3; + + pub const BlockHashCount: u64 = 250; + pub const MaximumBlockWeight: u32 = 1024; + pub const MaximumBlockLength: u32 = 2 * 1024; + pub const AvailableBlockRatio: Perbill = Perbill::one(); + + pub const ExistentialDeposit: u64 = 0; + pub const TransferFee: u64 = 0; + pub const CreationFee: u64 = 0; + pub const TransactionBaseFee: u64 = 0; + pub const TransactionByteFee: u64 = 0; +} + +impl system::Trait for Test { + type Origin = Origin; + type Index = u64; + type BlockNumber = u64; + type Hash = H256; + type Call = (); + type Hashing = BlakeTwo256; + type AccountId = u64; + type Lookup = IdentityLookup; + type Header = Header; + type WeightMultiplierUpdate = (); + type Event = (); + type BlockHashCount = BlockHashCount; + type MaximumBlockWeight = MaximumBlockWeight; + type MaximumBlockLength = MaximumBlockLength; + type AvailableBlockRatio = AvailableBlockRatio; + type Version = (); +} + +impl balances::Trait for Test { + type Balance = u64; + type OnFreeBalanceZero = (); + type OnNewAccount = (); + type Event = (); + type TransactionPayment = (); + type TransferPayment = (); + type DustRemoval = (); + type ExistentialDeposit = ExistentialDeposit; + type TransferFee = TransferFee; + type CreationFee = CreationFee; + type TransactionBaseFee = TransactionBaseFee; + type TransactionByteFee = TransactionByteFee; + type WeightToFee = (); +} + +thread_local! { + pub static MEMBERS: RefCell> = RefCell::new(vec![]); +} + +pub struct TestChangeMembers; +impl ChangeMembers for TestChangeMembers { + fn change_members_sorted(incoming: &[u64], outgoing: &[u64], new: &[u64]) { + let mut old_plus_incoming = MEMBERS.with(|m| m.borrow().to_vec()); + old_plus_incoming.extend_from_slice(incoming); + old_plus_incoming.sort(); + + let mut new_plus_outgoing = new.to_vec(); + new_plus_outgoing.extend_from_slice(outgoing); + new_plus_outgoing.sort(); + + assert_eq!(old_plus_incoming, new_plus_outgoing); + + MEMBERS.with(|m| *m.borrow_mut() = new.to_vec()); + } +} + +impl InitializeMembers for TestChangeMembers { + fn initialize_members(new_members: &[u64]) { + MEMBERS.with(|m| *m.borrow_mut() = new_members.to_vec()); + } +} + +impl Trait for Test { + type Event = (); + type KickOrigin = EnsureSignedBy; + type MembershipInitialized = TestChangeMembers; + type MembershipChanged = TestChangeMembers; + type Currency = balances::Module; + type CandidateDeposit = CandidateDeposit; + type Period = Period; + type Score = u64; + type ScoreOrigin = EnsureSignedBy; +} + +// This function basically just builds a genesis storage key/value store according to +// our desired mockup. +pub fn new_test_ext() -> runtime_io::TestExternalities { + let mut t = system::GenesisConfig::default().build_storage::().unwrap(); + // We use default for brevity, but you can configure as desired if needed. + balances::GenesisConfig:: { + balances: vec![ + (5, 500_000), + (10, 500_000), + (15, 500_000), + (20, 500_000), + (31, 500_000), + (40, 500_000), + (99, 1), + ], + vesting: vec![], + }.assimilate_storage(&mut t).unwrap(); + GenesisConfig::{ + pool: vec![ + (5, None), + (10, Some(1)), + (20, Some(2)), + (31, Some(2)), + (40, Some(3)), + ], + member_count: 2, + .. Default::default() + }.assimilate_storage(&mut t).unwrap(); + t.into() +} + +/// Fetch an entity from the pool, if existent. +pub fn fetch_from_pool(who: u64) -> Option<(u64, Option)> { + >::pool() + .into_iter() + .find(|item| item.0 == who) +} + +/// Find an entity in the pool. +/// Returns its position in the `Pool` vec, if existent. +pub fn find_in_pool(who: u64) -> Option { + >::pool() + .into_iter() + .position(|item| item.0 == who) +} diff --git a/srml/scored-pool/src/tests.rs b/srml/scored-pool/src/tests.rs new file mode 100644 index 0000000000000000000000000000000000000000..740e707ce0529e6afabddd3d713a03bbfcf11170 --- /dev/null +++ b/srml/scored-pool/src/tests.rs @@ -0,0 +1,283 @@ +// Copyright 2019 Parity Technologies (UK) Ltd. +// This file is part of Substrate. + +// Substrate 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. + +// Substrate 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 Substrate. If not, see . + +//! Tests for the module. + +use super::*; +use mock::*; + +use support::{assert_ok, assert_noop}; +use runtime_io::with_externalities; +use sr_primitives::traits::OnInitialize; + +type ScoredPool = Module; +type System = system::Module; +type Balances = balances::Module; + +const OOB_ERR: &str = "index out of bounds"; +const INDEX_ERR: &str = "index does not match requested account"; + +#[test] +fn query_membership_works() { + with_externalities(&mut new_test_ext(), || { + assert_eq!(ScoredPool::members(), vec![20, 40]); + assert_eq!(Balances::reserved_balance(&31), CandidateDeposit::get()); + assert_eq!(Balances::reserved_balance(&40), CandidateDeposit::get()); + assert_eq!(MEMBERS.with(|m| m.borrow().clone()), vec![20, 40]); + }); +} + +#[test] +fn submit_candidacy_must_not_work() { + with_externalities(&mut new_test_ext(), || { + assert_noop!( + ScoredPool::submit_candidacy(Origin::signed(99)), + "balance too low to submit candidacy" + ); + assert_noop!( + ScoredPool::submit_candidacy(Origin::signed(40)), + "already a member" + ); + }); +} + +#[test] +fn submit_candidacy_works() { + with_externalities(&mut new_test_ext(), || { + // given + let who = 15; + + // when + assert_ok!(ScoredPool::submit_candidacy(Origin::signed(who))); + assert_eq!(fetch_from_pool(15), Some((who, None))); + + // then + assert_eq!(Balances::reserved_balance(&who), CandidateDeposit::get()); + }); +} + +#[test] +fn scoring_works() { + with_externalities(&mut new_test_ext(), || { + // given + let who = 15; + let score = 99; + assert_ok!(ScoredPool::submit_candidacy(Origin::signed(who))); + + // when + let index = find_in_pool(who).expect("entity must be in pool") as u32; + assert_ok!(ScoredPool::score(Origin::signed(ScoreOrigin::get()), who, index, score)); + + // then + assert_eq!(fetch_from_pool(who), Some((who, Some(score)))); + assert_eq!(find_in_pool(who), Some(0)); // must be first element, since highest scored + }); +} + +#[test] +fn scoring_same_element_with_same_score_works() { + with_externalities(&mut new_test_ext(), || { + // given + let who = 31; + let index = find_in_pool(who).expect("entity must be in pool") as u32; + let score = 2; + + // when + assert_ok!(ScoredPool::score(Origin::signed(ScoreOrigin::get()), who, index, score)); + + // then + assert_eq!(fetch_from_pool(who), Some((who, Some(score)))); + + // must have been inserted right before the `20` element which is + // of the same score as `31`. so sort order is maintained. + assert_eq!(find_in_pool(who), Some(1)); + }); +} + +#[test] +fn kicking_works_only_for_authorized() { + with_externalities(&mut new_test_ext(), || { + let who = 40; + let index = find_in_pool(who).expect("entity must be in pool") as u32; + assert_noop!(ScoredPool::kick(Origin::signed(99), who, index), "bad origin"); + }); +} + +#[test] +fn kicking_works() { + with_externalities(&mut new_test_ext(), || { + // given + let who = 40; + assert_eq!(Balances::reserved_balance(&who), CandidateDeposit::get()); + assert_eq!(find_in_pool(who), Some(0)); + + // when + let index = find_in_pool(who).expect("entity must be in pool") as u32; + assert_ok!(ScoredPool::kick(Origin::signed(KickOrigin::get()), who, index)); + + // then + assert_eq!(find_in_pool(who), None); + assert_eq!(ScoredPool::members(), vec![20, 31]); + assert_eq!(MEMBERS.with(|m| m.borrow().clone()), ScoredPool::members()); + assert_eq!(Balances::reserved_balance(&who), 0); // deposit must have been returned + }); +} + +#[test] +fn unscored_entities_must_not_be_used_for_filling_members() { + with_externalities(&mut new_test_ext(), || { + // given + // we submit a candidacy, score will be `None` + assert_ok!(ScoredPool::submit_candidacy(Origin::signed(15))); + + // when + // we remove every scored member + ScoredPool::pool() + .into_iter() + .for_each(|(who, score)| { + if let Some(_) = score { + let index = find_in_pool(who).expect("entity must be in pool") as u32; + assert_ok!(ScoredPool::kick(Origin::signed(KickOrigin::get()), who, index)); + } + }); + + // then + // the `None` candidates should not have been filled in + assert_eq!(ScoredPool::members(), vec![]); + assert_eq!(MEMBERS.with(|m| m.borrow().clone()), ScoredPool::members()); + }); +} + +#[test] +fn refreshing_works() { + with_externalities(&mut new_test_ext(), || { + // given + let who = 15; + assert_ok!(ScoredPool::submit_candidacy(Origin::signed(who))); + let index = find_in_pool(who).expect("entity must be in pool") as u32; + assert_ok!(ScoredPool::score(Origin::signed(ScoreOrigin::get()), who, index, 99)); + + // when + ScoredPool::refresh_members(ScoredPool::pool(), ChangeReceiver::MembershipChanged); + + // then + assert_eq!(ScoredPool::members(), vec![15, 40]); + assert_eq!(MEMBERS.with(|m| m.borrow().clone()), ScoredPool::members()); + }); +} + +#[test] +fn refreshing_happens_every_period() { + with_externalities(&mut new_test_ext(), || { + // given + System::set_block_number(1); + assert_ok!(ScoredPool::submit_candidacy(Origin::signed(15))); + let index = find_in_pool(15).expect("entity must be in pool") as u32; + assert_ok!(ScoredPool::score(Origin::signed(ScoreOrigin::get()), 15, index, 99)); + assert_eq!(ScoredPool::members(), vec![20, 40]); + + // when + System::set_block_number(4); + ScoredPool::on_initialize(4); + + // then + assert_eq!(ScoredPool::members(), vec![15, 40]); + assert_eq!(MEMBERS.with(|m| m.borrow().clone()), ScoredPool::members()); + }); +} + +#[test] +fn withdraw_candidacy_must_only_work_for_members() { + with_externalities(&mut new_test_ext(), || { + let who = 77; + let index = 0; + assert_noop!( ScoredPool::withdraw_candidacy(Origin::signed(who), index), INDEX_ERR); + }); +} + +#[test] +fn oob_index_should_abort() { + with_externalities(&mut new_test_ext(), || { + let who = 40; + let oob_index = ScoredPool::pool().len() as u32; + assert_noop!(ScoredPool::withdraw_candidacy(Origin::signed(who), oob_index), OOB_ERR); + assert_noop!(ScoredPool::score(Origin::signed(ScoreOrigin::get()), who, oob_index, 99), OOB_ERR); + assert_noop!(ScoredPool::kick(Origin::signed(KickOrigin::get()), who, oob_index), OOB_ERR); + }); +} + +#[test] +fn index_mismatches_should_abort() { + with_externalities(&mut new_test_ext(), || { + let who = 40; + let index = 3; + assert_noop!(ScoredPool::withdraw_candidacy(Origin::signed(who), index), INDEX_ERR); + assert_noop!(ScoredPool::score(Origin::signed(ScoreOrigin::get()), who, index, 99), INDEX_ERR); + assert_noop!(ScoredPool::kick(Origin::signed(KickOrigin::get()), who, index), INDEX_ERR); + }); +} + +#[test] +fn withdraw_unscored_candidacy_must_work() { + with_externalities(&mut new_test_ext(), || { + // given + let who = 5; + + // when + let index = find_in_pool(who).expect("entity must be in pool") as u32; + assert_ok!(ScoredPool::withdraw_candidacy(Origin::signed(who), index)); + + // then + assert_eq!(fetch_from_pool(5), None); + }); +} + +#[test] +fn withdraw_scored_candidacy_must_work() { + with_externalities(&mut new_test_ext(), || { + // given + let who = 40; + assert_eq!(Balances::reserved_balance(&who), CandidateDeposit::get()); + + // when + let index = find_in_pool(who).expect("entity must be in pool") as u32; + assert_ok!(ScoredPool::withdraw_candidacy(Origin::signed(who), index)); + + // then + assert_eq!(fetch_from_pool(who), None); + assert_eq!(ScoredPool::members(), vec![20, 31]); + assert_eq!(Balances::reserved_balance(&who), 0); + }); +} + +#[test] +fn candidacy_resubmitting_works() { + with_externalities(&mut new_test_ext(), || { + // given + let who = 15; + + // when + assert_ok!(ScoredPool::submit_candidacy(Origin::signed(who))); + assert_eq!(ScoredPool::candidate_exists(who), true); + let index = find_in_pool(who).expect("entity must be in pool") as u32; + assert_ok!(ScoredPool::withdraw_candidacy(Origin::signed(who), index)); + assert_eq!(ScoredPool::candidate_exists(who), false); + assert_ok!(ScoredPool::submit_candidacy(Origin::signed(who))); + + // then + assert_eq!(ScoredPool::candidate_exists(who), true); + }); +} diff --git a/srml/session/Cargo.toml b/srml/session/Cargo.toml index d084ab4261b3cbd977872191589173d72c12573b..b114755ad91c203f9c1664bb32568edb9084c572 100644 --- a/srml/session/Cargo.toml +++ b/srml/session/Cargo.toml @@ -5,21 +5,23 @@ authors = ["Parity Technologies "] edition = "2018" [dependencies] -serde = { version = "1.0", optional = true } -safe-mix = { version = "1.0", default-features = false} +serde = { version = "1.0.101", optional = true } +safe-mix = { version = "1.0.0", default-features = false } codec = { package = "parity-scale-codec", version = "1.0.0", default-features = false, features = ["derive"] } rstd = { package = "sr-std", path = "../../core/sr-std", default-features = false } sr-primitives = { path = "../../core/sr-primitives", default-features = false } -srml-support = { path = "../support", default-features = false } +sr-staking-primitives = { path = "../../core/sr-staking-primitives", default-features = false } +support = { package = "srml-support", path = "../support", default-features = false } system = { package = "srml-system", path = "../system", default-features = false } timestamp = { package = "srml-timestamp", path = "../timestamp", default-features = false } substrate-trie = { path = "../../core/trie", default-features = false, optional = true } -runtime_io = { package = "sr-io", path = "../../core/sr-io", default-features = false } +runtime-io ={ package = "sr-io", path = "../../core/sr-io", default-features = false } +impl-trait-for-tuples = "0.1.2" [dev-dependencies] primitives = { package = "substrate-primitives", path = "../../core/primitives" } app-crypto = { package = "substrate-application-crypto", path = "../../core/application-crypto" } -lazy_static = "1.0" +lazy_static = "1.4.0" [features] default = ["std", "historical"] @@ -29,8 +31,10 @@ std = [ "safe-mix/std", "codec/std", "rstd/std", - "srml-support/std", + "support/std", "sr-primitives/std", + "sr-staking-primitives/std", "timestamp/std", - "substrate-trie/std" + "substrate-trie/std", + "runtime-io/std", ] diff --git a/srml/session/src/historical.rs b/srml/session/src/historical.rs index c0ffdeb464eb390f725a95fe3152efc4761b9a6e..24821a03932600308557f3c3ad951babf61a0600 100644 --- a/srml/session/src/historical.rs +++ b/srml/session/src/historical.rs @@ -29,14 +29,14 @@ use rstd::prelude::*; use codec::{Encode, Decode}; use sr_primitives::KeyTypeId; use sr_primitives::traits::{Convert, OpaqueKeys, Hash as HashT}; -use srml_support::{ - StorageValue, StorageMap, decl_module, decl_storage, -}; -use srml_support::{Parameter, print}; +use support::{decl_module, decl_storage}; +use support::{Parameter, print}; use substrate_trie::{MemoryDB, Trie, TrieMut, Recorder, EMPTY_PREFIX}; use substrate_trie::trie_types::{TrieDBMut, TrieDB}; use super::{SessionIndex, Module as SessionModule}; +type ValidatorCount = u32; + /// Trait necessary for the historical module. pub trait Trait: super::Trait { /// Full identification of the validator. @@ -55,8 +55,8 @@ pub trait Trait: super::Trait { decl_storage! { trait Store for Module as Session { - /// Mapping from historical session indices to session-data root hash. - HistoricalSessions get(historical_root): map SessionIndex => Option; + /// Mapping from historical session indices to session-data root hash and validator count. + HistoricalSessions get(historical_root): map SessionIndex => Option<(T::Hash, ValidatorCount)>; /// Queued full identifications for queued sessions whose validators have become obsolete. CachedObsolete get(cached_obsolete): map SessionIndex => Option>; @@ -121,8 +121,9 @@ impl crate::OnSessionEnding for NoteHistoricalRoot< // do all of this _before_ calling the other `on_session_ending` impl // so that we have e.g. correct exposures from the _current_. + let count = >::validators().len() as u32; match ProvingTrie::::generate_for(ending) { - Ok(trie) => >::insert(ending, &trie.root), + Ok(trie) => >::insert(ending, &(trie.root, count)), Err(reason) => { print("Failed to generate historical ancestry-inclusion proof."); print(reason); @@ -274,11 +275,11 @@ pub struct Proof { trie_nodes: Vec>, } -impl> srml_support::traits::KeyOwnerProofSystem<(KeyTypeId, D)> +impl> support::traits::KeyOwnerProofSystem<(KeyTypeId, D)> for Module { type Proof = Proof; - type FullIdentification = IdentificationTuple; + type IdentificationTuple = IdentificationTuple; fn prove(key: (KeyTypeId, D)) -> Option { let session = >::current_index(); @@ -300,7 +301,7 @@ impl> srml_support::traits::KeyOwnerProofSystem<(KeyTyp T::FullIdentificationOf::convert(owner.clone()).map(move |id| (owner, id)) ) } else { - let root = >::get(&proof.session)?; + let (root, _) = >::get(&proof.session)?; let trie = ProvingTrie::::from_nodes(root, &proof.trie_nodes); trie.query(id, data.as_ref()) @@ -318,7 +319,7 @@ mod tests { NEXT_VALIDATORS, force_new_session, set_next_validators, Test, System, Session, }; - use srml_support::traits::KeyOwnerProofSystem; + use support::traits::KeyOwnerProofSystem; type Historical = Module; diff --git a/srml/session/src/lib.rs b/srml/session/src/lib.rs index 53c5c9b394f8b39e4c0b65bbc356bc2222eaac5d..208be4664aa6e03d6f35d326a5b41825138f9c44 100644 --- a/srml/session/src/lib.rs +++ b/srml/session/src/lib.rs @@ -121,14 +121,15 @@ use rstd::{prelude::*, marker::PhantomData, ops::{Sub, Rem}}; use codec::Decode; -use sr_primitives::{KeyTypeId, AppKey}; +use sr_primitives::{KeyTypeId, Perbill, RuntimeAppPublic}; use sr_primitives::weights::SimpleDispatchInfo; use sr_primitives::traits::{Convert, Zero, Member, OpaqueKeys}; -use srml_support::{ - dispatch::Result, ConsensusEngineId, StorageValue, StorageDoubleMap, for_each_tuple, - decl_module, decl_event, decl_storage, +use sr_staking_primitives::SessionIndex; +use support::{ + dispatch::Result, ConsensusEngineId, decl_module, decl_event, + decl_storage, }; -use srml_support::{ensure, traits::{OnFreeBalanceZero, Get, FindAuthor}, Parameter}; +use support::{ensure, traits::{OnFreeBalanceZero, Get, FindAuthor}, Parameter}; use system::{self, ensure_signed}; #[cfg(test)] @@ -137,9 +138,6 @@ mod mock; #[cfg(feature = "historical")] pub mod historical; -/// Simple index type with which we can count sessions. -pub type SessionIndex = u32; - /// Decides whether the session should be ended. pub trait ShouldEndSession { /// Return `true` if the session should be ended. @@ -168,9 +166,16 @@ impl< } /// An event handler for when the session is ending. +/// TODO [slashing] consider renaming to OnSessionStarting pub trait OnSessionEnding { /// Handle the fact that the session is ending, and optionally provide the new validator set. /// + /// Even if the validator-set is the same as before, if any underlying economic + /// conditions have changed (i.e. stake-weights), the new validator set must be returned. + /// This is necessary for consensus engines making use of the session module to + /// issue a validator-set change so misbehavior can be provably associated with the new + /// economic conditions as opposed to the old. + /// /// `ending_index` is the index of the currently ending session. /// The returned validator set, if any, will not be applied until `will_apply_at`. /// `will_apply_at` is guaranteed to be at least `ending_index + 1`, since session indices don't @@ -185,64 +190,112 @@ impl OnSessionEnding for () { fn on_session_ending(_: SessionIndex, _: SessionIndex) -> Option> { None } } -/// Handler for when a session keys set changes. +/// Handler for session lifecycle events. pub trait SessionHandler { - /// Session set has changed; act appropriately. + /// The given validator set will be used for the genesis session. + /// It is guaranteed that the given validator set will also be used + /// for the second session, therefore the first call to `on_new_session` + /// should provide the same validator set. + fn on_genesis_session(validators: &[(ValidatorId, Ks)]); + + /// Session set has changed; act appropriately. Note that this can be called + /// before initialization of your module. + /// + /// `changed` is true whenever any of the session keys or underlying economic + /// identities or weightings behind those keys has changed. fn on_new_session( changed: bool, validators: &[(ValidatorId, Ks)], queued_validators: &[(ValidatorId, Ks)], ); + /// A notification for end of the session. + /// + /// Note it is triggered before any `OnSessionEnding` handlers, + /// so we can still affect the validator set. + fn on_before_session_ending() {} + /// A validator got disabled. Act accordingly until a new session begins. fn on_disabled(validator_index: usize); } -/// One session-key type handler. +/// A session handler for specific key type. pub trait OneSessionHandler { /// The key type expected. - type Key: Decode + Default + AppKey; + type Key: Decode + Default + RuntimeAppPublic; - fn on_new_session<'a, I: 'a>(changed: bool, validators: I, queued_validators: I) + fn on_genesis_session<'a, I: 'a>(validators: I) where I: Iterator, ValidatorId: 'a; - fn on_disabled(i: usize); + + /// Session set has changed; act appropriately. Note that this can be called + /// before initialization of your module. + /// + /// `changed` is true when at least one of the session keys + /// or the underlying economic identities/distribution behind one the + /// session keys has changed, false otherwise. + /// + /// The `validators` are the validators of the incoming session, and `queued_validators` + /// will follow. + fn on_new_session<'a, I: 'a>( + changed: bool, + validators: I, + queued_validators: I, + ) where I: Iterator, ValidatorId: 'a; + + + /// A notification for end of the session. + /// + /// Note it is triggered before any `OnSessionEnding` handlers, + /// so we can still affect the validator set. + fn on_before_session_ending() {} + + /// A validator got disabled. Act accordingly until a new session begins. + fn on_disabled(_validator_index: usize); } -macro_rules! impl_session_handlers { - () => ( - impl SessionHandler for () { - fn on_new_session(_: bool, _: &[(AId, Ks)], _: &[(AId, Ks)]) {} - fn on_disabled(_: usize) {} - } - ); +#[impl_trait_for_tuples::impl_for_tuples(30)] +#[tuple_types_no_default_trait_bound] +impl SessionHandler for Tuple { + for_tuples!( where #( Tuple: OneSessionHandler )* ); - ( $($t:ident)* ) => { - impl ),*> SessionHandler for ( $( $t , )* ) { - fn on_new_session( - changed: bool, - validators: &[(AId, Ks)], - queued_validators: &[(AId, Ks)], - ) { - $( - let our_keys: Box> = Box::new(validators.iter() - .map(|k| (&k.0, k.1.get::<$t::Key>(<$t::Key as AppKey>::ID) - .unwrap_or_default()))); - let queued_keys: Box> = Box::new(queued_validators.iter() - .map(|k| (&k.0, k.1.get::<$t::Key>(<$t::Key as AppKey>::ID) - .unwrap_or_default()))); - $t::on_new_session(changed, our_keys, queued_keys); - )* - } - fn on_disabled(i: usize) { - $( - $t::on_disabled(i); - )* - } - } + fn on_genesis_session(validators: &[(AId, Ks)]) { + for_tuples!( + #( + let our_keys: Box> = Box::new(validators.iter() + .map(|k| (&k.0, k.1.get::(::ID) + .unwrap_or_default()))); + + Tuple::on_genesis_session(our_keys); + )* + ) + } + + fn on_new_session( + changed: bool, + validators: &[(AId, Ks)], + queued_validators: &[(AId, Ks)], + ) { + for_tuples!( + #( + let our_keys: Box> = Box::new(validators.iter() + .map(|k| (&k.0, k.1.get::(::ID) + .unwrap_or_default()))); + let queued_keys: Box> = Box::new(queued_validators.iter() + .map(|k| (&k.0, k.1.get::(::ID) + .unwrap_or_default()))); + Tuple::on_new_session(changed, our_keys, queued_keys); + )* + ) + } + + fn on_before_session_ending() { + for_tuples!( #( Tuple::on_before_session_ending(); )* ) } -} -for_each_tuple!(impl_session_handlers); + fn on_disabled(i: usize) { + for_tuples!( #( Tuple::on_disabled(i); )* ) + } +} /// Handler for selecting the genesis validator set. pub trait SelectInitialValidators { @@ -281,6 +334,12 @@ pub trait Trait: system::Trait { /// The keys. type Keys: OpaqueKeys + Member + Parameter + Default; + /// The fraction of validators set that is safe to be disabled. + /// + /// After the threshold is reached `disabled` method starts to return true, + /// which in combination with `srml_staking` forces a new era. + type DisabledValidatorsThreshold: Get; + /// Select initial validators. type SelectInitialValidators: SelectInitialValidators; } @@ -295,16 +354,19 @@ decl_storage! { /// Current index of the session. CurrentIndex get(current_index): SessionIndex; - /// True if anything has changed in this session. - Changed: bool; - - /// Queued keys changed. + /// True if the underlying economic identities or weighting behind the validators + /// has changed in the queued validator set. QueuedChanged: bool; /// The queued keys for the next session. When the next session begins, these keys /// will be used to determine the validator's session keys. QueuedKeys get(queued_keys): Vec<(T::ValidatorId, T::Keys)>; + /// Indices of disabled validators. + /// + /// The set is cleared when `on_session_ending` returns a new set of identities. + DisabledValidators get(disabled_validators): Vec; + /// The next session keys for a validator. /// /// The first key is always `DEDUP_KEY_PREFIX` to have all the data in the same branch of @@ -319,38 +381,36 @@ decl_storage! { } add_extra_genesis { config(keys): Vec<(T::ValidatorId, T::Keys)>; - build(| - storage: &mut (sr_primitives::StorageOverlay, sr_primitives::ChildrenStorageOverlay), - config: &GenesisConfig - | { - runtime_io::with_storage(storage, || { - for (who, keys) in config.keys.iter().cloned() { - assert!( - >::load_keys(&who).is_none(), - "genesis config contained duplicate validator {:?}", who, - ); - - >::do_set_keys(&who, keys) - .expect("genesis config must not contain duplicates; qed"); - } + build(|config: &GenesisConfig| { + for (who, keys) in config.keys.iter().cloned() { + assert!( + >::load_keys(&who).is_none(), + "genesis config contained duplicate validator {:?}", who, + ); + + >::do_set_keys(&who, keys) + .expect("genesis config must not contain duplicates; qed"); + } - let initial_validators = T::SelectInitialValidators::select_initial_validators() - .unwrap_or_else(|| config.keys.iter().map(|(ref v, _)| v.clone()).collect()); + let initial_validators = T::SelectInitialValidators::select_initial_validators() + .unwrap_or_else(|| config.keys.iter().map(|(ref v, _)| v.clone()).collect()); - assert!(!initial_validators.is_empty(), "Empty validator set in genesis block!"); + assert!(!initial_validators.is_empty(), "Empty validator set in genesis block!"); - let queued_keys: Vec<_> = initial_validators - .iter() - .cloned() - .map(|v| ( - v.clone(), - >::load_keys(&v).unwrap_or_default(), - )) - .collect(); + let queued_keys: Vec<_> = initial_validators + .iter() + .cloned() + .map(|v| ( + v.clone(), + >::load_keys(&v).unwrap_or_default(), + )) + .collect(); - >::put(initial_validators); - >::put(queued_keys); - }); + // Tell everyone about the genesis session keys + T::SessionHandler::on_genesis_session::(&queued_keys); + + >::put(initial_validators); + >::put(queued_keys); }); } } @@ -394,13 +454,10 @@ decl_module! { Self::do_set_keys(&who, keys)?; - // Something changed. - Changed::put(true); - Ok(()) } - /// Called when a block is finalized. Will rotate session if it is the last + /// Called when a block is initialized. Will rotate session if it is the last /// block of the current session. fn on_initialize(n: T::BlockNumber) { if T::ShouldEndSession::should_end_session(n) { @@ -418,7 +475,9 @@ impl Module { let session_index = CurrentIndex::get(); let changed = QueuedChanged::get(); - let mut next_changed = Changed::take(); + + // Inform the session handlers that a session is going to end. + T::SessionHandler::on_before_session_ending(); // Get queued session keys and validators. let session_keys = >::get(); @@ -427,15 +486,24 @@ impl Module { .collect::>(); >::put(&validators); + if changed { + // reset disabled validators + DisabledValidators::take(); + } + let applied_at = session_index + 2; // Get next validator set. - let maybe_validators = T::OnSessionEnding::on_session_ending(session_index, applied_at); - let next_validators = if let Some(validators) = maybe_validators { - next_changed = true; - validators + let maybe_next_validators = T::OnSessionEnding::on_session_ending(session_index, applied_at); + let (next_validators, next_identities_changed) + = if let Some(validators) = maybe_next_validators + { + // NOTE: as per the documentation on `OnSessionEnding`, we consider + // the validator set as having changed even if the validators are the + // same as before, as underlying economic conditions may have changed. + (validators, true) } else { - >::get() + (>::get(), false) }; // Increment session index. @@ -443,9 +511,34 @@ impl Module { CurrentIndex::put(session_index); // Queue next session keys. - let queued_amalgamated = next_validators.into_iter() - .map(|a| { let k = Self::load_keys(&a).unwrap_or_default(); (a, k) }) - .collect::>(); + let (queued_amalgamated, next_changed) = { + // until we are certain there has been a change, iterate the prior + // validators along with the current and check for changes + let mut changed = next_identities_changed; + + let mut now_session_keys = session_keys.iter(); + let mut check_next_changed = |keys: &T::Keys| { + if changed { return } + // since a new validator set always leads to `changed` starting + // as true, we can ensure that `now_session_keys` and `next_validators` + // have the same length. this function is called once per iteration. + if let Some(&(_, ref old_keys)) = now_session_keys.next() { + if old_keys != keys { + changed = true; + return + } + } + }; + let queued_amalgamated = next_validators.into_iter() + .map(|a| { + let k = Self::load_keys(&a).unwrap_or_default(); + check_next_changed(&k); + (a, k) + }) + .collect::>(); + + (queued_amalgamated, changed) + }; >::put(queued_amalgamated.clone()); QueuedChanged::put(next_changed); @@ -454,18 +547,44 @@ impl Module { Self::deposit_event(Event::NewSession(session_index)); // Tell everyone about the new session keys. - T::SessionHandler::on_new_session::(changed, &session_keys, &queued_amalgamated); + T::SessionHandler::on_new_session::( + changed, + &session_keys, + &queued_amalgamated, + ); } /// Disable the validator of index `i`. - pub fn disable_index(i: usize) { - T::SessionHandler::on_disabled(i); - Changed::put(true); + /// + /// Returns `true` if this causes a `DisabledValidatorsThreshold` of validators + /// to be already disabled. + pub fn disable_index(i: usize) -> bool { + let (fire_event, threshold_reached) = DisabledValidators::mutate(|disabled| { + let i = i as u32; + if let Err(index) = disabled.binary_search(&i) { + let count = >::decode_len().unwrap_or(0) as u32; + let threshold = T::DisabledValidatorsThreshold::get() * count; + disabled.insert(index, i); + (true, disabled.len() as u32 > threshold) + } else { + (false, false) + } + }); + + if fire_event { + T::SessionHandler::on_disabled(i); + } + + threshold_reached } - /// Disable the validator identified by `c`. (If using with the staking module, this would be - /// their *stash* account.) - pub fn disable(c: &T::ValidatorId) -> rstd::result::Result<(), ()> { + /// Disable the validator identified by `c`. (If using with the staking module, + /// this would be their *stash* account.) + /// + /// Returns `Ok(true)` if more than `DisabledValidatorsThreshold` validators in current + /// session is already disabled. + /// If used with the staking module it allows to force a new era in such case. + pub fn disable(c: &T::ValidatorId) -> rstd::result::Result { Self::validators().iter().position(|i| i == c).map(Self::disable_index).ok_or(()) } @@ -505,8 +624,6 @@ impl Module { let key_data = old_keys.get_raw(id); Self::clear_key_owner(id, key_data); } - - Changed::put(true); } } @@ -523,15 +640,15 @@ impl Module { } fn key_owner(id: KeyTypeId, key_data: &[u8]) -> Option { - >::get(DEDUP_KEY_PREFIX, &(id, key_data.to_vec())) + >::get(DEDUP_KEY_PREFIX, (id, key_data)) } fn put_key_owner(id: KeyTypeId, key_data: &[u8], v: &T::ValidatorId) { - >::insert(DEDUP_KEY_PREFIX, &(id, key_data.to_vec()), v) + >::insert(DEDUP_KEY_PREFIX, (id, key_data), v) } fn clear_key_owner(id: KeyTypeId, key_data: &[u8]) { - >::remove(DEDUP_KEY_PREFIX, &(id, key_data.to_vec())); + >::remove(DEDUP_KEY_PREFIX, (id, key_data)); } } @@ -562,7 +679,7 @@ impl> FindAuthor #[cfg(test)] mod tests { use super::*; - use srml_support::assert_ok; + use support::assert_ok; use runtime_io::with_externalities; use primitives::{Blake2Hasher, crypto::key_types::DUMMY}; use sr_primitives::{ @@ -572,6 +689,7 @@ mod tests { use mock::{ NEXT_VALIDATORS, SESSION_CHANGED, TEST_SESSION_CHANGED, authorities, force_new_session, set_next_validators, set_session_length, session_changed, Test, Origin, System, Session, + reset_before_session_end_called, before_session_end_called, }; fn new_test_ext() -> runtime_io::TestExternalities { @@ -619,13 +737,13 @@ mod tests { Session::on_free_balance_zero(&1); assert_eq!(Session::load_keys(&1), None); assert_eq!(Session::key_owner(id, UintAuthorityId(1).get_raw(id)), None); - - assert!(Changed::get()); }) } #[test] fn authorities_should_track_validators() { + reset_before_session_end_called(); + with_externalities(&mut new_test_ext(), || { set_next_validators(vec![1, 2]); force_new_session(); @@ -636,6 +754,8 @@ mod tests { ]); assert_eq!(Session::validators(), vec![1, 2, 3]); assert_eq!(authorities(), vec![UintAuthorityId(1), UintAuthorityId(2), UintAuthorityId(3)]); + assert!(before_session_end_called()); + reset_before_session_end_called(); force_new_session(); initialize_block(2); @@ -645,6 +765,8 @@ mod tests { ]); assert_eq!(Session::validators(), vec![1, 2]); assert_eq!(authorities(), vec![UintAuthorityId(1), UintAuthorityId(2)]); + assert!(before_session_end_called()); + reset_before_session_end_called(); set_next_validators(vec![1, 2, 4]); assert_ok!(Session::set_keys(Origin::signed(4), UintAuthorityId(4).into(), vec![])); @@ -657,6 +779,7 @@ mod tests { ]); assert_eq!(Session::validators(), vec![1, 2]); assert_eq!(authorities(), vec![UintAuthorityId(1), UintAuthorityId(2)]); + assert!(before_session_end_called()); force_new_session(); initialize_block(4); @@ -738,38 +861,63 @@ mod tests { #[test] fn session_changed_flag_works() { + reset_before_session_end_called(); + with_externalities(&mut new_test_ext(), || { TEST_SESSION_CHANGED.with(|l| *l.borrow_mut() = true); force_new_session(); initialize_block(1); assert!(!session_changed()); + assert!(before_session_end_called()); + reset_before_session_end_called(); force_new_session(); initialize_block(2); assert!(!session_changed()); + assert!(before_session_end_called()); + reset_before_session_end_called(); Session::disable_index(0); force_new_session(); initialize_block(3); assert!(!session_changed()); + assert!(before_session_end_called()); + reset_before_session_end_called(); force_new_session(); initialize_block(4); assert!(session_changed()); + assert!(before_session_end_called()); + reset_before_session_end_called(); force_new_session(); initialize_block(5); assert!(!session_changed()); + assert!(before_session_end_called()); + reset_before_session_end_called(); assert_ok!(Session::set_keys(Origin::signed(2), UintAuthorityId(5).into(), vec![])); force_new_session(); initialize_block(6); assert!(!session_changed()); + assert!(before_session_end_called()); + reset_before_session_end_called(); + // changing the keys of a validator leads to change. + assert_ok!(Session::set_keys(Origin::signed(69), UintAuthorityId(69).into(), vec![])); force_new_session(); initialize_block(7); assert!(session_changed()); + assert!(before_session_end_called()); + reset_before_session_end_called(); + + // while changing the keys of a non-validator does not. + force_new_session(); + initialize_block(7); + assert!(!session_changed()); + assert!(before_session_end_called()); + reset_before_session_end_called(); }); } @@ -815,4 +963,22 @@ mod tests { ); }); } + + #[test] + fn return_true_if_more_than_third_is_disabled() { + with_externalities(&mut new_test_ext(), || { + set_next_validators(vec![1, 2, 3, 4, 5, 6, 7]); + force_new_session(); + initialize_block(1); + // apply the new validator set + force_new_session(); + initialize_block(2); + + assert_eq!(Session::disable_index(0), false); + assert_eq!(Session::disable_index(1), false); + assert_eq!(Session::disable_index(2), true); + assert_eq!(Session::disable_index(3), true); + }); + + } } diff --git a/srml/session/src/mock.rs b/srml/session/src/mock.rs index 66bf93032d29f5ed41dd5f657645699d6f163af7..736d3fa4da920fbc9dbafe8349a0bc352b098a7a 100644 --- a/srml/session/src/mock.rs +++ b/srml/session/src/mock.rs @@ -18,12 +18,13 @@ use super::*; use std::cell::RefCell; -use srml_support::{impl_outer_origin, parameter_types}; +use support::{impl_outer_origin, parameter_types}; use primitives::{crypto::key_types::DUMMY, H256}; use sr_primitives::{ Perbill, impl_opaque_keys, traits::{BlakeTwo256, IdentityLookup, ConvertInto}, testing::{Header, UintAuthorityId} }; +use sr_staking_primitives::SessionIndex; impl_opaque_keys! { pub struct MockSessionKeys { @@ -43,6 +44,7 @@ impl_outer_origin! { } thread_local! { + pub static VALIDATORS: RefCell> = RefCell::new(vec![1, 2, 3]); pub static NEXT_VALIDATORS: RefCell> = RefCell::new(vec![1, 2, 3]); pub static AUTHORITIES: RefCell> = RefCell::new(vec![UintAuthorityId(1), UintAuthorityId(2), UintAuthorityId(3)]); @@ -50,6 +52,9 @@ thread_local! { pub static SESSION_LENGTH: RefCell = RefCell::new(2); pub static SESSION_CHANGED: RefCell = RefCell::new(false); pub static TEST_SESSION_CHANGED: RefCell = RefCell::new(false); + pub static DISABLED: RefCell = RefCell::new(false); + // Stores if `on_before_session_end` was called + pub static BEFORE_SESSION_END_CALLED: RefCell = RefCell::new(false); } pub struct TestShouldEndSession; @@ -62,6 +67,7 @@ impl ShouldEndSession for TestShouldEndSession { pub struct TestSessionHandler; impl SessionHandler for TestSessionHandler { + fn on_genesis_session(_validators: &[(u64, T)]) {} fn on_new_session( changed: bool, validators: &[(u64, T)], @@ -74,14 +80,27 @@ impl SessionHandler for TestSessionHandler { .collect() ); } - fn on_disabled(_validator_index: usize) {} + fn on_disabled(_validator_index: usize) { + DISABLED.with(|l| *l.borrow_mut() = true) + } + fn on_before_session_ending() { + BEFORE_SESSION_END_CALLED.with(|b| *b.borrow_mut() = true); + } } pub struct TestOnSessionEnding; impl OnSessionEnding for TestOnSessionEnding { fn on_session_ending(_: SessionIndex, _: SessionIndex) -> Option> { if !TEST_SESSION_CHANGED.with(|l| *l.borrow()) { - Some(NEXT_VALIDATORS.with(|l| l.borrow().clone())) + VALIDATORS.with(|v| { + let mut v = v.borrow_mut(); + *v = NEXT_VALIDATORS.with(|l| l.borrow().clone()); + Some(v.clone()) + }) + } else if DISABLED.with(|l| std::mem::replace(&mut *l.borrow_mut(), false)) { + // If there was a disabled validator, underlying conditions have changed + // so we return `Some`. + Some(VALIDATORS.with(|v| v.borrow().clone())) } else { None } @@ -90,16 +109,13 @@ impl OnSessionEnding for TestOnSessionEnding { #[cfg(feature = "historical")] impl crate::historical::OnSessionEnding for TestOnSessionEnding { - fn on_session_ending(_: SessionIndex, _: SessionIndex) + fn on_session_ending(ending_index: SessionIndex, will_apply_at: SessionIndex) -> Option<(Vec, Vec<(u64, u64)>)> { - if !TEST_SESSION_CHANGED.with(|l| *l.borrow()) { - let last_validators = Session::validators(); - let last_identifications = last_validators.into_iter().map(|v| (v, v)).collect(); - Some((NEXT_VALIDATORS.with(|l| l.borrow().clone()), last_identifications)) - } else { - None - } + let pair_with_ids = |vals: &[u64]| vals.iter().map(|&v| (v, v)).collect::>(); + >::on_session_ending(ending_index, will_apply_at) + .map(|vals| (pair_with_ids(&vals), vals)) + .map(|(ids, vals)| (vals, ids)) } } @@ -123,8 +139,17 @@ pub fn set_next_validators(next: Vec) { NEXT_VALIDATORS.with(|v| *v.borrow_mut() = next); } +pub fn before_session_end_called() -> bool { + BEFORE_SESSION_END_CALLED.with(|b| *b.borrow()) +} + +pub fn reset_before_session_end_called() { + BEFORE_SESSION_END_CALLED.with(|b| *b.borrow_mut() = false); +} + #[derive(Clone, Eq, PartialEq)] pub struct Test; + parameter_types! { pub const BlockHashCount: u64 = 250; pub const MaximumBlockWeight: u32 = 1024; @@ -149,6 +174,7 @@ impl system::Trait for Test { type MaximumBlockWeight = MaximumBlockWeight; type AvailableBlockRatio = AvailableBlockRatio; type MaximumBlockLength = MaximumBlockLength; + type Version = (); } impl timestamp::Trait for Test { @@ -157,6 +183,10 @@ impl timestamp::Trait for Test { type MinimumPeriod = MinimumPeriod; } +parameter_types! { + pub const DisabledValidatorsThreshold: Perbill = Perbill::from_percent(33); +} + impl Trait for Test { type ShouldEndSession = TestShouldEndSession; #[cfg(feature = "historical")] @@ -169,6 +199,7 @@ impl Trait for Test { type Keys = MockSessionKeys; type Event = (); type SelectInitialValidators = (); + type DisabledValidatorsThreshold = DisabledValidatorsThreshold; } #[cfg(feature = "historical")] diff --git a/srml/staking/Cargo.toml b/srml/staking/Cargo.toml index 5428d663f3f44cc7b0ab3c2d8f217dcf1717820d..67f3ab41d6583f73deb70ff2e6b01539e73182c6 100644 --- a/srml/staking/Cargo.toml +++ b/srml/staking/Cargo.toml @@ -5,14 +5,16 @@ authors = ["Parity Technologies "] edition = "2018" [dependencies] -serde = { version = "1.0", optional = true } -safe-mix = { version = "1.0", default-features = false} +serde = { version = "1.0.101", optional = true } +safe-mix = { version = "1.0.0", default-features = false } codec = { package = "parity-scale-codec", version = "1.0.0", default-features = false, features = ["derive"] } substrate-keyring = { path = "../../core/keyring", optional = true } rstd = { package = "sr-std", path = "../../core/sr-std", default-features = false } -runtime_io = { package = "sr-io", path = "../../core/sr-io", default-features = false } +phragmen = { package = "substrate-phragmen", path = "../../core/phragmen", default-features = false } +runtime-io ={ package = "sr-io", path = "../../core/sr-io", default-features = false } sr-primitives = { path = "../../core/sr-primitives", default-features = false } -srml-support = { path = "../support", default-features = false } +sr-staking-primitives = { path = "../../core/sr-staking-primitives", default-features = false } +support = { package = "srml-support", path = "../support", default-features = false } system = { package = "srml-system", path = "../system", default-features = false } session = { package = "srml-session", path = "../session", default-features = false, features = ["historical"] } authorship = { package = "srml-authorship", path = "../authorship", default-features = false } @@ -21,11 +23,10 @@ authorship = { package = "srml-authorship", path = "../authorship", default-feat primitives = { package = "substrate-primitives", path = "../../core/primitives" } balances = { package = "srml-balances", path = "../balances" } timestamp = { package = "srml-timestamp", path = "../timestamp" } -rand = "0.6.5" +srml-staking-reward-curve = { path = "../staking/reward-curve"} [features] equalize = [] -bench = [] default = ["std", "equalize"] std = [ "serde", @@ -33,9 +34,11 @@ std = [ "substrate-keyring", "codec/std", "rstd/std", - "runtime_io/std", - "srml-support/std", + "phragmen/std", + "runtime-io/std", + "support/std", "sr-primitives/std", + "sr-staking-primitives/std", "session/std", "system/std", "authorship/std", diff --git a/srml/staking/reward-curve/Cargo.toml b/srml/staking/reward-curve/Cargo.toml new file mode 100644 index 0000000000000000000000000000000000000000..4fb0ab1672ce0ce670db4a4a8c7f50c63fec1086 --- /dev/null +++ b/srml/staking/reward-curve/Cargo.toml @@ -0,0 +1,17 @@ +[package] +name = "srml-staking-reward-curve" +version = "2.0.0" +authors = ["Parity Technologies "] +edition = "2018" + +[lib] +proc-macro = true + +[dependencies] +syn = { version = "1.0", features = [ "full", "visit" ] } +quote = "1.0" +proc-macro2 = "1.0.4" +proc-macro-crate = "0.1.4" + +[dev-dependencies] +sr-primitives = { path = "../../../core/sr-primitives" } diff --git a/srml/staking/reward-curve/src/lib.rs b/srml/staking/reward-curve/src/lib.rs new file mode 100644 index 0000000000000000000000000000000000000000..7e1f1e6aa945f1b9a961c7b8da547c5248dca6cd --- /dev/null +++ b/srml/staking/reward-curve/src/lib.rs @@ -0,0 +1,416 @@ +extern crate proc_macro; + +mod log; + +use log::log2; +use proc_macro::TokenStream; +use proc_macro2::{TokenStream as TokenStream2, Span}; +use proc_macro_crate::crate_name; +use quote::{quote, ToTokens}; +use std::convert::TryInto; +use syn::parse::{Parse, ParseStream}; + +/// Accepts a number of expressions to create a instance of PiecewiseLinear which represents the +/// NPoS curve (as detailed +/// [here](http://research.web3.foundation/en/latest/polkadot/Token%20Economics/#inflation-model)) +/// for those parameters. Parameters are: +/// - `min_inflation`: the minimal amount to be rewarded between validators, expressed as a fraction +/// of total issuance. Known as `I_0` in the literature. +/// Expressed in millionth, must be between 0 and 1_000_000. +/// +/// - `max_inflation`: the maximum amount to be rewarded between validators, expressed as a fraction +/// of total issuance. This is attained only when `ideal_stake` is achieved. +/// Expressed in millionth, must be between min_inflation and 1_000_000. +/// +/// - `ideal_stake`: the fraction of total issued tokens that should be actively staked behind +/// validators. Known as `x_ideal` in the literature. +/// Expressed in millionth, must be between 0_100_000 and 0_900_000. +/// +/// - `falloff`: Known as `decay_rate` in the literature. A co-efficient dictating the strength of +/// the global incentivisation to get the `ideal_stake`. A higher number results in less typical +/// inflation at the cost of greater volatility for validators. +/// Expressed in millionth, must be between 0 and 1_000_000. +/// +/// - `max_piece_count`: The maximum number of pieces in the curve. A greater number uses more +/// resources but results in higher accuracy. +/// Must be between 2 and 1_000. +/// +/// - `test_precision`: The maximum error allowed in the generated test. +/// Expressed in millionth, must be between 0 and 1_000_000. +/// +/// # Example +/// +/// ``` +/// # fn main() {} +/// use sr_primitives::curve::PiecewiseLinear; +/// +/// srml_staking_reward_curve::build! { +/// const I_NPOS: PiecewiseLinear<'static> = curve!( +/// min_inflation: 0_025_000, +/// max_inflation: 0_100_000, +/// ideal_stake: 0_500_000, +/// falloff: 0_050_000, +/// max_piece_count: 40, +/// test_precision: 0_005_000, +/// ); +/// } +/// ``` +#[proc_macro] +pub fn build(input: TokenStream) -> TokenStream { + let input = syn::parse_macro_input!(input as INposInput); + + let points = compute_points(&input); + + let declaration = generate_piecewise_linear(points); + let test_module = generate_test_module(&input); + + let imports = match crate_name("sr-primitives") { + Ok(sr_primitives) => { + let ident = syn::Ident::new(&sr_primitives, Span::call_site()); + quote!( extern crate #ident as _sr_primitives; ) + }, + Err(e) => syn::Error::new(Span::call_site(), &e).to_compile_error(), + }; + + let const_name = input.ident; + let const_type = input.typ; + + quote!( + const #const_name: #const_type = { + #imports + #declaration + }; + #test_module + ).into() +} + +const MILLION: u32 = 1_000_000; + +mod keyword { + syn::custom_keyword!(curve); + syn::custom_keyword!(min_inflation); + syn::custom_keyword!(max_inflation); + syn::custom_keyword!(ideal_stake); + syn::custom_keyword!(falloff); + syn::custom_keyword!(max_piece_count); + syn::custom_keyword!(test_precision); +} + +struct INposInput { + ident: syn::Ident, + typ: syn::Type, + min_inflation: u32, + ideal_stake: u32, + max_inflation: u32, + falloff: u32, + max_piece_count: u32, + test_precision: u32, +} + +struct Bounds { + min: u32, + min_strict: bool, + max: u32, + max_strict: bool, +} + +impl Bounds { + fn check(&self, value: u32) -> bool { + let wrong = (self.min_strict && value <= self.min) + || (!self.min_strict && value < self.min) + || (self.max_strict && value >= self.max) + || (!self.max_strict && value > self.max); + + !wrong + } +} + +impl core::fmt::Display for Bounds { + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { + write!( + f, + "{}{:07}; {:07}{}", + if self.min_strict { "]" } else { "[" }, + self.min, + self.max, + if self.max_strict { "[" } else { "]" }, + ) + } +} + +fn parse_field(input: ParseStream, bounds: Bounds) + -> syn::Result +{ + ::parse(&input)?; + ::parse(&input)?; + let value_lit = syn::LitInt::parse(&input)?; + let value: u32 = value_lit.base10_parse()?; + if !bounds.check(value) { + return Err(syn::Error::new(value_lit.span(), format!( + "Invalid {}: {}, must be in {}", Token::default().to_token_stream(), value, bounds, + ))); + } + + Ok(value) +} + +impl Parse for INposInput { + fn parse(input: ParseStream) -> syn::Result { + let args_input; + + ::parse(&input)?; + let ident = ::parse(&input)?; + ::parse(&input)?; + let typ = ::parse(&input)?; + ::parse(&input)?; + ::parse(&input)?; + ::parse(&input)?; + syn::parenthesized!(args_input in input); + ::parse(&input)?; + + if !input.is_empty() { + return Err(input.error("expected end of input stream, no token expected")); + } + + let min_inflation = parse_field::(&args_input, Bounds { + min: 0, + min_strict: true, + max: 1_000_000, + max_strict: false, + })?; + ::parse(&args_input)?; + let max_inflation = parse_field::(&args_input, Bounds { + min: min_inflation, + min_strict: true, + max: 1_000_000, + max_strict: false, + })?; + ::parse(&args_input)?; + let ideal_stake = parse_field::(&args_input, Bounds { + min: 0_100_000, + min_strict: false, + max: 0_900_000, + max_strict: false, + })?; + ::parse(&args_input)?; + let falloff = parse_field::(&args_input, Bounds { + min: 0_010_000, + min_strict: false, + max: 1_000_000, + max_strict: false, + })?; + ::parse(&args_input)?; + let max_piece_count = parse_field::(&args_input, Bounds { + min: 2, + min_strict: false, + max: 1_000, + max_strict: false, + })?; + ::parse(&args_input)?; + let test_precision = parse_field::(&args_input, Bounds { + min: 0, + min_strict: false, + max: 1_000_000, + max_strict: false, + })?; + >::parse(&args_input)?; + + if !args_input.is_empty() { + return Err(args_input.error("expected end of input stream, no token expected")); + } + + Ok(Self { + ident, + typ, + min_inflation, + ideal_stake, + max_inflation, + falloff, + max_piece_count, + test_precision, + }) + } +} + +struct INPoS { + i_0: u32, + i_ideal_times_x_ideal: u32, + i_ideal: u32, + x_ideal: u32, + d: u32, +} + +impl INPoS { + fn from_input(input: &INposInput) -> Self { + INPoS { + i_0: input.min_inflation, + i_ideal: (input.max_inflation as u64 * MILLION as u64 / input.ideal_stake as u64) + .try_into().unwrap(), + i_ideal_times_x_ideal: input.max_inflation, + x_ideal: input.ideal_stake, + d: input.falloff, + } + } + + fn compute_opposite_after_x_ideal(&self, y: u32) -> u32 { + if y == self.i_0 { + return u32::max_value(); + } + let log = log2(self.i_ideal_times_x_ideal - self.i_0, y - self.i_0); + + let term: u32 = ((self.d as u64 * log as u64) / 1_000_000).try_into().unwrap(); + + self.x_ideal + term + } +} + +fn compute_points(input: &INposInput) -> Vec<(u32, u32)> { + let inpos = INPoS::from_input(input); + + let mut points = vec![]; + points.push((0, inpos.i_0)); + points.push((inpos.x_ideal, inpos.i_ideal_times_x_ideal)); + + // For each point p: (next_p.0 - p.0) < segment_lenght && (next_p.1 - p.1) < segment_lenght. + // This ensures that the total number of segment doesn't overflow max_piece_count. + let max_length = (input.max_inflation - input.min_inflation + 1_000_000 - inpos.x_ideal) + / (input.max_piece_count - 1); + + let mut delta_y = max_length; + let mut y = input.max_inflation; + + // The algorithm divide the curve in segment with vertical len and horizontal len less + // than `max_length`. This is not very accurate in case of very consequent steep. + while delta_y != 0 { + let next_y = y - delta_y; + + if next_y <= input.min_inflation { + delta_y = delta_y.saturating_sub(1); + continue + } + + let next_x = inpos.compute_opposite_after_x_ideal(next_y); + + if (next_x - points.last().unwrap().0) > max_length { + delta_y = delta_y.saturating_sub(1); + continue + } + + if next_x >= 1_000_000 { + let prev = points.last().unwrap(); + // Compute the y corresponding to x=1_000_000 using the this point and the previous one. + + let delta_y: u32 = ( + (next_x - 1_000_000) as u64 + * (prev.1 - next_y) as u64 + / (next_x - prev.0) as u64 + ).try_into().unwrap(); + + let y = next_y + delta_y; + + points.push((1_000_000, y)); + return points; + } + points.push((next_x, next_y)); + y = next_y; + } + + points.push((1_000_000, inpos.i_0)); + + points +} + +fn generate_piecewise_linear(points: Vec<(u32, u32)>) -> TokenStream2 { + let mut points_tokens = quote!(); + + for (x, y) in points { + let error = || panic!(format!( + "Generated reward curve approximation doesn't fit into [0, 1] -> [0, 1] \ + because of point: + x = {:07} per million + y = {:07} per million", + x, y + )); + + let x_perbill = x.checked_mul(1_000).unwrap_or_else(error); + let y_perbill = y.checked_mul(1_000).unwrap_or_else(error); + + points_tokens.extend(quote!( + ( + _sr_primitives::Perbill::from_parts(#x_perbill), + _sr_primitives::Perbill::from_parts(#y_perbill), + ), + )); + } + + quote!( + _sr_primitives::curve::PiecewiseLinear::<'static> { + points: & [ #points_tokens ], + } + ) +} + +fn generate_test_module(input: &INposInput) -> TokenStream2 { + let inpos = INPoS::from_input(input); + + let ident = &input.ident; + let precision = input.test_precision; + let i_0 = inpos.i_0 as f64/ MILLION as f64; + let i_ideal_times_x_ideal = inpos.i_ideal_times_x_ideal as f64 / MILLION as f64; + let i_ideal = inpos.i_ideal as f64 / MILLION as f64; + let x_ideal = inpos.x_ideal as f64 / MILLION as f64; + let d = inpos.d as f64 / MILLION as f64; + let max_piece_count = input.max_piece_count; + + quote!( + #[cfg(test)] + mod __srml_staking_reward_curve_test_module { + fn i_npos(x: f64) -> f64 { + if x <= #x_ideal { + #i_0 + x * (#i_ideal - #i_0 / #x_ideal) + } else { + #i_0 + (#i_ideal_times_x_ideal - #i_0) * 2_f64.powf((#x_ideal - x) / #d) + } + } + + const MILLION: u32 = 1_000_000; + + #[test] + fn reward_curve_precision() { + for &base in [MILLION, u32::max_value()].into_iter() { + let number_of_check = 100_000.min(base); + for check_index in 0..=number_of_check { + let i = (check_index as u64 * base as u64 / number_of_check as u64) as u32; + let x = i as f64 / base as f64; + let float_res = (i_npos(x) * base as f64).round() as u32; + let int_res = super::#ident.calculate_for_fraction_times_denominator(i, base); + let err = ( + (float_res.max(int_res) - float_res.min(int_res)) as u64 + * MILLION as u64 + / float_res as u64 + ) as u32; + if err > #precision { + panic!(format!("\n\ + Generated reward curve approximation differ from real one:\n\t\ + for i = {} and base = {}, f(i/base) * base = {},\n\t\ + but approximation = {},\n\t\ + err = {:07} millionth,\n\t\ + try increase the number of segment: {} or the test_error: {}.\n", + i, base, float_res, int_res, err, #max_piece_count, #precision + )); + } + } + } + } + + #[test] + fn reward_curve_piece_count() { + assert!( + super::#ident.points.len() as u32 - 1 <= #max_piece_count, + "Generated reward curve approximation is invalid: \ + has more points than specified, please fill an issue." + ); + } + } + ).into() +} diff --git a/srml/staking/reward-curve/src/log.rs b/srml/staking/reward-curve/src/log.rs new file mode 100644 index 0000000000000000000000000000000000000000..1a25dbb98628bd1b526fea508158490945d2a6da --- /dev/null +++ b/srml/staking/reward-curve/src/log.rs @@ -0,0 +1,70 @@ +use std::convert::TryInto; + +/// Return Per-million value. +pub fn log2(p: u32, q: u32) -> u32 { + assert!(p >= q); + assert!(p <= u32::max_value()/2); + + // This restriction should not be mandatory. But function is only tested and used for this. + assert!(p <= 1_000_000); + assert!(q <= 1_000_000); + + if p == q { + return 0 + } + + let mut n = 0u32; + while !(p >= 2u32.pow(n)*q) || !(p < 2u32.pow(n+1)*q) { + n += 1; + } + assert!(p < 2u32.pow(n+1) * q); + + let y_num: u32 = (p - 2u32.pow(n) * q).try_into().unwrap(); + let y_den: u32 = (p + 2u32.pow(n) * q).try_into().unwrap(); + + let _2_div_ln_2 = 2_885_390u32; + + let taylor_term = |k: u32| -> u32 { + if k == 0 { + (_2_div_ln_2 as u128 * (y_num as u128).pow(1) / (y_den as u128).pow(1)) + .try_into().unwrap() + } else { + let mut res = _2_div_ln_2 as u128 * (y_num as u128).pow(3) / (y_den as u128).pow(3); + for _ in 1..k { + res = res * (y_num as u128).pow(2) / (y_den as u128).pow(2); + } + res /= 2 * k as u128 + 1; + + res.try_into().unwrap() + } + }; + + let mut res = n * 1_000_000u32; + let mut k = 0; + loop { + let term = taylor_term(k); + if term == 0 { + break + } + + res += term; + k += 1; + } + + res +} + +#[test] +fn test_log() { + let div = 1_000; + for p in 0..=div { + for q in 1..=p { + let p: u32 = (1_000_000 as u64 * p as u64 / div as u64).try_into().unwrap(); + let q: u32 = (1_000_000 as u64 * q as u64 / div as u64).try_into().unwrap(); + + let res = - (log2(p, q) as i64); + let expected = ((q as f64 / p as f64).log(2.0) * 1_000_000 as f64).round() as i64; + assert!((res - expected).abs() <= 6); + } + } +} diff --git a/srml/staking/reward-curve/tests/test.rs b/srml/staking/reward-curve/tests/test.rs new file mode 100644 index 0000000000000000000000000000000000000000..55a3b7d383e9e618bcce18ee00106f015bee7b3a --- /dev/null +++ b/srml/staking/reward-curve/tests/test.rs @@ -0,0 +1,44 @@ +// Copyright 2019 Parity Technologies (UK) Ltd. +// This file is part of Substrate. + +// Substrate 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. + +// Substrate 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 Substrate. If not, see . + +//! Test crate for srml-staking-reward-curve. Allows to test for procedural macro. +//! See tests directory. + +mod test_small_falloff { + srml_staking_reward_curve::build! { + const REWARD_CURVE: sr_primitives::curve::PiecewiseLinear<'static> = curve!( + min_inflation: 0_020_000, + max_inflation: 0_200_000, + ideal_stake: 0_600_000, + falloff: 0_010_000, + max_piece_count: 200, + test_precision: 0_005_000, + ); + } +} + +mod test_big_falloff { + srml_staking_reward_curve::build! { + const REWARD_CURVE: sr_primitives::curve::PiecewiseLinear<'static> = curve!( + min_inflation: 0_100_000, + max_inflation: 0_400_000, + ideal_stake: 0_400_000, + falloff: 1_000_000, + max_piece_count: 40, + test_precision: 0_005_000, + ); + } +} diff --git a/srml/staking/src/benches.rs b/srml/staking/src/benches.rs deleted file mode 100644 index 6e79ee70a47a26dedd201494e5e92adfb8943293..0000000000000000000000000000000000000000 --- a/srml/staking/src/benches.rs +++ /dev/null @@ -1,195 +0,0 @@ -// Copyright 2019 Parity Technologies -// -// 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. - -//! Benchmarks of the phragmen election algorithm. -//! Note that execution times will not be accurate in an absolute scale, since -//! - Everything is executed in the context of `TestExternalities` -//! - Everything is executed in native environment. -//! -//! Run using: -//! -//! ```zsh -//! cargo bench --features bench --color always -//! ``` - -use test::Bencher; -use runtime_io::with_externalities; -use mock::*; -use super::*; -use rand::{self, Rng}; - -const VALIDATORS: u64 = 1000; -const NOMINATORS: u64 = 10_000; -const EDGES: u64 = 2; -const TO_ELECT: usize = 100; -const STAKE: u64 = 1000; - -fn do_phragmen( - b: &mut Bencher, - num_vals: u64, - num_noms: u64, - count: usize, - votes_per: u64, - eq_iters: usize, - eq_tolerance: u128, -) { - with_externalities(&mut ExtBuilder::default().nominate(false).build(), || { - assert!(num_vals > votes_per); - let rr = |a, b| rand::thread_rng().gen_range(a as usize, b as usize) as u64; - - // prefix to distinguish the validator and nominator account ranges. - let np = 10_000; - - (1 ..= 2*num_vals) - .step_by(2) - .for_each(|acc| bond_validator(acc, STAKE + rr(10, 50))); - - (np ..= (np + 2*num_noms)) - .step_by(2) - .for_each(|acc| { - let mut stashes_to_vote = (1 ..= 2*num_vals) - .step_by(2) - .map(|ctrl| ctrl + 1) - .collect::>(); - let votes = (0 .. votes_per) - .map(|_| { - stashes_to_vote.remove(rr(0, stashes_to_vote.len()) as usize) - }) - .collect::>(); - bond_nominator(acc, STAKE + rr(10, 50), votes); - }); - - b.iter(|| { - let r = phragmen::elect::( - count, - 1_usize, - >::enumerate(), - >::enumerate(), - Staking::slashable_balance_of - ).unwrap(); - - // Do the benchmarking with equalize. - if eq_iters > 0 { - let elected_stashes = r.0; - let assignments = r.1; - - let to_balance = |b: ExtendedBalance| - <::CurrencyToVote as Convert>::convert(b); - let to_votes = |b: Balance| - <::CurrencyToVote as Convert>::convert(b) as ExtendedBalance; - let ratio_of = |b, p| (p as ExtendedBalance).saturating_mul(to_votes(b)) / ACCURACY; - - let assignments_with_stakes = assignments.into_iter().map(|(n, a)|( - n, - Staking::slashable_balance_of(&n), - a.into_iter().map(|(acc, r)| ( - acc.clone(), - r, - to_balance(ratio_of(Staking::slashable_balance_of(&n), r)), - )) - .collect::>>() - )).collect::>)>>(); - - let mut exposures = >::new(); - elected_stashes - .into_iter() - .map(|e| (e, Staking::slashable_balance_of(&e))) - .for_each(|(e, s)| { - let item = Exposure { own: s, total: s, ..Default::default() }; - exposures.insert(e, item); - }); - - for (n, _, assignment) in &assignments_with_stakes { - for (c, _, s) in assignment { - if let Some(expo) = exposures.get_mut(c) { - expo.total = expo.total.saturating_add(*s); - expo.others.push( IndividualExposure { who: n.clone(), value: *s } ); - } - } - } - - let mut assignments_with_votes = assignments_with_stakes.into_iter() - .map(|a| ( - a.0, a.1, - a.2.into_iter() - .map(|e| (e.0, e.1, to_votes(e.2))) - .collect::>() - )) - .collect:: - )>>(); - equalize::(&mut assignments_with_votes, &mut exposures, eq_tolerance, eq_iters); - } - }) - }) -} - -macro_rules! phragmen_benches { - ($($name:ident: $tup:expr,)*) => { - $( - #[bench] - fn $name(b: &mut Bencher) { - let (v, n, t, e, eq_iter, eq_tol) = $tup; - println!(""); - println!( - r#" -++ Benchmark: {} Validators // {} Nominators // {} Edges-per-nominator // {} total edges // -electing {} // Equalize: {} iterations -- {} tolerance"#, - v, n, e, e * n, t, eq_iter, eq_tol, - ); - do_phragmen(b, v, n, t, e, eq_iter, eq_tol); - } - )* - } -} - -phragmen_benches! { - bench_1_1: (VALIDATORS, NOMINATORS, TO_ELECT, EDGES, 0, 0), - bench_1_2: (VALIDATORS*2, NOMINATORS, TO_ELECT, EDGES, 0, 0), - bench_1_3: (VALIDATORS*4, NOMINATORS, TO_ELECT, EDGES, 0, 0), - bench_1_4: (VALIDATORS*8, NOMINATORS, TO_ELECT, EDGES, 0, 0), - bench_1_1_eq: (VALIDATORS, NOMINATORS, TO_ELECT, EDGES, 2, 0), - bench_1_2_eq: (VALIDATORS*2, NOMINATORS, TO_ELECT, EDGES, 2, 0), - bench_1_3_eq: (VALIDATORS*4, NOMINATORS, TO_ELECT, EDGES, 2, 0), - bench_1_4_eq: (VALIDATORS*8, NOMINATORS, TO_ELECT, EDGES, 2, 0), - - bench_0_1: (VALIDATORS, NOMINATORS, TO_ELECT, EDGES, 0, 0), - bench_0_2: (VALIDATORS, NOMINATORS, TO_ELECT * 4, EDGES, 0, 0), - bench_0_3: (VALIDATORS, NOMINATORS, TO_ELECT * 8, EDGES, 0, 0), - bench_0_4: (VALIDATORS, NOMINATORS, TO_ELECT * 16, EDGES , 0, 0), - bench_0_1_eq: (VALIDATORS, NOMINATORS, TO_ELECT, EDGES, 2, 0), - bench_0_2_eq: (VALIDATORS, NOMINATORS, TO_ELECT * 4, EDGES, 2, 0), - bench_0_3_eq: (VALIDATORS, NOMINATORS, TO_ELECT * 8, EDGES, 2, 0), - bench_0_4_eq: (VALIDATORS, NOMINATORS, TO_ELECT * 16, EDGES , 2, 0), - - bench_2_1: (VALIDATORS, NOMINATORS, TO_ELECT, EDGES, 0, 0), - bench_2_2: (VALIDATORS, NOMINATORS*2, TO_ELECT, EDGES, 0, 0), - bench_2_3: (VALIDATORS, NOMINATORS*4, TO_ELECT, EDGES, 0, 0), - bench_2_4: (VALIDATORS, NOMINATORS*8, TO_ELECT, EDGES, 0, 0), - bench_2_1_eq: (VALIDATORS, NOMINATORS, TO_ELECT, EDGES, 2, 0), - bench_2_2_eq: (VALIDATORS, NOMINATORS*2, TO_ELECT, EDGES, 2, 0), - bench_2_3_eq: (VALIDATORS, NOMINATORS*4, TO_ELECT, EDGES, 2, 0), - bench_2_4_eq: (VALIDATORS, NOMINATORS*8, TO_ELECT, EDGES, 2, 0), - - bench_3_1: (VALIDATORS, NOMINATORS, TO_ELECT, EDGES, 0, 0 ), - bench_3_2: (VALIDATORS, NOMINATORS, TO_ELECT, EDGES*2, 0, 0), - bench_3_3: (VALIDATORS, NOMINATORS, TO_ELECT, EDGES*4, 0, 0), - bench_3_4: (VALIDATORS, NOMINATORS, TO_ELECT, EDGES*8, 0, 0), - bench_3_1_eq: (VALIDATORS, NOMINATORS, TO_ELECT, EDGES, 2, 0), - bench_3_2_eq: (VALIDATORS, NOMINATORS, TO_ELECT, EDGES*2, 2, 0), - bench_3_3_eq: (VALIDATORS, NOMINATORS, TO_ELECT, EDGES*4, 2, 0), - bench_3_4_eq: (VALIDATORS, NOMINATORS, TO_ELECT, EDGES*8, 2, 0), -} diff --git a/srml/staking/src/inflation.rs b/srml/staking/src/inflation.rs index 80065886d7cac6a545a33391db4e4c41087e716f..89326b92c0fd11359963b04067c9d741b98a5295 100644 --- a/srml/staking/src/inflation.rs +++ b/srml/staking/src/inflation.rs @@ -18,369 +18,77 @@ //! the total payout for the era given the era duration and the staking rate in NPoS. //! The staking rate in NPoS is the total amount of tokens staked by nominators and validators, //! divided by the total token supply. -//! -//! This payout is computed from the desired yearly inflation `I_NPoS`. -//! -//! `I_NPoS` is defined as such: -//! -//! let's introduce some constant: -//! * `I0` represents a tight upper-bound on our estimate of the operational costs of all -//! validators, expressed as a fraction of the total token supply. I_NPoS must be always -//! superior or equal to this value. -//! * `x_ideal` the ideal staking rate in NPoS. -//! * `i_ideal` the ideal yearly interest rate: the ideal total yearly amount of tokens minted to -//! pay all validators and nominators for NPoS, divided by the total amount of tokens staked by -//! them. `i(x) = I(x)/x` and `i(x_ideal) = i_deal` -//! * `d` decay rate. -//! -//! We define I_NPoS as a linear function from 0 to `x_ideal` and an exponential decrease after -//! `x_ideal` to 1. We choose exponential decrease for `I_NPoS` because this implies an exponential -//! decrease for the yearly interest rate as well, and we want the interest rate to fall sharply -//! beyond `x_ideal` to avoid illiquidity. -//! -//! Function is defined as such: -//! ```nocompile -//! for 0 < x < x_ideal: I_NPoS(x) = I0 + x*(i_ideal - I0/x_ideal) -//! for x_ideal < x < 1: I_NPoS(x) = I0 + (i_ideal*x_ideal - I0)*2^((x_ideal-x)/d) -//! ``` -//! -//! Thus we have the following properties: -//! * `I_NPoS > I0` -//! * `I_NPoS(0) = I0` -//! * `I_NPoS(x_ideal) = max(I_NPoS) = x_ideal*i_ideal` -//! * `i(x)` is monotone decreasing -//! -//! More details can be found [here](http://research.web3.foundation/en/latest/polkadot/Token%20Eco -//! nomics/#inflation-model) - -use sr_primitives::{Perbill, traits::SimpleArithmetic}; - -/// Linear function truncated to positive part `y = max(0, b [+ or -] a*x)` for `P_NPoS` usage. -#[derive(Debug, PartialEq, Eq, Clone, Copy)] -struct Linear { - // Negate the `a*x` term. - negative_a: bool, - // Per-billion representation of `a`, the x coefficient. - a: u32, - // Per-billion representation of `b`, the intercept. - b: u32, -} - -impl Linear { - /// Compute `f(n/d)*d`. This is useful to avoid loss of precision. - fn calculate_for_fraction_times_denominator(&self, n: N, d: N) -> N - where - N: SimpleArithmetic + Clone - { - if self.negative_a { - (Perbill::from_parts(self.b) * d).saturating_sub(Perbill::from_parts(self.a) * n) - } else { - (Perbill::from_parts(self.b) * d).saturating_add(Perbill::from_parts(self.a) * n) - } - } -} - -/// Piecewise Linear function for `P_NPoS` usage -#[derive(Debug, PartialEq, Eq)] -struct PiecewiseLinear { - /// Array of tuples of an abscissa in a per-billion representation and a linear function. - /// - /// Abscissas in the array must be in order from the lowest to the highest. - /// - /// The array defines a piecewise linear function as such: - /// * the n-th segment starts at the abscissa of the n-th element until the abscissa of the - /// n-th + 1 element, and is defined by the linear function of the n-th element - /// * last segment doesn't end - pieces: [(u32, Linear); 20], -} - -impl PiecewiseLinear { - /// Compute `f(n/d)*d`. This is useful to avoid loss of precision. - fn calculate_for_fraction_times_denominator(&self, n: N, d: N) -> N - where - N: SimpleArithmetic + Clone - { - let part = self.pieces.iter() - .take_while(|(abscissa, _)| n > Perbill::from_parts(*abscissa) * d.clone()) - .last() - .unwrap_or(&self.pieces[0]); - - part.1.calculate_for_fraction_times_denominator(n, d) - } -} - -/// Piecewise linear approximation of `I_NPoS`. -/// -/// Using the constants: -/// * `I_0` = 0.025; -/// * `i_ideal` = 0.2; -/// * `x_ideal` = 0.5; -/// * `d` = 0.05; -/// -/// This approximation is tested to be close to real one by an error less than 1% see -/// `i_npos_precision` test. -const I_NPOS: PiecewiseLinear = PiecewiseLinear { - pieces: [ - (0, Linear { negative_a: false, a: 150000000, b: 25000000 }), - (500000000, Linear { negative_a: true, a: 986493987, b: 593246993 }), - (507648979, Linear { negative_a: true, a: 884661327, b: 541551747 }), - (515726279, Linear { negative_a: true, a: 788373842, b: 491893761 }), - (524282719, Linear { negative_a: true, a: 697631517, b: 444319128 }), - (533378749, Linear { negative_a: true, a: 612434341, b: 398876765 }), - (543087019, Linear { negative_a: true, a: 532782338, b: 355618796 }), - (553495919, Linear { negative_a: true, a: 458675508, b: 314600968 }), - (564714479, Linear { negative_a: true, a: 390113843, b: 275883203 }), - (576879339, Linear { negative_a: true, a: 327097341, b: 239530285 }), - (590164929, Linear { negative_a: true, a: 269626004, b: 205612717 }), - (604798839, Linear { negative_a: true, a: 217699848, b: 174207838 }), - (621085859, Linear { negative_a: true, a: 171318873, b: 145401271 }), - (639447429, Linear { negative_a: true, a: 130483080, b: 119288928 }), - (660489879, Linear { negative_a: true, a: 95192479, b: 95979842 }), - (685131379, Linear { negative_a: true, a: 65447076, b: 75600334 }), - (714860569, Linear { negative_a: true, a: 41246910, b: 58300589 }), - (752334749, Linear { negative_a: true, a: 22592084, b: 44265915 }), - (803047659, Linear { negative_a: true, a: 9482996, b: 33738693 }), - (881691659, Linear { negative_a: true, a: 2572702, b: 27645944 }) - ] -}; - -/// Second per year for the Julian year (365.25 days). -const SECOND_PER_YEAR: u32 = 3600*24*36525/100; +use sr_primitives::{Perbill, traits::SimpleArithmetic, curve::PiecewiseLinear}; /// The total payout to all validators (and their nominators) per era. /// -/// Named P_NPoS in the [paper](http://research.web3.foundation/en/latest/polkadot/Token%20Ec -/// onomics/#inflation-model). -/// -/// For x the staking rate in NPoS: `P_NPoS(x) = I_NPoS(x) * current_total_token / era_per_year` -/// i.e. `P_NPoS(x) = I_NPoS(x) * current_total_token * era_duration / year_duration` +/// Defined as such: +/// `payout = yearly_inflation(npos_token_staked / total_tokens) * total_tokans / era_per_year` /// -/// I_NPoS is the desired yearly inflation rate for nominated proof of stake. -pub fn compute_total_payout(npos_token_staked: N, total_tokens: N, era_duration: N) -> N -where - N: SimpleArithmetic + Clone +/// `era_duration` is expressed in millisecond. +pub fn compute_total_payout( + yearly_inflation: &PiecewiseLinear<'static>, + npos_token_staked: N, + total_tokens: N, + era_duration: u64 +) -> N where N: SimpleArithmetic + Clone { - let year_duration: N = SECOND_PER_YEAR.into(); - I_NPOS.calculate_for_fraction_times_denominator(npos_token_staked, total_tokens) - * era_duration / year_duration + // Milliseconds per year for the Julian year (365.25 days). + const MILLISECONDS_PER_YEAR: u64 = 1000 * 3600 * 24 * 36525 / 100; + + Perbill::from_rational_approximation(era_duration as u64, MILLISECONDS_PER_YEAR) + * yearly_inflation.calculate_for_fraction_times_denominator(npos_token_staked, total_tokens) } -#[allow(non_upper_case_globals, non_snake_case)] // To stick with paper notations #[cfg(test)] -mod test_inflation { - use std::convert::TryInto; - - // Function `y = a*x + b` using float used for testing precision of Linear - #[derive(Debug)] - struct LinearFloat { - a: f64, - b: f64, - } - - impl LinearFloat { - fn new(x0: f64, y0: f64, x1: f64, y1: f64) -> Self { - LinearFloat { - a: (y1 - y0) / (x1 - x0), - b: (x0*y1 - x1*y0) / (x0 - x1), - } - } - - fn compute(&self, x: f64) -> f64 { - self.a*x + self.b - } - } - - #[test] - fn linear_float_works() { - assert_eq!(LinearFloat::new(1.0, 2.0, 4.0, 3.0).compute(7.0), 4.0); - } - - // Constants defined in paper - const I_0: f64 = 0.025; - const i_ideal: f64 = 0.2; - const x_ideal: f64 = 0.5; - const d: f64 = 0.05; - - // Left part from `x_ideal` - fn I_left(x: f64) -> f64 { - I_0 + x * (i_ideal - I_0/x_ideal) - } - - // Right part from `x_ideal` - fn I_right(x: f64) -> f64 { - I_0 + (i_ideal*x_ideal - I_0) * 2_f64.powf((x_ideal-x)/d) - } - - // Definition of I_NPoS in float - fn I_full(x: f64) -> f64 { - if x <= x_ideal { - I_left(x) - } else { - I_right(x) - } - } - - // Compute approximation of I_NPoS into piecewise linear function - fn I_NPoS_points() -> super::PiecewiseLinear { - let mut points = vec![]; - - // Points for left part - points.push((0.0, I_0)); - points.push((x_ideal, I_left(x_ideal))); - - // Approximation for right part. - // - // We start from x_ideal (x0) and we try to find the next point (x1) for which the linear - // approximation of (x0, x1) doesn't deviate from float definition by an error of - // GEN_ERROR. - - // When computing deviation between linear approximation and float definition we iterate - // over all points with this step precision. - const STEP_PRECISION: f64 = 0.000_000_1; - // Max error used for generating points. - const GEN_ERROR: f64 = 0.000_1; - - let mut x0: f64 = x_ideal; - let mut x1: f64 = x0; - - // This is just a step used to find next x1: - // if x1 + step result in a not enought precise approximation we reduce step and try again. - // we stop as soon as step is less than STEP_PRECISION. - let mut step: f64 = 0.1; - - loop { - let next_x1 = x1 + step; - - if next_x1 >= 1.0 { - points.push((1.0, I_right(1.0))); - break; - } - - let y0 = I_right(x0); - let next_y1 = I_right(next_x1); - - let mut error_overflowed = false; - - // Test error is not overflowed - - // Quick test on one point - if (I_right((x0 + next_x1)/2.0) - (y0 + next_y1)/2.0).abs() > GEN_ERROR { - error_overflowed = true; - } - - // Long test on all points - if !error_overflowed { - let linear = LinearFloat::new(x0, y0, next_x1, next_y1); - let mut cursor = x0; - while cursor < x1 { - if (I_right(cursor) - linear.compute(cursor)).abs() > GEN_ERROR { - error_overflowed = true; - } - cursor += STEP_PRECISION; - } - } - - if error_overflowed { - if step <= STEP_PRECISION { - points.push((x1, I_right(x1))); - x0 = x1; - step = 0.1; - } else { - step /= 10.0; - } - } else { - x1 = next_x1; - } - } - - // Convert points to piecewise linear definition - let pieces: Vec<(u32, super::Linear)> = (0..points.len()-1) - .map(|i| { - let p0 = points[i]; - let p1 = points[i+1]; - - let linear = LinearFloat::new(p0.0, p0.1, p1.0, p1.1); - - // Needed if we want to use a Perbill later - assert!(linear.a.abs() <= 1.0); - // Needed if we want to use a Perbill later - assert!(linear.b.abs() <= 1.0); - // Needed to stick with our restrictive definition of linear - assert!(linear.b.signum() == 1.0); - - ( - (p0.0 * 1_000_000_000.0) as u32, - super::Linear { - negative_a: linear.a.signum() < 0.0, - a: (linear.a.abs() * 1_000_000_000.0) as u32, - b: (linear.b.abs() * 1_000_000_000.0) as u32, - } - ) - }) - .collect(); - - println!("Generated pieces: {:?}", pieces); - assert_eq!(pieces.len(), 20); - - super::PiecewiseLinear { pieces: (&pieces[..]).try_into().unwrap() } - } - - /// This test is only useful to generate a new set of points for the definition of I_NPoS. - #[test] - fn generate_I_NPOS() { - assert_eq!(super::I_NPOS, I_NPoS_points()); +mod test { + use sr_primitives::curve::PiecewiseLinear; + + srml_staking_reward_curve::build! { + const I_NPOS: PiecewiseLinear<'static> = curve!( + min_inflation: 0_025_000, + max_inflation: 0_100_000, + ideal_stake: 0_500_000, + falloff: 0_050_000, + max_piece_count: 40, + test_precision: 0_005_000, + ); } - /// This test ensure that i_npos piecewise linear approximation is close to the actual function. - /// It does compare the result from a computation in integer of different capcity and in f64. #[test] - fn i_npos_precision() { - const STEP_PRECISION: f64 = 0.000_001; - const ERROR: f64 = 0.000_2; - - macro_rules! test_for_value { - ($($total_token:expr => $type:ty,)*) => { - let mut x = 0.1; - while x <= 1.0 { - let expected = I_full(x); - $({ - let result = super::I_NPOS.calculate_for_fraction_times_denominator( - (x * $total_token as f64) as $type, - $total_token, - ) as f64; - let expected = expected * $total_token as f64; - let error = (ERROR * $total_token as f64).max(2.0); - - let diff = (result - expected).abs(); - if diff >= error { - println!("total_token: {}", $total_token); - println!("x: {}", x); - println!("diff: {}", diff); - println!("error: {}", error); - panic!("error overflowed"); - } - })* - x += STEP_PRECISION - } - } - } - - test_for_value!( - 1_000u32 => u32, - 1_000_000u32 => u32, - 1_000_000_000u32 => u32, - 1_000_000_000_000u64 => u64, - 1_000_000_000_000_000u64 => u64, - 1_000_000_000_000_000_000u64 => u64, - 1_000_000_000_000_000_000_000u128 => u128, - 1_000_000_000_000_000_000_000_000u128 => u128, - 1_000_000_000_000_000_000_000_000_000u128 => u128, - 1_000_000_000_000_000_000_000_000_000_000u128 => u128, - 1_000_000_000_000_000_000_000_000_000_000_000_000u128 => u128, - u32::max_value() => u32, - u64::max_value() => u64, - u128::max_value() => u128, + fn npos_curve_is_sensible() { + const YEAR: u64 = 365 * 24 * 60 * 60 * 1000; + //super::I_NPOS.calculate_for_fraction_times_denominator(25, 100) + assert_eq!(super::compute_total_payout(&I_NPOS, 0, 100_000u64, YEAR), 2_498); + assert_eq!(super::compute_total_payout(&I_NPOS, 5_000, 100_000u64, YEAR), 3_248); + assert_eq!(super::compute_total_payout(&I_NPOS, 25_000, 100_000u64, YEAR), 6_246); + assert_eq!(super::compute_total_payout(&I_NPOS, 40_000, 100_000u64, YEAR), 8_494); + assert_eq!(super::compute_total_payout(&I_NPOS, 50_000, 100_000u64, YEAR), 9_993); + assert_eq!(super::compute_total_payout(&I_NPOS, 60_000, 100_000u64, YEAR), 4_379); + assert_eq!(super::compute_total_payout(&I_NPOS, 75_000, 100_000u64, YEAR), 2_733); + assert_eq!(super::compute_total_payout(&I_NPOS, 95_000, 100_000u64, YEAR), 2_513); + assert_eq!(super::compute_total_payout(&I_NPOS, 100_000, 100_000u64, YEAR), 2_505); + + const DAY: u64 = 24 * 60 * 60 * 1000; + assert_eq!(super::compute_total_payout(&I_NPOS, 25_000, 100_000u64, DAY), 17); + assert_eq!(super::compute_total_payout(&I_NPOS, 50_000, 100_000u64, DAY), 27); + assert_eq!(super::compute_total_payout(&I_NPOS, 75_000, 100_000u64, DAY), 7); + + const SIX_HOURS: u64 = 6 * 60 * 60 * 1000; + assert_eq!(super::compute_total_payout(&I_NPOS, 25_000, 100_000u64, SIX_HOURS), 4); + assert_eq!(super::compute_total_payout(&I_NPOS, 50_000, 100_000u64, SIX_HOURS), 7); + assert_eq!(super::compute_total_payout(&I_NPOS, 75_000, 100_000u64, SIX_HOURS), 2); + + const HOUR: u64 = 60 * 60 * 1000; + assert_eq!( + super::compute_total_payout( + &I_NPOS, + 2_500_000_000_000_000_000_000_000_000u128, + 5_000_000_000_000_000_000_000_000_000u128, + HOUR + ), + 57_038_500_000_000_000_000_000 ); } } diff --git a/srml/staking/src/lib.rs b/srml/staking/src/lib.rs index 5a04ae5c5e36c02fb715d5c7b2aa482515ec94ef..0a2f37ccc4425bc16c817a60616d43c7af94796d 100644 --- a/srml/staking/src/lib.rs +++ b/srml/staking/src/lib.rs @@ -133,10 +133,10 @@ //! //! ## Usage //! -//! ### Example: Reporting Misbehavior +//! ### Example: Rewarding a validator by id. //! //! ``` -//! use srml_support::{decl_module, dispatch::Result}; +//! use support::{decl_module, dispatch::Result}; //! use system::ensure_signed; //! use srml_staking::{self as staking}; //! @@ -144,10 +144,10 @@ //! //! decl_module! { //! pub struct Module for enum Call where origin: T::Origin { -//! /// Report whoever calls this function as offline once. -//! pub fn report_sender(origin) -> Result { +//! /// Reward a validator. +//! pub fn reward_myself(origin) -> Result { //! let reported = ensure_signed(origin)?; -//! >::on_offline_validator(reported, 1); +//! >::reward_by_ids(vec![(reported, 10)]); //! Ok(()) //! } //! } @@ -203,28 +203,6 @@ //! - Stash account, not increasing the staked value. //! - Stash account, also increasing the staked value. //! -//! ### Slashing details -//! -//! A validator can be _reported_ to be offline at any point via the public function -//! [`on_offline_validator`](enum.Call.html#variant.on_offline_validator). Each validator declares -//! how many times it can be _reported_ before it actually gets slashed via its -//! [`ValidatorPrefs::unstake_threshold`](./struct.ValidatorPrefs.html#structfield.unstake_threshold). -//! -//! On top of this, the Staking module also introduces an -//! [`OfflineSlashGrace`](./struct.Module.html#method.offline_slash_grace), which applies -//! to all validators and prevents them from getting immediately slashed. -//! -//! Essentially, a validator gets slashed once they have been reported more than -//! [`OfflineSlashGrace`] + [`ValidatorPrefs::unstake_threshold`] times. Getting slashed due to -//! offline report always leads to being _unstaked_ (_i.e._ removed as a validator candidate) as -//! the consequence. -//! -//! The base slash value is computed _per slash-event_ by multiplying -//! [`OfflineSlash`](./struct.Module.html#method.offline_slash) and the `total` `Exposure`. This -//! value is then multiplied by `2.pow(unstake_threshold)` to obtain the final slash value. All -//! individual accounts' punishments are capped at their total stake (NOTE: This cap should never -//! come into force in a correctly implemented, non-corrupted, well-configured system). -//! //! ### Additional Fund Management Operations //! //! Any funds already placed into stash can be the target of the following operations: @@ -265,75 +243,71 @@ #![recursion_limit="128"] #![cfg_attr(not(feature = "std"), no_std)] -#![cfg_attr(all(feature = "bench", test), feature(test))] - -#[cfg(all(feature = "bench", test))] -extern crate test; -#[cfg(any(feature = "bench", test))] +#[cfg(test)] mod mock; - #[cfg(test)] mod tests; -mod phragmen; -mod inflation; - -#[cfg(all(feature = "bench", test))] -mod benches; +pub mod inflation; -#[cfg(feature = "std")] -use runtime_io::with_storage; -use rstd::{prelude::*, result, collections::btree_map::BTreeMap}; +use rstd::{prelude::*, result}; use codec::{HasCompact, Encode, Decode}; -use srml_support::{ - StorageValue, StorageMap, EnumerableStorageMap, decl_module, decl_event, - decl_storage, ensure, traits::{ +use support::{ + decl_module, decl_event, decl_storage, ensure, + traits::{ Currency, OnFreeBalanceZero, OnDilution, LockIdentifier, LockableCurrency, - WithdrawReasons, WithdrawReason, OnUnbalanced, Imbalance, Get, Time + WithdrawReasons, OnUnbalanced, Imbalance, Get, Time } }; -use session::{historical::OnSessionEnding, SelectInitialValidators, SessionIndex}; -use sr_primitives::Perbill; -use sr_primitives::weights::SimpleDispatchInfo; -use sr_primitives::traits::{ - Convert, Zero, One, StaticLookup, CheckedSub, CheckedShl, Saturating, Bounded, - SaturatedConversion, SimpleArithmetic +use session::{historical::OnSessionEnding, SelectInitialValidators}; +use sr_primitives::{ + Perbill, + curve::PiecewiseLinear, + weights::SimpleDispatchInfo, + traits::{ + Convert, Zero, One, StaticLookup, CheckedSub, Saturating, Bounded, SaturatedConversion, + } +}; +use sr_staking_primitives::{ + SessionIndex, + offence::{OnOffenceHandler, OffenceDetails, Offence, ReportOffence}, }; #[cfg(feature = "std")] use sr_primitives::{Serialize, Deserialize}; use system::{ensure_signed, ensure_root}; -use phragmen::{elect, ACCURACY, ExtendedBalance, equalize}; +use phragmen::{elect, equalize, ExtendedBalance, Support, SupportMap, PhragmenStakedAssignment}; -const RECENT_OFFLINE_COUNT: usize = 32; const DEFAULT_MINIMUM_VALIDATOR_COUNT: u32 = 4; const MAX_NOMINATIONS: usize = 16; -const MAX_UNSTAKE_THRESHOLD: u32 = 10; const MAX_UNLOCKING_CHUNKS: usize = 32; const STAKING_ID: LockIdentifier = *b"staking "; /// Counter for the number of eras that have passed. pub type EraIndex = u32; +/// Counter for the number of "reward" points earned by a given validator. +pub type Points = u32; + /// Reward points of an era. Used to split era total payout between validators. #[derive(Encode, Decode, Default)] -pub struct EraRewards { +pub struct EraPoints { /// Total number of points. Equals the sum of reward points for each validator. - total: u32, - /// Reward at one index correspond to reward for validator in current_elected of this index. - /// Thus this reward vec is only valid for one elected set. - rewards: Vec, + total: Points, + /// The reward points earned by a given validator. The index of this vec corresponds to the + /// index into the current validator set. + individual: Vec, } -impl EraRewards { +impl EraPoints { /// Add the reward to the validator at the given index. Index must be valid /// (i.e. `index < current_elected.len()`). fn add_points_to_index(&mut self, index: u32, points: u32) { if let Some(new_total) = self.total.checked_add(points) { self.total = new_total; - self.rewards.resize((index as usize + 1).max(self.rewards.len()), 0); - self.rewards[index as usize] += points; // Addition is less than total + self.individual.resize((index as usize + 1).max(self.individual.len()), 0); + self.individual[index as usize] += points; // Addition is less than total } } } @@ -371,9 +345,6 @@ impl Default for RewardDestination { #[derive(PartialEq, Eq, Clone, Encode, Decode)] #[cfg_attr(feature = "std", derive(Debug))] pub struct ValidatorPrefs { - /// Validator should ensure this many more slashes than is necessary before being unstaked. - #[codec(compact)] - pub unstake_threshold: u32, /// Reward that validator takes up-front; only the rest is split between themselves and /// nominators. #[codec(compact)] @@ -383,7 +354,6 @@ pub struct ValidatorPrefs { impl Default for ValidatorPrefs { fn default() -> Self { ValidatorPrefs { - unstake_threshold: 3, validator_payment: Default::default(), } } @@ -465,6 +435,15 @@ pub struct Exposure { pub others: Vec>, } +/// A slashing event occurred, slashing a validator for a given amount of balance. +#[derive(PartialEq, Eq, PartialOrd, Ord, Clone, Encode, Decode, Default)] +#[cfg_attr(feature = "std", derive(Debug))] +pub struct SlashJournalEntry { + who: AccountId, + amount: Balance, + own_slash: Balance, // the amount of `who`'s own exposure that was slashed +} + pub type BalanceOf = <::Currency as Currency<::AccountId>>::Balance; type PositiveImbalanceOf = @@ -473,26 +452,20 @@ type NegativeImbalanceOf = <::Currency as Currency<::AccountId>>::NegativeImbalance; type MomentOf= <::Time as Time>::Moment; -type RawAssignment = (::AccountId, ExtendedBalance); -type Assignment = (::AccountId, ExtendedBalance, BalanceOf); -type ExpoMap = BTreeMap< - ::AccountId, - Exposure<::AccountId, BalanceOf> ->; - -pub const DEFAULT_SESSIONS_PER_ERA: u32 = 3; -pub const DEFAULT_BONDING_DURATION: u32 = 1; - /// Means for interacting with a specialized version of the `session` trait. /// /// This is needed because `Staking` sets the `ValidatorIdOf` of the `session::Trait` pub trait SessionInterface: system::Trait { /// Disable a given validator by stash ID. - fn disable_validator(validator: &AccountId) -> Result<(), ()>; + /// + /// Returns `true` if new era should be forced at the end of this session. + /// This allows preventing a situation where there is too many validators + /// disabled and block production stalls. + fn disable_validator(validator: &AccountId) -> Result; /// Get the validators from session. fn validators() -> Vec; /// Prune historical session tries up to but not including the given index. - fn prune_historical_up_to(up_to: session::SessionIndex); + fn prune_historical_up_to(up_to: SessionIndex); } impl SessionInterface<::AccountId> for T where @@ -506,7 +479,7 @@ impl SessionInterface<::AccountId> for T where T::SelectInitialValidators: session::SelectInitialValidators<::AccountId>, T::ValidatorIdOf: Convert<::AccountId, Option<::AccountId>> { - fn disable_validator(validator: &::AccountId) -> Result<(), ()> { + fn disable_validator(validator: &::AccountId) -> Result { >::disable(validator) } @@ -514,7 +487,7 @@ impl SessionInterface<::AccountId> for T where >::validators() } - fn prune_historical_up_to(up_to: session::SessionIndex) { + fn prune_historical_up_to(up_to: SessionIndex) { >::prune_up_to(up_to); } } @@ -530,7 +503,7 @@ pub trait Trait: system::Trait { /// This must fit into a `u64` but is allowed to be sensibly lossy. /// TODO: #1377 /// The backward convert should be removed as the new Phragmen API returns ratio. - /// The post-processing needs it but will be moved to off-chain. + /// The post-processing needs it but will be moved to off-chain. TODO: #2908 type CurrencyToVote: Convert, u64> + Convert>; /// Some tokens minted. @@ -553,6 +526,9 @@ pub trait Trait: system::Trait { /// Interface for interacting with a session module. type SessionInterface: self::SessionInterface; + + /// The NPoS reward curve to use. + type RewardCurve: Get<&'static PiecewiseLinear<'static>>; } /// Mode of era-forcing. @@ -579,10 +555,6 @@ decl_storage! { /// Minimum number of staking participants before emergency conditions are imposed. pub MinimumValidatorCount get(minimum_validator_count) config(): u32 = DEFAULT_MINIMUM_VALIDATOR_COUNT; - /// Slash, per validator that is taken for the first time they are found to be offline. - pub OfflineSlash get(offline_slash) config(): Perbill = Perbill::from_millionths(1000); - /// Number of instances of offline reports before slashing begins for validators. - pub OfflineSlashGrace get(offline_slash_grace) config(): u32; /// Any validators that may never be slashed or forcibly kicked. It's a Vec since they're /// easy to initialize and the performance hit is minimal (we expect no more than four @@ -623,7 +595,7 @@ decl_storage! { pub CurrentEraStartSessionIndex get(current_era_start_session_index): SessionIndex; /// Rewards for the current era. Using indices of current elected set. - CurrentEraRewards get(current_era_reward): EraRewards; + CurrentEraPointsEarned get(current_era_reward): EraPoints; /// The amount of balance actively at stake for each validator slot, currently. /// @@ -632,54 +604,51 @@ decl_storage! { config.stakers.iter().map(|&(_, _, value, _)| value).min().unwrap_or_default() }): BalanceOf; - /// The number of times a given validator has been reported offline. This gets decremented - /// by one each era that passes. - pub SlashCount get(slash_count): map T::AccountId => u32; - - /// Most recent `RECENT_OFFLINE_COUNT` instances. (Who it was, when it was reported, how - /// many instances they were offline for). - pub RecentlyOffline get(recently_offline): Vec<(T::AccountId, T::BlockNumber, u32)>; - /// True if the next session change will be a new era regardless of index. pub ForceEra get(force_era) config(): Forcing; + /// The percentage of the slash that is distributed to reporters. + /// + /// The rest of the slashed value is handled by the `Slash`. + pub SlashRewardFraction get(slash_reward_fraction) config(): Perbill; + /// A mapping from still-bonded eras to the first session index of that era. BondedEras: Vec<(EraIndex, SessionIndex)>; + + /// All slashes that have occurred in a given era. + EraSlashJournal get(era_slash_journal): + map EraIndex => Vec>>; } add_extra_genesis { config(stakers): Vec<(T::AccountId, T::AccountId, BalanceOf, StakerStatus)>; - build(| - storage: &mut (sr_primitives::StorageOverlay, sr_primitives::ChildrenStorageOverlay), - config: &GenesisConfig - | { - with_storage(storage, || { - for &(ref stash, ref controller, balance, ref status) in &config.stakers { - assert!( - T::Currency::free_balance(&stash) >= balance, - "Stash does not have enough balance to bond." - ); - let _ = >::bond( - T::Origin::from(Some(stash.clone()).into()), - T::Lookup::unlookup(controller.clone()), - balance, - RewardDestination::Staked - ); - let _ = match status { - StakerStatus::Validator => { - >::validate( - T::Origin::from(Some(controller.clone()).into()), - Default::default() - ) - }, StakerStatus::Nominator(votes) => { - >::nominate( - T::Origin::from(Some(controller.clone()).into()), - votes.iter().map(|l| {T::Lookup::unlookup(l.clone())}).collect() - ) - }, _ => Ok(()) - }; - } - }); + build(|config: &GenesisConfig| { + for &(ref stash, ref controller, balance, ref status) in &config.stakers { + assert!( + T::Currency::free_balance(&stash) >= balance, + "Stash does not have enough balance to bond." + ); + let _ = >::bond( + T::Origin::from(Some(stash.clone()).into()), + T::Lookup::unlookup(controller.clone()), + balance, + RewardDestination::Staked, + ); + let _ = match status { + StakerStatus::Validator => { + >::validate( + T::Origin::from(Some(controller.clone()).into()), + Default::default(), + ) + }, + StakerStatus::Nominator(votes) => { + >::nominate( + T::Origin::from(Some(controller.clone()).into()), + votes.iter().map(|l| T::Lookup::unlookup(l.clone())).collect(), + ) + }, _ => Ok(()) + }; + } }); } } @@ -688,11 +657,11 @@ decl_event!( pub enum Event where Balance = BalanceOf, ::AccountId { /// All validators have been rewarded by the given balance. Reward(Balance), - /// One validator (and its nominators) has been given an offline-warning (it is still - /// within its grace). The accrued number of slashes is recorded, too. - OfflineWarning(AccountId, u32), /// One validator (and its nominators) has been slashed by the given amount. - OfflineSlash(AccountId, Balance), + Slash(AccountId, Balance), + /// An old slashing report from a prior era was discarded because it could + /// not be processed. + OldSlashingReportDiscarded(SessionIndex), } ); @@ -704,7 +673,7 @@ decl_module! { /// Number of eras that staked funds must remain bonded for. const BondingDuration: EraIndex = T::BondingDuration::get(); - fn deposit_event() = default; + fn deposit_event() = default; fn on_finalize() { // Set the start of the first era. @@ -716,7 +685,7 @@ decl_module! { /// Take the origin account as a stash and lock up `value` of its balance. `controller` will /// be the account that controls it. /// - /// `value` must be more than the `existential_deposit` defined in the Balances module. + /// `value` must be more than the `minimum_balance` specified by `T::Currency`. /// /// The dispatch origin for this call must be _Signed_ by the stash account. /// @@ -753,7 +722,7 @@ decl_module! { // You're auto-bonded forever, here. We might improve this by only bonding when // you actually validate/nominate and remove once you unbond __everything__. - >::insert(&stash, controller.clone()); + >::insert(&stash, &controller); >::insert(&stash, payee); let stash_balance = T::Currency::free_balance(&stash); @@ -795,7 +764,7 @@ decl_module! { /// Schedule a portion of the stash to be unlocked ready for transfer out after the bond /// period ends. If this leaves an amount actively bonded less than - /// T::Currency::existential_deposit(), then it is increased to the full amount. + /// T::Currency::minimum_balance(), then it is increased to the full amount. /// /// Once the unlock period is done, you can call `withdraw_unbonded` to actually move /// the funds out of management ready for transfer. @@ -895,10 +864,6 @@ decl_module! { let controller = ensure_signed(origin)?; let ledger = Self::ledger(&controller).ok_or("not a controller")?; let stash = &ledger.stash; - ensure!( - prefs.unstake_threshold <= MAX_UNSTAKE_THRESHOLD, - "unstake threshold too large" - ); >::remove(stash); >::insert(stash, prefs); } @@ -922,8 +887,8 @@ decl_module! { ensure!(!targets.is_empty(), "targets cannot be empty"); let targets = targets.into_iter() .take(MAX_NOMINATIONS) - .map(T::Lookup::lookup) - .collect::, &'static str>>()?; + .map(|t| T::Lookup::lookup(t)) + .collect::, _>>()?; >::remove(stash); >::insert(stash, targets); @@ -1027,13 +992,6 @@ decl_module! { ForceEra::put(Forcing::ForceNew); } - /// Set the offline slash grace period. - #[weight = SimpleDispatchInfo::FixedOperational(10_000)] - fn set_offline_slash_grace(origin, #[compact] new: u32) { - ensure_root(origin)?; - OfflineSlashGrace::put(new); - } - /// Set the validators who cannot be slashed (if any). #[weight = SimpleDispatchInfo::FixedOperational(10_000)] fn set_invulnerables(origin, validators: Vec) { @@ -1048,8 +1006,8 @@ impl Module { /// The total balance that can be slashed from a validator controller account as of /// right now. - pub fn slashable_balance(who: &T::AccountId) -> BalanceOf { - Self::stakers(who).total + pub fn slashable_balance_of(stash: &T::AccountId) -> BalanceOf { + Self::bonded(stash).and_then(Self::ledger).map(|l| l.active).unwrap_or_default() } // MUTABLES (DANGEROUS) @@ -1065,25 +1023,47 @@ impl Module { &ledger.stash, ledger.total, T::BlockNumber::max_value(), - WithdrawReasons::except(WithdrawReason::TransactionPayment), + WithdrawReasons::all(), ); >::insert(controller, ledger); } - /// Slash a given validator by a specific amount. Removes the slash from the validator's - /// balance by preference, and reduces the nominators' balance if needed. - fn slash_validator(stash: &T::AccountId, slash: BalanceOf) { - // The exposure (backing stake) information of the validator to be slashed. - let exposure = Self::stakers(stash); + /// Slash a given validator by a specific amount with given (historical) exposure. + /// + /// Removes the slash from the validator's balance by preference, + /// and reduces the nominators' balance if needed. + /// + /// Returns the resulting `NegativeImbalance` to allow distributing the slashed amount and + /// pushes an entry onto the slash journal. + fn slash_validator( + stash: &T::AccountId, + slash: BalanceOf, + exposure: &Exposure>, + journal: &mut Vec>>, + ) -> NegativeImbalanceOf { // The amount we are actually going to slash (can't be bigger than the validator's total // exposure) let slash = slash.min(exposure.total); + + // limit what we'll slash of the stash's own to only what's in + // the exposure. + // + // note: this is fine only because we limit reports of the current era. + // otherwise, these funds may have already been slashed due to something + // reported from a prior era. + let already_slashed_own = journal.iter() + .filter(|entry| &entry.who == stash) + .map(|entry| entry.own_slash) + .fold(>::zero(), |a, c| a.saturating_add(c)); + + let own_remaining = exposure.own.saturating_sub(already_slashed_own); + // The amount we'll slash from the validator's stash directly. - let own_slash = exposure.own.min(slash); + let own_slash = own_remaining.min(slash); let (mut imbalance, missing) = T::Currency::slash(stash, own_slash); let own_slash = own_slash - missing; - // The amount remaining that we can't slash from the validator, that must be taken from the - // nominators. + // The amount remaining that we can't slash from the validator, + // that must be taken from the nominators. let rest_slash = slash - own_slash; if !rest_slash.is_zero() { // The total to be slashed from the nominators. @@ -1096,7 +1076,19 @@ impl Module { } } } - T::Slash::on_unbalanced(imbalance); + + journal.push(SlashJournalEntry { + who: stash.clone(), + own_slash: own_slash.clone(), + amount: slash, + }); + + // trigger the event + Self::deposit_event( + RawEvent::Slash(stash.clone(), slash) + ); + + imbalance } /// Actually make a payment to a staker. This uses the currency's reward function @@ -1154,9 +1146,10 @@ impl Module { fn new_session(session_index: SessionIndex) -> Option<(Vec, Vec<(T::AccountId, Exposure>)>)> { + let era_length = session_index.checked_sub(Self::current_era_start_session_index()).unwrap_or(0); match ForceEra::get() { Forcing::ForceNew => ForceEra::kill(), - Forcing::NotForcing if session_index % T::SessionsPerEra::get() == 0 => (), + Forcing::NotForcing if era_length >= T::SessionsPerEra::get() => (), _ => return None, } let validators = T::SessionInterface::validators(); @@ -1173,10 +1166,10 @@ impl Module { /// get a chance to set their session keys. fn new_era(start_session_index: SessionIndex) -> Option> { // Payout - let rewards = CurrentEraRewards::take(); + let points = CurrentEraPointsEarned::take(); let now = T::Time::now(); let previous_era_start = >::mutate(|v| { - rstd::mem::replace(v, now.clone()) + rstd::mem::replace(v, now) }); let era_duration = now - previous_era_start; if !era_duration.is_zero() { @@ -1186,23 +1179,25 @@ impl Module { let total_rewarded_stake = Self::slot_stake() * validator_len; let total_payout = inflation::compute_total_payout( + &T::RewardCurve::get(), total_rewarded_stake.clone(), T::Currency::total_issuance(), - // Era of duration more than u32::MAX is rewarded as u32::MAX. - >::from(era_duration.saturated_into::()), + // Duration of era; more than u64::MAX is rewarded as u64::MAX. + era_duration.saturated_into::(), ); let mut total_imbalance = >::zero(); - let total_points = rewards.total; - for (v, points) in validators.iter().zip(rewards.rewards.into_iter()) { - if points != 0 { - let reward = multiply_by_rational(total_payout, points, total_points); + for (v, p) in validators.iter().zip(points.individual.into_iter()) { + if p != 0 { + let reward = Perbill::from_rational_approximation(p, points.total) * total_payout; total_imbalance.subsume(Self::reward_validator(v, reward)); } } let total_reward = total_imbalance.peek(); + // assert!(total_reward <= total_payout) + Self::deposit_event(RawEvent::Reward(total_reward)); T::Reward::on_unbalanced(total_imbalance); T::OnRewardMinted::on_dilution(total_reward, total_rewarded_stake); @@ -1210,6 +1205,10 @@ impl Module { // Increment current era. let current_era = CurrentEra::mutate(|s| { *s += 1; *s }); + + // prune journal for last era. + >::remove(current_era - 1); + CurrentEraStartSessionIndex::mutate(|v| { *v = start_session_index; }); @@ -1239,108 +1238,108 @@ impl Module { maybe_new_validators } - fn slashable_balance_of(stash: &T::AccountId) -> BalanceOf { - Self::bonded(stash).and_then(Self::ledger).map(|l| l.active).unwrap_or_default() - } - /// Select a new validator set from the assembled stakers and their role preferences. /// /// Returns the new `SlotStake` value and a set of newly selected _stash_ IDs. fn select_validators() -> (BalanceOf, Option>) { - let maybe_elected_set = elect::( + let maybe_phragmen_result = elect::<_, _, _, T::CurrencyToVote>( Self::validator_count() as usize, Self::minimum_validator_count().max(1) as usize, - >::enumerate(), - >::enumerate(), + >::enumerate().map(|(who, _)| who).collect::>(), + >::enumerate().collect(), Self::slashable_balance_of, + true, ); - if let Some(elected_set) = maybe_elected_set { - let elected_stashes = elected_set.0; - let assignments = elected_set.1; + if let Some(phragmen_result) = maybe_phragmen_result { + let elected_stashes = phragmen_result.winners.iter() + .map(|(s, _)| s.clone()) + .collect::>(); + let assignments = phragmen_result.assignments; - // helper closure. - let to_balance = |b: ExtendedBalance| - >>::convert(b); let to_votes = |b: BalanceOf| , u64>>::convert(b) as ExtendedBalance; + let to_balance = |e: ExtendedBalance| + >>::convert(e); - // The return value of this is safe to be converted to u64. - // The original balance, `b` is within the scope of u64. It is just extended to u128 - // to be properly multiplied by a ratio, which will lead to another value - // less than u64 for sure. The result can then be safely passed to `to_balance`. - // For now the backward convert is used. A simple `TryFrom` is also safe. - let ratio_of = |b, p| (p as ExtendedBalance).saturating_mul(to_votes(b)) / ACCURACY; - - // Compute the actual stake from nominator's ratio. - let assignments_with_stakes = assignments.iter().map(|(n, a)|( - n.clone(), - Self::slashable_balance_of(n), - a.iter().map(|(acc, r)| ( - acc.clone(), - *r, - to_balance(ratio_of(Self::slashable_balance_of(n), *r)), - )) - .collect::>>() - )).collect::, Vec>)>>(); - - // update elected candidate exposures. - let mut exposures = >::new(); + // Initialize the support of each candidate. + let mut supports = >::new(); elected_stashes .iter() - .map(|e| (e, Self::slashable_balance_of(e))) + .map(|e| (e, to_votes(Self::slashable_balance_of(e)))) .for_each(|(e, s)| { - let item = Exposure { own: s, total: s, ..Default::default() }; - exposures.insert(e.clone(), item); + let item = Support { own: s, total: s, ..Default::default() }; + supports.insert(e.clone(), item); }); - for (n, _, assignment) in &assignments_with_stakes { - for (c, _, s) in assignment { - if let Some(expo) = exposures.get_mut(c) { - // NOTE: simple example where this saturates: - // candidate with max_value stake. 1 nominator with max_value stake. - // Nuked. Sadly there is not much that we can do about this. - // See this test: phragmen_should_not_overflow_xxx() - expo.total = expo.total.saturating_add(*s); - expo.others.push( IndividualExposure { who: n.clone(), value: *s } ); + // build support struct. + for (n, assignment) in assignments.iter() { + for (c, per_thing) in assignment.iter() { + let nominator_stake = to_votes(Self::slashable_balance_of(n)); + // AUDIT: it is crucially important for the `Mul` implementation of all + // per-things to be sound. + let other_stake = *per_thing * nominator_stake; + if let Some(support) = supports.get_mut(c) { + // For an astronomically rich validator with more astronomically rich + // set of nominators, this might saturate. + support.total = support.total.saturating_add(other_stake); + support.others.push((n.clone(), other_stake)); } } } if cfg!(feature = "equalize") { + let mut staked_assignments + : Vec<(T::AccountId, Vec>)> + = Vec::with_capacity(assignments.len()); + for (n, assignment) in assignments.iter() { + let mut staked_assignment + : Vec> + = Vec::with_capacity(assignment.len()); + for (c, per_thing) in assignment.iter() { + let nominator_stake = to_votes(Self::slashable_balance_of(n)); + let other_stake = *per_thing * nominator_stake; + staked_assignment.push((c.clone(), other_stake)); + } + staked_assignments.push((n.clone(), staked_assignment)); + } + let tolerance = 0_u128; let iterations = 2_usize; - let mut assignments_with_votes = assignments_with_stakes.iter() - .map(|a| ( - a.0.clone(), a.1, - a.2.iter() - .map(|e| (e.0.clone(), e.1, to_votes(e.2))) - .collect::>() - )) - .collect::, - Vec<(T::AccountId, ExtendedBalance, ExtendedBalance)> - )>>(); - equalize::(&mut assignments_with_votes, &mut exposures, tolerance, iterations); + equalize::<_, _, T::CurrencyToVote, _>( + staked_assignments, + &mut supports, + tolerance, + iterations, + Self::slashable_balance_of, + ); } - // Clear Stakers and reduce their slash_count. + // Clear Stakers. for v in Self::current_elected().iter() { >::remove(v); - let slash_count = >::take(v); - if slash_count > 1 { - >::insert(v, slash_count - 1); - } } // Populate Stakers and figure out the minimum stake behind a slot. let mut slot_stake = BalanceOf::::max_value(); - for (c, e) in exposures.iter() { - if e.total < slot_stake { - slot_stake = e.total; + for (c, s) in supports.into_iter() { + // build `struct exposure` from `support` + let exposure = Exposure { + own: to_balance(s.own), + // This might reasonably saturate and we cannot do much about it. The sum of + // someone's stake might exceed the balance type if they have the maximum amount + // of balance and receive some support. This is super unlikely to happen, yet + // we simulate it in some tests. + total: to_balance(s.total), + others: s.others + .into_iter() + .map(|(who, value)| IndividualExposure { who, value: to_balance(value) }) + .collect::>>(), + }; + if exposure.total < slot_stake { + slot_stake = exposure.total; } - >::insert(c.clone(), e.clone()); + >::insert(&c, exposure.clone()); } // Update slot stake. @@ -1349,6 +1348,10 @@ impl Module { // Set the new validator set in sessions. >::put(&elected_stashes); + // In order to keep the property required by `n_session_ending` + // that we must return the new validator set even if it's the same as the old, + // as long as any underlying economic conditions have changed, we don't attempt + // to do any optimization where we compare against the prior set. (slot_stake, Some(elected_stashes)) } else { // There were not enough candidates for even our minimal level of functionality. @@ -1371,68 +1374,10 @@ impl Module { >::remove(&controller); } >::remove(stash); - >::remove(stash); >::remove(stash); >::remove(stash); } - /// Call when a validator is determined to be offline. `count` is the - /// number of offenses the validator has committed. - /// - /// NOTE: This is called with the controller (not the stash) account id. - pub fn on_offline_validator(controller: T::AccountId, count: usize) { - if let Some(l) = Self::ledger(&controller) { - let stash = l.stash; - - // Early exit if validator is invulnerable. - if Self::invulnerables().contains(&stash) { - return - } - - let slash_count = Self::slash_count(&stash); - let new_slash_count = slash_count + count as u32; - >::insert(&stash, new_slash_count); - let grace = Self::offline_slash_grace(); - - if RECENT_OFFLINE_COUNT > 0 { - let item = (stash.clone(), >::block_number(), count as u32); - >::mutate(|v| if v.len() >= RECENT_OFFLINE_COUNT { - let index = v.iter() - .enumerate() - .min_by_key(|(_, (_, block, _))| block) - .expect("v is non-empty; qed") - .0; - v[index] = item; - } else { - v.push(item); - }); - } - - let prefs = Self::validators(&stash); - let unstake_threshold = prefs.unstake_threshold.min(MAX_UNSTAKE_THRESHOLD); - let max_slashes = grace + unstake_threshold; - - let event = if new_slash_count > max_slashes { - let slash_exposure = Self::stakers(&stash).total; - let offline_slash_base = Self::offline_slash() * slash_exposure; - // They're bailing. - let slash = offline_slash_base - // Multiply slash_mantissa by 2^(unstake_threshold with upper bound) - .checked_shl(unstake_threshold) - .map(|x| x.min(slash_exposure)) - .unwrap_or(slash_exposure); - let _ = Self::slash_validator(&stash, slash); - let _ = T::SessionInterface::disable_validator(&stash); - - RawEvent::OfflineSlash(stash.clone(), slash) - } else { - RawEvent::OfflineWarning(stash.clone(), slash_count) - }; - - Self::deposit_event(event); - } - } - /// Add reward points to validators using their stash account ID. /// /// Validators are keyed by stash account ID and must be in the current elected set. @@ -1446,7 +1391,7 @@ impl Module { /// COMPLEXITY: Complexity is `number_of_validator_to_reward x current_elected_len`. /// If you need to reward lots of validator consider using `reward_by_indices`. pub fn reward_by_ids(validators_points: impl IntoIterator) { - CurrentEraRewards::mutate(|rewards| { + CurrentEraPointsEarned::mutate(|rewards| { let current_elected = >::current_elected(); for (validator, points) in validators_points.into_iter() { if let Some(index) = current_elected.iter() @@ -1466,7 +1411,7 @@ impl Module { // TODO: This can be optimised once #3302 is implemented. let current_elected_len = >::current_elected().len() as u32; - CurrentEraRewards::mutate(|rewards| { + CurrentEraPointsEarned::mutate(|rewards| { for (validator_index, points) in validators_points.into_iter() { if validator_index < current_elected_len { rewards.add_points_to_index(validator_index, points); @@ -1512,31 +1457,6 @@ impl authorship::EventHandler(value: N, num: u32, den: u32) -> N - where N: SimpleArithmetic + Clone -{ - let num = num.min(den); - - let result_divisor_part = value.clone() / den.into() * num.into(); - - let result_remainder_part = { - let rem = value % den.into(); - - // Fits into u32 because den is u32 and remainder < den - let rem_u32 = rem.saturated_into::(); - - // Multiplication fits into u64 as both term are u32 - let rem_part = rem_u32 as u64 * num as u64 / den as u64; - - // Result fits into u32 as num < total_points - (rem_part as u32).into() - }; - - result_divisor_part + result_remainder_part -} - /// A `Convert` implementation that finds the stash of the given controller account, /// if any. pub struct StashOf(rstd::marker::PhantomData); @@ -1564,3 +1484,100 @@ impl SelectInitialValidators for Module { >::select_validators().1 } } + +/// This is intended to be used with `FilterHistoricalOffences`. +impl OnOffenceHandler> for Module where + T: session::Trait::AccountId>, + T: session::historical::Trait< + FullIdentification = Exposure<::AccountId, BalanceOf>, + FullIdentificationOf = ExposureOf, + >, + T::SessionHandler: session::SessionHandler<::AccountId>, + T::OnSessionEnding: session::OnSessionEnding<::AccountId>, + T::SelectInitialValidators: session::SelectInitialValidators<::AccountId>, + T::ValidatorIdOf: Convert<::AccountId, Option<::AccountId>> +{ + fn on_offence( + offenders: &[OffenceDetails>], + slash_fraction: &[Perbill], + ) { + let mut remaining_imbalance = >::zero(); + let slash_reward_fraction = SlashRewardFraction::get(); + + let era_now = Self::current_era(); + let mut journal = Self::era_slash_journal(era_now); + for (details, slash_fraction) in offenders.iter().zip(slash_fraction) { + let stash = &details.offender.0; + let exposure = &details.offender.1; + + // Skip if the validator is invulnerable. + if Self::invulnerables().contains(stash) { + continue + } + + // calculate the amount to slash + let slash_exposure = exposure.total; + let amount = *slash_fraction * slash_exposure; + // in some cases `slash_fraction` can be just `0`, + // which means we are not slashing this time. + if amount.is_zero() { + continue; + } + + // make sure to disable validator till the end of this session + if T::SessionInterface::disable_validator(stash).unwrap_or(false) { + // force a new era, to select a new validator set + ForceEra::put(Forcing::ForceNew); + } + // actually slash the validator + let slashed_amount = Self::slash_validator(stash, amount, exposure, &mut journal); + + // distribute the rewards according to the slash + let slash_reward = slash_reward_fraction * slashed_amount.peek(); + if !slash_reward.is_zero() && !details.reporters.is_empty() { + let (mut reward, rest) = slashed_amount.split(slash_reward); + // split the reward between reporters equally. Division cannot fail because + // we guarded against it in the enclosing if. + let per_reporter = reward.peek() / (details.reporters.len() as u32).into(); + for reporter in &details.reporters { + let (reporter_reward, rest) = reward.split(per_reporter); + reward = rest; + T::Currency::resolve_creating(reporter, reporter_reward); + } + // The rest goes to the treasury. + remaining_imbalance.subsume(reward); + remaining_imbalance.subsume(rest); + } else { + remaining_imbalance.subsume(slashed_amount); + } + } + >::insert(era_now, journal); + + // Handle the rest of imbalances + T::Slash::on_unbalanced(remaining_imbalance); + } +} + +/// Filter historical offences out and only allow those from the current era. +pub struct FilterHistoricalOffences { + _inner: rstd::marker::PhantomData<(T, R)>, +} + +impl ReportOffence + for FilterHistoricalOffences, R> where + T: Trait, + R: ReportOffence, + O: Offence, +{ + fn report_offence(reporters: Vec, offence: O) { + // disallow any slashing from before the current era. + let offence_session = offence.session_index(); + if offence_session >= >::current_era_start_session_index() { + R::report_offence(reporters, offence) + } else { + >::deposit_event( + RawEvent::OldSlashingReportDiscarded(offence_session) + ) + } + } +} diff --git a/srml/staking/src/mock.rs b/srml/staking/src/mock.rs index d8233e5f45dfa585300d6c9e8cf3dc19c0aa4e83..d8d36561426761ece8cbf8ab388f9b933e5fe16e 100644 --- a/srml/staking/src/mock.rs +++ b/srml/staking/src/mock.rs @@ -18,12 +18,14 @@ use std::{collections::HashSet, cell::RefCell}; use sr_primitives::Perbill; -use sr_primitives::traits::{IdentityLookup, Convert, OpaqueKeys, OnInitialize}; +use sr_primitives::curve::PiecewiseLinear; +use sr_primitives::traits::{IdentityLookup, Convert, OpaqueKeys, OnInitialize, SaturatedConversion}; use sr_primitives::testing::{Header, UintAuthorityId}; +use sr_staking_primitives::SessionIndex; use primitives::{H256, Blake2Hasher}; use runtime_io; -use srml_support::{assert_ok, impl_outer_origin, parameter_types, EnumerableStorageMap}; -use srml_support::traits::{Currency, Get, FindAuthor}; +use support::{assert_ok, impl_outer_origin, parameter_types, StorageLinkedMap}; +use support::traits::{Currency, Get, FindAuthor}; use crate::{ EraIndex, GenesisConfig, Module, Trait, StakerStatus, ValidatorPrefs, RewardDestination, Nominators, inflation @@ -40,9 +42,7 @@ impl Convert for CurrencyToVoteHandler { fn convert(x: u64) -> u64 { x } } impl Convert for CurrencyToVoteHandler { - fn convert(x: u128) -> u64 { - x as u64 - } + fn convert(x: u128) -> u64 { x.saturated_into() } } thread_local! { @@ -52,6 +52,8 @@ thread_local! { pub struct TestSessionHandler; impl session::SessionHandler for TestSessionHandler { + fn on_genesis_session(_validators: &[(AccountId, Ks)]) {} + fn on_new_session( _changed: bool, validators: &[(AccountId, Ks)], @@ -71,8 +73,8 @@ impl session::SessionHandler for TestSessionHandler { } } -pub fn is_disabled(validator: AccountId) -> bool { - let stash = Staking::ledger(&validator).unwrap().stash; +pub fn is_disabled(controller: AccountId) -> bool { + let stash = Staking::ledger(&controller).unwrap().stash; SESSION.with(|d| d.borrow().1.contains(&stash)) } @@ -91,7 +93,7 @@ impl_outer_origin!{ pub struct Author11; impl FindAuthor for Author11 { fn find_author<'a, I>(_digests: I) -> Option - where I: 'a + IntoIterator + where I: 'a + IntoIterator { Some(11) } @@ -122,6 +124,7 @@ impl system::Trait for Test { type MaximumBlockWeight = MaximumBlockWeight; type AvailableBlockRatio = AvailableBlockRatio; type MaximumBlockLength = MaximumBlockLength; + type Version = (); } parameter_types! { pub const TransferFee: Balance = 0; @@ -148,6 +151,7 @@ parameter_types! { pub const Period: BlockNumber = 1; pub const Offset: BlockNumber = 0; pub const UncleGenerations: u64 = 0; + pub const DisabledValidatorsThreshold: Perbill = Perbill::from_percent(25); } impl session::Trait for Test { type OnSessionEnding = session::historical::NoteHistoricalRoot; @@ -158,6 +162,7 @@ impl session::Trait for Test { type ValidatorId = AccountId; type ValidatorIdOf = crate::StashOf; type SelectInitialValidators = Staking; + type DisabledValidatorsThreshold = DisabledValidatorsThreshold; } impl session::historical::Trait for Test { @@ -178,9 +183,20 @@ impl timestamp::Trait for Test { type OnTimestampSet = (); type MinimumPeriod = MinimumPeriod; } +srml_staking_reward_curve::build! { + const I_NPOS: PiecewiseLinear<'static> = curve!( + min_inflation: 0_025_000, + max_inflation: 0_100_000, + ideal_stake: 0_500_000, + falloff: 0_050_000, + max_piece_count: 40, + test_precision: 0_005_000, + ); +} parameter_types! { - pub const SessionsPerEra: session::SessionIndex = 3; + pub const SessionsPerEra: SessionIndex = 3; pub const BondingDuration: EraIndex = 3; + pub const RewardCurve: &'static PiecewiseLinear<'static> = &I_NPOS; } impl Trait for Test { type Currency = balances::Module; @@ -193,6 +209,7 @@ impl Trait for Test { type SessionsPerEra = SessionsPerEra; type BondingDuration = BondingDuration; type SessionInterface = Self; + type RewardCurve = RewardCurve; } pub struct ExtBuilder { @@ -203,6 +220,7 @@ pub struct ExtBuilder { minimum_validator_count: u32, fair: bool, num_validators: Option, + invulnerables: Vec, } impl Default for ExtBuilder { @@ -215,6 +233,7 @@ impl Default for ExtBuilder { minimum_validator_count: 0, fair: true, num_validators: None, + invulnerables: vec![], } } } @@ -248,6 +267,10 @@ impl ExtBuilder { self.num_validators = Some(num_validators); self } + pub fn invulnerables(mut self, invulnerables: Vec) -> Self { + self.invulnerables = invulnerables; + self + } pub fn set_associated_consts(&self) { EXISTENTIAL_DEPOSIT.with(|v| *v.borrow_mut() = self.existential_deposit); } @@ -298,6 +321,7 @@ impl ExtBuilder { let _ = GenesisConfig::{ current_era: 0, stakers: vec![ + // (stash, controller, staked_amount, status) (11, 10, balance_factor * 1000, StakerStatus::::Validator), (21, 20, stake_21, StakerStatus::::Validator), (31, 30, stake_31, StakerStatus::::Validator), @@ -307,10 +331,9 @@ impl ExtBuilder { ], validator_count: self.validator_count, minimum_validator_count: self.minimum_validator_count, - offline_slash: Perbill::from_percent(5), - offline_slash_grace: 0, - invulnerables: vec![], - .. Default::default() + invulnerables: self.invulnerables, + slash_reward_fraction: Perbill::from_percent(10), + ..Default::default() }.assimilate_storage(&mut storage); let _ = session::GenesisConfig:: { @@ -371,11 +394,6 @@ pub fn check_nominator_exposure(stash: u64) { ); } -pub fn assert_total_expo(stash: u64, val: u64) { - let expo = Staking::stakers(&stash); - assert_eq!(expo.total, val); -} - pub fn assert_is_stash(acc: u64) { assert!(Staking::bonded(&acc).is_some(), "Not a stash."); } @@ -383,25 +401,30 @@ pub fn assert_is_stash(acc: u64) { pub fn bond_validator(acc: u64, val: u64) { // a = controller // a + 1 = stash - let _ = Balances::make_free_balance_be(&(acc+1), val); - assert_ok!(Staking::bond(Origin::signed(acc+1), acc, val, RewardDestination::Controller)); + let _ = Balances::make_free_balance_be(&(acc + 1), val); + assert_ok!(Staking::bond(Origin::signed(acc + 1), acc, val, RewardDestination::Controller)); assert_ok!(Staking::validate(Origin::signed(acc), ValidatorPrefs::default())); } pub fn bond_nominator(acc: u64, val: u64, target: Vec) { // a = controller // a + 1 = stash - let _ = Balances::make_free_balance_be(&(acc+1), val); - assert_ok!(Staking::bond(Origin::signed(acc+1), acc, val, RewardDestination::Controller)); + let _ = Balances::make_free_balance_be(&(acc + 1), val); + assert_ok!(Staking::bond(Origin::signed(acc + 1), acc, val, RewardDestination::Controller)); assert_ok!(Staking::nominate(Origin::signed(acc), target)); } -pub fn start_session(session_index: session::SessionIndex) { +pub fn advance_session() { + let current_index = Session::current_index(); + start_session(current_index + 1); +} + +pub fn start_session(session_index: SessionIndex) { // Compensate for session delay let session_index = session_index + 1; for i in Session::current_index()..session_index { System::set_block_number((i + 1).into()); - Timestamp::set_timestamp(System::block_number()); + Timestamp::set_timestamp(System::block_number() * 1000); Session::on_initialize(System::block_number()); } @@ -415,7 +438,8 @@ pub fn start_era(era_index: EraIndex) { pub fn current_total_payout_for_duration(duration: u64) -> u64 { let res = inflation::compute_total_payout( - >::slot_stake()*2, + ::RewardCurve::get(), + >::slot_stake() * 2, Balances::total_issuance(), duration, ); diff --git a/srml/staking/src/phragmen.rs b/srml/staking/src/phragmen.rs deleted file mode 100644 index 14b8a3845f2c497e570c9404272a8d4698d3eaf2..0000000000000000000000000000000000000000 --- a/srml/staking/src/phragmen.rs +++ /dev/null @@ -1,393 +0,0 @@ -// Copyright 2019 Parity Technologies (UK) Ltd. -// This file is part of Substrate. - -// Substrate 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. - -// Substrate 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 Substrate. If not, see . - -//! Rust implementation of the Phragmén election algorithm. - -use rstd::{prelude::*, collections::btree_map::BTreeMap}; -use sr_primitives::{PerU128}; -use sr_primitives::traits::{Zero, Convert, Saturating}; -use crate::{BalanceOf, RawAssignment, ExpoMap, Trait, ValidatorPrefs, IndividualExposure}; - -type Fraction = PerU128; -/// Wrapper around the type used as the _safe_ wrapper around a `balance`. -pub type ExtendedBalance = u128; - -// this is only used while creating the candidate score. Due to reasons explained below -// The more accurate this is, the less likely we choose a wrong candidate. -const SCALE_FACTOR: ExtendedBalance = u32::max_value() as ExtendedBalance + 1; -/// These are used to expose a fixed accuracy to the caller function. The bigger they are, -/// the more accurate we get, but the more likely it is for us to overflow. The case of overflow -/// is handled but accuracy will be lost. 32 or 16 are reasonable values. -pub const ACCURACY: ExtendedBalance = u32::max_value() as ExtendedBalance + 1; - -/// Wrapper around validation candidates some metadata. -#[derive(Clone, Default)] -#[cfg_attr(feature = "std", derive(Debug))] -pub struct Candidate { - /// The validator's account - pub who: AccountId, - /// Intermediary value used to sort candidates. - pub score: Fraction, - /// Accumulator of the stake of this candidate based on received votes. - approval_stake: ExtendedBalance, - /// Flag for being elected. - elected: bool, -} - -/// Wrapper around the nomination info of a single nominator for a group of validators. -#[derive(Clone, Default)] -#[cfg_attr(feature = "std", derive(Debug))] -pub struct Nominator { - /// The nominator's account. - who: AccountId, - /// List of validators proposed by this nominator. - edges: Vec>, - /// the stake amount proposed by the nominator as a part of the vote. - budget: ExtendedBalance, - /// Incremented each time a nominee that this nominator voted for has been elected. - load: Fraction, -} - -/// Wrapper around a nominator vote and the load of that vote. -#[derive(Clone, Default)] -#[cfg_attr(feature = "std", derive(Debug))] -pub struct Edge { - /// Account being voted for - who: AccountId, - /// Load of this vote. - load: Fraction, - /// Equal to `edge.load / nom.load`. Stored only to be used with post-processing. - ratio: ExtendedBalance, - /// Index of the candidate stored in the 'candidates' vector. - candidate_index: usize, -} - -/// Perform election based on Phragmén algorithm. -/// -/// Reference implementation: https://github.com/w3f/consensus -/// -/// Returns an Option of elected candidates, if election is performed. -/// Returns None if not enough candidates exist. -/// -/// The returned Option is a tuple consisting of: -/// - The list of elected candidates. -/// - The list of nominators and their associated vote weights. -pub fn elect( - validator_count: usize, - minimum_validator_count: usize, - validator_iter: FV, - nominator_iter: FN, - slashable_balance_of: FS, -) -> Option<(Vec, Vec<(T::AccountId, Vec>)>)> where - FV: Iterator>)>, - FN: Iterator)>, - for <'r> FS: Fn(&'r T::AccountId) -> BalanceOf, -{ - let to_votes = |b: BalanceOf| , u64>>::convert(b) as ExtendedBalance; - - // return structures - let mut elected_candidates: Vec; - let mut assigned: Vec<(T::AccountId, Vec>)>; - let mut c_idx_cache = BTreeMap::::new(); - - // 1- Pre-process candidates and place them in a container, optimisation and add phantom votes. - // Candidates who have 0 stake => have no votes or all null-votes. Kick them out not. - let mut nominators: Vec> = - Vec::with_capacity(validator_iter.size_hint().0 + nominator_iter.size_hint().0); - let mut candidates = validator_iter.map(|(who, _)| { - let stash_balance = slashable_balance_of(&who); - (Candidate { who, ..Default::default() }, stash_balance) - }) - .filter_map(|(mut c, s)| { - c.approval_stake += to_votes(s); - if c.approval_stake.is_zero() { - None - } else { - Some((c, s)) - } - }) - .enumerate() - .map(|(idx, (c, s))| { - nominators.push(Nominator { - who: c.who.clone(), - edges: vec![ Edge { who: c.who.clone(), candidate_index: idx, ..Default::default() }], - budget: to_votes(s), - load: Fraction::zero(), - }); - c_idx_cache.insert(c.who.clone(), idx); - c - }) - .collect::>>(); - - // 2- Collect the nominators with the associated votes. - // Also collect approval stake along the way. - nominators.extend(nominator_iter.map(|(who, nominees)| { - let nominator_stake = slashable_balance_of(&who); - let mut edges: Vec> = Vec::with_capacity(nominees.len()); - for n in &nominees { - if let Some(idx) = c_idx_cache.get(n) { - // This candidate is valid + already cached. - candidates[*idx].approval_stake = candidates[*idx].approval_stake - .saturating_add(to_votes(nominator_stake)); - edges.push(Edge { who: n.clone(), candidate_index: *idx, ..Default::default() }); - } // else {} would be wrong votes. We don't really care about it. - } - Nominator { - who, - edges: edges, - budget: to_votes(nominator_stake), - load: Fraction::zero(), - } - })); - - // 4- If we have more candidates then needed, run Phragmén. - if candidates.len() >= minimum_validator_count { - let validator_count = validator_count.min(candidates.len()); - - elected_candidates = Vec::with_capacity(validator_count); - assigned = Vec::with_capacity(validator_count); - // Main election loop - for _round in 0..validator_count { - // Loop 1: initialize score - for c in &mut candidates { - if !c.elected { - c.score = Fraction::from_xth(c.approval_stake); - } - } - // Loop 2: increment score. - for n in &nominators { - for e in &n.edges { - let c = &mut candidates[e.candidate_index]; - if !c.elected && !c.approval_stake.is_zero() { - // Basic fixed-point shifting by 32. - // `n.budget.saturating_mul(SCALE_FACTOR)` will never saturate - // since n.budget cannot exceed u64,despite being stored in u128. yet, - // `*n.load / SCALE_FACTOR` might collapse to zero. Hence, 32 or 16 bits are better scale factors. - // Note that left-associativity in operators precedence is crucially important here. - let temp = - n.budget.saturating_mul(SCALE_FACTOR) / c.approval_stake - * (*n.load / SCALE_FACTOR); - c.score = Fraction::from_parts((*c.score).saturating_add(temp)); - } - } - } - - // Find the best - if let Some(winner) = candidates - .iter_mut() - .filter(|c| !c.elected) - .min_by_key(|c| *c.score) - { - // loop 3: update nominator and edge load - winner.elected = true; - for n in &mut nominators { - for e in &mut n.edges { - if e.who == winner.who { - e.load = Fraction::from_parts(*winner.score - *n.load); - n.load = winner.score; - } - } - } - - elected_candidates.push(winner.who.clone()); - } else { - break - } - } // end of all rounds - - // 4.1- Update backing stake of candidates and nominators - for n in &mut nominators { - let mut assignment = (n.who.clone(), vec![]); - for e in &mut n.edges { - if let Some(c) = elected_candidates.iter().find(|c| **c == e.who) { - if *c != n.who { - let ratio = { - // Full support. No need to calculate. - if *n.load == *e.load { ACCURACY } - else { - // This should not saturate. Safest is to just check - if let Some(r) = ACCURACY.checked_mul(*e.load) { - r / n.load.max(1) - } else { - // Just a simple trick. - *e.load / (n.load.max(1) / ACCURACY) - } - } - }; - e.ratio = ratio; - assignment.1.push((e.who.clone(), ratio)); - } - } - } - - if assignment.1.len() > 0 { - // To ensure an assertion indicating: no stake from the nominator going to waste, - // we add a minimal post-processing to equally assign all of the leftover stake ratios. - let vote_count = assignment.1.len() as ExtendedBalance; - let l = assignment.1.len(); - let sum = assignment.1.iter().map(|a| a.1).sum::(); - let diff = ACCURACY.checked_sub(sum).unwrap_or(0); - let diff_per_vote= diff / vote_count; - - if diff_per_vote > 0 { - for i in 0..l { - assignment.1[i%l].1 = - assignment.1[i%l].1 - .saturating_add(diff_per_vote); - } - } - - // `remainder` is set to be less than maximum votes of a nominator (currently 16). - // safe to cast it to usize. - let remainder = diff - diff_per_vote * vote_count; - for i in 0..remainder as usize { - assignment.1[i%l].1 = - assignment.1[i%l].1 - .saturating_add(1); - } - assigned.push(assignment); - } - } - - } else { - // if we have less than minimum, use the previous validator set. - return None - } - Some((elected_candidates, assigned)) -} - -/// Performs equalize post-processing to the output of the election algorithm -/// This function mutates the input parameters, most noticeably it updates the exposure of -/// the elected candidates. -/// -/// No value is returned from the function and the `expo_map` parameter is updated. -pub fn equalize( - assignments: &mut Vec<(T::AccountId, BalanceOf, Vec<(T::AccountId, ExtendedBalance, ExtendedBalance)>)>, - expo_map: &mut ExpoMap, - tolerance: ExtendedBalance, - iterations: usize, -) { - for _i in 0..iterations { - let mut max_diff = 0; - assignments.iter_mut().for_each(|(n, budget, assignment)| { - let diff = do_equalize::(&n, *budget, assignment, expo_map, tolerance); - if diff > max_diff { - max_diff = diff; - } - }); - if max_diff < tolerance { - break; - } - } -} - -fn do_equalize( - nominator: &T::AccountId, - budget_balance: BalanceOf, - elected_edges: &mut Vec<(T::AccountId, ExtendedBalance, ExtendedBalance)>, - expo_map: &mut ExpoMap, - tolerance: ExtendedBalance -) -> ExtendedBalance { - let to_votes = |b: BalanceOf| - , u64>>::convert(b) as ExtendedBalance; - let to_balance = |v: ExtendedBalance| - >>::convert(v); - let budget = to_votes(budget_balance); - - // Nothing to do. This nominator had nothing useful. - // Defensive only. Assignment list should always be populated. - if elected_edges.is_empty() { return 0; } - - let stake_used = elected_edges - .iter() - .fold(0 as ExtendedBalance, |s, e| s.saturating_add(e.2)); - - let backed_stakes_iter = elected_edges - .iter() - .filter_map(|e| expo_map.get(&e.0)) - .map(|e| to_votes(e.total)); - - let backing_backed_stake = elected_edges - .iter() - .filter(|e| e.2 > 0) - .filter_map(|e| expo_map.get(&e.0)) - .map(|e| to_votes(e.total)) - .collect::>(); - - let mut difference; - if backing_backed_stake.len() > 0 { - let max_stake = backing_backed_stake - .iter() - .max() - .expect("vector with positive length will have a max; qed"); - let min_stake = backed_stakes_iter - .min() - .expect("iterator with positive length will have a min; qed"); - - difference = max_stake.saturating_sub(min_stake); - difference = difference.saturating_add(budget.saturating_sub(stake_used)); - if difference < tolerance { - return difference; - } - } else { - difference = budget; - } - - // Undo updates to exposure - elected_edges.iter_mut().for_each(|e| { - if let Some(expo) = expo_map.get_mut(&e.0) { - expo.total = expo.total.saturating_sub(to_balance(e.2)); - expo.others.retain(|i_expo| i_expo.who != *nominator); - } - e.2 = 0; - }); - - elected_edges.sort_unstable_by_key(|e| - if let Some(e) = expo_map.get(&e.0) { e.total } else { Zero::zero() } - ); - - let mut cumulative_stake: ExtendedBalance = 0; - let mut last_index = elected_edges.len() - 1; - elected_edges.iter_mut().enumerate().for_each(|(idx, e)| { - if let Some(expo) = expo_map.get_mut(&e.0) { - let stake: ExtendedBalance = to_votes(expo.total); - let stake_mul = stake.saturating_mul(idx as ExtendedBalance); - let stake_sub = stake_mul.saturating_sub(cumulative_stake); - if stake_sub > budget { - last_index = idx.checked_sub(1).unwrap_or(0); - return - } - cumulative_stake = cumulative_stake.saturating_add(stake); - } - }); - - let last_stake = elected_edges[last_index].2; - let split_ways = last_index + 1; - let excess = budget - .saturating_add(cumulative_stake) - .saturating_sub(last_stake.saturating_mul(split_ways as ExtendedBalance)); - elected_edges.iter_mut().take(split_ways).for_each(|e| { - if let Some(expo) = expo_map.get_mut(&e.0) { - e.2 = (excess / split_ways as ExtendedBalance) - .saturating_add(last_stake) - .saturating_sub(to_votes(expo.total)); - expo.total = expo.total.saturating_add(to_balance(e.2)); - expo.others.push(IndividualExposure { who: nominator.clone(), value: to_balance(e.2)}); - } - }); - - difference -} diff --git a/srml/staking/src/tests.rs b/srml/staking/src/tests.rs index de473dd9902fc0cb114700cb090693ade80de5d6..6b51fb9b3f0d8abddb75d214f48886c6c9e13388 100644 --- a/srml/staking/src/tests.rs +++ b/srml/staking/src/tests.rs @@ -17,12 +17,12 @@ //! Tests for the module. use super::*; -use runtime_io::with_externalities; -use phragmen; -use sr_primitives::traits::OnInitialize; -use srml_support::{assert_ok, assert_noop, assert_eq_uvec, EnumerableStorageMap}; use mock::*; -use srml_support::traits::{Currency, ReservableCurrency}; +use runtime_io::with_externalities; +use sr_primitives::{assert_eq_error_rate, traits::OnInitialize}; +use sr_staking_primitives::offence::{OffenceDetails, OnOffenceHandler}; +use support::{assert_ok, assert_noop, assert_eq_uvec}; +use support::traits::{Currency, ReservableCurrency}; #[test] fn basic_setup_works() { @@ -30,26 +30,37 @@ fn basic_setup_works() { with_externalities(&mut ExtBuilder::default() .build(), || { - assert_eq!(Staking::bonded(&11), Some(10)); // Account 11 is stashed and locked, and account 10 is the controller - assert_eq!(Staking::bonded(&21), Some(20)); // Account 21 is stashed and locked, and account 20 is the controller - assert_eq!(Staking::bonded(&1), None); // Account 1 is not a stashed + // Account 11 is stashed and locked, and account 10 is the controller + assert_eq!(Staking::bonded(&11), Some(10)); + // Account 21 is stashed and locked, and account 20 is the controller + assert_eq!(Staking::bonded(&21), Some(20)); + // Account 1 is not a stashed + assert_eq!(Staking::bonded(&1), None); // Account 10 controls the stash from account 11, which is 100 * balance_factor units - assert_eq!(Staking::ledger(&10), Some(StakingLedger { stash: 11, total: 1000, active: 1000, unlocking: vec![] })); + assert_eq!( + Staking::ledger(&10), + Some(StakingLedger { stash: 11, total: 1000, active: 1000, unlocking: vec![] }) + ); // Account 20 controls the stash from account 21, which is 200 * balance_factor units - assert_eq!(Staking::ledger(&20), Some(StakingLedger { stash: 21, total: 1000, active: 1000, unlocking: vec![] })); + assert_eq!( + Staking::ledger(&20), + Some(StakingLedger { stash: 21, total: 1000, active: 1000, unlocking: vec![] }) + ); // Account 1 does not control any stash assert_eq!(Staking::ledger(&1), None); - // ValidatorPrefs are default, thus unstake_threshold is 3, other values are default for their type + // ValidatorPrefs are default assert_eq!(>::enumerate().collect::>(), vec![ - (31, ValidatorPrefs { unstake_threshold: 3, validator_payment: 0 }), - (21, ValidatorPrefs { unstake_threshold: 3, validator_payment: 0 }), - (11, ValidatorPrefs { unstake_threshold: 3, validator_payment: 0 }) + (31, ValidatorPrefs::default()), + (21, ValidatorPrefs::default()), + (11, ValidatorPrefs::default()) ]); - // Account 100 is the default nominator - assert_eq!(Staking::ledger(100), Some(StakingLedger { stash: 101, total: 500, active: 500, unlocking: vec![] })); + assert_eq!( + Staking::ledger(100), + Some(StakingLedger { stash: 101, total: 500, active: 500, unlocking: vec![] }) + ); assert_eq!(Staking::nominators(101), vec![11, 21]); if cfg!(feature = "equalize") { @@ -83,32 +94,16 @@ fn basic_setup_works() { // Initial Era and session assert_eq!(Staking::current_era(), 0); - // initial slash_count of validators - assert_eq!(Staking::slash_count(&11), 0); - assert_eq!(Staking::slash_count(&21), 0); - - // All exposures must be correct. - check_exposure_all(); - check_nominator_all(); - }); -} - -#[test] -fn no_offline_should_work() { - // Test the staking module works when no validators are offline - with_externalities(&mut ExtBuilder::default().build(), - || { - // Slashing begins for validators immediately if found offline - assert_eq!(Staking::offline_slash_grace(), 0); - // Account 10 has not been reported offline - assert_eq!(Staking::slash_count(&10), 0); // Account 10 has `balance_factor` free balance assert_eq!(Balances::free_balance(&10), 1); - // Nothing happens to Account 10, as expected - assert_eq!(Staking::slash_count(&10), 0); assert_eq!(Balances::free_balance(&10), 1); + // New era is not being forced assert_eq!(Staking::force_era(), Forcing::NotForcing); + + // All exposures must be correct. + check_exposure_all(); + check_nominator_all(); }); } @@ -135,183 +130,6 @@ fn change_controller_works() { }) } -#[test] -fn invulnerability_should_work() { - // Test that users can be invulnerable from slashing and being kicked - with_externalities(&mut ExtBuilder::default().build(), - || { - // Make account 11 invulnerable - assert_ok!(Staking::set_invulnerables(Origin::ROOT, vec![11])); - // Give account 11 some funds - let _ = Balances::make_free_balance_be(&11, 70); - // There is no slash grace -- slash immediately. - assert_eq!(Staking::offline_slash_grace(), 0); - // Account 11 has not been slashed - assert_eq!(Staking::slash_count(&11), 0); - // Account 11 has the 70 funds we gave it above - assert_eq!(Balances::free_balance(&11), 70); - // Account 11 should be a validator - assert!(>::exists(&11)); - - // Set account 11 as an offline validator with a large number of reports - // Should exit early if invulnerable - Staking::on_offline_validator(10, 100); - - // Show that account 11 has not been touched - assert_eq!(Staking::slash_count(&11), 0); - assert_eq!(Balances::free_balance(&11), 70); - assert!(>::exists(&11)); - // New era not being forced - // NOTE: new era is always forced once slashing happens -> new validators need to be chosen. - assert_eq!(Staking::force_era(), Forcing::NotForcing); - }); -} - -#[test] -fn offline_should_slash_and_disable() { - // Test that an offline validator gets slashed and kicked - with_externalities(&mut ExtBuilder::default().build(), || { - // Give account 10 some balance - let _ = Balances::make_free_balance_be(&11, 1000); - // Confirm account 10 is a validator - assert!(>::exists(&11)); - // Validators get slashed immediately - assert_eq!(Staking::offline_slash_grace(), 0); - // Unstake threshold is 3 - assert_eq!(Staking::validators(&11).unstake_threshold, 3); - // Account 10 has not been slashed before - assert_eq!(Staking::slash_count(&11), 0); - // Account 10 has the funds we just gave it - assert_eq!(Balances::free_balance(&11), 1000); - // Account 10 is not yet disabled. - assert!(!is_disabled(10)); - // Report account 10 as offline, one greater than unstake threshold - Staking::on_offline_validator(10, 4); - // Confirm user has been reported - assert_eq!(Staking::slash_count(&11), 4); - // Confirm balance has been reduced by 2^unstake_threshold * offline_slash() * amount_at_stake. - let slash_base = Staking::offline_slash() * Staking::stakers(11).total; - assert_eq!(Balances::free_balance(&11), 1000 - 2_u64.pow(3) * slash_base); - // Confirm account 10 has been disabled. - assert!(is_disabled(10)); - }); -} - -#[test] -fn offline_grace_should_delay_slashing() { - // Tests that with grace, slashing is delayed - with_externalities(&mut ExtBuilder::default().build(), || { - // Initialize account 10 with balance - let _ = Balances::make_free_balance_be(&11, 70); - // Verify account 11 has balance - assert_eq!(Balances::free_balance(&11), 70); - - // Set offline slash grace - let offline_slash_grace = 1; - assert_ok!(Staking::set_offline_slash_grace(Origin::ROOT, offline_slash_grace)); - assert_eq!(Staking::offline_slash_grace(), 1); - - // Check unstake_threshold is 3 (default) - let default_unstake_threshold = 3; - assert_eq!( - Staking::validators(&11), - ValidatorPrefs { unstake_threshold: default_unstake_threshold, validator_payment: 0 } - ); - - // Check slash count is zero - assert_eq!(Staking::slash_count(&11), 0); - - // Report account 10 up to the threshold - Staking::on_offline_validator(10, default_unstake_threshold as usize + offline_slash_grace as usize); - // Confirm slash count - assert_eq!(Staking::slash_count(&11), 4); - - // Nothing should happen - assert_eq!(Balances::free_balance(&11), 70); - - // Report account 10 one more time - Staking::on_offline_validator(10, 1); - assert_eq!(Staking::slash_count(&11), 5); - // User gets slashed - assert!(Balances::free_balance(&11) < 70); - // New era is forced - assert!(is_disabled(10)); - }); -} - - -#[test] -fn max_unstake_threshold_works() { - // Tests that max_unstake_threshold gets used when prefs.unstake_threshold is large - with_externalities(&mut ExtBuilder::default().build(), || { - const MAX_UNSTAKE_THRESHOLD: u32 = 10; - // Two users with maximum possible balance - let _ = Balances::make_free_balance_be(&11, u64::max_value()); - let _ = Balances::make_free_balance_be(&21, u64::max_value()); - - // Give them full exposure as a staker - >::insert(&11, Exposure { total: 1000000, own: 1000000, others: vec![]}); - >::insert(&21, Exposure { total: 2000000, own: 2000000, others: vec![]}); - - // Check things are initialized correctly - assert_eq!(Balances::free_balance(&11), u64::max_value()); - assert_eq!(Balances::free_balance(&21), u64::max_value()); - assert_eq!(Staking::offline_slash_grace(), 0); - // Account 10 will have max unstake_threshold - assert_ok!(Staking::validate(Origin::signed(10), ValidatorPrefs { - unstake_threshold: MAX_UNSTAKE_THRESHOLD, - validator_payment: 0, - })); - // Account 20 could not set their unstake_threshold past 10 - assert_noop!(Staking::validate(Origin::signed(20), ValidatorPrefs { - unstake_threshold: MAX_UNSTAKE_THRESHOLD + 1, - validator_payment: 0}), - "unstake threshold too large" - ); - // Give Account 20 unstake_threshold 11 anyway, should still be limited to 10 - >::insert(21, ValidatorPrefs { - unstake_threshold: MAX_UNSTAKE_THRESHOLD + 1, - validator_payment: 0, - }); - - OfflineSlash::put(Perbill::from_fraction(0.0001)); - - // Report each user 1 more than the max_unstake_threshold - Staking::on_offline_validator(10, MAX_UNSTAKE_THRESHOLD as usize + 1); - Staking::on_offline_validator(20, MAX_UNSTAKE_THRESHOLD as usize + 1); - - // Show that each balance only gets reduced by 2^max_unstake_threshold times 10% - // of their total stake. - assert_eq!(Balances::free_balance(&11), u64::max_value() - 2_u64.pow(MAX_UNSTAKE_THRESHOLD) * 100); - assert_eq!(Balances::free_balance(&21), u64::max_value() - 2_u64.pow(MAX_UNSTAKE_THRESHOLD) * 200); - }); -} - -#[test] -fn slashing_does_not_cause_underflow() { - // Tests that slashing more than a user has does not underflow - with_externalities(&mut ExtBuilder::default().build(), || { - // Verify initial conditions - assert_eq!(Balances::free_balance(&11), 1000); - assert_eq!(Staking::offline_slash_grace(), 0); - - // Set validator preference so that 2^unstake_threshold would cause overflow (greater than 64) - // FIXME: that doesn't overflow. - >::insert(11, ValidatorPrefs { - unstake_threshold: 10, - validator_payment: 0, - }); - - System::set_block_number(1); - Session::on_initialize(System::block_number()); - - // Should not panic - Staking::on_offline_validator(10, 100); - // Confirm that underflow has not occurred, and account balance is set to zero - assert_eq!(Balances::free_balance(&11), 0); - }); -} - #[test] fn rewards_should_work() { // should check that: @@ -325,7 +143,7 @@ fn rewards_should_work() { // Init some balances let _ = Balances::make_free_balance_be(&2, 500); - let delay = 1; + let delay = 1000; let init_balance_2 = Balances::total_balance(&2); let init_balance_10 = Balances::total_balance(&10); let init_balance_11 = Balances::total_balance(&11); @@ -353,7 +171,7 @@ fn rewards_should_work() { let mut block = 3; // Block 3 => Session 1 => Era 0 System::set_block_number(block); - Timestamp::set_timestamp(block*5); // on time. + Timestamp::set_timestamp(block * 5000); // on time. Session::on_initialize(System::block_number()); assert_eq!(Staking::current_era(), 0); assert_eq!(Session::current_index(), 1); @@ -365,7 +183,7 @@ fn rewards_should_work() { >::reward_by_ids(vec![(1001, 10_000)]); // Compute total payout now for whole duration as other parameter won't change - let total_payout = current_total_payout_for_duration(9 * 5); + let total_payout = current_total_payout_for_duration(9 * 5 * 1000); assert!(total_payout > 10); // Test is meaningful if reward something // No reward yet @@ -375,21 +193,21 @@ fn rewards_should_work() { block = 6; // Block 6 => Session 2 => Era 0 System::set_block_number(block); - Timestamp::set_timestamp(block*5 + delay); // a little late. + Timestamp::set_timestamp(block * 5000 + delay); // a little late. Session::on_initialize(System::block_number()); assert_eq!(Staking::current_era(), 0); assert_eq!(Session::current_index(), 2); block = 9; // Block 9 => Session 3 => Era 1 System::set_block_number(block); - Timestamp::set_timestamp(block*5); // back to being on time. no delays + Timestamp::set_timestamp(block * 5000); // back to being on time. no delays Session::on_initialize(System::block_number()); assert_eq!(Staking::current_era(), 1); assert_eq!(Session::current_index(), 3); // 11 validator has 2/3 of the total rewards and half half for it and its nominator - assert_eq!(Balances::total_balance(&2), init_balance_2 + total_payout/3); - assert_eq!(Balances::total_balance(&10), init_balance_10 + total_payout/3); + assert_eq_error_rate!(Balances::total_balance(&2), init_balance_2 + total_payout / 3, 1); + assert_eq_error_rate!(Balances::total_balance(&10), init_balance_10 + total_payout / 3, 1); assert_eq!(Balances::total_balance(&11), init_balance_11); }); } @@ -409,7 +227,7 @@ fn multi_era_reward_should_work() { assert_ok!(Staking::set_payee(Origin::signed(10), RewardDestination::Controller)); // Compute now as other parameter won't change - let total_payout_0 = current_total_payout_for_duration(3); + let total_payout_0 = current_total_payout_for_duration(3000); assert!(total_payout_0 > 10); // Test is meaningfull if reward something dbg!(>::slot_stake()); >::reward_by_ids(vec![(11, 1)]); @@ -424,7 +242,7 @@ fn multi_era_reward_should_work() { start_session(4); - let total_payout_1 = current_total_payout_for_duration(3); + let total_payout_1 = current_total_payout_for_duration(3000); assert!(total_payout_1 > 10); // Test is meaningfull if reward something >::reward_by_ids(vec![(11, 101)]); @@ -531,8 +349,6 @@ fn less_than_needed_candidates_works() { #[test] fn no_candidate_emergency_condition() { - // Test the situation where the number of validators are less than `ValidatorCount` and less than - // The expected behavior is to choose all candidates from the previous era. with_externalities(&mut ExtBuilder::default() .minimum_validator_count(10) .validator_count(15) @@ -566,7 +382,6 @@ fn no_candidate_emergency_condition() { fn nominating_and_rewards_should_work() { // PHRAGMEN OUTPUT: running this test with the reference impl gives: // - // Votes [('10', 1000, ['10']), ('20', 1000, ['20']), ('30', 1000, ['30']), ('40', 1000, ['40']), ('2', 1000, ['10', '20', '30']), ('4', 1000, ['10', '20', '40'])] // Sequential Phragmén gives // 10 is elected with stake 2200.0 and score 0.0003333333333333333 // 20 is elected with stake 1800.0 and score 0.0005555555555555556 @@ -629,7 +444,7 @@ fn nominating_and_rewards_should_work() { assert_ok!(Staking::nominate(Origin::signed(4), vec![11, 21, 41])); // the total reward for era 0 - let total_payout_0 = current_total_payout_for_duration(3); + let total_payout_0 = current_total_payout_for_duration(3000); assert!(total_payout_0 > 100); // Test is meaningfull if reward something >::reward_by_ids(vec![(41, 1)]); >::reward_by_ids(vec![(31, 1)]); @@ -642,19 +457,19 @@ fn nominating_and_rewards_should_work() { assert_eq_uvec!(validator_controllers(), vec![20, 10]); // OLD validators must have already received some rewards. - assert_eq!(Balances::total_balance(&40), 1 + total_payout_0/2); - assert_eq!(Balances::total_balance(&30), 1 + total_payout_0/2); + assert_eq!(Balances::total_balance(&40), 1 + total_payout_0 / 2); + assert_eq!(Balances::total_balance(&30), 1 + total_payout_0 / 2); // ------ check the staked value of all parties. if cfg!(feature = "equalize") { // total expo of 10, with 1200 coming from nominators (externals), according to phragmen. assert_eq!(Staking::stakers(11).own, 1000); - assert_eq!(Staking::stakers(11).total, 1000 + 999); + assert_eq_error_rate!(Staking::stakers(11).total, 1000 + 1000, 2); // 2 and 4 supported 10, each with stake 600, according to phragmen. assert_eq!( Staking::stakers(11).others.iter().map(|e| e.value).collect::>>(), - vec![599, 400] + vec![600, 400] ); assert_eq!( Staking::stakers(11).others.iter().map(|e| e.who).collect::>(), @@ -662,11 +477,11 @@ fn nominating_and_rewards_should_work() { ); // total expo of 20, with 500 coming from nominators (externals), according to phragmen. assert_eq!(Staking::stakers(21).own, 1000); - assert_eq!(Staking::stakers(21).total, 1000 + 999); + assert_eq_error_rate!(Staking::stakers(21).total, 1000 + 1000, 2); // 2 and 4 supported 20, each with stake 250, according to phragmen. assert_eq!( Staking::stakers(21).others.iter().map(|e| e.value).collect::>>(), - vec![400, 599] + vec![400, 600] ); assert_eq!( Staking::stakers(21).others.iter().map(|e| e.who).collect::>(), @@ -687,11 +502,11 @@ fn nominating_and_rewards_should_work() { ); // total expo of 20, with 500 coming from nominators (externals), according to phragmen. assert_eq!(Staking::stakers(21).own, 1000); - assert_eq!(Staking::stakers(21).total, 1000 + 1198); + assert_eq_error_rate!(Staking::stakers(21).total, 1000 + 1200, 2); // 2 and 4 supported 20, each with stake 250, according to phragmen. assert_eq!( Staking::stakers(21).others.iter().map(|e| e.value).collect::>>(), - vec![599, 599] + vec![600, 600] ); assert_eq!( Staking::stakers(21).others.iter().map(|e| e.who).collect::>(), @@ -704,7 +519,7 @@ fn nominating_and_rewards_should_work() { assert_eq!(Staking::stakers(41).total, 0); // the total reward for era 1 - let total_payout_1 = current_total_payout_for_duration(3); + let total_payout_1 = current_total_payout_for_duration(3000); assert!(total_payout_1 > 100); // Test is meaningfull if reward something >::reward_by_ids(vec![(41, 10)]); // must be no-op >::reward_by_ids(vec![(31, 10)]); // must be no-op @@ -716,28 +531,60 @@ fn nominating_and_rewards_should_work() { // nothing else will happen, era ends and rewards are paid again, // it is expected that nominators will also be paid. See below - let payout_for_10 = total_payout_1/3; - let payout_for_20 = 2*total_payout_1/3; + let payout_for_10 = total_payout_1 / 3; + let payout_for_20 = 2 * total_payout_1 / 3; if cfg!(feature = "equalize") { - // Nominator 2: has [400/2000 ~ 1/5 from 10] + [600/2000 ~ 3/10 from 20]'s reward. - assert_eq!(Balances::total_balance(&2), initial_balance + payout_for_10/5 + payout_for_20*3/10 - 1); - // Nominator 4: has [400/2000 ~ 1/5 from 20] + [600/2000 ~ 3/10 from 10]'s reward. - assert_eq!(Balances::total_balance(&4), initial_balance + payout_for_20/5 + payout_for_10*3/10); + // Nominator 2: has [400 / 2000 ~ 1 / 5 from 10] + [600 / 2000 ~ 3 / 10 from 20]'s reward. + assert_eq_error_rate!( + Balances::total_balance(&2), + initial_balance + payout_for_10 / 5 + payout_for_20 * 3 / 10, + 2, + ); + // Nominator 4: has [400 / 2000 ~ 1 / 5 from 20] + [600 / 2000 ~ 3 / 10 from 10]'s reward. + assert_eq_error_rate!( + Balances::total_balance(&4), + initial_balance + payout_for_20 / 5 + payout_for_10 * 3 / 10, + 2, + ); // Validator 10: got 1000 / 2000 external stake. - assert_eq!(Balances::total_balance(&10), initial_balance + payout_for_10/2); + assert_eq_error_rate!( + Balances::total_balance(&10), + initial_balance + payout_for_10 / 2, + 1, + ); // Validator 20: got 1000 / 2000 external stake. - assert_eq!(Balances::total_balance(&20), initial_balance + payout_for_20/2); + assert_eq_error_rate!( + Balances::total_balance(&20), + initial_balance + payout_for_20 / 2, + 1, + ); } else { // Nominator 2: has [400/1800 ~ 2/9 from 10] + [600/2200 ~ 3/11 from 20]'s reward. ==> 2/9 + 3/11 - assert_eq!(Balances::total_balance(&2), initial_balance + (2*payout_for_10/9 + 3*payout_for_20/11) - 2); + assert_eq_error_rate!( + Balances::total_balance(&2), + initial_balance + (2 * payout_for_10 / 9 + 3 * payout_for_20 / 11), + 1, + ); // Nominator 4: has [400/1800 ~ 2/9 from 10] + [600/2200 ~ 3/11 from 20]'s reward. ==> 2/9 + 3/11 - assert_eq!(Balances::total_balance(&4), initial_balance + (2*payout_for_10/9 + 3*payout_for_20/11) - 2); + assert_eq_error_rate!( + Balances::total_balance(&4), + initial_balance + (2 * payout_for_10 / 9 + 3 * payout_for_20 / 11), + 1, + ); // Validator 10: got 800 / 1800 external stake => 8/18 =? 4/9 => Validator's share = 5/9 - assert_eq!(Balances::total_balance(&10), initial_balance + 5*payout_for_10/9 - 1); + assert_eq_error_rate!( + Balances::total_balance(&10), + initial_balance + 5 * payout_for_10 / 9, + 1, + ); // Validator 20: got 1200 / 2200 external stake => 12/22 =? 6/11 => Validator's share = 5/11 - assert_eq!(Balances::total_balance(&20), initial_balance + 5*payout_for_20/11); + assert_eq_error_rate!( + Balances::total_balance(&20), + initial_balance + 5 * payout_for_20 / 11, + 1, + ); } check_exposure_all(); @@ -748,13 +595,12 @@ fn nominating_and_rewards_should_work() { #[test] fn nominators_also_get_slashed() { // A nominator should be slashed if the validator they nominated is slashed + // Here is the breakdown of roles: + // 10 - is the controller of 11 + // 11 - is the stash. + // 2 - is the nominator of 20, 10 with_externalities(&mut ExtBuilder::default().nominate(false).build(), || { assert_eq!(Staking::validator_count(), 2); - // slash happens immediately. - assert_eq!(Staking::offline_slash_grace(), 0); - // Account 10 has not been reported offline - assert_eq!(Staking::slash_count(&10), 0); - OfflineSlash::put(Perbill::from_percent(12)); // Set payee to controller assert_ok!(Staking::set_payee(Origin::signed(10), RewardDestination::Controller)); @@ -765,12 +611,12 @@ fn nominators_also_get_slashed() { let _ = Balances::make_free_balance_be(i, initial_balance); } - // 2 will nominate for 10 + // 2 will nominate for 10, 20 let nominator_stake = 500; assert_ok!(Staking::bond(Origin::signed(1), 2, nominator_stake, RewardDestination::default())); assert_ok!(Staking::nominate(Origin::signed(2), vec![20, 10])); - let total_payout = current_total_payout_for_duration(3); + let total_payout = current_total_payout_for_duration(3000); assert!(total_payout > 100); // Test is meaningfull if reward something >::reward_by_ids(vec![(11, 1)]); @@ -781,15 +627,24 @@ fn nominators_also_get_slashed() { assert_eq!(Balances::total_balance(&2), initial_balance); // 10 goes offline - Staking::on_offline_validator(10, 4); - let expo = Staking::stakers(10); - let slash_value = Staking::offline_slash() * expo.total * 2_u64.pow(3); + Staking::on_offence( + &[OffenceDetails { + offender: ( + 11, + Staking::stakers(&11), + ), + reporters: vec![], + }], + &[Perbill::from_percent(5)], + ); + let expo = Staking::stakers(11); + let slash_value = 50; let total_slash = expo.total.min(slash_value); let validator_slash = expo.own.min(total_slash); let nominator_slash = nominator_stake.min(total_slash - validator_slash); // initial + first era reward + slash - assert_eq!(Balances::total_balance(&10), initial_balance + total_payout - validator_slash); + assert_eq!(Balances::total_balance(&11), initial_balance - validator_slash); assert_eq!(Balances::total_balance(&2), initial_balance - nominator_slash); check_exposure_all(); check_nominator_all(); @@ -834,9 +689,15 @@ fn double_controlling_should_fail() { || { let arbitrary_value = 5; // 2 = controller, 1 stashed => ok - assert_ok!(Staking::bond(Origin::signed(1), 2, arbitrary_value, RewardDestination::default())); + assert_ok!( + Staking::bond(Origin::signed(1), 2, arbitrary_value, + RewardDestination::default()) + ); // 2 = controller, 3 stashed (Note that 2 is reused.) => no-op - assert_noop!(Staking::bond(Origin::signed(3), 2, arbitrary_value, RewardDestination::default()), "controller already paired"); + assert_noop!( + Staking::bond(Origin::signed(3), 2, arbitrary_value, RewardDestination::default()), + "controller already paired" + ); }); } @@ -907,10 +768,11 @@ fn forcing_new_era_works() { start_session(6); assert_eq!(Staking::current_era(), 1); - // back to normal + // back to normal. + // this immediatelly starts a new session. ForceEra::put(Forcing::NotForcing); start_session(7); - assert_eq!(Staking::current_era(), 1); + assert_eq!(Staking::current_era(), 2); start_session(8); assert_eq!(Staking::current_era(), 2); @@ -932,7 +794,10 @@ fn cannot_transfer_staked_balance() { // Confirm account 11 (via controller 10) is totally staked assert_eq!(Staking::stakers(&11).total, 1000); // Confirm account 11 cannot transfer as a result - assert_noop!(Balances::transfer(Origin::signed(11), 20, 1), "account liquidity restrictions prevent withdrawal"); + assert_noop!( + Balances::transfer(Origin::signed(11), 20, 1), + "account liquidity restrictions prevent withdrawal", + ); // Give account 11 extra free balance let _ = Balances::make_free_balance_be(&11, 10000); @@ -958,7 +823,10 @@ fn cannot_transfer_staked_balance_2() { // Confirm account 21 (via controller 20) is totally staked assert_eq!(Staking::stakers(&21).total, 1000); // Confirm account 21 can transfer at most 1000 - assert_noop!(Balances::transfer(Origin::signed(21), 20, 1001), "account liquidity restrictions prevent withdrawal"); + assert_noop!( + Balances::transfer(Origin::signed(21), 20, 1001), + "account liquidity restrictions prevent withdrawal", + ); assert_ok!(Balances::transfer(Origin::signed(21), 20, 1000)); }); } @@ -1002,7 +870,7 @@ fn reward_destination_works() { })); // Compute total payout now for whole duration as other parameter won't change - let total_payout_0 = current_total_payout_for_duration(3); + let total_payout_0 = current_total_payout_for_duration(3000); assert!(total_payout_0 > 100); // Test is meaningfull if reward something >::reward_by_ids(vec![(11, 1)]); @@ -1024,7 +892,7 @@ fn reward_destination_works() { >::insert(&11, RewardDestination::Stash); // Compute total payout now for whole duration as other parameter won't change - let total_payout_1 = current_total_payout_for_duration(3); + let total_payout_1 = current_total_payout_for_duration(3000); assert!(total_payout_1 > 100); // Test is meaningfull if reward something >::reward_by_ids(vec![(11, 1)]); @@ -1051,7 +919,7 @@ fn reward_destination_works() { assert_eq!(Balances::free_balance(&10), 1); // Compute total payout now for whole duration as other parameter won't change - let total_payout_2 = current_total_payout_for_duration(3); + let total_payout_2 = current_total_payout_for_duration(3000); assert!(total_payout_2 > 100); // Test is meaningfull if reward something >::reward_by_ids(vec![(11, 1)]); @@ -1100,12 +968,11 @@ fn validator_payment_prefs_work() { }); >::insert(&2, RewardDestination::Stash); >::insert(&11, ValidatorPrefs { - unstake_threshold: 3, validator_payment: validator_cut }); // Compute total payout now for whole duration as other parameter won't change - let total_payout_0 = current_total_payout_for_duration(3); + let total_payout_0 = current_total_payout_for_duration(3000); assert!(total_payout_0 > 100); // Test is meaningfull if reward something >::reward_by_ids(vec![(11, 1)]); @@ -1114,11 +981,11 @@ fn validator_payment_prefs_work() { // whats left to be shared is the sum of 3 rounds minus the validator's cut. let shared_cut = total_payout_0 - validator_cut; // Validator's payee is Staked account, 11, reward will be paid here. - assert_eq!(Balances::total_balance(&11), stash_initial_balance + shared_cut/2 + validator_cut); + assert_eq!(Balances::total_balance(&11), stash_initial_balance + shared_cut / 2 + validator_cut); // Controller account will not get any reward. assert_eq!(Balances::total_balance(&10), 1); // Rest of the reward will be shared and paid to the nominator in stake. - assert_eq!(Balances::total_balance(&2), 500 + shared_cut/2); + assert_eq!(Balances::total_balance(&2), 500 + shared_cut / 2); check_exposure_all(); check_nominator_all(); @@ -1319,7 +1186,7 @@ fn slot_stake_is_least_staked_validator_and_exposure_defines_maximum_punishment( >::insert(&20, StakingLedger { stash: 22, total: 69, active: 69, unlocking: vec![] }); // Compute total payout now for whole duration as other parameter won't change - let total_payout_0 = current_total_payout_for_duration(3); + let total_payout_0 = current_total_payout_for_duration(3000); assert!(total_payout_0 > 100); // Test is meaningfull if reward something >::reward_by_ids(vec![(11, 1)]); >::reward_by_ids(vec![(21, 1)]); @@ -1328,21 +1195,14 @@ fn slot_stake_is_least_staked_validator_and_exposure_defines_maximum_punishment( start_era(1); // -- new balances + reward - assert_eq!(Staking::stakers(&11).total, 1000 + total_payout_0/2); - assert_eq!(Staking::stakers(&21).total, 69 + total_payout_0/2); + assert_eq!(Staking::stakers(&11).total, 1000 + total_payout_0 / 2); + assert_eq!(Staking::stakers(&21).total, 69 + total_payout_0 / 2); let _11_balance = Balances::free_balance(&11); - assert_eq!(_11_balance, 1000 + total_payout_0/2); + assert_eq!(_11_balance, 1000 + total_payout_0 / 2); // -- slot stake should also be updated. - assert_eq!(Staking::slot_stake(), 69 + total_payout_0/2); - - // If 10 gets slashed now, it will be slashed by 5% of exposure.total * 2.pow(unstake_thresh) - Staking::on_offline_validator(10, 4); - // Confirm user has been reported - assert_eq!(Staking::slash_count(&11), 4); - // check the balance of 10 (slash will be deducted from free balance.) - assert_eq!(Balances::free_balance(&11), _11_balance - _11_balance*5/100 * 2u64.pow(3)); + assert_eq!(Staking::slot_stake(), 69 + total_payout_0 / 2); check_exposure_all(); check_nominator_all(); @@ -1365,8 +1225,6 @@ fn on_free_balance_zero_stash_removes_validator() { assert_eq!(Staking::bonded(&11), Some(10)); // Set some storage items which we expect to be cleaned up - // Initiate slash count storage item - Staking::on_offline_validator(10, 1); // Set payee information assert_ok!(Staking::set_payee(Origin::signed(10), RewardDestination::Stash)); @@ -1374,7 +1232,6 @@ fn on_free_balance_zero_stash_removes_validator() { assert!(>::exists(&10)); assert!(>::exists(&11)); assert!(>::exists(&11)); - assert!(>::exists(&11)); assert!(>::exists(&11)); // Reduce free_balance of controller to 0 @@ -1389,7 +1246,6 @@ fn on_free_balance_zero_stash_removes_validator() { assert!(>::exists(&10)); assert!(>::exists(&11)); assert!(>::exists(&11)); - assert!(>::exists(&11)); assert!(>::exists(&11)); // Reduce free_balance of stash to 0 @@ -1402,7 +1258,6 @@ fn on_free_balance_zero_stash_removes_validator() { assert!(!>::exists(&11)); assert!(!>::exists(&11)); assert!(!>::exists(&11)); - assert!(!>::exists(&11)); assert!(!>::exists(&11)); }); } @@ -1459,193 +1314,10 @@ fn on_free_balance_zero_stash_removes_nominator() { assert!(!>::exists(&11)); assert!(!>::exists(&11)); assert!(!>::exists(&11)); - assert!(!>::exists(&11)); assert!(!>::exists(&11)); }); } -#[test] -fn phragmen_poc_works() { - // Tests the POC test of the phragmen, mentioned in the paper and reference implementation. - // Initial votes: - // Votes [ - // ('2', 500, ['10', '20', '30']), - // ('4', 500, ['10', '20', '40']), - // ('10', 1000, ['10']), - // ('20', 1000, ['20']), - // ('30', 1000, ['30']), - // ('40', 1000, ['40'])] - // - // Sequential Phragmén gives - // 10 is elected with stake 1666.6666666666665 and score 0.0005 - // 20 is elected with stake 1333.3333333333333 and score 0.00075 - - // 2 has load 0.00075 and supported - // 10 with stake 333.3333333333333 20 with stake 166.66666666666666 30 with stake 0.0 - // 4 has load 0.00075 and supported - // 10 with stake 333.3333333333333 20 with stake 166.66666666666666 40 with stake 0.0 - // 10 has load 0.0005 and supported - // 10 with stake 1000.0 - // 20 has load 0.00075 and supported - // 20 with stake 1000.0 - // 30 has load 0 and supported - // 30 with stake 0 - // 40 has load 0 and supported - // 40 with stake 0 - - // Sequential Phragmén with post processing gives - // 10 is elected with stake 1500.0 and score 0.0005 - // 20 is elected with stake 1500.0 and score 0.00075 - // - // 10 has load 0.0005 and supported - // 10 with stake 1000.0 - // 20 has load 0.00075 and supported - // 20 with stake 1000.0 - // 30 has load 0 and supported - // 30 with stake 0 - // 40 has load 0 and supported - // 40 with stake 0 - // 2 has load 0.00075 and supported - // 10 with stake 166.66666666666674 20 with stake 333.33333333333326 30 with stake 0 - // 4 has load 0.00075 and supported - // 10 with stake 333.3333333333333 20 with stake 166.66666666666666 40 with stake 0.0 - with_externalities(&mut ExtBuilder::default() - .nominate(false) - .validator_pool(true) - .build(), - || { - // We don't really care about this. At this point everything is even. - assert_eq_uvec!(validator_controllers(), vec![40, 30]); - - // Set payees to Controller - assert_ok!(Staking::set_payee(Origin::signed(10), RewardDestination::Controller)); - assert_ok!(Staking::set_payee(Origin::signed(20), RewardDestination::Controller)); - assert_ok!(Staking::set_payee(Origin::signed(30), RewardDestination::Controller)); - assert_ok!(Staking::set_payee(Origin::signed(40), RewardDestination::Controller)); - - // no one is a nominator - assert_eq!(>::enumerate().count(), 0 as usize); - - // bond [2,1] / [4,3] a nominator - let _ = Balances::deposit_creating(&1, 1000); - let _ = Balances::deposit_creating(&3, 1000); - - assert_ok!(Staking::bond(Origin::signed(1), 2, 500, RewardDestination::default())); - assert_ok!(Staking::nominate(Origin::signed(2), vec![11, 21, 31])); - - assert_ok!(Staking::bond(Origin::signed(3), 4, 500, RewardDestination::default())); - assert_ok!(Staking::nominate(Origin::signed(4), vec![11, 21, 41])); - - // New era => election algorithm will trigger - start_era(1); - - assert_eq_uvec!(validator_controllers(), vec![20, 10]); - - assert_eq!(Staking::stakers(11).own, 1000); - assert_eq!(Staking::stakers(21).own, 1000); - - if cfg!(feature = "equalize") { - assert_eq!(Staking::stakers(11).total, 1000 + 499); - assert_eq!(Staking::stakers(21).total, 1000 + 499); - } else { - assert_eq!(Staking::stakers(11).total, 1000 + 332); - assert_eq!(Staking::stakers(21).total, 1000 + 666); - } - - // Nominator's stake distribution. - assert_eq!(Staking::stakers(11).others.iter().map(|e| e.who).collect::>>(), vec![3, 1]); - assert_eq!(Staking::stakers(21).others.iter().map(|e| e.who).collect::>>(), vec![3, 1]); - - if cfg!(feature = "equalize") { - assert_eq_uvec!( - Staking::stakers(11).others.iter().map(|e| e.value).collect::>>(), - vec![333, 166] - ); - assert_eq!( - Staking::stakers(11).others.iter().map(|e| e.value).sum::>(), - 499 - ); - assert_eq_uvec!( - Staking::stakers(21).others.iter().map(|e| e.value).collect::>>(), - vec![333, 166] - ); - assert_eq!( - Staking::stakers(21).others.iter().map(|e| e.value).sum::>(), - 499 - ); - } else { - assert_eq_uvec!( - Staking::stakers(11).others.iter().map(|e| e.value).collect::>>(), - vec![166, 166] - ); - assert_eq!( - Staking::stakers(11).others.iter().map(|e| e.value).sum::>(), - 332 - ); - assert_eq_uvec!( - Staking::stakers(21).others.iter().map(|e| e.value).collect::>>(), - vec![333, 333] - ); - assert_eq!( - Staking::stakers(21).others.iter().map(|e| e.value).sum::>(), - 666 - ); - } - check_exposure_all(); - check_nominator_all(); - }); -} - -#[test] -fn phragmen_poc_2_works() { - // tests the encapsulated phragmen::elect function. - // Votes [ - // ('10', 1000, ['10']), - // ('20', 1000, ['20']), - // ('30', 1000, ['30']), - // ('2', 50, ['10', '20']), - // ('4', 1000, ['10', '30']) - // ] - // Sequential Phragmén gives - // 10 is elected with stake 1705.7377049180327 and score 0.0004878048780487805 - // 30 is elected with stake 1344.2622950819673 and score 0.0007439024390243903 - with_externalities(&mut ExtBuilder::default().nominate(false).build(), || { - // initial setup of 10 and 20, both validators - assert_eq_uvec!(validator_controllers(), vec![20, 10]); - - // Bond [30, 31] as the third validator - assert_ok!(Staking::bond_extra(Origin::signed(31), 999)); - assert_ok!(Staking::validate(Origin::signed(30), ValidatorPrefs::default())); - - // bond [2,1](A), [4,3](B), as 2 nominators - for i in &[1, 3] { let _ = Balances::deposit_creating(i, 2000); } - - assert_ok!(Staking::bond(Origin::signed(1), 2, 50, RewardDestination::default())); - assert_ok!(Staking::nominate(Origin::signed(2), vec![11, 21])); - - assert_ok!(Staking::bond(Origin::signed(3), 4, 1000, RewardDestination::default())); - assert_ok!(Staking::nominate(Origin::signed(4), vec![11, 31])); - - let winners = phragmen::elect::( - 2, - Staking::minimum_validator_count() as usize, - >::enumerate(), - >::enumerate(), - Staking::slashable_balance_of, - ); - - let (winners, assignment) = winners.unwrap(); - - // 10 and 30 must be the winners - assert_eq!(winners, vec![11, 31]); - assert_eq!(assignment, vec![ - (3, vec![(11, 2816371998), (31, 1478595298)]), - (1, vec![(11, 4294967296)]), - ]); - check_exposure_all(); - check_nominator_all(); - }) -} #[test] fn switching_roles() { @@ -1753,7 +1425,7 @@ fn bond_with_no_staked_value() { .nominate(false) .minimum_validator_count(1) .build(), || { - // Can't bond with 1 + // Can't bond with 1 assert_noop!( Staking::bond(Origin::signed(1), 2, 1, RewardDestination::Controller), "can not bond with value less than minimum balance" @@ -1812,7 +1484,7 @@ fn bond_with_little_staked_value_bounded_by_slot_stake() { assert_ok!(Staking::bond(Origin::signed(1), 2, 1, RewardDestination::Controller)); assert_ok!(Staking::validate(Origin::signed(2), ValidatorPrefs::default())); - let total_payout_0 = current_total_payout_for_duration(3); + let total_payout_0 = current_total_payout_for_duration(3000); assert!(total_payout_0 > 100); // Test is meaningfull if reward something reward_all_elected(); start_era(1); @@ -1823,11 +1495,11 @@ fn bond_with_little_staked_value_bounded_by_slot_stake() { assert_eq!(Staking::slot_stake(), 1); // Old ones are rewarded. - assert_eq!(Balances::free_balance(&10), init_balance_10 + total_payout_0/3); + assert_eq!(Balances::free_balance(&10), init_balance_10 + total_payout_0 / 3); // no rewards paid to 2. This was initial election. assert_eq!(Balances::free_balance(&2), init_balance_2); - let total_payout_1 = current_total_payout_for_duration(3); + let total_payout_1 = current_total_payout_for_duration(3000); assert!(total_payout_1 > 100); // Test is meaningfull if reward something reward_all_elected(); start_era(2); @@ -1835,8 +1507,8 @@ fn bond_with_little_staked_value_bounded_by_slot_stake() { assert_eq_uvec!(validator_controllers(), vec![20, 10, 2]); assert_eq!(Staking::slot_stake(), 1); - assert_eq!(Balances::free_balance(&2), init_balance_2 + total_payout_1/3); - assert_eq!(Balances::free_balance(&10), init_balance_10 + total_payout_0/3 + total_payout_1/3); + assert_eq!(Balances::free_balance(&2), init_balance_2 + total_payout_1 / 3); + assert_eq!(Balances::free_balance(&10), init_balance_10 + total_payout_0 / 3 + total_payout_1 / 3); check_exposure_all(); check_nominator_all(); }); @@ -1875,13 +1547,13 @@ fn phragmen_linear_worse_case_equalize() { assert_eq_uvec!(validator_controllers(), vec![10, 60, 40, 20, 50, 30, 70]); - assert_eq!(Staking::stakers(11).total, 3000); - assert_eq!(Staking::stakers(21).total, 2254); - assert_eq!(Staking::stakers(31).total, 2254); - assert_eq!(Staking::stakers(41).total, 1926); - assert_eq!(Staking::stakers(51).total, 1871); - assert_eq!(Staking::stakers(61).total, 1892); - assert_eq!(Staking::stakers(71).total, 1799); + assert_eq_error_rate!(Staking::stakers(11).total, 3000, 2); + assert_eq_error_rate!(Staking::stakers(21).total, 2255, 2); + assert_eq_error_rate!(Staking::stakers(31).total, 2255, 2); + assert_eq_error_rate!(Staking::stakers(41).total, 1925, 2); + assert_eq_error_rate!(Staking::stakers(51).total, 1870, 2); + assert_eq_error_rate!(Staking::stakers(61).total, 1890, 2); + assert_eq_error_rate!(Staking::stakers(71).total, 1800, 2); check_exposure_all(); check_nominator_all(); @@ -1889,7 +1561,7 @@ fn phragmen_linear_worse_case_equalize() { } #[test] -fn phragmen_chooses_correct_number_of_validators() { +fn new_era_elects_correct_number_of_validators() { with_externalities(&mut ExtBuilder::default() .nominate(true) .validator_pool(true) @@ -1909,26 +1581,6 @@ fn phragmen_chooses_correct_number_of_validators() { }) } - -#[test] -fn phragmen_score_should_be_accurate_on_large_stakes() { - with_externalities(&mut ExtBuilder::default() - .nominate(false) - .build(), - || { - bond_validator(2, u64::max_value()); - bond_validator(4, u64::max_value()); - bond_validator(6, u64::max_value()-1); - bond_validator(8, u64::max_value()-2); - - start_era(1); - - assert_eq!(validator_controllers(), vec![4, 2]); - check_exposure_all(); - check_nominator_all(); - }) -} - #[test] fn phragmen_should_not_overflow_validators() { with_externalities(&mut ExtBuilder::default() @@ -1941,8 +1593,8 @@ fn phragmen_should_not_overflow_validators() { bond_validator(2, u64::max_value()); bond_validator(4, u64::max_value()); - bond_nominator(6, u64::max_value()/2, vec![3, 5]); - bond_nominator(8, u64::max_value()/2, vec![3, 5]); + bond_nominator(6, u64::max_value() / 2, vec![3, 5]); + bond_nominator(8, u64::max_value() / 2, vec![3, 5]); start_era(1); @@ -1964,8 +1616,8 @@ fn phragmen_should_not_overflow_nominators() { let _ = Staking::chill(Origin::signed(10)); let _ = Staking::chill(Origin::signed(20)); - bond_validator(2, u64::max_value()/2); - bond_validator(4, u64::max_value()/2); + bond_validator(2, u64::max_value() / 2); + bond_validator(4, u64::max_value() / 2); bond_nominator(6, u64::max_value(), vec![3, 5]); bond_nominator(8, u64::max_value(), vec![3, 5]); @@ -2002,84 +1654,6 @@ fn phragmen_should_not_overflow_ultimate() { }) } - -#[test] -fn phragmen_large_scale_test() { - with_externalities(&mut ExtBuilder::default() - .nominate(false) - .minimum_validator_count(1) - .validator_count(20) - .build(), - || { - let _ = Staking::chill(Origin::signed(10)); - let _ = Staking::chill(Origin::signed(20)); - let _ = Staking::chill(Origin::signed(30)); - let prefix = 200; - - bond_validator(prefix + 2, 1); - bond_validator(prefix + 4, 100); - bond_validator(prefix + 6, 1000000); - bond_validator(prefix + 8, 100000000001000); - bond_validator(prefix + 10, 100000000002000); - bond_validator(prefix + 12, 100000000003000); - bond_validator(prefix + 14, 400000000000000); - bond_validator(prefix + 16, 400000000001000); - bond_validator(prefix + 18, 18000000000000000); - bond_validator(prefix + 20, 20000000000000000); - bond_validator(prefix + 22, 500000000000100000); - bond_validator(prefix + 24, 500000000000200000); - - bond_nominator(50, 990000000000000000, vec![ - prefix + 3, - prefix + 5, - prefix + 7, - prefix + 9, - prefix + 11, - prefix + 13, - prefix + 15, - prefix + 17, - prefix + 19, - prefix + 21, - prefix + 23, - prefix + 25] - ); - - start_era(1); - - check_exposure_all(); - check_nominator_all(); - }) -} - -#[test] -fn phragmen_large_scale_test_2() { - with_externalities(&mut ExtBuilder::default() - .nominate(false) - .minimum_validator_count(1) - .validator_count(2) - .build(), - || { - let _ = Staking::chill(Origin::signed(10)); - let _ = Staking::chill(Origin::signed(20)); - let nom_budget: u64 = 1_000_000_000_000_000_000; - let c_budget: u64 = 4_000_000; - - bond_validator(2, c_budget as u64); - bond_validator(4, c_budget as u64); - - bond_nominator(50, nom_budget, vec![3, 5]); - - start_era(1); - - // Each exposure => total == own + sum(others) - check_exposure_all(); - check_nominator_all(); - - assert_total_expo(3, nom_budget / 2 + c_budget); - assert_total_expo(5, nom_budget / 2 + c_budget); - }) -} - #[test] fn reward_validator_slashing_validator_doesnt_overflow() { with_externalities(&mut ExtBuilder::default() @@ -2107,7 +1681,7 @@ fn reward_validator_slashing_validator_doesnt_overflow() { ]}); // Check slashing - Staking::slash_validator(&11, reward_slash); + let _ = Staking::slash_validator(&11, reward_slash, &Staking::stakers(&11), &mut Vec::new()); assert_eq!(Balances::total_balance(&11), stake - 1); assert_eq!(Balances::total_balance(&2), 1); }) @@ -2134,9 +1708,9 @@ fn reward_from_authorship_event_handler_works() { assert_eq!(>::get(), vec![21, 11]); // 21 is rewarded as an uncle producer - // 11 is rewarded as a block procuder and uncle referencer and uncle producer - assert_eq!(CurrentEraRewards::get().rewards, vec![1, 20+2*3 + 1]); - assert_eq!(CurrentEraRewards::get().total, 28); + // 11 is rewarded as a block producer and uncle referencer and uncle producer + assert_eq!(CurrentEraPointsEarned::get().individual, vec![1, 20 + 2 * 3 + 1]); + assert_eq!(CurrentEraPointsEarned::get().total, 28); }) } @@ -2163,8 +1737,8 @@ fn add_reward_points_fns_works() { (11, 1), ]); - assert_eq!(CurrentEraRewards::get().rewards, vec![2, 4]); - assert_eq!(CurrentEraRewards::get().total, 6); + assert_eq!(CurrentEraPointsEarned::get().individual, vec![2, 4]); + assert_eq!(CurrentEraPointsEarned::get().total, 6); }) } @@ -2180,3 +1754,162 @@ fn unbonded_balance_is_not_slashable() { assert_eq!(Staking::slashable_balance_of(&11), 200); }) } + +#[test] +fn era_is_always_same_length() { + // This ensures that the sessions is always of the same length if there is no forcing no + // session changes. + with_externalities(&mut ExtBuilder::default().build(), || { + start_era(1); + assert_eq!(Staking::current_era_start_session_index(), SessionsPerEra::get()); + + start_era(2); + assert_eq!(Staking::current_era_start_session_index(), SessionsPerEra::get() * 2); + + let session = Session::current_index(); + ForceEra::put(Forcing::ForceNew); + advance_session(); + assert_eq!(Staking::current_era(), 3); + assert_eq!(Staking::current_era_start_session_index(), session + 1); + + start_era(4); + assert_eq!(Staking::current_era_start_session_index(), session + SessionsPerEra::get() + 1); + }); +} + +#[test] +fn offence_forces_new_era() { + with_externalities(&mut ExtBuilder::default().build(), || { + Staking::on_offence( + &[OffenceDetails { + offender: ( + 11, + Staking::stakers(&11), + ), + reporters: vec![], + }], + &[Perbill::from_percent(5)], + ); + + assert_eq!(Staking::force_era(), Forcing::ForceNew); + }); +} + +#[test] +fn slashing_performed_according_exposure() { + // This test checks that slashing is performed according the exposure (or more precisely, + // historical exposure), not the current balance. + with_externalities(&mut ExtBuilder::default().build(), || { + assert_eq!(Staking::stakers(&11).own, 1000); + + // Handle an offence with a historical exposure. + Staking::on_offence( + &[OffenceDetails { + offender: ( + 11, + Exposure { + total: 500, + own: 500, + others: vec![], + }, + ), + reporters: vec![], + }], + &[Perbill::from_percent(50)], + ); + + // The stash account should be slashed for 250 (50% of 500). + assert_eq!(Balances::free_balance(&11), 1000 - 250); + }); +} + +#[test] +fn reporters_receive_their_slice() { + // This test verifies that the reporters of the offence receive their slice from the slashed + // amount. + with_externalities(&mut ExtBuilder::default().build(), || { + // The reporters' reward is calculated from the total exposure. + #[cfg(feature = "equalize")] + let initial_balance = 1250; + #[cfg(not(feature = "equalize"))] + let initial_balance = 1125; + + assert_eq!(Staking::stakers(&11).total, initial_balance); + + Staking::on_offence( + &[OffenceDetails { + offender: ( + 11, + Staking::stakers(&11), + ), + reporters: vec![1, 2], + }], + &[Perbill::from_percent(50)], + ); + + // initial_balance x 50% (slash fraction) x 10% (rewards slice) + let reward = initial_balance / 20 / 2; + assert_eq!(Balances::free_balance(&1), 10 + reward); + assert_eq!(Balances::free_balance(&2), 20 + reward); + }); +} + +#[test] +fn invulnerables_are_not_slashed() { + // For invulnerable validators no slashing is performed. + with_externalities( + &mut ExtBuilder::default().invulnerables(vec![11]).build(), + || { + #[cfg(feature = "equalize")] + let initial_balance = 1250; + #[cfg(not(feature = "equalize"))] + let initial_balance = 1375; + + assert_eq!(Balances::free_balance(&11), 1000); + assert_eq!(Balances::free_balance(&21), 2000); + assert_eq!(Staking::stakers(&21).total, initial_balance); + + Staking::on_offence( + &[ + OffenceDetails { + offender: (11, Staking::stakers(&11)), + reporters: vec![], + }, + OffenceDetails { + offender: (21, Staking::stakers(&21)), + reporters: vec![], + }, + ], + &[Perbill::from_percent(50), Perbill::from_percent(20)], + ); + + // The validator 11 hasn't been slashed, but 21 has been. + assert_eq!(Balances::free_balance(&11), 1000); + // 2000 - (0.2 * initial_balance) + assert_eq!(Balances::free_balance(&21), 2000 - (2 * initial_balance / 10)); + }, + ); +} + +#[test] +fn dont_slash_if_fraction_is_zero() { + // Don't slash if the fraction is zero. + with_externalities(&mut ExtBuilder::default().build(), || { + assert_eq!(Balances::free_balance(&11), 1000); + + Staking::on_offence( + &[OffenceDetails { + offender: ( + 11, + Staking::stakers(&11), + ), + reporters: vec![], + }], + &[Perbill::from_percent(0)], + ); + + // The validator hasn't been slashed. The new era is not forced. + assert_eq!(Balances::free_balance(&11), 1000); + assert_eq!(Staking::force_era(), Forcing::NotForcing); + }); +} diff --git a/srml/sudo/Cargo.toml b/srml/sudo/Cargo.toml index d0e2d5dbc55e494afbdb5a99b495622b613ad775..152f32ab89363364e41483dbb3cd99c85021dff9 100644 --- a/srml/sudo/Cargo.toml +++ b/srml/sudo/Cargo.toml @@ -5,17 +5,15 @@ authors = ["Parity Technologies "] edition = "2018" [dependencies] -serde = { version = "1.0", optional = true } +serde = { version = "1.0.101", optional = true } codec = { package = "parity-scale-codec", version = "1.0.0", default-features = false, features = ["derive"] } -sr-std = { path = "../../core/sr-std", default-features = false } -sr-io = { path = "../../core/sr-io", default-features = false } +rstd = { package = "sr-std", path = "../../core/sr-std", default-features = false } +runtime-io = { package = "sr-io", path = "../../core/sr-io", default-features = false } sr-primitives = { path = "../../core/sr-primitives", default-features = false } -srml-support = { path = "../support", default-features = false } -srml-support-procedural = { path = "../support/procedural" } +support = { package = "srml-support", path = "../support", default-features = false } system = { package = "srml-system", path = "../system", default-features = false } [dev-dependencies] -sr-io = { path = "../../core/sr-io", default-features = false } primitives = { package = "substrate-primitives", path = "../../core/primitives" } [features] @@ -23,9 +21,9 @@ default = ["std"] std = [ "serde", "codec/std", - "sr-std/std", - "sr-io/std", + "rstd/std", + "runtime-io/std", "sr-primitives/std", - "srml-support/std", + "support/std", "system/std", ] diff --git a/srml/sudo/src/lib.rs b/srml/sudo/src/lib.rs index 65a15b4abfb0342f76999fe5c9b5c43fbdfcdcfb..c4e13eefe24ef1ce124c5d5bbbedf85e607cf383 100644 --- a/srml/sudo/src/lib.rs +++ b/srml/sudo/src/lib.rs @@ -51,7 +51,7 @@ //! This is an example of a module that exposes a privileged function: //! //! ``` -//! use srml_support::{decl_module, dispatch::Result}; +//! use support::{decl_module, dispatch::Result}; //! use system::ensure_root; //! //! pub trait Trait: system::Trait {} @@ -86,13 +86,11 @@ #![cfg_attr(not(feature = "std"), no_std)] -use sr_std::prelude::*; -use sr_primitives::traits::StaticLookup; -use sr_primitives::weights::SimpleDispatchInfo; -use srml_support::{ - StorageValue, Parameter, Dispatchable, decl_module, decl_event, - decl_storage, ensure +use rstd::prelude::*; +use sr_primitives::{ + traits::{StaticLookup, Dispatchable}, weights::SimpleDispatchInfo, DispatchError, }; +use support::{Parameter, decl_module, decl_event, decl_storage, ensure}; use system::ensure_signed; pub trait Trait: system::Trait { @@ -106,7 +104,7 @@ pub trait Trait: system::Trait { decl_module! { // Simple declaration of the `Module` type. Lets the macro know what it's working on. pub struct Module for enum Call where origin: T::Origin { - fn deposit_event() = default; + fn deposit_event() = default; /// Authenticates the sudo key and dispatches a function call with `Root` origin. /// @@ -115,9 +113,10 @@ decl_module! { /// # /// - O(1). /// - Limited storage reads. - /// - No DB writes. + /// - One DB write (event). + /// - Unknown weight of derivative `proposal` execution. /// # - #[weight = SimpleDispatchInfo::FixedOperational(1_000_000)] + #[weight = SimpleDispatchInfo::FreeOperational] fn sudo(origin, proposal: Box) { // This is a public call, so we ensure that the origin is some signed account. let sender = ensure_signed(origin)?; @@ -126,7 +125,8 @@ decl_module! { let res = match proposal.dispatch(system::RawOrigin::Root.into()) { Ok(_) => true, Err(e) => { - sr_io::print(e); + let e: DispatchError = e.into(); + sr_primitives::print(e); false } }; @@ -152,6 +152,37 @@ decl_module! { Self::deposit_event(RawEvent::KeyChanged(Self::key())); >::put(new); } + + /// Authenticates the sudo key and dispatches a function call with `Signed` origin from + /// a given account. + /// + /// The dispatch origin for this call must be _Signed_. + /// + /// # + /// - O(1). + /// - Limited storage reads. + /// - One DB write (event). + /// - Unknown weight of derivative `proposal` execution. + /// # + #[weight = SimpleDispatchInfo::FixedOperational(0)] + fn sudo_as(origin, who: ::Source, proposal: Box) { + // This is a public call, so we ensure that the origin is some signed account. + let sender = ensure_signed(origin)?; + ensure!(sender == Self::key(), "only the current sudo key can sudo"); + + let who = T::Lookup::lookup(who)?; + + let res = match proposal.dispatch(system::RawOrigin::Signed(who).into()) { + Ok(_) => true, + Err(e) => { + let e: DispatchError = e.into(); + sr_primitives::print(e); + false + } + }; + + Self::deposit_event(RawEvent::SudoAsDone(res)); + } } } @@ -161,6 +192,8 @@ decl_event!( Sudid(bool), /// The sudoer just switched identity; the old key is supplied. KeyChanged(AccountId), + /// A sudo just took place. + SudoAsDone(bool), } ); diff --git a/srml/support/Cargo.toml b/srml/support/Cargo.toml index 2befc11b19538def8b23f695cdea80925c50ae0e..79a3beb6dc6af08262acb63aee651ae8a43a109e 100644 --- a/srml/support/Cargo.toml +++ b/srml/support/Cargo.toml @@ -5,18 +5,19 @@ authors = ["Parity Technologies "] edition = "2018" [dependencies] -serde = { version = "1.0", optional = true, features = ["derive"] } -codec = { package = "parity-scale-codec", version = "1.0.0", default-features = false, features = ["derive"] } +serde = { version = "1.0.101", optional = true, features = ["derive"] } +codec = { package = "parity-scale-codec", version = "1.0.6", default-features = false, features = ["derive"] } srml-metadata = { path = "../metadata", default-features = false } -sr-std = { path = "../../core/sr-std", default-features = false } -runtime_io = { package = "sr-io", path = "../../core/sr-io", default-features = false } +rstd = { package = "sr-std", path = "../../core/sr-std", default-features = false } +runtime-io ={ package = "sr-io", path = "../../core/sr-io", default-features = false } sr-primitives = { path = "../../core/sr-primitives", default-features = false } primitives = { package = "substrate-primitives", path = "../../core/primitives", default-features = false } inherents = { package = "substrate-inherents", path = "../../core/inherents", default-features = false } -srml-support-procedural = { path = "./procedural" } -paste = "0.1" -once_cell = { version = "0.1.6", default-features = false, optional = true } -bitmask = { version = "0.5", default-features = false } +srml-support-procedural = { package = "srml-support-procedural", path = "./procedural" } +paste = "0.1.6" +once_cell = { version = "0.2.4", default-features = false, optional = true } +bitmask = { version = "0.5.0", default-features = false } +impl-trait-for-tuples = "0.1.2" [dev-dependencies] pretty_assertions = "0.6.1" @@ -28,9 +29,9 @@ std = [ "once_cell", "bitmask/std", "serde", - "runtime_io/std", + "runtime-io/std", "codec/std", - "sr-std/std", + "rstd/std", "sr-primitives/std", "srml-metadata/std", "inherents/std", diff --git a/srml/support/procedural/Cargo.toml b/srml/support/procedural/Cargo.toml index fba706c17e890bccf203cc8171b0e904cd529cfe..91b4ca507497e69b862397df510f359264857845 100644 --- a/srml/support/procedural/Cargo.toml +++ b/srml/support/procedural/Cargo.toml @@ -8,9 +8,9 @@ edition = "2018" proc-macro = true [dependencies] -srml-support-procedural-tools = { path = "./tools" } +srml-support-procedural-tools = { package = "srml-support-procedural-tools", path = "./tools" } sr-api-macros = { path = "../../../core/sr-api-macros" } proc-macro2 = "0.4.27" -quote = { version = "0.6.12" } -syn = { version = "0.15.32", features = ["full"] } +quote = "0.6.12" +syn = { version = "0.15.44", features = ["full"] } diff --git a/srml/support/procedural/src/lib.rs b/srml/support/procedural/src/lib.rs index 78051ee8f2735e4fe72b8482bf9dfcdf139bbd42..a9cfa8d30d1b180cd5b55c19bccdc0b4842dc5c9 100644 --- a/srml/support/procedural/src/lib.rs +++ b/srml/support/procedural/src/lib.rs @@ -44,38 +44,60 @@ use proc_macro::TokenStream; /// with `Store` a (pub) trait generated associating each storage item to the `Module` and /// `as Example` setting the prefix used for storage items of this module. `Example` must be unique: /// another module with the same name and the same inner storage item name will conflict. +/// `Example` is called the module prefix. +/// +/// note: For instantiable modules the module prefix is prepended with instance +/// prefix. Instance prefix is "" for default instance and "Instance$n" for instance number $n. +/// Thus, instance 3 of module Example has a module prefix of `Instance3Example` /// /// Basic storage consists of a name and a type; supported types are: /// -/// * Value: `Foo: type`: Implements the [`StorageValue`](../srml_support/storage/trait.StorageValue.html) trait. +/// * Value: `Foo: type`: Implements the +/// [`StorageValue`](../srml_support/storage/trait.StorageValue.html) trait using the +/// [`StorageValue generator`](../srml_support/storage/generator/trait.StorageValue.html). +/// The generator `unhashed_key` is `$module_prefix ++ " " ++ $storage_name` +/// /// * Map: `Foo: map hasher($hash) type => type`: Implements the -/// [`StorageMap`](../srml_support/storage/trait.StorageMap.html) trait -/// with `$hash` representing a choice of hashing algorithms available in the +/// [`StorageMap`](../srml_support/storage/trait.StorageMap.html) trait using the +/// [`StorageMap generator`](../srml_support/storage/generator/trait.StorageMap.html). +/// +/// `$hash` representing a choice of hashing algorithms available in the /// [`Hashable`](../srml_support/trait.Hashable.html) trait. /// -/// `hasher($hash)` is optional and its default is `blake2_256`. +/// `hasher($hash)` is optional and its default is `blake2_256`. One should use another hasher +/// with care, see generator documentation. /// -/// /!\ Be careful with each key in the map that is inserted in the trie -/// `$hash(module_name ++ " " ++ storage_name ++ encoding(key))`. -/// If the keys are not trusted (e.g. can be set by a user), a cryptographic `hasher` such as -/// `blake2_256` must be used. Otherwise, other values in storage can be compromised. +/// The generator is implemented with: +/// * `prefix`: `$module_prefix ++ " " ++ $storage_name` +/// * `Hasher`: $hash /// -/// * Linked map: `Foo: linked_map hasher($hash) type => type`: Same as `Map` but also implements -/// the [`EnumerableStorageMap`](../srml_support/storage/trait.EnumerableStorageMap.html) trait. +/// * Linked map: `Foo: linked_map hasher($hash) type => type`: Implements the +/// [`StorageLinkedMap`](../srml_support/storage/trait.StorageLinkedMap.html) trait using the +/// [`StorageLinkedMap generator`](../srml_support/storage/generator/trait.StorageLinkedMap.html). /// -/// * Double map: `Foo: double_map hasher($hash) u32, $hash2(u32) => u32`: Implements the -/// [`StorageDoubleMap`](../srml_support/storage/trait.StorageDoubleMap.html) trait with -/// `$hash` and `$hash2` representing choices of hashing algorithms available in the +/// `$hash` representing a choice of hashing algorithms available in the /// [`Hashable`](../srml_support/trait.Hashable.html) trait. /// -/// `hasher($hash)` is optional and its default is `blake2_256`. +/// `hasher($hash)` is optional and its default is `blake2_256`. One should use another hasher +/// with care, see generator documentation. +/// +/// The generator is implemented with: +/// * `prefix`: `$module_prefix ++ " " ++ $storage_name` +/// * `head_key`: `"head of " ++ $module_prefix ++ " " ++ $storage_name` +/// * `Hasher`: $hash /// -/// /!\ Be careful with each key pair in the double map that is inserted in the trie. -/// The final key is calculated as follows: +/// * Double map: `Foo: double_map hasher($hash1) u32, $hash2(u32) => u32`: Implements the +/// [`StorageDoubleMap`](../srml_support/storage/trait.StorageDoubleMap.html) trait using the +/// [`StorageDoubleMap generator`](../srml_support/storage/generator/trait.StorageDoubleMap.html). /// -/// ```nocompile -/// $hash(module_name ++ " " ++ storage_name ++ encoding(first_key)) ++ $hash2(encoding(second_key)) -/// ``` +/// `$hash1` and `$hash2` representing choices of hashing algorithms available in the +/// [`Hashable`](../srml_support/trait.Hashable.html) trait. They must be choosen with care, see +/// generator documentation. +/// +/// `hasher($hash)` is optional and its default is `blake2_256`. +/// +/// `hasher($hash)` is optional and its default is `blake2_256`. One should use another hasher +/// with care, see generator documentation. /// /// If the first key is untrusted, a cryptographic `hasher` such as `blake2_256` must be used. /// Otherwise, other values of all storage items can be compromised. @@ -83,6 +105,11 @@ use proc_macro::TokenStream; /// If the second key is untrusted, a cryptographic `hasher` such as `blake2_256` must be used. /// Otherwise, other items in storage with the same first key can be compromised. /// +/// The generator is implemented with: +/// * `key1_prefix`: `$module_prefix ++ " " ++ $storage_name` +/// * `Hasher1`: $hash1 +/// * `Hasher2`: $hash2 +/// /// Supported hashers (ordered from least to best security): /// /// * `twox_64_concat` - TwoX with 64bit + key concatenated. @@ -126,14 +153,24 @@ use proc_macro::TokenStream; /// config(genesis_field): GenesisFieldType; /// config(genesis_field2): GenesisFieldType; /// ... -/// build(|_: &mut StorageOverlay, _: &mut ChildrenStorageOverlay, _: &GenesisConfig| { +/// build(|_: &Self| { /// // Modification of storage /// }) /// } /// } /// ``` /// -/// This struct can be exposed as `Config` by the `decl_runtime!` macro. +/// This struct can be exposed as `ExampleConfig` by the `construct_runtime!` macro like follows: +/// +/// ```nocompile +/// construct_runtime!( +/// pub enum Runtume with ... { +/// ..., +/// Example: example::{Module, Storage, ..., Config}, +/// ..., +/// } +/// ); +/// ``` /// /// ### Module with Instances /// diff --git a/srml/support/procedural/src/storage/impls.rs b/srml/support/procedural/src/storage/impls.rs index dd936636735141231ee6352e14c4032a00ad35df..ee6fa9a1642ffbedfa8cc59449ece55d92488972 100644 --- a/srml/support/procedural/src/storage/impls.rs +++ b/srml/support/procedural/src/storage/impls.rs @@ -21,13 +21,23 @@ use proc_macro2::TokenStream as TokenStream2; use syn::Ident; use quote::quote; -pub fn option_unwrap(is_option: bool) -> TokenStream2 { +fn from_optional_value_to_query(is_option: bool, fielddefault: TokenStream2) -> TokenStream2 { if !is_option { // raw type case - quote!( unwrap_or_else ) + quote!( v.unwrap_or_else(|| #fielddefault ) ) } else { // Option<> type case - quote!( or_else ) + quote!( v.or_else(|| #fielddefault ) ) + } +} + +fn from_query_to_optional_value(is_option: bool) -> TokenStream2 { + if !is_option { + // raw type case + quote!( Some(v) ) + } else { + // Option<> type case + quote!( v ) } } @@ -67,20 +77,9 @@ impl<'a, I: Iterator> Impls<'a, I> { .. } = self; let DeclStorageTypeInfos { typ, value_type, is_option, .. } = type_infos; - let option_simple_1 = option_unwrap(is_option); - let mutate_impl = if !is_option { - quote!{ - >::put(&val, storage) - } - } else { - quote!{ - match val { - Some(ref val) => >::put(&val, storage), - None => >::kill(storage), - } - } - }; + let from_optional_value_to_query = from_optional_value_to_query(is_option, fielddefault); + let from_query_to_optional_value = from_query_to_optional_value(is_option); let InstanceOpts { equal_default_instance, @@ -121,39 +120,21 @@ impl<'a, I: Iterator> Impls<'a, I> { #scrate::rstd::marker::PhantomData<(#trait_and_instance)> ) #where_clause; - impl<#impl_trait> #scrate::storage::hashed::generator::StorageValue<#typ> + impl<#impl_trait> #scrate::storage::generator::StorageValue<#typ> for #name<#trait_and_instance> #where_clause { type Query = #value_type; - /// Get the storage key. - fn key() -> &'static [u8] { + fn unhashed_key() -> &'static [u8] { #final_prefix } - /// Load the value from the provided storage instance. - fn get>(storage: &S) -> Self::Query { - storage.get(>::key()) - .#option_simple_1(|| #fielddefault) + fn from_optional_value_to_query(v: Option<#typ>) -> Self::Query { + #from_optional_value_to_query } - /// Take a value from storage, removing it afterwards. - fn take>(storage: &mut S) -> Self::Query { - storage.take(>::key()) - .#option_simple_1(|| #fielddefault) - } - - /// Mutate the value under a key. - fn mutate(f: F, storage: &mut S) -> R - where - F: FnOnce(&mut Self::Query) -> R, - S: #scrate::HashedStorage<#scrate::Twox128>, - { - let mut val = >::get(storage); - - let ret = f(&mut val); - #mutate_impl ; - ret + fn from_query_to_optional_value(v: Self::Query) -> Option<#typ> { + #from_query_to_optional_value } } } @@ -175,22 +156,9 @@ impl<'a, I: Iterator> Impls<'a, I> { .. } = self; let DeclStorageTypeInfos { typ, value_type, is_option, .. } = type_infos; - let option_simple_1 = option_unwrap(is_option); - let as_map = quote!{ > }; - - let mutate_impl = if !is_option { - quote!{ - #as_map::insert(key, &val, storage) - } - } else { - quote!{ - match val { - Some(ref val) => #as_map::insert(key, &val, storage), - None => #as_map::remove(key, storage), - } - } - }; + let from_optional_value_to_query = from_optional_value_to_query(is_option, fielddefault); + let from_query_to_optional_value = from_query_to_optional_value(is_option); let InstanceOpts { equal_default_instance, @@ -235,54 +203,24 @@ impl<'a, I: Iterator> Impls<'a, I> { #scrate::rstd::marker::PhantomData<(#trait_and_instance)> ) #where_clause; - impl<#impl_trait> #scrate::storage::hashed::generator::StorageMap<#kty, #typ> + impl<#impl_trait> #scrate::storage::generator::StorageMap<#kty, #typ> for #name<#trait_and_instance> #where_clause { type Query = #value_type; - type Hasher = #scrate::#hasher; - /// Get the prefix key in storage. fn prefix() -> &'static [u8] { #final_prefix } - /// Get the storage key used to fetch a value corresponding to a specific key. - fn key_for(x: &#kty) -> #scrate::rstd::vec::Vec { - let mut key = #as_map::prefix().to_vec(); - #scrate::codec::Encode::encode_to(x, &mut key); - key - } - - /// Load the value associated with the given key from the map. - fn get>(key: &#kty, storage: &S) -> Self::Query { - let key = #as_map::key_for(key); - storage.get(&key[..]).#option_simple_1(|| #fielddefault) - } - - /// Take the value, reading and removing it. - fn take>(key: &#kty, storage: &mut S) -> Self::Query { - let key = #as_map::key_for(key); - storage.take(&key[..]).#option_simple_1(|| #fielddefault) + fn from_optional_value_to_query(v: Option<#typ>) -> Self::Query { + #from_optional_value_to_query } - /// Mutate the value under a key - fn mutate(key: &#kty, f: F, storage: &mut S) -> R - where - F: FnOnce(&mut Self::Query) -> R, - S: #scrate::HashedStorage<#scrate::#hasher>, - { - let mut val = #as_map::get(key, storage); - - let ret = f(&mut val); - #mutate_impl ; - ret + fn from_query_to_optional_value(v: Self::Query) -> Option<#typ> { + #from_query_to_optional_value } } - - impl<#impl_trait> #scrate::storage::hashed::generator::AppendableStorageMap<#kty, #typ> - for #name<#trait_and_instance> #where_clause - {} } } @@ -319,379 +257,67 @@ impl<'a, I: Iterator> Impls<'a, I> { }; // make sure to use different prefix for head and elements. - let final_head_key = if let Some(instance) = instance { + let head_key = if let Some(instance) = instance { let const_name = Ident::new( &format!("{}{}", HEAD_KEY_FOR, name.to_string()), proc_macro2::Span::call_site() ); quote!{ #instance::#const_name.as_bytes() } } else { - let final_head_key = format!("head of {}", prefix); - quote!{ #final_head_key.as_bytes() } + let head_key = format!("head of {}", prefix); + quote!{ #head_key.as_bytes() } }; let DeclStorageTypeInfos { typ, value_type, is_option, .. } = type_infos; - let option_simple_1 = option_unwrap(is_option); - let name_lowercase = name.to_string().to_lowercase(); - let inner_module = Ident::new( - &format!("__linked_map_details_for_{}_do_not_use", name_lowercase), name.span() - ); - let linkage = Ident::new(&format!("__LinkageFor{}DoNotUse", name), name.span()); - let phantom_data = quote! { #scrate::rstd::marker::PhantomData }; - let as_map = quote!{ > }; - let put_or_insert = quote! { - match linkage { - Some(linkage) => storage.put(key_for, &(val, linkage)), - None => #as_map::insert(key, &val, storage), - } - }; - let mutate_impl = if !type_infos.is_option { - put_or_insert - } else { - quote! { - match val { - Some(ref val) => #put_or_insert, - None => #as_map::remove(key, storage), - } - } - }; - let mutate_map = if type_infos.is_option { - quote! { .map(|(data, linkage)| (Some(data), Some(linkage))) } - } else { - quote! { .map(|(data, linkage)| (data, Some(linkage))) } - }; + let from_optional_value_to_query = from_optional_value_to_query(is_option, fielddefault); + let from_query_to_optional_value = from_query_to_optional_value(is_option); let trait_required = ext::type_contains_ident(value_type, traitinstance) || ext::type_contains_ident(kty, traitinstance); - let (struct_trait, impl_trait, trait_and_instance) = if trait_required { + let (struct_trait, impl_trait, trait_and_instance, where_clause) = if trait_required { ( quote!(#traitinstance: #traittype, #instance #bound_instantiable #equal_default_instance), quote!(#traitinstance: #traittype, #instance #bound_instantiable), quote!(#traitinstance, #instance), + where_clause.clone(), ) } else { ( quote!(#instance #bound_instantiable #equal_default_instance), quote!(#instance #bound_instantiable), quote!(#instance), - ) - }; - - let (where_clause, trait_where_clause) = if trait_required { - ( - where_clause.clone(), - where_clause.clone().map(|mut wc| { - wc.predicates.push(syn::parse_quote!(#traitinstance: 'static)); - wc - }).or_else(|| syn::parse_quote!(where #traitinstance: 'static)), - ) - } else { - ( - None, None, ) }; // generator for linked map - let helpers = quote! { - /// Linkage data of an element (it's successor and predecessor) - #[derive(#scrate::codec::Encode, #scrate::codec::Decode)] - pub(crate) struct #linkage { - /// Previous element key in storage (None for the first element) - pub previous: Option, - /// Next element key in storage (None for the last element) - pub next: Option, - } - - mod #inner_module { - use super::*; - - /// Re-exported version of linkage to overcome proc-macro derivation issue. - pub(crate) use super::#linkage as Linkage; - - impl Default for Linkage { - fn default() -> Self { - Self { - previous: None, - next: None, - } - } - } - - /// A key-value pair iterator for enumerable map. - pub(crate) struct Enumerator<'a, S, K, V> { - pub storage: &'a S, - pub next: Option, - pub _data: #phantom_data, - } - - impl<'a, S: #scrate::HashedStorage<#scrate::#hasher>, #impl_trait> Iterator - for Enumerator<'a, S, #kty, (#typ, #trait_and_instance)> #where_clause - { - type Item = (#kty, #typ); - - fn next(&mut self) -> Option { - let next = self.next.take()?; - let key_for = - as #scrate::storage::hashed::generator::StorageMap<#kty, #typ>>::key_for(&next); - - let (val, linkage): (#typ, Linkage<#kty>) = self.storage.get(&*key_for) - .expect("previous/next only contain existing entires; we enumerate using next; entry exists; qed"); - self.next = linkage.next; - Some((next, val)) - } - } - - pub(crate) trait Utils<#struct_trait> { - /// Update linkage when this element is removed. - /// - /// Takes care of updating previous and next elements points - /// as well as updates head if the element is first or last. - fn remove_linkage>(linkage: Linkage<#kty>, storage: &mut S); - - /// Read the contained data and it's linkage. - fn read_with_linkage(storage: &S, key: &[u8]) -> Option<(#typ, Linkage<#kty>)> - where - S: #scrate::HashedStorage<#scrate::#hasher>; - - /// Generate linkage for newly inserted element. - /// - /// Takes care of updating head and previous head's pointer. - fn new_head_linkage>( - storage: &mut S, - key: &#kty, - ) -> Linkage<#kty>; - - /// Read current head pointer. - fn read_head>(storage: &S) -> Option<#kty>; - - /// Overwrite current head pointer. - /// - /// If `None` is given head is removed from storage. - fn write_head>(storage: &mut S, head: Option<&#kty>); - } - } - }; - - let structure = quote! { - #( #[ #attrs ] )* - #visibility struct #name<#struct_trait>(#phantom_data<(#trait_and_instance)>); - - impl<#impl_trait> self::#inner_module::Utils<#trait_and_instance> - for #name<#trait_and_instance> #where_clause - { - fn remove_linkage>( - linkage: self::#inner_module::Linkage<#kty>, - storage: &mut S, - ) { - use self::#inner_module::Utils; - - let next_key = linkage.next.as_ref().map(|x| #as_map::key_for(x)); - let prev_key = linkage.previous.as_ref().map(|x| #as_map::key_for(x)); - - if let Some(prev_key) = prev_key { - // Retrieve previous element and update `next` - let mut res = Self::read_with_linkage(storage, &*prev_key) - .expect("Linkage is updated in case entry is removed; it always points to existing keys; qed"); - res.1.next = linkage.next; - storage.put(&*prev_key, &res); - } else { - // we were first so let's update the head - Self::write_head(storage, linkage.next.as_ref()); - } - - if let Some(next_key) = next_key { - // Update previous of next element - let mut res = Self::read_with_linkage(storage, &*next_key) - .expect("Linkage is updated in case entry is removed; it always points to existing keys; qed"); - res.1.previous = linkage.previous; - storage.put(&*next_key, &res); - } - } - - fn read_with_linkage>( - storage: &S, - key: &[u8], - ) -> Option<(#typ, self::#inner_module::Linkage<#kty>)> { - storage.get(key) - } - - fn new_head_linkage>( - storage: &mut S, - key: &#kty, - ) -> self::#inner_module::Linkage<#kty> { - use self::#inner_module::Utils; - - if let Some(head) = Self::read_head(storage) { - // update previous head predecessor - { - let head_key = #as_map::key_for(&head); - let (data, linkage) = Self::read_with_linkage(storage, &*head_key).expect(r#" - head is set when first element is inserted and unset when last element is removed; - if head is Some then it points to existing key; qed - "#); - storage.put(&*head_key, &(data, self::#inner_module::Linkage { - next: linkage.next.as_ref(), - previous: Some(key), - })); - } - // update to current head - Self::write_head(storage, Some(key)); - // return linkage with pointer to previous head - let mut linkage = self::#inner_module::Linkage::default(); - linkage.next = Some(head); - linkage - } else { - // we are first - update the head and produce empty linkage - Self::write_head(storage, Some(key)); - self::#inner_module::Linkage::default() - } - } - - fn read_head>(storage: &S) -> Option<#kty> { - storage.get(#final_head_key) - } - - fn write_head>(storage: &mut S, head: Option<&#kty>) { - match head { - Some(head) => storage.put(#final_head_key, head), - None => storage.kill(#final_head_key), - } - } - } - }; - quote! { - #helpers - - #structure + #( #[ #attrs ] )* + #visibility struct #name<#struct_trait>( + #scrate::rstd::marker::PhantomData<(#trait_and_instance)> + ) #where_clause; - impl<#impl_trait> #scrate::storage::hashed::generator::StorageMap<#kty, #typ> + impl<#impl_trait> #scrate::storage::generator::StorageLinkedMap<#kty, #typ> for #name<#trait_and_instance> #where_clause { type Query = #value_type; - type Hasher = #scrate::#hasher; - /// Get the prefix key in storage. fn prefix() -> &'static [u8] { #final_prefix } - /// Get the storage key used to fetch a value corresponding to a specific key. - fn key_for(key: &#kty) -> #scrate::rstd::vec::Vec { - let mut key_for = #as_map::prefix().to_vec(); - #scrate::codec::Encode::encode_to(&key, &mut key_for); - key_for + fn head_key() -> &'static [u8] { + #head_key } - /// Load the value associated with the given key from the map. - fn get>(key: &#kty, storage: &S) -> Self::Query { - storage.get(&*#as_map::key_for(key)).#option_simple_1(|| #fielddefault) - } - - /// Take the value, reading and removing it. - fn take>(key: &#kty, storage: &mut S) -> Self::Query { - use self::#inner_module::Utils; - - let res: Option<(#typ, self::#inner_module::Linkage<#kty>)> = storage.take(&*#as_map::key_for(key)); - - res.map(|(d, l)| { - Self::remove_linkage(l, storage); - d - }).#option_simple_1(|| #fielddefault) + fn from_optional_value_to_query(v: Option<#typ>) -> Self::Query { + #from_optional_value_to_query } - /// Remove the value under a key. - fn remove>(key: &#kty, storage: &mut S) { - #as_map::take(key, storage); - } - - /// Store a value to be associated with the given key from the map. - fn insert>( - key: &#kty, - val: &#typ, - storage: &mut S, - ) { - use self::#inner_module::Utils; - - let key_for = &*#as_map::key_for(key); - let linkage = match Self::read_with_linkage(storage, key_for) { - // overwrite but reuse existing linkage - Some((_data, linkage)) => linkage, - // create new linkage - None => Self::new_head_linkage(storage, key), - }; - - storage.put(key_for, &(val, linkage)) - } - - /// Store a value under this key into the provided storage instance; this can take any reference - /// type that derefs to `T` (and has `Encode` implemented). - /// Store a value under this key into the provided storage instance. - fn insert_ref(key: &#kty, val: &Arg, storage: &mut S) - where - #typ: AsRef, - Arg: ?Sized + #scrate::codec::Encode, - S: #scrate::HashedStorage<#scrate::#hasher> - { - use self::#inner_module::Utils; - - let key_for = &*#as_map::key_for(key); - let linkage = match Self::read_with_linkage(storage, key_for) { - // overwrite but reuse existing linkage - Some((_data, linkage)) => linkage, - // create new linkage - None => Self::new_head_linkage(storage, key), - }; - - storage.put(key_for, &(val, linkage)) - } - - /// Mutate the value under a key - fn mutate(key: &#kty, f: F, storage: &mut S) -> R - where - F: FnOnce(&mut Self::Query) -> R, - S: #scrate::HashedStorage<#scrate::#hasher>, - { - use self::#inner_module::Utils; - - let key_for = &*#as_map::key_for(key); - let (mut val, linkage) = Self::read_with_linkage(storage, key_for) - #mutate_map - .unwrap_or_else(|| (#fielddefault, None)); - - let ret = f(&mut val); - #mutate_impl; - ret - } - } - - impl<#impl_trait> #scrate::storage::hashed::generator::EnumerableStorageMap<#kty, #typ> - for #name<#trait_and_instance> #trait_where_clause - { - fn head>(storage: &S) -> Option<#kty> { - use self::#inner_module::Utils; - - Self::read_head(storage) - } - - fn enumerate<'a, S>( - storage: &'a S - ) -> #scrate::rstd::boxed::Box + 'a> - where - S: #scrate::HashedStorage<#scrate::#hasher>, - #kty: 'a, - #typ: 'a, - { - use self::#inner_module::{Utils, Enumerator}; - - #scrate::rstd::boxed::Box::new(Enumerator { - next: Self::read_head(storage), - storage, - _data: #phantom_data::<(#typ, #trait_and_instance)>::default(), - }) + fn from_query_to_optional_value(v: Self::Query) -> Option<#typ> { + #from_query_to_optional_value } } } @@ -720,29 +346,9 @@ impl<'a, I: Iterator> Impls<'a, I> { } = self; let DeclStorageTypeInfos { typ, value_type, is_option, .. } = type_infos; - let option_simple_1 = option_unwrap(is_option); - - let as_double_map = quote!{ - > - }; - let mutate_impl = if !is_option { - quote!{ - #as_double_map::insert(k1, k2, &val, storage) - } - } else { - quote!{ - match val { - Some(ref val) => #as_double_map::insert::( - k1, - k2, - val, - storage, - ), - None => #as_double_map::remove(k1, k2, storage), - } - } - }; + let from_optional_value_to_query = from_optional_value_to_query(is_option, fielddefault); + let from_query_to_optional_value = from_query_to_optional_value(is_option); let InstanceOpts { equal_default_instance, @@ -782,90 +388,29 @@ impl<'a, I: Iterator> Impls<'a, I> { // generator for double map quote!{ #( #[ #attrs ] )* - #visibility struct #name<#struct_trait> - (#scrate::rstd::marker::PhantomData<(#trait_and_instance)>); + #visibility struct #name<#struct_trait> ( + #scrate::rstd::marker::PhantomData<(#trait_and_instance)> + ) #where_clause; - impl<#impl_trait> #scrate::storage::unhashed::generator::StorageDoubleMap<#k1ty, #k2ty, #typ> + impl<#impl_trait> #scrate::storage::generator::StorageDoubleMap<#k1ty, #k2ty, #typ> for #name<#trait_and_instance> #where_clause { type Query = #value_type; - fn prefix_for(k1: &KArg1) -> #scrate::rstd::vec::Vec where - KArg1: ?Sized + #scrate::codec::Encode, - #k1ty: #scrate::rstd::borrow::Borrow, - { - use #scrate::storage::hashed::generator::StorageHasher; + type Hasher1 = #scrate::#hasher; - let mut key = #as_double_map::prefix().to_vec(); - #scrate::codec::Encode::encode_to(k1, &mut key); - #scrate::#hasher::hash(&key[..]).to_vec() - } + type Hasher2 = #scrate::#k2_hasher; - fn prefix() -> &'static [u8] { + fn key1_prefix() -> &'static [u8] { #final_prefix } - fn key_for( - k1: &KArg1, - k2: &KArg2, - ) -> #scrate::rstd::vec::Vec where - #k1ty: #scrate::rstd::borrow::Borrow, - #k2ty: #scrate::rstd::borrow::Borrow, - KArg1: ?Sized + #scrate::codec::Encode, - KArg2: ?Sized + #scrate::codec::Encode, - { - use #scrate::storage::hashed::generator::StorageHasher; - - let mut key = #as_double_map::prefix_for(k1); - #scrate::codec::Encode::using_encoded(k2, |e| key.extend(&#scrate::#k2_hasher::hash(e))); - key - } - - fn get( - k1: &KArg1, - k2: &KArg2, - storage: &S, - ) -> Self::Query where - #k1ty: #scrate::rstd::borrow::Borrow, - #k2ty: #scrate::rstd::borrow::Borrow, - KArg1: ?Sized + #scrate::codec::Encode, - KArg2: ?Sized + #scrate::codec::Encode, - { - let key = #as_double_map::key_for(k1, k2); - storage.get(&key).#option_simple_1(|| #fielddefault) - } - - fn take( - k1: &KArg1, - k2: &KArg2, - storage: &mut S, - ) -> Self::Query where - #k1ty: #scrate::rstd::borrow::Borrow, - #k2ty: #scrate::rstd::borrow::Borrow, - KArg1: ?Sized + #scrate::codec::Encode, - KArg2: ?Sized + #scrate::codec::Encode, - { - let key = #as_double_map::key_for(k1, k2); - storage.take(&key).#option_simple_1(|| #fielddefault) + fn from_optional_value_to_query(v: Option<#typ>) -> Self::Query { + #from_optional_value_to_query } - fn mutate( - k1: &KArg1, - k2: &KArg2, - f: F, - storage: &mut S, - ) -> R where - #k1ty: #scrate::rstd::borrow::Borrow, - #k2ty: #scrate::rstd::borrow::Borrow, - KArg1: ?Sized + #scrate::codec::Encode, - KArg2: ?Sized + #scrate::codec::Encode, - F: FnOnce(&mut Self::Query) -> R, - { - let mut val = #as_double_map::get(k1, k2, storage); - - let ret = f(&mut val); - #mutate_impl; - ret + fn from_query_to_optional_value(v: Self::Query) -> Option<#typ> { + #from_query_to_optional_value } } } diff --git a/srml/support/procedural/src/storage/transformation.rs b/srml/support/procedural/src/storage/transformation.rs index d378907cb1e72fbc2af14dc66beac2340b477af9..c6a3a1f668cdcbabb8e5d5066598a297923a60c8 100644 --- a/srml/support/procedural/src/storage/transformation.rs +++ b/srml/support/procedural/src/storage/transformation.rs @@ -35,7 +35,7 @@ use syn::{ }, parse_macro_input, }; -use quote::quote; +use quote::{quote, quote_spanned}; use super::*; @@ -122,7 +122,7 @@ pub fn decl_storage_impl(input: TokenStream) -> TokenStream { &cratename, &storage_lines, &where_clause, - ); + ).unwrap_or_else(|err| err.to_compile_error()); let decl_store_items = decl_store_items( &storage_lines, @@ -155,6 +155,13 @@ pub fn decl_storage_impl(input: TokenStream) -> TokenStream { } = instance_opts; let expanded = quote! { + use #scrate::{ + StorageValue as _, + StorageMap as _, + StorageLinkedMap as _, + StorageDoubleMap as _ + }; + #scrate_decl #decl_storage_items #visibility trait #storetype { @@ -330,11 +337,11 @@ fn decl_store_extra_genesis( let v = (#builder)(&self); < #name<#struct_trait #instance> as - #scrate::storage::hashed::generator::StorageValue<#typ> - >::put(&v, storage); + #scrate::storage::StorageValue<#typ> + >::put::<#typ>(v); }} }, - DeclStorageTypeInfosKind::Map { key_type, .. } => { + DeclStorageTypeInfosKind::Map { key_type, is_linked, .. } => { let struct_trait = if ext::type_contains_ident(&type_infos.value_type, traitinstance) || ext::type_contains_ident(key_type, traitinstance) { @@ -344,13 +351,19 @@ fn decl_store_extra_genesis( quote!() }; + let map = if is_linked { + quote! { StorageLinkedMap } + } else { + quote! { StorageMap } + }; + quote!{{ let data = (#builder)(&self); data.into_iter().for_each(|(k, v)| { < #name<#struct_trait #instance> as - #scrate::storage::hashed::generator::StorageMap<#key_type, #typ> - >::insert(&k, &v, storage); + #scrate::storage::#map<#key_type, #typ> + >::insert::<#key_type, #typ>(k, v); }); }} }, @@ -370,8 +383,8 @@ fn decl_store_extra_genesis( data.into_iter().for_each(|(k1, k2, v)| { < #name<#struct_trait #instance> as - #scrate::storage::unhashed::generator::StorageDoubleMap<#key1_type, #key2_type, #typ> - >::insert(&k1, &k2, &v, storage); + #scrate::storage::StorageDoubleMap<#key1_type, #key2_type, #typ> + >::insert::<#key1_type, #key2_type, #typ>(k1, k2, v); }); }} }, @@ -380,7 +393,7 @@ fn decl_store_extra_genesis( } let mut has_scall = false; - let mut scall = quote!{ ( |_, _| {} ) }; + let mut scall = quote!{ let scall: fn(&Self) = |_| {}; scall }; let mut genesis_extrafields = TokenStream2::new(); let mut genesis_extrafields_default = TokenStream2::new(); @@ -417,7 +430,9 @@ fn decl_store_extra_genesis( } assimilate_require_generic |= ext::expr_contains_ident(&expr.content, traitinstance); let content = &expr.content; - scall = quote!( ( #content ) ); + scall = quote_spanned! { expr.span() => + let scall: fn(&Self) = #content; scall + }; has_scall = true; }, } @@ -549,13 +564,13 @@ fn decl_store_extra_genesis( #scrate::sr_primitives::ChildrenStorageOverlay, ), ) -> std::result::Result<(), String> #fn_where_clause { - let storage = &mut tuple_storage.0; - - #builders + #scrate::with_storage(tuple_storage, || { + #builders - #scall(tuple_storage, &self); + #scall(&self); - Ok(()) + Ok(()) + }) } } @@ -585,15 +600,15 @@ fn create_and_impl_instance( instance_prefix: &str, ident: &Ident, doc: &TokenStream2, - const_names: &[(Ident, String)], + const_names: &[(Ident, String, String)], scrate: &TokenStream2, instantiable: &Ident, cratename: &Ident, ) -> TokenStream2 { let mut const_impls = TokenStream2::new(); - for (const_name, partial_const_value) in const_names { - let const_value = format!("{}{}", instance_prefix, partial_const_value); + for (const_name, const_value_prefix, const_value_suffix) in const_names { + let const_value = format!("{}{}{}", const_value_prefix, instance_prefix, const_value_suffix); const_impls.extend(quote! { const #const_name: &'static str = #const_value; }); @@ -622,7 +637,7 @@ fn decl_storage_items( cratename: &Ident, storage_lines: &ext::Punctuated, where_clause: &Option, -) -> TokenStream2 { +) -> syn::Result { let mut impls = TokenStream2::new(); let InstanceOpts { @@ -651,15 +666,13 @@ fn decl_storage_items( let const_name = syn::Ident::new( &format!("{}{}", impls::PREFIX_FOR, name.to_string()), proc_macro2::Span::call_site() ); - let partial_const_value = prefix.clone(); - const_names.push((const_name, partial_const_value)); + const_names.push((const_name, String::new(), prefix.clone())); if let DeclStorageTypeInfosKind::Map { is_linked: true, .. } = type_infos.kind { let const_name = syn::Ident::new( &format!("{}{}", impls::HEAD_KEY_FOR, name.to_string()), proc_macro2::Span::call_site() ); - let partial_const_value = format!("head of {}", prefix); - const_names.push((const_name, partial_const_value)); + const_names.push((const_name, "head of ".into(), prefix)); } } @@ -670,7 +683,7 @@ fn decl_storage_items( // Declare Instance trait { let mut const_impls = TokenStream2::new(); - for (const_name, _) in &const_names { + for (const_name, ..) in &const_names { const_impls.extend(quote! { const #const_name: &'static str; }); @@ -753,6 +766,19 @@ fn decl_storage_items( } = sline; let type_infos = get_type_infos(storage_type); + + if type_infos.is_option && default_value.inner.is_some() { + return Err(syn::Error::new_spanned( + default_value, + "Default values for Option types are not supported" + )); + } + + let fielddefault = default_value.inner + .as_ref() + .map(|d| &d.expr) + .map(|d| quote!( #d )) + .unwrap_or_else(|| quote!{ Default::default() }); let kind = type_infos.kind.clone(); // Propagate doc attributes. let attrs = attrs.inner.iter().filter_map(|a| a.parse_meta().ok()).filter(|m| m.name() == "doc"); @@ -765,8 +791,7 @@ fn decl_storage_items( traittype, instance_opts, type_infos, - fielddefault: default_value.inner.as_ref().map(|d| &d.expr).map(|d| quote!( #d )) - .unwrap_or_else(|| quote!{ Default::default() }), + fielddefault, prefix: build_prefix(cratename, name), name, attrs, @@ -789,7 +814,8 @@ fn decl_storage_items( }; impls.extend(implementation) } - impls + + Ok(impls) } fn decl_store_items(storage_lines: &ext::Punctuated) -> TokenStream2 { @@ -877,14 +903,14 @@ fn impl_store_fns( quote!{ #( #[ #attrs ] )* pub fn #get_fn() -> #value_type { - <#name<#struct_trait #instance> as - #scrate::storage::hashed::generator::StorageValue<#typ>> :: get( - &#scrate::storage::RuntimeStorage - ) + < + #name<#struct_trait #instance> as + #scrate::storage::StorageValue<#typ> + >::get() } } }, - DeclStorageTypeInfosKind::Map { key_type, .. } => { + DeclStorageTypeInfosKind::Map { key_type, is_linked, .. } => { let struct_trait = if ext::type_contains_ident(&type_infos.value_type, traitinstance) || ext::type_contains_ident(key_type, traitinstance) { @@ -893,13 +919,19 @@ fn impl_store_fns( quote!() }; + let map = if is_linked { + quote! { StorageLinkedMap } + } else { + quote! { StorageMap } + }; + quote!{ #( #[ #attrs ] )* - pub fn #get_fn>(key: K) -> #value_type { + pub fn #get_fn>(key: K) -> #value_type { < #name<#struct_trait #instance> as - #scrate::storage::hashed::generator::StorageMap<#key_type, #typ> - >::get(key.borrow(), &#scrate::storage::RuntimeStorage) + #scrate::storage::#map<#key_type, #typ> + >::get(key) } } } @@ -914,17 +946,15 @@ fn impl_store_fns( }; quote!{ - pub fn #get_fn(k1: &KArg1, k2: &KArg2) -> #value_type + pub fn #get_fn(k1: KArg1, k2: KArg2) -> #value_type where - #key1_type: #scrate::rstd::borrow::Borrow, - #key2_type: #scrate::rstd::borrow::Borrow, - KArg1: ?Sized + #scrate::codec::Encode, - KArg2: ?Sized + #scrate::codec::Encode, + KArg1: #scrate::codec::EncodeLike<#key1_type>, + KArg2: #scrate::codec::EncodeLike<#key2_type>, { < #name<#struct_trait #instance> as - #scrate::storage::unhashed::generator::StorageDoubleMap<#key1_type, #key2_type, #typ> - >::get(k1, k2, &#scrate::storage::RuntimeStorage) + #scrate::storage::StorageDoubleMap<#key1_type, #key2_type, #typ> + >::get(k1, k2) } } } @@ -1057,7 +1087,9 @@ fn store_functions_to_metadata ( #[cfg(feature = "std")] #[allow(non_upper_case_globals)] - static #cache_name: #scrate::once_cell::sync::OnceCell<#scrate::rstd::vec::Vec> = #scrate::once_cell::sync::OnceCell::INIT; + static #cache_name: #scrate::once_cell::sync::OnceCell< + #scrate::rstd::vec::Vec + > = #scrate::once_cell::sync::OnceCell::new(); #[cfg(feature = "std")] impl<#traitinstance: #traittype, #instance #bound_instantiable> #scrate::metadata::DefaultByte diff --git a/srml/support/procedural/tools/Cargo.toml b/srml/support/procedural/tools/Cargo.toml index bb6d24def2da8c933fc1881e3bf4c53f39063dd0..62c55a703f4ed23b51b3c9da224fd045cbd79aeb 100644 --- a/srml/support/procedural/tools/Cargo.toml +++ b/srml/support/procedural/tools/Cargo.toml @@ -5,8 +5,8 @@ authors = ["Parity Technologies "] edition = "2018" [dependencies] -srml-support-procedural-tools-derive = { path = "./derive" } +srml-support-procedural-tools-derive = { package = "srml-support-procedural-tools-derive", path = "./derive" } proc-macro2 = "0.4.27" -quote = { version = "0.6.12" } -syn = { version = "0.15.30", features = ["full"] } -proc-macro-crate = "0.1.3" +quote = "0.6.12" +syn = { version = "0.15.44", features = ["full"] } +proc-macro-crate = "0.1.4" diff --git a/srml/support/procedural/tools/derive/Cargo.toml b/srml/support/procedural/tools/derive/Cargo.toml index 2f7f35ff4a70228423ec451aaf9c641c30e38699..54bfaba83843414387a95a713a30f6172f95abef 100644 --- a/srml/support/procedural/tools/derive/Cargo.toml +++ b/srml/support/procedural/tools/derive/Cargo.toml @@ -10,4 +10,4 @@ proc-macro = true [dependencies] proc-macro2 = "0.4.27" quote = { version = "0.6.12", features = ["proc-macro"] } -syn = { version = "0.15.30", features = ["proc-macro" ,"full", "extra-traits", "parsing"] } +syn = { version = "0.15.44", features = ["proc-macro" ,"full", "extra-traits", "parsing"] } diff --git a/srml/support/src/dispatch.rs b/srml/support/src/dispatch.rs index 21a2a817fbb1fb78b24d974c0a8c6e3d39a3869c..67cd3e44bf92f16812598610319bce71e28b2396 100644 --- a/srml/support/src/dispatch.rs +++ b/srml/support/src/dispatch.rs @@ -20,23 +20,23 @@ pub use crate::rstd::{result, prelude::{Vec, Clone, Eq, PartialEq}, marker}; #[cfg(feature = "std")] pub use std::fmt; -pub use crate::codec::{Codec, Decode, Encode, Input, Output, HasCompact, EncodeAsRef}; +pub use crate::codec::{Codec, EncodeLike, Decode, Encode, Input, Output, HasCompact, EncodeAsRef}; pub use srml_metadata::{ FunctionMetadata, DecodeDifferent, DecodeDifferentArray, FunctionArgumentMetadata, ModuleConstantMetadata, DefaultByte, DefaultByteGetter, }; -pub use sr_primitives::weights::{SimpleDispatchInfo, GetDispatchInfo, DispatchInfo, WeighData, - ClassifyDispatch, - TransactionPriority +pub use sr_primitives::{ + weights::{ + SimpleDispatchInfo, GetDispatchInfo, DispatchInfo, WeighData, ClassifyDispatch, + TransactionPriority + }, traits::{Dispatchable, DispatchResult, ModuleDispatchError}, DispatchError }; -pub use sr_primitives::traits::{Dispatchable, DispatchResult}; /// A type that cannot be instantiated. pub enum Never {} -/// Result of a module function call; either nothing (functions are only called for "side effects") -/// or an error message. -pub type Result = DispatchResult; +/// Result with string error message. This exists for backward compatibility purpose. +pub type Result = DispatchResult<&'static str>; /// Serializable version of Dispatchable. /// This value can be used as a "function" in an extrinsic. @@ -49,16 +49,16 @@ pub trait Callable { pub type CallableCallFor = >::Call; #[cfg(feature = "std")] -pub trait Parameter: Codec + Clone + Eq + fmt::Debug {} +pub trait Parameter: Codec + EncodeLike + Clone + Eq + fmt::Debug {} #[cfg(feature = "std")] -impl Parameter for T where T: Codec + Clone + Eq + fmt::Debug {} +impl Parameter for T where T: Codec + EncodeLike + Clone + Eq + fmt::Debug {} #[cfg(not(feature = "std"))] -pub trait Parameter: Codec + Clone + Eq {} +pub trait Parameter: Codec + EncodeLike + Clone + Eq {} #[cfg(not(feature = "std"))] -impl Parameter for T where T: Codec + Clone + Eq {} +impl Parameter for T where T: Codec + EncodeLike + Clone + Eq {} /// Declares a `Module` struct and a `Call` enum, which implements the dispatch logic. /// @@ -171,6 +171,9 @@ impl Parameter for T where T: Codec + Clone + Eq {} /// # fn main() {} /// ``` /// +/// Note: `decl_storage` must be called to generate `Instance` trait and optionally +/// `DefaultInstance` type. +/// /// ## Where clause /// /// Besides the default `origin: T::Origin`, you can also pass other bounds to the module declaration. @@ -200,7 +203,7 @@ impl Parameter for T where T: Codec + Clone + Eq {} /// * `deposit_event`: Helper function for depositing an [event](https://docs.substrate.dev/docs/event-enum). /// The default behavior is to call `deposit_event` from the [System module](../srml_system/index.html). /// However, you can write your own implementation for events in your runtime. To use the default behavior, -/// add `fn deposit_event() = default;` to your `Module`. +/// add `fn deposit_event() = default;` to your `Module`. /// /// The following reserved functions also take the block number (with type `T::BlockNumber`) as an optional input: /// @@ -236,6 +239,7 @@ macro_rules! decl_module { {} {} {} + {} [] $($t)* ); @@ -267,6 +271,7 @@ macro_rules! decl_module { {} {} {} + {} [] $($t)* ); @@ -283,9 +288,10 @@ macro_rules! decl_module { { $( $on_finalize:tt )* } { $( $offchain:tt )* } { $( $constants:tt )* } + { $( $error_type:tt )* } [ $( $dispatchables:tt )* ] $(#[doc = $doc_attr:tt])* - $vis:vis fn deposit_event $(<$dpeg:ident $(, $dpeg_instance:ident)?>)* () = default; + $vis:vis fn deposit_event() = default; $($rest:tt)* ) => { $crate::decl_module!(@normalize @@ -293,11 +299,12 @@ macro_rules! decl_module { pub struct $mod_type<$trait_instance: $trait_name$(, I: $instantiable $(= $module_default_instance)?)?> for enum $call_type where origin: $origin_type, system = $system { $( $other_where_bounds )* } - { $vis fn deposit_event $(<$dpeg $(, $dpeg_instance)?>)* () = default; } + { $vis fn deposit_event() = default; } { $( $on_initialize )* } { $( $on_finalize )* } { $( $offchain )* } { $( $constants )* } + { $( $error_type )* } [ $( $dispatchables )* ] $($rest)* ); @@ -312,25 +319,14 @@ macro_rules! decl_module { { $( $on_finalize:tt )* } { $( $offchain:tt )* } { $( $constants:tt )* } + { $( $error_type:tt )* } [ $( $dispatchables:tt )* ] $(#[doc = $doc_attr:tt])* - $vis:vis fn deposit_event $(<$dpeg:ident $(, $dpeg_instance:ident)?>)* ( - $($param_name:ident : $param:ty),* - ) { $( $impl:tt )* } + $vis:vis fn deposit_event $($rest:tt)* ) => { - $crate::decl_module!(@normalize - $(#[$attr])* - pub struct $mod_type<$trait_instance: $trait_name$(, I: $instantiable $(= $module_default_instance)?)?> - for enum $call_type where origin: $origin_type, system = $system - { $( $other_where_bounds )* } - { $vis fn deposit_event $(<$dpeg $(, $dpeg_instance)?>)* ($( $param_name: $param ),* ) { $( $impl )* } } - { $( $on_initialize )* } - { $( $on_finalize )* } - { $( $offchain )* } - { $( $constants )* } - [ $( $dispatchables )* ] - $($rest)* + compile_error!( + "`deposit_event` function is reserved and must follow the syntax: `$vis:vis fn deposit_event() = default;`" ); }; (@normalize @@ -343,9 +339,10 @@ macro_rules! decl_module { {} { $( $offchain:tt )* } { $( $constants:tt )* } + { $( $error_type:tt )* } [ $( $dispatchables:tt )* ] $(#[doc = $doc_attr:tt])* - fn on_finalize($($param_name:ident : $param:ty),* ) { $( $impl:tt )* } + fn on_finalize( $( $param_name:ident : $param:ty ),* $(,)? ) { $( $impl:tt )* } $($rest:tt)* ) => { $crate::decl_module!(@normalize @@ -358,29 +355,11 @@ macro_rules! decl_module { { fn on_finalize( $( $param_name : $param ),* ) { $( $impl )* } } { $( $offchain )* } { $( $constants )* } + { $( $error_type )* } [ $( $dispatchables )* ] $($rest)* ); }; - (@normalize - $(#[$attr:meta])* - pub struct $mod_type:ident<$trait_instance:ident: $trait_name:ident$(, I: $instantiable:path $(= $module_default_instance:path)?)?> - for enum $call_type:ident where origin: $origin_type:ty, system = $system:ident - { $( $other_where_bounds:tt )* } - { $( $deposit_event:tt )* } - { $( $on_initialize:tt )* } - {} - { $( $offchain:tt )* } - { $( $constants:tt )* } - [ $( $dispatchables:tt )* ] - $(#[doc = $doc_attr:tt])* - fn on_finalise($($param_name:ident : $param:ty),* ) { $( $impl:tt )* } - $($rest:tt)* - ) => { - compile_error!( - "`on_finalise` was renamed to `on_finalize`. Please rename your function accordingly." - ); - }; (@normalize $(#[$attr:meta])* pub struct $mod_type:ident<$trait_instance:ident: $trait_name:ident$(, I: $instantiable:path $(= $module_default_instance:path)?)?> @@ -391,9 +370,10 @@ macro_rules! decl_module { { $( $on_finalize:tt )* } { $( $offchain:tt )* } { $( $constants:tt )* } + { $( $error_type:tt )* } [ $( $dispatchables:tt )* ] $(#[doc = $doc_attr:tt])* - fn on_initialize($($param_name:ident : $param:ty),* ) { $( $impl:tt )* } + fn on_initialize( $( $param_name:ident : $param:ty ),* $(,)? ) { $( $impl:tt )* } $($rest:tt)* ) => { $crate::decl_module!(@normalize @@ -406,29 +386,11 @@ macro_rules! decl_module { { $( $on_finalize )* } { $( $offchain )* } { $( $constants )* } + { $( $error_type )* } [ $( $dispatchables )* ] $($rest)* ); }; - (@normalize - $(#[$attr:meta])* - pub struct $mod_type:ident<$trait_instance:ident: $trait_name:ident$(, I: $instantiable:path $(= $module_default_instance:path)?)?> - for enum $call_type:ident where origin: $origin_type:ty, system = $system:ident - { $( $other_where_bounds:tt )* } - { $( $deposit_event:tt )* } - {} - { $( $on_finalize:tt )* } - { $( $offchain:tt )* } - { $( $constants:tt )* } - [ $( $dispatchables:tt )* ] - $(#[doc = $doc_attr:tt])* - fn on_initialise($($param_name:ident : $param:ty),* ) { $( $impl:tt )* } - $($rest:tt)* - ) => { - compile_error!( - "`on_initialise` was renamed to `on_initialize`. Please rename your function accordingly." - ); - }; (@normalize $(#[$attr:meta])* pub struct $mod_type:ident< @@ -442,9 +404,10 @@ macro_rules! decl_module { { $( $on_finalize:tt )* } { } { $( $constants:tt )* } + { $( $error_type:tt )* } [ $( $dispatchables:tt )* ] $(#[doc = $doc_attr:tt])* - fn offchain_worker($($param_name:ident : $param:ty),* ) { $( $impl:tt )* } + fn offchain_worker( $( $param_name:ident : $param:ty ),* $(,)? ) { $( $impl:tt )* } $($rest:tt)* ) => { $crate::decl_module!(@normalize @@ -459,6 +422,7 @@ macro_rules! decl_module { { $( $on_finalize )* } { fn offchain_worker( $( $param_name : $param ),* ) { $( $impl )* } } { $( $constants )* } + { $( $error_type )* } [ $( $dispatchables )* ] $($rest)* ); @@ -478,6 +442,7 @@ macro_rules! decl_module { { $( $on_finalize:tt )* } { $( $offchain:tt )* } { $( $constants:tt )* } + { $( $error_type:tt )* } [ $( $dispatchables:tt )* ] $( #[doc = $doc_attr:tt] )* const $name:ident: $ty:ty = $value:expr; @@ -500,10 +465,84 @@ macro_rules! decl_module { $( #[doc = $doc_attr ] )* $name: $ty = $value; } + { $( $error_type )* } + [ $( $dispatchables )* ] + $($rest)* + ); + }; + + // Parse error type + (@normalize + $(#[$attr:meta])* + pub struct $mod_type:ident< + $trait_instance:ident: + $trait_name:ident$(, $instance:ident: $instantiable:path $(= $module_default_instance:path)?)? + > + for enum $call_type:ident where origin: $origin_type:ty, system = $system:ident + { $( $other_where_bounds:tt )* } + { $( $deposit_event:tt )* } + { $( $on_initialize:tt )* } + { $( $on_finalize:tt )* } + { $( $offchain:tt )* } + { $( $constants:tt )* } + { } + [ $( $dispatchables:tt )* ] + $(#[doc = $doc_attr:tt])* + type Error = $error_type:ty; + $($rest:tt)* + ) => { + $crate::decl_module!(@normalize + $(#[$attr])* + pub struct $mod_type< + $trait_instance: $trait_name$(, $instance: $instantiable $(= $module_default_instance)?)? + > + for enum $call_type where origin: $origin_type, system = $system + { $( $other_where_bounds )* } + { $( $deposit_event )* } + { $( $on_initialize )* } + { $( $on_finalize )* } + { $( $offchain )* } + { $( $constants )* } + { $error_type } [ $( $dispatchables )* ] $($rest)* ); }; + // Add default Error if none supplied + (@normalize + $(#[$attr:meta])* + pub struct $mod_type:ident< + $trait_instance:ident: + $trait_name:ident$(, $instance:ident: $instantiable:path $(= $module_default_instance:path)?)? + > + for enum $call_type:ident where origin: $origin_type:ty, system = $system:ident + { $( $other_where_bounds:tt )* } + { $( $deposit_event:tt )* } + { $( $on_initialize:tt )* } + { $( $on_finalize:tt )* } + { $( $offchain:tt )* } + { $( $constants:tt )* } + { } + [ $($t:tt)* ] + $($rest:tt)* + ) => { + $crate::decl_module!(@normalize + $(#[$attr])* + pub struct $mod_type< + $trait_instance: $trait_name$(, $instance: $instantiable $(= $module_default_instance)?)? + > + for enum $call_type where origin: $origin_type, system = $system + { $( $other_where_bounds )* } + { $( $deposit_event )* } + { $( $on_initialize )* } + { $( $on_finalize )* } + { $( $offchain )* } + { $( $constants )* } + { &'static str } + [ $($t)* ] + $($rest)* + ); + }; // This puts the function statement into the [], decreasing `$rest` and moving toward finishing the parse. (@normalize @@ -519,11 +558,12 @@ macro_rules! decl_module { { $( $on_finalize:tt )* } { $( $offchain:tt )* } { $( $constants:tt )* } + { $error_type:ty } [ $( $dispatchables:tt )* ] $(#[doc = $doc_attr:tt])* #[weight = $weight:expr] $fn_vis:vis fn $fn_name:ident( - $origin:ident $(, $(#[$codec_attr:ident])* $param_name:ident : $param:ty)* + $origin:ident $( , $(#[$codec_attr:ident])* $param_name:ident : $param:ty )* $(,)? ) $( -> $result:ty )* { $( $impl:tt )* } $($rest:tt)* ) => { @@ -539,6 +579,7 @@ macro_rules! decl_module { { $( $on_finalize )* } { $( $offchain )* } { $( $constants )* } + { $error_type } [ $( $dispatchables )* $(#[doc = $doc_attr])* @@ -565,10 +606,11 @@ macro_rules! decl_module { { $( $on_finalize:tt )* } { $( $offchain:tt )* } { $( $constants:tt )* } + { $( $error_type:tt )* } [ $( $dispatchables:tt )* ] $(#[doc = $doc_attr:tt])* $fn_vis:vis fn $fn_name:ident( - $from:ident $(, $(#[$codec_attr:ident])* $param_name:ident : $param:ty)* + $from:ident $( , $( #[$codec_attr:ident] )* $param_name:ident : $param:ty )* $(,)? ) $( -> $result:ty )* { $( $impl:tt )* } $($rest:tt)* ) => { @@ -584,6 +626,7 @@ macro_rules! decl_module { { $( $on_finalize )* } { $( $offchain )* } { $( $constants )* } + { $( $error_type )* } [ $( $dispatchables )* ] $(#[doc = $doc_attr])* #[weight = $crate::dispatch::SimpleDispatchInfo::default()] @@ -604,11 +647,12 @@ macro_rules! decl_module { { $( $on_finalize:tt )* } { $( $offchain:tt )* } { $( $constants:tt )* } + { $( $error_type:tt )* } [ $( $dispatchables:tt )* ] $(#[doc = $doc_attr:tt])* $(#[weight = $weight:expr])? $fn_vis:vis fn $fn_name:ident( - $origin:ident : T::Origin $(, $(#[$codec_attr:ident])* $param_name:ident : $param:ty)* + $origin:ident : T::Origin $( , $( #[$codec_attr:ident] )* $param_name:ident : $param:ty )* $(,)? ) $( -> $result:ty )* { $( $impl:tt )* } $($rest:tt)* ) => { @@ -628,11 +672,12 @@ macro_rules! decl_module { { $( $on_finalize:tt )* } { $( $offchain:tt )* } { $( $constants:tt )* } + { $( $error_type:tt )* } [ $( $dispatchables:tt )* ] $(#[doc = $doc_attr:tt])* $(#[weight = $weight:expr])? $fn_vis:vis fn $fn_name:ident( - origin : $origin:ty $(, $(#[$codec_attr:ident])* $param_name:ident : $param:ty)* + origin : $origin:ty $( , $( #[$codec_attr:ident] )* $param_name:ident : $param:ty )* $(,)? ) $( -> $result:ty )* { $( $impl:tt )* } $($rest:tt)* ) => { @@ -652,11 +697,12 @@ macro_rules! decl_module { { $( $on_finalize:tt )* } { $( $offchain:tt )* } { $( $constants:tt )* } + { $( $error_type:tt )* } [ $( $dispatchables:tt )* ] $(#[doc = $doc_attr:tt])* $(#[weight = $weight:expr])? $fn_vis:vis fn $fn_name:ident( - $( $(#[$codec_attr:ident])* $param_name:ident : $param:ty),* + $( $(#[$codec_attr:ident])* $param_name:ident : $param:ty ),* $(,)? ) $( -> $result:ty )* { $( $impl:tt )* } $($rest:tt)* ) => { @@ -677,6 +723,7 @@ macro_rules! decl_module { { $( $on_finalize:tt )* } { $( $offchain:tt )* } { $( $constants:tt )* } + { $( $error_type:tt )* } [ $( $dispatchables:tt )* ] ) => { $crate::decl_module!(@imp @@ -691,6 +738,7 @@ macro_rules! decl_module { { $( $on_finalize )* } { $( $offchain )* } { $( $constants )* } + { $( $error_type )* } ); }; @@ -720,25 +768,10 @@ macro_rules! decl_module { impl<$trait_instance: $trait_name$(, $instance: $instantiable)?> $module<$trait_instance $(, $instance)?> where $( $other_where_bounds )* { - $vis fn deposit_event(event: Event$(<$event_trait_instance $(, $event_instance)?>)?) { - <$system::Module<$trait_instance>>::deposit_event( - <$trait_instance as $trait_name$(<$instance>)?>::Event::from(event).into() - ); - } - } - }; - - (@impl_deposit_event - $module:ident<$trait_instance:ident: $trait_name:ident$(, $instance:ident: $instantiable:path)?>; - $system:ident; - { $( $other_where_bounds:tt )* } - $vis:vis fn deposit_event($param:ident : $param_ty:ty) { $( $impl:tt )* } - ) => { - impl<$trait_instance: $trait_name$(, $instance: $instantiable)?> $module<$trait_instance $(, $instance)?> - where $( $other_where_bounds )* - { - $vis fn deposit_event($param: $param_ty) { - $( $impl )* + $vis fn deposit_event( + event: impl Into<< $trait_instance as $trait_name $(<$instance>)? >::Event> + ) { + <$system::Module<$trait_instance>>::deposit_event(event.into()) } } }; @@ -856,6 +889,7 @@ macro_rules! decl_module { (@impl_function $module:ident<$trait_instance:ident: $trait_name:ident$(, $instance:ident: $instantiable:path)?>; $origin_ty:ty; + $error_type:ty; $ignore:ident; $(#[doc = $doc_attr:tt])* $vis:vis fn $name:ident ( @@ -866,7 +900,7 @@ macro_rules! decl_module { #[allow(unreachable_code)] $vis fn $name( $origin: $origin_ty $(, $param: $param_ty )* - ) -> $crate::dispatch::Result { + ) -> $crate::dispatch::DispatchResult<$error_type> { { $( $impl )* } // May be unreachable. Ok(()) @@ -877,6 +911,7 @@ macro_rules! decl_module { (@impl_function $module:ident<$trait_instance:ident: $trait_name:ident$(, $instance:ident: $instantiable:path)?>; $origin_ty:ty; + $error_type:ty; $ignore:ident; $(#[doc = $doc_attr:tt])* $vis:vis fn $name:ident ( @@ -1031,6 +1066,7 @@ macro_rules! decl_module { { $( $on_finalize:tt )* } { $( $offchain:tt )* } { $( $constants:tt )* } + { $error_type:ty } ) => { $crate::__check_reserved_fn_name! { $( $fn_name )* } @@ -1082,6 +1118,7 @@ macro_rules! decl_module { @impl_function $mod_type<$trait_instance: $trait_name $(, $fn_instance: $fn_instantiable)?>; $origin_type; + $error_type; $from; $(#[doc = $doc_attr])* $fn_vis fn $fn_name ( @@ -1212,7 +1249,8 @@ macro_rules! decl_module { { type Trait = $trait_instance; type Origin = $origin_type; - fn dispatch(self, _origin: Self::Origin) -> $crate::dispatch::Result { + type Error = $error_type; + fn dispatch(self, _origin: Self::Origin) -> $crate::dispatch::DispatchResult { match self { $( $call_type::$fn_name( $( $param_name ),* ) => { @@ -1239,8 +1277,8 @@ macro_rules! decl_module { #[doc(hidden)] pub fn dispatch>( d: D, - origin: D::Origin, - ) -> $crate::dispatch::Result { + origin: D::Origin + ) -> $crate::dispatch::DispatchResult { d.dispatch(origin) } } @@ -1296,9 +1334,19 @@ macro_rules! impl_outer_dispatch { impl $crate::dispatch::Dispatchable for $call_type { type Origin = $origin; type Trait = $call_type; - fn dispatch(self, origin: $origin) -> $crate::dispatch::Result { - match self { - $( $call_type::$camelcase(call) => call.dispatch(origin), )* + type Error = $crate::dispatch::DispatchError; + fn dispatch( + self, + origin: $origin, + ) -> $crate::dispatch::DispatchResult<$crate::dispatch::DispatchError> { + $crate::impl_outer_dispatch! { + @DISPATCH_MATCH + self + $call_type + origin + {} + 0; + $( $camelcase ),* } } } @@ -1320,6 +1368,43 @@ macro_rules! impl_outer_dispatch { } } )* + }; + (@DISPATCH_MATCH + $self:ident + $call_type:ident + $origin:ident + { $( $generated:tt )* } + $index:expr; + $name:ident + $( , $rest:ident )* + ) => { + $crate::impl_outer_dispatch! { + @DISPATCH_MATCH + $self + $call_type + $origin + { + $( $generated )* + $call_type::$name(call) => call.dispatch($origin).map_err(|e| { + let mut error: $crate::dispatch::DispatchError = e.into(); + error.module = Some($index); + error + }), + } + $index + 1; + $( $rest ),* + } + }; + (@DISPATCH_MATCH + $self:ident + $call_type:ident + $origin:ident + { $( $generated:tt )* } + $index:expr; + ) => { + match $self { + $( $generated )* + } } } @@ -1576,13 +1661,13 @@ macro_rules! __check_reserved_fn_name { $crate::__check_reserved_fn_name!(@compile_error on_initialize); }; (on_initialise $( $rest:ident )*) => { - $crate::__check_reserved_fn_name!(@compile_error on_initialise); + $crate::__check_reserved_fn_name!(@compile_error_renamed on_initialise on_initialize); }; (on_finalize $( $rest:ident )*) => { $crate::__check_reserved_fn_name!(@compile_error on_finalize); }; (on_finalise $( $rest:ident )*) => { - $crate::__check_reserved_fn_name!(@compile_error on_finalise); + $crate::__check_reserved_fn_name!(@compile_error_renamed on_finalise on_finalize); }; (offchain_worker $( $rest:ident )*) => { $crate::__check_reserved_fn_name!(@compile_error offchain_worker); @@ -1592,9 +1677,26 @@ macro_rules! __check_reserved_fn_name { }; () => {}; (@compile_error $ident:ident) => { - compile_error!(concat!("Invalid call fn name: `", stringify!($ident), - "`, name is reserved and doesn't match expected signature, please refer to `decl_module!`", - " documentation to see the appropriate usage, or rename it to an unreserved keyword.")); + compile_error!( + concat!( + "Invalid call fn name: `", + stringify!($ident), + "`, name is reserved and doesn't match expected signature, please refer to ", + "`decl_module!` documentation to see the appropriate usage, or rename it to an ", + "unreserved keyword." + ), + ); + }; + (@compile_error_renamed $ident:ident $new_ident:ident) => { + compile_error!( + concat!( + "`", + stringify!($ident), + "` was renamed to `", + stringify!($new_ident), + "`. Please rename your function accordingly.", + ), + ); }; } @@ -1628,19 +1730,19 @@ mod tests { pub struct Module for enum Call where origin: T::Origin, T::AccountId: From { /// Hi, this is a comment. fn aux_0(_origin) -> Result { unreachable!() } - fn aux_1(_origin, #[compact] _data: u32) -> Result { unreachable!() } + fn aux_1(_origin, #[compact] _data: u32,) -> Result { unreachable!() } fn aux_2(_origin, _data: i32, _data2: String) -> Result { unreachable!() } #[weight = SimpleDispatchInfo::FixedNormal(3)] fn aux_3(_origin) -> Result { unreachable!() } fn aux_4(_origin, _data: i32) -> Result { unreachable!() } - fn aux_5(_origin, _data: i32, #[compact] _data2: u32) -> Result { unreachable!() } + fn aux_5(_origin, _data: i32, #[compact] _data2: u32,) -> Result { unreachable!() } - fn on_initialize(n: T::BlockNumber) { if n.into() == 42 { panic!("on_initialize") } } + fn on_initialize(n: T::BlockNumber,) { if n.into() == 42 { panic!("on_initialize") } } fn on_finalize(n: T::BlockNumber) { if n.into() == 42 { panic!("on_finalize") } } fn offchain_worker() {} #[weight = SimpleDispatchInfo::FixedOperational(5)] - fn operational(_origin) { unreachable!() } + fn operational(_origin,) { unreachable!() } } } diff --git a/srml/support/src/double_map.rs b/srml/support/src/double_map.rs deleted file mode 100644 index aec7f497a63913391256237b7a8df1a360ab3ccb..0000000000000000000000000000000000000000 --- a/srml/support/src/double_map.rs +++ /dev/null @@ -1,140 +0,0 @@ -// Copyright 2017-2019 Parity Technologies (UK) Ltd. -// This file is part of Substrate. - -// Substrate 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. - -// Substrate 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 Substrate. If not, see . - -//! An implementation of double map backed by storage. - -use crate::rstd::prelude::*; -use crate::codec::{Codec, Encode}; -use crate::storage::unhashed; -use sr_std::borrow::Borrow; - -/// An implementation of a map with a two keys. -/// -/// It provides an important ability to efficiently remove all entries -/// that have a common first key. -/// -/// # Mapping of keys to a storage path -/// -/// The storage key (i.e. the key under which the `Value` will be stored) is created from two parts. -/// The first part is a hash of a concatenation of the `PREFIX` and `Key1`. And the second part -/// is a hash of a `Key2`. -/// -/// Hasher are implemented in derive_key* methods. -pub trait StorageDoubleMapWithHasher { - type Key1: Encode; - type Key2: Encode; - type Value: Codec + Default; - - const PREFIX: &'static [u8]; - - /// Insert an entry into this map. - fn insert(k1: &Q, k2: &R, val: Self::Value) - where - Self::Key1: Borrow, - Self::Key2: Borrow, - Q: Codec, - R: Codec - { - unhashed::put(&Self::full_key(k1, k2)[..], &val); - } - - /// Remove an entry from this map. - fn remove(k1: &Q, k2: &R) - where - Self::Key1: Borrow, - Self::Key2: Borrow, - Q: Codec, - R: Codec - { - unhashed::kill(&Self::full_key(k1, k2)[..]); - } - - /// Get an entry from this map. - /// - /// If there is no entry stored under the given keys, returns `None`. - fn get(k1: &Q, k2: &R) -> Option - where - Self::Key1: Borrow, - Self::Key2: Borrow, - Q: Codec, - R: Codec - { - unhashed::get(&Self::full_key(k1, k2)[..]) - } - - /// Returns `true` if value under the specified keys exists. - fn exists(k1: &Q, k2: &R) -> bool - where - Self::Key1: Borrow, - Self::Key2: Borrow, - Q: Codec, - R: Codec - { - unhashed::exists(&Self::full_key(k1, k2)[..]) - } - - /// Removes all entries that shares the `k1` as the first key. - fn remove_prefix(k1: &Q) - where - Self::Key1: Borrow, - Q: Codec - { - unhashed::kill_prefix(&Self::derive_key1(Self::encode_key1(k1))) - } - - /// Encode key1 into Vec and prepend a prefix - fn encode_key1(key: &Q) -> Vec - where - Self::Key1: Borrow, - Q: Codec - { - let mut raw_prefix = Vec::new(); - raw_prefix.extend(Self::PREFIX); - key.encode_to(&mut raw_prefix); - raw_prefix - } - - /// Encode key2 into Vec - fn encode_key2(key: &R) -> Vec - where - Self::Key2: Borrow, - R: Codec - { - Encode::encode(&key) - } - - /// Derive the first part of the key - fn derive_key1(key1_data: Vec) -> Vec; - - /// Derive the remaining part of the key - fn derive_key2(key2_data: Vec) -> Vec; - - /// Returns a compound key that consist of the two parts: (prefix, `k1`) and `k2`. - /// The first part is hashed and then concatenated with a hash of `k2`. - fn full_key(k1: &Q, k2: &R) -> Vec - where - Self::Key1: Borrow, - Self::Key2: Borrow, - Q: Codec, - R: Codec - { - let key1_data = Self::encode_key1(k1); - let key2_data = Self::encode_key2(k2); - let mut key = Self::derive_key1(key1_data); - key.extend(Self::derive_key2(key2_data)); - key - } -} diff --git a/srml/support/src/error.rs b/srml/support/src/error.rs new file mode 100644 index 0000000000000000000000000000000000000000..2f9d9379bfd04b23aabc3727384656fd39bf56a6 --- /dev/null +++ b/srml/support/src/error.rs @@ -0,0 +1,151 @@ +// Copyright 2019 Parity Technologies (UK) Ltd. +// This file is part of Substrate. + +// Substrate 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. + +// Substrate 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 Substrate. If not, see . + +//! Macro for declaring a module error. + +#[doc(hidden)] +pub use sr_primitives::traits::LookupError; + +/// Declare an error type for a runtime module. +/// +/// The generated error type inherently has the variants `Other` and `CannotLookup`. `Other` can +/// hold any `&'static str` error message and is present for convenience/backward compatibility. +/// The `CannotLookup` variant indicates that some lookup could not be done. For both variants the +/// error type implements `From<&'static str>` and `From` to make them usable with the +/// try operator. +/// +/// # Usage +/// +/// ``` +/// # use srml_support::decl_error; +/// decl_error! { +/// /// Errors that can occur in my module. +/// pub enum MyError { +/// /// Hey this is an error message that indicates bla. +/// MyCoolErrorMessage, +/// /// You are just not cool enough for my module! +/// YouAreNotCoolEnough, +/// } +/// } +/// ``` +/// +/// `decl_error!` supports only variants that do not hold any data. +#[macro_export] +macro_rules! decl_error { + ( + $(#[$attr:meta])* + pub enum $error:ident { + $( + $( #[$variant_attr:meta] )* + $name:ident + ),* + $(,)? + } + ) => { + #[derive(Clone, PartialEq, Eq)] + #[cfg_attr(feature = "std", derive(Debug))] + $(#[$attr])* + pub enum $error { + Other(&'static str), + CannotLookup, + $( + $(#[$variant_attr])* + $name + ),* + } + + impl $crate::dispatch::ModuleDispatchError for $error { + fn as_u8(&self) -> u8 { + $crate::decl_error! { + @GENERATE_AS_U8 + self + $error + {} + 2, + $( $name ),* + } + } + + fn as_str(&self) -> &'static str { + match self { + $error::Other(err) => err, + $error::CannotLookup => "Can not lookup", + $( + $error::$name => stringify!($name), + )* + } + } + } + + impl From<&'static str> for $error { + fn from(val: &'static str) -> $error { + $error::Other(val) + } + } + + impl From<$crate::error::LookupError> for $error { + fn from(_: $crate::error::LookupError) -> $error { + $error::CannotLookup + } + } + + impl From<$error> for &'static str { + fn from(err: $error) -> &'static str { + use $crate::dispatch::ModuleDispatchError; + err.as_str() + } + } + + impl Into<$crate::dispatch::DispatchError> for $error { + fn into(self) -> $crate::dispatch::DispatchError { + use $crate::dispatch::ModuleDispatchError; + $crate::dispatch::DispatchError::new(None, self.as_u8(), Some(self.as_str())) + } + } + }; + (@GENERATE_AS_U8 + $self:ident + $error:ident + { $( $generated:tt )* } + $index:expr, + $name:ident + $( , $rest:ident )* + ) => { + $crate::decl_error! { + @GENERATE_AS_U8 + $self + $error + { + $( $generated )* + $error::$name => $index, + } + $index + 1, + $( $rest ),* + } + }; + (@GENERATE_AS_U8 + $self:ident + $error:ident + { $( $generated:tt )* } + $index:expr, + ) => { + match $self { + $error::Other(_) => 0, + $error::CannotLookup => 1, + $( $generated )* + } + } +} diff --git a/srml/support/src/event.rs b/srml/support/src/event.rs index 857f42f49e8aaa2b9dfc2a2c49f6a1575a9883b2..eb5cc20635725b40b4416a0723fb3157a8f22f56 100644 --- a/srml/support/src/event.rs +++ b/srml/support/src/event.rs @@ -452,31 +452,44 @@ macro_rules! impl_outer_event { $( $module_name:ident::Event $( <$generic_param:ident> )? $( { $generic_instance:ident } )?, )*; ) => { $crate::paste::item! { - // Workaround for https://github.com/rust-lang/rust/issues/26925 . Remove when sorted. - #[derive(Clone, PartialEq, Eq, $crate::codec::Encode, $crate::codec::Decode)] - #[cfg_attr(feature = "std", derive(Debug))] - $(#[$attr])* - #[allow(non_camel_case_types)] - pub enum $name { - system($system::Event), - $( - [< $module_name $(_ $generic_instance )? >]( - $module_name::Event < $( $generic_param )? $(, $module_name::$generic_instance )? > - ), - )* - } - impl From<$system::Event> for $name { - fn from(x: $system::Event) -> Self { - $name::system(x) + #[derive(Clone, PartialEq, Eq, $crate::codec::Encode, $crate::codec::Decode)] + #[cfg_attr(feature = "std", derive(Debug))] + $(#[$attr])* + #[allow(non_camel_case_types)] + pub enum $name { + system($system::Event), + $( + [< $module_name $(_ $generic_instance )? >]( + $module_name::Event < $( $generic_param )? $(, $module_name::$generic_instance )? > + ), + )* } - } - $( - impl From<$module_name::Event < $( $generic_param, )? $( $module_name::$generic_instance )? >> for $name { - fn from(x: $module_name::Event < $( $generic_param, )? $( $module_name::$generic_instance )? >) -> Self { - $name::[< $module_name $(_ $generic_instance )? >](x) + impl From<$system::Event> for $name { + fn from(x: $system::Event) -> Self { + $name::system(x) } } - )* + $( + impl From<$module_name::Event < $( $generic_param, )? $( $module_name::$generic_instance )? >> for $name { + fn from(x: $module_name::Event < $( $generic_param, )? $( $module_name::$generic_instance )? >) -> Self { + $name::[< $module_name $(_ $generic_instance )? >](x) + } + } + impl $crate::rstd::convert::TryInto< + $module_name::Event < $( $generic_param, )? $( $module_name::$generic_instance )? > + > for $name { + type Error = (); + + fn try_into(self) -> $crate::rstd::result::Result< + $module_name::Event < $( $generic_param, )? $( $module_name::$generic_instance )? >, Self::Error + > { + match self { + Self::[< $module_name $(_ $generic_instance )? >](evt) => Ok(evt), + _ => Err(()), + } + } + } + )* } $crate::__impl_outer_event_json_metadata!( $runtime; diff --git a/srml/support/src/hash.rs b/srml/support/src/hash.rs new file mode 100644 index 0000000000000000000000000000000000000000..3775ebc26bc3b9a4bd2ffdee10d0bab0a90ac280 --- /dev/null +++ b/srml/support/src/hash.rs @@ -0,0 +1,114 @@ +// Copyright 2017-2019 Parity Technologies (UK) Ltd. +// This file is part of Substrate. + +// Substrate 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. + +// Substrate 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 Substrate. If not, see . + +//! Hash utilities. + +use codec::Codec; +use rstd::prelude::Vec; +use runtime_io::{blake2_128, blake2_256, twox_64, twox_128, twox_256}; + +// This trait must be kept coherent with srml-support-procedural HasherKind usage +pub trait Hashable: Sized { + fn blake2_128(&self) -> [u8; 16]; + fn blake2_256(&self) -> [u8; 32]; + fn twox_128(&self) -> [u8; 16]; + fn twox_256(&self) -> [u8; 32]; + fn twox_64_concat(&self) -> Vec; +} + +impl Hashable for T { + fn blake2_128(&self) -> [u8; 16] { + self.using_encoded(blake2_128) + } + fn blake2_256(&self) -> [u8; 32] { + self.using_encoded(blake2_256) + } + fn twox_128(&self) -> [u8; 16] { + self.using_encoded(twox_128) + } + fn twox_256(&self) -> [u8; 32] { + self.using_encoded(twox_256) + } + fn twox_64_concat(&self) -> Vec { + self.using_encoded(Twox64Concat::hash) + } +} + +/// Hasher to use to hash keys to insert to storage. +pub trait StorageHasher: 'static { + type Output: AsRef<[u8]>; + fn hash(x: &[u8]) -> Self::Output; +} + +/// Hash storage keys with `concat(twox64(key), key)` +pub struct Twox64Concat; +impl StorageHasher for Twox64Concat { + type Output = Vec; + fn hash(x: &[u8]) -> Vec { + twox_64(x) + .into_iter() + .chain(x.into_iter()) + .cloned() + .collect::>() + } +} + +/// Hash storage keys with blake2 128 +pub struct Blake2_128; +impl StorageHasher for Blake2_128 { + type Output = [u8; 16]; + fn hash(x: &[u8]) -> [u8; 16] { + blake2_128(x) + } +} + +/// Hash storage keys with blake2 256 +pub struct Blake2_256; +impl StorageHasher for Blake2_256 { + type Output = [u8; 32]; + fn hash(x: &[u8]) -> [u8; 32] { + blake2_256(x) + } +} + +/// Hash storage keys with twox 128 +pub struct Twox128; +impl StorageHasher for Twox128 { + type Output = [u8; 16]; + fn hash(x: &[u8]) -> [u8; 16] { + twox_128(x) + } +} + +/// Hash storage keys with twox 256 +pub struct Twox256; +impl StorageHasher for Twox256 { + type Output = [u8; 32]; + fn hash(x: &[u8]) -> [u8; 32] { + twox_256(x) + } +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_twox_64_concat() { + let r = Twox64Concat::hash(b"foo"); + assert_eq!(r.split_at(8), (&twox_128(b"foo")[..8], &b"foo"[..])) + } +} diff --git a/srml/support/src/hashable.rs b/srml/support/src/hashable.rs deleted file mode 100644 index b3ee2b3612c1efda2615a9f21d4e26b64325e528..0000000000000000000000000000000000000000 --- a/srml/support/src/hashable.rs +++ /dev/null @@ -1,50 +0,0 @@ -// Copyright 2017-2019 Parity Technologies (UK) Ltd. -// This file is part of Substrate. - -// Substrate 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. - -// Substrate 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 Substrate. If not, see . - -//! Hashable trait. - -use crate::codec::Codec; -use runtime_io::{blake2_128, blake2_256, twox_128, twox_256}; -use crate::storage::hashed::generator::StorageHasher; -use crate::Twox64Concat; -use crate::rstd::prelude::Vec; - -// This trait must be kept coherent with srml-support-procedural HasherKind usage -pub trait Hashable: Sized { - fn blake2_128(&self) -> [u8; 16]; - fn blake2_256(&self) -> [u8; 32]; - fn twox_128(&self) -> [u8; 16]; - fn twox_256(&self) -> [u8; 32]; - fn twox_64_concat(&self) -> Vec; -} - -impl Hashable for T { - fn blake2_128(&self) -> [u8; 16] { - self.using_encoded(blake2_128) - } - fn blake2_256(&self) -> [u8; 32] { - self.using_encoded(blake2_256) - } - fn twox_128(&self) -> [u8; 16] { - self.using_encoded(twox_128) - } - fn twox_256(&self) -> [u8; 32] { - self.using_encoded(twox_256) - } - fn twox_64_concat(&self) -> Vec { - self.using_encoded(Twox64Concat::hash) - } -} diff --git a/srml/support/src/inherent.rs b/srml/support/src/inherent.rs index 1b6d8fbdd7ed93588da2892c1ccc3357c900fd2f..935d3b4e74e4f47c14a7c6703a579533d0501dab 100644 --- a/srml/support/src/inherent.rs +++ b/srml/support/src/inherent.rs @@ -55,14 +55,16 @@ macro_rules! impl_outer_inherent { fn create_extrinsics(&self) -> $crate::inherent::Vec<<$block as $crate::inherent::BlockT>::Extrinsic> { use $crate::inherent::ProvideInherent; + use $crate::inherent::Extrinsic; let mut inherents = Vec::new(); $( if let Some(inherent) = $module::create_inherent(self) { - inherents.push($uncheckedextrinsic::new_unsigned( - Call::$call(inherent)) - ); + inherents.push($uncheckedextrinsic::new( + Call::$call(inherent), + None, + ).expect("Runtime UncheckedExtrinsic is not Opaque, so it has to return `Some`; qed")); } )* diff --git a/srml/support/src/lib.rs b/srml/support/src/lib.rs index 5623cab70f2ab4dc9b1f3451d1e17f7a72e12554..b88d86761c3141daba4448f54f85efb1fa891ca1 100644 --- a/srml/support/src/lib.rs +++ b/srml/support/src/lib.rs @@ -27,7 +27,7 @@ extern crate bitmask; #[cfg(feature = "std")] pub use serde; #[doc(hidden)] -pub use sr_std as rstd; +pub use rstd; #[doc(hidden)] pub use codec; #[cfg(feature = "std")] @@ -35,17 +35,17 @@ pub use codec; pub use once_cell; #[doc(hidden)] pub use paste; - -pub use self::storage::hashed::generator::{ - HashedStorage, Twox256, Twox128, Blake2_256, Blake2_128, Twox64Concat -}; -pub use self::storage::unhashed::generator::UnhashedStorage; +#[cfg(feature = "std")] +#[doc(hidden)] +pub use runtime_io::with_storage; +#[doc(hidden)] +pub use runtime_io::storage_root; #[macro_use] pub mod dispatch; #[macro_use] pub mod storage; -mod hashable; +mod hash; #[macro_use] pub mod event; #[macro_use] @@ -58,17 +58,14 @@ mod runtime; pub mod inherent; #[macro_use] pub mod unsigned; -mod double_map; +#[macro_use] +pub mod error; pub mod traits; -pub use self::storage::{ - StorageValue, StorageMap, EnumerableStorageMap, StorageDoubleMap, AppendableStorageMap -}; -pub use self::hashable::Hashable; -pub use self::dispatch::{Parameter, Dispatchable, Callable, IsSubType}; -pub use self::double_map::StorageDoubleMapWithHasher; -pub use runtime_io::{print, storage_root}; -pub use sr_primitives::{self, ConsensusEngineId}; +pub use self::hash::{Twox256, Twox128, Blake2_256, Blake2_128, Twox64Concat, Hashable}; +pub use self::storage::{StorageValue, StorageMap, StorageLinkedMap, StorageDoubleMap}; +pub use self::dispatch::{Parameter, Callable, IsSubType}; +pub use sr_primitives::{self, ConsensusEngineId, print, traits::Printable}; /// Macro for easily creating a new implementation of the `Get` trait. Use similarly to /// how you would declare a `const`: @@ -130,7 +127,7 @@ macro_rules! fail { /// Used as `ensure!(expression_to_ensure, expression_to_return_on_false)`. #[macro_export] macro_rules! ensure { - ( $x:expr, $y:expr ) => {{ + ( $x:expr, $y:expr $(,)? ) => {{ if !$x { $crate::fail!($y); } @@ -144,7 +141,10 @@ macro_rules! ensure { #[macro_export] #[cfg(feature = "std")] macro_rules! assert_noop { - ( $x:expr , $y:expr ) => { + ( + $x:expr, + $y:expr $(,)? + ) => { let h = $crate::storage_root(); $crate::assert_err!($x, $y); assert_eq!(h, $crate::storage_root()); @@ -161,7 +161,7 @@ macro_rules! assert_noop { #[macro_export] #[cfg(feature = "std")] macro_rules! assert_err { - ( $x:expr , $y:expr ) => { + ( $x:expr , $y:expr $(,)? ) => { assert_eq!($x, Err($y)); } } @@ -222,37 +222,6 @@ macro_rules! __assert_eq_uvec { } } -/// Checks that `$x` is equal to `$y` with an error rate of `$error`. -/// -/// # Example -/// -/// ```rust -/// # fn main() { -/// srml_support::assert_eq_error_rate!(10, 10, 0); -/// srml_support::assert_eq_error_rate!(10, 11, 1); -/// srml_support::assert_eq_error_rate!(12, 10, 2); -/// # } -/// ``` -/// -/// ```rust,should_panic -/// # fn main() { -/// srml_support::assert_eq_error_rate!(12, 10, 1); -/// # } -/// ``` -#[macro_export] -#[cfg(feature = "std")] -macro_rules! assert_eq_error_rate { - ($x:expr, $y:expr, $error:expr) => { - assert!( - ($x) >= (($y) - ($error)) && ($x) <= (($y) + ($error)), - "{:?} != {:?} (with error rate {:?})", - $x, - $y, - $error, - ); - }; -} - /// The void type - it cannot exist. // Oh rust, you crack me up... #[derive(Clone, Eq, PartialEq)] @@ -263,26 +232,12 @@ pub enum Void {} #[doc(hidden)] pub use serde::{Serialize, Deserialize}; -/// Programatically create derivations for tuples of up to 19 elements. You provide a second macro -/// which is called once per tuple size, along with a number of identifiers, one for each element -/// of the tuple. -#[macro_export] -macro_rules! for_each_tuple { - ($m:ident) => { - for_each_tuple! { @IMPL $m !! A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, } - }; - (@IMPL $m:ident !!) => { $m! { } }; - (@IMPL $m:ident !! $h:ident, $($t:ident,)*) => { - $m! { $h $($t)* } - for_each_tuple! { @IMPL $m !! $($t,)* } - } -} - #[cfg(test)] mod tests { use super::*; - use codec::Codec; - use runtime_io::{with_externalities, Blake2Hasher}; + use codec::{Codec, EncodeLike}; + use runtime_io::with_externalities; + use primitives::Blake2Hasher; pub use srml_metadata::{ DecodeDifferent, StorageEntryMetadata, StorageMetadata, StorageEntryType, StorageEntryModifier, DefaultByte, DefaultByteGetter, StorageHasher @@ -290,7 +245,7 @@ mod tests { pub use rstd::marker::PhantomData; pub trait Trait { - type BlockNumber: Codec + Default; + type BlockNumber: Codec + EncodeLike + Default; type Origin; } @@ -342,6 +297,35 @@ mod tests { }); } + #[test] + fn linked_map_swap_works() { + with_externalities(&mut new_test_ext(), || { + OptionLinkedMap::insert(0, 0); + OptionLinkedMap::insert(1, 1); + OptionLinkedMap::insert(2, 2); + OptionLinkedMap::insert(3, 3); + + let collect = || OptionLinkedMap::enumerate().collect::>(); + assert_eq!(collect(), vec![(3, 3), (2, 2), (1, 1), (0, 0)]); + + // Two existing + OptionLinkedMap::swap(1, 2); + assert_eq!(collect(), vec![(3, 3), (2, 1), (1, 2), (0, 0)]); + + // Back to normal + OptionLinkedMap::swap(2, 1); + assert_eq!(collect(), vec![(3, 3), (2, 2), (1, 1), (0, 0)]); + + // Left existing + OptionLinkedMap::swap(2, 5); + assert_eq!(collect(), vec![(5, 2), (3, 3), (1, 1), (0, 0)]); + + // Right existing + OptionLinkedMap::swap(5, 2); + assert_eq!(collect(), vec![(2, 2), (3, 3), (1, 1), (0, 0)]); + }); + } + #[test] fn linked_map_basic_insert_remove_should_work() { with_externalities(&mut new_test_ext(), || { diff --git a/srml/support/src/metadata.rs b/srml/support/src/metadata.rs index 4bc1f906dad55821f6e8326d31177d582849fc33..7ae5f7d193cc5ade1059621d97313c3dc63c10f0 100644 --- a/srml/support/src/metadata.rs +++ b/srml/support/src/metadata.rs @@ -324,7 +324,7 @@ mod tests { StorageMethod : Option; } add_extra_genesis { - build(|_, _| {}); + build(|_| {}); } } } diff --git a/srml/support/src/runtime.rs b/srml/support/src/runtime.rs index 9aae241dba18aac3426a4d22b7be4b224d965e09..491252ce7083bb1ba55b5a5e0825106210b6ff04 100644 --- a/srml/support/src/runtime.rs +++ b/srml/support/src/runtime.rs @@ -220,6 +220,7 @@ macro_rules! construct_runtime { $runtime; ; {}; + {}; $( $name: $module:: $( < $module_instance >:: )? { $( $modules ),* }, )* @@ -299,6 +300,7 @@ macro_rules! __create_decl_macro { )* ); }; + // Parse system module (@inner $runtime:ident; ; // there can not be multiple `System`s @@ -315,6 +317,7 @@ macro_rules! __create_decl_macro { $d( $rest )* ); }; + // Parse instantiable module with generic (@inner $runtime:ident; $d( $system:ident )?; @@ -334,6 +337,23 @@ macro_rules! __create_decl_macro { $d( $rest )* ); }; + // Parse instantiable module with no generic + (@inner + $runtime:ident; + $d( $system:ident )?; + { $d( $parsed:tt )* }; + $name:ident : $module:ident:: < $module_instance:ident >:: { + $macro_enum_name $d(, $ingore:ident $d( <$ignor:ident> )* )* + }, + $d( $rest:tt )* + ) => { + compile_error!(concat!( + "Instantiable module with not generic ", stringify!($macro_enum_name), + " cannot be constructed: module `", stringify!($name), "` must have generic ", + stringify!($macro_enum_name), "." + )); + }; + // Parse instantiable module with no generic (@inner $runtime:ident; $d( $system:ident )?; @@ -353,6 +373,7 @@ macro_rules! __create_decl_macro { $d( $rest )* ); }; + // Ignore keyword (@inner $runtime:ident; $d( $system:ident )?; @@ -370,6 +391,7 @@ macro_rules! __create_decl_macro { $d( $rest )* ); }; + // Ignore module (@inner $runtime:ident; $d( $system:ident )?; @@ -384,6 +406,7 @@ macro_rules! __create_decl_macro { $d( $rest )* ); }; + // Expand (@inner $runtime:ident; $system:ident; @@ -412,6 +435,7 @@ macro_rules! __decl_all_modules { $runtime:ident; ; { $( $parsed:tt )* }; + { $( $parsed_nested:tt )* }; System: $module:ident::{ Module $(, $modules:ident )* }, $( $rest:tt )* ) => { @@ -419,6 +443,26 @@ macro_rules! __decl_all_modules { $runtime; $module; { $( $parsed )* }; + { $( $parsed_nested )* }; + $( $rest )* + ); + }; + ( + $runtime:ident; + $( $system:ident )?; + { $( $parsed:tt )* }; + {}; + $name:ident: $module:ident:: $( < $module_instance:ident >:: )? { Module $(, $modules:ident )* }, + $( $rest:tt )* + ) => { + $crate::__decl_all_modules!( + $runtime; + $( $system )?; + { + $( $parsed )* + $module::$name $(<$module_instance>)?, + }; + { $name }; $( $rest )* ); }; @@ -426,6 +470,7 @@ macro_rules! __decl_all_modules { $runtime:ident; $( $system:ident )?; { $( $parsed:tt )* }; + { $( $parsed_nested:tt )* }; $name:ident: $module:ident:: $( < $module_instance:ident >:: )? { Module $(, $modules:ident )* }, $( $rest:tt )* ) => { @@ -436,6 +481,7 @@ macro_rules! __decl_all_modules { $( $parsed )* $module::$name $(<$module_instance>)?, }; + { ( $( $parsed_nested )*, $name, ) }; $( $rest )* ); }; @@ -443,6 +489,7 @@ macro_rules! __decl_all_modules { $runtime:ident; $( $system:ident )?; { $( $parsed:tt )* }; + { $( $parsed_nested:tt )* }; $name:ident: $module:ident:: $( < $module_instance:ident >:: )? { $ignore:ident $(, $modules:ident )* }, $( $rest:tt )* ) => { @@ -450,6 +497,7 @@ macro_rules! __decl_all_modules { $runtime; $( $system )?; { $( $parsed )* }; + { $( $parsed_nested )* }; $name: $module::{ $( $modules ),* }, $( $rest )* ); @@ -465,6 +513,7 @@ macro_rules! __decl_all_modules { $runtime; $( $system )?; { $( $parsed )* }; + { $( $parsed_nested )* }; $( $rest )* ); }; @@ -472,12 +521,13 @@ macro_rules! __decl_all_modules { $runtime:ident; $system:ident; { $( $parsed_module:ident :: $parsed_name:ident $(<$instance:ident>)? ,)*}; + { $( $parsed_nested:tt )* }; ) => { pub type System = system::Module<$runtime>; $( pub type $parsed_name = $parsed_module::Module<$runtime $(, $parsed_module::$instance )?>; )* - type AllModules = ( $( $parsed_name, )* ); + type AllModules = ( $( $parsed_nested )* ); } } diff --git a/srml/support/src/storage/child.rs b/srml/support/src/storage/child.rs index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..1d6ee7a6f1a61bf0de30a31a0e758cf82cbd931f 100644 --- a/srml/support/src/storage/child.rs +++ b/srml/support/src/storage/child.rs @@ -0,0 +1,107 @@ +// Copyright 2019 Parity Technologies (UK) Ltd. +// This file is part of Substrate. + +// Substrate 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. + +// Substrate 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 Substrate. If not, see . + +//! Operation on runtime child storages. +//! +//! This module is a currently only a variant of unhashed with additional `storage_key`. +//! Note that `storage_key` must be unique and strong (strong in the sense of being long enough to +//! avoid collision from a resistant hash function (which unique implies)). +// NOTE: could replace unhashed by having only one kind of storage (root being null storage key (storage_key can become Option<&[u8]>). + +use crate::rstd::prelude::*; +use codec::{Codec, Encode, Decode}; + +/// Return the value of the item in storage under `key`, or `None` if there is no explicit entry. +pub fn get(storage_key: &[u8], key: &[u8]) -> Option { + runtime_io::child_storage(storage_key, key).map(|v| { + Decode::decode(&mut &v[..]).expect("storage is not null, therefore must be a valid type") + }) +} + +/// Return the value of the item in storage under `key`, or the type's default if there is no +/// explicit entry. +pub fn get_or_default(storage_key: &[u8], key: &[u8]) -> T { + get(storage_key, key).unwrap_or_else(Default::default) +} + +/// Return the value of the item in storage under `key`, or `default_value` if there is no +/// explicit entry. +pub fn get_or(storage_key: &[u8], key: &[u8], default_value: T) -> T { + get(storage_key, key).unwrap_or(default_value) +} + +/// Return the value of the item in storage under `key`, or `default_value()` if there is no +/// explicit entry. +pub fn get_or_else T>(storage_key: &[u8], key: &[u8], default_value: F) -> T { + get(storage_key, key).unwrap_or_else(default_value) +} + +/// Put `value` in storage under `key`. +pub fn put(storage_key: &[u8], key: &[u8], value: &T) { + value.using_encoded(|slice| runtime_io::set_child_storage(storage_key, key, slice)); +} + +/// Remove `key` from storage, returning its value if it had an explicit entry or `None` otherwise. +pub fn take(storage_key: &[u8], key: &[u8]) -> Option { + let r = get(storage_key, key); + if r.is_some() { + kill(storage_key, key); + } + r +} + +/// Remove `key` from storage, returning its value, or, if there was no explicit entry in storage, +/// the default for its type. +pub fn take_or_default(storage_key: &[u8], key: &[u8]) -> T { + take(storage_key, key).unwrap_or_else(Default::default) +} + +/// Return the value of the item in storage under `key`, or `default_value` if there is no +/// explicit entry. Ensure there is no explicit entry on return. +pub fn take_or(storage_key: &[u8],key: &[u8], default_value: T) -> T { + take(storage_key, key).unwrap_or(default_value) +} + +/// Return the value of the item in storage under `key`, or `default_value()` if there is no +/// explicit entry. Ensure there is no explicit entry on return. +pub fn take_or_else T>(storage_key: &[u8], key: &[u8], default_value: F) -> T { + take(storage_key, key).unwrap_or_else(default_value) +} + +/// Check to see if `key` has an explicit entry in storage. +pub fn exists(storage_key: &[u8], key: &[u8]) -> bool { + runtime_io::read_child_storage(storage_key, key, &mut [0;0][..], 0).is_some() +} + +/// Remove all `storage_key` key/values +pub fn kill_storage(storage_key: &[u8]) { + runtime_io::kill_child_storage(storage_key) +} + +/// Ensure `key` has no explicit entry in storage. +pub fn kill(storage_key: &[u8], key: &[u8]) { + runtime_io::clear_child_storage(storage_key, key); +} + +/// Get a Vec of bytes from storage. +pub fn get_raw(storage_key: &[u8], key: &[u8]) -> Option> { + runtime_io::child_storage(storage_key, key) +} + +/// Put a raw byte slice into storage. +pub fn put_raw(storage_key: &[u8], key: &[u8], value: &[u8]) { + runtime_io::set_child_storage(storage_key, key, value) +} diff --git a/srml/support/src/storage/generator/double_map.rs b/srml/support/src/storage/generator/double_map.rs new file mode 100644 index 0000000000000000000000000000000000000000..cac8dbd034e85089e0305df3b68b85c15ad619f1 --- /dev/null +++ b/srml/support/src/storage/generator/double_map.rs @@ -0,0 +1,207 @@ +// Copyright 2019 Parity Technologies (UK) Ltd. +// This file is part of Substrate. + +// Substrate 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. + +// Substrate 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 Substrate. If not, see . + +use rstd::prelude::*; +use rstd::borrow::Borrow; +use codec::{Ref, FullCodec, FullEncode, Encode, EncodeLike, EncodeAppend}; +use crate::{storage::{self, unhashed}, hash::StorageHasher}; + +/// Generator for `StorageDoubleMap` used by `decl_storage`. +/// +/// # Mapping of keys to a storage path +/// +/// The storage key (i.e. the key under which the `Value` will be stored) is created from two parts. +/// The first part is a hash of a concatenation of the `key1_prefix` and `Key1`. And the second part +/// is a hash of a `Key2`. +/// +/// Thus value for (key1, key2) is stored at: +/// ```nocompile +/// Hasher1(key1_prefix ++ key1) ++ Hasher2(key2) +/// ``` +/// +/// # Warning +/// +/// If the key1s are not trusted (e.g. can be set by a user), a cryptographic `hasher` such as +/// `blake2_256` must be used for Hasher1. Otherwise, other values in storage can be compromised. +/// If the key2s are not trusted (e.g. can be set by a user), a cryptographic `hasher` such as +/// `blake2_256` must be used for Hasher2. Otherwise, other items in storage with the same first +/// key can be compromised. +pub trait StorageDoubleMap { + /// The type that get/take returns. + type Query; + + /// Hasher for the first key. + type Hasher1: StorageHasher; + + /// Hasher for the second key. + type Hasher2: StorageHasher; + + /// Get the prefix for first key. + fn key1_prefix() -> &'static [u8]; + + /// Convert an optional value retrieved from storage to the type queried. + fn from_optional_value_to_query(v: Option) -> Self::Query; + + /// Convert a query to an optional value into storage. + fn from_query_to_optional_value(v: Self::Query) -> Option; + + /// Generate the first part of the key used in top storage. + fn storage_double_map_final_key1(k1: KArg1) -> ::Output + where + KArg1: EncodeLike, + { + let mut final_key1 = Self::key1_prefix().to_vec(); + k1.encode_to(&mut final_key1); + Self::Hasher1::hash(&final_key1) + } + + /// Generate the full key used in top storage. + fn storage_double_map_final_key(k1: KArg1, k2: KArg2) -> Vec + where + KArg1: EncodeLike, + KArg2: EncodeLike, + { + let mut final_key = Self::storage_double_map_final_key1(k1).as_ref().to_vec(); + final_key.extend_from_slice(k2.using_encoded(Self::Hasher2::hash).as_ref()); + final_key + } +} + +impl storage::StorageDoubleMap for G +where + K1: FullEncode, + K2: FullEncode, + V: FullCodec, + G: StorageDoubleMap, +{ + type Query = G::Query; + + fn exists(k1: KArg1, k2: KArg2) -> bool + where + KArg1: EncodeLike, + KArg2: EncodeLike, + { + unhashed::exists(&Self::storage_double_map_final_key(k1, k2)) + } + + fn get(k1: KArg1, k2: KArg2) -> Self::Query + where + KArg1: EncodeLike, + KArg2: EncodeLike, + { + G::from_optional_value_to_query(unhashed::get(&Self::storage_double_map_final_key(k1, k2))) + } + + fn take(k1: KArg1, k2: KArg2) -> Self::Query + where + KArg1: EncodeLike, + KArg2: EncodeLike, + { + let final_key = Self::storage_double_map_final_key(k1, k2); + + let value = unhashed::take(&final_key); + G::from_optional_value_to_query(value) + } + + fn insert(k1: KArg1, k2: KArg2, val: VArg) + where + KArg1: EncodeLike, + KArg2: EncodeLike, + VArg: EncodeLike, + { + unhashed::put(&Self::storage_double_map_final_key(k1, k2), &val.borrow()) + } + + fn remove(k1: KArg1, k2: KArg2) + where + KArg1: EncodeLike, + KArg2: EncodeLike, + { + unhashed::kill(&Self::storage_double_map_final_key(k1, k2)) + } + + fn remove_prefix(k1: KArg1) where KArg1: EncodeLike { + unhashed::kill_prefix(Self::storage_double_map_final_key1(k1).as_ref()) + } + + fn mutate(k1: KArg1, k2: KArg2, f: F) -> R + where + KArg1: EncodeLike, + KArg2: EncodeLike, + F: FnOnce(&mut Self::Query) -> R, + { + let final_key = Self::storage_double_map_final_key(k1, k2); + let mut val = G::from_optional_value_to_query(unhashed::get(final_key.as_ref())); + + let ret = f(&mut val); + match G::from_query_to_optional_value(val) { + Some(ref val) => unhashed::put(final_key.as_ref(), val), + None => unhashed::kill(final_key.as_ref()), + } + ret + } + + fn append( + k1: KArg1, + k2: KArg2, + items: Items, + ) -> Result<(), &'static str> + where + KArg1: EncodeLike, + KArg2: EncodeLike, + Item: Encode, + EncodeLikeItem: EncodeLike, + V: EncodeAppend, + Items: IntoIterator, + Items::IntoIter: ExactSizeIterator + { + let final_key = Self::storage_double_map_final_key(k1, k2); + + let encoded_value = unhashed::get_raw(&final_key) + .unwrap_or_else(|| { + match G::from_query_to_optional_value(G::from_optional_value_to_query(None)) { + Some(value) => value.encode(), + None => vec![], + } + }); + + let new_val = V::append_or_new( + encoded_value, + items, + ).map_err(|_| "Could not append given item")?; + unhashed::put_raw(&final_key, &new_val); + + Ok(()) + } + + fn append_or_insert( + k1: KArg1, + k2: KArg2, + items: Items, + ) + where + KArg1: EncodeLike, + KArg2: EncodeLike, + Item: Encode, + EncodeLikeItem: EncodeLike, + V: EncodeAppend, + Items: IntoIterator + Clone + EncodeLike, + Items::IntoIter: ExactSizeIterator + { + Self::append(Ref::from(&k1), Ref::from(&k2), items.clone()) + .unwrap_or_else(|_| Self::insert(k1, k2, items)); + } +} diff --git a/srml/support/src/storage/generator/linked_map.rs b/srml/support/src/storage/generator/linked_map.rs new file mode 100644 index 0000000000000000000000000000000000000000..6643a37f4f50cef2af2f7a784582975917fc8b29 --- /dev/null +++ b/srml/support/src/storage/generator/linked_map.rs @@ -0,0 +1,363 @@ +// Copyright 2019 Parity Technologies (UK) Ltd. +// This file is part of Substrate. + +// Substrate 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. + +// Substrate 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 Substrate. If not, see . + +use codec::{FullCodec, Encode, Decode, EncodeLike, Ref}; +use crate::{storage::{self, unhashed}, hash::StorageHasher, traits::Len}; +use rstd::marker::PhantomData; + +/// Generator for `StorageLinkedMap` used by `decl_storage`. +/// +/// # Mapping of keys to a storage path +/// +/// The key for the head of the map is stored at one fixed path: +/// ```nocompile +/// Hasher(head_key) +/// ``` +/// +/// For each key, the value stored under that key is appended with a +/// [`Linkage`](struct.Linkage.html) (which hold previous and next key) at the path: +/// ```nocompile +/// Hasher(prefix ++ key) +/// ``` +/// +/// Enumeration is done by getting the head of the linked map and then iterating getting the +/// value and linkage stored at the key until the found linkage has no next key. +/// +/// # Warning +/// +/// If the keys are not trusted (e.g. can be set by a user), a cryptographic `hasher` such as +/// `blake2_256` must be used. Otherwise, other values in storage can be compromised. +pub trait StorageLinkedMap { + /// The type that get/take returns. + type Query; + + /// Hasher used to insert into storage. + type Hasher: StorageHasher; + + /// Prefix used to prepend each key. + fn prefix() -> &'static [u8]; + + /// Key used to store linked map head. + fn head_key() -> &'static [u8]; + + /// Convert an optionnal value retrieved from storage to the type queried. + fn from_optional_value_to_query(v: Option) -> Self::Query; + + /// Convert a query to an optionnal value into storage. + fn from_query_to_optional_value(v: Self::Query) -> Option; + + /// Generate the full key used in top storage. + fn storage_linked_map_final_key(key: KeyArg) -> ::Output + where + KeyArg: EncodeLike, + { + let mut final_key = Self::prefix().to_vec(); + key.encode_to(&mut final_key); + Self::Hasher::hash(&final_key) + } + + /// Generate the hashed key for head + fn storage_linked_map_final_head_key() -> ::Output { + Self::Hasher::hash(Self::head_key()) + } +} + +/// Linkage data of an element (it's successor and predecessor) +#[derive(Encode, Decode)] +pub struct Linkage { + /// Previous element key in storage (None for the first element) + pub previous: Option, + /// Next element key in storage (None for the last element) + pub next: Option, +} + +impl Default for Linkage { + fn default() -> Self { + Self { + previous: None, + next: None, + } + } +} + +// Encode like a linkage. +#[derive(Encode)] +struct EncodeLikeLinkage, NKey: EncodeLike, Key: Encode> { + // Previous element key in storage (None for the first element) + previous: Option, + // Next element key in storage (None for the last element) + next: Option, + // The key of the linkage this type encode to + phantom: core::marker::PhantomData, +} + +/// A key-value pair iterator for enumerable map. +pub struct Enumerator> { + next: Option, + _phantom: PhantomData<(G, V)>, +} + +impl Iterator for Enumerator +where + K: FullCodec, + V: FullCodec, + G: StorageLinkedMap, +{ + type Item = (K, V); + + fn next(&mut self) -> Option { + let next = self.next.take()?; + let (val, linkage): (V, Linkage) = { + let next_full_key = G::storage_linked_map_final_key(&next); + unhashed::get(next_full_key.as_ref()) + .expect("previous/next only contain existing entires; + we enumerate using next; entry exists; qed") + }; + + self.next = linkage.next; + Some((next, val)) + } +} + +/// Update linkage when this element is removed. +/// +/// Takes care of updating previous and next elements points +/// as well as updates head if the element is first or last. +fn remove_linkage(linkage: Linkage) +where + K: FullCodec, + V: FullCodec, + G: StorageLinkedMap, +{ + let next_key = linkage.next.as_ref() + .map(G::storage_linked_map_final_key) + .map(|x| x.as_ref().to_vec()); + let prev_key = linkage.previous.as_ref() + .map(G::storage_linked_map_final_key) + .map(|x| x.as_ref().to_vec()); + + if let Some(prev_key) = prev_key { + // Retrieve previous element and update `next` + let mut res = read_with_linkage::<_, _, G>(prev_key.as_ref()) + .expect("Linkage is updated in case entry is removed; + it always points to existing keys; qed"); + res.1.next = linkage.next; + unhashed::put(prev_key.as_ref(), &res); + } else { + // we were first so let's update the head + write_head::<_, _, _, G>(linkage.next.as_ref()); + } + if let Some(next_key) = next_key { + // Update previous of next element + let mut res = read_with_linkage::<_, _, G>(next_key.as_ref()) + .expect("Linkage is updated in case entry is removed; + it always points to existing keys; qed"); + res.1.previous = linkage.previous; + unhashed::put(next_key.as_ref(), &res); + } +} + +/// Read the contained data and it's linkage. +fn read_with_linkage(key: &[u8]) -> Option<(V, Linkage)> +where + K: FullCodec, + V: FullCodec, + G: StorageLinkedMap, +{ + unhashed::get(key) +} + +/// Generate linkage for newly inserted element. +/// +/// Takes care of updating head and previous head's pointer. +fn new_head_linkage(key: KeyArg) -> Linkage +where + KeyArg: EncodeLike, + K: FullCodec, + V: FullCodec, + G: StorageLinkedMap, +{ + if let Some(head) = read_head::<_, _, G>() { + // update previous head predecessor + { + let head_key = G::storage_linked_map_final_key(&head); + let (data, linkage) = read_with_linkage::<_, _, G>(head_key.as_ref()) + .expect("head is set when first element is inserted + and unset when last element is removed; + if head is Some then it points to existing key; qed"); + let new_linkage = EncodeLikeLinkage::<_, _, K> { + previous: Some(Ref::from(&key)), + next: linkage.next.as_ref(), + phantom: Default::default(), + }; + unhashed::put(head_key.as_ref(), &(data, new_linkage)); + } + // update to current head + write_head::<_, _, _, G>(Some(key)); + // return linkage with pointer to previous head + let mut linkage = Linkage::default(); + linkage.next = Some(head); + linkage + } else { + // we are first - update the head and produce empty linkage + write_head::<_, _, _, G>(Some(key)); + Linkage::default() + } +} + +/// Read current head pointer. +fn read_head() -> Option +where + K: FullCodec, + V: FullCodec, + G: StorageLinkedMap, +{ + unhashed::get(G::storage_linked_map_final_head_key().as_ref()) +} + +/// Overwrite current head pointer. +/// +/// If `None` is given head is removed from storage. +fn write_head(head: Option) +where + KeyArg: EncodeLike, + K: FullCodec, + V: FullCodec, + G: StorageLinkedMap, +{ + match head.as_ref() { + Some(head) => unhashed::put(G::storage_linked_map_final_head_key().as_ref(), head), + None => unhashed::kill(G::storage_linked_map_final_head_key().as_ref()), + } +} + +impl storage::StorageLinkedMap for G +where + K: FullCodec, + V: FullCodec, + G: StorageLinkedMap, +{ + type Query = G::Query; + + type Enumerator = Enumerator; + + fn exists>(key: KeyArg) -> bool { + unhashed::exists(Self::storage_linked_map_final_key(key).as_ref()) + } + + fn get>(key: KeyArg) -> Self::Query { + let val = unhashed::get(Self::storage_linked_map_final_key(key).as_ref()); + G::from_optional_value_to_query(val) + } + + fn swap, KeyArg2: EncodeLike>(key1: KeyArg1, key2: KeyArg2) { + let final_key1 = Self::storage_linked_map_final_key(Ref::from(&key1)); + let final_key2 = Self::storage_linked_map_final_key(Ref::from(&key2)); + let full_value_1 = read_with_linkage::<_, _, G>(final_key1.as_ref()); + let full_value_2 = read_with_linkage::<_, _, G>(final_key2.as_ref()); + + match (full_value_1, full_value_2) { + // Just keep linkage in order and only swap values. + (Some((value1, linkage1)), Some((value2, linkage2))) => { + unhashed::put(final_key1.as_ref(), &(value2, linkage1)); + unhashed::put(final_key2.as_ref(), &(value1, linkage2)); + } + // Remove key and insert the new one. + (Some((value, _linkage)), None) => { + Self::remove(key1); + let linkage = new_head_linkage::<_, _, _, G>(key2); + unhashed::put(final_key2.as_ref(), &(value, linkage)); + } + // Remove key and insert the new one. + (None, Some((value, _linkage))) => { + Self::remove(key2); + let linkage = new_head_linkage::<_, _, _, G>(key1); + unhashed::put(final_key1.as_ref(), &(value, linkage)); + } + // No-op. + (None, None) => (), + } + } + + fn insert, ValArg: EncodeLike>(key: KeyArg, val: ValArg) { + let final_key = Self::storage_linked_map_final_key(Ref::from(&key)); + let linkage = match read_with_linkage::<_, _, G>(final_key.as_ref()) { + // overwrite but reuse existing linkage + Some((_data, linkage)) => linkage, + // create new linkage + None => new_head_linkage::<_, _, _, G>(key), + }; + unhashed::put(final_key.as_ref(), &(val, linkage)) + } + + fn remove>(key: KeyArg) { + G::take(key); + } + + fn mutate, R, F: FnOnce(&mut Self::Query) -> R>(key: KeyArg, f: F) -> R { + let final_key = Self::storage_linked_map_final_key(Ref::from(&key)); + + let (mut val, _linkage) = read_with_linkage::<_, _, G>(final_key.as_ref()) + .map(|(data, linkage)| (G::from_optional_value_to_query(Some(data)), Some(linkage))) + .unwrap_or_else(|| (G::from_optional_value_to_query(None), None)); + + let ret = f(&mut val); + match G::from_query_to_optional_value(val) { + Some(ref val) => G::insert(key, val), + None => G::remove(key), + } + ret + } + + fn take>(key: KeyArg) -> Self::Query { + let final_key = Self::storage_linked_map_final_key(key); + + let full_value: Option<(V, Linkage)> = unhashed::take(final_key.as_ref()); + + let value = full_value.map(|(data, linkage)| { + remove_linkage::<_, _, G>(linkage); + data + }); + + G::from_optional_value_to_query(value) + } + + fn enumerate() -> Self::Enumerator { + Enumerator::<_, _, G> { + next: read_head::<_, _, G>(), + _phantom: Default::default(), + } + } + + fn head() -> Option { + read_head::<_, _, G>() + } + + fn decode_len>(key: KeyArg) -> Result + where V: codec::DecodeLength + Len + { + let key = Self::storage_linked_map_final_key(key); + if let Some(v) = unhashed::get_raw(key.as_ref()) { + ::len(&v).map_err(|e| e.what()) + } else { + let len = G::from_query_to_optional_value(G::from_optional_value_to_query(None)) + .map(|v| v.len()) + .unwrap_or(0); + + Ok(len) + } + } +} diff --git a/srml/support/src/storage/generator/map.rs b/srml/support/src/storage/generator/map.rs new file mode 100644 index 0000000000000000000000000000000000000000..3c3edac28a42a37f779c93c8eded02dc968672e0 --- /dev/null +++ b/srml/support/src/storage/generator/map.rs @@ -0,0 +1,172 @@ +// Copyright 2019 Parity Technologies (UK) Ltd. +// This file is part of Substrate. + +// Substrate 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. + +// Substrate 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 Substrate. If not, see . + +#[cfg(not(feature = "std"))] +use rstd::prelude::*; +use rstd::borrow::Borrow; +use codec::{FullCodec, FullEncode, Encode, EncodeLike, Ref, EncodeAppend}; +use crate::{storage::{self, unhashed}, hash::StorageHasher, traits::Len}; + +/// Generator for `StorageMap` used by `decl_storage`. +/// +/// For each key value is stored at: +/// ```nocompile +/// Hasher(prefix ++ key) +/// ``` +/// +/// # Warning +/// +/// If the keys are not trusted (e.g. can be set by a user), a cryptographic `hasher` such as +/// `blake2_256` must be used. Otherwise, other values in storage can be compromised. +pub trait StorageMap { + /// The type that get/take returns. + type Query; + + /// Hasher used to insert into storage. + type Hasher: StorageHasher; + + /// Prefix used to prepend each key. + fn prefix() -> &'static [u8]; + + /// Convert an optional value retrieved from storage to the type queried. + fn from_optional_value_to_query(v: Option) -> Self::Query; + + /// Convert a query to an optional value into storage. + fn from_query_to_optional_value(v: Self::Query) -> Option; + + /// Generate the full key used in top storage. + fn storage_map_final_key(key: KeyArg) -> ::Output + where + KeyArg: EncodeLike, + { + let mut final_key = Self::prefix().to_vec(); + key.borrow().encode_to(&mut final_key); + Self::Hasher::hash(&final_key) + } +} + +impl> storage::StorageMap for G { + type Query = G::Query; + + fn hashed_key_for>(key: KeyArg) -> Vec { + Self::storage_map_final_key(key).as_ref().to_vec() + } + + fn swap, KeyArg2: EncodeLike>(key1: KeyArg1, key2: KeyArg2) { + let k1 = Self::storage_map_final_key(key1); + let k2 = Self::storage_map_final_key(key2); + + let v1 = unhashed::get_raw(k1.as_ref()); + if let Some(val) = unhashed::get_raw(k2.as_ref()) { + unhashed::put_raw(k1.as_ref(), &val); + } else { + unhashed::kill(k1.as_ref()) + } + if let Some(val) = v1 { + unhashed::put_raw(k2.as_ref(), &val); + } else { + unhashed::kill(k2.as_ref()) + } + } + + fn exists>(key: KeyArg) -> bool { + unhashed::exists(Self::storage_map_final_key(key).as_ref()) + } + + fn get>(key: KeyArg) -> Self::Query { + G::from_optional_value_to_query(unhashed::get(Self::storage_map_final_key(key).as_ref())) + } + + fn insert, ValArg: EncodeLike>(key: KeyArg, val: ValArg) { + unhashed::put(Self::storage_map_final_key(key).as_ref(), &val.borrow()) + } + + fn remove>(key: KeyArg) { + unhashed::kill(Self::storage_map_final_key(key).as_ref()) + } + + fn mutate, R, F: FnOnce(&mut Self::Query) -> R>(key: KeyArg, f: F) -> R { + let final_key = Self::storage_map_final_key(key); + let mut val = G::from_optional_value_to_query(unhashed::get(final_key.as_ref())); + + let ret = f(&mut val); + match G::from_query_to_optional_value(val) { + Some(ref val) => unhashed::put(final_key.as_ref(), &val.borrow()), + None => unhashed::kill(final_key.as_ref()), + } + ret + } + + fn take>(key: KeyArg) -> Self::Query { + let key = Self::storage_map_final_key(key); + let value = unhashed::take(key.as_ref()); + G::from_optional_value_to_query(value) + } + + fn append(key: KeyArg, items: Items) -> Result<(), &'static str> + where + KeyArg: EncodeLike, + Item: Encode, + EncodeLikeItem: EncodeLike, + V: EncodeAppend, + Items: IntoIterator, + Items::IntoIter: ExactSizeIterator, + { + let key = Self::storage_map_final_key(key); + let encoded_value = unhashed::get_raw(key.as_ref()) + .unwrap_or_else(|| { + match G::from_query_to_optional_value(G::from_optional_value_to_query(None)) { + Some(value) => value.encode(), + None => vec![], + } + }); + + let new_val = V::append_or_new( + encoded_value, + items, + ).map_err(|_| "Could not append given item")?; + unhashed::put_raw(key.as_ref(), &new_val); + Ok(()) + } + + fn append_or_insert(key: KeyArg, items: Items) + where + KeyArg: EncodeLike, + Item: Encode, + EncodeLikeItem: EncodeLike, + V: EncodeAppend, + Items: IntoIterator + Clone + EncodeLike, + Items::IntoIter: ExactSizeIterator, + { + Self::append(Ref::from(&key), items.clone()) + .unwrap_or_else(|_| Self::insert(key, items)); + } + + fn decode_len>(key: KeyArg) -> Result + where V: codec::DecodeLength + Len + { + let key = Self::storage_map_final_key(key); + if let Some(v) = unhashed::get_raw(key.as_ref()) { + ::len(&v).map_err(|e| e.what()) + } else { + let len = G::from_query_to_optional_value(G::from_optional_value_to_query(None)) + .map(|v| v.len()) + .unwrap_or(0); + + Ok(len) + } + } +} diff --git a/srml/support/src/storage/generator/mod.rs b/srml/support/src/storage/generator/mod.rs new file mode 100644 index 0000000000000000000000000000000000000000..ab7616158afd80eda28aca445bc18ee8f3be4326 --- /dev/null +++ b/srml/support/src/storage/generator/mod.rs @@ -0,0 +1,32 @@ +// Copyright 2019 Parity Technologies (UK) Ltd. +// This file is part of Substrate. + +// Substrate 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. + +// Substrate 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 Substrate. If not, see . + +//! Generators are a set of trait on which storage traits are implemented. +//! +//! (i.e. implementing the generator for StorageValue on a type will automatically derive the +//! implementation of StorageValue for this type). +//! +//! They are used by `decl_storage`. + +mod linked_map; +mod map; +mod double_map; +mod value; + +pub use linked_map::{StorageLinkedMap, Enumerator, Linkage}; +pub use map::StorageMap; +pub use double_map::StorageDoubleMap; +pub use value::StorageValue; diff --git a/srml/support/src/storage/generator/value.rs b/srml/support/src/storage/generator/value.rs new file mode 100644 index 0000000000000000000000000000000000000000..8423503dde20e2ba8f6e0fb02cc08885f944def3 --- /dev/null +++ b/srml/support/src/storage/generator/value.rs @@ -0,0 +1,154 @@ +// Copyright 2019 Parity Technologies (UK) Ltd. +// This file is part of Substrate. + +// Substrate 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. + +// Substrate 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 Substrate. If not, see . + +#[cfg(not(feature = "std"))] +use rstd::prelude::*; +use codec::{FullCodec, Encode, EncodeAppend, EncodeLike}; +use crate::{storage::{self, unhashed}, hash::{Twox128, StorageHasher}, traits::Len}; + +/// Generator for `StorageValue` used by `decl_storage`. +/// +/// Value is stored at: +/// ```nocompile +/// Twox128(unhashed_key) +/// ``` +pub trait StorageValue { + /// The type that get/take returns. + type Query; + + /// Unhashed key used in storage + fn unhashed_key() -> &'static [u8]; + + /// Convert an optional value retrieved from storage to the type queried. + fn from_optional_value_to_query(v: Option) -> Self::Query; + + /// Convert a query to an optional value into storage. + fn from_query_to_optional_value(v: Self::Query) -> Option; + + /// Generate the full key used in top storage. + fn storage_value_final_key() -> [u8; 16] { + Twox128::hash(Self::unhashed_key()) + } +} + +impl> storage::StorageValue for G { + type Query = G::Query; + + fn hashed_key() -> [u8; 16] { + Self::storage_value_final_key() + } + + fn exists() -> bool { + unhashed::exists(&Self::storage_value_final_key()) + } + + fn get() -> Self::Query { + let value = unhashed::get(&Self::storage_value_final_key()); + G::from_optional_value_to_query(value) + } + + fn put>(val: Arg) { + unhashed::put(&Self::storage_value_final_key(), &val) + } + + fn kill() { + unhashed::kill(&Self::storage_value_final_key()) + } + + fn mutate R>(f: F) -> R { + let mut val = G::get(); + + let ret = f(&mut val); + match G::from_query_to_optional_value(val) { + Some(ref val) => G::put(val), + None => G::kill(), + } + ret + } + + fn take() -> G::Query { + let key = Self::storage_value_final_key(); + let value = unhashed::get(&key); + if value.is_some() { + unhashed::kill(&key) + } + G::from_optional_value_to_query(value) + } + + /// Append the given items to the value in the storage. + /// + /// `T` is required to implement `codec::EncodeAppend`. + fn append(items: Items) -> Result<(), &'static str> + where + Item: Encode, + EncodeLikeItem: EncodeLike, + T: EncodeAppend, + Items: IntoIterator, + Items::IntoIter: ExactSizeIterator, + { + let key = Self::storage_value_final_key(); + let encoded_value = unhashed::get_raw(&key) + .unwrap_or_else(|| { + match G::from_query_to_optional_value(G::from_optional_value_to_query(None)) { + Some(value) => value.encode(), + None => vec![], + } + }); + + let new_val = T::append_or_new( + encoded_value, + items, + ).map_err(|_| "Could not append given item")?; + unhashed::put_raw(&key, &new_val); + Ok(()) + } + + /// Safely append the given items to the value in the storage. If a codec error occurs, then the + /// old (presumably corrupt) value is replaced with the given `items`. + /// + /// `T` is required to implement `codec::EncodeAppend`. + fn append_or_put(items: Items) where + Item: Encode, + EncodeLikeItem: EncodeLike, + T: EncodeAppend, + Items: IntoIterator + Clone + EncodeLike, + Items::IntoIter: ExactSizeIterator + { + Self::append(items.clone()).unwrap_or_else(|_| Self::put(items)); + } + + /// Read the length of the value in a fast way, without decoding the entire value. + /// + /// `T` is required to implement `Codec::DecodeLength`. + /// + /// Note that `0` is returned as the default value if no encoded value exists at the given key. + /// Therefore, this function cannot be used as a sign of _existence_. use the `::exists()` + /// function for this purpose. + fn decode_len() -> Result where T: codec::DecodeLength, T: Len { + let key = Self::storage_value_final_key(); + + // attempt to get the length directly. + if let Some(k) = unhashed::get_raw(&key) { + ::len(&k).map_err(|e| e.what()) + } else { + let len = G::from_query_to_optional_value(G::from_optional_value_to_query(None)) + .map(|v| v.len()) + .unwrap_or(0); + + Ok(len) + } + } +} diff --git a/srml/support/src/storage/hashed/mod.rs b/srml/support/src/storage/hashed.rs similarity index 57% rename from srml/support/src/storage/hashed/mod.rs rename to srml/support/src/storage/hashed.rs index 5ca718df8c012e1bc5942b97ee1a6ec988a397d4..2eca8f5bcafbc8390537b4187a3b249f0049c3b1 100644 --- a/srml/support/src/storage/hashed/mod.rs +++ b/srml/support/src/storage/hashed.rs @@ -16,12 +16,9 @@ //! Operation on runtime storage using hashed keys. -pub mod generator; use super::unhashed; -use crate::rstd::prelude::*; -use crate::rstd::borrow::Borrow; -use runtime_io::{self, twox_128}; -use crate::codec::{Codec, Encode, Decode, KeyedVec}; +use rstd::prelude::*; +use codec::{Encode, Decode}; /// Return the value of the item in storage under `key`, or `None` if there is no explicit entry. pub fn get(hash: &HashFn, key: &[u8]) -> Option @@ -156,131 +153,3 @@ where { unhashed::put_raw(&hash(key).as_ref(), value) } - -/// A trait to conveniently store a vector of storable data. -/// -/// It uses twox_128 hasher. Final keys in trie are `twox_128(concatenation(PREFIX,count))` -pub trait StorageVec { - type Item: Default + Sized + Codec; - const PREFIX: &'static [u8]; - - /// Get the current set of items. - fn items() -> Vec { - (0..Self::count()).into_iter().map(Self::item).collect() - } - - /// Set the current set of items. - fn set_items(items: I) - where - I: IntoIterator, - T: Borrow, - { - let mut count: u32 = 0; - - for i in items.into_iter() { - put(&twox_128, &count.to_keyed_vec(Self::PREFIX), i.borrow()); - count = count.checked_add(1).expect("exceeded runtime storage capacity"); - } - - Self::set_count(count); - } - - /// Push an item. - fn push(item: &Self::Item) { - let len = Self::count(); - put(&twox_128, &len.to_keyed_vec(Self::PREFIX), item); - Self::set_count(len + 1); - } - - fn set_item(index: u32, item: &Self::Item) { - if index < Self::count() { - put(&twox_128, &index.to_keyed_vec(Self::PREFIX), item); - } - } - - fn clear_item(index: u32) { - if index < Self::count() { - kill(&twox_128, &index.to_keyed_vec(Self::PREFIX)); - } - } - - fn item(index: u32) -> Self::Item { - get_or_default(&twox_128, &index.to_keyed_vec(Self::PREFIX)) - } - - fn set_count(count: u32) { - (count..Self::count()).for_each(Self::clear_item); - put(&twox_128, &b"len".to_keyed_vec(Self::PREFIX), &count); - } - - fn count() -> u32 { - get_or_default(&twox_128, &b"len".to_keyed_vec(Self::PREFIX)) - } -} - -#[cfg(test)] -mod tests { - use super::*; - use runtime_io::{twox_128, TestExternalities, with_externalities}; - - #[test] - fn integers_can_be_stored() { - let mut t = TestExternalities::default(); - with_externalities(&mut t, || { - let x = 69u32; - put(&twox_128, b":test", &x); - let y: u32 = get(&twox_128, b":test").unwrap(); - assert_eq!(x, y); - }); - with_externalities(&mut t, || { - let x = 69426942i64; - put(&twox_128, b":test", &x); - let y: i64 = get(&twox_128, b":test").unwrap(); - assert_eq!(x, y); - }); - } - - #[test] - fn bools_can_be_stored() { - let mut t = TestExternalities::default(); - with_externalities(&mut t, || { - let x = true; - put(&twox_128, b":test", &x); - let y: bool = get(&twox_128, b":test").unwrap(); - assert_eq!(x, y); - }); - - with_externalities(&mut t, || { - let x = false; - put(&twox_128, b":test", &x); - let y: bool = get(&twox_128, b":test").unwrap(); - assert_eq!(x, y); - }); - } - - #[test] - fn vecs_can_be_retrieved() { - let mut t = TestExternalities::default(); - with_externalities(&mut t, || { - runtime_io::set_storage(&twox_128(b":test"), b"\x2cHello world"); - let x = b"Hello world".to_vec(); - let y = get::, _, _>(&twox_128, b":test").unwrap(); - assert_eq!(x, y); - }); - } - - #[test] - fn vecs_can_be_stored() { - let mut t = TestExternalities::default(); - let x = b"Hello world".to_vec(); - - with_externalities(&mut t, || { - put(&twox_128, b":test", &x); - }); - - with_externalities(&mut t, || { - let y: Vec = get(&twox_128, b":test").unwrap(); - assert_eq!(x, y); - }); - } -} diff --git a/srml/support/src/storage/hashed/generator.rs b/srml/support/src/storage/hashed/generator.rs deleted file mode 100644 index f8b8fb5483e1e163744afd51a8172004602b89f9..0000000000000000000000000000000000000000 --- a/srml/support/src/storage/hashed/generator.rs +++ /dev/null @@ -1,310 +0,0 @@ -// Copyright 2019 Parity Technologies (UK) Ltd. -// This file is part of Substrate. - -// Substrate 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. - -// Substrate 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 Substrate. If not, see . - -//! Abstract storage to use on HashedStorage trait - -use crate::codec::{self, Encode}; -use crate::rstd::prelude::{Vec, Box}; -#[cfg(feature = "std")] -use crate::storage::unhashed::generator::UnhashedStorage; -use runtime_io::{twox_64, twox_128, blake2_128, twox_256, blake2_256}; - -pub trait StorageHasher: 'static { - type Output: AsRef<[u8]>; - fn hash(x: &[u8]) -> Self::Output; -} - -/// Hash storage keys with `concat(twox64(key), key)` -pub struct Twox64Concat; -impl StorageHasher for Twox64Concat { - type Output = Vec; - fn hash(x: &[u8]) -> Vec { - twox_64(x) - .into_iter() - .chain(x.into_iter()) - .cloned() - .collect::>() - } -} - -#[test] -fn test_twox_64_concat() { - let r = Twox64Concat::hash(b"foo"); - assert_eq!(r.split_at(8), (&twox_128(b"foo")[..8], &b"foo"[..])) -} - -/// Hash storage keys with blake2 128 -pub struct Blake2_128; -impl StorageHasher for Blake2_128 { - type Output = [u8; 16]; - fn hash(x: &[u8]) -> [u8; 16] { - blake2_128(x) - } -} - -/// Hash storage keys with blake2 256 -pub struct Blake2_256; -impl StorageHasher for Blake2_256 { - type Output = [u8; 32]; - fn hash(x: &[u8]) -> [u8; 32] { - blake2_256(x) - } -} - -/// Hash storage keys with twox 128 -pub struct Twox128; -impl StorageHasher for Twox128 { - type Output = [u8; 16]; - fn hash(x: &[u8]) -> [u8; 16] { - twox_128(x) - } -} - -/// Hash storage keys with twox 256 -pub struct Twox256; -impl StorageHasher for Twox256 { - type Output = [u8; 32]; - fn hash(x: &[u8]) -> [u8; 32] { - twox_256(x) - } -} - -/// Abstraction around storage. -pub trait HashedStorage { - /// true if the key exists in storage. - fn exists(&self, key: &[u8]) -> bool; - - /// Load the bytes of a key from storage. Can panic if the type is incorrect. - fn get(&self, key: &[u8]) -> Option; - - /// Load the bytes of a key from storage. Can panic if the type is incorrect. Will panic if - /// it's not there. - fn require(&self, key: &[u8]) -> T { - self.get(key).expect("Required values must be in storage") - } - - /// Load the bytes of a key from storage. Can panic if the type is incorrect. The type's - /// default is returned if it's not there. - fn get_or_default(&self, key: &[u8]) -> T { - self.get(key).unwrap_or_default() - } - - /// Put a value in under a key. - fn put(&mut self, key: &[u8], val: &T); - - /// Remove the bytes of a key from storage. - fn kill(&mut self, key: &[u8]); - - /// Take a value from storage, deleting it after reading. - fn take(&mut self, key: &[u8]) -> Option { - let value = self.get(key); - self.kill(key); - value - } - - /// Take a value from storage, deleting it after reading. - fn take_or_panic(&mut self, key: &[u8]) -> T { - self.take(key).expect("Required values must be in storage") - } - - /// Take a value from storage, deleting it after reading. - fn take_or_default(&mut self, key: &[u8]) -> T { - self.take(key).unwrap_or_default() - } - - /// Get a Vec of bytes from storage. - fn get_raw(&self, key: &[u8]) -> Option>; - - /// Put a raw byte slice into storage. - fn put_raw(&mut self, key: &[u8], value: &[u8]); -} - -// We use a construct like this during when genesis storage is being built. -#[cfg(feature = "std")] -impl HashedStorage for sr_primitives::StorageOverlay { - fn exists(&self, key: &[u8]) -> bool { - UnhashedStorage::exists(self, &H::hash(key).as_ref()) - } - - fn get(&self, key: &[u8]) -> Option { - UnhashedStorage::get(self, &H::hash(key).as_ref()) - } - - fn put(&mut self, key: &[u8], val: &T) { - UnhashedStorage::put(self, &H::hash(key).as_ref(), val) - } - - fn kill(&mut self, key: &[u8]) { - UnhashedStorage::kill(self, &H::hash(key).as_ref()) - } - - fn get_raw(&self, key: &[u8]) -> Option> { - UnhashedStorage::get_raw(self, &H::hash(key).as_ref()) - } - - fn put_raw(&mut self, key: &[u8], value: &[u8]) { - UnhashedStorage::put_raw(self, &H::hash(key).as_ref(), value) - } -} - -/// A strongly-typed value kept in storage. -pub trait StorageValue { - /// The type that get/take returns. - type Query; - - /// Get the storage key. - fn key() -> &'static [u8]; - - /// true if the value is defined in storage. - fn exists>(storage: &S) -> bool { - storage.exists(Self::key()) - } - - /// Load the value from the provided storage instance. - fn get>(storage: &S) -> Self::Query; - - /// Take a value from storage, removing it afterwards. - fn take>(storage: &mut S) -> Self::Query; - - /// Store a value under this key into the provided storage instance. - fn put>(val: &T, storage: &mut S) { - storage.put(Self::key(), val) - } - - /// Store a value under this key into the provided storage instance; this can take any reference - /// type that derefs to `T` (and has `Encode` implemented). - /// Store a value under this key into the provided storage instance. - fn put_ref>(val: &Arg, storage: &mut S) where T: AsRef { - val.using_encoded(|b| storage.put_raw(Self::key(), b)) - } - - /// Mutate this value - fn mutate R, S: HashedStorage>(f: F, storage: &mut S) -> R; - - /// Clear the storage value. - fn kill>(storage: &mut S) { - storage.kill(Self::key()) - } - - /// Append the given items to the value in the storage. - /// - /// `T` is required to implement `codec::EncodeAppend`. - fn append, I: codec::Encode>( - items: &[I], storage: &mut S - ) -> Result<(), &'static str> where T: codec::EncodeAppend { - let new_val = ::append( - storage.get_raw(Self::key()).unwrap_or_default(), - items, - ).map_err(|_| "Could not append given item")?; - storage.put_raw(Self::key(), &new_val); - Ok(()) - } -} - -/// A strongly-typed map in storage. -pub trait StorageMap { - /// The type that get/take returns. - type Query; - - type Hasher: StorageHasher; - - /// Get the prefix key in storage. - fn prefix() -> &'static [u8]; - - /// Get the storage key used to fetch a value corresponding to a specific key. - fn key_for(x: &K) -> Vec; - - /// true if the value is defined in storage. - fn exists>(key: &K, storage: &S) -> bool { - storage.exists(&Self::key_for(key)[..]) - } - - /// Load the value associated with the given key from the map. - fn get>(key: &K, storage: &S) -> Self::Query; - - /// Take the value under a key. - fn take>(key: &K, storage: &mut S) -> Self::Query; - - /// Swap the values of two keys. - fn swap>(key1: &K, key2: &K, storage: &mut S) { - let k1 = Self::key_for(key1); - let k2 = Self::key_for(key2); - let v1 = storage.get_raw(&k1[..]); - if let Some(val) = storage.get_raw(&k2[..]) { - storage.put_raw(&k1[..], &val[..]); - } else { - storage.kill(&k1[..]) - } - if let Some(val) = v1 { - storage.put_raw(&k2[..], &val[..]); - } else { - storage.kill(&k2[..]) - } - } - - /// Store a value to be associated with the given key from the map. - fn insert>(key: &K, val: &V, storage: &mut S) { - storage.put(&Self::key_for(key)[..], val); - } - - /// Store a value under this key into the provided storage instance; this can take any reference - /// type that derefs to `T` (and has `Encode` implemented). - /// Store a value under this key into the provided storage instance. - fn insert_ref>( - key: &K, - val: &Arg, - storage: &mut S - ) where V: AsRef { - val.using_encoded(|b| storage.put_raw(&Self::key_for(key)[..], b)) - } - - /// Remove the value under a key. - fn remove>(key: &K, storage: &mut S) { - storage.kill(&Self::key_for(key)[..]); - } - - /// Mutate the value under a key. - fn mutate R, S: HashedStorage>(key: &K, f: F, storage: &mut S) -> R; -} - -/// A `StorageMap` with enumerable entries. -pub trait EnumerableStorageMap: StorageMap { - /// Return current head element. - fn head>(storage: &S) -> Option; - - /// Enumerate all elements in the map. - fn enumerate<'a, S: HashedStorage>( - storage: &'a S - ) -> Box + 'a> where K: 'a, V: 'a; -} - -/// A `StorageMap` with appendable entries. -pub trait AppendableStorageMap: StorageMap { - /// Append the given items to the value in the storage. - /// - /// `T` is required to implement `codec::EncodeAppend`. - fn append, I: codec::Encode>( - key : &K, items: &[I], storage: &mut S - ) -> Result<(), &'static str> where V: codec::EncodeAppend { - let k = Self::key_for(key); - let new_val = ::append( - storage.get_raw(&k[..]).unwrap_or_default(), - items, - ).map_err(|_| "Could not append given item")?; - storage.put_raw(&k[..], &new_val); - Ok(()) - } -} diff --git a/srml/support/src/storage/mod.rs b/srml/support/src/storage/mod.rs index 385fad42eb260bc8be30de7052b28533e6bf4c6b..648009b470e421083558d2ebab19406b6a4d2245 100644 --- a/srml/support/src/storage/mod.rs +++ b/srml/support/src/storage/mod.rs @@ -16,100 +16,24 @@ //! Stuff to do with the runtime's storage. -use crate::rstd::prelude::*; -use crate::rstd::borrow::Borrow; -use codec::{Codec, Encode, Decode, KeyedVec, EncodeAppend}; -use hashed::generator::{HashedStorage, StorageHasher}; -use unhashed::generator::UnhashedStorage; +use rstd::prelude::*; +use codec::{FullCodec, FullEncode, Encode, EncodeAppend, EncodeLike}; +use crate::traits::Len; #[macro_use] pub mod storage_items; pub mod unhashed; pub mod hashed; - -/// The underlying runtime storage. -pub struct RuntimeStorage; - -impl HashedStorage for RuntimeStorage { - fn exists(&self, key: &[u8]) -> bool { - hashed::exists(&H::hash, key) - } - - /// Load the bytes of a key from storage. Can panic if the type is incorrect. - fn get(&self, key: &[u8]) -> Option { - hashed::get(&H::hash, key) - } - - /// Put a value in under a key. - fn put(&mut self, key: &[u8], val: &T) { - hashed::put(&H::hash, key, val) - } - - /// Remove the bytes of a key from storage. - fn kill(&mut self, key: &[u8]) { - hashed::kill(&H::hash, key) - } - - /// Take a value from storage, deleting it after reading. - fn take(&mut self, key: &[u8]) -> Option { - hashed::take(&H::hash, key) - } - - fn get_raw(&self, key: &[u8]) -> Option> { - hashed::get_raw(&H::hash, key) - } - - fn put_raw(&mut self, key: &[u8], value: &[u8]) { - hashed::put_raw(&H::hash, key, value) - } -} - -impl UnhashedStorage for RuntimeStorage { - fn exists(&self, key: &[u8]) -> bool { - unhashed::exists(key) - } - - /// Load the bytes of a key from storage. Can panic if the type is incorrect. - fn get(&self, key: &[u8]) -> Option { - unhashed::get(key) - } - - /// Put a value in under a key. - fn put(&mut self, key: &[u8], val: &T) { - unhashed::put(key, val) - } - - /// Remove the bytes of a key from storage. - fn kill(&mut self, key: &[u8]) { - unhashed::kill(key) - } - - /// Remove the bytes of a key from storage. - fn kill_prefix(&mut self, prefix: &[u8]) { - unhashed::kill_prefix(prefix) - } - - /// Take a value from storage, deleting it after reading. - fn take(&mut self, key: &[u8]) -> Option { - unhashed::take(key) - } - - fn get_raw(&self, key: &[u8]) -> Option> { - unhashed::get_raw(key) - } - - fn put_raw(&mut self, key: &[u8], value: &[u8]) { - unhashed::put_raw(key, value) - } -} +pub mod child; +pub mod generator; /// A trait for working with macro-generated storage values under the substrate storage API. -pub trait StorageValue { +pub trait StorageValue { /// The type that get/take return. type Query; /// Get the storage key. - fn key() -> &'static [u8]; + fn hashed_key() -> [u8; 16]; /// Does the value (explicitly) exist in storage? fn exists() -> bool; @@ -118,11 +42,7 @@ pub trait StorageValue { fn get() -> Self::Query; /// Store a value under this key into the provided storage instance. - fn put>(val: Arg); - - /// Store a value under this key into the provided storage instance; this can take any reference - /// type that derefs to `T` (and has `Encode` implemented). - fn put_ref(val: &Arg) where T: AsRef; + fn put>(val: Arg); /// Mutate the value fn mutate R>(f: F) -> R; @@ -136,453 +56,220 @@ pub trait StorageValue { /// Append the given item to the value in the storage. /// /// `T` is required to implement `codec::EncodeAppend`. - fn append(items: &[I]) -> Result<(), &'static str> - where T: EncodeAppend; -} + fn append(items: Items) -> Result<(), &'static str> + where + Item: Encode, + EncodeLikeItem: EncodeLike, + T: EncodeAppend, + Items: IntoIterator, + Items::IntoIter: ExactSizeIterator; -impl StorageValue for U where U: hashed::generator::StorageValue { - type Query = U::Query; - - fn key() -> &'static [u8] { - >::key() - } - fn exists() -> bool { - U::exists(&RuntimeStorage) - } - fn get() -> Self::Query { - U::get(&RuntimeStorage) - } - fn put>(val: Arg) { - U::put(val.borrow(), &mut RuntimeStorage) - } - fn put_ref(val: &Arg) where T: AsRef { - U::put_ref(val, &mut RuntimeStorage) - } - fn mutate R>(f: F) -> R { - U::mutate(f, &mut RuntimeStorage) - } - fn kill() { - U::kill(&mut RuntimeStorage) - } - fn take() -> Self::Query { - U::take(&mut RuntimeStorage) - } - fn append(items: &[I]) -> Result<(), &'static str> - where T: EncodeAppend - { - U::append(items, &mut RuntimeStorage) - } + /// Append the given items to the value in the storage. + /// + /// `T` is required to implement `Codec::EncodeAppend`. + /// + /// Upon any failure, it replaces `items` as the new value (assuming that the previous stored + /// data is simply corrupt and no longer usable). + /// + /// ### WARNING + /// + /// use with care; if your use-case is not _exactly_ as what this function is doing, + /// you should use append and sensibly handle failure within the runtime code if it happens. + fn append_or_put(items: Items) where + Item: Encode, + EncodeLikeItem: EncodeLike, + T: EncodeAppend, + Items: IntoIterator + Clone + EncodeLike, + Items::IntoIter: ExactSizeIterator; + + + /// Read the length of the value in a fast way, without decoding the entire value. + /// + /// `T` is required to implement `Codec::DecodeLength`. + fn decode_len() -> Result + where T: codec::DecodeLength + Len; } /// A strongly-typed map in storage. -pub trait StorageMap { +pub trait StorageMap { /// The type that get/take return. type Query; - /// Get the prefix key in storage. - fn prefix() -> &'static [u8]; - /// Get the storage key used to fetch a value corresponding to a specific key. - fn key_for>(key: KeyArg) -> Vec; + fn hashed_key_for>(key: KeyArg) -> Vec; /// Does the value (explicitly) exist in storage? - fn exists>(key: KeyArg) -> bool; + fn exists>(key: KeyArg) -> bool; /// Load the value associated with the given key from the map. - fn get>(key: KeyArg) -> Self::Query; + fn get>(key: KeyArg) -> Self::Query; /// Swap the values of two keys. - fn swap, KeyArg2: Borrow>(key1: KeyArg1, key2: KeyArg2); + fn swap, KeyArg2: EncodeLike>(key1: KeyArg1, key2: KeyArg2); /// Store a value to be associated with the given key from the map. - fn insert, ValArg: Borrow>(key: KeyArg, val: ValArg); - - /// Store a value under this key into the provided storage instance; this can take any reference - /// type that derefs to `T` (and has `Encode` implemented). - fn insert_ref, ValArg: ?Sized + Encode>(key: KeyArg, val: &ValArg) where V: AsRef; + fn insert, ValArg: EncodeLike>(key: KeyArg, val: ValArg); /// Remove the value under a key. - fn remove>(key: KeyArg); + fn remove>(key: KeyArg); /// Mutate the value under a key. - fn mutate, R, F: FnOnce(&mut Self::Query) -> R>(key: KeyArg, f: F) -> R; + fn mutate, R, F: FnOnce(&mut Self::Query) -> R>(key: KeyArg, f: F) -> R; /// Take the value under a key. - fn take>(key: KeyArg) -> Self::Query; -} + fn take>(key: KeyArg) -> Self::Query; -impl StorageMap for U where U: hashed::generator::StorageMap { - type Query = U::Query; - - fn prefix() -> &'static [u8] { - >::prefix() - } - - fn key_for>(key: KeyArg) -> Vec { - >::key_for(key.borrow()) - } - - fn exists>(key: KeyArg) -> bool { - U::exists(key.borrow(), &RuntimeStorage) - } + /// Append the given items to the value in the storage. + /// + /// `V` is required to implement `codec::EncodeAppend`. + fn append(key: KeyArg, items: Items) -> Result<(), &'static str> + where + KeyArg: EncodeLike, + Item: Encode, + EncodeLikeItem: EncodeLike, + V: EncodeAppend, + Items: IntoIterator, + Items::IntoIter: ExactSizeIterator; + + /// Safely append the given items to the value in the storage. If a codec error occurs, then the + /// old (presumably corrupt) value is replaced with the given `items`. + /// + /// `V` is required to implement `codec::EncodeAppend`. + fn append_or_insert(key: KeyArg, items: Items) + where + KeyArg: EncodeLike, + Item: Encode, + EncodeLikeItem: EncodeLike, + V: EncodeAppend, + Items: IntoIterator + Clone + EncodeLike, + Items::IntoIter: ExactSizeIterator; + + /// Read the length of the value in a fast way, without decoding the entire value. + /// + /// `T` is required to implement `Codec::DecodeLength`. + /// + /// Note that `0` is returned as the default value if no encoded value exists at the given key. + /// Therefore, this function cannot be used as a sign of _existence_. use the `::exists()` + /// function for this purpose. + fn decode_len>(key: KeyArg) -> Result + where V: codec::DecodeLength + Len; +} - fn get>(key: KeyArg) -> Self::Query { - U::get(key.borrow(), &RuntimeStorage) - } +/// A strongly-typed linked map in storage. +/// +/// Similar to `StorageMap` but allows to enumerate other elements and doesn't implement append. +pub trait StorageLinkedMap { + /// The type that get/take return. + type Query; - fn swap, KeyArg2: Borrow>(key1: KeyArg1, key2: KeyArg2) { - U::swap(key1.borrow(), key2.borrow(), &mut RuntimeStorage) - } + /// The type that iterates over all `(key, value)`. + type Enumerator: Iterator; - fn insert, ValArg: Borrow>(key: KeyArg, val: ValArg) { - U::insert(key.borrow(), val.borrow(), &mut RuntimeStorage) - } + /// Does the value (explicitly) exist in storage? + fn exists>(key: KeyArg) -> bool; - fn insert_ref, ValArg: ?Sized + Encode>(key: KeyArg, val: &ValArg) where V: AsRef { - U::insert_ref(key.borrow(), val, &mut RuntimeStorage) - } + /// Load the value associated with the given key from the map. + fn get>(key: KeyArg) -> Self::Query; - fn remove>(key: KeyArg) { - U::remove(key.borrow(), &mut RuntimeStorage) - } + /// Swap the values of two keys. + fn swap, KeyArg2: EncodeLike>(key1: KeyArg1, key2: KeyArg2); - fn mutate, R, F: FnOnce(&mut Self::Query) -> R>(key: KeyArg, f: F) -> R { - U::mutate(key.borrow(), f, &mut RuntimeStorage) - } + /// Store a value to be associated with the given key from the map. + fn insert, ValArg: EncodeLike>(key: KeyArg, val: ValArg); - fn take>(key: KeyArg) -> Self::Query { - U::take(key.borrow(), &mut RuntimeStorage) - } -} + /// Remove the value under a key. + fn remove>(key: KeyArg); -/// A storage map with values that can be appended to. -pub trait AppendableStorageMap: StorageMap { - /// Append the given item to the value in the storage. - /// - /// `T` is required to implement `codec::EncodeAppend`. - fn append, I: Encode>(key: KeyArg, items: &[I]) -> Result<(), &'static str> - where V: EncodeAppend; -} + /// Mutate the value under a key. + fn mutate, R, F: FnOnce(&mut Self::Query) -> R>(key: KeyArg, f: F) -> R; -impl AppendableStorageMap for U - where U: hashed::generator::AppendableStorageMap -{ - fn append, I: Encode>(key: KeyArg, items: &[I]) -> Result<(), &'static str> - where V: EncodeAppend - { - U::append(key.borrow(), items, &mut RuntimeStorage) - } -} + /// Take the value under a key. + fn take>(key: KeyArg) -> Self::Query; -/// A storage map that can be enumerated. -/// -/// Primarily useful for off-chain computations. -/// Runtime implementors should avoid enumerating storage entries on-chain. -pub trait EnumerableStorageMap: StorageMap { /// Return current head element. fn head() -> Option; /// Enumerate all elements in the map. - fn enumerate() -> Box> where K: 'static, V: 'static; -} + fn enumerate() -> Self::Enumerator; -impl EnumerableStorageMap for U - where U: hashed::generator::EnumerableStorageMap -{ - fn head() -> Option { - >::head(&RuntimeStorage) - } - - fn enumerate() -> Box> where K: 'static, V: 'static { - >::enumerate(&RuntimeStorage) - } + /// Read the length of the value in a fast way, without decoding the entire value. + /// + /// `T` is required to implement `Codec::DecodeLength`. + /// + /// Note that `0` is returned as the default value if no encoded value exists at the given key. + /// Therefore, this function cannot be used as a sign of _existence_. use the `::exists()` + /// function for this purpose. + fn decode_len>(key: KeyArg) -> Result + where V: codec::DecodeLength + Len; } /// An implementation of a map with a two keys. /// /// It provides an important ability to efficiently remove all entries /// that have a common first key. -/// -/// # Mapping of keys to a storage path -/// -/// The storage key (i.e. the key under which the `Value` will be stored) is created from two parts. -/// The first part is a hash of a concatenation of the `PREFIX` and `Key1`. And the second part -/// is a hash of a `Key2`. -/// -/// /!\ be careful while choosing the Hash, indeed malicious could craft second keys to lower the trie. -pub trait StorageDoubleMap { +pub trait StorageDoubleMap { /// The type that get/take returns. type Query; - fn prefix() -> &'static [u8]; - - fn key_for(k1: &KArg1, k2: &KArg2) -> Vec + fn exists(k1: KArg1, k2: KArg2) -> bool where - K1: Borrow, - K2: Borrow, - KArg1: ?Sized + Encode, - KArg2: ?Sized + Encode; - - fn prefix_for(k1: &KArg1) -> Vec where KArg1: ?Sized + Encode, K1: Borrow; + KArg1: EncodeLike, + KArg2: EncodeLike; - fn exists(k1: &KArg1, k2: &KArg2) -> bool + fn get(k1: KArg1, k2: KArg2) -> Self::Query where - K1: Borrow, - K2: Borrow, - KArg1: ?Sized + Encode, - KArg2: ?Sized + Encode; + KArg1: EncodeLike, + KArg2: EncodeLike; - fn get(k1: &KArg1, k2: &KArg2) -> Self::Query + fn take(k1: KArg1, k2: KArg2) -> Self::Query where - K1: Borrow, - K2: Borrow, - KArg1: ?Sized + Encode, - KArg2: ?Sized + Encode; + KArg1: EncodeLike, + KArg2: EncodeLike; - fn take(k1: &KArg1, k2: &KArg2) -> Self::Query + fn insert(k1: KArg1, k2: KArg2, val: VArg) where - K1: Borrow, - K2: Borrow, - KArg1: ?Sized + Encode, - KArg2: ?Sized + Encode; + KArg1: EncodeLike, + KArg2: EncodeLike, + VArg: EncodeLike; - fn insert(k1: &KArg1, k2: &KArg2, val: &VArg) - where - K1: Borrow, - K2: Borrow, - V: Borrow, - KArg1: ?Sized + Encode, - KArg2: ?Sized + Encode, - VArg: ?Sized + Encode; - - fn remove(k1: &KArg1, k2: &KArg2) + fn remove(k1: KArg1, k2: KArg2) where - K1: Borrow, - K2: Borrow, - KArg1: ?Sized + Encode, - KArg2: ?Sized + Encode; + KArg1: EncodeLike, + KArg2: EncodeLike; - fn remove_prefix(k1: &KArg1) where KArg1: ?Sized + Encode, K1: Borrow; + fn remove_prefix(k1: KArg1) where KArg1: ?Sized + EncodeLike; - fn mutate(k1: &KArg1, k2: &KArg2, f: F) -> R + fn mutate(k1: KArg1, k2: KArg2, f: F) -> R where - K1: Borrow, - K2: Borrow, - KArg1: ?Sized + Encode, - KArg2: ?Sized + Encode, + KArg1: EncodeLike, + KArg2: EncodeLike, F: FnOnce(&mut Self::Query) -> R; - fn append( - k1: &KArg1, - k2: &KArg2, - items: &[I], + fn append( + k1: KArg1, + k2: KArg2, + items: Items, ) -> Result<(), &'static str> where - K1: Borrow, - K2: Borrow, - KArg1: ?Sized + Encode, - KArg2: ?Sized + Encode, - I: codec::Encode, - V: EncodeAppend; -} - -impl StorageDoubleMap for U -where - U: unhashed::generator::StorageDoubleMap -{ - type Query = U::Query; - - fn prefix() -> &'static [u8] { - >::prefix() - } - - fn key_for(k1: &KArg1, k2: &KArg2) -> Vec - where - K1: Borrow, - K2: Borrow, - KArg1: ?Sized + Encode, - KArg2: ?Sized + Encode, - { - >::key_for(k1, k2) - } - - fn prefix_for(k1: &KArg1) -> Vec where KArg1: ?Sized + Encode, K1: Borrow { - >::prefix_for(k1) - } - - fn exists(k1: &KArg1, k2: &KArg2) -> bool - where - K1: Borrow, - K2: Borrow, - KArg1: ?Sized + Encode, - KArg2: ?Sized + Encode, - { - U::exists(k1, k2, &RuntimeStorage) - } - - fn get(k1: &KArg1, k2: &KArg2) -> Self::Query + KArg1: EncodeLike, + KArg2: EncodeLike, + Item: Encode, + EncodeLikeItem: EncodeLike, + V: EncodeAppend, + Items: IntoIterator, + Items::IntoIter: ExactSizeIterator; + + fn append_or_insert( + k1: KArg1, + k2: KArg2, + items: Items, + ) where - K1: Borrow, - K2: Borrow, - KArg1: ?Sized + Encode, - KArg2: ?Sized + Encode, - { - U::get(k1, k2, &RuntimeStorage) - } - - fn take(k1: &KArg1, k2: &KArg2) -> Self::Query - where - K1: Borrow, - K2: Borrow, - KArg1: ?Sized + Encode, - KArg2: ?Sized + Encode, - { - U::take(k1.borrow(), k2.borrow(), &mut RuntimeStorage) - } - - fn insert(k1: &KArg1, k2: &KArg2, val: &VArg) - where - K1: Borrow, - K2: Borrow, - V: Borrow, - KArg1: ?Sized + Encode, - KArg2: ?Sized + Encode, - VArg: ?Sized + Encode, - { - U::insert(k1, k2, val, &mut RuntimeStorage) - } - - fn remove(k1: &KArg1, k2: &KArg2) - where - K1: Borrow, - K2: Borrow, - KArg1: ?Sized + Encode, - KArg2: ?Sized + Encode, - { - U::remove(k1, k2, &mut RuntimeStorage) - } - - fn remove_prefix(k1: &KArg1) where KArg1: ?Sized + Encode, K1: Borrow { - U::remove_prefix(k1, &mut RuntimeStorage) - } - - fn mutate(k1: &KArg1, k2: &KArg2, f: F) -> R - where - K1: Borrow, - K2: Borrow, - KArg1: ?Sized + Encode, - KArg2: ?Sized + Encode, - F: FnOnce(&mut Self::Query) -> R - { - U::mutate(k1, k2, f, &mut RuntimeStorage) - } - - fn append( - k1: &KArg1, - k2: &KArg2, - items: &[I], - ) -> Result<(), &'static str> - where - K1: Borrow, - K2: Borrow, - KArg1: ?Sized + Encode, - KArg2: ?Sized + Encode, - I: codec::Encode, - V: EncodeAppend, - { - U::append(k1, k2, items, &mut RuntimeStorage) - } -} - -/// child storage NOTE could replace unhashed by having only one kind of storage (root being null storage -/// key (storage_key can become Option<&[u8]>). -/// This module is a currently only a variant of unhashed with additional `storage_key`. -/// Note that `storage_key` must be unique and strong (strong in the sense of being long enough to -/// avoid collision from a resistant hash function (which unique implies)). -pub mod child { - use super::{Codec, Decode, Vec}; - - /// Return the value of the item in storage under `key`, or `None` if there is no explicit entry. - pub fn get(storage_key: &[u8], key: &[u8]) -> Option { - runtime_io::child_storage(storage_key, key).map(|v| { - Decode::decode(&mut &v[..]).expect("storage is not null, therefore must be a valid type") - }) - } - - /// Return the value of the item in storage under `key`, or the type's default if there is no - /// explicit entry. - pub fn get_or_default(storage_key: &[u8], key: &[u8]) -> T { - get(storage_key, key).unwrap_or_else(Default::default) - } - - /// Return the value of the item in storage under `key`, or `default_value` if there is no - /// explicit entry. - pub fn get_or(storage_key: &[u8], key: &[u8], default_value: T) -> T { - get(storage_key, key).unwrap_or(default_value) - } - - /// Return the value of the item in storage under `key`, or `default_value()` if there is no - /// explicit entry. - pub fn get_or_else T>(storage_key: &[u8], key: &[u8], default_value: F) -> T { - get(storage_key, key).unwrap_or_else(default_value) - } - - /// Put `value` in storage under `key`. - pub fn put(storage_key: &[u8], key: &[u8], value: &T) { - value.using_encoded(|slice| runtime_io::set_child_storage(storage_key, key, slice)); - } - - /// Remove `key` from storage, returning its value if it had an explicit entry or `None` otherwise. - pub fn take(storage_key: &[u8], key: &[u8]) -> Option { - let r = get(storage_key, key); - if r.is_some() { - kill(storage_key, key); - } - r - } - - /// Remove `key` from storage, returning its value, or, if there was no explicit entry in storage, - /// the default for its type. - pub fn take_or_default(storage_key: &[u8], key: &[u8]) -> T { - take(storage_key, key).unwrap_or_else(Default::default) - } - - /// Return the value of the item in storage under `key`, or `default_value` if there is no - /// explicit entry. Ensure there is no explicit entry on return. - pub fn take_or(storage_key: &[u8],key: &[u8], default_value: T) -> T { - take(storage_key, key).unwrap_or(default_value) - } - - /// Return the value of the item in storage under `key`, or `default_value()` if there is no - /// explicit entry. Ensure there is no explicit entry on return. - pub fn take_or_else T>(storage_key: &[u8], key: &[u8], default_value: F) -> T { - take(storage_key, key).unwrap_or_else(default_value) - } - - /// Check to see if `key` has an explicit entry in storage. - pub fn exists(storage_key: &[u8], key: &[u8]) -> bool { - runtime_io::read_child_storage(storage_key, key, &mut [0;0][..], 0).is_some() - } - - /// Remove all `storage_key` key/values - pub fn kill_storage(storage_key: &[u8]) { - runtime_io::kill_child_storage(storage_key) - } - - /// Ensure `key` has no explicit entry in storage. - pub fn kill(storage_key: &[u8], key: &[u8]) { - runtime_io::clear_child_storage(storage_key, key); - } - - /// Get a Vec of bytes from storage. - pub fn get_raw(storage_key: &[u8], key: &[u8]) -> Option> { - runtime_io::child_storage(storage_key, key) - } - - /// Put a raw byte slice into storage. - pub fn put_raw(storage_key: &[u8], key: &[u8], value: &[u8]) { - runtime_io::set_child_storage(storage_key, key, value) - } - - pub use super::unhashed::StorageVec; + KArg1: EncodeLike, + KArg2: EncodeLike, + Item: Encode, + EncodeLikeItem: EncodeLike, + V: EncodeAppend, + Items: IntoIterator + Clone + EncodeLike, + Items::IntoIter: ExactSizeIterator; } diff --git a/srml/support/src/storage/storage_items.rs b/srml/support/src/storage/storage_items.rs index 06cb8fc55b5cd7c3c7bc64aa03b0509799172257..24a7f3984a8650b7327196e0d90dd3e875178baf 100644 --- a/srml/support/src/storage/storage_items.rs +++ b/srml/support/src/storage/storage_items.rs @@ -19,7 +19,7 @@ //! This crate exports a macro `storage_items!` and traits describing behavior of generated //! structs. //! -//! Three kinds of data types are currently supported: +//! Two kinds of data types are currently supported: //! - values //! - maps //! @@ -50,109 +50,127 @@ pub use crate::rstd::marker::PhantomData; #[doc(hidden)] pub use crate::rstd::boxed::Box; +#[doc(hidden)] +pub fn id(t: T) -> T { + t +} + +#[doc(hidden)] +pub use Some; + +#[doc(hidden)] +pub fn unwrap_or_default(t: Option) -> T { + t.unwrap_or_else(|| Default::default()) +} + +#[doc(hidden)] +pub fn require(t: Option) -> T { + t.expect("Required values must be in storage") +} + // FIXME #1466 Remove this in favor of `decl_storage` macro. /// Declares strongly-typed wrappers around codec-compatible types in storage. #[macro_export] macro_rules! storage_items { // simple values ($name:ident : $key:expr => $ty:ty; $($t:tt)*) => { - $crate::__storage_items_internal!(() () (OPTION_TYPE Option<$ty>) (get) (take) $name: $key => $ty); + $crate::__storage_items_internal!(() () (OPTION_TYPE Option<$ty>) (id) (id) $name: $key => $ty); storage_items!($($t)*); }; (pub $name:ident : $key:expr => $ty:ty; $($t:tt)*) => { - $crate::__storage_items_internal!((pub) () (OPTION_TYPE Option<$ty>) (get) (take) $name: $key => $ty); + $crate::__storage_items_internal!((pub) () (OPTION_TYPE Option<$ty>) (id) (id) $name: $key => $ty); storage_items!($($t)*); }; ($name:ident : $key:expr => default $ty:ty; $($t:tt)*) => { - $crate::__storage_items_internal!(() () (RAW_TYPE $ty) (get_or_default) (take_or_default) $name: $key => $ty); + $crate::__storage_items_internal!(() () (RAW_TYPE $ty) (unwrap_or_default) (Some) $name: $key => $ty); storage_items!($($t)*); }; (pub $name:ident : $key:expr => default $ty:ty; $($t:tt)*) => { - $crate::__storage_items_internal!((pub) () (RAW_TYPE $ty) (get_or_default) (take_or_default) $name: $key => $ty); + $crate::__storage_items_internal!((pub) () (RAW_TYPE $ty) (unwrap_or_default) (Some) $name: $key => $ty); storage_items!($($t)*); }; ($name:ident : $key:expr => required $ty:ty; $($t:tt)*) => { - $crate::__storage_items_internal!(() () (RAW_TYPE $ty) (require) (take_or_panic) $name: $key => $ty); + $crate::__storage_items_internal!(() () (RAW_TYPE $ty) (require) (Some) $name: $key => $ty); storage_items!($($t)*); }; (pub $name:ident : $key:expr => required $ty:ty; $($t:tt)*) => { - $crate::__storage_items_internal!((pub) () (RAW_TYPE $ty) (require) (take_or_panic) $name: $key => $ty); + $crate::__storage_items_internal!((pub) () (RAW_TYPE $ty) (require) (Some) $name: $key => $ty); storage_items!($($t)*); }; ($name:ident get($getfn:ident) : $key:expr => $ty:ty; $($t:tt)*) => { - $crate::__storage_items_internal!(() ($getfn) (OPTION_TYPE Option<$ty>) (get) (take) $name: $key => $ty); + $crate::__storage_items_internal!(() ($getfn) (OPTION_TYPE Option<$ty>) (id) (id) $name: $key => $ty); storage_items!($($t)*); }; (pub $name:ident get($getfn:ident) : $key:expr => $ty:ty; $($t:tt)*) => { - $crate::__storage_items_internal!((pub) ($getfn) (OPTION_TYPE Option<$ty>) (get) (take) $name: $key => $ty); + $crate::__storage_items_internal!((pub) ($getfn) (OPTION_TYPE Option<$ty>) (id) (id) $name: $key => $ty); storage_items!($($t)*); }; ($name:ident get($getfn:ident) : $key:expr => default $ty:ty; $($t:tt)*) => { - $crate::__storage_items_internal!(() ($getfn) (RAW_TYPE $ty) (get_or_default) (take_or_default) $name: $key => $ty); + $crate::__storage_items_internal!(() ($getfn) (RAW_TYPE $ty) (unwrap_or_default) (Some) $name: $key => $ty); storage_items!($($t)*); }; (pub $name:ident get($getfn:ident) : $key:expr => default $ty:ty; $($t:tt)*) => { - $crate::__storage_items_internal!((pub) ($getfn) (RAW_TYPE $ty) (get_or_default) (take_or_default) $name: $key => $ty); + $crate::__storage_items_internal!((pub) ($getfn) (RAW_TYPE $ty) (unwrap_or_default) (Some) $name: $key => $ty); storage_items!($($t)*); }; ($name:ident get($getfn:ident) : $key:expr => required $ty:ty; $($t:tt)*) => { - $crate::__storage_items_internal!(() ($getfn) (RAW_TYPE $ty) (require) (take_or_panic) $name: $key => $ty); + $crate::__storage_items_internal!(() ($getfn) (RAW_TYPE $ty) (require) (Some) $name: $key => $ty); storage_items!($($t)*); }; (pub $name:ident get($getfn:ident) : $key:expr => required $ty:ty; $($t:tt)*) => { - $crate::__storage_items_internal!((pub) ($getfn) (RAW_TYPE $ty) (require) (take_or_panic) $name: $key => $ty); + $crate::__storage_items_internal!((pub) ($getfn) (RAW_TYPE $ty) (require) (Some) $name: $key => $ty); storage_items!($($t)*); }; // maps ($name:ident : $prefix:expr => map [$kty:ty => $ty:ty]; $($t:tt)*) => { - $crate::__storage_items_internal!(() () (OPTION_TYPE Option<$ty>) (get) (take) $name: $prefix => map [$kty => $ty]); + $crate::__storage_items_internal!(() () (OPTION_TYPE Option<$ty>) (id) (id) $name: $prefix => map [$kty => $ty]); storage_items!($($t)*); }; (pub $name:ident : $prefix:expr => map [$kty:ty => $ty:ty]; $($t:tt)*) => { - $crate::__storage_items_internal!((pub) () (OPTION_TYPE Option<$ty>) (get) (take) $name: $prefix => map [$kty => $ty]); + $crate::__storage_items_internal!((pub) () (OPTION_TYPE Option<$ty>) (id) (id) $name: $prefix => map [$kty => $ty]); storage_items!($($t)*); }; ($name:ident : $prefix:expr => default map [$kty:ty => $ty:ty]; $($t:tt)*) => { - $crate::__storage_items_internal!(() () (RAW_TYPE $ty) (get_or_default) (take_or_default) $name: $prefix => map [$kty => $ty]); + $crate::__storage_items_internal!(() () (RAW_TYPE $ty) (unwrap_or_default) (Some) $name: $prefix => map [$kty => $ty]); storage_items!($($t)*); }; (pub $name:ident : $prefix:expr => default map [$kty:ty => $ty:ty]; $($t:tt)*) => { - $crate::__storage_items_internal!((pub) () (RAW_TYPE $ty) (get_or_default) (take_or_default) $name: $prefix => map [$kty => $ty]); + $crate::__storage_items_internal!((pub) () (RAW_TYPE $ty) (unwrap_or_default) (Some) $name: $prefix => map [$kty => $ty]); storage_items!($($t)*); }; ($name:ident : $prefix:expr => required map [$kty:ty => $ty:ty]; $($t:tt)*) => { - $crate::__storage_items_internal!(() () (RAW_TYPE $ty) (require) (take_or_panic) $name: $prefix => map [$kty => $ty]); + $crate::__storage_items_internal!(() () (RAW_TYPE $ty) (require) (Some) $name: $prefix => map [$kty => $ty]); storage_items!($($t)*); }; (pub $name:ident : $prefix:expr => required map [$kty:ty => $ty:ty]; $($t:tt)*) => { - $crate::__storage_items_internal!((pub) () (RAW_TYPE $ty) (require) (take_or_panic) $name: $prefix => map [$kty => $ty]); + $crate::__storage_items_internal!((pub) () (RAW_TYPE $ty) (require) (Some) $name: $prefix => map [$kty => $ty]); storage_items!($($t)*); }; ($name:ident get($getfn:ident) : $prefix:expr => map [$kty:ty => $ty:ty]; $($t:tt)*) => { - $crate::__storage_items_internal!(() ($getfn) (OPTION_TYPE Option<$ty>) (get) (take) $name: $prefix => map [$kty => $ty]); + $crate::__storage_items_internal!(() ($getfn) (OPTION_TYPE Option<$ty>) (id) (id) $name: $prefix => map [$kty => $ty]); storage_items!($($t)*); }; (pub $name:ident get($getfn:ident) : $prefix:expr => map [$kty:ty => $ty:ty]; $($t:tt)*) => { - $crate::__storage_items_internal!((pub) ($getfn) (OPTION_TYPE Option<$ty>) (get) (take) $name: $prefix => map [$kty => $ty]); + $crate::__storage_items_internal!((pub) ($getfn) (OPTION_TYPE Option<$ty>) (id) (id) $name: $prefix => map [$kty => $ty]); storage_items!($($t)*); }; ($name:ident get($getfn:ident) : $prefix:expr => default map [$kty:ty => $ty:ty]; $($t:tt)*) => { - $crate::__storage_items_internal!(() ($getfn) (RAW_TYPE $ty) (get_or_default) (take_or_default) $name: $prefix => map [$kty => $ty]); + $crate::__storage_items_internal!(() ($getfn) (RAW_TYPE $ty) (unwrap_or_default) (Some) $name: $prefix => map [$kty => $ty]); storage_items!($($t)*); }; (pub $name:ident get($getfn:ident) : $prefix:expr => default map [$kty:ty => $ty:ty]; $($t:tt)*) => { - $crate::__storage_items_internal!((pub) ($getfn) (RAW_TYPE $ty) (get_or_default) (take_or_default) $name: $prefix => map [$kty => $ty]); + $crate::__storage_items_internal!((pub) ($getfn) (RAW_TYPE $ty) (unwrap_or_default) (Some) $name: $prefix => map [$kty => $ty]); storage_items!($($t)*); }; ($name:ident get($getfn:ident) : $prefix:expr => required map [$kty:ty => $ty:ty]; $($t:tt)*) => { - $crate::__storage_items_internal!(() ($getfn) (RAW_TYPE $ty) (require) (take_or_panic) $name: $prefix => map [$kty => $ty]); + $crate::__storage_items_internal!(() ($getfn) (RAW_TYPE $ty) (require) (Some) $name: $prefix => map [$kty => $ty]); storage_items!($($t)*); }; (pub $name:ident get($getfn:ident) : $prefix:expr => required map [$kty:ty => $ty:ty]; $($t:tt)*) => { - $crate::__storage_items_internal!((pub) ($getfn) (RAW_TYPE $ty) (require) (take_or_panic) $name: $prefix => map [$kty => $ty]); + $crate::__storage_items_internal!((pub) ($getfn) (RAW_TYPE $ty) (require) (Some) $name: $prefix => map [$kty => $ty]); storage_items!($($t)*); }; @@ -163,109 +181,53 @@ macro_rules! storage_items { #[doc(hidden)] macro_rules! __storage_items_internal { // generator for values. - (($($vis:tt)*) ($get_fn:ident) ($wraptype:ident $gettype:ty) ($getter:ident) ($taker:ident) $name:ident : $key:expr => $ty:ty) => { - $crate::__storage_items_internal!{ ($($vis)*) () ($wraptype $gettype) ($getter) ($taker) $name : $key => $ty } - pub fn $get_fn() -> $gettype { <$name as $crate::storage::hashed::generator::StorageValue<$ty>> :: get(&$crate::storage::RuntimeStorage) } + (($($vis:tt)*) ($get_fn:ident) ($wraptype:ident $gettype:ty) ($into_query:ident) ($into_opt_val:ident) $name:ident : $key:expr => $ty:ty) => { + $crate::__storage_items_internal!{ ($($vis)*) () ($wraptype $gettype) ($into_query) ($into_opt_val) $name : $key => $ty } + pub fn $get_fn() -> $gettype { <$name as $crate::storage::StorageValue<$ty>> :: get() } }; - (($($vis:tt)*) () ($wraptype:ident $gettype:ty) ($getter:ident) ($taker:ident) $name:ident : $key:expr => $ty:ty) => { + (($($vis:tt)*) () ($wraptype:ident $gettype:ty) ($into_query:ident) ($into_opt_val:ident) $name:ident : $key:expr => $ty:ty) => { $($vis)* struct $name; - impl $crate::storage::hashed::generator::StorageValue<$ty> for $name { + impl $crate::storage::generator::StorageValue<$ty> for $name { type Query = $gettype; - /// Get the storage key. - fn key() -> &'static [u8] { + fn unhashed_key() -> &'static [u8] { $key } - /// Load the value from the provided storage instance. - fn get>(storage: &S) -> Self::Query { - storage.$getter($key) + fn from_optional_value_to_query(v: Option<$ty>) -> Self::Query { + $crate::storage::storage_items::$into_query(v) } - /// Take a value from storage, removing it afterwards. - fn take>(storage: &mut S) -> Self::Query { - storage.$taker($key) - } - - /// Mutate this value. - fn mutate R, S: $crate::HashedStorage<$crate::Twox128>>(f: F, storage: &mut S) -> R { - let mut val = >::get(storage); - - let ret = f(&mut val); - - $crate::__handle_wrap_internal!($wraptype { - // raw type case - >::put(&val, storage) - } { - // Option<> type case - match val { - Some(ref val) => >::put(&val, storage), - None => >::kill(storage), - } - }); - - ret + fn from_query_to_optional_value(v: Self::Query) -> Option<$ty> { + $crate::storage::storage_items::$into_opt_val(v) } } }; // generator for maps. - (($($vis:tt)*) ($get_fn:ident) ($wraptype:ident $gettype:ty) ($getter:ident) ($taker:ident) $name:ident : $prefix:expr => map [$kty:ty => $ty:ty]) => { - $crate::__storage_items_internal!{ ($($vis)*) () ($wraptype $gettype) ($getter) ($taker) $name : $prefix => map [$kty => $ty] } - pub fn $get_fn>(key: K) -> $gettype { - <$name as $crate::storage::hashed::generator::StorageMap<$kty, $ty>> :: get(key.borrow(), &$crate::storage::RuntimeStorage) + (($($vis:tt)*) ($get_fn:ident) ($wraptype:ident $gettype:ty) ($into_query:ident) ($into_opt_val:ident) $name:ident : $prefix:expr => map [$kty:ty => $ty:ty]) => { + $crate::__storage_items_internal!{ ($($vis)*) () ($wraptype $gettype) ($into_query) ($into_opt_val) $name : $prefix => map [$kty => $ty] } + pub fn $get_fn>(key: K) -> $gettype { + <$name as $crate::storage::StorageMap<$kty, $ty>> :: get(key.borrow()) } }; - (($($vis:tt)*) () ($wraptype:ident $gettype:ty) ($getter:ident) ($taker:ident) $name:ident : $prefix:expr => map [$kty:ty => $ty:ty]) => { + (($($vis:tt)*) () ($wraptype:ident $gettype:ty) ($into_query:ident) ($into_opt_val:ident) $name:ident : $prefix:expr => map [$kty:ty => $ty:ty]) => { $($vis)* struct $name; - impl $crate::storage::hashed::generator::StorageMap<$kty, $ty> for $name { + impl $crate::storage::generator::StorageMap<$kty, $ty> for $name { type Query = $gettype; - type Hasher = $crate::Blake2_256; - /// Get the prefix key in storage. fn prefix() -> &'static [u8] { $prefix } - /// Get the storage key used to fetch a value corresponding to a specific key. - fn key_for(x: &$kty) -> $crate::rstd::vec::Vec { - let mut key = $prefix.to_vec(); - $crate::codec::Encode::encode_to(x, &mut key); - key + fn from_optional_value_to_query(v: Option<$ty>) -> Self::Query { + $crate::storage::storage_items::$into_query(v) } - /// Load the value associated with the given key from the map. - fn get>(key: &$kty, storage: &S) -> Self::Query { - let key = <$name as $crate::storage::hashed::generator::StorageMap<$kty, $ty>>::key_for(key); - storage.$getter(&key[..]) - } - - /// Take the value, reading and removing it. - fn take>(key: &$kty, storage: &mut S) -> Self::Query { - let key = <$name as $crate::storage::hashed::generator::StorageMap<$kty, $ty>>::key_for(key); - storage.$taker(&key[..]) - } - - /// Mutate the value under a key. - fn mutate R, S: $crate::HashedStorage>(key: &$kty, f: F, storage: &mut S) -> R { - let mut val = >::take(key, storage); - - let ret = f(&mut val); - - $crate::__handle_wrap_internal!($wraptype { - // raw type case - >::insert(key, &val, storage) - } { - // Option<> type case - match val { - Some(ref val) => >::insert(key, &val, storage), - None => >::remove(key, storage), - } - }); - - ret + fn from_query_to_optional_value(v: Self::Query) -> Option<$ty> { + $crate::storage::storage_items::$into_opt_val(v) } } }; @@ -291,12 +253,10 @@ macro_rules! __handle_wrap_internal { // Do not complain about unused `dispatch` and `dispatch_aux`. #[allow(dead_code)] mod tests { - use std::collections::HashMap; - use super::*; use crate::metadata::*; use crate::metadata::StorageHasher; use crate::rstd::marker::PhantomData; - use crate::storage::hashed::generator::*; + use crate::codec::{Encode, Decode, EncodeLike}; storage_items! { Value: b"a" => u32; @@ -305,27 +265,29 @@ mod tests { #[test] fn value() { - let mut storage = HashMap::new(); - assert!(Value::get(&storage).is_none()); - Value::put(&100_000, &mut storage); - assert_eq!(Value::get(&storage), Some(100_000)); - Value::kill(&mut storage); - assert!(Value::get(&storage).is_none()); + runtime_io::with_storage(&mut Default::default(), || { + assert!(Value::get().is_none()); + Value::put(&100_000); + assert_eq!(Value::get(), Some(100_000)); + Value::kill(); + assert!(Value::get().is_none()); + }) } #[test] fn map() { - let mut storage = HashMap::new(); - assert!(Map::get(&5, &storage).is_none()); - Map::insert(&5, &[1; 32], &mut storage); - assert_eq!(Map::get(&5, &storage), Some([1; 32])); - assert_eq!(Map::take(&5, &mut storage), Some([1; 32])); - assert!(Map::get(&5, &storage).is_none()); - assert!(Map::get(&999, &storage).is_none()); + runtime_io::with_storage(&mut Default::default(), || { + assert!(Map::get(&5).is_none()); + Map::insert(&5, &[1; 32]); + assert_eq!(Map::get(&5), Some([1; 32])); + assert_eq!(Map::take(&5), Some([1; 32])); + assert!(Map::get(&5).is_none()); + assert!(Map::get(&999).is_none()); + }) } pub trait Trait { - type Origin: crate::codec::Encode + crate::codec::Decode + ::std::default::Default; + type Origin: Encode + Decode + EncodeLike + std::default::Default; type BlockNumber; } @@ -338,10 +300,10 @@ mod tests { // non-getters: pub / $default /// Hello, this is doc! - U32 : Option = Some(3); + U32 : Option; pub PUBU32 : Option; - U32MYDEF : Option = None; - pub PUBU32MYDEF : Option = Some(3); + U32MYDEF : Option; + pub PUBU32MYDEF : Option; // getters: pub / $default // we need at least one type which uses T, otherwise GenesisConfig will complain. @@ -349,17 +311,17 @@ mod tests { pub PUBGETU32 get(pub_u32_getter) build(|config: &GenesisConfig| config.u32_getter_with_config): u32; GETU32WITHCONFIG get(u32_getter_with_config) config(): u32; pub PUBGETU32WITHCONFIG get(pub_u32_getter_with_config) config(): u32; - GETU32MYDEF get(u32_getter_mydef): Option = Some(4); + GETU32MYDEF get(u32_getter_mydef): Option; pub PUBGETU32MYDEF get(pub_u32_getter_mydef) config(): u32 = 3; GETU32WITHCONFIGMYDEF get(u32_getter_with_config_mydef) config(): u32 = 2; pub PUBGETU32WITHCONFIGMYDEF get(pub_u32_getter_with_config_mydef) config(): u32 = 1; - PUBGETU32WITHCONFIGMYDEFOPT get(pub_u32_getter_with_config_mydef_opt) config(): Option = Some(100); + PUBGETU32WITHCONFIGMYDEFOPT get(pub_u32_getter_with_config_mydef_opt) config(): Option; // map non-getters: pub / $default MAPU32 : map u32 => Option; pub PUBMAPU32 : map u32 => Option; - MAPU32MYDEF : map u32 => Option = None; - pub PUBMAPU32MYDEF : map u32 => Option = Some("hello".into()); + MAPU32MYDEF : map u32 => Option; + pub PUBMAPU32MYDEF : map u32 => Option; // map getters: pub / $default GETMAPU32 get(map_u32_getter): map u32 => String; @@ -370,7 +332,7 @@ mod tests { // linked map LINKEDMAPU32 : linked_map u32 => Option; - pub PUBLINKEDMAPU32MYDEF : linked_map u32 => Option = Some("hello".into()); + pub PUBLINKEDMAPU32MYDEF : linked_map u32 => Option; GETLINKEDMAPU32 get(linked_map_u32_getter): linked_map u32 => String; pub PUBGETLINKEDMAPU32MYDEF get(pub_linked_map_u32_getter_mydef): linked_map u32 => String = "pubmap".into(); @@ -379,7 +341,7 @@ mod tests { COMPLEXTYPE3: ([u32;25]); } add_extra_genesis { - build(|_, _| {}); + build(|_| {}); } } @@ -726,7 +688,7 @@ mod tests { assert_eq!(config.pub_u32_getter_mydef, 3u32); assert_eq!(config.u32_getter_with_config_mydef, 2u32); assert_eq!(config.pub_u32_getter_with_config_mydef, 1u32); - assert_eq!(config.pub_u32_getter_with_config_mydef_opt, 100u32); + assert_eq!(config.pub_u32_getter_with_config_mydef_opt, 0u32); } } @@ -755,7 +717,7 @@ mod test2 { add_extra_genesis { config(_marker) : ::std::marker::PhantomData; config(extra_field) : u32 = 32; - build(|_, _| {}); + build(|_| {}); } } @@ -795,18 +757,38 @@ mod test3 { #[cfg(test)] #[allow(dead_code)] -mod test_map_vec_append { +mod test_append_and_len { + use crate::storage::{StorageValue}; + use runtime_io::{with_externalities, TestExternalities}; + use codec::{Encode, Decode}; + pub trait Trait { type Origin; type BlockNumber; } + decl_module! { pub struct Module for enum Call where origin: T::Origin {} } + + #[derive(PartialEq, Eq, Clone, Encode, Decode)] + struct NoDef(u32); + crate::decl_storage! { trait Store for Module as Test { + NoDefault: Option; + JustVec: Vec; + JustVecWithDefault: Vec = vec![6, 9]; + OptionVec: Option>; + MapVec: map u32 => Vec; + MapVecWithDefault: map u32 => Vec = vec![6, 9]; + OptionMapVec: map u32 => Option>; + + LinkedMapVec: linked_map u32 => Vec; + LinkedMapVecWithDefault: linked_map u32 => Vec = vec![6, 9]; + OptionLinkedMapVec: linked_map u32 => Option>; } } @@ -817,21 +799,108 @@ mod test_map_vec_append { type BlockNumber = u32; } + #[test] + fn default_for_option() { + with_externalities(&mut TestExternalities::default(), || { + assert_eq!(OptionVec::get(), None); + assert_eq!(JustVec::get(), vec![]); + }); + } + #[test] fn append_works() { - use crate::storage::{AppendableStorageMap, StorageMap, StorageValue}; - use runtime_io::{with_externalities, TestExternalities}; + with_externalities(&mut TestExternalities::default(), || { + let _ = MapVec::append(1, [1, 2, 3].iter()); + let _ = MapVec::append(1, [4, 5].iter()); + assert_eq!(MapVec::get(1), vec![1, 2, 3, 4, 5]); + + let _ = JustVec::append([1, 2, 3].iter()); + let _ = JustVec::append([4, 5].iter()); + assert_eq!(JustVec::get(), vec![1, 2, 3, 4, 5]); + }); + } + + #[test] + fn append_works_for_default() { + with_externalities(&mut TestExternalities::default(), || { + assert_eq!(JustVecWithDefault::get(), vec![6, 9]); + let _ = JustVecWithDefault::append([1].iter()); + assert_eq!(JustVecWithDefault::get(), vec![6, 9, 1]); + + assert_eq!(MapVecWithDefault::get(0), vec![6, 9]); + let _ = MapVecWithDefault::append(0, [1].iter()); + assert_eq!(MapVecWithDefault::get(0), vec![6, 9, 1]); + + assert_eq!(OptionVec::get(), None); + let _ = OptionVec::append([1].iter()); + assert_eq!(OptionVec::get(), Some(vec![1])); + }); + } + #[test] + fn append_or_put_works() { with_externalities(&mut TestExternalities::default(), || { - let _ = MapVec::append(1, &[1, 2, 3]); - let _ = MapVec::append(1, &[4, 5]); + let _ = MapVec::append_or_insert(1, &[1, 2, 3][..]); + let _ = MapVec::append_or_insert(1, &[4, 5][..]); assert_eq!(MapVec::get(1), vec![1, 2, 3, 4, 5]); - let _ = JustVec::append(&[1, 2, 3]); - let _ = JustVec::append(&[4, 5]); + let _ = JustVec::append_or_put(&[1, 2, 3][..]); + let _ = JustVec::append_or_put(&[4, 5][..]); assert_eq!(JustVec::get(), vec![1, 2, 3, 4, 5]); + + let _ = OptionVec::append_or_put(&[1, 2, 3][..]); + let _ = OptionVec::append_or_put(&[4, 5][..]); + assert_eq!(OptionVec::get(), Some(vec![1, 2, 3, 4, 5])); }); } -} + #[test] + fn len_works() { + with_externalities(&mut TestExternalities::default(), || { + JustVec::put(&vec![1, 2, 3, 4]); + OptionVec::put(&vec![1, 2, 3, 4, 5]); + MapVec::insert(1, &vec![1, 2, 3, 4, 5, 6]); + LinkedMapVec::insert(2, &vec![1, 2, 3]); + + assert_eq!(JustVec::decode_len().unwrap(), 4); + assert_eq!(OptionVec::decode_len().unwrap(), 5); + assert_eq!(MapVec::decode_len(1).unwrap(), 6); + assert_eq!(LinkedMapVec::decode_len(2).unwrap(), 3); + }); + } + + #[test] + fn len_works_for_default() { + with_externalities(&mut TestExternalities::default(), || { + // vec + assert_eq!(JustVec::get(), vec![]); + assert_eq!(JustVec::decode_len(), Ok(0)); + + assert_eq!(JustVecWithDefault::get(), vec![6, 9]); + assert_eq!(JustVecWithDefault::decode_len(), Ok(2)); + + assert_eq!(OptionVec::get(), None); + assert_eq!(OptionVec::decode_len(), Ok(0)); + + // map + assert_eq!(MapVec::get(0), vec![]); + assert_eq!(MapVec::decode_len(0), Ok(0)); + assert_eq!(MapVecWithDefault::get(0), vec![6, 9]); + assert_eq!(MapVecWithDefault::decode_len(0), Ok(2)); + + assert_eq!(OptionMapVec::get(0), None); + assert_eq!(OptionMapVec::decode_len(0), Ok(0)); + + // linked map + assert_eq!(LinkedMapVec::get(0), vec![]); + assert_eq!(LinkedMapVec::decode_len(0), Ok(0)); + + assert_eq!(LinkedMapVecWithDefault::get(0), vec![6, 9]); + assert_eq!(LinkedMapVecWithDefault::decode_len(0), Ok(2)); + + assert_eq!(OptionLinkedMapVec::get(0), None); + assert_eq!(OptionLinkedMapVec::decode_len(0), Ok(0)); + }); + } +} diff --git a/srml/support/src/storage/unhashed/mod.rs b/srml/support/src/storage/unhashed.rs similarity index 72% rename from srml/support/src/storage/unhashed/mod.rs rename to srml/support/src/storage/unhashed.rs index 5d086c36c4819aa8c97183e393828f9615d4a4c9..6397fd39fcd2d90dd39012e199c329c741c50832 100644 --- a/srml/support/src/storage/unhashed/mod.rs +++ b/srml/support/src/storage/unhashed.rs @@ -14,12 +14,10 @@ // You should have received a copy of the GNU General Public License // along with Substrate. If not, see . -//! Operation on unhashed runtime storage +//! Operation on unhashed runtime storage. -use crate::rstd::borrow::Borrow; -use super::{Codec, Encode, Decode, KeyedVec, Vec}; - -pub mod generator; +use rstd::prelude::*; +use codec::{Encode, Decode}; /// Return the value of the item in storage under `key`, or `None` if there is no explicit entry. pub fn get(key: &[u8]) -> Option { @@ -102,55 +100,3 @@ pub fn get_raw(key: &[u8]) -> Option> { pub fn put_raw(key: &[u8], value: &[u8]) { runtime_io::set_storage(key, value) } - -/// A trait to conveniently store a vector of storable data. -pub trait StorageVec { - type Item: Default + Sized + Codec; - const PREFIX: &'static [u8]; - - /// Get the current set of items. - fn items() -> Vec { - (0..Self::count()).into_iter().map(Self::item).collect() - } - - /// Set the current set of items. - fn set_items(items: I) - where - I: IntoIterator, - T: Borrow, - { - let mut count: u32 = 0; - - for i in items.into_iter() { - put(&count.to_keyed_vec(Self::PREFIX), i.borrow()); - count = count.checked_add(1).expect("exceeded runtime storage capacity"); - } - - Self::set_count(count); - } - - fn set_item(index: u32, item: &Self::Item) { - if index < Self::count() { - put(&index.to_keyed_vec(Self::PREFIX), item); - } - } - - fn clear_item(index: u32) { - if index < Self::count() { - kill(&index.to_keyed_vec(Self::PREFIX)); - } - } - - fn item(index: u32) -> Self::Item { - get_or_default(&index.to_keyed_vec(Self::PREFIX)) - } - - fn set_count(count: u32) { - (count..Self::count()).for_each(Self::clear_item); - put(&b"len".to_keyed_vec(Self::PREFIX), &count); - } - - fn count() -> u32 { - get_or_default(&b"len".to_keyed_vec(Self::PREFIX)) - } -} diff --git a/srml/support/src/storage/unhashed/generator.rs b/srml/support/src/storage/unhashed/generator.rs deleted file mode 100644 index a5385af8fb2f97154361dfe8846f6e673c3cb2bd..0000000000000000000000000000000000000000 --- a/srml/support/src/storage/unhashed/generator.rs +++ /dev/null @@ -1,241 +0,0 @@ -// Copyright 2019 Parity Technologies (UK) Ltd. -// This file is part of Substrate. - -// Substrate 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. - -// Substrate 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 Substrate. If not, see . - -use crate::codec::{self, Encode, EncodeAppend}; -use crate::rstd::{borrow::Borrow, vec::Vec}; - -/// Abstraction around storage with unhashed access. -pub trait UnhashedStorage { - /// true if the key exists in storage. - fn exists(&self, key: &[u8]) -> bool; - - /// Load the bytes of a key from storage. Can panic if the type is incorrect. - fn get(&self, key: &[u8]) -> Option; - - /// Load the bytes of a key from storage. Can panic if the type is incorrect. Will panic if - /// it's not there. - fn require(&self, key: &[u8]) -> T { - self.get(key).expect("Required values must be in storage") - } - - /// Load the bytes of a key from storage. Can panic if the type is incorrect. The type's - /// default is returned if it's not there. - fn get_or_default(&self, key: &[u8]) -> T { - self.get(key).unwrap_or_default() - } - - /// Put a value in under a key. - fn put(&mut self, key: &[u8], val: &T); - - /// Remove the bytes of a key from storage. - fn kill(&mut self, key: &[u8]); - - /// Remove the bytes of a key from storage. - fn kill_prefix(&mut self, prefix: &[u8]); - - /// Take a value from storage, deleting it after reading. - fn take(&mut self, key: &[u8]) -> Option { - let value = self.get(key); - self.kill(key); - value - } - - /// Take a value from storage, deleting it after reading. - fn take_or_panic(&mut self, key: &[u8]) -> T { - self.take(key).expect("Required values must be in storage") - } - - /// Take a value from storage, deleting it after reading. - fn take_or_default(&mut self, key: &[u8]) -> T { - self.take(key).unwrap_or_default() - } - - /// Get a Vec of bytes from storage. - fn get_raw(&self, key: &[u8]) -> Option>; - - /// Put a raw byte slice into storage. - fn put_raw(&mut self, key: &[u8], value: &[u8]); -} - -// We use a construct like this during when genesis storage is being built. -#[cfg(feature = "std")] -impl UnhashedStorage for sr_primitives::StorageOverlay { - fn exists(&self, key: &[u8]) -> bool { - self.contains_key(key) - } - - fn get(&self, key: &[u8]) -> Option { - self.get(key) - .map(|x| codec::Decode::decode(&mut x.as_slice()).expect("Unable to decode expected type.")) - } - - fn put(&mut self, key: &[u8], val: &T) { - self.insert(key.to_vec(), codec::Encode::encode(val)); - } - - fn kill(&mut self, key: &[u8]) { - self.remove(key); - } - - fn kill_prefix(&mut self, prefix: &[u8]) { - self.retain(|key, _| { - !key.starts_with(prefix) - }) - } - - fn get_raw(&self, key: &[u8]) -> Option> { - self.get(key).cloned() - } - - fn put_raw(&mut self, key: &[u8], value: &[u8]) { - self.insert(key.to_vec(), value.to_vec()); - } -} - -/// An implementation of a map with a two keys. -/// -/// It provides an important ability to efficiently remove all entries -/// that have a common first key. -/// -/// # Mapping of keys to a storage path -/// -/// The storage key (i.e. the key under which the `Value` will be stored) is created from two parts. -/// The first part is a hash of a concatenation of the `PREFIX` and `Key1`. And the second part -/// is a hash of a `Key2`. -/// -/// /!\ be careful while choosing the Hash, indeed malicious could craft second keys to lower the trie. -pub trait StorageDoubleMap { - /// The type that get/take returns. - type Query; - - /// Get the prefix key in storage. - fn prefix() -> &'static [u8]; - - /// Get the storage key used to fetch a value corresponding to a specific key. - fn key_for( - k1: &KArg1, - k2: &KArg2, - ) -> Vec where - K1: Borrow, - K2: Borrow, - KArg1: ?Sized + Encode, - KArg2: ?Sized + Encode; - - /// Get the storage prefix used to fetch keys corresponding to a specific key1. - fn prefix_for(k1: &KArg1) -> Vec where KArg1: ?Sized + Encode, K1: Borrow; - - /// true if the value is defined in storage. - fn exists( - k1: &KArg1, - k2: &KArg2, - storage: &S, - ) -> bool where K1: Borrow, K2: Borrow, KArg1: ?Sized + Encode, KArg2: ?Sized + Encode { - storage.exists(&Self::key_for(k1, k2)) - } - - /// Load the value associated with the given key from the map. - fn get( - k1: &KArg1, - k2: &KArg2, - storage: &S, - ) -> Self::Query where - K1: Borrow, - K2: Borrow, - KArg1: ?Sized + Encode, - KArg2: ?Sized + Encode; - - /// Take the value under a key. - fn take( - k1: &KArg1, - k2: &KArg2, - storage: &mut S, - ) -> Self::Query where - K1: Borrow, - K2: Borrow, - KArg1: ?Sized + Encode, - KArg2: ?Sized + Encode; - - /// Store a value to be associated with the given key from the map. - fn insert( - k1: &KArg1, - k2: &KArg2, - val: &VArg, - storage: &mut S, - ) where - K1: Borrow, - K2: Borrow, - V: Borrow, - KArg1: ?Sized + Encode, - KArg2: ?Sized + Encode, - VArg: ?Sized + Encode, - { - storage.put(&Self::key_for(k1, k2), val); - } - - /// Remove the value under a key. - fn remove( - k1: &KArg1, - k2: &KArg2, - storage: &mut S, - ) where K1: Borrow, K2: Borrow, KArg1: ?Sized + Encode, KArg2: ?Sized + Encode { - storage.kill(&Self::key_for(k1, k2)); - } - - /// Removes all entries that shares the `k1` as the first key. - fn remove_prefix( - k1: &KArg1, - storage: &mut S, - ) where KArg1: ?Sized + Encode, K1: Borrow { - storage.kill_prefix(&Self::prefix_for(k1)); - } - - /// Mutate the value under a key. - fn mutate( - k1: &KArg1, - k2: &KArg2, - f: F, - storage: &mut S, - ) -> R where - K1: Borrow, - K2: Borrow, - KArg1: ?Sized + Encode, - KArg2: ?Sized + Encode, - F: FnOnce(&mut Self::Query) -> R; - - /// Append the given items to the value under the key specified. - fn append( - k1: &KArg1, - k2: &KArg2, - items: &[I], - storage: &mut S, - ) -> Result<(), &'static str> - where - K1: Borrow, - K2: Borrow, - KArg1: ?Sized + Encode, - KArg2: ?Sized + Encode, - I: codec::Encode, - V: EncodeAppend, - { - let key = Self::key_for(k1, k2); - let new_val = ::append( - storage.get_raw(&key).unwrap_or_default(), - items, - ).map_err(|_| "Could not append given item")?; - storage.put_raw(&key, &new_val); - Ok(()) - } -} diff --git a/srml/support/src/traits.rs b/srml/support/src/traits.rs index a7d8c9e6ba0fabed83d0ce2de19bf7563f250d8c..88e61593659dca3a3a46a04dbd95e4a95fd6a963 100644 --- a/srml/support/src/traits.rs +++ b/srml/support/src/traits.rs @@ -18,13 +18,25 @@ //! //! NOTE: If you're looking for `parameter_types`, it has moved in to the top-level module. -use crate::rstd::{prelude::*, result, marker::PhantomData, ops::Div}; -use crate::codec::{Codec, Encode, Decode}; +use rstd::{prelude::*, result, marker::PhantomData, ops::Div}; +use codec::{FullCodec, Codec, Encode, Decode}; use primitives::u32_trait::Value as U32; -use crate::sr_primitives::traits::{MaybeSerializeDebug, SimpleArithmetic, Saturating}; -use crate::sr_primitives::ConsensusEngineId; +use sr_primitives::{ + ConsensusEngineId, + traits::{MaybeSerializeDebug, SimpleArithmetic, Saturating}, +}; + +/// Anything that can have a `::len()` method. +pub trait Len { + /// Return the length of data type. + fn len(&self) -> usize; +} -use super::for_each_tuple; +impl Len for T where ::IntoIter: ExactSizeIterator { + fn len(&self) -> usize { + self.clone().into_iter().len() + } +} /// A trait for querying a single fixed value from a type. pub trait Get { @@ -32,6 +44,10 @@ pub trait Get { fn get() -> T; } +impl Get for () { + fn get() -> T { T::default() } +} + /// A trait for querying whether a type can be said to statically "contain" a value. Similar /// in nature to `Get`, except it is designed to be lazy rather than active (you can't ask it to /// enumerate all values that it contains) and work for multiple values rather than just one. @@ -47,29 +63,12 @@ impl> Contains for T { } /// The account with the given id was killed. +#[impl_trait_for_tuples::impl_for_tuples(30)] pub trait OnFreeBalanceZero { /// The account was the given id was killed. fn on_free_balance_zero(who: &AccountId); } -macro_rules! impl_on_free_balance_zero { - () => ( - impl OnFreeBalanceZero for () { - fn on_free_balance_zero(_: &AccountId) {} - } - ); - - ( $($t:ident)* ) => { - impl),*> OnFreeBalanceZero for ($($t,)*) { - fn on_free_balance_zero(who: &AccountId) { - $($t::on_free_balance_zero(who);)* - } - } - } -} - -for_each_tuple!(impl_on_free_balance_zero); - /// Trait for a hook to get called when some balance has been minted, causing dilution. pub trait OnDilution { /// Some `portion` of the total balance just "grew" by `minted`. `portion` is the pre-growth @@ -117,8 +116,8 @@ pub trait VerifySeal { pub trait KeyOwnerProofSystem { /// The proof of membership itself. type Proof: Codec; - /// The full identification of a key owner. - type FullIdentification: Codec; + /// The full identification of a key owner and the stash account. + type IdentificationTuple: Codec; /// Prove membership of a key owner in the current block-state. /// @@ -131,7 +130,7 @@ pub trait KeyOwnerProofSystem { /// Check a proof of membership on-chain. Return `Some` iff the proof is /// valid and recent enough to check. - fn check_proof(key: Key, proof: Self::Proof) -> Option; + fn check_proof(key: Key, proof: Self::Proof) -> Option; } /// Handler for when some currency "account" decreased in balance for @@ -255,7 +254,7 @@ pub enum SignedImbalance>{ impl< P: Imbalance, N: Imbalance, - B: SimpleArithmetic + Codec + Copy + MaybeSerializeDebug + Default, + B: SimpleArithmetic + FullCodec + Copy + MaybeSerializeDebug + Default, > SignedImbalance { pub fn zero() -> Self { SignedImbalance::Positive(P::zero()) @@ -318,7 +317,7 @@ impl< /// Abstraction over a fungible assets system. pub trait Currency { /// The balance of an account. - type Balance: SimpleArithmetic + Codec + Copy + MaybeSerializeDebug + Default; + type Balance: SimpleArithmetic + FullCodec + Copy + MaybeSerializeDebug + Default; /// The opaque token type for an imbalance. This is returned by unbalanced operations /// and must be dealt with. It may be dropped but cannot be cloned. @@ -616,13 +615,23 @@ bitmask! { } pub trait Time { - type Moment: SimpleArithmetic + Codec + Clone + Default; + type Moment: SimpleArithmetic + FullCodec + Clone + Default + Copy; fn now() -> Self::Moment; } impl WithdrawReasons { /// Choose all variants except for `one`. + /// + /// ```rust + /// # use srml_support::traits::{WithdrawReason, WithdrawReasons}; + /// # fn main() { + /// assert_eq!( + /// WithdrawReason::Fee | WithdrawReason::Transfer | WithdrawReason::Reserve, + /// WithdrawReasons::except(WithdrawReason::TransactionPayment), + /// ); + /// # } + /// ``` pub fn except(one: WithdrawReason) -> WithdrawReasons { let mut mask = Self::all(); mask.toggle(one); @@ -652,6 +661,16 @@ pub trait ChangeMembers { /// Set the new members; they **must already be sorted**. This will compute the diff and use it to /// call `change_members_sorted`. fn set_members_sorted(new_members: &[AccountId], old_members: &[AccountId]) { + let (incoming, outgoing) = Self::compute_members_diff(new_members, old_members); + Self::change_members_sorted(&incoming[..], &outgoing[..], &new_members); + } + + /// Set the new members; they **must already be sorted**. This will compute the diff and use it to + /// call `change_members_sorted`. + fn compute_members_diff( + new_members: &[AccountId], + old_members: &[AccountId] + ) -> (Vec, Vec) { let mut old_iter = old_members.iter(); let mut new_iter = new_members.iter(); let mut incoming = Vec::new(); @@ -679,8 +698,7 @@ pub trait ChangeMembers { } } } - - Self::change_members_sorted(&incoming[..], &outgoing[..], &new_members); + (incoming, outgoing) } } @@ -698,4 +716,4 @@ pub trait InitializeMembers { impl InitializeMembers for () { fn initialize_members(_: &[T]) {} -} \ No newline at end of file +} diff --git a/srml/support/src/unsigned.rs b/srml/support/src/unsigned.rs index 1c62dd0c58435670e1e1ee3a562d2539deb0c2ac..4d2ceddd79f4aeec5500340459643c9d3d40a887 100644 --- a/srml/support/src/unsigned.rs +++ b/srml/support/src/unsigned.rs @@ -17,7 +17,7 @@ #[doc(hidden)] pub use crate::sr_primitives::traits::ValidateUnsigned; #[doc(hidden)] -pub use crate::sr_primitives::transaction_validity::TransactionValidity; +pub use crate::sr_primitives::transaction_validity::{TransactionValidity, UnknownTransaction}; #[doc(hidden)] pub use crate::sr_primitives::ApplyError; @@ -72,7 +72,7 @@ macro_rules! impl_outer_validate_unsigned { #[allow(unreachable_patterns)] match call { $( Call::$module(inner_call) => $module::validate_unsigned(inner_call), )* - _ => $crate::unsigned::TransactionValidity::Invalid($crate::unsigned::ApplyError::BadSignature as i8), + _ => $crate::unsigned::UnknownTransaction::NoUnsignedValidator.into(), } } } @@ -81,8 +81,7 @@ macro_rules! impl_outer_validate_unsigned { #[cfg(test)] mod test_empty_call { - pub enum Call { - } + pub enum Call {} #[allow(unused)] pub struct Runtime; diff --git a/srml/support/test/Cargo.toml b/srml/support/test/Cargo.toml index fa3a04d3bc32a1dfb4ec33b610eadce55081180d..bb1b3749e9d5f45c4ef8bb5359ee0ebdb7f0b19b 100644 --- a/srml/support/test/Cargo.toml +++ b/srml/support/test/Cargo.toml @@ -5,13 +5,13 @@ authors = ["Parity Technologies "] edition = "2018" [dependencies] -serde = { version = "1.0", default-features = false, features = ["derive"] } +serde = { version = "1.0.101", default-features = false, features = ["derive"] } codec = { package = "parity-scale-codec", version = "1.0.0", default-features = false, features = ["derive"] } -runtime_io = { package = "sr-io", path = "../../../core/sr-io", default-features = false } -srml-support = { version = "2", path = "../", default-features = false } +runtime-io ={ package = "sr-io", path = "../../../core/sr-io", default-features = false } +support = { package = "srml-support", version = "2", path = "../", default-features = false } inherents = { package = "substrate-inherents", path = "../../../core/inherents", default-features = false } primitives = { package = "substrate-primitives", path = "../../../core/primitives", default-features = false } -trybuild = "1" +trybuild = "1.0.14" pretty_assertions = "0.6.1" [features] @@ -19,8 +19,8 @@ default = ["std"] std = [ "serde/std", "codec/std", - "runtime_io/std", - "srml-support/std", + "runtime-io/std", + "support/std", "inherents/std", "primitives/std", ] diff --git a/srml/support/test/src/lib.rs b/srml/support/test/src/lib.rs index a7a869cf8794d7855697b6c7d3066c21b32533bb..0e4ab936291415d31d533d2fa981c4eeee7c9458 100644 --- a/srml/support/test/src/lib.rs +++ b/srml/support/test/src/lib.rs @@ -14,7 +14,7 @@ // You should have received a copy of the GNU General Public License // along with Substrate. If not, see . -//! Test crate for srml_support. Allow to make use of `srml_support::decl_storage`. +//! Test crate for srml_support. Allow to make use of `support::decl_storage`. //! See tests directory. #[test] diff --git a/srml/support/test/tests/final_keys.rs b/srml/support/test/tests/final_keys.rs index 9c770075c46493c0a4bde76d74fc520fa13b43f5..04b243ae7ce0b7cb89f5f208f1301c4018b4a039 100644 --- a/srml/support/test/tests/final_keys.rs +++ b/srml/support/test/tests/final_keys.rs @@ -14,83 +14,211 @@ // You should have received a copy of the GNU General Public License // along with Substrate. If not, see . -use runtime_io::{with_externalities, Blake2Hasher}; -use srml_support::{StorageValue, StorageMap, StorageDoubleMap}; -use srml_support::storage::unhashed; -use codec::{Encode, Decode}; - -pub trait Trait { - type Origin; - type BlockNumber: Encode + Decode + Default + Clone; -} +use runtime_io::with_storage; +use support::storage::unhashed; +use codec::Encode; +use support::{StorageDoubleMap, StorageLinkedMap, StorageMap, StorageValue}; -srml_support::decl_module! { - pub struct Module for enum Call where origin: T::Origin {} -} +mod no_instance { + use codec::{Encode, Decode, EncodeLike}; + + pub trait Trait { + type Origin; + type BlockNumber: Encode + Decode + EncodeLike + Default + Clone; + } -srml_support::decl_storage!{ - trait Store for Module as FinalKeys { - pub Value config(value): u32; + support::decl_module! { + pub struct Module for enum Call where origin: T::Origin {} + } + + support::decl_storage!{ + trait Store for Module as FinalKeysNone { + pub Value config(value): u32; - pub Map: map u32 => u32; - pub Map2: map hasher(twox_128) u32 => u32; + pub Map: map u32 => u32; + pub Map2: map hasher(twox_128) u32 => u32; - pub LinkedMap: linked_map u32 => u32; - pub LinkedMap2: linked_map hasher(twox_128) u32 => u32; + pub LinkedMap: linked_map u32 => u32; + pub LinkedMap2: linked_map hasher(twox_128) u32 => u32; - pub DoubleMap: double_map u32, blake2_256(u32) => u32; - pub DoubleMap2: double_map hasher(twox_128) u32, blake2_128(u32) => u32; + pub DoubleMap: double_map u32, blake2_256(u32) => u32; + pub DoubleMap2: double_map hasher(twox_128) u32, blake2_128(u32) => u32; - pub Foo get(foo) config(): Option; - pub Foo2 get(foo2) config(): double_map u32, blake2_256(T::BlockNumber) => Option; + pub TestGenericValue get(test_generic_value) config(): Option; + pub TestGenericDoubleMap get(foo2) config(test_generic_double_map): + double_map u32, blake2_256(T::BlockNumber) => Option; + } } } -struct Test; -impl Trait for Test { - type BlockNumber = u32; - type Origin = u32; +mod instance { + pub trait Trait: super::no_instance::Trait {} + + support::decl_module! { + pub struct Module, I: Instantiable = DefaultInstance> + for enum Call where origin: T::Origin {} + } + + support::decl_storage!{ + trait Store for Module, I: Instantiable = DefaultInstance> + as FinalKeysSome + { + pub Value config(value): u32; + + pub Map: map u32 => u32; + pub Map2: map hasher(twox_128) u32 => u32; + + pub LinkedMap: linked_map u32 => u32; + pub LinkedMap2: linked_map hasher(twox_128) u32 => u32; + + pub DoubleMap: double_map u32, blake2_256(u32) => u32; + pub DoubleMap2: double_map hasher(twox_128) u32, blake2_128(u32) => u32; + + pub TestGenericValue get(test_generic_value) config(): Option; + pub TestGenericDoubleMap get(foo2) config(test_generic_double_map): + double_map u32, blake2_256(T::BlockNumber) => Option; + } + add_extra_genesis { + // See `decl_storage` limitation. + config(phantom): core::marker::PhantomData; + } + } } -fn new_test_ext() -> runtime_io::TestExternalities { - GenesisConfig::::default().build_storage().unwrap().into() +#[test] +fn final_keys_no_instance() { + with_storage(&mut Default::default(), || { + no_instance::Value::put(1); + assert_eq!(unhashed::get::(&runtime_io::twox_128(b"FinalKeysNone Value")), Some(1u32)); + + no_instance::Map::insert(1, 2); + let mut k = b"FinalKeysNone Map".to_vec(); + k.extend(1u32.encode()); + assert_eq!(unhashed::get::(&runtime_io::blake2_256(&k)), Some(2u32)); + + no_instance::Map2::insert(1, 2); + let mut k = b"FinalKeysNone Map2".to_vec(); + k.extend(1u32.encode()); + assert_eq!(unhashed::get::(&runtime_io::twox_128(&k)), Some(2u32)); + + let head = b"head of FinalKeysNone LinkedMap".to_vec(); + assert_eq!(unhashed::get::(&runtime_io::blake2_256(&head)), None); + + no_instance::LinkedMap::insert(1, 2); + let mut k = b"FinalKeysNone LinkedMap".to_vec(); + k.extend(1u32.encode()); + assert_eq!(unhashed::get::(&runtime_io::blake2_256(&k)), Some(2u32)); + assert_eq!(unhashed::get::(&runtime_io::blake2_256(&head)), Some(1u32)); + + no_instance::LinkedMap2::insert(1, 2); + let mut k = b"FinalKeysNone LinkedMap2".to_vec(); + k.extend(1u32.encode()); + assert_eq!(unhashed::get::(&runtime_io::twox_128(&k)), Some(2u32)); + + no_instance::DoubleMap::insert(&1, &2, &3); + let mut k = b"FinalKeysNone DoubleMap".to_vec(); + k.extend(1u32.encode()); + let mut k = runtime_io::blake2_256(&k).to_vec(); + k.extend(&runtime_io::blake2_256(&2u32.encode())); + assert_eq!(unhashed::get::(&k), Some(3u32)); + + no_instance::DoubleMap2::insert(&1, &2, &3); + let mut k = b"FinalKeysNone DoubleMap2".to_vec(); + k.extend(1u32.encode()); + let mut k = runtime_io::twox_128(&k).to_vec(); + k.extend(&runtime_io::blake2_128(&2u32.encode())); + assert_eq!(unhashed::get::(&k), Some(3u32)); + }); } #[test] -fn final_keys() { - with_externalities(&mut new_test_ext(), || { - Value::put(1); - assert_eq!(unhashed::get::(&runtime_io::twox_128(b"FinalKeys Value")), Some(1u32)); +fn final_keys_default_instance() { + with_storage(&mut Default::default(), || { + >::put(1); + assert_eq!(unhashed::get::(&runtime_io::twox_128(b"FinalKeysSome Value")), Some(1u32)); + + >::insert(1, 2); + let mut k = b"FinalKeysSome Map".to_vec(); + k.extend(1u32.encode()); + assert_eq!(unhashed::get::(&runtime_io::blake2_256(&k)), Some(2u32)); + + >::insert(1, 2); + let mut k = b"FinalKeysSome Map2".to_vec(); + k.extend(1u32.encode()); + assert_eq!(unhashed::get::(&runtime_io::twox_128(&k)), Some(2u32)); - Map::insert(1, 2); - let mut k = b"FinalKeys Map".to_vec(); + let head = b"head of FinalKeysSome LinkedMap".to_vec(); + assert_eq!(unhashed::get::(&runtime_io::blake2_256(&head)), None); + + >::insert(1, 2); + let mut k = b"FinalKeysSome LinkedMap".to_vec(); k.extend(1u32.encode()); assert_eq!(unhashed::get::(&runtime_io::blake2_256(&k)), Some(2u32)); + assert_eq!(unhashed::get::(&runtime_io::blake2_256(&head)), Some(1u32)); - Map2::insert(1, 2); - let mut k = b"FinalKeys Map2".to_vec(); +< instance::LinkedMap2>::insert(1, 2); + let mut k = b"FinalKeysSome LinkedMap2".to_vec(); k.extend(1u32.encode()); assert_eq!(unhashed::get::(&runtime_io::twox_128(&k)), Some(2u32)); - LinkedMap::insert(1, 2); - let mut k = b"FinalKeys LinkedMap".to_vec(); + >::insert(&1, &2, &3); + let mut k = b"FinalKeysSome DoubleMap".to_vec(); + k.extend(1u32.encode()); + let mut k = runtime_io::blake2_256(&k).to_vec(); + k.extend(&runtime_io::blake2_256(&2u32.encode())); + assert_eq!(unhashed::get::(&k), Some(3u32)); + + >::insert(&1, &2, &3); + let mut k = b"FinalKeysSome DoubleMap2".to_vec(); + k.extend(1u32.encode()); + let mut k = runtime_io::twox_128(&k).to_vec(); + k.extend(&runtime_io::blake2_128(&2u32.encode())); + assert_eq!(unhashed::get::(&k), Some(3u32)); + }); +} + +#[test] +fn final_keys_instance_2() { + with_storage(&mut Default::default(), || { + >::put(1); + assert_eq!( + unhashed::get::(&runtime_io::twox_128(b"Instance2FinalKeysSome Value")), + Some(1u32) + ); + + >::insert(1, 2); + let mut k = b"Instance2FinalKeysSome Map".to_vec(); + k.extend(1u32.encode()); + assert_eq!(unhashed::get::(&runtime_io::blake2_256(&k)), Some(2u32)); + + >::insert(1, 2); + let mut k = b"Instance2FinalKeysSome Map2".to_vec(); + k.extend(1u32.encode()); + assert_eq!(unhashed::get::(&runtime_io::twox_128(&k)), Some(2u32)); + + let head = b"head of Instance2FinalKeysSome LinkedMap".to_vec(); + assert_eq!(unhashed::get::(&runtime_io::blake2_256(&head)), None); + + >::insert(1, 2); + let mut k = b"Instance2FinalKeysSome LinkedMap".to_vec(); k.extend(1u32.encode()); assert_eq!(unhashed::get::(&runtime_io::blake2_256(&k)), Some(2u32)); + assert_eq!(unhashed::get::(&runtime_io::blake2_256(&head)), Some(1u32)); - LinkedMap2::insert(1, 2); - let mut k = b"FinalKeys LinkedMap2".to_vec(); + >::insert(1, 2); + let mut k = b"Instance2FinalKeysSome LinkedMap2".to_vec(); k.extend(1u32.encode()); assert_eq!(unhashed::get::(&runtime_io::twox_128(&k)), Some(2u32)); - DoubleMap::insert(&1, &2, &3); - let mut k = b"FinalKeys DoubleMap".to_vec(); + >::insert(&1, &2, &3); + let mut k = b"Instance2FinalKeysSome DoubleMap".to_vec(); k.extend(1u32.encode()); let mut k = runtime_io::blake2_256(&k).to_vec(); k.extend(&runtime_io::blake2_256(&2u32.encode())); assert_eq!(unhashed::get::(&k), Some(3u32)); - DoubleMap2::insert(&1, &2, &3); - let mut k = b"FinalKeys DoubleMap2".to_vec(); + >::insert(&1, &2, &3); + let mut k = b"Instance2FinalKeysSome DoubleMap2".to_vec(); k.extend(1u32.encode()); let mut k = runtime_io::twox_128(&k).to_vec(); k.extend(&runtime_io::blake2_128(&2u32.encode())); diff --git a/srml/support/test/tests/genesisconfig.rs b/srml/support/test/tests/genesisconfig.rs index b190fa8b747f3e161ff956930bbcc86689f2fea1..e945c774c0d07e97cc5186316fe77425748d2d23 100644 --- a/srml/support/test/tests/genesisconfig.rs +++ b/srml/support/test/tests/genesisconfig.rs @@ -15,18 +15,18 @@ // along with Substrate. If not, see . pub trait Trait { - type BlockNumber: codec::Codec + Default; - type Origin; + type BlockNumber: codec::Codec + codec::EncodeLike + Default; + type Origin; } -srml_support::decl_module! { - pub struct Module for enum Call where origin: T::Origin {} +support::decl_module! { + pub struct Module for enum Call where origin: T::Origin {} } -srml_support::decl_storage! { - trait Store for Module as Example { - pub AppendableDM config(t): double_map u32, blake2_256(T::BlockNumber) => Vec; - } +support::decl_storage! { + trait Store for Module as Example { + pub AppendableDM config(t): double_map u32, blake2_256(T::BlockNumber) => Vec; + } } struct Test; diff --git a/srml/support/test/tests/instance.rs b/srml/support/test/tests/instance.rs index 440fb9e779996b5ae5e7ce77bb5cb3787731e2a7..da4e73e71017a1bdacf30abafadfa216c7c41788 100644 --- a/srml/support/test/tests/instance.rs +++ b/srml/support/test/tests/instance.rs @@ -15,20 +15,20 @@ // along with Substrate. If not, see . #![recursion_limit="128"] -use runtime_io::{with_externalities, Blake2Hasher}; -use srml_support::{ +use runtime_io::with_externalities; +use support::{ Parameter, traits::Get, parameter_types, sr_primitives::{generic, BuildStorage, traits::{BlakeTwo256, Block as _, Verify}}, metadata::{ DecodeDifferent, StorageMetadata, StorageEntryModifier, StorageEntryType, DefaultByteGetter, StorageEntryMetadata, StorageHasher }, + StorageValue, StorageMap, StorageLinkedMap, StorageDoubleMap, }; use inherents::{ ProvideInherent, InherentData, InherentIdentifier, RuntimeString, MakeFatalError }; -use srml_support::{StorageValue, StorageMap, StorageDoubleMap, EnumerableStorageMap}; -use primitives::{H256, sr25519}; +use primitives::{H256, sr25519, Blake2Hasher}; mod system; @@ -45,17 +45,17 @@ mod module1 { type Event: From> + Into<::Event>; type Origin: From>; type SomeParameter: Get; - type GenericType: Default + Clone + codec::Codec; + type GenericType: Default + Clone + codec::Codec + codec::EncodeLike; } - srml_support::decl_module! { + support::decl_module! { pub struct Module, I: InstantiableThing> for enum Call where origin: ::Origin, T::BlockNumber: From { fn offchain_worker() {} - fn deposit_event() = default; + fn deposit_event() = default; fn one(origin) { system::ensure_root(origin)?; @@ -64,7 +64,7 @@ mod module1 { } } - srml_support::decl_storage! { + support::decl_storage! { trait Store for Module, I: InstantiableThing> as Module1 where T::BlockNumber: From + std::fmt::Display { @@ -75,13 +75,13 @@ mod module1 { add_extra_genesis { config(test) : T::BlockNumber; - build(|_, config: &Self| { + build(|config: &Self| { println!("{}", config.test); }); } } - srml_support::decl_event! { + support::decl_event! { pub enum Event where Phantom = std::marker::PhantomData { _Phantom(Phantom), AnotherVariant(u32), @@ -128,15 +128,15 @@ mod module2 { impl, I: Instance> Currency for Module {} - srml_support::decl_module! { + support::decl_module! { pub struct Module, I: Instance=DefaultInstance> for enum Call where origin: ::Origin { - fn deposit_event() = default; + fn deposit_event() = default; } } - srml_support::decl_storage! { + support::decl_storage! { trait Store for Module, I: Instance=DefaultInstance> as Module2 { pub Value config(value): T::Amount; pub Map config(map): map u64 => u64; @@ -145,7 +145,7 @@ mod module2 { } } - srml_support::decl_event! { + support::decl_event! { pub enum Event where Amount = >::Amount { Variant(Amount), } @@ -185,7 +185,7 @@ mod module3 { type Currency2: Currency; } - srml_support::decl_module! { + support::decl_module! { pub struct Module for enum Call where origin: ::Origin {} } } @@ -244,7 +244,7 @@ impl system::Trait for Runtime { type Event = Event; } -srml_support::construct_runtime!( +support::construct_runtime!( pub enum Runtime where Block = Block, NodeBlock = Block, @@ -304,53 +304,27 @@ fn new_test_ext() -> runtime_io::TestExternalities { #[test] fn storage_instance_independance() { - with_externalities(&mut new_test_ext(), || { - let mut map = std::collections::btree_map::BTreeMap::new(); - for key in [ - module2::Value::::key().to_vec(), - module2::Value::::key().to_vec(), - module2::Value::::key().to_vec(), - module2::Value::::key().to_vec(), - module2::Map::::prefix().to_vec(), - module2::Map::::prefix().to_vec(), - module2::Map::::prefix().to_vec(), - module2::Map::::prefix().to_vec(), - module2::LinkedMap::::prefix().to_vec(), - module2::LinkedMap::::prefix().to_vec(), - module2::LinkedMap::::prefix().to_vec(), - module2::LinkedMap::::prefix().to_vec(), - module2::DoubleMap::::prefix().to_vec(), - module2::DoubleMap::::prefix().to_vec(), - module2::DoubleMap::::prefix().to_vec(), - module2::DoubleMap::::prefix().to_vec(), - module2::Map::::key_for(0), - module2::Map::::key_for(0).to_vec(), - module2::Map::::key_for(0).to_vec(), - module2::Map::::key_for(0).to_vec(), - module2::LinkedMap::::key_for(0), - module2::LinkedMap::::key_for(0).to_vec(), - module2::LinkedMap::::key_for(0).to_vec(), - module2::LinkedMap::::key_for(0).to_vec(), - module2::Map::::key_for(1), - module2::Map::::key_for(1).to_vec(), - module2::Map::::key_for(1).to_vec(), - module2::Map::::key_for(1).to_vec(), - module2::LinkedMap::::key_for(1), - module2::LinkedMap::::key_for(1).to_vec(), - module2::LinkedMap::::key_for(1).to_vec(), - module2::LinkedMap::::key_for(1).to_vec(), - module2::DoubleMap::::prefix_for(&1), - module2::DoubleMap::::prefix_for(&1).to_vec(), - module2::DoubleMap::::prefix_for(&1).to_vec(), - module2::DoubleMap::::prefix_for(&1).to_vec(), - module2::DoubleMap::::key_for(&1, &1), - module2::DoubleMap::::key_for(&1, &1).to_vec(), - module2::DoubleMap::::key_for(&1, &1).to_vec(), - module2::DoubleMap::::key_for(&1, &1).to_vec(), - ].iter() { - assert!(map.insert(key, ()).is_none()) - } + let mut storage = (std::collections::HashMap::new(), std::collections::HashMap::new()); + runtime_io::with_storage(&mut storage, || { + module2::Value::::put(0); + module2::Value::::put(0); + module2::Value::::put(0); + module2::Value::::put(0); + module2::Map::::insert(0, 0); + module2::Map::::insert(0, 0); + module2::Map::::insert(0, 0); + module2::Map::::insert(0, 0); + module2::LinkedMap::::insert::<_, Vec>(0, vec![]); + module2::LinkedMap::::insert::<_, Vec>(0, vec![]); + module2::LinkedMap::::insert::<_, Vec>(0, vec![]); + module2::LinkedMap::::insert::<_, Vec>(0, vec![]); + module2::DoubleMap::::insert(&0, &0, &0); + module2::DoubleMap::::insert(&0, &0, &0); + module2::DoubleMap::::insert(&0, &0, &0); + module2::DoubleMap::::insert(&0, &0, &0); }); + // 16 storage values + 4 linked_map head. + assert_eq!(storage.0.len(), 16 + 4); } #[test] @@ -403,7 +377,7 @@ fn storage_with_instance_basic_operation() { assert_eq!(LinkedMap::get(key), vec![]); assert_eq!(LinkedMap::exists(key), false); assert_eq!(LinkedMap::enumerate().count(), 1); - LinkedMap::insert_ref(key, &vec![1]); + LinkedMap::insert(key, &vec![1]); assert_eq!(LinkedMap::enumerate().count(), 2); let key1 = 1; diff --git a/srml/support/test/tests/issue2219.rs b/srml/support/test/tests/issue2219.rs index cb8b4cef09f0d61ed7b6ea79c6a72a76d385dfad..28bd9463ffa9cfd41ac5061cdb7c27bf70ecbf5f 100644 --- a/srml/support/test/tests/issue2219.rs +++ b/srml/support/test/tests/issue2219.rs @@ -14,9 +14,9 @@ // You should have received a copy of the GNU General Public License // along with Substrate. If not, see . -use srml_support::sr_primitives::generic; -use srml_support::sr_primitives::traits::{BlakeTwo256, Block as _, Verify}; -use srml_support::codec::{Encode, Decode}; +use support::sr_primitives::generic; +use support::sr_primitives::traits::{BlakeTwo256, Block as _, Verify}; +use support::codec::{Encode, Decode}; use primitives::{H256, sr25519}; use serde::{Serialize, Deserialize}; @@ -82,7 +82,7 @@ mod module { pub trait Trait: system::Trait {} - srml_support::decl_module! { + support::decl_module! { pub struct Module for enum Call where origin: T::Origin {} } @@ -99,7 +99,7 @@ mod module { } } - srml_support::decl_storage! { + support::decl_storage! { trait Store for Module as Actors { /// requirements to enter and maintain status in roles pub Parameters get(parameters) build(|config: &GenesisConfig| { @@ -164,7 +164,7 @@ impl system::Trait for Runtime { impl module::Trait for Runtime {} -srml_support::construct_runtime!( +support::construct_runtime!( pub enum Runtime where Block = Block, NodeBlock = Block, diff --git a/srml/support/test/tests/reserved_keyword/on_initialize.rs b/srml/support/test/tests/reserved_keyword/on_initialize.rs index f9c2f5f7f0e5add4bdf3358e3330fec4123321eb..f9604c9487a9eb5098734071dd5740d6ec74f6fe 100644 --- a/srml/support/test/tests/reserved_keyword/on_initialize.rs +++ b/srml/support/test/tests/reserved_keyword/on_initialize.rs @@ -2,7 +2,7 @@ macro_rules! reserved { ($($reserved:ident)*) => { $( mod $reserved { - pub use srml_support::dispatch::Result; + pub use support::dispatch::Result; pub trait Trait { type Origin; @@ -10,14 +10,14 @@ macro_rules! reserved { } pub mod system { - use srml_support::dispatch::Result; + use support::dispatch::Result; pub fn ensure_root(_: R) -> Result { Ok(()) } } - srml_support::decl_module! { + support::decl_module! { pub struct Module for enum Call where origin: T::Origin { fn $reserved(_origin) -> Result { unreachable!() } } @@ -29,5 +29,4 @@ macro_rules! reserved { reserved!(on_finalize on_initialize on_finalise on_initialise offchain_worker deposit_event); -fn main() { -} +fn main() {} diff --git a/srml/support/test/tests/reserved_keyword/on_initialize.stderr b/srml/support/test/tests/reserved_keyword/on_initialize.stderr index 7a37eb66c32acd89f96ef45fa3a88dd9724030c1..13c2ef8d2c8691b7a6a576612683e9c3f963671a 100644 --- a/srml/support/test/tests/reserved_keyword/on_initialize.stderr +++ b/srml/support/test/tests/reserved_keyword/on_initialize.stderr @@ -14,7 +14,7 @@ error: Invalid call fn name: `on_initialize`, name is reserved and doesn't match | = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info) -error: Invalid call fn name: `on_finalise`, name is reserved and doesn't match expected signature, please refer to `decl_module!` documentation to see the appropriate usage, or rename it to an unreserved keyword. +error: `on_finalise` was renamed to `on_finalize`. Please rename your function accordingly. --> $DIR/on_initialize.rs:30:1 | 30 | reserved!(on_finalize on_initialize on_finalise on_initialise offchain_worker deposit_event); @@ -22,7 +22,7 @@ error: Invalid call fn name: `on_finalise`, name is reserved and doesn't match e | = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info) -error: Invalid call fn name: `on_initialise`, name is reserved and doesn't match expected signature, please refer to `decl_module!` documentation to see the appropriate usage, or rename it to an unreserved keyword. +error: `on_initialise` was renamed to `on_initialize`. Please rename your function accordingly. --> $DIR/on_initialize.rs:30:1 | 30 | reserved!(on_finalize on_initialize on_finalise on_initialise offchain_worker deposit_event); @@ -38,7 +38,7 @@ error: Invalid call fn name: `offchain_worker`, name is reserved and doesn't mat | = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info) -error: Invalid call fn name: `deposit_event`, name is reserved and doesn't match expected signature, please refer to `decl_module!` documentation to see the appropriate usage, or rename it to an unreserved keyword. +error: `deposit_event` function is reserved and must follow the syntax: `$vis:vis fn deposit_event() = default;` --> $DIR/on_initialize.rs:30:1 | 30 | reserved!(on_finalize on_initialize on_finalise on_initialise offchain_worker deposit_event); diff --git a/srml/support/test/tests/system.rs b/srml/support/test/tests/system.rs index 6483161211afcc3ab232c8d1fcfa2e71dce6e215..1040b26cc61268cc9c20b91a794dec14c93bd1ff 100644 --- a/srml/support/test/tests/system.rs +++ b/srml/support/test/tests/system.rs @@ -1,29 +1,39 @@ -use srml_support::codec::{Encode, Decode}; +use support::codec::{Encode, Decode, EncodeLike}; pub trait Trait: 'static + Eq + Clone { type Origin: Into, Self::Origin>> + From>; - type BlockNumber: Decode + Encode + Clone + Default; + type BlockNumber: Decode + Encode + EncodeLike + Clone + Default; type Hash; - type AccountId: Encode + Decode; + type AccountId: Encode + EncodeLike + Decode; type Event: From; } -srml_support::decl_module! { +support::decl_module! { pub struct Module for enum Call where origin: T::Origin { - pub fn deposit_event(_event: T::Event) { - } } } -srml_support::decl_event!( +impl Module { + pub fn deposit_event(_event: impl Into) { + } +} + +support::decl_event!( pub enum Event { ExtrinsicSuccess, ExtrinsicFailed, } ); +support::decl_error! { + pub enum Error { + TestError, + AnotherError + } +} + /// Origin for the system module. #[derive(PartialEq, Eq, Clone)] #[cfg_attr(feature = "std", derive(Debug))] @@ -49,4 +59,4 @@ pub fn ensure_root(o: OuterOrigin) -> Result<(), &'stati where OuterOrigin: Into, OuterOrigin>> { o.into().map(|_| ()).map_err(|_| "bad origin: expected to be a root origin") -} \ No newline at end of file +} diff --git a/srml/system/Cargo.toml b/srml/system/Cargo.toml index 98165556216fc344ae75289fd099d614c486fa06..a9ce6b3f8c830a7dc7313bad0e6c4fd2342cf78b 100644 --- a/srml/system/Cargo.toml +++ b/srml/system/Cargo.toml @@ -5,17 +5,19 @@ authors = ["Parity Technologies "] edition = "2018" [dependencies] -serde = { version = "1.0", optional = true, features = ["derive"] } -safe-mix = { version = "1.0", default-features = false} +serde = { version = "1.0.101", optional = true, features = ["derive"] } +safe-mix = { version = "1.0.0", default-features = false } codec = { package = "parity-scale-codec", version = "1.0.0", default-features = false, features = ["derive"] } primitives = { package = "substrate-primitives", path = "../../core/primitives", default-features = false } rstd = { package = "sr-std", path = "../../core/sr-std", default-features = false } -runtime_io = { package = "sr-io", path = "../../core/sr-io", default-features = false } +runtime-io ={ package = "sr-io", path = "../../core/sr-io", default-features = false } sr-primitives = { path = "../../core/sr-primitives", default-features = false } -srml-support = { path = "../support", default-features = false } +sr-version = { path = "../../core/sr-version", default-features = false } +support = { package = "srml-support", path = "../support", default-features = false } +impl-trait-for-tuples = "0.1.2" [dev-dependencies] -criterion = "0.2" +criterion = "0.2.11" [features] default = ["std"] @@ -25,9 +27,10 @@ std = [ "codec/std", "primitives/std", "rstd/std", - "runtime_io/std", - "srml-support/std", + "runtime-io/std", + "support/std", "sr-primitives/std", + "sr-version/std", ] [[bench]] diff --git a/srml/system/benches/bench.rs b/srml/system/benches/bench.rs index 521123118d274a00f5708a96099d2f0a460f8227..b24e52f45720bbd7c43d01dc50e12653cf2a3191 100644 --- a/srml/system/benches/bench.rs +++ b/srml/system/benches/bench.rs @@ -16,9 +16,9 @@ use criterion::{Criterion, criterion_group, criterion_main, black_box}; use srml_system as system; -use srml_support::{decl_module, decl_event, impl_outer_origin, impl_outer_event}; -use runtime_io::{with_externalities, Blake2Hasher}; -use primitives::H256; +use support::{decl_module, decl_event, impl_outer_origin, impl_outer_event}; +use runtime_io::with_externalities; +use primitives::{H256, Blake2Hasher}; use sr_primitives::{Perbill, traits::{BlakeTwo256, IdentityLookup}, testing::Header}; mod module { @@ -51,7 +51,7 @@ impl_outer_event! { } } -srml_support::parameter_types! { +support::parameter_types! { pub const BlockHashCount: u64 = 250; pub const MaximumBlockWeight: u32 = 4 * 1024 * 1024; pub const MaximumBlockLength: u32 = 4 * 1024 * 1024; @@ -75,6 +75,7 @@ impl system::Trait for Runtime { type MaximumBlockWeight = MaximumBlockWeight; type MaximumBlockLength = MaximumBlockLength; type AvailableBlockRatio = AvailableBlockRatio; + type Version = (); } impl module::Trait for Runtime { diff --git a/srml/system/src/lib.rs b/srml/system/src/lib.rs index 1d17ef2b1c9861f0cbd47a4a2ddd58f925c9966b..5a1115b90d71ce04a040fef378612f20fcc9bcb2 100644 --- a/srml/system/src/lib.rs +++ b/srml/system/src/lib.rs @@ -42,6 +42,23 @@ //! //! See the [`Module`](./struct.Module.html) struct for details of publicly available functions. //! +//! ### Signed Extensions +//! +//! The system module defines the following extensions: +//! +//! - [`CheckWeight`]: Checks the weight and length of the block and ensure that it does not +//! exceed the limits. +//! - ['CheckNonce']: Checks the nonce of the transaction. Contains a single payload of type +//! `T::Index`. +//! - [`CheckEra`]: Checks the era of the transaction. Contains a single payload of type `Era`. +//! - [`CheckGenesis`]: Checks the provided genesis hash of the transaction. Must be a part of the +//! signed payload of the transaction. +//! - [`CheckVersion`]: Checks that the runtime version is the same as the one encoded in the +//! transaction. +//! +//! Lookup the runtime aggregator file (e.g. `node/runtime`) to see the full list of signed +//! extensions included in a chain. +//! //! ## Usage //! //! ### Prerequisites @@ -51,7 +68,7 @@ //! ### Example - Get random seed and extrinsic count for the current block //! //! ``` -//! use srml_support::{decl_module, dispatch::Result}; +//! use support::{decl_module, dispatch::Result}; //! use srml_system::{self as system, ensure_signed}; //! //! pub trait Trait: system::Trait {} @@ -77,56 +94,44 @@ use rstd::prelude::*; #[cfg(any(feature = "std", test))] use rstd::map; use rstd::marker::PhantomData; -use sr_primitives::generic::{self, Era}; -use sr_primitives::Perbill; -use sr_primitives::weights::{ - Weight, DispatchInfo, DispatchClass, WeightMultiplier, SimpleDispatchInfo -}; -use sr_primitives::transaction_validity::{ - ValidTransaction, TransactionPriority, TransactionLongevity -}; -use sr_primitives::traits::{self, CheckEqual, SimpleArithmetic, Zero, SignedExtension, Convert, - SimpleBitOps, Hash, Member, MaybeDisplay, EnsureOrigin, DispatchError, SaturatedConversion, - MaybeSerializeDebugButNotDeserialize, MaybeSerializeDebug, StaticLookup, One, Bounded, Lookup, +use sr_version::RuntimeVersion; +use sr_primitives::{ + generic::{self, Era}, Perbill, ApplyError, ApplyOutcome, DispatchError, + weights::{Weight, DispatchInfo, DispatchClass, WeightMultiplier, SimpleDispatchInfo}, + transaction_validity::{ + ValidTransaction, TransactionPriority, TransactionLongevity, TransactionValidityError, + InvalidTransaction, TransactionValidity, + }, + traits::{ + self, CheckEqual, SimpleArithmetic, Zero, SignedExtension, Convert, Lookup, LookupError, + SimpleBitOps, Hash, Member, MaybeDisplay, EnsureOrigin, SaturatedConversion, + MaybeSerializeDebugButNotDeserialize, MaybeSerializeDebug, StaticLookup, One, Bounded, + }, }; + use primitives::storage::well_known_keys; -use srml_support::{ - storage, decl_module, decl_event, decl_storage, StorageDoubleMap, StorageValue, StorageMap, - Parameter, for_each_tuple, traits::{Contains, Get} +use support::{ + decl_module, decl_event, decl_storage, decl_error, storage, Parameter, + traits::{Contains, Get}, }; use safe_mix::TripletMix; use codec::{Encode, Decode}; #[cfg(any(feature = "std", test))] -use runtime_io::{twox_128, TestExternalities, Blake2Hasher}; +use runtime_io::TestExternalities; #[cfg(any(feature = "std", test))] -use primitives::ChangesTrieConfiguration; +use primitives::{ChangesTrieConfiguration, Blake2Hasher}; + +pub mod offchain; /// Handler for when a new account has been created. +#[impl_trait_for_tuples::impl_for_tuples(30)] pub trait OnNewAccount { /// A new account `who` has been registered. fn on_new_account(who: &AccountId); } -macro_rules! impl_on_new_account { - () => ( - impl OnNewAccount for () { - fn on_new_account(_: &AccountId) {} - } - ); - - ( $($t:ident)* ) => { - impl),*> OnNewAccount for ($($t,)*) { - fn on_new_account(who: &AccountId) { - $($t::on_new_account(who);)* - } - } - } -} - -for_each_tuple!(impl_on_new_account); - /// Determiner to say whether a given account is unused. pub trait IsDeadAccount { /// Is the given account dead? @@ -146,8 +151,7 @@ pub fn extrinsics_root(extrinsics: &[E]) -> H::Output /// Compute the trie root of a list of extrinsics. pub fn extrinsics_data_root(xts: Vec>) -> H::Output { - let xts = xts.iter().map(Vec::as_slice).collect::>(); - H::ordered_trie_root(&xts) + H::ordered_trie_root(xts) } pub trait Trait: 'static + Eq + Clone { @@ -216,6 +220,8 @@ pub trait Trait: 'static + Eq + Clone { /// module, including weight and length. type AvailableBlockRatio: Get; + /// Get the chain's current version. + type Version: Get; } pub type DigestOf = generic::Digest<::Hash>; @@ -226,10 +232,7 @@ pub type KeyValue = (Vec, Vec); decl_module! { pub struct Module for enum Call where origin: T::Origin { - /// Deposits an event into this block's event record. - pub fn deposit_event(event: T::Event) { - Self::deposit_event_indexed(&[], event); - } + type Error = Error; /// A big dispatch that will disallow any other transaction to be included. // TODO: this must be preferable available for testing really (not possible at the moment). @@ -275,6 +278,13 @@ decl_module! { storage::unhashed::kill(&key); } } + + /// Kill all storage items with a key that starts with the given prefix. + #[weight = SimpleDispatchInfo::FixedOperational(10_000)] + fn kill_prefix(origin, prefix: Key) { + ensure_root(origin)?; + storage::unhashed::kill_prefix(&prefix); + } } } @@ -306,10 +316,21 @@ decl_event!( /// An extrinsic completed successfully. ExtrinsicSuccess, /// An extrinsic failed. - ExtrinsicFailed, + ExtrinsicFailed(DispatchError), } ); +decl_error! { + /// Error for the System module + pub enum Error { + BadSignature, + BlockFull, + RequireSignedOrigin, + RequireRootOrigin, + RequireNoOrigin, + } +} + /// Origin for the System module. #[derive(PartialEq, Eq, Clone)] #[cfg_attr(feature = "std", derive(Debug))] @@ -410,25 +431,23 @@ decl_storage! { #[serde(with = "primitives::bytes")] config(code): Vec; - build( - |storage: &mut (sr_primitives::StorageOverlay, sr_primitives::ChildrenStorageOverlay), - config: &GenesisConfig| - { + build(|config: &GenesisConfig| { use codec::Encode; - storage.0.insert(well_known_keys::CODE.to_vec(), config.code.clone()); - storage.0.insert(well_known_keys::EXTRINSIC_INDEX.to_vec(), 0u32.encode()); + runtime_io::set_storage(well_known_keys::CODE, &config.code); + runtime_io::set_storage(well_known_keys::EXTRINSIC_INDEX, &0u32.encode()); if let Some(ref changes_trie_config) = config.changes_trie_config { - storage.0.insert( - well_known_keys::CHANGES_TRIE_CONFIG.to_vec(), - changes_trie_config.encode()); + runtime_io::set_storage( + well_known_keys::CHANGES_TRIE_CONFIG, + &changes_trie_config.encode(), + ); } }); } } -pub struct EnsureRoot(::rstd::marker::PhantomData); +pub struct EnsureRoot(rstd::marker::PhantomData); impl< O: Into, O>> + From>, AccountId, @@ -442,7 +461,7 @@ impl< } } -pub struct EnsureSigned(::rstd::marker::PhantomData); +pub struct EnsureSigned(rstd::marker::PhantomData); impl< O: Into, O>> + From>, AccountId, @@ -456,7 +475,7 @@ impl< } } -pub struct EnsureSignedBy(::rstd::marker::PhantomData<(Who, AccountId)>); +pub struct EnsureSignedBy(rstd::marker::PhantomData<(Who, AccountId)>); impl< O: Into, O>> + From>, Who: Contains, @@ -471,7 +490,7 @@ impl< } } -pub struct EnsureNone(::rstd::marker::PhantomData); +pub struct EnsureNone(rstd::marker::PhantomData); impl< O: Into, O>> + From>, AccountId, @@ -485,7 +504,7 @@ impl< } } -pub struct EnsureNever(::rstd::marker::PhantomData); +pub struct EnsureNever(rstd::marker::PhantomData); impl EnsureOrigin for EnsureNever { type Success = T; fn try_origin(o: O) -> Result { @@ -495,36 +514,41 @@ impl EnsureOrigin for EnsureNever { /// Ensure that the origin `o` represents a signed extrinsic (i.e. transaction). /// Returns `Ok` with the account that signed the extrinsic or an `Err` otherwise. -pub fn ensure_signed(o: OuterOrigin) -> Result +pub fn ensure_signed(o: OuterOrigin) -> Result where OuterOrigin: Into, OuterOrigin>> { match o.into() { Ok(RawOrigin::Signed(t)) => Ok(t), - _ => Err("bad origin: expected to be a signed origin"), + _ => Err(Error::RequireSignedOrigin), } } /// Ensure that the origin `o` represents the root. Returns `Ok` or an `Err` otherwise. -pub fn ensure_root(o: OuterOrigin) -> Result<(), &'static str> +pub fn ensure_root(o: OuterOrigin) -> Result<(), Error> where OuterOrigin: Into, OuterOrigin>> { match o.into() { Ok(RawOrigin::Root) => Ok(()), - _ => Err("bad origin: expected to be a root origin"), + _ => Err(Error::RequireRootOrigin), } } /// Ensure that the origin `o` represents an unsigned extrinsic. Returns `Ok` or an `Err` otherwise. -pub fn ensure_none(o: OuterOrigin) -> Result<(), &'static str> +pub fn ensure_none(o: OuterOrigin) -> Result<(), Error> where OuterOrigin: Into, OuterOrigin>> { match o.into() { Ok(RawOrigin::None) => Ok(()), - _ => Err("bad origin: expected to be no origin"), + _ => Err(Error::RequireNoOrigin), } } impl Module { + /// Deposits an event into this block's event record. + pub fn deposit_event(event: impl Into) { + Self::deposit_event_indexed(&[], event.into()); + } + /// Deposits an event into this block's event record adding this event /// to the corresponding topic indexes. /// @@ -558,7 +582,7 @@ impl Module { // We perform early return if we've reached the maximum capacity of the event list, // so `Events` seems to be corrupted. Also, this has happened after the start of execution // (since the event list is cleared at the block initialization). - if >::append(&[event]).is_err() { + if >::append([event].into_iter()).is_err() { // The most sensible thing to do here is to just ignore this event and wait until the // new block. return; @@ -683,9 +707,9 @@ impl Module { #[cfg(any(feature = "std", test))] pub fn externalities() -> TestExternalities { TestExternalities::new((map![ - twox_128(&>::key_for(T::BlockNumber::zero())).to_vec() => [69u8; 32].encode(), - twox_128(>::key()).to_vec() => T::BlockNumber::one().encode(), - twox_128(>::key()).to_vec() => [69u8; 32].encode() + >::hashed_key_for(T::BlockNumber::zero()) => [69u8; 32].encode(), + >::hashed_key().to_vec() => T::BlockNumber::one().encode(), + >::hashed_key().to_vec() => [69u8; 32].encode() ], map![])) } @@ -709,6 +733,9 @@ impl Module { >::put(n); } + /// Return the chain's current runtime version. + pub fn runtime_version() -> RuntimeVersion { T::Version::get() } + /// Get the basic random seed. /// /// In general you won't want to use this, but rather `Self::random` which @@ -788,11 +815,13 @@ impl Module { } /// To be called immediately after an extrinsic has been applied. - pub fn note_applied_extrinsic(r: &Result<(), &'static str>, _encoded_len: u32) { - Self::deposit_event(match r { - Ok(_) => Event::ExtrinsicSuccess, - Err(_) => Event::ExtrinsicFailed, - }.into()); + pub fn note_applied_extrinsic(r: &ApplyOutcome, _encoded_len: u32) { + Self::deposit_event( + match r { + Ok(()) => Event::ExtrinsicSuccess, + Err(err) => Event::ExtrinsicFailed(err.clone()), + } + ); let next_extrinsic_index = Self::extrinsic_index().unwrap_or_default() + 1u32; @@ -821,7 +850,6 @@ impl Module { pub struct CheckWeight(PhantomData); impl CheckWeight { - /// Get the quota ratio of each dispatch class type. This indicates that all operational /// dispatches can use the full capacity of any resource, while user-triggered ones can consume /// a portion. @@ -836,31 +864,33 @@ impl CheckWeight { /// Checks if the current extrinsic can fit into the block with respect to block weight limits. /// /// Upon successes, it returns the new block weight as a `Result`. - fn check_weight(info: DispatchInfo) -> Result { + fn check_weight(info: DispatchInfo) -> Result { let current_weight = Module::::all_extrinsics_weight(); let maximum_weight = T::MaximumBlockWeight::get(); let limit = Self::get_dispatch_limit_ratio(info.class) * maximum_weight; let added_weight = info.weight.min(limit); let next_weight = current_weight.saturating_add(added_weight); if next_weight > limit { - return Err(DispatchError::Exhausted) + Err(InvalidTransaction::ExhaustsResources.into()) + } else { + Ok(next_weight) } - Ok(next_weight) } /// Checks if the current extrinsic can fit into the block with respect to block length limits. /// /// Upon successes, it returns the new block length as a `Result`. - fn check_block_length(info: DispatchInfo, len: usize) -> Result { + fn check_block_length(info: DispatchInfo, len: usize) -> Result { let current_len = Module::::all_extrinsics_len(); let maximum_len = T::MaximumBlockLength::get(); let limit = Self::get_dispatch_limit_ratio(info.class) * maximum_len; let added_len = len as u32; let next_len = current_len.saturating_add(added_len); if next_len > limit { - return Err(DispatchError::Exhausted) + Err(InvalidTransaction::ExhaustsResources.into()) + } else { + Ok(next_len) } - Ok(next_len) } /// get the priority of an extrinsic denoted by `info`. @@ -871,8 +901,7 @@ impl CheckWeight { } } - /// Utility constructor for tests and client code. - #[cfg(feature = "std")] + /// Creates new `SignedExtension` to check weight of the extrinsic. pub fn new() -> Self { Self(PhantomData) } @@ -884,7 +913,7 @@ impl SignedExtension for CheckWeight { type AdditionalSigned = (); type Pre = (); - fn additional_signed(&self) -> rstd::result::Result<(), &'static str> { Ok(()) } + fn additional_signed(&self) -> rstd::result::Result<(), TransactionValidityError> { Ok(()) } fn pre_dispatch( self, @@ -892,7 +921,7 @@ impl SignedExtension for CheckWeight { _call: &Self::Call, info: DispatchInfo, len: usize, - ) -> Result<(), DispatchError> { + ) -> Result<(), ApplyError> { let next_len = Self::check_block_length(info, len)?; AllExtrinsicsLen::put(next_len); let next_weight = Self::check_weight(info)?; @@ -906,12 +935,18 @@ impl SignedExtension for CheckWeight { _call: &Self::Call, info: DispatchInfo, len: usize, - ) -> Result { + ) -> TransactionValidity { // There is no point in writing to storage here since changes are discarded. This basically - // discards any transaction which is bigger than the length or weight limit **alone**,which + // discards any transaction which is bigger than the length or weight limit **alone**, which // is a guarantee that it will fail in the pre-dispatch phase. - let _ = Self::check_block_length(info, len)?; - let _ = Self::check_weight(info)?; + if let Err(e) = Self::check_block_length(info, len) { + return Err(e); + } + + if let Err(e) = Self::check_weight(info) { + return Err(e); + } + Ok(ValidTransaction { priority: Self::get_priority(info), ..Default::default() }) } } @@ -927,7 +962,6 @@ impl rstd::fmt::Debug for CheckWeight { #[derive(Encode, Decode, Clone, Eq, PartialEq)] pub struct CheckNonce(#[codec(compact)] T::Index); -#[cfg(feature = "std")] impl CheckNonce { /// utility constructor. Used only in client/factory code. pub fn from(nonce: T::Index) -> Self { @@ -948,7 +982,7 @@ impl SignedExtension for CheckNonce { type AdditionalSigned = (); type Pre = (); - fn additional_signed(&self) -> rstd::result::Result<(), &'static str> { Ok(()) } + fn additional_signed(&self) -> rstd::result::Result<(), TransactionValidityError> { Ok(()) } fn pre_dispatch( self, @@ -956,13 +990,18 @@ impl SignedExtension for CheckNonce { _call: &Self::Call, _info: DispatchInfo, _len: usize, - ) -> Result<(), DispatchError> { + ) -> Result<(), ApplyError> { let expected = >::get(who); if self.0 != expected { return Err( - if self.0 < expected { DispatchError::Stale } else { DispatchError::Future } + if self.0 < expected { + InvalidTransaction::Stale + } else { + InvalidTransaction::Future + }.into() ) } + >::insert(who, expected + T::Index::one()); Ok(()) } @@ -973,11 +1012,11 @@ impl SignedExtension for CheckNonce { _call: &Self::Call, info: DispatchInfo, _len: usize, - ) -> Result { + ) -> TransactionValidity { // check index let expected = >::get(who); if self.0 < expected { - return Err(DispatchError::Stale) + return InvalidTransaction::Stale.into() } let provides = vec![Encode::encode(&(who, self.0))]; @@ -997,11 +1036,10 @@ impl SignedExtension for CheckNonce { } } -/// Nonce check and increment to give replay protection for transactions. +/// Check for transaction mortality. #[derive(Encode, Decode, Clone, Eq, PartialEq)] pub struct CheckEra((Era, rstd::marker::PhantomData)); -#[cfg(feature = "std")] impl CheckEra { /// utility constructor. Used only in client/factory code. pub fn from(era: Era) -> Self { @@ -1022,11 +1060,29 @@ impl SignedExtension for CheckEra { type AdditionalSigned = T::Hash; type Pre = (); - fn additional_signed(&self) -> Result { + fn validate( + &self, + _who: &Self::AccountId, + _call: &Self::Call, + _info: DispatchInfo, + _len: usize, + ) -> TransactionValidity { + let current_u64 = >::block_number().saturated_into::(); + let valid_till = (self.0).0.death(current_u64); + Ok(ValidTransaction { + longevity: valid_till.saturating_sub(current_u64), + ..Default::default() + }) + } + + fn additional_signed(&self) -> Result { let current_u64 = >::block_number().saturated_into::(); let n = (self.0).0.birth(current_u64).saturated_into::(); - if !>::exists(n) { Err("transaction birth block ancient")? } - Ok(>::block_hash(n)) + if !>::exists(n) { + Err(InvalidTransaction::AncientBirthBlock.into()) + } else { + Ok(>::block_hash(n)) + } } } @@ -1041,10 +1097,10 @@ impl rstd::fmt::Debug for CheckGenesis { } } -#[cfg(feature = "std")] impl CheckGenesis { + /// Creates new `SignedExtension` to check genesis hash. pub fn new() -> Self { - Self(std::marker::PhantomData) + Self(rstd::marker::PhantomData) } } @@ -1054,22 +1110,52 @@ impl SignedExtension for CheckGenesis { type AdditionalSigned = T::Hash; type Pre = (); - fn additional_signed(&self) -> Result { + fn additional_signed(&self) -> Result { Ok(>::block_hash(T::BlockNumber::zero())) } } -pub struct ChainContext(::rstd::marker::PhantomData); +/// Ensure the runtime version registered in the transaction is the same as at present. +#[derive(Encode, Decode, Clone, Eq, PartialEq)] +pub struct CheckVersion(rstd::marker::PhantomData); + +#[cfg(feature = "std")] +impl rstd::fmt::Debug for CheckVersion { + fn fmt(&self, _f: &mut rstd::fmt::Formatter) -> rstd::fmt::Result { + Ok(()) + } +} + +impl CheckVersion { + /// Create new `SignedExtension` to check runtime version. + pub fn new() -> Self { + Self(rstd::marker::PhantomData) + } +} + +impl SignedExtension for CheckVersion { + type AccountId = T::AccountId; + type Call = ::Call; + type AdditionalSigned = u32; + type Pre = (); + + fn additional_signed(&self) -> Result { + Ok(>::runtime_version().spec_version) + } +} + +pub struct ChainContext(rstd::marker::PhantomData); impl Default for ChainContext { fn default() -> Self { - ChainContext(::rstd::marker::PhantomData) + ChainContext(rstd::marker::PhantomData) } } impl Lookup for ChainContext { type Source = ::Source; type Target = ::Target; - fn lookup(&self, s: Self::Source) -> rstd::result::Result { + + fn lookup(&self, s: Self::Source) -> Result { ::lookup(s) } } @@ -1079,10 +1165,10 @@ mod tests { use super::*; use runtime_io::with_externalities; use primitives::H256; - use sr_primitives::{traits::{BlakeTwo256, IdentityLookup}, testing::Header}; - use srml_support::{impl_outer_origin, parameter_types}; + use sr_primitives::{traits::{BlakeTwo256, IdentityLookup}, testing::Header, DispatchError}; + use support::{impl_outer_origin, parameter_types}; - impl_outer_origin!{ + impl_outer_origin! { pub enum Origin for Test where system = super {} } @@ -1112,13 +1198,14 @@ mod tests { type MaximumBlockWeight = MaximumBlockWeight; type AvailableBlockRatio = AvailableBlockRatio; type MaximumBlockLength = MaximumBlockLength; + type Version = (); } impl From for u16 { fn from(e: Event) -> u16 { match e { Event::ExtrinsicSuccess => 100, - Event::ExtrinsicFailed => 101, + Event::ExtrinsicFailed(_) => 101, } } } @@ -1167,16 +1254,19 @@ mod tests { System::initialize(&2, &[0u8; 32].into(), &[0u8; 32].into(), &Default::default()); System::deposit_event(42u16); System::note_applied_extrinsic(&Ok(()), 0); - System::note_applied_extrinsic(&Err(""), 0); + System::note_applied_extrinsic(&Err(DispatchError::new(Some(1), 2, None)), 0); System::note_finished_extrinsics(); System::deposit_event(3u16); System::finalize(); - assert_eq!(System::events(), vec![ - EventRecord { phase: Phase::ApplyExtrinsic(0), event: 42u16, topics: vec![] }, - EventRecord { phase: Phase::ApplyExtrinsic(0), event: 100u16, topics: vec![] }, - EventRecord { phase: Phase::ApplyExtrinsic(1), event: 101u16, topics: vec![] }, - EventRecord { phase: Phase::Finalization, event: 3u16, topics: vec![] } - ]); + assert_eq!( + System::events(), + vec![ + EventRecord { phase: Phase::ApplyExtrinsic(0), event: 42u16, topics: vec![] }, + EventRecord { phase: Phase::ApplyExtrinsic(0), event: 100u16, topics: vec![] }, + EventRecord { phase: Phase::ApplyExtrinsic(1), event: 101u16, topics: vec![] }, + EventRecord { phase: Phase::Finalization, event: 3u16, topics: vec![] } + ] + ); }); } @@ -1375,14 +1465,17 @@ mod tests { let op = DispatchInfo { weight: 100, class: DispatchClass::Operational }; let len = 0_usize; - assert_eq!( - CheckWeight::(PhantomData).validate(&1, CALL, normal, len).unwrap().priority, - 100, - ); - assert_eq!( - CheckWeight::(PhantomData).validate(&1, CALL, op, len).unwrap().priority, - Bounded::max_value(), - ); + let priority = CheckWeight::(PhantomData) + .validate(&1, CALL, normal, len) + .unwrap() + .priority; + assert_eq!(priority, 100); + + let priority = CheckWeight::(PhantomData) + .validate(&1, CALL, op, len) + .unwrap() + .priority; + assert_eq!(priority, Bounded::max_value()); }) } @@ -1416,7 +1509,7 @@ mod tests { // future assert_eq!( CheckEra::::from(Era::mortal(4, 2)).additional_signed().err().unwrap(), - "transaction birth block ancient" + InvalidTransaction::AncientBirthBlock.into(), ); // correct @@ -1425,4 +1518,20 @@ mod tests { assert!(CheckEra::::from(Era::mortal(4, 12)).additional_signed().is_ok()); }) } + + #[test] + fn signed_ext_check_era_should_change_longevity() { + with_externalities(&mut new_test_ext(), || { + let normal = DispatchInfo { weight: 100, class: DispatchClass::Normal }; + let len = 0_usize; + let ext = ( + CheckWeight::(PhantomData), + CheckEra::::from(Era::mortal(16, 256)), + ); + System::set_block_number(17); + >::insert(16, H256::repeat_byte(1)); + + assert_eq!(ext.validate(&1, CALL, normal, len).unwrap().longevity, 15); + }) + } } diff --git a/srml/system/src/offchain.rs b/srml/system/src/offchain.rs new file mode 100644 index 0000000000000000000000000000000000000000..e234c74c089442843cacedc7b7093ff8bc396c4f --- /dev/null +++ b/srml/system/src/offchain.rs @@ -0,0 +1,135 @@ +// Copyright 2019 Parity Technologies (UK) Ltd. +// This file is part of Substrate. + +// Substrate 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. + +// Substrate 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 Substrate. If not, see . + +//! Module helpers for offchain calls. + +use codec::Encode; +use sr_primitives::app_crypto::RuntimeAppPublic; +use sr_primitives::traits::Extrinsic as ExtrinsicT; + +/// A trait responsible for signing a payload using given account. +pub trait Signer { + /// Sign any encodable payload with given account and produce a signature. + /// + /// Returns `Some` if signing succeeded and `None` in case the `account` couldn't be used. + fn sign(account: Account, payload: &Payload) -> Option; +} + +impl Signer for AppPublic where + AppPublic: RuntimeAppPublic + From, + AppPublic::Signature: Into, +{ + fn sign(account: Account, raw_payload: &Payload) -> Option { + raw_payload.using_encoded(|payload| { + AppPublic::from(account).sign(&payload).map(Into::into) + }) + } +} + +/// Creates runtime-specific signed transaction. +pub trait CreateTransaction { + type Signature; + + /// Attempt to create signed extrinsic data that encodes call from given account. + /// + /// Runtime implementation is free to construct the payload to sign and the signature + /// in any way it wants. + /// Returns `None` if signed extrinsic could not be created (either because signing failed + /// or because of any other runtime-specific reason). + fn create_transaction>( + call: Extrinsic::Call, + account: T::AccountId, + nonce: T::Index, + ) -> Option<(Extrinsic::Call, Extrinsic::SignaturePayload)>; +} + +/// A trait to sign and submit transactions in offchain calls. +pub trait SubmitSignedTransaction { + /// Unchecked extrinsic type. + type Extrinsic: ExtrinsicT + codec::Encode; + + /// A runtime-specific type to produce signed data for the extrinsic. + type CreateTransaction: CreateTransaction; + + /// A type used to sign transactions created using `CreateTransaction`. + type Signer: Signer< + T::AccountId, + >::Signature, + >; + + /// Sign given call and submit it to the transaction pool. + /// + /// Returns `Ok` if the transaction was submitted correctly + /// and `Err` if the key for given `id` was not found or the + /// transaction was rejected from the pool. + fn sign_and_submit(call: impl Into, id: T::AccountId) -> Result<(), ()> { + let call = call.into(); + let expected = >::account_nonce(&id); + let (call, signature_data) = Self::CreateTransaction + ::create_transaction::(call, id, expected) + .ok_or(())?; + let xt = Self::Extrinsic::new(call, Some(signature_data)).ok_or(())?; + runtime_io::submit_transaction(xt.encode()) + } +} + +/// A trait to submit unsigned transactions in offchain calls. +pub trait SubmitUnsignedTransaction { + /// Unchecked extrinsic type. + type Extrinsic: ExtrinsicT + codec::Encode; + + /// Submit given call to the transaction pool as unsigned transaction. + /// + /// Returns `Ok` if the transaction was submitted correctly + /// and `Err` if transaction was rejected from the pool. + fn submit_unsigned(call: impl Into) -> Result<(), ()> { + let xt = Self::Extrinsic::new(call.into(), None).ok_or(())?; + runtime_io::submit_transaction(xt.encode()) + } +} + +/// A default type used to submit transactions to the pool. +pub struct TransactionSubmitter { + _signer: rstd::marker::PhantomData<(S, C, E)>, +} + +impl Default for TransactionSubmitter { + fn default() -> Self { + Self { + _signer: Default::default(), + } + } +} + +/// A blanket implementation to simplify creation of transaction signer & submitter in the runtime. +impl SubmitSignedTransaction for TransactionSubmitter where + T: crate::Trait, + C: CreateTransaction, + S: Signer>::Signature>, + E: ExtrinsicT + codec::Encode, +{ + type Extrinsic = E; + type CreateTransaction = C; + type Signer = S; +} + +/// A blanket impl to use the same submitter for usigned transactions as well. +impl SubmitUnsignedTransaction for TransactionSubmitter where + T: crate::Trait, + E: ExtrinsicT + codec::Encode, +{ + type Extrinsic = E; +} diff --git a/srml/timestamp/Cargo.toml b/srml/timestamp/Cargo.toml index 9b066a15058d72192460553c663e8689f0f544cd..939fb725666083d90ce6ce0daffa74c03bb90152 100644 --- a/srml/timestamp/Cargo.toml +++ b/srml/timestamp/Cargo.toml @@ -5,16 +5,17 @@ authors = ["Parity Technologies "] edition = "2018" [dependencies] -serde = { version = "1.0", optional = true } +serde = { version = "1.0.101", optional = true } codec = { package = "parity-scale-codec", version = "1.0.0", default-features = false, features = ["derive"] } rstd = { package = "sr-std", path = "../../core/sr-std", default-features = false } sr-primitives = { path = "../../core/sr-primitives", default-features = false } inherents = { package = "substrate-inherents", path = "../../core/inherents", default-features = false } -srml-support = { path = "../support", default-features = false } +support = { package = "srml-support", path = "../support", default-features = false } system = { package = "srml-system", path = "../system", default-features = false } +impl-trait-for-tuples = "0.1.2" [dev-dependencies] -runtime_io = { package = "sr-io", path = "../../core/sr-io" } +runtime-io ={ package = "sr-io", path = "../../core/sr-io" } primitives = { package = "substrate-primitives", path = "../../core/primitives" } [features] @@ -24,7 +25,7 @@ std = [ "codec/std", "rstd/std", "sr-primitives/std", - "srml-support/std", + "support/std", "serde", "system/std", ] diff --git a/srml/timestamp/src/lib.rs b/srml/timestamp/src/lib.rs index 502acadf61e330bc2fda515caa11ba7025d89852..4af0de8bd1b1806dd7eac887b3efc9681669fded 100644 --- a/srml/timestamp/src/lib.rs +++ b/srml/timestamp/src/lib.rs @@ -61,7 +61,7 @@ //! ### Get current timestamp //! //! ``` -//! use srml_support::{decl_module, dispatch::Result}; +//! use support::{decl_module, dispatch::Result}; //! # use srml_timestamp as timestamp; //! use system::ensure_signed; //! @@ -96,8 +96,8 @@ use codec::Encode; use codec::Decode; #[cfg(feature = "std")] use inherents::ProvideInherentData; -use srml_support::{StorageValue, Parameter, decl_storage, decl_module, for_each_tuple}; -use srml_support::traits::{Time, Get}; +use support::{Parameter, decl_storage, decl_module}; +use support::traits::{Time, Get}; use sr_primitives::traits::{ SimpleArithmetic, Zero, SaturatedConversion, Scale }; @@ -183,33 +183,16 @@ impl ProvideInherentData for InherentDataProvider { } /// A trait which is called when the timestamp is set. +#[impl_trait_for_tuples::impl_for_tuples(30)] pub trait OnTimestampSet { fn on_timestamp_set(moment: Moment); } -macro_rules! impl_timestamp_set { - () => ( - impl OnTimestampSet for () { - fn on_timestamp_set(_: Moment) {} - } - ); - - ( $($t:ident)* ) => { - impl),*> OnTimestampSet for ($($t,)*) { - fn on_timestamp_set(moment: Moment) { - $($t::on_timestamp_set(moment.clone());)* - } - } - } -} - -for_each_tuple!(impl_timestamp_set); - /// The module configuration trait pub trait Trait: system::Trait { /// Type used for expressing timestamp. type Moment: Parameter + Default + SimpleArithmetic - + Scale; + + Scale + Copy; /// Something which can be notified when the timestamp is set. Set this to `()` if not needed. type OnTimestampSet: OnTimestampSet; @@ -246,7 +229,7 @@ decl_module! { Self::now().is_zero() || now >= Self::now() + T::MinimumPeriod::get(), "Timestamp must increment by at least between sequential blocks" ); - ::Now::put(now.clone()); + ::Now::put(now); ::DidUpdate::put(true); >::on_timestamp_set(now); @@ -338,7 +321,7 @@ impl Time for Module { mod tests { use super::*; - use srml_support::{impl_outer_origin, assert_ok, parameter_types}; + use support::{impl_outer_origin, assert_ok, parameter_types}; use runtime_io::{with_externalities, TestExternalities}; use primitives::H256; use sr_primitives::{Perbill, traits::{BlakeTwo256, IdentityLookup}, testing::Header}; @@ -371,6 +354,7 @@ mod tests { type MaximumBlockWeight = MaximumBlockWeight; type AvailableBlockRatio = AvailableBlockRatio; type MaximumBlockLength = MaximumBlockLength; + type Version = (); } parameter_types! { pub const MinimumPeriod: u64 = 5; diff --git a/srml/treasury/Cargo.toml b/srml/treasury/Cargo.toml index ae2681e11b48e5e7ac665dd517d06e171d61d4e1..f19fa2c2188eb44a4d1e639c687146a1b60eda73 100644 --- a/srml/treasury/Cargo.toml +++ b/srml/treasury/Cargo.toml @@ -5,16 +5,16 @@ authors = ["Parity Technologies "] edition = "2018" [dependencies] -serde = { version = "1.0", optional = true, features = ["derive"] } +serde = { version = "1.0.101", optional = true, features = ["derive"] } codec = { package = "parity-scale-codec", version = "1.0.0", default-features = false, features = ["derive"] } rstd = { package = "sr-std", path = "../../core/sr-std", default-features = false } sr-primitives = { path = "../../core/sr-primitives", default-features = false } -srml-support = { path = "../support", default-features = false } +support = { package = "srml-support", path = "../support", default-features = false } system = { package = "srml-system", path = "../system", default-features = false } balances = { package = "srml-balances", path = "../balances", default-features = false } [dev-dependencies] -runtime_io = { package = "sr-io", path = "../../core/sr-io" } +runtime-io ={ package = "sr-io", path = "../../core/sr-io" } primitives = { package = "substrate-primitives", path = "../../core/primitives" } [features] @@ -24,7 +24,7 @@ std = [ "codec/std", "rstd/std", "sr-primitives/std", - "srml-support/std", + "support/std", "system/std", "balances/std", ] diff --git a/srml/treasury/src/lib.rs b/srml/treasury/src/lib.rs index 21c670e152e70ac02a7fe347254cc51e607942d6..db8b0f34c90445d26eabbb1055c44756d5c5b2e0 100644 --- a/srml/treasury/src/lib.rs +++ b/srml/treasury/src/lib.rs @@ -70,14 +70,14 @@ #[cfg(feature = "std")] use serde::{Serialize, Deserialize}; use rstd::prelude::*; -use srml_support::{StorageValue, StorageMap, decl_module, decl_storage, decl_event, ensure, print}; -use srml_support::traits::{ +use support::{decl_module, decl_storage, decl_event, ensure, print}; +use support::traits::{ Currency, ExistenceRequirement, Get, Imbalance, OnDilution, OnUnbalanced, ReservableCurrency, WithdrawReason }; -use sr_primitives::{Permill, ModuleId}; +use sr_primitives::{Permill, Perbill, ModuleId}; use sr_primitives::traits::{ - Zero, EnsureOrigin, StaticLookup, CheckedSub, CheckedMul, AccountIdConversion + Zero, EnsureOrigin, StaticLookup, AccountIdConversion, CheckedSub }; use sr_primitives::weights::SimpleDispatchInfo; use codec::{Encode, Decode}; @@ -89,11 +89,6 @@ type NegativeImbalanceOf = <::Currency as Currency< + ReservableCurrency; @@ -144,7 +139,7 @@ decl_module! { /// Percentage of spare funds (if any) that are burnt per spend period. const Burn: Permill = T::Burn::get(); - fn deposit_event() = default; + fn deposit_event() = default; /// Put forward a suggestion for spending. A deposit proportional to the value /// is reserved and slashed if the proposal is rejected. It is returned once the /// proposal is awarded. @@ -348,10 +343,9 @@ impl OnDilution> for Module { if !minted.is_zero() && !portion.is_zero() { let total_issuance = T::Currency::total_issuance(); if let Some(funding) = total_issuance.checked_sub(&portion) { - let funding = funding / portion; - if let Some(funding) = funding.checked_mul(&minted) { - Self::on_unbalanced(T::Currency::issue(funding)); - } + let increase_ratio = Perbill::from_rational_approximation(minted, portion); + let funding = increase_ratio * funding; + Self::on_unbalanced(T::Currency::issue(funding)); } } } @@ -362,9 +356,13 @@ mod tests { use super::*; use runtime_io::with_externalities; - use srml_support::{assert_noop, assert_ok, impl_outer_origin, parameter_types}; + use support::{assert_noop, assert_ok, impl_outer_origin, parameter_types}; use primitives::{H256, Blake2Hasher}; - use sr_primitives::{Perbill, traits::{BlakeTwo256, OnFinalize, IdentityLookup}, testing::Header}; + use sr_primitives::{ + traits::{BlakeTwo256, OnFinalize, IdentityLookup}, + testing::Header, + assert_eq_error_rate, + }; impl_outer_origin! { pub enum Origin for Test {} @@ -394,6 +392,7 @@ mod tests { type MaximumBlockWeight = MaximumBlockWeight; type AvailableBlockRatio = AvailableBlockRatio; type MaximumBlockLength = MaximumBlockLength; + type Version = (); } parameter_types! { pub const ExistentialDeposit: u64 = 0; @@ -464,6 +463,32 @@ mod tests { }); } + #[test] + fn minting_works_2() { + let tests = [(1, 10), (1, 20), (40, 130), (2, 66), (2, 67), (2, 100), (2, 101), (2, 134)]; + for &(minted, portion) in &tests { + with_externalities(&mut new_test_ext(), || { + let init_total_issuance = Balances::total_issuance(); + Treasury::on_dilution(minted, portion); + + assert_eq!( + Treasury::pot(), + (((init_total_issuance - portion) * minted) as f32 / portion as f32) + .round() as u64 + ); + + // Assert: + // portion / init_total_issuance + // == (portion + minted) / (init_total_issuance + Treasury::pot() + minted), + assert_eq_error_rate!( + portion * 1_000 / init_total_issuance, + (portion + minted) * 1_000 / (init_total_issuance + Treasury::pot() + minted), + 2, + ); + }); + } + } + #[test] fn spend_proposal_takes_min_deposit() { with_externalities(&mut new_test_ext(), || { @@ -506,10 +531,13 @@ mod tests { #[test] fn unused_pot_should_diminish() { with_externalities(&mut new_test_ext(), || { + let init_total_issuance = Balances::total_issuance(); Treasury::on_dilution(100, 100); + assert_eq!(Balances::total_issuance(), init_total_issuance + 100); >::on_finalize(2); assert_eq!(Treasury::pot(), 50); + assert_eq!(Balances::total_issuance(), init_total_issuance + 50); }); } @@ -578,37 +606,6 @@ mod tests { }); } - #[test] - // Note: This test demonstrates that `on_dilution` does not increase the pot with good resolution - // with large amounts of the network staked. https://github.com/paritytech/substrate/issues/2579 - // A fix to 2579 should include a change of this test. - fn on_dilution_quantization_effects() { - with_externalities(&mut new_test_ext(), || { - // minted = 1% of total issuance for all cases - assert_eq!(Balances::total_issuance(), 200); - - Treasury::on_dilution(2, 66); // portion = 33% of total issuance - assert_eq!(Treasury::pot(), 4); // should increase by 4 (200 - 66) / 66 * 2 - Balances::make_free_balance_be(&Treasury::account_id(), 0); - - Treasury::on_dilution(2, 67); // portion = 33+eps% of total issuance - assert_eq!(Treasury::pot(), 2); // should increase by 2 (200 - 67) / 67 * 2 - Balances::make_free_balance_be(&Treasury::account_id(), 0); - - Treasury::on_dilution(2, 100); // portion = 50% of total issuance - assert_eq!(Treasury::pot(), 2); // should increase by 2 (200 - 100) / 100 * 2 - Balances::make_free_balance_be(&Treasury::account_id(), 0); - - // If any more than 50% of the network is staked (i.e. (2 * portion) > total_issuance) - // then the pot will not increase. - Treasury::on_dilution(2, 101); // portion = 50+eps% of total issuance - assert_eq!(Treasury::pot(), 0); // should increase by 0 (200 - 101) / 101 * 2 - - Treasury::on_dilution(2, 134); // portion = 67% of total issuance - assert_eq!(Treasury::pot(), 0); // should increase by 0 (200 - 134) / 134 * 2 - }); - } - #[test] fn pot_underflow_should_not_diminish() { with_externalities(&mut new_test_ext(), || { diff --git a/srml/utility/Cargo.toml b/srml/utility/Cargo.toml new file mode 100644 index 0000000000000000000000000000000000000000..d46ed62a556c494466c220c363f2a340edde487a --- /dev/null +++ b/srml/utility/Cargo.toml @@ -0,0 +1,30 @@ +[package] +name = "srml-utility" +version = "2.0.0" +authors = ["Parity Technologies "] +edition = "2018" + +[dependencies] +serde = { version = "1.0", optional = true } +codec = { package = "parity-scale-codec", version = "1.0.0", default-features = false } +support = { package = "srml-support", path = "../support", default-features = false } +system = { package = "srml-system", path = "../system", default-features = false } +sr-primitives = { path = "../../core/sr-primitives", default-features = false } +rstd = { package = "sr-std", path = "../../core/sr-std", default-features = false } +runtime-io = { package = "sr-io", path = "../../core/sr-io", default-features = false } + +[dev-dependencies] +primitives = { package = "substrate-primitives", path = "../../core/primitives" } +balances = { package = "srml-balances", path = "../balances" } + +[features] +default = ["std"] +std = [ + "serde", + "codec/std", + "sr-primitives/std", + "support/std", + "system/std", + "runtime-io/std", + "rstd/std" +] diff --git a/srml/utility/src/lib.rs b/srml/utility/src/lib.rs new file mode 100644 index 0000000000000000000000000000000000000000..c0b1954da9bb5b6ed51b7699447d4ba59024c14f --- /dev/null +++ b/srml/utility/src/lib.rs @@ -0,0 +1,168 @@ +// Copyright 2019 Parity Technologies (UK) Ltd. +// This file is part of Substrate. + +// Substrate 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. + +// Substrate 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 Substrate. If not, see . + +//! # Utility Module +//! A module full of useful helpers for practical chain management. + +// Ensure we're `no_std` when compiling for Wasm. +#![cfg_attr(not(feature = "std"), no_std)] + +use rstd::prelude::*; +use support::{decl_module, decl_event, Parameter}; +use system::ensure_root; +use sr_primitives::{traits::Dispatchable, weights::SimpleDispatchInfo, DispatchError}; + +/// Configuration trait. +pub trait Trait: system::Trait { + /// The overarching event type. + type Event: From + Into<::Event>; + + /// The overarching call type. + type Call: Parameter + Dispatchable; +} + +decl_event!( + /// Events type. + pub enum Event { + BatchExecuted(Vec>), + } +); + +decl_module! { + pub struct Module for enum Call where origin: T::Origin { + /// Deposit one of this module's events by using the default implementation. + fn deposit_event() = default; + + /// Send a batch of dispatch calls (only root). + #[weight = SimpleDispatchInfo::FreeOperational] + fn batch(origin, calls: Vec<::Call>) { + ensure_root(origin)?; + let results = calls.into_iter() + .map(|call| call.dispatch(system::RawOrigin::Root.into())) + .map(|res| res.map_err(Into::into)) + .collect::>(); + Self::deposit_event(Event::BatchExecuted(results)); + } + } +} + +#[cfg(test)] +mod tests { + use super::*; + + use support::{assert_ok, assert_noop, impl_outer_origin, parameter_types, impl_outer_dispatch}; + use runtime_io::with_externalities; + use primitives::{H256, Blake2Hasher}; + use sr_primitives::{ + Perbill, traits::{BlakeTwo256, IdentityLookup}, testing::Header + }; + + impl_outer_origin! { + pub enum Origin for Test {} + } + + impl_outer_dispatch! { + pub enum Call for Test where origin: Origin { + balances::Balances, + utility::Utility, + } + } + + // For testing the module, we construct most of a mock runtime. This means + // first constructing a configuration type (`Test`) which `impl`s each of the + // configuration traits of modules we want to use. + #[derive(Clone, Eq, PartialEq)] + pub struct Test; + parameter_types! { + pub const BlockHashCount: u64 = 250; + pub const MaximumBlockWeight: u32 = 1024; + pub const MaximumBlockLength: u32 = 2 * 1024; + pub const AvailableBlockRatio: Perbill = Perbill::one(); + } + impl system::Trait for Test { + type Origin = Origin; + type Index = u64; + type BlockNumber = u64; + type Hash = H256; + type Call = Call; + type Hashing = BlakeTwo256; + type AccountId = u64; + type Lookup = IdentityLookup; + type Header = Header; + type WeightMultiplierUpdate = (); + type Event = (); + type BlockHashCount = BlockHashCount; + type MaximumBlockWeight = MaximumBlockWeight; + type MaximumBlockLength = MaximumBlockLength; + type AvailableBlockRatio = AvailableBlockRatio; + type Version = (); + } + parameter_types! { + pub const ExistentialDeposit: u64 = 0; + pub const TransferFee: u64 = 0; + pub const CreationFee: u64 = 0; + pub const TransactionBaseFee: u64 = 0; + pub const TransactionByteFee: u64 = 0; + } + impl balances::Trait for Test { + type Balance = u64; + type OnFreeBalanceZero = (); + type OnNewAccount = (); + type Event = (); + type TransactionPayment = (); + type TransferPayment = (); + type DustRemoval = (); + type ExistentialDeposit = ExistentialDeposit; + type TransferFee = TransferFee; + type CreationFee = CreationFee; + type TransactionBaseFee = TransactionBaseFee; + type TransactionByteFee = TransactionByteFee; + type WeightToFee = (); + } + impl Trait for Test { + type Event = (); + type Call = Call; + } + type Balances = balances::Module; + type Utility = Module; + + fn new_test_ext() -> runtime_io::TestExternalities { + let mut t = system::GenesisConfig::default().build_storage::().unwrap(); + balances::GenesisConfig:: { + balances: vec![(1, 10), (2, 0)], + vesting: vec![], + }.assimilate_storage(&mut t).unwrap(); + t.into() + } + + #[test] + fn batch_works() { + with_externalities(&mut new_test_ext(), || { + assert_eq!(Balances::free_balance(1), 10); + assert_eq!(Balances::free_balance(2), 0); + assert_noop!(Utility::batch(Origin::signed(1), vec![ + Call::Balances(balances::Call::force_transfer(1, 2, 5)), + Call::Balances(balances::Call::force_transfer(1, 2, 5)) + ]), "RequireRootOrigin"); + assert_ok!(Utility::batch(Origin::ROOT, vec![ + Call::Balances(balances::Call::force_transfer(1, 2, 5)), + Call::Balances(balances::Call::force_transfer(1, 2, 5)) + ])); + assert_eq!(Balances::free_balance(1), 0); + assert_eq!(Balances::free_balance(2), 10); + }); + } +} diff --git a/subkey/Cargo.toml b/subkey/Cargo.toml index 9e7112a029c203d84eeac2ee79fb2d05fe542a5e..1b1a697d0fa675d12d2e12eb165259e8481d44d9 100644 --- a/subkey/Cargo.toml +++ b/subkey/Cargo.toml @@ -9,13 +9,13 @@ primitives = { package = "substrate-primitives", version = "*", path = "../core node-runtime = { version = "*", path = "../node/runtime" } node-primitives = { version = "*", path = "../node/primitives" } sr-primitives = { version = "*", path = "../core/sr-primitives" } -rand = "0.6" -clap = { version = "~2.32", features = ["yaml"] } -tiny-bip39 = "0.6.0" -rustc-hex = "2.0" +rand = "0.7.2" +clap = { version = "~2.32.0", features = ["yaml"] } +tiny-bip39 = "0.6.2" +rustc-hex = "2.0.1" substrate-bip39 = "0.3.1" -hex = "0.3" -hex-literal = "0.2" +hex = "0.3.2" +hex-literal = "0.2.1" codec = { package = "parity-scale-codec", version = "1.0.0" } system = { package = "srml-system", path = "../srml/system" } balances = { package = "srml-balances", path = "../srml/balances" } diff --git a/subkey/README.adoc b/subkey/README.adoc index 52770e78ec4432778a5683bd140e25005b877a96..07533a002f80ef1f1912b352829c147be81bad88 100644 --- a/subkey/README.adoc +++ b/subkey/README.adoc @@ -31,7 +31,7 @@ OUTPUT: `subkey` expects a message to come in on STDIN, one way to sign a message would look like this: ```bash -echo | subkey sign +echo -n | subkey sign OUTPUT: a69da4a6ccbf81dbbbfad235fa12cf8528c18012b991ae89214de8d20d29c1280576ced6eb38b7406d1b7e03231df6dd4a5257546ddad13259356e1c3adfb509 @@ -40,7 +40,7 @@ a69da4a6ccbf81dbbbfad235fa12cf8528c18012b991ae89214de8d20d29c1280576ced6eb38b740 === Verifying a signature ```bash -echo | subkey verify
+echo -n | subkey verify
OUTPUT: Signature verifies correctly. diff --git a/subkey/src/cli.yml b/subkey/src/cli.yml index b4f99f8743fa545898a93e06e9693c737b66bc16..aa6c6d4a574e50e879e27e956845e622c4ad6c63 100644 --- a/subkey/src/cli.yml +++ b/subkey/src/cli.yml @@ -23,7 +23,7 @@ args: long: network takes_value: true required: false - help: Specify a network. One of substrate (default), polkadot and kusama. + help: Specify a network. One of substrate (default), polkadot, kusama, or dothereum. subcommands: - generate: about: Generate a random account diff --git a/subkey/src/main.rs b/subkey/src/main.rs index fde301b44f25c7b9954a8517a7c7f56579f46cdc..973502b3d6810fcae9a0152a914e40681eb0a84b 100644 --- a/subkey/src/main.rs +++ b/subkey/src/main.rs @@ -18,54 +18,69 @@ #[cfg(feature = "bench")] extern crate test; -use std::{str::FromStr, io::{stdin, Read}, convert::TryInto}; +use bip39::{Language, Mnemonic, MnemonicType}; +use clap::{load_yaml, App, ArgMatches}; +use codec::{Decode, Encode}; use hex_literal::hex; -use clap::load_yaml; -use bip39::{Mnemonic, Language, MnemonicType}; +use node_primitives::{Balance, Hash, Index}; +use node_runtime::{BalancesCall, Call, Runtime, SignedPayload, UncheckedExtrinsic, VERSION}; use primitives::{ - ed25519, sr25519, hexdisplay::HexDisplay, Pair, Public, blake2_256, - crypto::{Ss58Codec, set_default_ss58_version, Ss58AddressFormat} + crypto::{set_default_ss58_version, Ss58AddressFormat, Ss58Codec}, + ed25519, sr25519, Pair, Public, H256, hexdisplay::HexDisplay, }; -use codec::{Encode, Decode}; use sr_primitives::generic::Era; -use node_primitives::{Balance, Index, Hash}; -use node_runtime::{Call, UncheckedExtrinsic, BalancesCall, Runtime}; +use std::{ + convert::TryInto, + io::{stdin, Read}, + str::FromStr, +}; mod vanity; -trait Crypto { - type Pair: Pair; +trait Crypto: Sized { + type Pair: Pair; type Public: Public + Ss58Codec + AsRef<[u8]> + std::hash::Hash; fn pair_from_suri(suri: &str, password: Option<&str>) -> Self::Pair { Self::Pair::from_string(suri, password).expect("Invalid phrase") } - fn ss58_from_pair(pair: &Self::Pair) -> String { pair.public().to_ss58check() } - fn public_from_pair(pair: &Self::Pair) -> Vec { pair.public().as_ref().to_owned() } + fn ss58_from_pair(pair: &Self::Pair) -> String { + pair.public().to_ss58check() + } + fn public_from_pair(pair: &Self::Pair) -> Self::Public { + pair.public() + } fn print_from_uri( uri: &str, password: Option<&str>, network_override: Option, - ) where ::Public: Sized + Ss58Codec + AsRef<[u8]> { + ) where + ::Public: PublicT, + { if let Ok((pair, seed)) = Self::Pair::from_phrase(uri, password) { - println!("Secret phrase `{}` is account:\n Secret seed: 0x{}\n Public key (hex): 0x{}\n Address (SS58): {}", + let public_key = Self::public_from_pair(&pair); + println!("Secret phrase `{}` is account:\n Secret seed: {}\n Public key (hex): {}\n Address (SS58): {}", uri, - HexDisplay::from(&seed.as_ref()), - HexDisplay::from(&Self::public_from_pair(&pair)), + format_seed::(seed), + format_public_key::(public_key), Self::ss58_from_pair(&pair) ); } else if let Ok(pair) = Self::Pair::from_string(uri, password) { - println!("Secret Key URI `{}` is account:\n Public key (hex): 0x{}\n Address (SS58): {}", + let public_key = Self::public_from_pair(&pair); + println!( + "Secret Key URI `{}` is account:\n Public key (hex): {}\n Address (SS58): {}", uri, - HexDisplay::from(&Self::public_from_pair(&pair)), + format_public_key::(public_key), Self::ss58_from_pair(&pair) ); - } else if let Ok((public, v)) = ::Public::from_string_with_version(uri) { + } else if let Ok((public_key, v)) = + ::Public::from_string_with_version(uri) + { let v = network_override.unwrap_or(v); - println!("Public Key URI `{}` is account:\n Network ID/version: {}\n Public key (hex): 0x{}\n Address (SS58): {}", + println!("Public Key URI `{}` is account:\n Network ID/version: {}\n Public key (hex): {}\n Address (SS58): {}", uri, String::from(v), - HexDisplay::from(&public.as_ref()), - public.to_ss58check_with_version(v) + format_public_key::(public_key.clone()), + public_key.to_ss58check_with_version(v) ); } else { println!("Invalid phrase/URI given"); @@ -91,215 +106,360 @@ impl Crypto for Sr25519 { type Public = sr25519::Public; } -fn execute(matches: clap::ArgMatches) where - <::Pair as Pair>::Signature: AsRef<[u8]> + AsMut<[u8]> + Default, - <::Pair as Pair>::Public: Sized + AsRef<[u8]> + Ss58Codec, +type SignatureOf = <::Pair as Pair>::Signature; +type PublicOf = <::Pair as Pair>::Public; +type SeedOf = <::Pair as Pair>::Seed; + +trait SignatureT: AsRef<[u8]> + AsMut<[u8]> + Default {} +trait PublicT: Sized + AsRef<[u8]> + Ss58Codec {} + +impl SignatureT for sr25519::Signature {} +impl SignatureT for ed25519::Signature {} +impl PublicT for sr25519::Public {} +impl PublicT for ed25519::Public {} + +fn main() { + let yaml = load_yaml!("cli.yml"); + let matches = App::from_yaml(yaml) + .version(env!("CARGO_PKG_VERSION")) + .get_matches(); + + if matches.is_present("ed25519") { + execute::(matches) + } else { + execute::(matches) + } +} + +fn execute(matches: ArgMatches) +where + SignatureOf: SignatureT, + PublicOf: PublicT, { - let extra = |i: Index, f: Balance| { - ( - system::CheckGenesis::::new(), - system::CheckEra::::from(Era::Immortal), - system::CheckNonce::::from(i), - system::CheckWeight::::new(), - balances::TakeFees::::from(f), - ) - }; let password = matches.value_of("password"); - let maybe_network: Option = matches.value_of("network") - .map(|network| network.try_into() - .expect("Invalid network name: must be polkadot/substrate/kusama") - ); + let maybe_network: Option = matches.value_of("network").map(|network| { + network + .try_into() + .expect("Invalid network name: must be polkadot/substrate/kusama/dothereum") + }); if let Some(network) = maybe_network { set_default_ss58_version(network); } match matches.subcommand() { ("generate", Some(matches)) => { - // create a new randomly generated mnemonic phrase - let words = matches.value_of("words") - .map(|x| usize::from_str(x).expect("Invalid number given for --words")) - .map(|x| MnemonicType::for_word_count(x) - .expect("Invalid number of words given for phrase: must be 12/15/18/21/24") - ).unwrap_or(MnemonicType::Words12); - let mnemonic = Mnemonic::new(words, Language::English); + let mnemonic = generate_mnemonic(matches); C::print_from_uri(mnemonic.phrase(), password, maybe_network); } ("inspect", Some(matches)) => { - let uri = matches.value_of("uri") + let uri = matches + .value_of("uri") .expect("URI parameter is required; thus it can't be None; qed"); C::print_from_uri(uri, password, maybe_network); } - ("vanity", Some(matches)) => { - let desired: String = matches.value_of("pattern").map(str::to_string).unwrap_or_default(); - let result = vanity::generate_key::(&desired).expect("Key generation failed"); - C::print_from_uri( - &format!("0x{}", HexDisplay::from(&result.seed.as_ref())), - None, - maybe_network - ); - } ("sign", Some(matches)) => { - let suri = matches.value_of("suri") - .expect("secret URI parameter is required; thus it can't be None; qed"); - let pair = C::pair_from_suri(suri, password); - let mut message = vec![]; - stdin().lock().read_to_end(&mut message).expect("Error reading from stdin"); - if matches.is_present("hex") { - message = hex::decode(&message).expect("Invalid hex in message"); + let should_decode = matches.is_present("hex"); + let message = read_message_from_stdin(should_decode); + let signature = do_sign::(matches, message, password); + println!("{}", signature); + } + ("verify", Some(matches)) => { + let should_decode = matches.is_present("hex"); + let message = read_message_from_stdin(should_decode); + let is_valid_signature = do_verify::(matches, message, password); + if is_valid_signature { + println!("Signature verifies correctly."); + } else { + println!("Signature invalid."); } - let sig = pair.sign(&message); - println!("{}", hex::encode(&sig)); + } + ("vanity", Some(matches)) => { + let desired: String = matches + .value_of("pattern") + .map(str::to_string) + .unwrap_or_default(); + let result = vanity::generate_key::(&desired).expect("Key generation failed"); + let formated_seed = format_seed::(result.seed); + C::print_from_uri(&formated_seed, None, maybe_network); } ("transfer", Some(matches)) => { - let signer = matches.value_of("from") - .expect("parameter is required; thus it can't be None; qed"); - let signer = Sr25519::pair_from_suri(signer, password); - - let to = matches.value_of("to") - .expect("parameter is required; thus it can't be None; qed"); - let to = sr25519::Public::from_string(to).ok().or_else(|| - sr25519::Pair::from_string(to, password).ok().map(|p| p.public()) - ).expect("Invalid 'to' URI; expecting either a secret URI or a public URI."); - - let amount = matches.value_of("amount") - .expect("parameter is required; thus it can't be None; qed"); - let amount = str::parse::(amount) - .expect("Invalid 'amount' parameter; expecting an integer."); - - let index = matches.value_of("index") - .expect("parameter is required; thus it can't be None; qed"); - let index = str::parse::(index) - .expect("Invalid 'amount' parameter; expecting an integer."); + let signer = read_pair::(matches.value_of("from"), password); + let index = read_required_parameter::(matches, "index"); + let genesis_hash = read_genesis_hash(matches); + let to = read_public_key::(matches.value_of("to"), password); + let amount = read_required_parameter::(matches, "amount"); let function = Call::Balances(BalancesCall::transfer(to.into(), amount)); - let genesis_hash: Hash = match matches.value_of("genesis").unwrap_or("alex") { - "elm" => hex!["10c08714a10c7da78f40a60f6f732cf0dba97acfb5e2035445b032386157d5c3"].into(), - "alex" => hex!["dcd1346701ca8396496e52aa2785b1748deb6db09551b72159dcb3e08991025b"].into(), - h => hex::decode(h).ok().and_then(|x| Decode::decode(&mut &x[..]).ok()) - .expect("Invalid genesis hash or unrecognised chain identifier"), - }; + let extrinsic = create_extrinsic(function, index, signer, genesis_hash); - println!("Using a genesis hash of {}", HexDisplay::from(&genesis_hash.as_ref())); - - let raw_payload = ( - function, - extra(index, 0), - (&genesis_hash, &genesis_hash), - ); - let signature = raw_payload.using_encoded(|payload| if payload.len() > 256 { - signer.sign(&blake2_256(payload)[..]) - } else { - println!("Signing {}", HexDisplay::from(&payload)); - signer.sign(payload) - }); - let extrinsic = UncheckedExtrinsic::new_signed( - raw_payload.0, - signer.public().into(), - signature.into(), - extra(index, 0), - ); - println!("0x{}", hex::encode(&extrinsic.encode())); + print_extrinsic(extrinsic); } ("sign-transaction", Some(matches)) => { - let s = matches.value_of("suri") - .expect("secret URI parameter is required; thus it can't be None; qed"); - let signer = Sr25519::pair_from_suri(s, password); - - let index = matches.value_of("nonce") - .expect("nonce is required; thus it can't be None; qed"); - let index = str::parse::(index) - .expect("Invalid 'index' parameter; expecting an integer."); - - let call = matches.value_of("call") - .expect("call is required; thus it can't be None; qed"); - let function: Call = hex::decode(&call).ok() - .and_then(|x| Decode::decode(&mut &x[..]).ok()).unwrap(); - - let genesis_hash: Hash = match matches.value_of("genesis").unwrap_or("alex") { - "elm" => hex!["10c08714a10c7da78f40a60f6f732cf0dba97acfb5e2035445b032386157d5c3"].into(), - "alex" => hex!["dcd1346701ca8396496e52aa2785b1748deb6db09551b72159dcb3e08991025b"].into(), - h => hex::decode(h).ok().and_then(|x| Decode::decode(&mut &x[..]).ok()) - .expect("Invalid genesis hash or unrecognised chain identifier"), - }; - - println!("Using a genesis hash of {}", HexDisplay::from(&genesis_hash.as_ref())); - - let raw_payload = ( - function, - extra(index, 0), - (&genesis_hash, &genesis_hash), - ); - let signature = raw_payload.using_encoded(|payload| - if payload.len() > 256 { - signer.sign(&blake2_256(payload)[..]) - } else { - signer.sign(payload) - } - ); + let signer = read_pair::(matches.value_of("suri"), password); + let index = read_required_parameter::(matches, "nonce"); + let genesis_hash = read_genesis_hash(matches); - let extrinsic = UncheckedExtrinsic::new_signed( - raw_payload.0, - signer.public().into(), - signature.into(), - extra(index, 0), - ); + let call = matches.value_of("call").expect("call is required; qed"); + let function: Call = hex::decode(&call) + .ok() + .and_then(|x| Decode::decode(&mut &x[..]).ok()) + .unwrap(); - println!("0x{}", hex::encode(&extrinsic.encode())); - } - ("verify", Some(matches)) => { - let sig_data = matches.value_of("sig") - .expect("signature parameter is required; thus it can't be None; qed"); - let mut sig = <::Pair as Pair>::Signature::default(); - let sig_data = hex::decode(sig_data).expect("signature is invalid hex"); - if sig_data.len() != sig.as_ref().len() { - panic!("signature is an invalid length. {} bytes is not the expected value of {} bytes", sig_data.len(), sig.as_ref().len()); - } - sig.as_mut().copy_from_slice(&sig_data); - let uri = matches.value_of("uri") - .expect("public uri parameter is required; thus it can't be None; qed"); - let pubkey = <::Pair as Pair>::Public::from_string(uri).ok().or_else(|| - ::Pair::from_string(uri, password).ok().map(|p| p.public()) - ).expect("Invalid URI; expecting either a secret URI or a public URI."); - let mut message = vec![]; - stdin().lock().read_to_end(&mut message).expect("Error reading from stdin"); - if matches.is_present("hex") { - message = hex::decode(&message).expect("Invalid hex in message"); - } - if <::Pair as Pair>::verify(&sig, &message, &pubkey) { - println!("Signature verifies correctly.") - } else { - println!("Signature invalid.") - } + let extrinsic = create_extrinsic(function, index, signer, genesis_hash); + + print_extrinsic(extrinsic); } _ => print_usage(&matches), } } -fn main() { - let yaml = load_yaml!("cli.yml"); - let matches = clap::App::from_yaml(yaml) - .version(env!("CARGO_PKG_VERSION")) - .get_matches(); +/// Creates a new randomly generated mnemonic phrase. +fn generate_mnemonic(matches: &ArgMatches) -> Mnemonic { + let words = matches + .value_of("words") + .map(|x| usize::from_str(x).expect("Invalid number given for --words")) + .map(|x| { + MnemonicType::for_word_count(x) + .expect("Invalid number of words given for phrase: must be 12/15/18/21/24") + }) + .unwrap_or(MnemonicType::Words12); + Mnemonic::new(words, Language::English) +} - if matches.is_present("ed25519") { - execute::(matches) +fn do_sign(matches: &ArgMatches, message: Vec, password: Option<&str>) -> String +where + SignatureOf: SignatureT, + PublicOf: PublicT, +{ + let pair = read_pair::(matches.value_of("suri"), password); + let signature = pair.sign(&message); + format_signature::(&signature) +} + +fn do_verify(matches: &ArgMatches, message: Vec, password: Option<&str>) -> bool +where + SignatureOf: SignatureT, + PublicOf: PublicT, +{ + let signature = read_signature::(matches); + let pubkey = read_public_key::(matches.value_of("uri"), password); + <::Pair as Pair>::verify(&signature, &message, &pubkey) +} + +fn read_message_from_stdin(should_decode: bool) -> Vec { + let mut message = vec![]; + stdin() + .lock() + .read_to_end(&mut message) + .expect("Error reading from stdin"); + if should_decode { + message = hex::decode(&message).expect("Invalid hex in message"); + } + message +} + +fn read_required_parameter(matches: &ArgMatches, name: &str) -> T +where + ::Err: std::fmt::Debug, +{ + let str_value = matches + .value_of(name) + .expect("parameter is required; thus it can't be None; qed"); + str::parse::(str_value).expect("Invalid 'nonce' parameter; expecting an integer.") +} + +fn read_genesis_hash(matches: &ArgMatches) -> H256 { + let genesis_hash: Hash = match matches.value_of("genesis").unwrap_or("alex") { + "elm" => hex!["10c08714a10c7da78f40a60f6f732cf0dba97acfb5e2035445b032386157d5c3"].into(), + "alex" => hex!["dcd1346701ca8396496e52aa2785b1748deb6db09551b72159dcb3e08991025b"].into(), + h => hex::decode(h) + .ok() + .and_then(|x| Decode::decode(&mut &x[..]).ok()) + .expect("Invalid genesis hash or unrecognised chain identifier"), + }; + println!( + "Using a genesis hash of {}", + HexDisplay::from(&genesis_hash.as_ref()) + ); + genesis_hash +} + +fn read_signature(matches: &ArgMatches) -> SignatureOf +where + SignatureOf: SignatureT, + PublicOf: PublicT, +{ + let sig_data = matches + .value_of("sig") + .expect("signature parameter is required; thus it can't be None; qed"); + let mut signature = <::Pair as Pair>::Signature::default(); + let sig_data = hex::decode(sig_data).expect("signature is invalid hex"); + if sig_data.len() != signature.as_ref().len() { + panic!( + "signature has an invalid length. read {} bytes, expected {} bytes", + sig_data.len(), + signature.as_ref().len(), + ); + } + signature.as_mut().copy_from_slice(&sig_data); + signature +} + +fn read_public_key(matched_uri: Option<&str>, password: Option<&str>) -> PublicOf +where + SignatureOf: SignatureT, + PublicOf: PublicT, +{ + let uri = matched_uri.expect("parameter is required; thus it can't be None; qed"); + let uri = if uri.starts_with("0x") { + &uri[2..] } else { - execute::(matches) + uri + }; + if let Ok(pubkey_vec) = hex::decode(uri) { + ::Public::from_slice(pubkey_vec.as_slice()) + } else { + ::Pair::from_string(uri, password) + .ok() + .map(|p| p.public()) + .expect("Invalid URI; expecting either a secret URI or a public URI.") } } -fn print_usage(matches: &clap::ArgMatches) { +fn read_pair( + matched_suri: Option<&str>, + password: Option<&str>, +) -> ::Pair +where + SignatureOf: SignatureT, + PublicOf: PublicT, +{ + let suri = matched_suri.expect("parameter is required; thus it can't be None; qed"); + C::pair_from_suri(suri, password) +} + +fn format_signature(signature: &SignatureOf) -> String { + format!("{}", hex::encode(signature)) +} + +fn format_seed(seed: SeedOf) -> String { + format!("0x{}", HexDisplay::from(&seed.as_ref())) +} + +fn format_public_key(public_key: PublicOf) -> String { + format!("0x{}", HexDisplay::from(&public_key.as_ref())) +} + +fn create_extrinsic( + function: Call, + index: Index, + signer: ::Pair, + genesis_hash: H256, +) -> UncheckedExtrinsic { + let extra = |i: Index, f: Balance| { + ( + system::CheckVersion::::new(), + system::CheckGenesis::::new(), + system::CheckEra::::from(Era::Immortal), + system::CheckNonce::::from(i), + system::CheckWeight::::new(), + balances::TakeFees::::from(f), + Default::default(), + ) + }; + let raw_payload = SignedPayload::from_raw( + function, + extra(index, 0), + ( + VERSION.spec_version as u32, + genesis_hash, + genesis_hash, + (), + (), + (), + (), + ), + ); + let signature = raw_payload.using_encoded(|payload| signer.sign(payload)); + let (function, extra, _) = raw_payload.deconstruct(); + + UncheckedExtrinsic::new_signed( + function, + signer.public().into(), + signature.into(), + extra, + ) +} + +fn print_extrinsic(extrinsic: UncheckedExtrinsic) { + println!("0x{}", hex::encode(&extrinsic.encode())); +} + +fn print_usage(matches: &ArgMatches) { println!("{}", matches.usage()); } #[cfg(test)] mod tests { - use super::{Hash, Decode}; + use super::*; + + fn test_generate_sign_verify() + where + SignatureOf: SignatureT, + PublicOf: PublicT, + { + let yaml = load_yaml!("cli.yml"); + let app = App::from_yaml(yaml); + let password = None; + + // Generate public key and seed. + let arg_vec = vec!["subkey", "generate"]; + + let matches = app.clone().get_matches_from(arg_vec); + let matches = matches.subcommand().1.unwrap(); + let mnemonic = generate_mnemonic(matches); + + let (pair, seed) = + <::Pair as Pair>::from_phrase(mnemonic.phrase(), password) + .unwrap(); + let public_key = CryptoType::public_from_pair(&pair); + let public_key = format_public_key::(public_key); + let seed = format_seed::(seed); + + // Sign a message using previous seed. + let arg_vec = vec!["subkey", "sign", &seed[..]]; + + let matches = app.get_matches_from(arg_vec); + let matches = matches.subcommand().1.unwrap(); + let message = "Blah Blah\n".as_bytes().to_vec(); + let signature = do_sign::(matches, message.clone(), password); + + // Verify the previous signature. + let arg_vec = vec!["subkey", "verify", &signature[..], &public_key[..]]; + + let matches = App::from_yaml(yaml).get_matches_from(arg_vec); + let matches = matches.subcommand().1.unwrap(); + assert!(do_verify::(matches, message, password)); + } + + #[test] + fn generate_sign_verify_should_work_for_ed25519() { + test_generate_sign_verify::(); + } + + #[test] + fn generate_sign_verify_should_work_for_sr25519() { + test_generate_sign_verify::(); + } + #[test] fn should_work() { let s = "0123456789012345678901234567890123456789012345678901234567890123"; - let d1: Hash = hex::decode(s).ok().and_then(|x| Decode::decode(&mut &x[..]).ok()).unwrap(); + let d1: Hash = hex::decode(s) + .ok() + .and_then(|x| Decode::decode(&mut &x[..]).ok()) + .unwrap(); let d2: Hash = { let mut gh: [u8; 32] = Default::default(); diff --git a/subkey/src/vanity.rs b/subkey/src/vanity.rs index 988055c67cac4402c67f8c2da3d2afe469027ec9..b612bc470f3938eca9b11ba03b0876f20d51e689 100644 --- a/subkey/src/vanity.rs +++ b/subkey/src/vanity.rs @@ -14,15 +14,15 @@ // You should have received a copy of the GNU General Public License // along with Substrate. If not, see . -use rand::{rngs::OsRng, RngCore}; use super::Crypto; use primitives::Pair; +use rand::{rngs::OsRng, RngCore}; fn good_waypoint(done: u64) -> u64 { match done { - 0 ..= 1_000_000 => 100_000, - 0 ..= 10_000_000 => 1_000_000, - 0 ..= 100_000_000 => 10_000_000, + 0..=1_000_000 => 100_000, + 0..=10_000_000 => 1_000_000, + 0..=100_000_000 => 10_000_000, _ => 100_000_000, } } @@ -30,8 +30,13 @@ fn good_waypoint(done: u64) -> u64 { fn next_seed(seed: &mut [u8]) { for i in 0..seed.len() { match seed[i] { - 255 => { seed[i] = 0; } - _ => { seed[i] += 1; break; } + 255 => { + seed[i] = 0; + } + _ => { + seed[i] += 1; + break; + } } } } @@ -71,7 +76,7 @@ pub(super) fn generate_key(desired: &str) -> Result, &str> loop { if done % 100000 == 0 { - OsRng::new().unwrap().fill_bytes(seed.as_mut()); + OsRng.fill_bytes(seed.as_mut()); } else { next_seed(seed.as_mut()); } @@ -101,15 +106,20 @@ pub(super) fn generate_key(desired: &str) -> Result, &str> #[cfg(test)] mod tests { - use super::*; use super::super::Ed25519; - use primitives::{Pair, crypto::Ss58Codec}; + use super::*; + use primitives::{crypto::Ss58Codec, Pair}; #[cfg(feature = "bench")] use test::Bencher; #[test] fn test_generation_with_single_char() { - assert!(generate_key::("j").unwrap().pair.public().to_ss58check().contains("j")); + assert!(generate_key::("j") + .unwrap() + .pair + .public() + .to_ss58check() + .contains("j")); } #[test] @@ -120,34 +130,45 @@ mod tests { #[test] fn test_score_100() { - let score = calculate_score("Polkadot", "5PolkadotwHY5k9GpdTgpqs9xjuNvtv8EcwCFpEeyEf3KHim"); + let score = calculate_score( + "Polkadot", + "5PolkadotwHY5k9GpdTgpqs9xjuNvtv8EcwCFpEeyEf3KHim", + ); assert_eq!(score, 430); } #[test] fn test_score_50_2() { // 50% for the position + 50% for the size - assert_eq!(calculate_score("Polkadot", "5PolkXXXXwHY5k9GpdTgpqs9xjuNvtv8EcwCFpEeyEf3KHim"), 238); + assert_eq!( + calculate_score( + "Polkadot", + "5PolkXXXXwHY5k9GpdTgpqs9xjuNvtv8EcwCFpEeyEf3KHim" + ), + 238 + ); } #[test] fn test_score_0() { - assert_eq!(calculate_score("Polkadot", "5GUWv4bLCchGUHJrzULXnh4JgXsMpTKRnjuXTY7Qo1Kh9uYK"), 0); + assert_eq!( + calculate_score( + "Polkadot", + "5GUWv4bLCchGUHJrzULXnh4JgXsMpTKRnjuXTY7Qo1Kh9uYK" + ), + 0 + ); } #[cfg(feature = "bench")] #[bench] fn bench_paranoiac(b: &mut Bencher) { - b.iter(|| { - generate_key("polk") - }); + b.iter(|| generate_key("polk")); } #[cfg(feature = "bench")] #[bench] fn bench_not_paranoiac(b: &mut Bencher) { - b.iter(|| { - generate_key("polk") - }); + b.iter(|| generate_key("polk")); } } diff --git a/test-utils/chain-spec-builder/Cargo.lock b/test-utils/chain-spec-builder/Cargo.lock deleted file mode 100644 index afa92a46f8f4dd70021d0b2e7a53fb81dff6a3fa..0000000000000000000000000000000000000000 --- a/test-utils/chain-spec-builder/Cargo.lock +++ /dev/null @@ -1,5198 +0,0 @@ -# This file is automatically @generated by Cargo. -# It is not intended for manual editing. -[[package]] -name = "aes" -version = "0.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "aes-soft 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", - "aesni 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)", - "block-cipher-trait 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "aes-ctr" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "aes-soft 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", - "aesni 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)", - "ctr 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", - "stream-cipher 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "aes-soft" -version = "0.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "block-cipher-trait 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", - "byteorder 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)", - "opaque-debug 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "aesni" -version = "0.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "block-cipher-trait 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", - "opaque-debug 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", - "stream-cipher 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "aho-corasick" -version = "0.7.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "memchr 2.2.0 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "aio-limited" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "futures 0.1.26 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", - "parking_lot 0.5.5 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-executor 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-io 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-timer 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "ansi_term" -version = "0.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "app_dirs" -version = "1.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "ole32-sys 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", - "shell32-sys 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", - "xdg 2.2.0 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "arrayref" -version = "0.3.5" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "arrayvec" -version = "0.4.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "nodrop 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "asn1_der" -version = "0.6.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "asn1_der_derive 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "asn1_der_derive" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "quote 0.6.12 (registry+https://github.com/rust-lang/crates.io-index)", - "syn 0.15.34 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "atty" -version = "0.2.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "libc 0.2.54 (registry+https://github.com/rust-lang/crates.io-index)", - "termion 1.5.2 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "autocfg" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "backtrace" -version = "0.3.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "autocfg 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", - "backtrace-sys 0.1.28 (registry+https://github.com/rust-lang/crates.io-index)", - "cfg-if 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.54 (registry+https://github.com/rust-lang/crates.io-index)", - "rustc-demangle 0.1.14 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "backtrace-sys" -version = "0.1.28" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "cc 1.0.26 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.54 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "base-x" -version = "0.2.4" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "base58" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "base64" -version = "0.9.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "byteorder 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)", - "safemem 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "base64" -version = "0.10.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "byteorder 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "bigint" -version = "4.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "byteorder 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)", - "crunchy 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "bindgen" -version = "0.47.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", - "cexpr 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)", - "cfg-if 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)", - "clang-sys 0.26.4 (registry+https://github.com/rust-lang/crates.io-index)", - "clap 2.32.0 (registry+https://github.com/rust-lang/crates.io-index)", - "env_logger 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)", - "hashbrown 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", - "lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", - "peeking_take_while 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", - "proc-macro2 0.4.30 (registry+https://github.com/rust-lang/crates.io-index)", - "quote 0.6.12 (registry+https://github.com/rust-lang/crates.io-index)", - "regex 1.1.6 (registry+https://github.com/rust-lang/crates.io-index)", - "which 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "bitflags" -version = "1.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "bitmask" -version = "0.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "blake2" -version = "0.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "byte-tools 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", - "crypto-mac 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", - "digest 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", - "opaque-debug 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "blake2-rfc" -version = "0.2.18" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "arrayvec 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)", - "constant_time_eq 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "block-buffer" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "byte-tools 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", - "generic-array 0.8.3 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "block-buffer" -version = "0.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "arrayref 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)", - "byte-tools 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "block-buffer" -version = "0.7.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "block-padding 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", - "byte-tools 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", - "byteorder 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)", - "generic-array 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "block-cipher-trait" -version = "0.6.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "generic-array 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "block-modes" -version = "0.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "block-cipher-trait 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", - "block-padding 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "block-padding" -version = "0.1.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "byte-tools 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "bs58" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "bstr" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "memchr 2.2.0 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "bumpalo" -version = "2.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "byte-tools" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "byte-tools" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "byteorder" -version = "0.5.3" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "byteorder" -version = "1.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "bytes" -version = "0.4.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "byteorder 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)", - "iovec 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "c_linked_list" -version = "1.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "cc" -version = "1.0.26" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "rayon 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "cexpr" -version = "0.3.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "nom 4.2.3 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "cfg-if" -version = "0.1.7" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "chain-spec-builder" -version = "0.1.0" -dependencies = [ - "clap 2.32.0 (registry+https://github.com/rust-lang/crates.io-index)", - "node-cli 1.0.0", - "substrate-primitives 1.0.0", - "substrate-service 1.0.0", -] - -[[package]] -name = "chrono" -version = "0.4.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "num-integer 0.1.39 (registry+https://github.com/rust-lang/crates.io-index)", - "num-traits 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)", - "time 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "clang-sys" -version = "0.26.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "glob 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.54 (registry+https://github.com/rust-lang/crates.io-index)", - "libloading 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "clap" -version = "2.32.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "ansi_term 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)", - "atty 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", - "bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", - "strsim 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", - "textwrap 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)", - "unicode-width 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", - "vec_map 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)", - "yaml-rust 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "clear_on_drop" -version = "0.2.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "cc 1.0.26 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "cloudabi" -version = "0.0.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "constant_time_eq" -version = "0.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "core-foundation" -version = "0.6.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "core-foundation-sys 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.54 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "core-foundation-sys" -version = "0.6.2" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "crossbeam" -version = "0.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "cfg-if 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)", - "crossbeam-channel 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", - "crossbeam-deque 0.6.3 (registry+https://github.com/rust-lang/crates.io-index)", - "crossbeam-epoch 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)", - "crossbeam-utils 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", - "lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", - "num_cpus 1.10.0 (registry+https://github.com/rust-lang/crates.io-index)", - "parking_lot 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "crossbeam-channel" -version = "0.3.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "crossbeam-utils 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", - "smallvec 0.6.10 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "crossbeam-deque" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "crossbeam-epoch 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", - "crossbeam-utils 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "crossbeam-deque" -version = "0.6.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "crossbeam-epoch 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)", - "crossbeam-utils 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "crossbeam-deque" -version = "0.7.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "crossbeam-epoch 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)", - "crossbeam-utils 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "crossbeam-epoch" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "arrayvec 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)", - "cfg-if 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)", - "crossbeam-utils 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", - "lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", - "memoffset 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", - "nodrop 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)", - "scopeguard 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "crossbeam-epoch" -version = "0.7.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "arrayvec 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)", - "cfg-if 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)", - "crossbeam-utils 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", - "lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", - "memoffset 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", - "scopeguard 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "crossbeam-queue" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "crossbeam-utils 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "crossbeam-utils" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "cfg-if 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "crossbeam-utils" -version = "0.6.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "cfg-if 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)", - "lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "crunchy" -version = "0.1.6" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "crunchy" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "crypto-mac" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "constant_time_eq 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", - "generic-array 0.8.3 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "crypto-mac" -version = "0.6.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "constant_time_eq 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", - "generic-array 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "crypto-mac" -version = "0.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "generic-array 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)", - "subtle 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "ctr" -version = "0.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "block-cipher-trait 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", - "stream-cipher 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "cuckoofilter" -version = "0.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "byteorder 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)", - "rand 0.3.23 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "curve25519-dalek" -version = "1.1.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "byteorder 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)", - "clear_on_drop 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", - "digest 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", - "rand_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", - "subtle 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "data-encoding" -version = "2.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "derive_more" -version = "0.14.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "proc-macro2 0.4.30 (registry+https://github.com/rust-lang/crates.io-index)", - "quote 0.6.12 (registry+https://github.com/rust-lang/crates.io-index)", - "rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", - "syn 0.15.34 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "digest" -version = "0.6.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "generic-array 0.8.3 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "digest" -version = "0.7.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "generic-array 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "digest" -version = "0.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "generic-array 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "discard" -version = "1.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "dns-parser" -version = "0.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "byteorder 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)", - "quick-error 1.2.2 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "ed25519-dalek" -version = "1.0.0-pre.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "clear_on_drop 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", - "curve25519-dalek 1.1.4 (registry+https://github.com/rust-lang/crates.io-index)", - "failure 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", - "rand 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", - "sha2 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "either" -version = "1.5.2" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "elastic-array" -version = "0.10.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "heapsize 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "env_logger" -version = "0.6.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "atty 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", - "humantime 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", - "regex 1.1.6 (registry+https://github.com/rust-lang/crates.io-index)", - "termcolor 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "environmental" -version = "1.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "erased-serde" -version = "0.3.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "serde 1.0.91 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "error-chain" -version = "0.12.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "backtrace 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "exit-future" -version = "0.1.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "futures 0.1.26 (registry+https://github.com/rust-lang/crates.io-index)", - "parking_lot 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "failure" -version = "0.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "backtrace 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)", - "failure_derive 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "failure_derive" -version = "0.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "proc-macro2 0.4.30 (registry+https://github.com/rust-lang/crates.io-index)", - "quote 0.6.12 (registry+https://github.com/rust-lang/crates.io-index)", - "syn 0.15.34 (registry+https://github.com/rust-lang/crates.io-index)", - "synstructure 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "fake-simd" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "fdlimit" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "libc 0.2.54 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "finality-grandpa" -version = "0.7.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "futures 0.1.26 (registry+https://github.com/rust-lang/crates.io-index)", - "hashmap_core 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", - "num-traits 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)", - "parity-codec 3.5.1 (registry+https://github.com/rust-lang/crates.io-index)", - "parity-codec-derive 3.3.0 (registry+https://github.com/rust-lang/crates.io-index)", - "parking_lot 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "fixed-hash" -version = "0.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "byteorder 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)", - "heapsize 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.54 (registry+https://github.com/rust-lang/crates.io-index)", - "rand 0.5.6 (registry+https://github.com/rust-lang/crates.io-index)", - "rustc-hex 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)", - "static_assertions 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "fnv" -version = "1.0.6" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "foreign-types" -version = "0.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "foreign-types-shared 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "foreign-types-shared" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "fork-tree" -version = "1.0.0" -dependencies = [ - "parity-codec 3.5.1 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "fs-swap" -version = "0.2.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.54 (registry+https://github.com/rust-lang/crates.io-index)", - "libloading 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "fuchsia-cprng" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "fuchsia-zircon" -version = "0.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", - "fuchsia-zircon-sys 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "fuchsia-zircon-sys" -version = "0.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "futures" -version = "0.1.26" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "futures-cpupool" -version = "0.1.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "futures 0.1.26 (registry+https://github.com/rust-lang/crates.io-index)", - "num_cpus 1.10.0 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "gcc" -version = "0.3.55" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "generic-array" -version = "0.8.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "nodrop 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)", - "typenum 1.10.0 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "generic-array" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "typenum 1.10.0 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "generic-array" -version = "0.12.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "typenum 1.10.0 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "get_if_addrs" -version = "0.5.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "c_linked_list 1.1.1 (registry+https://github.com/rust-lang/crates.io-index)", - "get_if_addrs-sys 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.54 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "get_if_addrs-sys" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "gcc 0.3.55 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.54 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "glob" -version = "0.2.11" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "globset" -version = "0.4.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "aho-corasick 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)", - "bstr 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", - "fnv 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", - "regex 1.1.6 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "h2" -version = "0.1.18" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "byteorder 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)", - "bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)", - "fnv 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", - "futures 0.1.26 (registry+https://github.com/rust-lang/crates.io-index)", - "http 0.1.17 (registry+https://github.com/rust-lang/crates.io-index)", - "indexmap 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", - "slab 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", - "string 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-io 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "hash-db" -version = "0.12.2" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "hash256-std-hasher" -version = "0.12.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "crunchy 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "hashbrown" -version = "0.1.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "byteorder 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)", - "scopeguard 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "hashmap_core" -version = "0.1.10" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "heapsize" -version = "0.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "heck" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "unicode-segmentation 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "hex" -version = "0.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "hex-literal" -version = "0.1.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "hex-literal-impl 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", - "proc-macro-hack 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "hex-literal" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "hex-literal-impl 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", - "proc-macro-hack 0.5.7 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "hex-literal-impl" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "proc-macro-hack 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "hex-literal-impl" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "proc-macro-hack 0.5.7 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "hmac" -version = "0.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "crypto-mac 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", - "digest 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", - "generic-array 0.8.3 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "hmac" -version = "0.6.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "crypto-mac 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", - "digest 0.7.6 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "hmac" -version = "0.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "crypto-mac 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", - "digest 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "hmac-drbg" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "digest 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", - "generic-array 0.8.3 (registry+https://github.com/rust-lang/crates.io-index)", - "hmac 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "http" -version = "0.1.17" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)", - "fnv 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", - "itoa 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "httparse" -version = "1.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "humantime" -version = "1.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "quick-error 1.2.2 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "hyper" -version = "0.10.16" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "base64 0.9.3 (registry+https://github.com/rust-lang/crates.io-index)", - "httparse 1.3.3 (registry+https://github.com/rust-lang/crates.io-index)", - "language-tags 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", - "mime 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)", - "num_cpus 1.10.0 (registry+https://github.com/rust-lang/crates.io-index)", - "time 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)", - "traitobject 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "typeable 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", - "unicase 1.4.2 (registry+https://github.com/rust-lang/crates.io-index)", - "url 1.7.2 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "hyper" -version = "0.12.28" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)", - "futures 0.1.26 (registry+https://github.com/rust-lang/crates.io-index)", - "futures-cpupool 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", - "h2 0.1.18 (registry+https://github.com/rust-lang/crates.io-index)", - "http 0.1.17 (registry+https://github.com/rust-lang/crates.io-index)", - "httparse 1.3.3 (registry+https://github.com/rust-lang/crates.io-index)", - "iovec 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", - "itoa 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", - "net2 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)", - "rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", - "time 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio 0.1.19 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-executor 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-io 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-reactor 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-tcp 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-threadpool 0.1.14 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-timer 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)", - "want 0.0.6 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "idna" -version = "0.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "matches 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", - "unicode-bidi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", - "unicode-normalization 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "impl-codec" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "parity-codec 3.5.1 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "impl-serde" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "rustc-hex 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.91 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "indexmap" -version = "1.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "integer-sqrt" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "interleaved-ordered" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "iovec" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "libc 0.2.54 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "itoa" -version = "0.4.4" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "js-sys" -version = "0.3.20" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "wasm-bindgen 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "jsonrpc-core" -version = "10.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "futures 0.1.26 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.91 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_derive 1.0.91 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_json 1.0.39 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "jsonrpc-derive" -version = "10.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "proc-macro2 0.4.30 (registry+https://github.com/rust-lang/crates.io-index)", - "quote 0.6.12 (registry+https://github.com/rust-lang/crates.io-index)", - "syn 0.15.34 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "jsonrpc-http-server" -version = "10.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "hyper 0.12.28 (registry+https://github.com/rust-lang/crates.io-index)", - "jsonrpc-core 10.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "jsonrpc-server-utils 10.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", - "net2 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)", - "unicase 2.4.0 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "jsonrpc-pubsub" -version = "10.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "jsonrpc-core 10.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", - "parking_lot 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.91 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "jsonrpc-server-utils" -version = "10.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)", - "globset 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)", - "jsonrpc-core 10.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", - "num_cpus 1.10.0 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio 0.1.19 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-codec 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", - "unicase 2.4.0 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "jsonrpc-ws-server" -version = "10.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "error-chain 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)", - "jsonrpc-core 10.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "jsonrpc-server-utils 10.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", - "parity-ws 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", - "parking_lot 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)", - "slab 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "keccak" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "kernel32-sys" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "kvdb" -version = "0.1.0" -source = "git+https://github.com/paritytech/parity-common?rev=b0317f649ab2c665b7987b8475878fc4d2e1f81d#b0317f649ab2c665b7987b8475878fc4d2e1f81d" -dependencies = [ - "elastic-array 0.10.2 (registry+https://github.com/rust-lang/crates.io-index)", - "parity-bytes 0.1.0 (git+https://github.com/paritytech/parity-common?rev=b0317f649ab2c665b7987b8475878fc4d2e1f81d)", -] - -[[package]] -name = "kvdb-rocksdb" -version = "0.1.4" -source = "git+https://github.com/paritytech/parity-common?rev=b0317f649ab2c665b7987b8475878fc4d2e1f81d#b0317f649ab2c665b7987b8475878fc4d2e1f81d" -dependencies = [ - "elastic-array 0.10.2 (registry+https://github.com/rust-lang/crates.io-index)", - "fs-swap 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)", - "interleaved-ordered 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", - "kvdb 0.1.0 (git+https://github.com/paritytech/parity-common?rev=b0317f649ab2c665b7987b8475878fc4d2e1f81d)", - "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", - "num_cpus 1.10.0 (registry+https://github.com/rust-lang/crates.io-index)", - "parking_lot 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)", - "regex 1.1.6 (registry+https://github.com/rust-lang/crates.io-index)", - "rocksdb 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "language-tags" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "lazy_static" -version = "1.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "lazycell" -version = "1.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "libc" -version = "0.2.54" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "libloading" -version = "0.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "cc 1.0.26 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "libp2p" -version = "0.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)", - "futures 0.1.26 (registry+https://github.com/rust-lang/crates.io-index)", - "lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", - "libp2p-core 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", - "libp2p-core-derive 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", - "libp2p-dns 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", - "libp2p-floodsub 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", - "libp2p-identify 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", - "libp2p-kad 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", - "libp2p-mdns 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", - "libp2p-mplex 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", - "libp2p-noise 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", - "libp2p-ping 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", - "libp2p-plaintext 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", - "libp2p-ratelimit 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", - "libp2p-secio 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", - "libp2p-tcp 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", - "libp2p-uds 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", - "libp2p-websocket 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", - "libp2p-yamux 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", - "parity-multiaddr 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", - "parity-multihash 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", - "parking_lot 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)", - "smallvec 0.6.10 (registry+https://github.com/rust-lang/crates.io-index)", - "stdweb 0.4.17 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-codec 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-executor 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-io 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "libp2p-core" -version = "0.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "asn1_der 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)", - "bs58 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", - "bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)", - "ed25519-dalek 1.0.0-pre.1 (registry+https://github.com/rust-lang/crates.io-index)", - "failure 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", - "fnv 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", - "futures 0.1.26 (registry+https://github.com/rust-lang/crates.io-index)", - "lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", - "multistream-select 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", - "parity-multiaddr 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", - "parity-multihash 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", - "parking_lot 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)", - "protobuf 2.5.0 (registry+https://github.com/rust-lang/crates.io-index)", - "quick-error 1.2.2 (registry+https://github.com/rust-lang/crates.io-index)", - "rand 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", - "ring 0.14.6 (registry+https://github.com/rust-lang/crates.io-index)", - "rw-stream-sink 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", - "secp256k1 0.12.2 (registry+https://github.com/rust-lang/crates.io-index)", - "sha2 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", - "smallvec 0.6.10 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-executor 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-io 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-timer 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)", - "unsigned-varint 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", - "untrusted 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", - "void 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", - "zeroize 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "libp2p-core-derive" -version = "0.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "quote 0.6.12 (registry+https://github.com/rust-lang/crates.io-index)", - "syn 0.15.34 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "libp2p-dns" -version = "0.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "futures 0.1.26 (registry+https://github.com/rust-lang/crates.io-index)", - "libp2p-core 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", - "parity-multiaddr 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-dns-unofficial 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-io 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "libp2p-floodsub" -version = "0.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "bs58 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", - "bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)", - "cuckoofilter 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", - "fnv 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", - "futures 0.1.26 (registry+https://github.com/rust-lang/crates.io-index)", - "libp2p-core 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", - "protobuf 2.5.0 (registry+https://github.com/rust-lang/crates.io-index)", - "rand 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", - "smallvec 0.6.10 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-codec 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-io 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", - "unsigned-varint 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "libp2p-identify" -version = "0.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)", - "fnv 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", - "futures 0.1.26 (registry+https://github.com/rust-lang/crates.io-index)", - "libp2p-core 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", - "parity-multiaddr 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", - "parking_lot 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)", - "protobuf 2.5.0 (registry+https://github.com/rust-lang/crates.io-index)", - "smallvec 0.6.10 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-codec 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-io 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-timer 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)", - "unsigned-varint 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", - "void 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "libp2p-kad" -version = "0.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "arrayref 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)", - "arrayvec 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)", - "bigint 4.4.1 (registry+https://github.com/rust-lang/crates.io-index)", - "bs58 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", - "bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)", - "fnv 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", - "futures 0.1.26 (registry+https://github.com/rust-lang/crates.io-index)", - "libp2p-core 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", - "parity-multiaddr 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", - "parity-multihash 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", - "parking_lot 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)", - "protobuf 2.5.0 (registry+https://github.com/rust-lang/crates.io-index)", - "rand 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", - "smallvec 0.6.10 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-codec 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-io 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-timer 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)", - "unsigned-varint 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", - "void 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "libp2p-mdns" -version = "0.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "data-encoding 2.1.2 (registry+https://github.com/rust-lang/crates.io-index)", - "dns-parser 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", - "futures 0.1.26 (registry+https://github.com/rust-lang/crates.io-index)", - "libp2p-core 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", - "net2 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)", - "parity-multiaddr 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", - "rand 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", - "smallvec 0.6.10 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-io 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-reactor 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-timer 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-udp 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", - "void 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "libp2p-mplex" -version = "0.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)", - "fnv 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", - "futures 0.1.26 (registry+https://github.com/rust-lang/crates.io-index)", - "libp2p-core 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", - "parking_lot 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-codec 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-io 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", - "unsigned-varint 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "libp2p-noise" -version = "0.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "curve25519-dalek 1.1.4 (registry+https://github.com/rust-lang/crates.io-index)", - "futures 0.1.26 (registry+https://github.com/rust-lang/crates.io-index)", - "lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", - "libp2p-core 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", - "rand 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", - "ring 0.14.6 (registry+https://github.com/rust-lang/crates.io-index)", - "snow 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-io 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", - "x25519-dalek 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)", - "zeroize 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "libp2p-ping" -version = "0.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "arrayvec 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)", - "bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)", - "futures 0.1.26 (registry+https://github.com/rust-lang/crates.io-index)", - "libp2p-core 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", - "parity-multiaddr 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", - "parking_lot 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)", - "rand 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-codec 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-io 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-timer 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)", - "void 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "libp2p-plaintext" -version = "0.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "futures 0.1.26 (registry+https://github.com/rust-lang/crates.io-index)", - "libp2p-core 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", - "void 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "libp2p-ratelimit" -version = "0.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "aio-limited 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "futures 0.1.26 (registry+https://github.com/rust-lang/crates.io-index)", - "libp2p-core 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-executor 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-io 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "libp2p-secio" -version = "0.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "aes-ctr 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", - "asn1_der 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)", - "bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)", - "ctr 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", - "futures 0.1.26 (registry+https://github.com/rust-lang/crates.io-index)", - "hmac 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", - "js-sys 0.3.20 (registry+https://github.com/rust-lang/crates.io-index)", - "lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", - "libp2p-core 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", - "protobuf 2.5.0 (registry+https://github.com/rust-lang/crates.io-index)", - "rand 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", - "ring 0.14.6 (registry+https://github.com/rust-lang/crates.io-index)", - "rw-stream-sink 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", - "secp256k1 0.12.2 (registry+https://github.com/rust-lang/crates.io-index)", - "send_wrapper 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", - "sha2 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-io 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", - "twofish 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", - "untrusted 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", - "wasm-bindgen 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)", - "wasm-bindgen-futures 0.3.20 (registry+https://github.com/rust-lang/crates.io-index)", - "web-sys 0.3.20 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "libp2p-tcp" -version = "0.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "futures 0.1.26 (registry+https://github.com/rust-lang/crates.io-index)", - "get_if_addrs 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)", - "libp2p-core 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", - "parity-multiaddr 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", - "tk-listen 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-io 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-tcp 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "libp2p-uds" -version = "0.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "futures 0.1.26 (registry+https://github.com/rust-lang/crates.io-index)", - "libp2p-core 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", - "parity-multiaddr 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-uds 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "libp2p-websocket" -version = "0.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "futures 0.1.26 (registry+https://github.com/rust-lang/crates.io-index)", - "libp2p-core 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", - "parity-multiaddr 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", - "rw-stream-sink 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", - "stdweb 0.4.17 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-io 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", - "wasm-bindgen 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)", - "websocket 0.22.4 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "libp2p-yamux" -version = "0.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "futures 0.1.26 (registry+https://github.com/rust-lang/crates.io-index)", - "libp2p-core 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-io 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", - "yamux 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "librocksdb-sys" -version = "5.18.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "bindgen 0.47.3 (registry+https://github.com/rust-lang/crates.io-index)", - "cc 1.0.26 (registry+https://github.com/rust-lang/crates.io-index)", - "glob 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.54 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "libsecp256k1" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "arrayref 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)", - "digest 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", - "hmac-drbg 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", - "rand 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", - "sha2 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)", - "typenum 1.10.0 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "linked-hash-map" -version = "0.5.2" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "linked_hash_set" -version = "0.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "linked-hash-map 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "lock_api" -version = "0.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "owning_ref 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", - "scopeguard 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "log" -version = "0.3.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "log" -version = "0.4.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "cfg-if 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "lru-cache" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "linked-hash-map 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "matches" -version = "0.1.8" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "memchr" -version = "2.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "memoffset" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "memory-db" -version = "0.12.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "hash-db 0.12.2 (registry+https://github.com/rust-lang/crates.io-index)", - "hashmap_core 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", - "heapsize 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "memory_units" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "merlin" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "byteorder 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)", - "clear_on_drop 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", - "keccak 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "rand_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "mime" -version = "0.2.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "mio" -version = "0.6.16" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "fuchsia-zircon 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", - "fuchsia-zircon-sys 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", - "iovec 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", - "kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", - "lazycell 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.54 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", - "miow 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", - "net2 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)", - "slab 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "mio-extras" -version = "2.0.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "lazycell 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", - "mio 0.6.16 (registry+https://github.com/rust-lang/crates.io-index)", - "slab 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "mio-uds" -version = "0.6.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "iovec 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.54 (registry+https://github.com/rust-lang/crates.io-index)", - "mio 0.6.16 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "miow" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", - "net2 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", - "ws2_32-sys 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "multistream-select" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)", - "futures 0.1.26 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", - "smallvec 0.6.10 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-codec 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-io 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", - "unsigned-varint 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "names" -version = "0.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "rand 0.3.23 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "native-tls" -version = "0.2.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.54 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", - "openssl 0.10.22 (registry+https://github.com/rust-lang/crates.io-index)", - "openssl-probe 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", - "openssl-sys 0.9.46 (registry+https://github.com/rust-lang/crates.io-index)", - "schannel 0.1.15 (registry+https://github.com/rust-lang/crates.io-index)", - "security-framework 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", - "security-framework-sys 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", - "tempfile 3.0.7 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "net2" -version = "0.2.33" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "cfg-if 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.54 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "node-cli" -version = "1.0.0" -dependencies = [ - "exit-future 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", - "futures 0.1.26 (registry+https://github.com/rust-lang/crates.io-index)", - "hex-literal 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", - "node-executor 1.0.0", - "node-primitives 1.0.0", - "node-runtime 1.0.0", - "parity-codec 3.5.1 (registry+https://github.com/rust-lang/crates.io-index)", - "sr-io 1.0.0", - "sr-primitives 1.0.0", - "structopt 0.2.15 (registry+https://github.com/rust-lang/crates.io-index)", - "substrate-basic-authorship 1.0.0", - "substrate-cli 1.0.0", - "substrate-client 1.0.0", - "substrate-consensus-aura 1.1.0", - "substrate-finality-grandpa 1.0.0", - "substrate-inherents 1.0.0", - "substrate-keystore 1.0.0", - "substrate-network 0.1.0", - "substrate-primitives 1.0.0", - "substrate-service 1.0.0", - "substrate-telemetry 1.0.0", - "substrate-transaction-pool 1.0.0", - "tokio 0.1.19 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "node-executor" -version = "1.0.0" -dependencies = [ - "node-primitives 1.0.0", - "node-runtime 1.0.0", - "parity-codec 3.5.1 (registry+https://github.com/rust-lang/crates.io-index)", - "sr-io 1.0.0", - "substrate-executor 1.0.0", - "substrate-primitives 1.0.0", - "substrate-state-machine 1.0.0", - "substrate-trie 1.0.0", - "trie-root 0.12.2 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "node-primitives" -version = "1.0.0" -dependencies = [ - "parity-codec 3.5.1 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.91 (registry+https://github.com/rust-lang/crates.io-index)", - "sr-primitives 1.0.0", - "sr-std 1.0.0", - "substrate-primitives 1.0.0", -] - -[[package]] -name = "node-runtime" -version = "1.0.0" -dependencies = [ - "integer-sqrt 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", - "node-primitives 1.0.0", - "parity-codec 3.5.1 (registry+https://github.com/rust-lang/crates.io-index)", - "rustc-hex 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)", - "safe-mix 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.91 (registry+https://github.com/rust-lang/crates.io-index)", - "sr-primitives 1.0.0", - "sr-std 1.0.0", - "sr-version 1.0.0", - "srml-aura 1.0.0", - "srml-balances 1.0.0", - "srml-consensus 1.0.0", - "srml-contract 1.0.0", - "srml-council 1.0.0", - "srml-democracy 1.0.0", - "srml-executive 1.0.0", - "srml-finality-tracker 1.0.0", - "srml-grandpa 1.0.0", - "srml-indices 1.0.0", - "srml-session 1.0.0", - "srml-staking 1.0.0", - "srml-sudo 1.0.0", - "srml-support 1.0.0", - "srml-system 1.0.0", - "srml-timestamp 1.0.0", - "srml-treasury 1.0.0", - "substrate-client 1.0.0", - "substrate-consensus-aura-primitives 1.0.0", - "substrate-consensus-authorities 1.0.0", - "substrate-keyring 1.0.0", - "substrate-offchain-primitives 0.1.0", - "substrate-primitives 1.0.0", -] - -[[package]] -name = "nodrop" -version = "0.1.13" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "nohash-hasher" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "nom" -version = "4.2.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "memchr 2.2.0 (registry+https://github.com/rust-lang/crates.io-index)", - "version_check 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "num-integer" -version = "0.1.39" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "num-traits 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "num-traits" -version = "0.2.6" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "num_cpus" -version = "1.10.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "libc 0.2.54 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "numtoa" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "ole32-sys" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "once_cell" -version = "0.1.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "parking_lot 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "opaque-debug" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "openssl" -version = "0.10.22" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", - "cfg-if 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)", - "foreign-types 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", - "lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.54 (registry+https://github.com/rust-lang/crates.io-index)", - "openssl-sys 0.9.46 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "openssl-probe" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "openssl-sys" -version = "0.9.46" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "autocfg 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", - "cc 1.0.26 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.54 (registry+https://github.com/rust-lang/crates.io-index)", - "pkg-config 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)", - "vcpkg 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "owning_ref" -version = "0.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "stable_deref_trait 1.1.1 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "owning_ref" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "stable_deref_trait 1.1.1 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "parity-bytes" -version = "0.1.0" -source = "git+https://github.com/paritytech/parity-common?rev=b0317f649ab2c665b7987b8475878fc4d2e1f81d#b0317f649ab2c665b7987b8475878fc4d2e1f81d" - -[[package]] -name = "parity-codec" -version = "3.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "arrayvec 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)", - "parity-codec-derive 3.3.0 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.91 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "parity-codec-derive" -version = "3.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "proc-macro-crate 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", - "proc-macro2 0.4.30 (registry+https://github.com/rust-lang/crates.io-index)", - "quote 0.6.12 (registry+https://github.com/rust-lang/crates.io-index)", - "syn 0.15.34 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "parity-crypto" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "aes 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", - "aes-ctr 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", - "block-modes 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", - "digest 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", - "quick-error 1.2.2 (registry+https://github.com/rust-lang/crates.io-index)", - "ring 0.14.6 (registry+https://github.com/rust-lang/crates.io-index)", - "ripemd160 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", - "scrypt 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", - "sha2 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", - "tiny-keccak 1.4.2 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "parity-multiaddr" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "arrayref 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)", - "bs58 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", - "byteorder 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)", - "bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)", - "data-encoding 2.1.2 (registry+https://github.com/rust-lang/crates.io-index)", - "parity-multihash 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.91 (registry+https://github.com/rust-lang/crates.io-index)", - "unsigned-varint 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "parity-multihash" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "blake2 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", - "rand 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", - "sha-1 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)", - "sha2 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", - "sha3 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)", - "unsigned-varint 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "parity-wasm" -version = "0.31.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "byteorder 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "parity-ws" -version = "0.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "byteorder 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)", - "bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)", - "httparse 1.3.3 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", - "mio 0.6.16 (registry+https://github.com/rust-lang/crates.io-index)", - "mio-extras 2.0.5 (registry+https://github.com/rust-lang/crates.io-index)", - "rand 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", - "sha1 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)", - "slab 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", - "url 1.7.2 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "parking_lot" -version = "0.5.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "owning_ref 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", - "parking_lot_core 0.2.14 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "parking_lot" -version = "0.6.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "lock_api 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", - "parking_lot_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "parking_lot" -version = "0.7.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "lock_api 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", - "parking_lot_core 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "parking_lot_core" -version = "0.2.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "libc 0.2.54 (registry+https://github.com/rust-lang/crates.io-index)", - "rand 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", - "smallvec 0.6.10 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "parking_lot_core" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "libc 0.2.54 (registry+https://github.com/rust-lang/crates.io-index)", - "rand 0.5.6 (registry+https://github.com/rust-lang/crates.io-index)", - "rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", - "smallvec 0.6.10 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "parking_lot_core" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "libc 0.2.54 (registry+https://github.com/rust-lang/crates.io-index)", - "rand 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", - "rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", - "smallvec 0.6.10 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "paste" -version = "0.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "paste-impl 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", - "proc-macro-hack 0.5.7 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "paste-impl" -version = "0.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "proc-macro-hack 0.5.7 (registry+https://github.com/rust-lang/crates.io-index)", - "proc-macro2 0.4.30 (registry+https://github.com/rust-lang/crates.io-index)", - "quote 0.6.12 (registry+https://github.com/rust-lang/crates.io-index)", - "syn 0.15.34 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "pbkdf2" -version = "0.2.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "byteorder 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)", - "crypto-mac 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", - "generic-array 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "pbkdf2" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "byteorder 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)", - "crypto-mac 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", - "rayon 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "peeking_take_while" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "percent-encoding" -version = "1.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "pkg-config" -version = "0.3.14" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "primitive-types" -version = "0.2.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "fixed-hash 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", - "impl-codec 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", - "impl-serde 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", - "uint 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "proc-macro-crate" -version = "0.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "toml 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "proc-macro-hack" -version = "0.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "proc-macro-hack-impl 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "proc-macro-hack" -version = "0.5.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "proc-macro2 0.4.30 (registry+https://github.com/rust-lang/crates.io-index)", - "quote 0.6.12 (registry+https://github.com/rust-lang/crates.io-index)", - "syn 0.15.34 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "proc-macro-hack-impl" -version = "0.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "proc-macro2" -version = "0.4.30" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "protobuf" -version = "2.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "pwasm-utils" -version = "0.6.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "byteorder 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", - "parity-wasm 0.31.3 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "quick-error" -version = "0.1.4" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "quick-error" -version = "1.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "quote" -version = "0.6.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "proc-macro2 0.4.30 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "rand" -version = "0.3.23" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "libc 0.2.54 (registry+https://github.com/rust-lang/crates.io-index)", - "rand 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "rand" -version = "0.4.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "fuchsia-cprng 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.54 (registry+https://github.com/rust-lang/crates.io-index)", - "rand_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", - "rdrand 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "rand" -version = "0.5.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "cloudabi 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)", - "fuchsia-cprng 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.54 (registry+https://github.com/rust-lang/crates.io-index)", - "rand_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "rand" -version = "0.6.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "autocfg 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.54 (registry+https://github.com/rust-lang/crates.io-index)", - "rand_chacha 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", - "rand_core 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", - "rand_hc 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "rand_isaac 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", - "rand_jitter 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", - "rand_os 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", - "rand_pcg 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", - "rand_xorshift 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "rand_chacha" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "autocfg 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", - "rand_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "rand_core" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "rand_core 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "rand_core" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "rand_hc" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "rand_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "rand_isaac" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "rand_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "rand_jitter" -version = "0.1.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "libc 0.2.54 (registry+https://github.com/rust-lang/crates.io-index)", - "rand_core 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "rand_os" -version = "0.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "cloudabi 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)", - "fuchsia-cprng 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.54 (registry+https://github.com/rust-lang/crates.io-index)", - "rand_core 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", - "rdrand 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "rand_pcg" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "autocfg 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", - "rand_core 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "rand_xorshift" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "rand_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "rayon" -version = "1.0.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "crossbeam-deque 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", - "either 1.5.2 (registry+https://github.com/rust-lang/crates.io-index)", - "rayon-core 1.4.1 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "rayon-core" -version = "1.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "crossbeam-deque 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", - "lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.54 (registry+https://github.com/rust-lang/crates.io-index)", - "num_cpus 1.10.0 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "rdrand" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "rand_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "redox_syscall" -version = "0.1.54" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "redox_termios" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "redox_syscall 0.1.54 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "regex" -version = "1.1.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "aho-corasick 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)", - "memchr 2.2.0 (registry+https://github.com/rust-lang/crates.io-index)", - "regex-syntax 0.6.6 (registry+https://github.com/rust-lang/crates.io-index)", - "thread_local 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", - "utf8-ranges 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "regex-syntax" -version = "0.6.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "ucd-util 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "remove_dir_all" -version = "0.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "ring" -version = "0.14.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "cc 1.0.26 (registry+https://github.com/rust-lang/crates.io-index)", - "lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.54 (registry+https://github.com/rust-lang/crates.io-index)", - "spin 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", - "untrusted 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "ripemd160" -version = "0.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "block-buffer 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)", - "digest 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", - "opaque-debug 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "rocksdb" -version = "0.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "libc 0.2.54 (registry+https://github.com/rust-lang/crates.io-index)", - "librocksdb-sys 5.18.3 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "rustc-demangle" -version = "0.1.14" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "rustc-hex" -version = "2.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "rustc_version" -version = "0.2.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "semver 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "rw-stream-sink" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)", - "futures 0.1.26 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-io 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "ryu" -version = "0.2.8" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "safe-mix" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "safemem" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "schannel" -version = "0.1.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "schnorrkel" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "clear_on_drop 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", - "curve25519-dalek 1.1.4 (registry+https://github.com/rust-lang/crates.io-index)", - "ed25519-dalek 1.0.0-pre.1 (registry+https://github.com/rust-lang/crates.io-index)", - "failure 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", - "merlin 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "rand 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", - "rand_chacha 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", - "sha2 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", - "sha3 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)", - "subtle 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "scopeguard" -version = "0.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "scrypt" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "byte-tools 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", - "byteorder 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)", - "hmac 0.6.3 (registry+https://github.com/rust-lang/crates.io-index)", - "pbkdf2 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", - "sha2 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "secp256k1" -version = "0.12.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "cc 1.0.26 (registry+https://github.com/rust-lang/crates.io-index)", - "rand 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "security-framework" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "core-foundation 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)", - "core-foundation-sys 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.54 (registry+https://github.com/rust-lang/crates.io-index)", - "security-framework-sys 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "security-framework-sys" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "core-foundation-sys 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "semver" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "semver-parser 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "semver-parser" -version = "0.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "send_wrapper" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "serde" -version = "1.0.91" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "serde_derive 1.0.91 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "serde_derive" -version = "1.0.91" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "proc-macro2 0.4.30 (registry+https://github.com/rust-lang/crates.io-index)", - "quote 0.6.12 (registry+https://github.com/rust-lang/crates.io-index)", - "syn 0.15.34 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "serde_json" -version = "1.0.39" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "itoa 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)", - "ryu 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.91 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "sha-1" -version = "0.8.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "block-buffer 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)", - "digest 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", - "fake-simd 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", - "opaque-debug 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "sha1" -version = "0.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "sha2" -version = "0.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "block-buffer 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", - "byte-tools 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", - "digest 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", - "fake-simd 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", - "generic-array 0.8.3 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "sha2" -version = "0.7.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "block-buffer 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", - "byte-tools 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", - "digest 0.7.6 (registry+https://github.com/rust-lang/crates.io-index)", - "fake-simd 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "sha2" -version = "0.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "block-buffer 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)", - "digest 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", - "fake-simd 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", - "opaque-debug 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "sha3" -version = "0.8.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "block-buffer 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)", - "byte-tools 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", - "digest 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", - "keccak 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "opaque-debug 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "shell32-sys" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "slab" -version = "0.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "slog" -version = "2.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "erased-serde 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "slog-async" -version = "2.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "slog 2.4.1 (registry+https://github.com/rust-lang/crates.io-index)", - "take_mut 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", - "thread_local 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "slog-json" -version = "2.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "chrono 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", - "erased-serde 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.91 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_json 1.0.39 (registry+https://github.com/rust-lang/crates.io-index)", - "slog 2.4.1 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "slog-scope" -version = "4.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "crossbeam 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)", - "lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", - "slog 2.4.1 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "slog_derive" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "proc-macro2 0.4.30 (registry+https://github.com/rust-lang/crates.io-index)", - "quote 0.6.12 (registry+https://github.com/rust-lang/crates.io-index)", - "syn 0.15.34 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "smallvec" -version = "0.6.9" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "snow" -version = "0.5.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "arrayref 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)", - "byteorder 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)", - "failure 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", - "failure_derive 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", - "rand_core 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", - "ring 0.14.6 (registry+https://github.com/rust-lang/crates.io-index)", - "rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", - "smallvec 0.6.10 (registry+https://github.com/rust-lang/crates.io-index)", - "static_slice 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)", - "subtle 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "sourcefile" -version = "0.1.4" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "spin" -version = "0.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "sr-api-macros" -version = "1.0.0" -dependencies = [ - "blake2-rfc 0.2.18 (registry+https://github.com/rust-lang/crates.io-index)", - "proc-macro-crate 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", - "proc-macro2 0.4.30 (registry+https://github.com/rust-lang/crates.io-index)", - "quote 0.6.12 (registry+https://github.com/rust-lang/crates.io-index)", - "syn 0.15.34 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "sr-io" -version = "1.0.0" -dependencies = [ - "environmental 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", - "hash-db 0.12.2 (registry+https://github.com/rust-lang/crates.io-index)", - "libsecp256k1 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", - "parity-codec 3.5.1 (registry+https://github.com/rust-lang/crates.io-index)", - "rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", - "sr-std 1.0.0", - "substrate-primitives 1.0.0", - "substrate-state-machine 1.0.0", - "substrate-trie 1.0.0", - "tiny-keccak 1.4.2 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "sr-primitives" -version = "1.0.0" -dependencies = [ - "integer-sqrt 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", - "num-traits 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)", - "parity-codec 3.5.1 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.91 (registry+https://github.com/rust-lang/crates.io-index)", - "sr-io 1.0.0", - "sr-std 1.0.0", - "substrate-primitives 1.0.0", -] - -[[package]] -name = "sr-sandbox" -version = "1.0.0" -dependencies = [ - "parity-codec 3.5.1 (registry+https://github.com/rust-lang/crates.io-index)", - "rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", - "sr-std 1.0.0", - "substrate-primitives 1.0.0", - "wasmi 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "sr-std" -version = "1.0.0" -dependencies = [ - "rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "sr-version" -version = "1.0.0" -dependencies = [ - "impl-serde 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", - "parity-codec 3.5.1 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.91 (registry+https://github.com/rust-lang/crates.io-index)", - "sr-primitives 1.0.0", - "sr-std 1.0.0", -] - -[[package]] -name = "srml-aura" -version = "1.0.0" -dependencies = [ - "parity-codec 3.5.1 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.91 (registry+https://github.com/rust-lang/crates.io-index)", - "sr-primitives 1.0.0", - "sr-std 1.0.0", - "srml-session 1.0.0", - "srml-staking 1.0.0", - "srml-support 1.0.0", - "srml-system 1.0.0", - "srml-timestamp 1.0.0", - "substrate-inherents 1.0.0", -] - -[[package]] -name = "srml-balances" -version = "1.0.0" -dependencies = [ - "parity-codec 3.5.1 (registry+https://github.com/rust-lang/crates.io-index)", - "safe-mix 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.91 (registry+https://github.com/rust-lang/crates.io-index)", - "sr-primitives 1.0.0", - "sr-std 1.0.0", - "srml-support 1.0.0", - "srml-system 1.0.0", - "substrate-keyring 1.0.0", -] - -[[package]] -name = "srml-consensus" -version = "1.0.0" -dependencies = [ - "parity-codec 3.5.1 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.91 (registry+https://github.com/rust-lang/crates.io-index)", - "sr-primitives 1.0.0", - "sr-std 1.0.0", - "srml-support 1.0.0", - "srml-system 1.0.0", - "substrate-inherents 1.0.0", - "substrate-primitives 1.0.0", -] - -[[package]] -name = "srml-contract" -version = "1.0.0" -dependencies = [ - "parity-codec 3.5.1 (registry+https://github.com/rust-lang/crates.io-index)", - "parity-wasm 0.31.3 (registry+https://github.com/rust-lang/crates.io-index)", - "pwasm-utils 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.91 (registry+https://github.com/rust-lang/crates.io-index)", - "sr-io 1.0.0", - "sr-primitives 1.0.0", - "sr-sandbox 1.0.0", - "sr-std 1.0.0", - "srml-support 1.0.0", - "srml-system 1.0.0", - "srml-timestamp 1.0.0", - "substrate-primitives 1.0.0", - "wasmi-validation 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "srml-council" -version = "1.0.0" -dependencies = [ - "parity-codec 3.5.1 (registry+https://github.com/rust-lang/crates.io-index)", - "safe-mix 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.91 (registry+https://github.com/rust-lang/crates.io-index)", - "sr-io 1.0.0", - "sr-primitives 1.0.0", - "sr-std 1.0.0", - "srml-democracy 1.0.0", - "srml-support 1.0.0", - "srml-system 1.0.0", - "substrate-primitives 1.0.0", -] - -[[package]] -name = "srml-democracy" -version = "1.0.0" -dependencies = [ - "parity-codec 3.5.1 (registry+https://github.com/rust-lang/crates.io-index)", - "safe-mix 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.91 (registry+https://github.com/rust-lang/crates.io-index)", - "sr-io 1.0.0", - "sr-primitives 1.0.0", - "sr-std 1.0.0", - "srml-support 1.0.0", - "srml-system 1.0.0", -] - -[[package]] -name = "srml-executive" -version = "1.0.0" -dependencies = [ - "parity-codec 3.5.1 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.91 (registry+https://github.com/rust-lang/crates.io-index)", - "sr-io 1.0.0", - "sr-primitives 1.0.0", - "sr-std 1.0.0", - "srml-support 1.0.0", - "srml-system 1.0.0", -] - -[[package]] -name = "srml-finality-tracker" -version = "1.0.0" -dependencies = [ - "parity-codec 3.5.1 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.91 (registry+https://github.com/rust-lang/crates.io-index)", - "sr-primitives 1.0.0", - "sr-std 1.0.0", - "srml-support 1.0.0", - "srml-system 1.0.0", - "substrate-inherents 1.0.0", -] - -[[package]] -name = "srml-grandpa" -version = "1.0.0" -dependencies = [ - "parity-codec 3.5.1 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.91 (registry+https://github.com/rust-lang/crates.io-index)", - "sr-primitives 1.0.0", - "sr-std 1.0.0", - "srml-consensus 1.0.0", - "srml-finality-tracker 1.0.0", - "srml-session 1.0.0", - "srml-support 1.0.0", - "srml-system 1.0.0", - "substrate-finality-grandpa-primitives 1.0.0", - "substrate-primitives 1.0.0", -] - -[[package]] -name = "srml-indices" -version = "1.0.0" -dependencies = [ - "parity-codec 3.5.1 (registry+https://github.com/rust-lang/crates.io-index)", - "safe-mix 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.91 (registry+https://github.com/rust-lang/crates.io-index)", - "sr-io 1.0.0", - "sr-primitives 1.0.0", - "sr-std 1.0.0", - "srml-support 1.0.0", - "srml-system 1.0.0", - "substrate-keyring 1.0.0", - "substrate-primitives 1.0.0", -] - -[[package]] -name = "srml-metadata" -version = "1.0.0" -dependencies = [ - "parity-codec 3.5.1 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.91 (registry+https://github.com/rust-lang/crates.io-index)", - "sr-std 1.0.0", - "substrate-primitives 1.0.0", -] - -[[package]] -name = "srml-session" -version = "1.0.0" -dependencies = [ - "parity-codec 3.5.1 (registry+https://github.com/rust-lang/crates.io-index)", - "safe-mix 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.91 (registry+https://github.com/rust-lang/crates.io-index)", - "sr-primitives 1.0.0", - "sr-std 1.0.0", - "srml-consensus 1.0.0", - "srml-support 1.0.0", - "srml-system 1.0.0", - "srml-timestamp 1.0.0", -] - -[[package]] -name = "srml-staking" -version = "1.0.0" -dependencies = [ - "parity-codec 3.5.1 (registry+https://github.com/rust-lang/crates.io-index)", - "safe-mix 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.91 (registry+https://github.com/rust-lang/crates.io-index)", - "sr-io 1.0.0", - "sr-primitives 1.0.0", - "sr-std 1.0.0", - "srml-consensus 1.0.0", - "srml-session 1.0.0", - "srml-support 1.0.0", - "srml-system 1.0.0", - "substrate-keyring 1.0.0", -] - -[[package]] -name = "srml-sudo" -version = "1.0.0" -dependencies = [ - "parity-codec 3.5.1 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.91 (registry+https://github.com/rust-lang/crates.io-index)", - "sr-primitives 1.0.0", - "sr-std 1.0.0", - "srml-support 1.0.0", - "srml-support-procedural 1.0.0", - "srml-system 1.0.0", -] - -[[package]] -name = "srml-support" -version = "1.0.0" -dependencies = [ - "bitmask 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", - "once_cell 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", - "parity-codec 3.5.1 (registry+https://github.com/rust-lang/crates.io-index)", - "paste 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.91 (registry+https://github.com/rust-lang/crates.io-index)", - "sr-io 1.0.0", - "sr-primitives 1.0.0", - "sr-std 1.0.0", - "srml-metadata 1.0.0", - "srml-support-procedural 1.0.0", - "substrate-inherents 1.0.0", -] - -[[package]] -name = "srml-support-procedural" -version = "1.0.0" -dependencies = [ - "proc-macro2 0.4.30 (registry+https://github.com/rust-lang/crates.io-index)", - "quote 0.6.12 (registry+https://github.com/rust-lang/crates.io-index)", - "sr-api-macros 1.0.0", - "srml-support-procedural-tools 1.0.0", - "syn 0.15.34 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "srml-support-procedural-tools" -version = "1.0.0" -dependencies = [ - "proc-macro-crate 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", - "proc-macro2 0.4.30 (registry+https://github.com/rust-lang/crates.io-index)", - "quote 0.6.12 (registry+https://github.com/rust-lang/crates.io-index)", - "srml-support-procedural-tools-derive 1.0.0", - "syn 0.15.34 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "srml-support-procedural-tools-derive" -version = "1.0.0" -dependencies = [ - "proc-macro2 0.4.30 (registry+https://github.com/rust-lang/crates.io-index)", - "quote 0.6.12 (registry+https://github.com/rust-lang/crates.io-index)", - "syn 0.15.34 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "srml-system" -version = "1.0.0" -dependencies = [ - "parity-codec 3.5.1 (registry+https://github.com/rust-lang/crates.io-index)", - "safe-mix 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.91 (registry+https://github.com/rust-lang/crates.io-index)", - "sr-io 1.0.0", - "sr-primitives 1.0.0", - "sr-std 1.0.0", - "srml-support 1.0.0", - "substrate-primitives 1.0.0", -] - -[[package]] -name = "srml-timestamp" -version = "1.0.0" -dependencies = [ - "parity-codec 3.5.1 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.91 (registry+https://github.com/rust-lang/crates.io-index)", - "sr-primitives 1.0.0", - "sr-std 1.0.0", - "srml-support 1.0.0", - "srml-system 1.0.0", - "substrate-inherents 1.0.0", -] - -[[package]] -name = "srml-treasury" -version = "1.0.0" -dependencies = [ - "parity-codec 3.5.1 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.91 (registry+https://github.com/rust-lang/crates.io-index)", - "sr-primitives 1.0.0", - "sr-std 1.0.0", - "srml-balances 1.0.0", - "srml-support 1.0.0", - "srml-system 1.0.0", -] - -[[package]] -name = "stable_deref_trait" -version = "1.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "static_assertions" -version = "0.2.5" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "static_slice" -version = "0.0.3" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "stdweb" -version = "0.4.17" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "discard 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", - "rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", - "stdweb-derive 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", - "stdweb-internal-macros 0.2.7 (registry+https://github.com/rust-lang/crates.io-index)", - "stdweb-internal-runtime 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", - "wasm-bindgen 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "stdweb-derive" -version = "0.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "proc-macro2 0.4.30 (registry+https://github.com/rust-lang/crates.io-index)", - "quote 0.6.12 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.91 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_derive 1.0.91 (registry+https://github.com/rust-lang/crates.io-index)", - "syn 0.15.34 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "stdweb-internal-macros" -version = "0.2.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "base-x 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)", - "proc-macro2 0.4.30 (registry+https://github.com/rust-lang/crates.io-index)", - "quote 0.6.12 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.91 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_derive 1.0.91 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_json 1.0.39 (registry+https://github.com/rust-lang/crates.io-index)", - "sha1 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)", - "syn 0.15.34 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "stdweb-internal-runtime" -version = "0.1.4" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "stream-cipher" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "generic-array 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "string" -version = "0.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "strsim" -version = "0.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "structopt" -version = "0.2.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "clap 2.32.0 (registry+https://github.com/rust-lang/crates.io-index)", - "structopt-derive 0.2.15 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "structopt-derive" -version = "0.2.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "heck 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", - "proc-macro2 0.4.30 (registry+https://github.com/rust-lang/crates.io-index)", - "quote 0.6.12 (registry+https://github.com/rust-lang/crates.io-index)", - "syn 0.15.34 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "strum" -version = "0.14.0" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "strum_macros" -version = "0.14.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "heck 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", - "proc-macro2 0.4.30 (registry+https://github.com/rust-lang/crates.io-index)", - "quote 0.6.12 (registry+https://github.com/rust-lang/crates.io-index)", - "syn 0.15.34 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "substrate-basic-authorship" -version = "1.0.0" -dependencies = [ - "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", - "parity-codec 3.5.1 (registry+https://github.com/rust-lang/crates.io-index)", - "sr-primitives 1.0.0", - "substrate-client 1.0.0", - "substrate-consensus-aura-primitives 1.0.0", - "substrate-consensus-common 1.0.0", - "substrate-inherents 1.0.0", - "substrate-primitives 1.0.0", - "substrate-telemetry 1.0.0", - "substrate-transaction-pool 1.0.0", -] - -[[package]] -name = "substrate-bip39" -version = "0.2.1" -source = "git+https://github.com/paritytech/substrate-bip39#44307fda4ea17fe97aeb93af317fbc8f6ed34193" -dependencies = [ - "hmac 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", - "pbkdf2 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", - "schnorrkel 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", - "sha2 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "substrate-cli" -version = "1.0.0" -dependencies = [ - "ansi_term 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)", - "app_dirs 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)", - "atty 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", - "clap 2.32.0 (registry+https://github.com/rust-lang/crates.io-index)", - "env_logger 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)", - "error-chain 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)", - "exit-future 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", - "fdlimit 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", - "futures 0.1.26 (registry+https://github.com/rust-lang/crates.io-index)", - "lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", - "names 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)", - "regex 1.1.6 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_json 1.0.39 (registry+https://github.com/rust-lang/crates.io-index)", - "sr-primitives 1.0.0", - "structopt 0.2.15 (registry+https://github.com/rust-lang/crates.io-index)", - "substrate-client 1.0.0", - "substrate-keyring 1.0.0", - "substrate-network 0.1.0", - "substrate-panic-handler 1.0.0", - "substrate-primitives 1.0.0", - "substrate-service 1.0.0", - "substrate-state-machine 1.0.0", - "substrate-telemetry 1.0.0", - "sysinfo 0.8.3 (registry+https://github.com/rust-lang/crates.io-index)", - "time 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio 0.1.19 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "substrate-client" -version = "1.0.0" -dependencies = [ - "derive_more 0.14.0 (registry+https://github.com/rust-lang/crates.io-index)", - "fnv 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", - "futures 0.1.26 (registry+https://github.com/rust-lang/crates.io-index)", - "hash-db 0.12.2 (registry+https://github.com/rust-lang/crates.io-index)", - "hex-literal 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", - "kvdb 0.1.0 (git+https://github.com/paritytech/parity-common?rev=b0317f649ab2c665b7987b8475878fc4d2e1f81d)", - "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", - "parity-codec 3.5.1 (registry+https://github.com/rust-lang/crates.io-index)", - "parking_lot 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)", - "sr-api-macros 1.0.0", - "sr-primitives 1.0.0", - "sr-std 1.0.0", - "sr-version 1.0.0", - "substrate-consensus-common 1.0.0", - "substrate-executor 1.0.0", - "substrate-inherents 1.0.0", - "substrate-keyring 1.0.0", - "substrate-primitives 1.0.0", - "substrate-state-machine 1.0.0", - "substrate-telemetry 1.0.0", - "substrate-trie 1.0.0", -] - -[[package]] -name = "substrate-client-db" -version = "1.0.0" -dependencies = [ - "hash-db 0.12.2 (registry+https://github.com/rust-lang/crates.io-index)", - "kvdb 0.1.0 (git+https://github.com/paritytech/parity-common?rev=b0317f649ab2c665b7987b8475878fc4d2e1f81d)", - "kvdb-rocksdb 0.1.4 (git+https://github.com/paritytech/parity-common?rev=b0317f649ab2c665b7987b8475878fc4d2e1f81d)", - "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", - "lru-cache 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", - "parity-codec 3.5.1 (registry+https://github.com/rust-lang/crates.io-index)", - "parking_lot 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)", - "sr-primitives 1.0.0", - "substrate-client 1.0.0", - "substrate-consensus-common 1.0.0", - "substrate-executor 1.0.0", - "substrate-primitives 1.0.0", - "substrate-state-db 1.0.0", - "substrate-state-machine 1.0.0", - "substrate-trie 1.0.0", -] - -[[package]] -name = "substrate-consensus-aura" -version = "1.1.0" -dependencies = [ - "error-chain 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)", - "futures 0.1.26 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", - "parity-codec 3.5.1 (registry+https://github.com/rust-lang/crates.io-index)", - "parking_lot 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)", - "sr-io 1.0.0", - "sr-primitives 1.0.0", - "sr-version 1.0.0", - "srml-aura 1.0.0", - "srml-consensus 1.0.0", - "srml-support 1.0.0", - "substrate-client 1.0.0", - "substrate-consensus-aura-primitives 1.0.0", - "substrate-consensus-authorities 1.0.0", - "substrate-consensus-common 1.0.0", - "substrate-consensus-slots 1.1.0", - "substrate-inherents 1.0.0", - "substrate-primitives 1.0.0", - "substrate-telemetry 1.0.0", - "tokio 0.1.19 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "substrate-consensus-aura-primitives" -version = "1.0.0" -dependencies = [ - "sr-primitives 1.0.0", - "substrate-client 1.0.0", -] - -[[package]] -name = "substrate-consensus-authorities" -version = "1.0.0" -dependencies = [ - "parity-codec 3.5.1 (registry+https://github.com/rust-lang/crates.io-index)", - "sr-io 1.0.0", - "sr-primitives 1.0.0", - "sr-std 1.0.0", - "sr-version 1.0.0", - "srml-support 1.0.0", - "substrate-client 1.0.0", - "substrate-primitives 1.0.0", -] - -[[package]] -name = "substrate-consensus-common" -version = "1.0.0" -dependencies = [ - "crossbeam-channel 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", - "error-chain 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)", - "futures 0.1.26 (registry+https://github.com/rust-lang/crates.io-index)", - "libp2p 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", - "parity-codec 3.5.1 (registry+https://github.com/rust-lang/crates.io-index)", - "sr-primitives 1.0.0", - "sr-version 1.0.0", - "substrate-inherents 1.0.0", - "substrate-primitives 1.0.0", - "tokio-timer 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "substrate-consensus-slots" -version = "1.1.0" -dependencies = [ - "error-chain 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)", - "futures 0.1.26 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", - "parity-codec 3.5.1 (registry+https://github.com/rust-lang/crates.io-index)", - "parking_lot 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)", - "sr-primitives 1.0.0", - "substrate-client 1.0.0", - "substrate-consensus-common 1.0.0", - "substrate-inherents 1.0.0", - "substrate-primitives 1.0.0", - "tokio 0.1.19 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "substrate-executor" -version = "1.0.0" -dependencies = [ - "byteorder 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)", - "error-chain 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)", - "lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", - "libsecp256k1 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", - "parity-codec 3.5.1 (registry+https://github.com/rust-lang/crates.io-index)", - "parking_lot 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)", - "sr-io 1.0.0", - "sr-version 1.0.0", - "substrate-panic-handler 1.0.0", - "substrate-primitives 1.0.0", - "substrate-serializer 1.0.0", - "substrate-state-machine 1.0.0", - "substrate-trie 1.0.0", - "tiny-keccak 1.4.2 (registry+https://github.com/rust-lang/crates.io-index)", - "wasmi 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "substrate-finality-grandpa" -version = "1.0.0" -dependencies = [ - "finality-grandpa 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)", - "fork-tree 1.0.0", - "futures 0.1.26 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", - "parity-codec 3.5.1 (registry+https://github.com/rust-lang/crates.io-index)", - "parking_lot 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)", - "rand 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_json 1.0.39 (registry+https://github.com/rust-lang/crates.io-index)", - "sr-primitives 1.0.0", - "srml-finality-tracker 1.0.0", - "substrate-client 1.0.0", - "substrate-consensus-common 1.0.0", - "substrate-finality-grandpa-primitives 1.0.0", - "substrate-inherents 1.0.0", - "substrate-network 0.1.0", - "substrate-primitives 1.0.0", - "substrate-service 1.0.0", - "substrate-telemetry 1.0.0", - "tokio 0.1.19 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "substrate-finality-grandpa-primitives" -version = "1.0.0" -dependencies = [ - "parity-codec 3.5.1 (registry+https://github.com/rust-lang/crates.io-index)", - "sr-primitives 1.0.0", - "sr-std 1.0.0", - "substrate-client 1.0.0", - "substrate-primitives 1.0.0", -] - -[[package]] -name = "substrate-inherents" -version = "1.0.0" -dependencies = [ - "parity-codec 3.5.1 (registry+https://github.com/rust-lang/crates.io-index)", - "parking_lot 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)", - "sr-primitives 1.0.0", - "sr-std 1.0.0", -] - -[[package]] -name = "substrate-keyring" -version = "1.0.0" -dependencies = [ - "lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", - "sr-primitives 1.0.0", - "strum 0.14.0 (registry+https://github.com/rust-lang/crates.io-index)", - "strum_macros 0.14.0 (registry+https://github.com/rust-lang/crates.io-index)", - "substrate-primitives 1.0.0", -] - -[[package]] -name = "substrate-keystore" -version = "1.0.0" -dependencies = [ - "error-chain 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)", - "hex 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", - "parity-crypto 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", - "rand 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_json 1.0.39 (registry+https://github.com/rust-lang/crates.io-index)", - "substrate-primitives 1.0.0", - "subtle 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "substrate-network" -version = "0.1.0" -dependencies = [ - "bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", - "crossbeam-channel 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", - "error-chain 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)", - "fork-tree 1.0.0", - "futures 0.1.26 (registry+https://github.com/rust-lang/crates.io-index)", - "linked-hash-map 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)", - "linked_hash_set 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", - "lru-cache 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", - "parity-codec 3.5.1 (registry+https://github.com/rust-lang/crates.io-index)", - "parking_lot 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)", - "rand 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", - "rustc-hex 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)", - "sr-primitives 1.0.0", - "substrate-client 1.0.0", - "substrate-consensus-common 1.0.0", - "substrate-network-libp2p 1.0.0", - "substrate-peerset 1.0.0", - "substrate-primitives 1.0.0", - "tokio 0.1.19 (registry+https://github.com/rust-lang/crates.io-index)", - "void 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "substrate-network-libp2p" -version = "1.0.0" -dependencies = [ - "byteorder 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)", - "bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)", - "erased-serde 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", - "error-chain 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)", - "fnv 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", - "futures 0.1.26 (registry+https://github.com/rust-lang/crates.io-index)", - "lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", - "libp2p 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", - "parking_lot 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)", - "rand 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.91 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_json 1.0.39 (registry+https://github.com/rust-lang/crates.io-index)", - "slog 2.4.1 (registry+https://github.com/rust-lang/crates.io-index)", - "slog_derive 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", - "smallvec 0.6.10 (registry+https://github.com/rust-lang/crates.io-index)", - "substrate-peerset 1.0.0", - "tokio-io 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-timer 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)", - "unsigned-varint 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", - "void 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "substrate-offchain" -version = "0.1.0" -dependencies = [ - "futures 0.1.26 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", - "parity-codec 3.5.1 (registry+https://github.com/rust-lang/crates.io-index)", - "sr-primitives 1.0.0", - "substrate-client 1.0.0", - "substrate-consensus-common 1.0.0", - "substrate-inherents 1.0.0", - "substrate-offchain-primitives 0.1.0", - "substrate-primitives 1.0.0", - "substrate-transaction-pool 1.0.0", - "tokio 0.1.19 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "substrate-offchain-primitives" -version = "0.1.0" -dependencies = [ - "sr-primitives 1.0.0", - "substrate-client 1.0.0", -] - -[[package]] -name = "substrate-panic-handler" -version = "1.0.0" -dependencies = [ - "backtrace 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "substrate-peerset" -version = "1.0.0" -dependencies = [ - "futures 0.1.26 (registry+https://github.com/rust-lang/crates.io-index)", - "libp2p 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", - "linked-hash-map 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", - "lru-cache 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_json 1.0.39 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "substrate-primitives" -version = "1.0.0" -dependencies = [ - "base58 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "blake2-rfc 0.2.18 (registry+https://github.com/rust-lang/crates.io-index)", - "byteorder 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)", - "hash-db 0.12.2 (registry+https://github.com/rust-lang/crates.io-index)", - "hash256-std-hasher 0.12.2 (registry+https://github.com/rust-lang/crates.io-index)", - "hex 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", - "impl-serde 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", - "parity-codec 3.5.1 (registry+https://github.com/rust-lang/crates.io-index)", - "primitive-types 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", - "rand 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", - "regex 1.1.6 (registry+https://github.com/rust-lang/crates.io-index)", - "ring 0.14.6 (registry+https://github.com/rust-lang/crates.io-index)", - "rustc-hex 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)", - "schnorrkel 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.91 (registry+https://github.com/rust-lang/crates.io-index)", - "sha2 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", - "sr-std 1.0.0", - "substrate-bip39 0.2.1 (git+https://github.com/paritytech/substrate-bip39)", - "tiny-bip39 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", - "twox-hash 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", - "untrusted 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", - "wasmi 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "substrate-rpc" -version = "1.0.0" -dependencies = [ - "error-chain 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)", - "jsonrpc-core 10.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "jsonrpc-derive 10.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "jsonrpc-pubsub 10.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", - "parity-codec 3.5.1 (registry+https://github.com/rust-lang/crates.io-index)", - "parking_lot 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.91 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_json 1.0.39 (registry+https://github.com/rust-lang/crates.io-index)", - "sr-primitives 1.0.0", - "sr-version 1.0.0", - "substrate-client 1.0.0", - "substrate-executor 1.0.0", - "substrate-network 0.1.0", - "substrate-primitives 1.0.0", - "substrate-state-machine 1.0.0", - "substrate-transaction-pool 1.0.0", - "tokio 0.1.19 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "substrate-rpc-servers" -version = "1.0.0" -dependencies = [ - "jsonrpc-http-server 10.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "jsonrpc-pubsub 10.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "jsonrpc-ws-server 10.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.91 (registry+https://github.com/rust-lang/crates.io-index)", - "sr-primitives 1.0.0", - "substrate-rpc 1.0.0", -] - -[[package]] -name = "substrate-serializer" -version = "1.0.0" -dependencies = [ - "serde 1.0.91 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_json 1.0.39 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "substrate-service" -version = "1.0.0" -dependencies = [ - "error-chain 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)", - "exit-future 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", - "futures 0.1.26 (registry+https://github.com/rust-lang/crates.io-index)", - "lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", - "parity-codec 3.5.1 (registry+https://github.com/rust-lang/crates.io-index)", - "parking_lot 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.91 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_json 1.0.39 (registry+https://github.com/rust-lang/crates.io-index)", - "slog 2.4.1 (registry+https://github.com/rust-lang/crates.io-index)", - "sr-io 1.0.0", - "sr-primitives 1.0.0", - "substrate-client 1.0.0", - "substrate-client-db 1.0.0", - "substrate-consensus-common 1.0.0", - "substrate-executor 1.0.0", - "substrate-inherents 1.0.0", - "substrate-keystore 1.0.0", - "substrate-network 0.1.0", - "substrate-offchain 0.1.0", - "substrate-primitives 1.0.0", - "substrate-rpc-servers 1.0.0", - "substrate-telemetry 1.0.0", - "substrate-transaction-pool 1.0.0", - "target_info 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio 0.1.19 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "substrate-state-db" -version = "1.0.0" -dependencies = [ - "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", - "parity-codec 3.5.1 (registry+https://github.com/rust-lang/crates.io-index)", - "parking_lot 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)", - "substrate-primitives 1.0.0", -] - -[[package]] -name = "substrate-state-machine" -version = "1.0.0" -dependencies = [ - "hash-db 0.12.2 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", - "parity-codec 3.5.1 (registry+https://github.com/rust-lang/crates.io-index)", - "parking_lot 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)", - "substrate-panic-handler 1.0.0", - "substrate-primitives 1.0.0", - "substrate-trie 1.0.0", - "trie-db 0.12.2 (registry+https://github.com/rust-lang/crates.io-index)", - "trie-root 0.12.2 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "substrate-telemetry" -version = "1.0.0" -dependencies = [ - "lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", - "parking_lot 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)", - "rand 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.91 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_json 1.0.39 (registry+https://github.com/rust-lang/crates.io-index)", - "slog 2.4.1 (registry+https://github.com/rust-lang/crates.io-index)", - "slog-async 2.3.0 (registry+https://github.com/rust-lang/crates.io-index)", - "slog-json 2.3.0 (registry+https://github.com/rust-lang/crates.io-index)", - "slog-scope 4.1.1 (registry+https://github.com/rust-lang/crates.io-index)", - "ws 0.7.9 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "substrate-transaction-graph" -version = "1.0.0" -dependencies = [ - "error-chain 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)", - "futures 0.1.26 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", - "parking_lot 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.91 (registry+https://github.com/rust-lang/crates.io-index)", - "sr-primitives 1.0.0", - "substrate-primitives 1.0.0", -] - -[[package]] -name = "substrate-transaction-pool" -version = "1.0.0" -dependencies = [ - "error-chain 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)", - "futures 0.1.26 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", - "parity-codec 3.5.1 (registry+https://github.com/rust-lang/crates.io-index)", - "parking_lot 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)", - "sr-primitives 1.0.0", - "substrate-client 1.0.0", - "substrate-primitives 1.0.0", - "substrate-transaction-graph 1.0.0", -] - -[[package]] -name = "substrate-trie" -version = "1.0.0" -dependencies = [ - "hash-db 0.12.2 (registry+https://github.com/rust-lang/crates.io-index)", - "memory-db 0.12.2 (registry+https://github.com/rust-lang/crates.io-index)", - "parity-codec 3.5.1 (registry+https://github.com/rust-lang/crates.io-index)", - "sr-std 1.0.0", - "substrate-primitives 1.0.0", - "trie-db 0.12.2 (registry+https://github.com/rust-lang/crates.io-index)", - "trie-root 0.12.2 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "subtle" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "subtle" -version = "2.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "syn" -version = "0.15.34" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "proc-macro2 0.4.30 (registry+https://github.com/rust-lang/crates.io-index)", - "quote 0.6.12 (registry+https://github.com/rust-lang/crates.io-index)", - "unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "synstructure" -version = "0.10.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "proc-macro2 0.4.30 (registry+https://github.com/rust-lang/crates.io-index)", - "quote 0.6.12 (registry+https://github.com/rust-lang/crates.io-index)", - "syn 0.15.34 (registry+https://github.com/rust-lang/crates.io-index)", - "unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "sysinfo" -version = "0.8.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "cfg-if 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.54 (registry+https://github.com/rust-lang/crates.io-index)", - "rayon 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "take_mut" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "target_info" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "tempfile" -version = "3.0.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "cfg-if 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.54 (registry+https://github.com/rust-lang/crates.io-index)", - "rand 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", - "redox_syscall 0.1.54 (registry+https://github.com/rust-lang/crates.io-index)", - "remove_dir_all 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "termcolor" -version = "1.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "wincolor 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "termion" -version = "1.5.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "libc 0.2.54 (registry+https://github.com/rust-lang/crates.io-index)", - "numtoa 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "redox_syscall 0.1.54 (registry+https://github.com/rust-lang/crates.io-index)", - "redox_termios 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "textwrap" -version = "0.10.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "unicode-width 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "thread_local" -version = "0.3.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "time" -version = "0.1.42" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "libc 0.2.54 (registry+https://github.com/rust-lang/crates.io-index)", - "redox_syscall 0.1.54 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "tiny-bip39" -version = "0.6.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "failure 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", - "hashbrown 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", - "hmac 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", - "once_cell 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", - "pbkdf2 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", - "rand 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", - "sha2 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "tiny-keccak" -version = "1.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "crunchy 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "tk-listen" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "futures 0.1.26 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio 0.1.19 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-io 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "tokio" -version = "0.1.19" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)", - "futures 0.1.26 (registry+https://github.com/rust-lang/crates.io-index)", - "mio 0.6.16 (registry+https://github.com/rust-lang/crates.io-index)", - "num_cpus 1.10.0 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-codec 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-current-thread 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-executor 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-fs 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-io 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-reactor 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-sync 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-tcp 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-threadpool 0.1.14 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-timer 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-trace-core 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-udp 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-uds 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "tokio-codec" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)", - "futures 0.1.26 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-io 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "tokio-current-thread" -version = "0.1.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "futures 0.1.26 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-executor 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "tokio-dns-unofficial" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "futures 0.1.26 (registry+https://github.com/rust-lang/crates.io-index)", - "futures-cpupool 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", - "lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio 0.1.19 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "tokio-executor" -version = "0.1.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "crossbeam-utils 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", - "futures 0.1.26 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "tokio-fs" -version = "0.1.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "futures 0.1.26 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-io 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-threadpool 0.1.14 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "tokio-io" -version = "0.1.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)", - "futures 0.1.26 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "tokio-reactor" -version = "0.1.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "crossbeam-utils 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", - "futures 0.1.26 (registry+https://github.com/rust-lang/crates.io-index)", - "lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", - "mio 0.6.16 (registry+https://github.com/rust-lang/crates.io-index)", - "num_cpus 1.10.0 (registry+https://github.com/rust-lang/crates.io-index)", - "parking_lot 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)", - "slab 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-executor 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-io 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-sync 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "tokio-sync" -version = "0.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "fnv 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", - "futures 0.1.26 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "tokio-tcp" -version = "0.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)", - "futures 0.1.26 (registry+https://github.com/rust-lang/crates.io-index)", - "iovec 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", - "mio 0.6.16 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-io 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-reactor 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "tokio-threadpool" -version = "0.1.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "crossbeam-deque 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)", - "crossbeam-queue 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", - "crossbeam-utils 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", - "futures 0.1.26 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", - "num_cpus 1.10.0 (registry+https://github.com/rust-lang/crates.io-index)", - "rand 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", - "slab 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-executor 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "tokio-timer" -version = "0.2.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "crossbeam-utils 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", - "futures 0.1.26 (registry+https://github.com/rust-lang/crates.io-index)", - "slab 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-executor 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "tokio-tls" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "futures 0.1.26 (registry+https://github.com/rust-lang/crates.io-index)", - "native-tls 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-io 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "tokio-trace-core" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "tokio-udp" -version = "0.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)", - "futures 0.1.26 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", - "mio 0.6.16 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-codec 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-io 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-reactor 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "tokio-uds" -version = "0.2.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)", - "futures 0.1.26 (registry+https://github.com/rust-lang/crates.io-index)", - "iovec 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.54 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", - "mio 0.6.16 (registry+https://github.com/rust-lang/crates.io-index)", - "mio-uds 0.6.7 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-codec 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-io 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-reactor 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "toml" -version = "0.4.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "serde 1.0.91 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "traitobject" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "trie-db" -version = "0.12.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "elastic-array 0.10.2 (registry+https://github.com/rust-lang/crates.io-index)", - "hash-db 0.12.2 (registry+https://github.com/rust-lang/crates.io-index)", - "hashmap_core 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", - "rand 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "trie-root" -version = "0.12.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "hash-db 0.12.2 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "try-lock" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "twofish" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "block-cipher-trait 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", - "byteorder 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)", - "opaque-debug 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "twox-hash" -version = "1.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "rand 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "typeable" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "typenum" -version = "1.10.0" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "ucd-util" -version = "0.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "uint" -version = "0.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "byteorder 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)", - "crunchy 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", - "heapsize 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", - "rustc-hex 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "unicase" -version = "1.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "version_check 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "unicase" -version = "2.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "version_check 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "unicode-bidi" -version = "0.3.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "matches 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "unicode-normalization" -version = "0.1.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "smallvec 0.6.10 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "unicode-segmentation" -version = "1.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "unicode-width" -version = "0.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "unicode-xid" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "unsigned-varint" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-codec 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "untrusted" -version = "0.6.2" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "url" -version = "1.7.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "idna 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", - "matches 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", - "percent-encoding 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "utf8-ranges" -version = "1.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "vcpkg" -version = "0.2.6" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "vec_map" -version = "0.8.1" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "version_check" -version = "0.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "void" -version = "1.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "want" -version = "0.0.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "futures 0.1.26 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", - "try-lock 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "wasm-bindgen" -version = "0.2.43" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "wasm-bindgen-macro 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "wasm-bindgen-backend" -version = "0.2.43" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "bumpalo 2.4.1 (registry+https://github.com/rust-lang/crates.io-index)", - "lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", - "proc-macro2 0.4.30 (registry+https://github.com/rust-lang/crates.io-index)", - "quote 0.6.12 (registry+https://github.com/rust-lang/crates.io-index)", - "syn 0.15.34 (registry+https://github.com/rust-lang/crates.io-index)", - "wasm-bindgen-shared 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "wasm-bindgen-futures" -version = "0.3.20" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "futures 0.1.26 (registry+https://github.com/rust-lang/crates.io-index)", - "js-sys 0.3.20 (registry+https://github.com/rust-lang/crates.io-index)", - "wasm-bindgen 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "wasm-bindgen-macro" -version = "0.2.43" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "quote 0.6.12 (registry+https://github.com/rust-lang/crates.io-index)", - "wasm-bindgen-macro-support 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "wasm-bindgen-macro-support" -version = "0.2.43" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "proc-macro2 0.4.30 (registry+https://github.com/rust-lang/crates.io-index)", - "quote 0.6.12 (registry+https://github.com/rust-lang/crates.io-index)", - "syn 0.15.34 (registry+https://github.com/rust-lang/crates.io-index)", - "wasm-bindgen-backend 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)", - "wasm-bindgen-shared 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "wasm-bindgen-shared" -version = "0.2.43" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "wasm-bindgen-webidl" -version = "0.2.43" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "failure 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", - "heck 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", - "proc-macro2 0.4.30 (registry+https://github.com/rust-lang/crates.io-index)", - "quote 0.6.12 (registry+https://github.com/rust-lang/crates.io-index)", - "syn 0.15.34 (registry+https://github.com/rust-lang/crates.io-index)", - "wasm-bindgen-backend 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)", - "weedle 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "wasmi" -version = "0.4.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "memory_units 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", - "parity-wasm 0.31.3 (registry+https://github.com/rust-lang/crates.io-index)", - "wasmi-validation 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "wasmi-validation" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "parity-wasm 0.31.3 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "web-sys" -version = "0.3.20" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "env_logger 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)", - "failure 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", - "js-sys 0.3.20 (registry+https://github.com/rust-lang/crates.io-index)", - "sourcefile 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", - "wasm-bindgen 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)", - "wasm-bindgen-webidl 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "websocket" -version = "0.22.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "base64 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)", - "bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", - "byteorder 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)", - "bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)", - "futures 0.1.26 (registry+https://github.com/rust-lang/crates.io-index)", - "hyper 0.10.16 (registry+https://github.com/rust-lang/crates.io-index)", - "native-tls 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", - "rand 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", - "sha1 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-codec 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-io 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-reactor 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-tcp 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-tls 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", - "unicase 1.4.2 (registry+https://github.com/rust-lang/crates.io-index)", - "url 1.7.2 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "weedle" -version = "0.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "nom 4.2.3 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "which" -version = "2.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "failure 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.54 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "winapi" -version = "0.2.8" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "winapi" -version = "0.3.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "winapi-i686-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi-x86_64-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "winapi-build" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "winapi-i686-pc-windows-gnu" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "winapi-util" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "winapi-x86_64-pc-windows-gnu" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "wincolor" -version = "1.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi-util 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "ws" -version = "0.7.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "byteorder 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)", - "bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)", - "httparse 1.3.3 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", - "mio 0.6.16 (registry+https://github.com/rust-lang/crates.io-index)", - "mio-extras 2.0.5 (registry+https://github.com/rust-lang/crates.io-index)", - "openssl 0.10.22 (registry+https://github.com/rust-lang/crates.io-index)", - "rand 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", - "sha1 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)", - "slab 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", - "url 1.7.2 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "ws2_32-sys" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "x25519-dalek" -version = "0.5.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "clear_on_drop 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", - "curve25519-dalek 1.1.4 (registry+https://github.com/rust-lang/crates.io-index)", - "rand_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "xdg" -version = "2.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "yaml-rust" -version = "0.3.5" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "yamux" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)", - "futures 0.1.26 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", - "nohash-hasher 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", - "parking_lot 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)", - "quick-error 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", - "rand 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-codec 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-io 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "zeroize" -version = "0.5.2" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[metadata] -"checksum aes 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "54eb1d8fe354e5fc611daf4f2ea97dd45a765f4f1e4512306ec183ae2e8f20c9" -"checksum aes-ctr 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d2e5b0458ea3beae0d1d8c0f3946564f8e10f90646cf78c06b4351052058d1ee" -"checksum aes-soft 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "cfd7e7ae3f9a1fb5c03b389fc6bb9a51400d0c13053f0dca698c832bfd893a0d" -"checksum aesni 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "2f70a6b5f971e473091ab7cfb5ffac6cde81666c4556751d8d5620ead8abf100" -"checksum aho-corasick 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)" = "e6f484ae0c99fec2e858eb6134949117399f222608d84cadb3f58c1f97c2364c" -"checksum aio-limited 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7f10b352bc3fc08ae24dc5d2d3ddcac153678533986122dc283d747b12071000" -"checksum ansi_term 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ee49baf6cb617b853aa8d93bf420db2383fab46d314482ca2803b40d5fde979b" -"checksum app_dirs 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "e73a24bad9bd6a94d6395382a6c69fe071708ae4409f763c5475e14ee896313d" -"checksum arrayref 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "0d382e583f07208808f6b1249e60848879ba3543f57c32277bf52d69c2f0f0ee" -"checksum arrayvec 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)" = "92c7fb76bc8826a8b33b4ee5bb07a247a81e76764ab4d55e8f73e3a4d8808c71" -"checksum asn1_der 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)" = "9893d63fc3b1c44231e667da6836a33f27d8b6b3bdc82f83da5dfd579d1b6528" -"checksum asn1_der_derive 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "9e7f92edafad155aff997fa5b727c6429b91e996b5a5d62a2b0adbae1306b5fe" -"checksum atty 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)" = "9a7d5b8723950951411ee34d271d99dddcc2035a16ab25310ea2c8cfd4369652" -"checksum autocfg 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "a6d640bee2da49f60a4068a7fae53acde8982514ab7bae8b8cea9e88cbcfd799" -"checksum backtrace 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)" = "f106c02a3604afcdc0df5d36cc47b44b55917dbaf3d808f71c163a0ddba64637" -"checksum backtrace-sys 0.1.28 (registry+https://github.com/rust-lang/crates.io-index)" = "797c830ac25ccc92a7f8a7b9862bde440715531514594a6154e3d4a54dd769b6" -"checksum base-x 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)" = "d55aa264e822dbafa12db4d54767aff17c6ba55ea2d8559b3e17392c7d000e5d" -"checksum base58 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "5024ee8015f02155eee35c711107ddd9a9bf3cb689cf2a9089c97e79b6e1ae83" -"checksum base64 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)" = "0b25d992356d2eb0ed82172f5248873db5560c4721f564b13cb5193bda5e668e" -"checksum base64 0.9.3 (registry+https://github.com/rust-lang/crates.io-index)" = "489d6c0ed21b11d038c31b6ceccca973e65d73ba3bd8ecb9a2babf5546164643" -"checksum bigint 4.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "ebecac13b3c745150d7b6c3ea7572d372f09d627c2077e893bf26c5c7f70d282" -"checksum bindgen 0.47.3 (registry+https://github.com/rust-lang/crates.io-index)" = "df683a55b54b41d5ea8ebfaebb5aa7e6b84e3f3006a78f010dadc9ca88469260" -"checksum bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "228047a76f468627ca71776ecdebd732a3423081fcf5125585bcd7c49886ce12" -"checksum bitmask 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "5da9b3d9f6f585199287a473f4f8dfab6566cf827d15c00c219f53c645687ead" -"checksum blake2 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "91721a6330935673395a0607df4d49a9cb90ae12d259f1b3e0a3f6e1d486872e" -"checksum blake2-rfc 0.2.18 (registry+https://github.com/rust-lang/crates.io-index)" = "5d6d530bdd2d52966a6d03b7a964add7ae1a288d25214066fd4b600f0f796400" -"checksum block-buffer 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1339a1042f5d9f295737ad4d9a6ab6bf81c84a933dba110b9200cd6d1448b814" -"checksum block-buffer 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "a076c298b9ecdb530ed9d967e74a6027d6a7478924520acddcddc24c1c8ab3ab" -"checksum block-buffer 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)" = "c0940dc441f31689269e10ac70eb1002a3a1d3ad1390e030043662eb7fe4688b" -"checksum block-cipher-trait 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)" = "1c924d49bd09e7c06003acda26cd9742e796e34282ec6c1189404dee0c1f4774" -"checksum block-modes 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "31aa8410095e39fdb732909fb5730a48d5bd7c2e3cd76bd1b07b3dbea130c529" -"checksum block-padding 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "6d4dc3af3ee2e12f3e5d224e5e1e3d73668abbeb69e566d361f7d5563a4fdf09" -"checksum bs58 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "0de79cfb98e7aa9988188784d8664b4b5dad6eaaa0863b91d9a4ed871d4f7a42" -"checksum bstr 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "6c8203ca06c502958719dae5f653a79e0cc6ba808ed02beffbf27d09610f2143" -"checksum bumpalo 2.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "4639720be048090544634e0402490838995ccdc9d2fe648f528f30d3c33ae71f" -"checksum byte-tools 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "560c32574a12a89ecd91f5e742165893f86e3ab98d21f8ea548658eb9eef5f40" -"checksum byte-tools 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "e3b5ca7a04898ad4bcd41c90c5285445ff5b791899bb1b0abdd2a2aa791211d7" -"checksum byteorder 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)" = "0fc10e8cc6b2580fda3f36eb6dc5316657f812a3df879a44a66fc9f0fdbc4855" -"checksum byteorder 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "a019b10a2a7cdeb292db131fc8113e57ea2a908f6e7894b0c3c671893b65dbeb" -"checksum bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)" = "206fdffcfa2df7cbe15601ef46c813fce0965eb3286db6b56c583b814b51c81c" -"checksum c_linked_list 1.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "4964518bd3b4a8190e832886cdc0da9794f12e8e6c1613a9e90ff331c4c8724b" -"checksum cc 1.0.26 (registry+https://github.com/rust-lang/crates.io-index)" = "389803e36973d242e7fecb092b2de44a3d35ac62524b3b9339e51d577d668e02" -"checksum cexpr 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "a7fa24eb00d5ffab90eaeaf1092ac85c04c64aaf358ea6f84505b8116d24c6af" -"checksum cfg-if 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)" = "11d43355396e872eefb45ce6342e4374ed7bc2b3a502d1b28e36d6e23c05d1f4" -"checksum chrono 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)" = "45912881121cb26fad7c38c17ba7daa18764771836b34fab7d3fbd93ed633878" -"checksum clang-sys 0.26.4 (registry+https://github.com/rust-lang/crates.io-index)" = "6ef0c1bcf2e99c649104bd7a7012d8f8802684400e03db0ec0af48583c6fa0e4" -"checksum clap 2.32.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b957d88f4b6a63b9d70d5f454ac8011819c6efa7727858f458ab71c756ce2d3e" -"checksum clear_on_drop 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "97276801e127ffb46b66ce23f35cc96bd454fa311294bced4bbace7baa8b1d17" -"checksum cloudabi 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "ddfc5b9aa5d4507acaf872de71051dfd0e309860e88966e1051e462a077aac4f" -"checksum constant_time_eq 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "8ff012e225ce166d4422e0e78419d901719760f62ae2b7969ca6b564d1b54a9e" -"checksum core-foundation 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)" = "25b9e03f145fd4f2bf705e07b900cd41fc636598fe5dc452fd0db1441c3f496d" -"checksum core-foundation-sys 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)" = "e7ca8a5221364ef15ce201e8ed2f609fc312682a8f4e0e3d4aa5879764e0fa3b" -"checksum crossbeam 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ad4c7ea749d9fb09e23c5cb17e3b70650860553a0e2744e38446b1803bf7db94" -"checksum crossbeam-channel 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)" = "0f0ed1a4de2235cabda8558ff5840bffb97fcb64c97827f354a451307df5f72b" -"checksum crossbeam-deque 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "f739f8c5363aca78cfb059edf753d8f0d36908c348f3d8d1503f03d8b75d9cf3" -"checksum crossbeam-deque 0.6.3 (registry+https://github.com/rust-lang/crates.io-index)" = "05e44b8cf3e1a625844d1750e1f7820da46044ff6d28f4d43e455ba3e5bb2c13" -"checksum crossbeam-deque 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)" = "b18cd2e169ad86297e6bc0ad9aa679aee9daa4f19e8163860faf7c164e4f5a71" -"checksum crossbeam-epoch 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "927121f5407de9956180ff5e936fe3cf4324279280001cd56b669d28ee7e9150" -"checksum crossbeam-epoch 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)" = "04c9e3102cc2d69cd681412141b390abd55a362afc1540965dad0ad4d34280b4" -"checksum crossbeam-queue 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7c979cd6cfe72335896575c6b5688da489e420d36a27a0b9eb0c73db574b4a4b" -"checksum crossbeam-utils 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "2760899e32a1d58d5abb31129f8fae5de75220bc2176e77ff7c627ae45c918d9" -"checksum crossbeam-utils 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)" = "f8306fcef4a7b563b76b7dd949ca48f52bc1141aa067d2ea09565f3e2652aa5c" -"checksum crunchy 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "a2f4a431c5c9f662e1200b7c7f02c34e91361150e382089a8f2dec3ba680cbda" -"checksum crunchy 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7a81dae078cea95a014a339291cec439d2f232ebe854a9d672b796c6afafa9b7" -"checksum crypto-mac 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "779015233ac67d65098614aec748ac1c756ab6677fa2e14cf8b37c08dfed1198" -"checksum crypto-mac 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7afa06d05a046c7a47c3a849907ec303504608c927f4e85f7bfff22b7180d971" -"checksum crypto-mac 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "4434400df11d95d556bac068ddfedd482915eb18fe8bea89bc80b6e4b1c179e5" -"checksum ctr 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "022cd691704491df67d25d006fe8eca083098253c4d43516c2206479c58c6736" -"checksum cuckoofilter 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "8dd43f7cfaffe0a386636a10baea2ee05cc50df3b77bea4a456c9572a939bf1f" -"checksum curve25519-dalek 1.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "750226d75fc2f5a8daec6e7477624e258674023eb73d8d647f63b943ca182a4a" -"checksum data-encoding 2.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "f4f47ca1860a761136924ddd2422ba77b2ea54fe8cc75b9040804a0d9d32ad97" -"checksum derive_more 0.14.0 (registry+https://github.com/rust-lang/crates.io-index)" = "fbe9f11be34f800b3ecaaed0ec9ec2e015d1d0ba0c8644c1310f73d6e8994615" -"checksum digest 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)" = "e5b29bf156f3f4b3c4f610a25ff69370616ae6e0657d416de22645483e72af0a" -"checksum digest 0.7.6 (registry+https://github.com/rust-lang/crates.io-index)" = "03b072242a8cbaf9c145665af9d250c59af3b958f83ed6824e13533cf76d5b90" -"checksum digest 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "05f47366984d3ad862010e22c7ce81a7dbcaebbdfb37241a620f8b6596ee135c" -"checksum discard 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "212d0f5754cb6769937f4501cc0e67f4f4483c8d2c3e1e922ee9edbe4ab4c7c0" -"checksum dns-parser 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c4d33be9473d06f75f58220f71f7a9317aca647dc061dbd3c361b0bef505fbea" -"checksum ed25519-dalek 1.0.0-pre.1 (registry+https://github.com/rust-lang/crates.io-index)" = "81956bcf7ef761fb4e1d88de3fa181358a0d26cbcb9755b587a08f9119824b86" -"checksum either 1.5.2 (registry+https://github.com/rust-lang/crates.io-index)" = "5527cfe0d098f36e3f8839852688e63c8fff1c90b2b405aef730615f9a7bcf7b" -"checksum elastic-array 0.10.2 (registry+https://github.com/rust-lang/crates.io-index)" = "073be79b6538296faf81c631872676600616073817dd9a440c477ad09b408983" -"checksum env_logger 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)" = "b61fa891024a945da30a9581546e8cfaf5602c7b3f4c137a2805cf388f92075a" -"checksum environmental 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "5c7464757b80de8930c91c9afe77ddce501826bf9d134a87db2c67d9dc177e2c" -"checksum erased-serde 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)" = "3beee4bc16478a1b26f2e80ad819a52d24745e292f521a63c16eea5f74b7eb60" -"checksum error-chain 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)" = "07e791d3be96241c77c43846b665ef1384606da2cd2a48730abe606a12906e02" -"checksum exit-future 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "d8013f441e38e31c670e7f34ec8f1d5d3a2bd9d303c1ff83976ca886005e8f48" -"checksum failure 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "795bd83d3abeb9220f257e597aa0080a508b27533824adf336529648f6abf7e2" -"checksum failure_derive 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "ea1063915fd7ef4309e222a5a07cf9c319fb9c7836b1f89b85458672dbb127e1" -"checksum fake-simd 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "e88a8acf291dafb59c2d96e8f59828f3838bb1a70398823ade51a84de6a6deed" -"checksum fdlimit 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "b1ee15a7050e5580b3712877157068ea713b245b080ff302ae2ca973cfcd9baa" -"checksum finality-grandpa 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)" = "5cdd9ef7c48777665dacc9657c272778121d4d09848100bcc2bd9c773c6cf837" -"checksum fixed-hash 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "d1a683d1234507e4f3bf2736eeddf0de1dc65996dc0164d57eba0a74bcf29489" -"checksum fnv 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)" = "2fad85553e09a6f881f739c29f0b00b0f01357c743266d478b68951ce23285f3" -"checksum foreign-types 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "f6f339eb8adc052cd2ca78910fda869aefa38d22d5cb648e6485e4d3fc06f3b1" -"checksum foreign-types-shared 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b" -"checksum fs-swap 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)" = "921d332c89b3b61a826de38c61ee5b6e02c56806cade1b0e5d81bd71f57a71bb" -"checksum fuchsia-cprng 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "a06f77d526c1a601b7c4cdd98f54b5eaabffc14d5f2f0296febdc7f357c6d3ba" -"checksum fuchsia-zircon 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "2e9763c69ebaae630ba35f74888db465e49e259ba1bc0eda7d06f4a067615d82" -"checksum fuchsia-zircon-sys 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "3dcaa9ae7725d12cdb85b3ad99a434db70b468c09ded17e012d86b5c1010f7a7" -"checksum futures 0.1.26 (registry+https://github.com/rust-lang/crates.io-index)" = "62941eff9507c8177d448bd83a44d9b9760856e184081d8cd79ba9f03dd24981" -"checksum futures-cpupool 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)" = "ab90cde24b3319636588d0c35fe03b1333857621051837ed769faefb4c2162e4" -"checksum gcc 0.3.55 (registry+https://github.com/rust-lang/crates.io-index)" = "8f5f3913fa0bfe7ee1fd8248b6b9f42a5af4b9d65ec2dd2c3c26132b950ecfc2" -"checksum generic-array 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3c0f28c2f5bfb5960175af447a2da7c18900693738343dc896ffbcabd9839592" -"checksum generic-array 0.8.3 (registry+https://github.com/rust-lang/crates.io-index)" = "fceb69994e330afed50c93524be68c42fa898c2d9fd4ee8da03bd7363acd26f2" -"checksum generic-array 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ef25c5683767570c2bbd7deba372926a55eaae9982d7726ee2a1050239d45b9d" -"checksum get_if_addrs 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)" = "abddb55a898d32925f3148bd281174a68eeb68bbfd9a5938a57b18f506ee4ef7" -"checksum get_if_addrs-sys 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "0d04f9fb746cf36b191c00f3ede8bde9c8e64f9f4b05ae2694a9ccf5e3f5ab48" -"checksum glob 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)" = "8be18de09a56b60ed0edf84bc9df007e30040691af7acd1c41874faac5895bfb" -"checksum globset 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)" = "ef4feaabe24a0a658fd9cf4a9acf6ed284f045c77df0f49020ba3245cfb7b454" -"checksum h2 0.1.18 (registry+https://github.com/rust-lang/crates.io-index)" = "85ab6286db06040ddefb71641b50017c06874614001a134b423783e2db2920bd" -"checksum hash-db 0.12.2 (registry+https://github.com/rust-lang/crates.io-index)" = "ba7fb417e5c470acdd61068c79767d0e65962e70836cf6c9dfd2409f06345ce0" -"checksum hash256-std-hasher 0.12.2 (registry+https://github.com/rust-lang/crates.io-index)" = "f8b2027c19ec91eb304999abae7307d225cf93be42af53b0039f76e98ed5af86" -"checksum hashbrown 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)" = "3bae29b6653b3412c2e71e9d486db9f9df5d701941d86683005efb9f2d28e3da" -"checksum hashmap_core 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)" = "8e04cb7a5051270ef3fa79f8c7604d581ecfa73d520e74f554e45541c4b5881a" -"checksum heapsize 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "1679e6ea370dee694f91f1dc469bf94cf8f52051d147aec3e1f9497c6fc22461" -"checksum heck 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "20564e78d53d2bb135c343b3f47714a56af2061f1c928fdb541dc7b9fdd94205" -"checksum hex 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "805026a5d0141ffc30abb3be3173848ad46a1b1664fe632428479619a3644d77" -"checksum hex-literal 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "ddc2928beef125e519d69ae1baa8c37ea2e0d3848545217f6db0179c5eb1d639" -"checksum hex-literal 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c3da68162fdd2147e66682e78e729bd77f93b4c99656db058c5782d8c6b6225a" -"checksum hex-literal-impl 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "520870c3213943eb8d7803e80180d12a6c7ceb4ae74602544529d1643dc4ddda" -"checksum hex-literal-impl 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "06095d08c7c05760f11a071b3e1d4c5b723761c01bd8d7201c30a9536668a612" -"checksum hmac 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7a13f4163aa0c5ca1be584aace0e2212b2e41be5478218d4f657f5f778b2ae2a" -"checksum hmac 0.6.3 (registry+https://github.com/rust-lang/crates.io-index)" = "733e1b3ac906631ca01ebb577e9bb0f5e37a454032b9036b5eaea4013ed6f99a" -"checksum hmac 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "f127a908633569f208325f86f71255d3363c79721d7f9fe31cd5569908819771" -"checksum hmac-drbg 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "4fe727d41d2eec0a6574d887914347e5ff96a3b87177817e2a9820c5c87fecc2" -"checksum http 0.1.17 (registry+https://github.com/rust-lang/crates.io-index)" = "eed324f0f0daf6ec10c474f150505af2c143f251722bf9dbd1261bd1f2ee2c1a" -"checksum httparse 1.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "e8734b0cfd3bc3e101ec59100e101c2eecd19282202e87808b3037b442777a83" -"checksum humantime 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3ca7e5f2e110db35f93b837c81797f3714500b81d517bf20c431b16d3ca4f114" -"checksum hyper 0.10.16 (registry+https://github.com/rust-lang/crates.io-index)" = "0a0652d9a2609a968c14be1a9ea00bf4b1d64e2e1f53a1b51b6fff3a6e829273" -"checksum hyper 0.12.28 (registry+https://github.com/rust-lang/crates.io-index)" = "e8e4606fed1c162e3a63d408c07584429f49a4f34c7176cb6cbee60e78f2372c" -"checksum idna 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "38f09e0f0b1fb55fdee1f17470ad800da77af5186a1a76c026b679358b7e844e" -"checksum impl-codec 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d2050d823639fbeae26b2b5ba09aca8907793117324858070ade0673c49f793b" -"checksum impl-serde 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "5158079de9d4158e0ce1de3ae0bd7be03904efc40b3d7dd8b8c301cbf6b52b56" -"checksum indexmap 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7e81a7c05f79578dbc15793d8b619db9ba32b4577003ef3af1a91c416798c58d" -"checksum integer-sqrt 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "ea155abb3ba6f382a75f1418988c05fe82959ed9ce727de427f9cfd425b0c903" -"checksum interleaved-ordered 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "141340095b15ed7491bd3d4ced9d20cebfb826174b6bb03386381f62b01e3d77" -"checksum iovec 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "dbe6e417e7d0975db6512b90796e8ce223145ac4e33c377e4a42882a0e88bb08" -"checksum itoa 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)" = "501266b7edd0174f8530248f87f99c88fbe60ca4ef3dd486835b8d8d53136f7f" -"checksum js-sys 0.3.20 (registry+https://github.com/rust-lang/crates.io-index)" = "e9c0d432259f651d765d888e30164c096ddbae13c89e56dd1d02a719e020efa8" -"checksum jsonrpc-core 10.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "dc15eef5f8b6bef5ac5f7440a957ff95d036e2f98706947741bfc93d1976db4c" -"checksum jsonrpc-derive 10.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c2dae61ca8a3b047fb11309b00661bc56837085bd07e46f907b9c562c0b03e68" -"checksum jsonrpc-http-server 10.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "11d2a00824306155b8ef57fe957f31b8cd8ad24262f15cf911d84dcf9a3f206d" -"checksum jsonrpc-pubsub 10.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "37fce55133ee264d0ab42bd862efcd45ae1d062cda599f4cc12ccc4be3195f2a" -"checksum jsonrpc-server-utils 10.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c9527f01ef25f251d64082cbefc0c6d6f367349afe6848ef908a674e06b2bdd3" -"checksum jsonrpc-ws-server 10.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3889012aa638a2f18eb1a879f46fc8b34e7e1423cbff3247cd1531de0d51084b" -"checksum keccak 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "67c21572b4949434e4fc1e1978b99c5f77064153c59d998bf13ecd96fb5ecba7" -"checksum kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7507624b29483431c0ba2d82aece8ca6cdba9382bff4ddd0f7490560c056098d" -"checksum kvdb 0.1.0 (git+https://github.com/paritytech/parity-common?rev=b0317f649ab2c665b7987b8475878fc4d2e1f81d)" = "" -"checksum kvdb-rocksdb 0.1.4 (git+https://github.com/paritytech/parity-common?rev=b0317f649ab2c665b7987b8475878fc4d2e1f81d)" = "" -"checksum language-tags 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "a91d884b6667cd606bb5a69aa0c99ba811a115fc68915e7056ec08a46e93199a" -"checksum lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "bc5729f27f159ddd61f4df6228e827e86643d4d3e7c32183cb30a1c08f604a14" -"checksum lazycell 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "b294d6fa9ee409a054354afc4352b0b9ef7ca222c69b8812cbea9e7d2bf3783f" -"checksum libc 0.2.54 (registry+https://github.com/rust-lang/crates.io-index)" = "c6785aa7dd976f5fbf3b71cfd9cd49d7f783c1ff565a858d71031c6c313aa5c6" -"checksum libloading 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "9c3ad660d7cb8c5822cd83d10897b0f1f1526792737a179e73896152f85b88c2" -"checksum libp2p 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "0231edab431064b30b7749484a39735eb36492cef4658c372c9059e58c3003aa" -"checksum libp2p-core 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d1a3bad2ed26297112847678683dd221473a0d44297250b61f004e1b35e72493" -"checksum libp2p-core-derive 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3f765f103b680cbed910b02bfdbdcfce5b1142899c93e51acb960bf59b6f81b1" -"checksum libp2p-dns 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "4b129d20cc8cbb6ce5da8361045649c024659173e246c5dfbf20ae06071c046a" -"checksum libp2p-floodsub 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "70d68816b8435d6788399416eb2f0a6974fb1d15c4be5c30141f87c8e81746df" -"checksum libp2p-identify 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "718ca645a065fd70855ca6042a7df686c24cd21add750c37a82c811fbd1e5c43" -"checksum libp2p-kad 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "bbe27c623a6a720efd5d704347838972062f89149a9c3cd149748da60bdcd3e0" -"checksum libp2p-mdns 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c9bc1a5d85f4812cae6367b49a432763fe28997bac7c530dc55b70ec18a78aa7" -"checksum libp2p-mplex 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "fe5a858342a1cc89464474f7edc4bae1da649b9c823a3e04d9fb494493601746" -"checksum libp2p-noise 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "fc6b5185c50a52a12e7bbe2ee7799059e24de4e52ab25edbfd26c8ab8515d317" -"checksum libp2p-ping 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7905c1431ad115bee83405770629a27d6f17153ad02ec9670a7347998ef20e22" -"checksum libp2p-plaintext 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "cc17626763ded57da8fed73187c2d9f6ebb89d30838673c430315bf560c7e4db" -"checksum libp2p-ratelimit 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "2409d08b809ab1a74269597f7da2829d117cc11b9ed3343af33fc20831619726" -"checksum libp2p-secio 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "258cdc6742945c8f6402997bbbf36733588e2db18e5a0014da6d46e3ccfb92cf" -"checksum libp2p-tcp 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1b5691e2ba2720d42bd1e93d6b90239fa9235c1956ef6a5f1dd499a7ae2767be" -"checksum libp2p-uds 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c9ab0b9ca050105fd94229c48911c0c84aef4d6b86a53d1b6df81d938354e47e" -"checksum libp2p-websocket 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "81692c3141a9aefd84f4faffdc93985af3858ef82ed7fe8185e6b27437b36183" -"checksum libp2p-yamux 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "5e6ff51a5b2056bacee1c9f2ed8455cdf3c5c619261ddb4efc783119130aaf52" -"checksum librocksdb-sys 5.18.3 (registry+https://github.com/rust-lang/crates.io-index)" = "d19778314deaa7048f2ea7d07b8aa12e1c227acebe975a37eeab6d2f8c74e41b" -"checksum libsecp256k1 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "688e8d65e495567c2c35ea0001b26b9debf0b4ea11f8cccc954233b75fc3428a" -"checksum linked-hash-map 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)" = "ae91b68aebc4ddb91978b11a1b02ddd8602a05ec19002801c5666000e05e0f83" -"checksum linked_hash_set 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "3c7c91c4c7bbeb4f2f7c4e5be11e6a05bd6830bc37249c47ce1ad86ad453ff9c" -"checksum lock_api 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "62ebf1391f6acad60e5c8b43706dde4582df75c06698ab44511d15016bc2442c" -"checksum log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)" = "e19e8d5c34a3e0e2223db8e060f9e8264aeeb5c5fc64a4ee9965c062211c024b" -"checksum log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)" = "c84ec4b527950aa83a329754b01dbe3f58361d1c5efacd1f6d68c494d08a17c6" -"checksum lru-cache 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "31e24f1ad8321ca0e8a1e0ac13f23cb668e6f5466c2c57319f6a5cf1cc8e3b1c" -"checksum matches 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)" = "7ffc5c5338469d4d3ea17d269fa8ea3512ad247247c30bd2df69e68309ed0a08" -"checksum memchr 2.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "2efc7bc57c883d4a4d6e3246905283d8dae951bb3bd32f49d6ef297f546e1c39" -"checksum memoffset 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "0f9dc261e2b62d7a622bf416ea3c5245cdd5d9a7fcc428c0d06804dfce1775b3" -"checksum memory-db 0.12.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7623b01a4f1b7acb7cf8e3f678f05e15e6ae26cb0b738dfeb5cc186fd6b82ef4" -"checksum memory_units 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "71d96e3f3c0b6325d8ccd83c33b28acb183edcb6c67938ba104ec546854b0882" -"checksum merlin 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "8c39467de91b004f5b9c06fac5bbc8e7d28309a205ee66905166b70804a71fea" -"checksum mime 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)" = "ba626b8a6de5da682e1caa06bdb42a335aee5a84db8e5046a3e8ab17ba0a3ae0" -"checksum mio 0.6.16 (registry+https://github.com/rust-lang/crates.io-index)" = "71646331f2619b1026cc302f87a2b8b648d5c6dd6937846a16cc8ce0f347f432" -"checksum mio-extras 2.0.5 (registry+https://github.com/rust-lang/crates.io-index)" = "46e73a04c2fa6250b8d802134d56d554a9ec2922bf977777c805ea5def61ce40" -"checksum mio-uds 0.6.7 (registry+https://github.com/rust-lang/crates.io-index)" = "966257a94e196b11bb43aca423754d87429960a768de9414f3691d6957abf125" -"checksum miow 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "8c1f2f3b1cf331de6896aabf6e9d55dca90356cc9960cca7eaaf408a355ae919" -"checksum multistream-select 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "f989d40aab0ed0d83c1cdb4856b5790e980b96548d1a921f280e985eb049f38d" -"checksum names 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ef320dab323286b50fb5cdda23f61c796a72a89998ab565ca32525c5c556f2da" -"checksum native-tls 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "4b2df1a4c22fd44a62147fd8f13dd0f95c9d8ca7b2610299b2a2f9cf8964274e" -"checksum net2 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)" = "42550d9fb7b6684a6d404d9fa7250c2eb2646df731d1c06afc06dcee9e1bcf88" -"checksum nodrop 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)" = "2f9667ddcc6cc8a43afc9b7917599d7216aa09c463919ea32c59ed6cac8bc945" -"checksum nohash-hasher 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "0d138afcce92d219ccb6eb53d9b1e8a96ac0d633cfd3c53cd9856d96d1741bb8" -"checksum nom 4.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "2ad2a91a8e869eeb30b9cb3119ae87773a8f4ae617f41b1eb9c154b2905f7bd6" -"checksum num-integer 0.1.39 (registry+https://github.com/rust-lang/crates.io-index)" = "e83d528d2677f0518c570baf2b7abdcf0cd2d248860b68507bdcb3e91d4c0cea" -"checksum num-traits 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)" = "0b3a5d7cc97d6d30d8b9bc8fa19bf45349ffe46241e8816f50f62f6d6aaabee1" -"checksum num_cpus 1.10.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1a23f0ed30a54abaa0c7e83b1d2d87ada7c3c23078d1d87815af3e3b6385fbba" -"checksum numtoa 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b8f8bdf33df195859076e54ab11ee78a1b208382d3a26ec40d142ffc1ecc49ef" -"checksum ole32-sys 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "5d2c49021782e5233cd243168edfa8037574afed4eba4bbaf538b3d8d1789d8c" -"checksum once_cell 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)" = "532c29a261168a45ce28948f9537ddd7a5dd272cc513b3017b1e82a88f962c37" -"checksum opaque-debug 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "93f5bb2e8e8dec81642920ccff6b61f1eb94fa3020c5a325c9851ff604152409" -"checksum openssl 0.10.22 (registry+https://github.com/rust-lang/crates.io-index)" = "a51f452b82d622fc8dd973d7266e9055ac64af25b957d9ced3989142dc61cb6b" -"checksum openssl-probe 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "77af24da69f9d9341038eba93a073b1fdaaa1b788221b00a69bce9e762cb32de" -"checksum openssl-sys 0.9.46 (registry+https://github.com/rust-lang/crates.io-index)" = "05636e06b4f8762d4b81d24a351f3966f38bd25ccbcfd235606c91fdb82cc60f" -"checksum owning_ref 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "cdf84f41639e037b484f93433aa3897863b561ed65c6e59c7073d7c561710f37" -"checksum owning_ref 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "49a4b8ea2179e6a2e27411d3bca09ca6dd630821cf6894c6c7c8467a8ee7ef13" -"checksum parity-bytes 0.1.0 (git+https://github.com/paritytech/parity-common?rev=b0317f649ab2c665b7987b8475878fc4d2e1f81d)" = "" -"checksum parity-codec 3.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "dcb43c05fb71c03b4ea7327bf15694da1e0f23f19d5b1e95bab6c6d74097e336" -"checksum parity-codec-derive 3.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "00a486fd383382ddcb2de928364b1f82571c1e48274fc43b7667a4738ee4056c" -"checksum parity-crypto 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "cf1b9c063d87e1507cb3807493c8d21859ef23b5414b39f81c53f0ba267d64c1" -"checksum parity-multiaddr 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "18a130a727008cfcd1068a28439fe939897ccad28664422aeca65b384d6de6d0" -"checksum parity-multihash 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "05d6a68e07ab34a9e87bd8dd4936f6bb5be21e4f6dbcdbaf04d8e854eba0af01" -"checksum parity-wasm 0.31.3 (registry+https://github.com/rust-lang/crates.io-index)" = "511379a8194230c2395d2f5fa627a5a7e108a9f976656ce723ae68fca4097bfc" -"checksum parity-ws 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "2fec5048fba72a2e01baeb0d08089db79aead4b57e2443df172fb1840075a233" -"checksum parking_lot 0.5.5 (registry+https://github.com/rust-lang/crates.io-index)" = "d4d05f1349491390b1730afba60bb20d55761bef489a954546b58b4b34e1e2ac" -"checksum parking_lot 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)" = "f0802bff09003b291ba756dc7e79313e51cc31667e94afbe847def490424cde5" -"checksum parking_lot 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)" = "ab41b4aed082705d1056416ae4468b6ea99d52599ecf3169b00088d43113e337" -"checksum parking_lot_core 0.2.14 (registry+https://github.com/rust-lang/crates.io-index)" = "4db1a8ccf734a7bce794cc19b3df06ed87ab2f3907036b693c68f56b4d4537fa" -"checksum parking_lot_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "ad7f7e6ebdc79edff6fdcb87a55b620174f7a989e3eb31b65231f4af57f00b8c" -"checksum parking_lot_core 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "94c8c7923936b28d546dfd14d4472eaf34c99b14e1c973a32b3e6d4eb04298c9" -"checksum paste 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "1f4a4a1c555c6505821f9d58b8779d0f630a6b7e4e1be24ba718610acf01fa79" -"checksum paste-impl 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "26e796e623b8b257215f27e6c80a5478856cae305f5b59810ff9acdaa34570e6" -"checksum pbkdf2 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "0c09cddfbfc98de7f76931acf44460972edb4023eb14d0c6d4018800e552d8e0" -"checksum pbkdf2 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "006c038a43a45995a9670da19e67600114740e8511d4333bf97a56e66a7542d9" -"checksum peeking_take_while 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "19b17cddbe7ec3f8bc800887bab5e717348c95ea2ca0b1bf0837fb964dc67099" -"checksum percent-encoding 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "31010dd2e1ac33d5b46a5b413495239882813e0369f8ed8a5e266f173602f831" -"checksum pkg-config 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)" = "676e8eb2b1b4c9043511a9b7bea0915320d7e502b0a079fb03f9635a5252b18c" -"checksum primitive-types 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "99d5a5fe9d93ddb394e2fb3fc49d0e31acb475fd45a30eeb8f3e76b767ecb7e1" -"checksum proc-macro-crate 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "4c6cf4e5b00300d151dfffae39f529dfa5188f42eeb14201229aa420d6aad10c" -"checksum proc-macro-hack 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "2c725b36c99df7af7bf9324e9c999b9e37d92c8f8caf106d82e1d7953218d2d8" -"checksum proc-macro-hack 0.5.7 (registry+https://github.com/rust-lang/crates.io-index)" = "0c1dd4172a1e1f96f709341418f49b11ea6c2d95d53dca08c0f74cbd332d9cf3" -"checksum proc-macro-hack-impl 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "2b753ad9ed99dd8efeaa7d2fb8453c8f6bc3e54b97966d35f1bc77ca6865254a" -"checksum proc-macro2 0.4.30 (registry+https://github.com/rust-lang/crates.io-index)" = "cf3d2011ab5c909338f7887f4fc896d35932e29146c12c8d01da6b22a80ba759" -"checksum protobuf 2.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "bc7badf647ae2fa27ba51c218e347386c88cc604fcfe71f2aba0ad017f3f2b75" -"checksum pwasm-utils 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)" = "efb0dcbddbb600f47a7098d33762a00552c671992171637f5bb310b37fe1f0e4" -"checksum quick-error 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "5fb6ccf8db7bbcb9c2eae558db5ab4f3da1c2a87e4e597ed394726bc8ea6ca1d" -"checksum quick-error 1.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "9274b940887ce9addde99c4eee6b5c44cc494b182b97e73dc8ffdcb3397fd3f0" -"checksum quote 0.6.12 (registry+https://github.com/rust-lang/crates.io-index)" = "faf4799c5d274f3868a4aae320a0a182cbd2baee377b378f080e16a23e9d80db" -"checksum rand 0.3.23 (registry+https://github.com/rust-lang/crates.io-index)" = "64ac302d8f83c0c1974bf758f6b041c6c8ada916fbb44a609158ca8b064cc76c" -"checksum rand 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)" = "552840b97013b1a26992c11eac34bdd778e464601a4c2054b5f0bff7c6761293" -"checksum rand 0.5.6 (registry+https://github.com/rust-lang/crates.io-index)" = "c618c47cd3ebd209790115ab837de41425723956ad3ce2e6a7f09890947cacb9" -"checksum rand 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)" = "6d71dacdc3c88c1fde3885a3be3fbab9f35724e6ce99467f7d9c5026132184ca" -"checksum rand_chacha 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "556d3a1ca6600bfcbab7c7c91ccb085ac7fbbcd70e008a98742e7847f4f7bcef" -"checksum rand_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7a6fdeb83b075e8266dcc8762c22776f6877a63111121f5f8c7411e5be7eed4b" -"checksum rand_core 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d0e7a549d590831370895ab7ba4ea0c1b6b011d106b5ff2da6eee112615e6dc0" -"checksum rand_hc 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7b40677c7be09ae76218dc623efbf7b18e34bced3f38883af07bb75630a21bc4" -"checksum rand_isaac 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "ded997c9d5f13925be2a6fd7e66bf1872597f759fd9dd93513dd7e92e5a5ee08" -"checksum rand_jitter 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "1166d5c91dc97b88d1decc3285bb0a99ed84b05cfd0bc2341bdf2d43fc41e39b" -"checksum rand_os 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "7b75f676a1e053fc562eafbb47838d67c84801e38fc1ba459e8f180deabd5071" -"checksum rand_pcg 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "abf9b09b01790cfe0364f52bf32995ea3c39f4d2dd011eac241d2914146d0b44" -"checksum rand_xorshift 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "cbf7e9e623549b0e21f6e97cf8ecf247c1a8fd2e8a992ae265314300b2455d5c" -"checksum rayon 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "373814f27745b2686b350dd261bfd24576a6fb0e2c5919b3a2b6005f820b0473" -"checksum rayon-core 1.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "b055d1e92aba6877574d8fe604a63c8b5df60f60e5982bf7ccbb1338ea527356" -"checksum rdrand 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "678054eb77286b51581ba43620cc911abf02758c91f93f479767aed0f90458b2" -"checksum redox_syscall 0.1.54 (registry+https://github.com/rust-lang/crates.io-index)" = "12229c14a0f65c4f1cb046a3b52047cdd9da1f4b30f8a39c5063c8bae515e252" -"checksum redox_termios 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7e891cfe48e9100a70a3b6eb652fef28920c117d366339687bd5576160db0f76" -"checksum regex 1.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "8f0a0bcab2fd7d1d7c54fa9eae6f43eddeb9ce2e7352f8518a814a4f65d60c58" -"checksum regex-syntax 0.6.6 (registry+https://github.com/rust-lang/crates.io-index)" = "dcfd8681eebe297b81d98498869d4aae052137651ad7b96822f09ceb690d0a96" -"checksum remove_dir_all 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "3488ba1b9a2084d38645c4c08276a1752dcbf2c7130d74f1569681ad5d2799c5" -"checksum ring 0.14.6 (registry+https://github.com/rust-lang/crates.io-index)" = "426bc186e3e95cac1e4a4be125a4aca7e84c2d616ffc02244eef36e2a60a093c" -"checksum ripemd160 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ad5112e0dbbb87577bfbc56c42450235e3012ce336e29c5befd7807bd626da4a" -"checksum rocksdb 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "f1651697fefd273bfb4fd69466cc2a9d20de557a0213b97233b22b5e95924b5e" -"checksum rustc-demangle 0.1.14 (registry+https://github.com/rust-lang/crates.io-index)" = "ccc78bfd5acd7bf3e89cffcf899e5cb1a52d6fafa8dec2739ad70c9577a57288" -"checksum rustc-hex 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "403bb3a286107a04825a5f82e1270acc1e14028d3d554d7a1e08914549575ab8" -"checksum rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "138e3e0acb6c9fb258b19b67cb8abd63c00679d2851805ea151465464fe9030a" -"checksum rw-stream-sink 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "d548a40fe17c3a77d54b82457b79fcc9b8a288d509ca20fbf5aa1dac386d22d6" -"checksum ryu 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)" = "b96a9549dc8d48f2c283938303c4b5a77aa29bfbc5b54b084fb1630408899a8f" -"checksum safe-mix 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7f7bf422d23a88c16d5090d455f182bc99c60af4df6a345c63428acf5129e347" -"checksum safemem 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "8dca453248a96cb0749e36ccdfe2b0b4e54a61bfef89fb97ec621eb8e0a93dd9" -"checksum schannel 0.1.15 (registry+https://github.com/rust-lang/crates.io-index)" = "f2f6abf258d99c3c1c5c2131d99d064e94b7b3dd5f416483057f308fea253339" -"checksum schnorrkel 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "b5eff518f9bed3d803a0d002af0ab96339b0ebbedde3bec98a684986134b7a39" -"checksum scopeguard 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "94258f53601af11e6a49f722422f6e3425c52b06245a5cf9bc09908b174f5e27" -"checksum scrypt 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "8570c5e2fa69cb29d492fd4e9974b6b5facb5a888e1c6da630d4a3cd7ebfef4a" -"checksum secp256k1 0.12.2 (registry+https://github.com/rust-lang/crates.io-index)" = "bfaccd3a23619349e0878d9a241f34b1982343cdf67367058cd7d078d326b63e" -"checksum security-framework 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "eee63d0f4a9ec776eeb30e220f0bc1e092c3ad744b2a379e3993070364d3adc2" -"checksum security-framework-sys 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "9636f8989cbf61385ae4824b98c1aaa54c994d7d8b41f11c601ed799f0549a56" -"checksum semver 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1d7eb9ef2c18661902cc47e535f9bc51b78acd254da71d375c2f6720d9a40403" -"checksum semver-parser 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3" -"checksum send_wrapper 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a0eddf2e8f50ced781f288c19f18621fa72a3779e3cb58dbf23b07469b0abeb4" -"checksum serde 1.0.91 (registry+https://github.com/rust-lang/crates.io-index)" = "a72e9b96fa45ce22a4bc23da3858dfccfd60acd28a25bcd328a98fdd6bea43fd" -"checksum serde_derive 1.0.91 (registry+https://github.com/rust-lang/crates.io-index)" = "101b495b109a3e3ca8c4cbe44cf62391527cdfb6ba15821c5ce80bcd5ea23f9f" -"checksum serde_json 1.0.39 (registry+https://github.com/rust-lang/crates.io-index)" = "5a23aa71d4a4d43fdbfaac00eff68ba8a06a51759a89ac3304323e800c4dd40d" -"checksum sha-1 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)" = "23962131a91661d643c98940b20fcaffe62d776a823247be80a48fcb8b6fce68" -"checksum sha1 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "2579985fda508104f7587689507983eadd6a6e84dd35d6d115361f530916fa0d" -"checksum sha2 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7d963c78ce367df26d7ea8b8cc655c651b42e8a1e584e869c1e17dae3ccb116a" -"checksum sha2 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)" = "9eb6be24e4c23a84d7184280d2722f7f2731fcdd4a9d886efbfe4413e4847ea0" -"checksum sha2 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7b4d8bfd0e469f417657573d8451fb33d16cfe0989359b93baf3a1ffc639543d" -"checksum sha3 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)" = "dd26bc0e7a2e3a7c959bc494caf58b72ee0c71d67704e9520f736ca7e4853ecf" -"checksum shell32-sys 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "9ee04b46101f57121c9da2b151988283b6beb79b34f5bb29a58ee48cb695122c" -"checksum slab 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "c111b5bd5695e56cffe5129854aa230b39c93a305372fdbb2668ca2394eea9f8" -"checksum slog 2.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "1e1a2eec401952cd7b12a84ea120e2d57281329940c3f93c2bf04f462539508e" -"checksum slog-async 2.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e544d16c6b230d84c866662fe55e31aacfca6ae71e6fc49ae9a311cb379bfc2f" -"checksum slog-json 2.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ddc0d2aff1f8f325ef660d9a0eb6e6dcd20b30b3f581a5897f58bf42d061c37a" -"checksum slog-scope 4.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "60c04b4726fa04595ccf2c2dad7bcd15474242c4c5e109a8a376e8a2c9b1539a" -"checksum slog_derive 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "9eff3b513cf2e0d1a60e1aba152dc72bedc5b05585722bb3cebd7bcb1e31b98f" -"checksum smallvec 0.6.10 (registry+https://github.com/rust-lang/crates.io-index)" = "ab606a9c5e214920bb66c458cd7be8ef094f813f20fe77a54cc7dbfff220d4b7" -"checksum snow 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)" = "5a64f02fd208ef15bd2d1a65861df4707e416151e1272d02c8faafad1c138100" -"checksum sourcefile 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "4bf77cb82ba8453b42b6ae1d692e4cdc92f9a47beaf89a847c8be83f4e328ad3" -"checksum spin 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "44363f6f51401c34e7be73db0db371c04705d35efbe9f7d6082e03a921a32c55" -"checksum stable_deref_trait 1.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "dba1a27d3efae4351c8051072d619e3ade2820635c3958d826bfea39d59b54c8" -"checksum static_assertions 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)" = "c19be23126415861cb3a23e501d34a708f7f9b2183c5252d690941c2e69199d5" -"checksum static_slice 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "92a7e0c5e3dfb52e8fbe0e63a1b947bbb17b4036408b151353c4491374931362" -"checksum stdweb 0.4.17 (registry+https://github.com/rust-lang/crates.io-index)" = "c34362bb10ac1a9439674795cc0e1bdcb0c46444c8fd4874ef39a01d9a8a8f24" -"checksum stdweb-derive 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "0e21ebd9179de08f2300a65454268a17ea3de204627458588c84319c4def3930" -"checksum stdweb-internal-macros 0.2.7 (registry+https://github.com/rust-lang/crates.io-index)" = "e68f7d08b76979a43e93fe043b66d2626e35d41d68b0b85519202c6dd8ac59fa" -"checksum stdweb-internal-runtime 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "d52317523542cc0af5b7e31017ad0f7d1e78da50455e38d5657cd17754f617da" -"checksum stream-cipher 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "8861bc80f649f5b4c9bd38b696ae9af74499d479dbfb327f0607de6b326a36bc" -"checksum string 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "b639411d0b9c738748b5397d5ceba08e648f4f1992231aa859af1a017f31f60b" -"checksum strsim 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "bb4f380125926a99e52bc279241539c018323fab05ad6368b56f93d9369ff550" -"checksum structopt 0.2.15 (registry+https://github.com/rust-lang/crates.io-index)" = "3d0760c312538987d363c36c42339b55f5ee176ea8808bbe4543d484a291c8d1" -"checksum structopt-derive 0.2.15 (registry+https://github.com/rust-lang/crates.io-index)" = "528aeb7351d042e6ffbc2a6fb76a86f9b622fdf7c25932798e7a82cb03bc94c6" -"checksum strum 0.14.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1810e25f576e7ffce1ff5243b37066da5ded0310b3274c20baaeccb1145b2806" -"checksum strum_macros 0.14.0 (registry+https://github.com/rust-lang/crates.io-index)" = "572a2f4e53dd4c3483fd79e5cc10ddd773a3acb1169bbfe8762365e107110579" -"checksum substrate-bip39 0.2.1 (git+https://github.com/paritytech/substrate-bip39)" = "" -"checksum subtle 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "2d67a5a62ba6e01cb2192ff309324cb4875d0c451d55fe2319433abe7a05a8ee" -"checksum subtle 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "01dca13cf6c3b179864ab3292bd794e757618d35a7766b7c46050c614ba00829" -"checksum syn 0.15.34 (registry+https://github.com/rust-lang/crates.io-index)" = "a1393e4a97a19c01e900df2aec855a29f71cf02c402e2f443b8d2747c25c5dbe" -"checksum synstructure 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)" = "73687139bf99285483c96ac0add482c3776528beac1d97d444f6e91f203a2015" -"checksum sysinfo 0.8.3 (registry+https://github.com/rust-lang/crates.io-index)" = "6d88e417391431019773011a31a6c967538da388782b7711f2f6fafd9e601e55" -"checksum take_mut 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "f764005d11ee5f36500a149ace24e00e3da98b0158b3e2d53a7495660d3f4d60" -"checksum target_info 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c63f48baada5c52e65a29eef93ab4f8982681b67f9e8d29c7b05abcfec2b9ffe" -"checksum tempfile 3.0.7 (registry+https://github.com/rust-lang/crates.io-index)" = "b86c784c88d98c801132806dadd3819ed29d8600836c4088e855cdf3e178ed8a" -"checksum termcolor 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "4096add70612622289f2fdcdbd5086dc81c1e2675e6ae58d6c4f62a16c6d7f2f" -"checksum termion 1.5.2 (registry+https://github.com/rust-lang/crates.io-index)" = "dde0593aeb8d47accea5392b39350015b5eccb12c0d98044d856983d89548dea" -"checksum textwrap 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)" = "307686869c93e71f94da64286f9a9524c0f308a9e1c87a583de8e9c9039ad3f6" -"checksum thread_local 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)" = "c6b53e329000edc2b34dbe8545fd20e55a333362d0a321909685a19bd28c3f1b" -"checksum time 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)" = "db8dcfca086c1143c9270ac42a2bbd8a7ee477b78ac8e45b19abfb0cbede4b6f" -"checksum tiny-bip39 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)" = "c1c5676413eaeb1ea35300a0224416f57abc3bd251657e0fafc12c47ff98c060" -"checksum tiny-keccak 1.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "e9175261fbdb60781fcd388a4d6cc7e14764a2b629a7ad94abb439aed223a44f" -"checksum tk-listen 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "5462b0f968c0457efe38fcd2df7e487096b992419e4f5337b06775a614bbda4b" -"checksum tokio 0.1.19 (registry+https://github.com/rust-lang/crates.io-index)" = "cec6c34409089be085de9403ba2010b80e36938c9ca992c4f67f407bb13db0b1" -"checksum tokio-codec 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "5c501eceaf96f0e1793cf26beb63da3d11c738c4a943fdf3746d81d64684c39f" -"checksum tokio-current-thread 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "d16217cad7f1b840c5a97dfb3c43b0c871fef423a6e8d2118c604e843662a443" -"checksum tokio-dns-unofficial 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "82c65483db54eb91b4ef3a9389a3364558590faf30ce473141707c0e16fda975" -"checksum tokio-executor 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)" = "83ea44c6c0773cc034771693711c35c677b4b5a4b21b9e7071704c54de7d555e" -"checksum tokio-fs 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "3fe6dc22b08d6993916647d108a1a7d15b9cd29c4f4496c62b92c45b5041b7af" -"checksum tokio-io 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)" = "5090db468dad16e1a7a54c8c67280c5e4b544f3d3e018f0b913b400261f85926" -"checksum tokio-reactor 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)" = "6af16bfac7e112bea8b0442542161bfc41cbfa4466b580bdda7d18cb88b911ce" -"checksum tokio-sync 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "5b2f843ffdf8d6e1f90bddd48da43f99ab071660cd92b7ec560ef3cdfd7a409a" -"checksum tokio-tcp 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "1d14b10654be682ac43efee27401d792507e30fd8d26389e1da3b185de2e4119" -"checksum tokio-threadpool 0.1.14 (registry+https://github.com/rust-lang/crates.io-index)" = "72558af20be886ea124595ea0f806dd5703b8958e4705429dd58b3d8231f72f2" -"checksum tokio-timer 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)" = "2910970404ba6fa78c5539126a9ae2045d62e3713041e447f695f41405a120c6" -"checksum tokio-tls 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "354b8cd83825b3c20217a9dc174d6a0c67441a2fae5c41bcb1ea6679f6ae0f7c" -"checksum tokio-trace-core 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "350c9edade9830dc185ae48ba45667a445ab59f6167ef6d0254ec9d2430d9dd3" -"checksum tokio-udp 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "66268575b80f4a4a710ef83d087fdfeeabdce9b74c797535fbac18a2cb906e92" -"checksum tokio-uds 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)" = "037ffc3ba0e12a0ab4aca92e5234e0dedeb48fddf6ccd260f1f150a36a9f2445" -"checksum toml 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)" = "758664fc71a3a69038656bee8b6be6477d2a6c315a6b81f7081f591bffa4111f" -"checksum traitobject 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "efd1f82c56340fdf16f2a953d7bda4f8fdffba13d93b00844c25572110b26079" -"checksum trie-db 0.12.2 (registry+https://github.com/rust-lang/crates.io-index)" = "1ba73747fd3a64ab531274c04cb588dfa9d30d972d62990831e63fbce2cfec59" -"checksum trie-root 0.12.2 (registry+https://github.com/rust-lang/crates.io-index)" = "cfa2e20c4f1418ac2e71ddc418e35e1b56e34022e2146209ffdbf1b2de8b1bd9" -"checksum try-lock 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "e604eb7b43c06650e854be16a2a03155743d3752dd1c943f6829e26b7a36e382" -"checksum twofish 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "712d261e83e727c8e2dbb75dacac67c36e35db36a958ee504f2164fc052434e1" -"checksum twox-hash 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "09871da9f15424236082e0b220fd404a4eb6bebc7205c67653701229234ac64c" -"checksum typeable 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "1410f6f91f21d1612654e7cc69193b0334f909dcf2c790c4826254fbb86f8887" -"checksum typenum 1.10.0 (registry+https://github.com/rust-lang/crates.io-index)" = "612d636f949607bdf9b123b4a6f6d966dedf3ff669f7f045890d3a4a73948169" -"checksum ucd-util 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "535c204ee4d8434478593480b8f86ab45ec9aae0e83c568ca81abf0fd0e88f86" -"checksum uint 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "91bb295c2c53c54742a6b8acb705114f6dfdf3c42becdb146a662cb77fcc0d02" -"checksum unicase 1.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7f4765f83163b74f957c797ad9253caf97f103fb064d3999aea9568d09fc8a33" -"checksum unicase 2.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a84e5511b2a947f3ae965dcb29b13b7b1691b6e7332cf5dbc1744138d5acb7f6" -"checksum unicode-bidi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "49f2bd0c6468a8230e1db229cff8029217cf623c767ea5d60bfbd42729ea54d5" -"checksum unicode-normalization 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)" = "141339a08b982d942be2ca06ff8b076563cbe223d1befd5450716790d44e2426" -"checksum unicode-segmentation 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "aa6024fc12ddfd1c6dbc14a80fa2324d4568849869b779f6bd37e5e4c03344d1" -"checksum unicode-width 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "882386231c45df4700b275c7ff55b6f3698780a650026380e72dabe76fa46526" -"checksum unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "fc72304796d0818e357ead4e000d19c9c174ab23dc11093ac919054d20a6a7fc" -"checksum unsigned-varint 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "2c64cdf40b4a9645534a943668681bcb219faf51874d4b65d2e0abda1b10a2ab" -"checksum untrusted 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)" = "55cd1f4b4e96b46aeb8d4855db4a7a9bd96eeeb5c6a1ab54593328761642ce2f" -"checksum url 1.7.2 (registry+https://github.com/rust-lang/crates.io-index)" = "dd4e7c0d531266369519a4aa4f399d748bd37043b00bde1e4ff1f60a120b355a" -"checksum utf8-ranges 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "796f7e48bef87609f7ade7e06495a87d5cd06c7866e6a5cbfceffc558a243737" -"checksum vcpkg 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)" = "def296d3eb3b12371b2c7d0e83bfe1403e4db2d7a0bba324a12b21c4ee13143d" -"checksum vec_map 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)" = "05c78687fb1a80548ae3250346c3db86a80a7cdd77bda190189f2d0a0987c81a" -"checksum version_check 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "914b1a6776c4c929a602fafd8bc742e06365d4bcbe48c30f9cca5824f70dc9dd" -"checksum void 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "6a02e4885ed3bc0f2de90ea6dd45ebcbb66dacffe03547fadbb0eeae2770887d" -"checksum want 0.0.6 (registry+https://github.com/rust-lang/crates.io-index)" = "797464475f30ddb8830cc529aaaae648d581f99e2036a928877dfde027ddf6b3" -"checksum wasm-bindgen 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)" = "546e4ab1bf7f9a3532d21472efd72d01a23f55abd885c60b165f393394dbad95" -"checksum wasm-bindgen-backend 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)" = "7b84bedebfd6ae3522cce59dec6b52ee6c53ceeaae8541668c15b9f42df8ecab" -"checksum wasm-bindgen-futures 0.3.20 (registry+https://github.com/rust-lang/crates.io-index)" = "c6fc76797785881eac82f72e9b676032a737dea717103878100dbf6106d8d2cb" -"checksum wasm-bindgen-macro 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)" = "f2a033fc6bfd5e486a488b0e19d7d1bb29e667ebb91db85f698381a8aa831786" -"checksum wasm-bindgen-macro-support 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)" = "fba68375ef8f095c4a169c093c95ed2e1b5e44f7872f3bcbcafe2c51b4a80480" -"checksum wasm-bindgen-shared 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)" = "321949f4d7f7bf7a49dccd464bdc46581b180f761d9505e4943926d50b2a4a64" -"checksum wasm-bindgen-webidl 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)" = "b8c2c2b45b827f96657beea954a5430d37da4cf477d2874595f5f0a6ad027980" -"checksum wasmi 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)" = "aebbaef470840d157a5c47c8c49f024da7b1b80e90ff729ca982b2b80447e78b" -"checksum wasmi-validation 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ab380192444b3e8522ae79c0a1976e42a82920916ccdfbce3def89f456ea33f3" -"checksum web-sys 0.3.20 (registry+https://github.com/rust-lang/crates.io-index)" = "47ad2ecfe3793a87a0aa49562ad6f01cb3af3c870213283bc60032ec8dd7e62a" -"checksum websocket 0.22.4 (registry+https://github.com/rust-lang/crates.io-index)" = "0adcd2a64c5746c9702b354a1b992802b0c363df1dfa324a74cb7aebe10e0cbf" -"checksum weedle 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "26a4c67f132386d965390b8a734d5d10adbcd30eb5cc74bd9229af8b83f10044" -"checksum which 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "b57acb10231b9493c8472b20cb57317d0679a49e0bdbee44b3b803a6473af164" -"checksum winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)" = "167dc9d6949a9b857f3451275e911c3f44255842c1f7a76f33c55103a909087a" -"checksum winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)" = "f10e386af2b13e47c89e7236a7a14a086791a2b88ebad6df9bf42040195cf770" -"checksum winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "2d315eee3b34aca4797b2da6b13ed88266e6d612562a0c46390af8299fc699bc" -"checksum winapi-i686-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" -"checksum winapi-util 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7168bab6e1daee33b4557efd0e95d5ca70a03706d39fa5f3fe7a236f584b03c9" -"checksum winapi-x86_64-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" -"checksum wincolor 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "561ed901ae465d6185fa7864d63fbd5720d0ef718366c9a4dc83cf6170d7e9ba" -"checksum ws 0.7.9 (registry+https://github.com/rust-lang/crates.io-index)" = "329d3e6dd450a9c5c73024e1047f0be7e24121a68484eb0b5368977bee3cf8c3" -"checksum ws2_32-sys 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "d59cefebd0c892fa2dd6de581e937301d8552cb44489cdff035c6187cb63fa5e" -"checksum x25519-dalek 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7ee1585dc1484373cbc1cee7aafda26634665cf449436fd6e24bfd1fad230538" -"checksum xdg 2.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d089681aa106a86fade1b0128fb5daf07d5867a509ab036d99988dec80429a57" -"checksum yaml-rust 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "e66366e18dc58b46801afbf2ca7661a9f59cc8c5962c29892b6039b4f86fa992" -"checksum yamux 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "01bd67889938c48f0049fc60a77341039e6c3eaf16cb7693e6ead7c0ba701295" -"checksum zeroize 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)" = "8ddfeb6eee2fb3b262ef6e0898a52b7563bb8e0d5955a313b3cf2f808246ea14" diff --git a/test-utils/chain-spec-builder/Cargo.toml b/test-utils/chain-spec-builder/Cargo.toml index 1e048a91cdb92d51ff78293dcb133f98772dc60e..0bd9b2c55ce45f07c1d6b0ffc483d269ee91269f 100644 --- a/test-utils/chain-spec-builder/Cargo.toml +++ b/test-utils/chain-spec-builder/Cargo.toml @@ -5,7 +5,7 @@ authors = ["Parity Technologies "] edition = "2018" [dependencies] -clap = { version = "~2.32", features = ["yaml"] } +clap = { version = "~2.32.0", features = ["yaml"] } node-cli = { path = "../../node/cli" } primitives = { package = "substrate-primitives", path = "../../core/primitives" } substrate-service = { path = "../../core/service" } diff --git a/test-utils/chain-spec-builder/src/main.rs b/test-utils/chain-spec-builder/src/main.rs index 13b4cc38a16463f3166f18fef09a482e8ffb52db..8f59c7349363f423cc79f8f364bedea71d460b7a 100644 --- a/test-utils/chain-spec-builder/src/main.rs +++ b/test-utils/chain-spec-builder/src/main.rs @@ -38,7 +38,7 @@ fn generate_chain_spec() -> String { None, None, None, - None, + Default::default(), ); build_spec(chain_spec, false).unwrap() } diff --git a/test-utils/transaction-factory/Cargo.toml b/test-utils/transaction-factory/Cargo.toml index f3c392c3d66ded30d9a3798b3cde37297588a57a..e53972eec65c50c63e1ea317401e42ea8ae1d336 100644 --- a/test-utils/transaction-factory/Cargo.toml +++ b/test-utils/transaction-factory/Cargo.toml @@ -8,7 +8,7 @@ edition = "2018" cli = { package = "substrate-cli", path = "../../core/cli" } client = { package = "substrate-client", path = "../../core/client" } consensus_common = { package = "substrate-consensus-common", path = "../../core/consensus/common" } -log = "0.4" +log = "0.4.8" codec = { package = "parity-scale-codec", version = "1.0.0", default-features = false, features = ["derive"] } primitives = { package = "substrate-primitives", path = "../../core/primitives", default-features = false } sr-primitives = { path = "../../core/sr-primitives", default-features = false } diff --git a/test-utils/transaction-factory/src/complex_mode.rs b/test-utils/transaction-factory/src/complex_mode.rs index 25170f8c1888b8e425ac3781186eb25fdd7574c7..ed76a66b09083e72ad9f8a19bdec4a5610db14aa 100644 --- a/test-utils/transaction-factory/src/complex_mode.rs +++ b/test-utils/transaction-factory/src/complex_mode.rs @@ -41,28 +41,30 @@ use std::sync::Arc; use log::info; +use client::Client; use client::block_builder::api::BlockBuilder; use client::runtime_api::ConstructRuntimeApi; +use primitives::{Blake2Hasher, Hasher}; use sr_primitives::generic::BlockId; use sr_primitives::traits::{Block as BlockT, ProvideRuntimeApi, One, Zero}; -use substrate_service::{ - FactoryBlock, FullClient, ServiceFactory, ComponentClient, FullComponents -}; use crate::{RuntimeAdapter, create_block}; -pub fn next( +pub fn next( factory_state: &mut RA, - client: &Arc>>, + client: &Arc>, + version: u32, genesis_hash: ::Hash, prior_block_hash: ::Hash, - prior_block_id: BlockId, -) -> Option<::Block> + prior_block_id: BlockId, +) -> Option where - F: ServiceFactory, - F::RuntimeApi: ConstructRuntimeApi, FullClient>, - FullClient: ProvideRuntimeApi, - as ProvideRuntimeApi>::Api: BlockBuilder>, + Block: BlockT::Out>, + Exec: client::CallExecutor + Send + Sync + Clone, + Backend: client::backend::Backend + Send, + Client: ProvideRuntimeApi, + as ProvideRuntimeApi>::Api: BlockBuilder, + RtApi: ConstructRuntimeApi> + Send + Sync, RA: RuntimeAdapter, { let total = factory_state.start_number() + factory_state.num() * factory_state.rounds(); @@ -92,6 +94,7 @@ where &from.1, &to, &amount, + version, &genesis_hash, &prior_block_hash, ); @@ -100,7 +103,7 @@ where let inherents = client.runtime_api().inherent_extrinsics(&prior_block_id, inherents) .expect("Failed to create inherent extrinsics"); - let block = create_block::(&client, transfer, inherents); + let block = create_block::(&client, transfer, inherents); info!( "Created block {} with hash {}. Transferring {} from {} to {}.", factory_state.block_no() + RA::Number::one(), diff --git a/test-utils/transaction-factory/src/lib.rs b/test-utils/transaction-factory/src/lib.rs index ab7dfb8ceab221c7159bf3ea4e7576ccc6e8cf7c..067c75c3fc3443e281a21f6b23a252efa0ed6733 100644 --- a/test-utils/transaction-factory/src/lib.rs +++ b/test-utils/transaction-factory/src/lib.rs @@ -26,22 +26,19 @@ use std::fmt::Display; use log::info; -use client::block_builder::api::BlockBuilder; -use client::runtime_api::ConstructRuntimeApi; +use client::{Client, block_builder::api::BlockBuilder, runtime_api::ConstructRuntimeApi}; use consensus_common::{ BlockOrigin, BlockImportParams, InherentData, ForkChoiceStrategy, SelectChain }; use consensus_common::block_import::BlockImport; use codec::{Decode, Encode}; +use primitives::{Blake2Hasher, Hasher}; use sr_primitives::generic::BlockId; use sr_primitives::traits::{ Block as BlockT, Header as HeaderT, ProvideRuntimeApi, SimpleArithmetic, One, Zero, }; -use substrate_service::{ - FactoryBlock, FactoryFullConfiguration, FullClient, new_client, - ServiceFactory, ComponentClient, FullComponents}; pub use crate::modes::Mode; pub mod modes; @@ -77,6 +74,7 @@ pub trait RuntimeAdapter { key: &Self::Secret, destination: &Self::AccountId, amount: &Self::Balance, + version: u32, genesis_hash: &::Hash, prior_block_hash: &::Hash, ) -> ::Extrinsic; @@ -94,15 +92,19 @@ pub trait RuntimeAdapter { /// Manufactures transactions. The exact amount depends on /// `mode`, `num` and `rounds`. -pub fn factory( +pub fn factory( mut factory_state: RA, - mut config: FactoryFullConfiguration, + client: &Arc>, + select_chain: &Sc, ) -> cli::error::Result<()> where - F: ServiceFactory, - F::RuntimeApi: ConstructRuntimeApi, FullClient>, - FullClient: ProvideRuntimeApi, - as ProvideRuntimeApi>::Api: BlockBuilder>, + Block: BlockT::Out>, + Exec: client::CallExecutor + Send + Sync + Clone, + Backend: client::backend::Backend + Send, + Client: ProvideRuntimeApi, + as ProvideRuntimeApi>::Api: BlockBuilder, + RtApi: ConstructRuntimeApi> + Send + Sync, + Sc: SelectChain, RA: RuntimeAdapter, <::Block as BlockT>::Hash: From, { @@ -111,35 +113,35 @@ where return Err(cli::error::Error::Input(msg)); } - let client = new_client::(&config)?; - - let select_chain = F::build_select_chain(&mut config, client.clone())?; - - let best_header: Result<::Header, cli::error::Error> = + let best_header: Result<::Header, cli::error::Error> = select_chain.best_chain().map_err(|e| format!("{:?}", e).into()); let mut best_hash = best_header?.hash(); - let best_block_id = BlockId::::hash(best_hash); + let mut best_block_id = BlockId::::hash(best_hash); + let version = client.runtime_version_at(&best_block_id)?.spec_version; let genesis_hash = client.block_hash(Zero::zero())? .expect("Genesis block always exists; qed").into(); while let Some(block) = match factory_state.mode() { - Mode::MasterToNToM => complex_mode::next::( + Mode::MasterToNToM => complex_mode::next::( &mut factory_state, &client, + version, genesis_hash, best_hash.into(), best_block_id, ), - _ => simple_modes::next::( + _ => simple_modes::next::( &mut factory_state, &client, + version, genesis_hash, best_hash.into(), best_block_id, ), } { best_hash = block.header().hash(); - import_block::(&client, block); + best_block_id = BlockId::::hash(best_hash); + import_block(&client, block); info!("Imported block at {}", factory_state.block_no()); } @@ -148,16 +150,18 @@ where } /// Create a baked block from a transfer extrinsic and timestamp inherent. -pub fn create_block( - client: &Arc>>, +pub fn create_block( + client: &Arc>, transfer: ::Extrinsic, - inherent_extrinsics: Vec<::Extrinsic>, -) -> ::Block + inherent_extrinsics: Vec<::Extrinsic>, +) -> Block where - F: ServiceFactory, - FullClient: ProvideRuntimeApi, - F::RuntimeApi: ConstructRuntimeApi, FullClient>, - as ProvideRuntimeApi>::Api: BlockBuilder>, + Block: BlockT::Out>, + Exec: client::CallExecutor + Send + Sync + Clone, + Backend: client::backend::Backend + Send, + Client: ProvideRuntimeApi, + RtApi: ConstructRuntimeApi> + Send + Sync, + as ProvideRuntimeApi>::Api: BlockBuilder, RA: RuntimeAdapter, { let mut block = client.new_block(Default::default()).expect("Failed to create new block"); @@ -173,10 +177,13 @@ where block.bake().expect("Failed to bake block") } -fn import_block( - client: &Arc>>, - block: ::Block -) -> () where F: ServiceFactory +fn import_block( + client: &Arc>, + block: Block +) -> () where + Block: BlockT::Out>, + Exec: client::CallExecutor + Send + Sync + Clone, + Backend: client::backend::Backend + Send, { let import = BlockImportParams { origin: BlockOrigin::File, diff --git a/test-utils/transaction-factory/src/simple_modes.rs b/test-utils/transaction-factory/src/simple_modes.rs index 0554678fbbd0d058e1224c2930c67f41dafde59a..bcbb91200657f2a0bd33031f9df021cd911299e5 100644 --- a/test-utils/transaction-factory/src/simple_modes.rs +++ b/test-utils/transaction-factory/src/simple_modes.rs @@ -36,28 +36,30 @@ use std::sync::Arc; use log::info; +use client::Client; use client::block_builder::api::BlockBuilder; use client::runtime_api::ConstructRuntimeApi; +use primitives::{Blake2Hasher, Hasher}; use sr_primitives::traits::{Block as BlockT, ProvideRuntimeApi, One}; use sr_primitives::generic::BlockId; -use substrate_service::{ - FactoryBlock, FullClient, ServiceFactory, ComponentClient, FullComponents -}; use crate::{Mode, RuntimeAdapter, create_block}; -pub fn next( +pub fn next( factory_state: &mut RA, - client: &Arc>>, + client: &Arc>, + version: u32, genesis_hash: ::Hash, prior_block_hash: ::Hash, - prior_block_id: BlockId, -) -> Option<::Block> + prior_block_id: BlockId, +) -> Option where - F: ServiceFactory, - F::RuntimeApi: ConstructRuntimeApi, FullClient>, - FullClient: ProvideRuntimeApi, - as ProvideRuntimeApi>::Api: BlockBuilder>, + Block: BlockT::Out>, + Exec: client::CallExecutor + Send + Sync + Clone, + Backend: client::backend::Backend + Send, + Client: ProvideRuntimeApi, + as ProvideRuntimeApi>::Api: BlockBuilder, + RtApi: ConstructRuntimeApi> + Send + Sync, RA: RuntimeAdapter, { if factory_state.block_no() >= factory_state.num() { @@ -83,6 +85,7 @@ where &from.1, &to, &amount, + version, &genesis_hash, &prior_block_hash, ); @@ -91,7 +94,7 @@ where let inherents = client.runtime_api().inherent_extrinsics(&prior_block_id, inherents) .expect("Failed to create inherent extrinsics"); - let block = create_block::(&client, transfer, inherents); + let block = create_block::(&client, transfer, inherents); factory_state.set_block_no(factory_state.block_no() + RA::Number::one());